Merge branch 'MDL-32442' of git://github.com/merrill-oakland/moodle
[moodle.git] / user / lib.php
blob68a027d250b14e956ab929de91e8de3fa3b29a48
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 // save the password in a temp value for later
43 if (isset($user->password)) {
45 //check password toward the password policy
46 if (!check_password_policy($user->password, $errmsg)) {
47 throw new moodle_exception($errmsg);
50 $userpassword = $user->password;
51 unset($user->password);
54 $user->timecreated = time();
55 $user->timemodified = $user->timecreated;
57 // insert the user into the database
58 $newuserid = $DB->insert_record('user', $user);
60 // trigger user_created event on the full database user row
61 $newuser = $DB->get_record('user', array('id' => $newuserid));
63 // create USER context for this user
64 get_context_instance(CONTEXT_USER, $newuserid);
66 // update user password if necessary
67 if (isset($userpassword)) {
68 $authplugin = get_auth_plugin($newuser->auth);
69 $authplugin->user_update_password($newuser, $userpassword);
72 events_trigger('user_created', $newuser);
74 add_to_log(SITEID, 'user', get_string('create'), '/view.php?id='.$newuser->id,
75 fullname($newuser));
77 return $newuserid;
81 /**
82 * Update a user with a user object (will compare against the ID)
84 * @param object $user the user to update
86 function user_update_user($user) {
87 global $DB;
89 // set the timecreate field to the current time
90 if (!is_object($user)) {
91 $user = (object)$user;
94 // unset password here, for updating later
95 if (isset($user->password)) {
97 //check password toward the password policy
98 if (!check_password_policy($user->password, $errmsg)) {
99 throw new moodle_exception($errmsg);
102 $passwd = $user->password;
103 unset($user->password);
106 $user->timemodified = time();
107 $DB->update_record('user', $user);
109 // trigger user_updated event on the full database user row
110 $updateduser = $DB->get_record('user', array('id' => $user->id));
112 // if password was set, then update its hash
113 if (isset($passwd)) {
114 $authplugin = get_auth_plugin($updateduser->auth);
115 if ($authplugin->can_change_password()) {
116 $authplugin->user_update_password($updateduser, $passwd);
120 events_trigger('user_updated', $updateduser);
122 add_to_log(SITEID, 'user', get_string('update'), '/view.php?id='.$updateduser->id,
123 fullname($updateduser));
128 * Marks user deleted in internal user database and notifies the auth plugin.
129 * Also unenrols user from all roles and does other cleanup.
131 * @todo Decide if this transaction is really needed (look for internal TODO:)
132 * @param object $user Userobject before delete (without system magic quotes)
133 * @return boolean success
135 function user_delete_user($user) {
136 return delete_user($user);
140 * Get users by id
141 * @param array $userids id of users to retrieve
144 function user_get_users_by_id($userids) {
145 global $DB;
146 return $DB->get_records_list('user', 'id', $userids);
152 * Give user record from mdl_user, build an array conntains
153 * all user details
154 * @param stdClass $user user record from mdl_user
155 * @param stdClass $context context object
156 * @param stdClass $course moodle course
157 * @param array $userfields required fields
158 * @return array
160 function user_get_user_details($user, $course = null, array $userfields = array()) {
161 global $USER, $DB, $CFG;
162 require_once($CFG->dirroot . "/user/profile/lib.php"); //custom field library
163 require_once($CFG->dirroot . "/lib/filelib.php"); // file handling on description and friends
165 $defaultfields = array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
166 'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
167 'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
168 'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
169 'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
170 'groups', 'roles', 'preferences', 'enrolledcourses'
173 if (empty($userfields)) {
174 $userfields = $defaultfields;
177 foreach ($userfields as $thefield) {
178 if (!in_array($thefield, $defaultfields)) {
179 throw new moodle_exception('invaliduserfield', 'error', '', $thefield);
184 // Make sure id and fullname are included
185 if (!in_array('id', $userfields)) {
186 $userfields[] = 'id';
189 if (!in_array('fullname', $userfields)) {
190 $userfields[] = 'fullname';
193 if (!empty($course)) {
194 $context = get_context_instance(CONTEXT_COURSE, $course->id);
195 $usercontext = get_context_instance(CONTEXT_USER, $user->id);
196 $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
197 } else {
198 $context = get_context_instance(CONTEXT_USER, $user->id);
199 $usercontext = $context;
200 $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
203 $currentuser = ($user->id == $USER->id);
204 $isadmin = is_siteadmin($USER);
206 if (!empty($course)) {
207 $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
208 } else {
209 $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
211 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
212 if (!empty($course)) {
213 $canviewuseremail = has_capability('moodle/course:useremail', $context);
214 } else {
215 $canviewuseremail = false;
217 $cannotviewdescription = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id));
218 if (!empty($course)) {
219 $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context);
220 } else {
221 $canaccessallgroups = false;
224 if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
225 // skip this user details
226 return null;
229 $userdetails = array();
230 $userdetails['id'] = $user->id;
232 if (($isadmin or $currentuser) and in_array('username', $userfields)) {
233 $userdetails['username'] = $user->username;
235 if ($isadmin or $canviewfullnames) {
236 if (in_array('firstname', $userfields)) {
237 $userdetails['firstname'] = $user->firstname;
239 if (in_array('lastname', $userfields)) {
240 $userdetails['lastname'] = $user->lastname;
243 $userdetails['fullname'] = fullname($user);
245 if (in_array('customfields', $userfields)) {
246 $fields = $DB->get_recordset_sql("SELECT f.*
247 FROM {user_info_field} f
248 JOIN {user_info_category} c
249 ON f.categoryid=c.id
250 ORDER BY c.sortorder ASC, f.sortorder ASC");
251 $userdetails['customfields'] = array();
252 foreach ($fields as $field) {
253 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
254 $newfield = 'profile_field_'.$field->datatype;
255 $formfield = new $newfield($field->id, $user->id);
256 if ($formfield->is_visible() and !$formfield->is_empty()) {
257 $userdetails['customfields'][] =
258 array('name' => $formfield->field->name, 'value' => $formfield->data,
259 'type' => $field->datatype, 'shortname' => $formfield->field->shortname);
262 $fields->close();
263 // unset customfields if it's empty
264 if (empty($userdetails['customfields'])) {
265 unset($userdetails['customfields']);
269 // profile image
270 if (in_array('profileimageurl', $userfields)) {
271 $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f1');
272 $userdetails['profileimageurl'] = $profileimageurl->out(false);
274 if (in_array('profileimageurlsmall', $userfields)) {
275 $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f2');
276 $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false);
279 //hidden user field
280 if ($canviewhiddenuserfields) {
281 $hiddenfields = array();
282 // address, phone1 and phone2 not appears in hidden fields list
283 // but require viewhiddenfields capability
284 // according to user/profile.php
285 if ($user->address && in_array('address', $userfields)) {
286 $userdetails['address'] = $user->address;
288 if ($user->phone1 && in_array('phone1', $userfields)) {
289 $userdetails['phone1'] = $user->phone1;
291 if ($user->phone2 && in_array('phone2', $userfields)) {
292 $userdetails['phone2'] = $user->phone2;
294 } else {
295 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
298 if (isset($user->description) && (!isset($hiddenfields['description']) or $isadmin)) {
299 if (!$cannotviewdescription) {
301 if (in_array('description', $userfields)) {
302 $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user', 'profile', null);
303 $userdetails['description'] = $user->description;
305 if (in_array('descriptionformat', $userfields)) {
306 $userdetails['descriptionformat'] = $user->descriptionformat;
311 if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) {
312 $userdetails['country'] = $user->country;
315 if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) {
316 $userdetails['city'] = $user->city;
319 if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
320 $url = $user->url;
321 if (strpos($user->url, '://') === false) {
322 $url = 'http://'. $url;
324 $user->url = clean_param($user->url, PARAM_URL);
325 $userdetails['url'] = $user->url;
328 if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
329 $userdetails['icq'] = $user->icq;
332 if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
333 $userdetails['skype'] = $user->skype;
335 if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
336 $userdetails['yahoo'] = $user->yahoo;
338 if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
339 $userdetails['aim'] = $user->aim;
341 if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
342 $userdetails['msn'] = $user->msn;
345 if (in_array('firstaccess', $userfields) && (!isset($hiddenfields['firstaccess']) or $isadmin)) {
346 if ($user->firstaccess) {
347 $userdetails['firstaccess'] = $user->firstaccess;
348 } else {
349 $userdetails['firstaccess'] = 0;
352 if (in_array('lastaccess', $userfields) && (!isset($hiddenfields['lastaccess']) or $isadmin)) {
353 if ($user->lastaccess) {
354 $userdetails['lastaccess'] = $user->lastaccess;
355 } else {
356 $userdetails['lastaccess'] = 0;
360 if (in_array('email', $userfields) && ($currentuser
361 or $canviewuseremail // this is a capability in course context, it will be false in usercontext
362 or $user->maildisplay == 1
363 or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
364 $userdetails['email'] = $user->email;;
367 if (in_array('interests', $userfields) && !empty($CFG->usetags)) {
368 require_once($CFG->dirroot . '/tag/lib.php');
369 if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT) ) {
370 $userdetails['interests'] = $interests;
374 //Departement/Institution are not displayed on any profile, however you can get them from editing profile.
375 if ($isadmin or $currentuser) {
376 if (in_array('institution', $userfields) && $user->institution) {
377 $userdetails['institution'] = $user->institution;
379 if (in_array('department', $userfields) && isset($user->department)) { //isset because it's ok to have department 0
380 $userdetails['department'] = $user->department;
384 if (in_array('roles', $userfields) && !empty($course)) {
385 // not a big secret
386 $roles = get_user_roles($context, $user->id, false);
387 $userdetails['roles'] = array();
388 foreach ($roles as $role) {
389 $userdetails['roles'][] = array(
390 'roleid' => $role->roleid,
391 'name' => $role->name,
392 'shortname' => $role->shortname,
393 'sortorder' => $role->sortorder
398 // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group
399 if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) {
400 $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name,g.description');
401 $userdetails['groups'] = array();
402 foreach ($usergroups as $group) {
403 $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'group', 'description', $group->id);
404 $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name, 'description'=>$group->description);
407 //list of courses where the user is enrolled
408 if (in_array('enrolledcourses', $userfields) && !isset($hiddenfields['mycourses'])) {
409 $enrolledcourses = array();
410 if ($mycourses = enrol_get_users_courses($user->id, true)) {
411 foreach ($mycourses as $mycourse) {
412 if ($mycourse->category) {
413 $coursecontext = get_context_instance(CONTEXT_COURSE, $mycourse->id);
414 $enrolledcourse = array();
415 $enrolledcourse['id'] = $mycourse->id;
416 $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $mycourse->id)));
417 $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext));
418 $enrolledcourses[] = $enrolledcourse;
421 $userdetails['enrolledcourses'] = $enrolledcourses;
425 //user preferences
426 if (in_array('preferences', $userfields) && $currentuser) {
427 $preferences = array();
428 $userpreferences = get_user_preferences();
429 foreach($userpreferences as $prefname => $prefvalue) {
430 $preferences[] = array('name' => $prefname, 'value' => $prefvalue);
432 $userdetails['preferences'] = $preferences;
435 return $userdetails;
439 * Return a list of page types
440 * @param string $pagetype current page type
441 * @param stdClass $parentcontext Block's parent context
442 * @param stdClass $currentcontext Current context of block
444 function user_page_type_list($pagetype, $parentcontext, $currentcontext) {
445 return array('user-profile'=>get_string('page-user-profile', 'pagetype'));