MDL-25290 MUC - add dbname to settings hash
[moodle.git] / user / lib.php
blobbeb8d900c20bf3d063ba7ae892015dfb153c123c
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.
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
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
28 /**
29 * Creates a user
31 * @param object $user user to create
32 * @return int id of the newly created user
34 function user_create_user($user) {
35 global $DB;
37 // set the timecreate field to the current time
38 if (!is_object($user)) {
39 $user = (object)$user;
42 //check username
43 if ($user->username !== textlib::strtolower($user->username)) {
44 throw new moodle_exception('usernamelowercase');
45 } else {
46 if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
47 throw new moodle_exception('invalidusername');
51 // save the password in a temp value for later
52 if (isset($user->password)) {
54 //check password toward the password policy
55 if (!check_password_policy($user->password, $errmsg)) {
56 throw new moodle_exception($errmsg);
59 $userpassword = $user->password;
60 unset($user->password);
63 $user->timecreated = time();
64 $user->timemodified = $user->timecreated;
66 // insert the user into the database
67 $newuserid = $DB->insert_record('user', $user);
69 // trigger user_created event on the full database user row
70 $newuser = $DB->get_record('user', array('id' => $newuserid));
72 // create USER context for this user
73 context_user::instance($newuserid);
75 // update user password if necessary
76 if (isset($userpassword)) {
77 $authplugin = get_auth_plugin($newuser->auth);
78 $authplugin->user_update_password($newuser, $userpassword);
81 events_trigger('user_created', $newuser);
83 add_to_log(SITEID, 'user', get_string('create'), '/view.php?id='.$newuser->id,
84 fullname($newuser));
86 return $newuserid;
90 /**
91 * Update a user with a user object (will compare against the ID)
93 * @param object $user the user to update
95 function user_update_user($user) {
96 global $DB;
98 // set the timecreate field to the current time
99 if (!is_object($user)) {
100 $user = (object)$user;
103 //check username
104 if (isset($user->username)) {
105 if ($user->username !== textlib::strtolower($user->username)) {
106 throw new moodle_exception('usernamelowercase');
107 } else {
108 if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
109 throw new moodle_exception('invalidusername');
114 // unset password here, for updating later
115 if (isset($user->password)) {
117 //check password toward the password policy
118 if (!check_password_policy($user->password, $errmsg)) {
119 throw new moodle_exception($errmsg);
122 $passwd = $user->password;
123 unset($user->password);
126 $user->timemodified = time();
127 $DB->update_record('user', $user);
129 // trigger user_updated event on the full database user row
130 $updateduser = $DB->get_record('user', array('id' => $user->id));
132 // if password was set, then update its hash
133 if (isset($passwd)) {
134 $authplugin = get_auth_plugin($updateduser->auth);
135 if ($authplugin->can_change_password()) {
136 $authplugin->user_update_password($updateduser, $passwd);
140 events_trigger('user_updated', $updateduser);
142 add_to_log(SITEID, 'user', get_string('update'), '/view.php?id='.$updateduser->id,
143 fullname($updateduser));
148 * Marks user deleted in internal user database and notifies the auth plugin.
149 * Also unenrols user from all roles and does other cleanup.
151 * @todo Decide if this transaction is really needed (look for internal TODO:)
152 * @param object $user Userobject before delete (without system magic quotes)
153 * @return boolean success
155 function user_delete_user($user) {
156 return delete_user($user);
160 * Get users by id
161 * @param array $userids id of users to retrieve
164 function user_get_users_by_id($userids) {
165 global $DB;
166 return $DB->get_records_list('user', 'id', $userids);
170 * Returns the list of default 'displayable' fields
172 * Contains database field names but also names used to generate information, such as enrolledcourses
174 * @return array of user fields
176 function user_get_default_fields() {
177 return array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
178 'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
179 'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
180 'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
181 'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
182 'groups', 'roles', 'preferences', 'enrolledcourses'
188 * Give user record from mdl_user, build an array conntains
189 * all user details
191 * Warning: description file urls are 'webservice/pluginfile.php' is use.
192 * it can be changed with $CFG->moodlewstextformatlinkstoimagesfile
194 * @param stdClass $user user record from mdl_user
195 * @param stdClass $context context object
196 * @param stdClass $course moodle course
197 * @param array $userfields required fields
198 * @return array
200 function user_get_user_details($user, $course = null, array $userfields = array()) {
201 global $USER, $DB, $CFG;
202 require_once($CFG->dirroot . "/user/profile/lib.php"); //custom field library
203 require_once($CFG->dirroot . "/lib/filelib.php"); // file handling on description and friends
205 $defaultfields = user_get_default_fields();
207 if (empty($userfields)) {
208 $userfields = $defaultfields;
211 foreach ($userfields as $thefield) {
212 if (!in_array($thefield, $defaultfields)) {
213 throw new moodle_exception('invaliduserfield', 'error', '', $thefield);
218 // Make sure id and fullname are included
219 if (!in_array('id', $userfields)) {
220 $userfields[] = 'id';
223 if (!in_array('fullname', $userfields)) {
224 $userfields[] = 'fullname';
227 if (!empty($course)) {
228 $context = context_course::instance($course->id);
229 $usercontext = context_user::instance($user->id);
230 $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
231 } else {
232 $context = context_user::instance($user->id);
233 $usercontext = $context;
234 $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
237 $currentuser = ($user->id == $USER->id);
238 $isadmin = is_siteadmin($USER);
240 $showuseridentityfields = get_extra_user_fields($context);
242 if (!empty($course)) {
243 $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
244 } else {
245 $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
247 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
248 if (!empty($course)) {
249 $canviewuseremail = has_capability('moodle/course:useremail', $context);
250 } else {
251 $canviewuseremail = false;
253 $cannotviewdescription = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id));
254 if (!empty($course)) {
255 $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context);
256 } else {
257 $canaccessallgroups = false;
260 if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
261 // skip this user details
262 return null;
265 $userdetails = array();
266 $userdetails['id'] = $user->id;
268 if (($isadmin or $currentuser) and in_array('username', $userfields)) {
269 $userdetails['username'] = $user->username;
271 if ($isadmin or $canviewfullnames) {
272 if (in_array('firstname', $userfields)) {
273 $userdetails['firstname'] = $user->firstname;
275 if (in_array('lastname', $userfields)) {
276 $userdetails['lastname'] = $user->lastname;
279 $userdetails['fullname'] = fullname($user);
281 if (in_array('customfields', $userfields)) {
282 $fields = $DB->get_recordset_sql("SELECT f.*
283 FROM {user_info_field} f
284 JOIN {user_info_category} c
285 ON f.categoryid=c.id
286 ORDER BY c.sortorder ASC, f.sortorder ASC");
287 $userdetails['customfields'] = array();
288 foreach ($fields as $field) {
289 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
290 $newfield = 'profile_field_'.$field->datatype;
291 $formfield = new $newfield($field->id, $user->id);
292 if ($formfield->is_visible() and !$formfield->is_empty()) {
293 $userdetails['customfields'][] =
294 array('name' => $formfield->field->name, 'value' => $formfield->data,
295 'type' => $field->datatype, 'shortname' => $formfield->field->shortname);
298 $fields->close();
299 // unset customfields if it's empty
300 if (empty($userdetails['customfields'])) {
301 unset($userdetails['customfields']);
305 // profile image
306 if (in_array('profileimageurl', $userfields)) {
307 $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f1');
308 $userdetails['profileimageurl'] = $profileimageurl->out(false);
310 if (in_array('profileimageurlsmall', $userfields)) {
311 $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f2');
312 $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false);
315 //hidden user field
316 if ($canviewhiddenuserfields) {
317 $hiddenfields = array();
318 // address, phone1 and phone2 not appears in hidden fields list
319 // but require viewhiddenfields capability
320 // according to user/profile.php
321 if ($user->address && in_array('address', $userfields)) {
322 $userdetails['address'] = $user->address;
324 } else {
325 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
328 if ($user->phone1 && in_array('phone1', $userfields) &&
329 (isset($showuseridentityfields['phone1']) or $canviewhiddenuserfields)) {
330 $userdetails['phone1'] = $user->phone1;
332 if ($user->phone2 && in_array('phone2', $userfields) &&
333 (isset($showuseridentityfields['phone2']) or $canviewhiddenuserfields)) {
334 $userdetails['phone2'] = $user->phone2;
337 if (isset($user->description) &&
338 ((!isset($hiddenfields['description']) && !$cannotviewdescription) or $isadmin)) {
339 if (in_array('description', $userfields)) {
340 // Always return the descriptionformat if description is requested.
341 list($userdetails['description'], $userdetails['descriptionformat']) =
342 external_format_text($user->description, $user->descriptionformat,
343 $usercontext->id, 'user', 'profile', null);
347 if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) {
348 $userdetails['country'] = $user->country;
351 if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) {
352 $userdetails['city'] = $user->city;
355 if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
356 $url = $user->url;
357 if (strpos($user->url, '://') === false) {
358 $url = 'http://'. $url;
360 $user->url = clean_param($user->url, PARAM_URL);
361 $userdetails['url'] = $user->url;
364 if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
365 $userdetails['icq'] = $user->icq;
368 if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
369 $userdetails['skype'] = $user->skype;
371 if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
372 $userdetails['yahoo'] = $user->yahoo;
374 if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
375 $userdetails['aim'] = $user->aim;
377 if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
378 $userdetails['msn'] = $user->msn;
381 if (in_array('firstaccess', $userfields) && (!isset($hiddenfields['firstaccess']) or $isadmin)) {
382 if ($user->firstaccess) {
383 $userdetails['firstaccess'] = $user->firstaccess;
384 } else {
385 $userdetails['firstaccess'] = 0;
388 if (in_array('lastaccess', $userfields) && (!isset($hiddenfields['lastaccess']) or $isadmin)) {
389 if ($user->lastaccess) {
390 $userdetails['lastaccess'] = $user->lastaccess;
391 } else {
392 $userdetails['lastaccess'] = 0;
396 if (in_array('email', $userfields) && ($isadmin // The admin is allowed the users email
397 or $currentuser // Of course the current user is as well
398 or $canviewuseremail // this is a capability in course context, it will be false in usercontext
399 or isset($showuseridentityfields['email'])
400 or $user->maildisplay == 1
401 or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
402 $userdetails['email'] = $user->email;
405 if (in_array('interests', $userfields) && !empty($CFG->usetags)) {
406 require_once($CFG->dirroot . '/tag/lib.php');
407 if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT) ) {
408 $userdetails['interests'] = $interests;
412 //Departement/Institution/Idnumber are not displayed on any profile, however you can get them from editing profile.
413 if ($isadmin or $currentuser or isset($showuseridentityfields['idnumber'])) {
414 if (in_array('idnumber', $userfields) && $user->idnumber) {
415 $userdetails['idnumber'] = $user->idnumber;
418 if ($isadmin or $currentuser or isset($showuseridentityfields['institution'])) {
419 if (in_array('institution', $userfields) && $user->institution) {
420 $userdetails['institution'] = $user->institution;
423 if ($isadmin or $currentuser or isset($showuseridentityfields['department'])) {
424 if (in_array('department', $userfields) && isset($user->department)) { //isset because it's ok to have department 0
425 $userdetails['department'] = $user->department;
429 if (in_array('roles', $userfields) && !empty($course)) {
430 // not a big secret
431 $roles = get_user_roles($context, $user->id, false);
432 $userdetails['roles'] = array();
433 foreach ($roles as $role) {
434 $userdetails['roles'][] = array(
435 'roleid' => $role->roleid,
436 'name' => $role->name,
437 'shortname' => $role->shortname,
438 'sortorder' => $role->sortorder
443 // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group
444 if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) {
445 $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid,
446 'g.id, g.name,g.description,g.descriptionformat');
447 $userdetails['groups'] = array();
448 foreach ($usergroups as $group) {
449 list($group->description, $group->descriptionformat) =
450 external_format_text($group->description, $group->descriptionformat,
451 $context->id, 'group', 'description', $group->id);
452 $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name,
453 'description'=>$group->description, 'descriptionformat'=>$group->descriptionformat);
456 //list of courses where the user is enrolled
457 if (in_array('enrolledcourses', $userfields) && !isset($hiddenfields['mycourses'])) {
458 $enrolledcourses = array();
459 if ($mycourses = enrol_get_users_courses($user->id, true)) {
460 foreach ($mycourses as $mycourse) {
461 if ($mycourse->category) {
462 $coursecontext = context_course::instance($mycourse->id);
463 $enrolledcourse = array();
464 $enrolledcourse['id'] = $mycourse->id;
465 $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => $coursecontext));
466 $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext));
467 $enrolledcourses[] = $enrolledcourse;
470 $userdetails['enrolledcourses'] = $enrolledcourses;
474 //user preferences
475 if (in_array('preferences', $userfields) && $currentuser) {
476 $preferences = array();
477 $userpreferences = get_user_preferences();
478 foreach($userpreferences as $prefname => $prefvalue) {
479 $preferences[] = array('name' => $prefname, 'value' => $prefvalue);
481 $userdetails['preferences'] = $preferences;
484 return $userdetails;
488 * Return a list of page types
489 * @param string $pagetype current page type
490 * @param stdClass $parentcontext Block's parent context
491 * @param stdClass $currentcontext Current context of block
493 function user_page_type_list($pagetype, $parentcontext, $currentcontext) {
494 return array('user-profile'=>get_string('page-user-profile', 'pagetype'));