MDL-34011 Lesson module: fixed incorrect display of student attempt for short answer...
[moodle.git] / user / lib.php
blob2f8bc6007bd8ae4bd9dc2d84fd6491aca9e66670
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 get_context_instance(CONTEXT_USER, $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);
172 * Give user record from mdl_user, build an array conntains
173 * all user details
175 * Warning: description file urls are 'webservice/pluginfile.php' is use.
176 * it can be changed with $CFG->moodlewstextformatlinkstoimagesfile
178 * @param stdClass $user user record from mdl_user
179 * @param stdClass $context context object
180 * @param stdClass $course moodle course
181 * @param array $userfields required fields
182 * @return array
184 function user_get_user_details($user, $course = null, array $userfields = array()) {
185 global $USER, $DB, $CFG;
186 require_once($CFG->dirroot . "/user/profile/lib.php"); //custom field library
187 require_once($CFG->dirroot . "/lib/filelib.php"); // file handling on description and friends
189 $defaultfields = array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
190 'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
191 'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
192 'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
193 'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
194 'groups', 'roles', 'preferences', 'enrolledcourses'
197 if (empty($userfields)) {
198 $userfields = $defaultfields;
201 foreach ($userfields as $thefield) {
202 if (!in_array($thefield, $defaultfields)) {
203 throw new moodle_exception('invaliduserfield', 'error', '', $thefield);
208 // Make sure id and fullname are included
209 if (!in_array('id', $userfields)) {
210 $userfields[] = 'id';
213 if (!in_array('fullname', $userfields)) {
214 $userfields[] = 'fullname';
217 if (!empty($course)) {
218 $context = get_context_instance(CONTEXT_COURSE, $course->id);
219 $usercontext = get_context_instance(CONTEXT_USER, $user->id);
220 $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
221 } else {
222 $context = get_context_instance(CONTEXT_USER, $user->id);
223 $usercontext = $context;
224 $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
227 $currentuser = ($user->id == $USER->id);
228 $isadmin = is_siteadmin($USER);
230 $showuseridentityfields = get_extra_user_fields($context);
232 if (!empty($course)) {
233 $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
234 } else {
235 $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
237 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
238 if (!empty($course)) {
239 $canviewuseremail = has_capability('moodle/course:useremail', $context);
240 } else {
241 $canviewuseremail = false;
243 $cannotviewdescription = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id));
244 if (!empty($course)) {
245 $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context);
246 } else {
247 $canaccessallgroups = false;
250 if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
251 // skip this user details
252 return null;
255 $userdetails = array();
256 $userdetails['id'] = $user->id;
258 if (($isadmin or $currentuser) and in_array('username', $userfields)) {
259 $userdetails['username'] = $user->username;
261 if ($isadmin or $canviewfullnames) {
262 if (in_array('firstname', $userfields)) {
263 $userdetails['firstname'] = $user->firstname;
265 if (in_array('lastname', $userfields)) {
266 $userdetails['lastname'] = $user->lastname;
269 $userdetails['fullname'] = fullname($user);
271 if (in_array('customfields', $userfields)) {
272 $fields = $DB->get_recordset_sql("SELECT f.*
273 FROM {user_info_field} f
274 JOIN {user_info_category} c
275 ON f.categoryid=c.id
276 ORDER BY c.sortorder ASC, f.sortorder ASC");
277 $userdetails['customfields'] = array();
278 foreach ($fields as $field) {
279 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
280 $newfield = 'profile_field_'.$field->datatype;
281 $formfield = new $newfield($field->id, $user->id);
282 if ($formfield->is_visible() and !$formfield->is_empty()) {
283 $userdetails['customfields'][] =
284 array('name' => $formfield->field->name, 'value' => $formfield->data,
285 'type' => $field->datatype, 'shortname' => $formfield->field->shortname);
288 $fields->close();
289 // unset customfields if it's empty
290 if (empty($userdetails['customfields'])) {
291 unset($userdetails['customfields']);
295 // profile image
296 if (in_array('profileimageurl', $userfields)) {
297 $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f1');
298 $userdetails['profileimageurl'] = $profileimageurl->out(false);
300 if (in_array('profileimageurlsmall', $userfields)) {
301 $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f2');
302 $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false);
305 //hidden user field
306 if ($canviewhiddenuserfields) {
307 $hiddenfields = array();
308 // address, phone1 and phone2 not appears in hidden fields list
309 // but require viewhiddenfields capability
310 // according to user/profile.php
311 if ($user->address && in_array('address', $userfields)) {
312 $userdetails['address'] = $user->address;
314 } else {
315 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
318 if ($user->phone1 && in_array('phone1', $userfields) &&
319 (isset($showuseridentityfields['phone1']) or $canviewhiddenuserfields)) {
320 $userdetails['phone1'] = $user->phone1;
322 if ($user->phone2 && in_array('phone2', $userfields) &&
323 (isset($showuseridentityfields['phone2']) or $canviewhiddenuserfields)) {
324 $userdetails['phone2'] = $user->phone2;
327 if (isset($user->description) &&
328 ((!isset($hiddenfields['description']) && !$cannotviewdescription) or $isadmin)) {
329 if (in_array('description', $userfields)) {
330 // Always return the descriptionformat if description is requested.
331 list($userdetails['description'], $userdetails['descriptionformat']) =
332 external_format_text($user->description, $user->descriptionformat,
333 $usercontext->id, 'user', 'profile', null);
337 if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) {
338 $userdetails['country'] = $user->country;
341 if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) {
342 $userdetails['city'] = $user->city;
345 if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
346 $url = $user->url;
347 if (strpos($user->url, '://') === false) {
348 $url = 'http://'. $url;
350 $user->url = clean_param($user->url, PARAM_URL);
351 $userdetails['url'] = $user->url;
354 if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
355 $userdetails['icq'] = $user->icq;
358 if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
359 $userdetails['skype'] = $user->skype;
361 if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
362 $userdetails['yahoo'] = $user->yahoo;
364 if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
365 $userdetails['aim'] = $user->aim;
367 if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
368 $userdetails['msn'] = $user->msn;
371 if (in_array('firstaccess', $userfields) && (!isset($hiddenfields['firstaccess']) or $isadmin)) {
372 if ($user->firstaccess) {
373 $userdetails['firstaccess'] = $user->firstaccess;
374 } else {
375 $userdetails['firstaccess'] = 0;
378 if (in_array('lastaccess', $userfields) && (!isset($hiddenfields['lastaccess']) or $isadmin)) {
379 if ($user->lastaccess) {
380 $userdetails['lastaccess'] = $user->lastaccess;
381 } else {
382 $userdetails['lastaccess'] = 0;
386 if (in_array('email', $userfields) && ($isadmin // The admin is allowed the users email
387 or $currentuser // Of course the current user is as well
388 or $canviewuseremail // this is a capability in course context, it will be false in usercontext
389 or isset($showuseridentityfields['email'])
390 or $user->maildisplay == 1
391 or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
392 $userdetails['email'] = $user->email;
395 if (in_array('interests', $userfields) && !empty($CFG->usetags)) {
396 require_once($CFG->dirroot . '/tag/lib.php');
397 if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT) ) {
398 $userdetails['interests'] = $interests;
402 //Departement/Institution/Idnumber are not displayed on any profile, however you can get them from editing profile.
403 if ($isadmin or $currentuser or isset($showuseridentityfields['idnumber'])) {
404 if (in_array('idnumber', $userfields) && $user->idnumber) {
405 $userdetails['idnumber'] = $user->idnumber;
408 if ($isadmin or $currentuser or isset($showuseridentityfields['institution'])) {
409 if (in_array('institution', $userfields) && $user->institution) {
410 $userdetails['institution'] = $user->institution;
413 if ($isadmin or $currentuser or isset($showuseridentityfields['department'])) {
414 if (in_array('department', $userfields) && isset($user->department)) { //isset because it's ok to have department 0
415 $userdetails['department'] = $user->department;
419 if (in_array('roles', $userfields) && !empty($course)) {
420 // not a big secret
421 $roles = get_user_roles($context, $user->id, false);
422 $userdetails['roles'] = array();
423 foreach ($roles as $role) {
424 $userdetails['roles'][] = array(
425 'roleid' => $role->roleid,
426 'name' => $role->name,
427 'shortname' => $role->shortname,
428 'sortorder' => $role->sortorder
433 // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group
434 if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) {
435 $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid,
436 'g.id, g.name,g.description,g.descriptionformat');
437 $userdetails['groups'] = array();
438 foreach ($usergroups as $group) {
439 list($group->description, $group->descriptionformat) =
440 external_format_text($group->description, $group->descriptionformat,
441 $context->id, 'group', 'description', $group->id);
442 $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name,
443 'description'=>$group->description, 'descriptionformat'=>$group->descriptionformat);
446 //list of courses where the user is enrolled
447 if (in_array('enrolledcourses', $userfields) && !isset($hiddenfields['mycourses'])) {
448 $enrolledcourses = array();
449 if ($mycourses = enrol_get_users_courses($user->id, true)) {
450 foreach ($mycourses as $mycourse) {
451 if ($mycourse->category) {
452 $coursecontext = get_context_instance(CONTEXT_COURSE, $mycourse->id);
453 $enrolledcourse = array();
454 $enrolledcourse['id'] = $mycourse->id;
455 $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $mycourse->id)));
456 $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext));
457 $enrolledcourses[] = $enrolledcourse;
460 $userdetails['enrolledcourses'] = $enrolledcourses;
464 //user preferences
465 if (in_array('preferences', $userfields) && $currentuser) {
466 $preferences = array();
467 $userpreferences = get_user_preferences();
468 foreach($userpreferences as $prefname => $prefvalue) {
469 $preferences[] = array('name' => $prefname, 'value' => $prefvalue);
471 $userdetails['preferences'] = $preferences;
474 return $userdetails;
478 * Return a list of page types
479 * @param string $pagetype current page type
480 * @param stdClass $parentcontext Block's parent context
481 * @param stdClass $currentcontext Current context of block
483 function user_page_type_list($pagetype, $parentcontext, $currentcontext) {
484 return array('user-profile'=>get_string('page-user-profile', 'pagetype'));