MDL-33434 mssql: Improve handling of returned ids on insert.
[moodle.git] / user / lib.php
bloba01e6fb6da7f0a90491668e03ebbb008fdf98e1b
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)) {
53 $userpassword = $user->password;
54 unset($user->password);
57 $user->timecreated = time();
58 $user->timemodified = $user->timecreated;
60 // insert the user into the database
61 $newuserid = $DB->insert_record('user', $user);
63 // trigger user_created event on the full database user row
64 $newuser = $DB->get_record('user', array('id' => $newuserid));
65 events_trigger('user_created', $newuser);
67 // create USER context for this user
68 get_context_instance(CONTEXT_USER, $newuserid);
70 // update user password if necessary
71 if (isset($userpassword)) {
72 update_internal_user_password($newuser, $userpassword);
75 return $newuserid;
79 /**
80 * Update a user with a user object (will compare against the ID)
82 * @param object $user the user to update
84 function user_update_user($user) {
85 global $DB;
87 // set the timecreate field to the current time
88 if (!is_object($user)) {
89 $user = (object)$user;
92 //check username
93 if (isset($user->username)) {
94 if ($user->username !== textlib::strtolower($user->username)) {
95 throw new moodle_exception('usernamelowercase');
96 } else {
97 if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
98 throw new moodle_exception('invalidusername');
103 // unset password here, for updating later
104 if (isset($user->password)) {
105 $passwd = $user->password;
106 unset($user->password);
109 $user->timemodified = time();
110 $DB->update_record('user', $user);
112 // trigger user_updated event on the full database user row
113 $updateduser = $DB->get_record('user', array('id' => $user->id));
114 events_trigger('user_updated', $updateduser);
116 // if password was set, then update its hash
117 if (isset($passwd)) {
118 update_internal_user_password($updateduser, $passwd);
124 * Marks user deleted in internal user database and notifies the auth plugin.
125 * Also unenrols user from all roles and does other cleanup.
127 * @todo Decide if this transaction is really needed (look for internal TODO:)
128 * @param object $user Userobject before delete (without system magic quotes)
129 * @return boolean success
131 function user_delete_user($user) {
132 return delete_user($user);
136 * Get users by id
137 * @param array $userids id of users to retrieve
140 function user_get_users_by_id($userids) {
141 global $DB;
142 return $DB->get_records_list('user', 'id', $userids);
148 * Give user record from mdl_user, build an array conntains
149 * all user details
150 * @param stdClass $user user record from mdl_user
151 * @param stdClass $context context object
152 * @param stdClass $course moodle course
153 * @return array
155 function user_get_user_details($user, $course = null) {
156 global $USER, $DB, $CFG;
157 require_once($CFG->dirroot . "/user/profile/lib.php"); //custom field library
158 require_once($CFG->dirroot . "/lib/filelib.php"); // file handling on description and friends
160 if (!empty($course)) {
161 $context = get_context_instance(CONTEXT_COURSE, $course->id);
162 $usercontext = get_context_instance(CONTEXT_USER, $user->id);
163 $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
164 } else {
165 $context = get_context_instance(CONTEXT_USER, $user->id);
166 $usercontext = $context;
167 $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
170 $currentuser = ($user->id == $USER->id);
171 $isadmin = is_siteadmin($USER);
173 if (!empty($course)) {
174 $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
175 } else {
176 $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
178 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
179 if (!empty($course)) {
180 $canviewuseremail = has_capability('moodle/course:useremail', $context);
181 } else {
182 $canviewuseremail = false;
184 $cannotviewdescription = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id));
185 if (!empty($course)) {
186 $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context);
187 } else {
188 $canaccessallgroups = false;
191 if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
192 // skip this user details
193 return null;
196 $userdetails = array();
197 $userdetails['id'] = $user->id;
199 if ($isadmin or $currentuser) {
200 $userdetails['username'] = $user->username;
202 if ($isadmin or $canviewfullnames) {
203 $userdetails['firstname'] = $user->firstname;
204 $userdetails['lastname'] = $user->lastname;
206 $userdetails['fullname'] = fullname($user);
208 $fields = $DB->get_recordset_sql("SELECT f.*
209 FROM {user_info_field} f
210 JOIN {user_info_category} c
211 ON f.categoryid=c.id
212 ORDER BY c.sortorder ASC, f.sortorder ASC");
213 $userdetails['customfields'] = array();
214 foreach ($fields as $field) {
215 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
216 $newfield = 'profile_field_'.$field->datatype;
217 $formfield = new $newfield($field->id, $user->id);
218 if ($formfield->is_visible() and !$formfield->is_empty()) {
219 $userdetails['customfields'][] =
220 array('name' => $formfield->field->name, 'value' => $formfield->data,
221 'type' => $field->datatype, 'shortname' => $formfield->field->shortname);
224 $fields->close();
225 // unset customfields if it's empty
226 if (empty($userdetails['customfields'])) {
227 unset($userdetails['customfields']);
230 // profile image
231 $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f1');
232 $userdetails['profileimageurl'] = $profileimageurl->out(false);
233 $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f2');
234 $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false);
236 //hidden user field
237 if ($canviewhiddenuserfields) {
238 $hiddenfields = array();
239 // address, phone1 and phone2 not appears in hidden fields list
240 // but require viewhiddenfields capability
241 // according to user/profile.php
242 if ($user->address) {
243 $userdetails['address'] = $user->address;
245 if ($user->phone1) {
246 $userdetails['phone1'] = $user->phone1;
248 if ($user->phone2) {
249 $userdetails['phone2'] = $user->phone2;
251 } else {
252 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
255 if (isset($user->description) && (!isset($hiddenfields['description']) or $isadmin)) {
256 if (!$cannotviewdescription) {
257 $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user', 'profile', null);
258 $userdetails['description'] = $user->description;
259 $userdetails['descriptionformat'] = $user->descriptionformat;
263 if ((!isset($hiddenfields['country']) or $isadmin) && $user->country) {
264 $userdetails['country'] = $user->country;
267 if ((!isset($hiddenfields['city']) or $isadmin) && $user->city) {
268 $userdetails['city'] = $user->city;
271 if ($user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
272 $url = $user->url;
273 if (strpos($user->url, '://') === false) {
274 $url = 'http://'. $url;
276 $user->url = clean_param($user->url, PARAM_URL);
277 $userdetails['url'] = $user->url;
280 if ($user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
281 $userdetails['icq'] = $user->icq;
284 if ($user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
285 $userdetails['skype'] = $user->skype;
287 if ($user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
288 $userdetails['yahoo'] = $user->yahoo;
290 if ($user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
291 $userdetails['aim'] = $user->aim;
293 if ($user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
294 $userdetails['msn'] = $user->msn;
297 if (!isset($hiddenfields['firstaccess']) or $isadmin) {
298 if ($user->firstaccess) {
299 $userdetails['firstaccess'] = $user->firstaccess;
300 } else {
301 $userdetails['firstaccess'] = 0;
304 if (!isset($hiddenfields['lastaccess']) or $isadmin) {
305 if ($user->lastaccess) {
306 $userdetails['lastaccess'] = $user->lastaccess;
307 } else {
308 $userdetails['lastaccess'] = 0;
312 if ($currentuser
313 or $canviewuseremail // this is a capability in course context, it will be false in usercontext
314 or $user->maildisplay == 1
315 or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER))) {
316 $userdetails['email'] = $user->email;;
319 if (!empty($CFG->usetags)) {
320 require_once($CFG->dirroot . '/tag/lib.php');
321 if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT) ) {
322 $userdetails['interests'] = $interests;
326 //Departement/Institution are not displayed on any profile, however you can get them from editing profile.
327 if ($isadmin or $currentuser) {
328 if ($user->institution) {
329 $userdetails['institution'] = $user->institution;
331 if (isset($user->department)) { //isset because it's ok to have department 0
332 $userdetails['department'] = $user->department;
336 if (!empty($course)) {
337 // not a big secret
338 $roles = get_user_roles($context, $user->id, false);
339 $userdetails['roles'] = array();
340 foreach ($roles as $role) {
341 $userdetails['roles'][] = array(
342 'roleid' => $role->roleid,
343 'name' => $role->name,
344 'shortname' => $role->shortname,
345 'sortorder' => $role->sortorder
350 // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group
351 if (!empty($course) && $canaccessallgroups) {
352 $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name,g.description');
353 $userdetails['groups'] = array();
354 foreach ($usergroups as $group) {
355 $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'group', 'description', $group->id);
356 $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name, 'description'=>$group->description);
359 //list of courses where the user is enrolled
360 if (!isset($hiddenfields['mycourses'])) {
361 $enrolledcourses = array();
362 if ($mycourses = enrol_get_users_courses($user->id, true)) {
363 foreach ($mycourses as $mycourse) {
364 if ($mycourse->category) {
365 $coursecontext = get_context_instance(CONTEXT_COURSE, $mycourse->id);
366 $enrolledcourse = array();
367 $enrolledcourse['id'] = $mycourse->id;
368 $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $mycourse->id)));
369 $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext));
370 $enrolledcourses[] = $enrolledcourse;
373 $userdetails['enrolledcourses'] = $enrolledcourses;
377 //user preferences
378 if ($currentuser) {
379 $preferences = array();
380 $userpreferences = get_user_preferences();
381 foreach($userpreferences as $prefname => $prefvalue) {
382 $preferences[] = array('name' => $prefname, 'value' => $prefvalue);
384 $userdetails['preferences'] = $preferences;
386 return $userdetails;
390 * Return a list of page types
391 * @param string $pagetype current page type
392 * @param stdClass $parentcontext Block's parent context
393 * @param stdClass $currentcontext Current context of block
395 function user_page_type_list($pagetype, $parentcontext, $currentcontext) {
396 return array('user-profile'=>get_string('page-user-profile', 'pagetype'));