Merge branch 'dev_MDL-29476_ws_participants_master' of git://github.com/dongsheng...
[moodle.git] / user / lib.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * External user API
20  *
21  * @package    moodlecore
22  * @subpackage user
23  * @copyright  2009 Moodle Pty Ltd (http://moodle.com)
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
28 /**
29  * Creates a user
30  * @param object $user user to create
31  * @return int id of the newly created user
32  */
33 function user_create_user($user) {
34     global $DB;
36 /// set the timecreate field to the current time
37     if (!is_object($user)) {
38             $user = (object)$user;
39     }
41     /// hash the password
42     $user->password = hash_internal_user_password($user->password);
44     $user->timecreated = time();
45     $user->timemodified = $user->timecreated;
47 /// insert the user into the database
48     $newuserid = $DB->insert_record('user', $user);
50 /// create USER context for this user
51     get_context_instance(CONTEXT_USER, $newuserid);
53     return $newuserid;
55 }
57 /**
58  * Update a user with a user object (will compare against the ID)
59  * @param object $user - the user to update
60  */
61 function user_update_user($user) {
62     global $DB;
64     /// set the timecreate field to the current time
65     if (!is_object($user)) {
66             $user = (object)$user;
67     }
69     /// hash the password
70     $user->password = hash_internal_user_password($user->password);
72     $user->timemodified = time();
73     $DB->update_record('user', $user);
74 }
77 /**
78  * Marks user deleted in internal user database and notifies the auth plugin.
79  * Also unenrols user from all roles and does other cleanup.
80  *
81  * @todo Decide if this transaction is really needed (look for internal TODO:)
82  * @param object $user Userobject before delete    (without system magic quotes)
83  * @return boolean success
84  */
85 function user_delete_user($user) {
86     return delete_user($user);
87 }
89 /**
90  * Get users by id
91  * @param array $userids id of users to retrieve
92  *
93  */
94 function user_get_users_by_id($userids) {
95     global $DB;
96     return $DB->get_records_list('user', 'id', $userids);
97 }
100 /**
101  *
102  * Give user record from mdl_user, build an array conntains
103  * all user details
104  * @param stdClass $user user record from mdl_user
105  * @param stdClass $context context object
106  * @param stdClass $course moodle course
107  * @param array $userfields required fields
108  * @return array
109  */
110 function user_get_user_details($user, $course = null, array $userfields = array()) {
111     global $USER, $DB, $CFG;
112     require_once($CFG->dirroot . "/user/profile/lib.php"); //custom field library
113     require_once($CFG->dirroot . "/lib/filelib.php");      // file handling on description and friends
115     $defaultfields = array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
116         'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
117         'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
118         'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
119         'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
120         'groups', 'roles', 'preferences', 'enrolledcourses'
121     );
123     if (empty($userfields)) {
124         $userfields = $defaultfields;
125     }
127     foreach ($userfields as $thefield) {
128         if (!in_array($thefield, $defaultfields)) {
129             throw new moodle_exception('invaliduserfield', 'error', '', $thefield);
130         }
131     }
134     // Make sure id and fullname are included
135     if (!in_array('id', $userfields)) {
136         $userfields[] = 'id';
137     }
139     if (!in_array('fullname', $userfields)) {
140         $userfields[] = 'fullname';
141     }
143     if (!empty($course)) {
144         $context = get_context_instance(CONTEXT_COURSE, $course->id);
145         $usercontext = get_context_instance(CONTEXT_USER, $user->id);
146         $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
147     } else {
148         $context = get_context_instance(CONTEXT_USER, $user->id);
149         $usercontext = $context;
150         $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
151     }
153     $currentuser = ($user->id == $USER->id);
154     $isadmin = is_siteadmin($USER);
156     if (!empty($course)) {
157         $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
158     } else {
159         $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
160     }
161     $canviewfullnames        = has_capability('moodle/site:viewfullnames', $context);
162     if (!empty($course)) {
163         $canviewuseremail = has_capability('moodle/course:useremail', $context);
164     } else {
165         $canviewuseremail = false;
166     }
167     $cannotviewdescription   = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id));
168     if (!empty($course)) {
169         $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context);
170     } else {
171         $canaccessallgroups = false;
172     }
174     if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
175         // skip this user details
176         return null;
177     }
179     $userdetails = array();
180     $userdetails['id'] = $user->id;
182     if (($isadmin or $currentuser) and in_array('username', $userfields)) {
183         $userdetails['username'] = $user->username;
184     }
185     if ($isadmin or $canviewfullnames) {
186         if (in_array('firstname', $userfields)) {
187             $userdetails['firstname'] = $user->firstname;
188         }
189         if (in_array('lastname', $userfields)) {
190             $userdetails['lastname'] = $user->lastname;
191         }
192     }
193     $userdetails['fullname'] = fullname($user);
195     if (in_array('customfields', $userfields)) {
196         $fields = $DB->get_recordset_sql("SELECT f.*
197                                             FROM {user_info_field} f
198                                             JOIN {user_info_category} c
199                                                  ON f.categoryid=c.id
200                                         ORDER BY c.sortorder ASC, f.sortorder ASC");
201         $userdetails['customfields'] = array();
202         foreach ($fields as $field) {
203             require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
204             $newfield = 'profile_field_'.$field->datatype;
205             $formfield = new $newfield($field->id, $user->id);
206             if ($formfield->is_visible() and !$formfield->is_empty()) {
207                 $userdetails['customfields'][] =
208                     array('name' => $formfield->field->name, 'value' => $formfield->data,
209                         'type' => $field->datatype, 'shortname' => $formfield->field->shortname);
210             }
211         }
212         $fields->close();
213         // unset customfields if it's empty
214         if (empty($userdetails['customfields'])) {
215             unset($userdetails['customfields']);
216         }
217     }
219     // profile image
220     if (in_array('profileimageurl', $userfields)) {
221         $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f1');
222         $userdetails['profileimageurl'] = $profileimageurl->out(false);
223     }
224     if (in_array('profileimageurlsmall', $userfields)) {
225         $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f2');
226         $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false);
227     }
229     //hidden user field
230     if ($canviewhiddenuserfields) {
231         $hiddenfields = array();
232         // address, phone1 and phone2 not appears in hidden fields list
233         // but require viewhiddenfields capability
234         // according to user/profile.php
235         if ($user->address && in_array('address', $userfields)) {
236             $userdetails['address'] = $user->address;
237         }
238         if ($user->phone1 && in_array('phone1', $userfields)) {
239             $userdetails['phone1'] = $user->phone1;
240         }
241         if ($user->phone2 && in_array('phone2', $userfields)) {
242             $userdetails['phone2'] = $user->phone2;
243         }
244     } else {
245         $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
246     }
248     if (isset($user->description) && (!isset($hiddenfields['description']) or $isadmin)) {
249         if (!$cannotviewdescription) {
251             if (in_array('description', $userfields)) {
252                 $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user', 'profile', null);
253                 $userdetails['description'] = $user->description;
254             }
255             if (in_array('descriptionformat', $userfields)) {
256                 $userdetails['descriptionformat'] = $user->descriptionformat;
257             }
258         }
259     }
261     if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) {
262         $userdetails['country'] = $user->country;
263     }
265     if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) {
266         $userdetails['city'] = $user->city;
267     }
269     if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
270         $url = $user->url;
271         if (strpos($user->url, '://') === false) {
272             $url = 'http://'. $url;
273         }
274         $user->url = clean_param($user->url, PARAM_URL);
275         $userdetails['url'] = $user->url;
276     }
278     if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
279         $userdetails['icq'] = $user->icq;
280     }
282     if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
283         $userdetails['skype'] = $user->skype;
284     }
285     if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
286         $userdetails['yahoo'] = $user->yahoo;
287     }
288     if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
289         $userdetails['aim'] = $user->aim;
290     }
291     if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
292         $userdetails['msn'] = $user->msn;
293     }
295     if (in_array('firstaccess', $userfields) && (!isset($hiddenfields['firstaccess']) or $isadmin)) {
296         if ($user->firstaccess) {
297             $userdetails['firstaccess'] = $user->firstaccess;
298         } else {
299             $userdetails['firstaccess'] = 0;
300         }
301     }
302     if (in_array('lastaccess', $userfields) && (!isset($hiddenfields['lastaccess']) or $isadmin)) {
303         if ($user->lastaccess) {
304             $userdetails['lastaccess'] = $user->lastaccess;
305         } else {
306             $userdetails['lastaccess'] = 0;
307         }
308     }
310     if (in_array('email', $userfields) && ($currentuser
311       or $canviewuseremail  // this is a capability in course context, it will be false in usercontext
312       or $user->maildisplay == 1
313       or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
314         $userdetails['email'] = $user->email;;
315     }
317     if (in_array('interests', $userfields) && !empty($CFG->usetags)) {
318         require_once($CFG->dirroot . '/tag/lib.php');
319         if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT) ) {
320             $userdetails['interests'] = $interests;
321         }
322     }
324     //Departement/Institution are not displayed on any profile, however you can get them from editing profile.
325     if ($isadmin or $currentuser) {
326         if (in_array('institution', $userfields) && $user->institution) {
327             $userdetails['institution'] = $user->institution;
328         }
329         if (in_array('department', $userfields) && isset($user->department)) { //isset because it's ok to have department 0
330             $userdetails['department'] = $user->department;
331         }
332     }
334     if (in_array('roles', $userfields) && !empty($course)) {
335         // not a big secret
336         $roles = get_user_roles($context, $user->id, false);
337         $userdetails['roles'] = array();
338         foreach ($roles as $role) {
339             $userdetails['roles'][] = array(
340                 'roleid'       => $role->roleid,
341                 'name'         => $role->name,
342                 'shortname'    => $role->shortname,
343                 'sortorder'    => $role->sortorder
344             );
345         }
346     }
348     // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group
349     if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) {
350         $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name,g.description');
351         $userdetails['groups'] = array();
352         foreach ($usergroups as $group) {
353             $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'group', 'description', $group->id);
354             $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name, 'description'=>$group->description);
355         }
356     }
357     //list of courses where the user is enrolled
358     if (in_array('enrolledcourses', $userfields) && !isset($hiddenfields['mycourses'])) {
359         $enrolledcourses = array();
360         if ($mycourses = enrol_get_users_courses($user->id, true)) {
361             foreach ($mycourses as $mycourse) {
362                 if ($mycourse->category) {
363                     $coursecontext = get_context_instance(CONTEXT_COURSE, $mycourse->id);
364                     $enrolledcourse = array();
365                     $enrolledcourse['id'] = $mycourse->id;
366                     $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $mycourse->id)));
367                     $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext));
368                     $enrolledcourses[] = $enrolledcourse;
369                 }
370             }
371             $userdetails['enrolledcourses'] = $enrolledcourses;
372         }
373     }
375     //user preferences
376     if (in_array('preferences', $userfields) && $currentuser) {
377         $preferences = array();
378         $userpreferences = get_user_preferences();
379          foreach($userpreferences as $prefname => $prefvalue) {
380             $preferences[] = array('name' => $prefname, 'value' => $prefvalue);
381          }
382          $userdetails['preferences'] = $preferences;
383     }
385     return $userdetails;
388 /**
389  * Return a list of page types
390  * @param string $pagetype current page type
391  * @param stdClass $parentcontext Block's parent context
392  * @param stdClass $currentcontext Current context of block
393  */
394 function user_page_type_list($pagetype, $parentcontext, $currentcontext) {
395     return array(
396         'user-profile'=>get_string('page-user-profile', 'pagetype'),
397         'my-index'=>get_string('page-my-index', 'pagetype')
398     );