MDL-29476 web service improvements
[moodle.git] / user / lib.php
blob7c2267fe327032a5308acaffe177baa542baadd4
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
30 * @param object $user user to create
31 * @return int id of the newly created user
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;
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;
57 /**
58 * Update a user with a user object (will compare against the ID)
59 * @param object $user - the user to update
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;
69 /// hash the password
70 $user->password = hash_internal_user_password($user->password);
72 $user->timemodified = time();
73 $DB->update_record('user', $user);
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.
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
85 function user_delete_user($user) {
86 return delete_user($user);
89 /**
90 * Get users by id
91 * @param array $userids id of users to retrieve
94 function user_get_users_by_id($userids) {
95 global $DB;
96 return $DB->get_records_list('user', 'id', $userids);
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
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'
123 if (empty($userfields)) {
124 $userfields = $defaultfields;
127 foreach ($userfields as $thefield) {
128 if (!in_array($thefield, $defaultfields)) {
129 throw new moodle_exception('invaliduserfield', 'error', '', $thefield);
134 // Make sure id and fullname are included
135 if (!in_array('id', $userfields)) {
136 $userfields[] = 'id';
139 if (!in_array('fullname', $userfields)) {
140 $userfields[] = 'fullname';
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);
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);
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;
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;
174 if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
175 // skip this user details
176 return null;
179 $userdetails = array();
180 $userdetails['id'] = $user->id;
182 if (($isadmin or $currentuser) and in_array('username', $userfields)) {
183 $userdetails['username'] = $user->username;
185 if ($isadmin or $canviewfullnames) {
186 if (in_array('firstname', $userfields)) {
187 $userdetails['firstname'] = $user->firstname;
189 if (in_array('lastname', $userfields)) {
190 $userdetails['lastname'] = $user->lastname;
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);
212 $fields->close();
213 // unset customfields if it's empty
214 if (empty($userdetails['customfields'])) {
215 unset($userdetails['customfields']);
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);
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);
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;
238 if ($user->phone1 && in_array('phone1', $userfields)) {
239 $userdetails['phone1'] = $user->phone1;
241 if ($user->phone2 && in_array('phone2', $userfields)) {
242 $userdetails['phone2'] = $user->phone2;
244 } else {
245 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
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;
255 if (in_array('descriptionformat', $userfields)) {
256 $userdetails['descriptionformat'] = $user->descriptionformat;
261 if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) {
262 $userdetails['country'] = $user->country;
265 if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) {
266 $userdetails['city'] = $user->city;
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;
274 $user->url = clean_param($user->url, PARAM_URL);
275 $userdetails['url'] = $user->url;
278 if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
279 $userdetails['icq'] = $user->icq;
282 if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
283 $userdetails['skype'] = $user->skype;
285 if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
286 $userdetails['yahoo'] = $user->yahoo;
288 if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
289 $userdetails['aim'] = $user->aim;
291 if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
292 $userdetails['msn'] = $user->msn;
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;
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;
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;;
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;
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;
329 if (in_array('department', $userfields) && isset($user->department)) { //isset because it's ok to have department 0
330 $userdetails['department'] = $user->department;
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
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);
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;
371 $userdetails['enrolledcourses'] = $enrolledcourses;
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);
382 $userdetails['preferences'] = $preferences;
385 return $userdetails;
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
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')