[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/user/ -> lib.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * External user API
  19   *
  20   * @package   core_user
  21   * @copyright 2009 Moodle Pty Ltd (http://moodle.com)
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  
  26  /**
  27   * Creates a user
  28   *
  29   * @throws moodle_exception
  30   * @param stdClass $user user to create
  31   * @param bool $updatepassword if true, authentication plugin will update password.
  32   * @param bool $triggerevent set false if user_created event should not be triggred.
  33   *             This will not affect user_password_updated event triggering.
  34   * @return int id of the newly created user
  35   */
  36  function user_create_user($user, $updatepassword = true, $triggerevent = true) {
  37      global $CFG, $DB;
  38  
  39      // Set the timecreate field to the current time.
  40      if (!is_object($user)) {
  41          $user = (object) $user;
  42      }
  43  
  44      // Check username.
  45      if ($user->username !== core_text::strtolower($user->username)) {
  46          throw new moodle_exception('usernamelowercase');
  47      } else {
  48          if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
  49              throw new moodle_exception('invalidusername');
  50          }
  51      }
  52  
  53      // Save the password in a temp value for later.
  54      if ($updatepassword && isset($user->password)) {
  55  
  56          // Check password toward the password policy.
  57          if (!check_password_policy($user->password, $errmsg)) {
  58              throw new moodle_exception($errmsg);
  59          }
  60  
  61          $userpassword = $user->password;
  62          unset($user->password);
  63      }
  64  
  65      // Make sure calendartype, if set, is valid.
  66      if (!empty($user->calendartype)) {
  67          $availablecalendartypes = \core_calendar\type_factory::get_list_of_calendar_types();
  68          if (empty($availablecalendartypes[$user->calendartype])) {
  69              $user->calendartype = $CFG->calendartype;
  70          }
  71      } else {
  72          $user->calendartype = $CFG->calendartype;
  73      }
  74  
  75      // Apply default values for user preferences that are stored in users table.
  76      if (!isset($user->maildisplay)) {
  77          $user->maildisplay = $CFG->defaultpreference_maildisplay;
  78      }
  79      if (!isset($user->mailformat)) {
  80          $user->mailformat = $CFG->defaultpreference_mailformat;
  81      }
  82      if (!isset($user->maildigest)) {
  83          $user->maildigest = $CFG->defaultpreference_maildigest;
  84      }
  85      if (!isset($user->autosubscribe)) {
  86          $user->autosubscribe = $CFG->defaultpreference_autosubscribe;
  87      }
  88      if (!isset($user->trackforums)) {
  89          $user->trackforums = $CFG->defaultpreference_trackforums;
  90      }
  91  
  92      $user->timecreated = time();
  93      $user->timemodified = $user->timecreated;
  94  
  95      // Insert the user into the database.
  96      $newuserid = $DB->insert_record('user', $user);
  97  
  98      // Create USER context for this user.
  99      $usercontext = context_user::instance($newuserid);
 100  
 101      // Update user password if necessary.
 102      if (isset($userpassword)) {
 103          // Get full database user row, in case auth is default.
 104          $newuser = $DB->get_record('user', array('id' => $newuserid));
 105          $authplugin = get_auth_plugin($newuser->auth);
 106          $authplugin->user_update_password($newuser, $userpassword);
 107      }
 108  
 109      // Trigger event If required.
 110      if ($triggerevent) {
 111          \core\event\user_created::create_from_userid($newuserid)->trigger();
 112      }
 113  
 114      return $newuserid;
 115  }
 116  
 117  /**
 118   * Update a user with a user object (will compare against the ID)
 119   *
 120   * @throws moodle_exception
 121   * @param stdClass $user the user to update
 122   * @param bool $updatepassword if true, authentication plugin will update password.
 123   * @param bool $triggerevent set false if user_updated event should not be triggred.
 124   *             This will not affect user_password_updated event triggering.
 125   */
 126  function user_update_user($user, $updatepassword = true, $triggerevent = true) {
 127      global $DB;
 128  
 129      // Set the timecreate field to the current time.
 130      if (!is_object($user)) {
 131          $user = (object) $user;
 132      }
 133  
 134      // Check username.
 135      if (isset($user->username)) {
 136          if ($user->username !== core_text::strtolower($user->username)) {
 137              throw new moodle_exception('usernamelowercase');
 138          } else {
 139              if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
 140                  throw new moodle_exception('invalidusername');
 141              }
 142          }
 143      }
 144  
 145      // Unset password here, for updating later, if password update is required.
 146      if ($updatepassword && isset($user->password)) {
 147  
 148          // Check password toward the password policy.
 149          if (!check_password_policy($user->password, $errmsg)) {
 150              throw new moodle_exception($errmsg);
 151          }
 152  
 153          $passwd = $user->password;
 154          unset($user->password);
 155      }
 156  
 157      // Make sure calendartype, if set, is valid.
 158      if (!empty($user->calendartype)) {
 159          $availablecalendartypes = \core_calendar\type_factory::get_list_of_calendar_types();
 160          // If it doesn't exist, then unset this value, we do not want to update the user's value.
 161          if (empty($availablecalendartypes[$user->calendartype])) {
 162              unset($user->calendartype);
 163          }
 164      } else {
 165          // Unset this variable, must be an empty string, which we do not want to update the calendartype to.
 166          unset($user->calendartype);
 167      }
 168  
 169      $user->timemodified = time();
 170      $DB->update_record('user', $user);
 171  
 172      if ($updatepassword) {
 173          // Get full user record.
 174          $updateduser = $DB->get_record('user', array('id' => $user->id));
 175  
 176          // If password was set, then update its hash.
 177          if (isset($passwd)) {
 178              $authplugin = get_auth_plugin($updateduser->auth);
 179              if ($authplugin->can_change_password()) {
 180                  $authplugin->user_update_password($updateduser, $passwd);
 181              }
 182          }
 183      }
 184      // Trigger event if required.
 185      if ($triggerevent) {
 186          \core\event\user_updated::create_from_userid($user->id)->trigger();
 187      }
 188  }
 189  
 190  /**
 191   * Marks user deleted in internal user database and notifies the auth plugin.
 192   * Also unenrols user from all roles and does other cleanup.
 193   *
 194   * @todo Decide if this transaction is really needed (look for internal TODO:)
 195   * @param object $user Userobject before delete    (without system magic quotes)
 196   * @return boolean success
 197   */
 198  function user_delete_user($user) {
 199      return delete_user($user);
 200  }
 201  
 202  /**
 203   * Get users by id
 204   *
 205   * @param array $userids id of users to retrieve
 206   * @return array
 207   */
 208  function user_get_users_by_id($userids) {
 209      global $DB;
 210      return $DB->get_records_list('user', 'id', $userids);
 211  }
 212  
 213  /**
 214   * Returns the list of default 'displayable' fields
 215   *
 216   * Contains database field names but also names used to generate information, such as enrolledcourses
 217   *
 218   * @return array of user fields
 219   */
 220  function user_get_default_fields() {
 221      return array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
 222          'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
 223          'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
 224          'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
 225          'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
 226          'groups', 'roles', 'preferences', 'enrolledcourses'
 227      );
 228  }
 229  
 230  /**
 231   *
 232   * Give user record from mdl_user, build an array contains all user details.
 233   *
 234   * Warning: description file urls are 'webservice/pluginfile.php' is use.
 235   *          it can be changed with $CFG->moodlewstextformatlinkstoimagesfile
 236   *
 237   * @throws moodle_exception
 238   * @param stdClass $user user record from mdl_user
 239   * @param stdClass $course moodle course
 240   * @param array $userfields required fields
 241   * @return array|null
 242   */
 243  function user_get_user_details($user, $course = null, array $userfields = array()) {
 244      global $USER, $DB, $CFG;
 245      require_once($CFG->dirroot . "/user/profile/lib.php"); // Custom field library.
 246      require_once($CFG->dirroot . "/lib/filelib.php");      // File handling on description and friends.
 247  
 248      $defaultfields = user_get_default_fields();
 249  
 250      if (empty($userfields)) {
 251          $userfields = $defaultfields;
 252      }
 253  
 254      foreach ($userfields as $thefield) {
 255          if (!in_array($thefield, $defaultfields)) {
 256              throw new moodle_exception('invaliduserfield', 'error', '', $thefield);
 257          }
 258      }
 259  
 260      // Make sure id and fullname are included.
 261      if (!in_array('id', $userfields)) {
 262          $userfields[] = 'id';
 263      }
 264  
 265      if (!in_array('fullname', $userfields)) {
 266          $userfields[] = 'fullname';
 267      }
 268  
 269      if (!empty($course)) {
 270          $context = context_course::instance($course->id);
 271          $usercontext = context_user::instance($user->id);
 272          $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
 273      } else {
 274          $context = context_user::instance($user->id);
 275          $usercontext = $context;
 276          $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
 277      }
 278  
 279      $currentuser = ($user->id == $USER->id);
 280      $isadmin = is_siteadmin($USER);
 281  
 282      $showuseridentityfields = get_extra_user_fields($context);
 283  
 284      if (!empty($course)) {
 285          $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
 286      } else {
 287          $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
 288      }
 289      $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
 290      if (!empty($course)) {
 291          $canviewuseremail = has_capability('moodle/course:useremail', $context);
 292      } else {
 293          $canviewuseremail = false;
 294      }
 295      $cannotviewdescription   = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid' => $user->id));
 296      if (!empty($course)) {
 297          $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context);
 298      } else {
 299          $canaccessallgroups = false;
 300      }
 301  
 302      if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
 303          // Skip this user details.
 304          return null;
 305      }
 306  
 307      $userdetails = array();
 308      $userdetails['id'] = $user->id;
 309  
 310      if (($isadmin or $currentuser) and in_array('username', $userfields)) {
 311          $userdetails['username'] = $user->username;
 312      }
 313      if ($isadmin or $canviewfullnames) {
 314          if (in_array('firstname', $userfields)) {
 315              $userdetails['firstname'] = $user->firstname;
 316          }
 317          if (in_array('lastname', $userfields)) {
 318              $userdetails['lastname'] = $user->lastname;
 319          }
 320      }
 321      $userdetails['fullname'] = fullname($user);
 322  
 323      if (in_array('customfields', $userfields)) {
 324          $fields = $DB->get_recordset_sql("SELECT f.*
 325                                              FROM {user_info_field} f
 326                                              JOIN {user_info_category} c
 327                                                   ON f.categoryid=c.id
 328                                          ORDER BY c.sortorder ASC, f.sortorder ASC");
 329          $userdetails['customfields'] = array();
 330          foreach ($fields as $field) {
 331              require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
 332              $newfield = 'profile_field_'.$field->datatype;
 333              $formfield = new $newfield($field->id, $user->id);
 334              if ($formfield->is_visible() and !$formfield->is_empty()) {
 335                  $userdetails['customfields'][] =
 336                      array('name' => $formfield->field->name, 'value' => $formfield->data,
 337                          'type' => $field->datatype, 'shortname' => $formfield->field->shortname);
 338              }
 339          }
 340          $fields->close();
 341          // Unset customfields if it's empty.
 342          if (empty($userdetails['customfields'])) {
 343              unset($userdetails['customfields']);
 344          }
 345      }
 346  
 347      // Profile image.
 348      if (in_array('profileimageurl', $userfields)) {
 349          $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', null, '/', 'f1');
 350          $userdetails['profileimageurl'] = $profileimageurl->out(false);
 351      }
 352      if (in_array('profileimageurlsmall', $userfields)) {
 353          $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', null, '/', 'f2');
 354          $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false);
 355      }
 356  
 357      // Hidden user field.
 358      if ($canviewhiddenuserfields) {
 359          $hiddenfields = array();
 360          // Address, phone1 and phone2 not appears in hidden fields list but require viewhiddenfields capability
 361          // according to user/profile.php.
 362          if ($user->address && in_array('address', $userfields)) {
 363              $userdetails['address'] = $user->address;
 364          }
 365      } else {
 366          $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
 367      }
 368  
 369      if ($user->phone1 && in_array('phone1', $userfields) &&
 370              (in_array('phone1', $showuseridentityfields) or $canviewhiddenuserfields)) {
 371          $userdetails['phone1'] = $user->phone1;
 372      }
 373      if ($user->phone2 && in_array('phone2', $userfields) &&
 374              (in_array('phone2', $showuseridentityfields) or $canviewhiddenuserfields)) {
 375          $userdetails['phone2'] = $user->phone2;
 376      }
 377  
 378      if (isset($user->description) &&
 379          ((!isset($hiddenfields['description']) && !$cannotviewdescription) or $isadmin)) {
 380          if (in_array('description', $userfields)) {
 381              // Always return the descriptionformat if description is requested.
 382              list($userdetails['description'], $userdetails['descriptionformat']) =
 383                      external_format_text($user->description, $user->descriptionformat,
 384                              $usercontext->id, 'user', 'profile', null);
 385          }
 386      }
 387  
 388      if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) {
 389          $userdetails['country'] = $user->country;
 390      }
 391  
 392      if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) {
 393          $userdetails['city'] = $user->city;
 394      }
 395  
 396      if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) {
 397          $url = $user->url;
 398          if (strpos($user->url, '://') === false) {
 399              $url = 'http://'. $url;
 400          }
 401          $user->url = clean_param($user->url, PARAM_URL);
 402          $userdetails['url'] = $user->url;
 403      }
 404  
 405      if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) {
 406          $userdetails['icq'] = $user->icq;
 407      }
 408  
 409      if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) {
 410          $userdetails['skype'] = $user->skype;
 411      }
 412      if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) {
 413          $userdetails['yahoo'] = $user->yahoo;
 414      }
 415      if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) {
 416          $userdetails['aim'] = $user->aim;
 417      }
 418      if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) {
 419          $userdetails['msn'] = $user->msn;
 420      }
 421  
 422      if (in_array('firstaccess', $userfields) && (!isset($hiddenfields['firstaccess']) or $isadmin)) {
 423          if ($user->firstaccess) {
 424              $userdetails['firstaccess'] = $user->firstaccess;
 425          } else {
 426              $userdetails['firstaccess'] = 0;
 427          }
 428      }
 429      if (in_array('lastaccess', $userfields) && (!isset($hiddenfields['lastaccess']) or $isadmin)) {
 430          if ($user->lastaccess) {
 431              $userdetails['lastaccess'] = $user->lastaccess;
 432          } else {
 433              $userdetails['lastaccess'] = 0;
 434          }
 435      }
 436  
 437      if (in_array('email', $userfields) && ($isadmin // The admin is allowed the users email.
 438        or $currentuser // Of course the current user is as well.
 439        or $canviewuseremail  // This is a capability in course context, it will be false in usercontext.
 440        or in_array('email', $showuseridentityfields)
 441        or $user->maildisplay == 1
 442        or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
 443          $userdetails['email'] = $user->email;
 444      }
 445  
 446      if (in_array('interests', $userfields) && !empty($CFG->usetags)) {
 447          require_once($CFG->dirroot . '/tag/lib.php');
 448          if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT) ) {
 449              $userdetails['interests'] = $interests;
 450          }
 451      }
 452  
 453      // Departement/Institution/Idnumber are not displayed on any profile, however you can get them from editing profile.
 454      if ($isadmin or $currentuser or in_array('idnumber', $showuseridentityfields)) {
 455          if (in_array('idnumber', $userfields) && $user->idnumber) {
 456              $userdetails['idnumber'] = $user->idnumber;
 457          }
 458      }
 459      if ($isadmin or $currentuser or in_array('institution', $showuseridentityfields)) {
 460          if (in_array('institution', $userfields) && $user->institution) {
 461              $userdetails['institution'] = $user->institution;
 462          }
 463      }
 464      if ($isadmin or $currentuser or in_array('department', $showuseridentityfields)) {
 465          if (in_array('department', $userfields) && isset($user->department)) { // Isset because it's ok to have department 0.
 466              $userdetails['department'] = $user->department;
 467          }
 468      }
 469  
 470      if (in_array('roles', $userfields) && !empty($course)) {
 471          // Not a big secret.
 472          $roles = get_user_roles($context, $user->id, false);
 473          $userdetails['roles'] = array();
 474          foreach ($roles as $role) {
 475              $userdetails['roles'][] = array(
 476                  'roleid'       => $role->roleid,
 477                  'name'         => $role->name,
 478                  'shortname'    => $role->shortname,
 479                  'sortorder'    => $role->sortorder
 480              );
 481          }
 482      }
 483  
 484      // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group.
 485      if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) {
 486          $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid,
 487                  'g.id, g.name,g.description,g.descriptionformat');
 488          $userdetails['groups'] = array();
 489          foreach ($usergroups as $group) {
 490              list($group->description, $group->descriptionformat) =
 491                  external_format_text($group->description, $group->descriptionformat,
 492                          $context->id, 'group', 'description', $group->id);
 493              $userdetails['groups'][] = array('id' => $group->id, 'name' => $group->name,
 494                  'description' => $group->description, 'descriptionformat' => $group->descriptionformat);
 495          }
 496      }
 497      // List of courses where the user is enrolled.
 498      if (in_array('enrolledcourses', $userfields) && !isset($hiddenfields['mycourses'])) {
 499          $enrolledcourses = array();
 500          if ($mycourses = enrol_get_users_courses($user->id, true)) {
 501              foreach ($mycourses as $mycourse) {
 502                  if ($mycourse->category) {
 503                      $coursecontext = context_course::instance($mycourse->id);
 504                      $enrolledcourse = array();
 505                      $enrolledcourse['id'] = $mycourse->id;
 506                      $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => $coursecontext));
 507                      $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext));
 508                      $enrolledcourses[] = $enrolledcourse;
 509                  }
 510              }
 511              $userdetails['enrolledcourses'] = $enrolledcourses;
 512          }
 513      }
 514  
 515      // User preferences.
 516      if (in_array('preferences', $userfields) && $currentuser) {
 517          $preferences = array();
 518          $userpreferences = get_user_preferences();
 519          foreach ($userpreferences as $prefname => $prefvalue) {
 520              $preferences[] = array('name' => $prefname, 'value' => $prefvalue);
 521          }
 522          $userdetails['preferences'] = $preferences;
 523      }
 524  
 525      return $userdetails;
 526  }
 527  
 528  /**
 529   * Tries to obtain user details, either recurring directly to the user's system profile
 530   * or through one of the user's course enrollments (course profile).
 531   *
 532   * @param stdClass $user The user.
 533   * @return array if unsuccessful or the allowed user details.
 534   */
 535  function user_get_user_details_courses($user) {
 536      global $USER;
 537      $userdetails = null;
 538  
 539      // Get the courses that the user is enrolled in (only active).
 540      $courses = enrol_get_users_courses($user->id, true);
 541  
 542      $systemprofile = false;
 543      if (can_view_user_details_cap($user) || ($user->id == $USER->id) || has_coursecontact_role($user->id)) {
 544          $systemprofile = true;
 545      }
 546  
 547      // Try using system profile.
 548      if ($systemprofile) {
 549          $userdetails = user_get_user_details($user, null);
 550      } else {
 551          // Try through course profile.
 552          foreach ($courses as $course) {
 553              if (can_view_user_details_cap($user, $course) || ($user->id == $USER->id) || has_coursecontact_role($user->id)) {
 554                  $userdetails = user_get_user_details($user, $course);
 555              }
 556          }
 557      }
 558  
 559      return $userdetails;
 560  }
 561  
 562  /**
 563   * Check if $USER have the necessary capabilities to obtain user details.
 564   *
 565   * @param stdClass $user
 566   * @param stdClass $course if null then only consider system profile otherwise also consider the course's profile.
 567   * @return bool true if $USER can view user details.
 568   */
 569  function can_view_user_details_cap($user, $course = null) {
 570      // Check $USER has the capability to view the user details at user context.
 571      $usercontext = context_user::instance($user->id);
 572      $result = has_capability('moodle/user:viewdetails', $usercontext);
 573      // Otherwise can $USER see them at course context.
 574      if (!$result && !empty($course)) {
 575          $context = context_course::instance($course->id);
 576          $result = has_capability('moodle/user:viewdetails', $context);
 577      }
 578      return $result;
 579  }
 580  
 581  /**
 582   * Return a list of page types
 583   * @param string $pagetype current page type
 584   * @param stdClass $parentcontext Block's parent context
 585   * @param stdClass $currentcontext Current context of block
 586   * @return array
 587   */
 588  function user_page_type_list($pagetype, $parentcontext, $currentcontext) {
 589      return array('user-profile' => get_string('page-user-profile', 'pagetype'));
 590  }
 591  
 592  /**
 593   * Count the number of failed login attempts for the given user, since last successful login.
 594   *
 595   * @param int|stdclass $user user id or object.
 596   * @param bool $reset Resets failed login count, if set to true.
 597   *
 598   * @return int number of failed login attempts since the last successful login.
 599   */
 600  function user_count_login_failures($user, $reset = true) {
 601      global $DB;
 602  
 603      if (!is_object($user)) {
 604          $user = $DB->get_record('user', array('id' => $user), '*', MUST_EXIST);
 605      }
 606      if ($user->deleted) {
 607          // Deleted user, nothing to do.
 608          return 0;
 609      }
 610      $count = get_user_preferences('login_failed_count_since_success', 0, $user);
 611      if ($reset) {
 612          set_user_preference('login_failed_count_since_success', 0, $user);
 613      }
 614      return $count;
 615  }
 616  
 617  /**
 618   * Converts a string into a flat array of links, where each link is a
 619   * stdClass with fields url, title, pix, and imgsrc.
 620   *
 621   * @param string $text the menu items definition
 622   * @param moodle_page $page the current page
 623   * @return array
 624   */
 625  function user_convert_text_to_menu_items($text, $page) {
 626      global $OUTPUT, $CFG;
 627  
 628      $lines = explode("\n", $text);
 629      $items = array();
 630      $lastchild = null;
 631      $lastdepth = null;
 632      $lastsort = 0;
 633      $children = array();
 634      foreach ($lines as $line) {
 635          $line = trim($line);
 636          $bits = explode('|', $line, 3);
 637          if (!array_key_exists(0, $bits) or empty($bits[0])) {
 638              // Every item must have a name to be valid.
 639              continue;
 640          } else {
 641              $bits[0] = ltrim($bits[0], '-');
 642          }
 643  
 644          // Create the child.
 645          $child = new stdClass();
 646  
 647          // Name processing.
 648          $namebits = explode(',', $bits[0], 2);
 649          if (count($namebits) == 2) {
 650              // Treat this as a language string.
 651              $child->title = get_string($namebits[0], $namebits[1]);
 652          } else {
 653              // Use it as is, don't even clean it.
 654              $child->title = $bits[0];
 655          }
 656  
 657          // URL processing.
 658          if (!array_key_exists(1, $bits) or empty($bits[1])) {
 659              // Set the url to null.
 660              $bits[1] = null;
 661          } else {
 662              // Make sure the url is a moodle url.
 663              $bits[1] = new moodle_url(trim($bits[1]));
 664          }
 665          $child->url = $bits[1];
 666  
 667          // PIX processing.
 668          $pixpath = "t/edit";
 669          if (!array_key_exists(2, $bits) or empty($bits[2])) {
 670              // Use the default.
 671              $child->pix = $pixpath;
 672          } else {
 673              // Check for the specified image existing.
 674              $pixpath = "t/" . $bits[2];
 675              if ($page->theme->resolve_image_location($pixpath, 'moodle', true)) {
 676                  // Use the image.
 677                  $child->pix = $pixpath;
 678              } else {
 679                  // Treat it like a URL.
 680                  $child->pix = null;
 681                  $child->imgsrc = $bits[2];
 682              }
 683          }
 684  
 685          // Add this child to the list of children.
 686          $children[] = $child;
 687      }
 688      return $children;
 689  }
 690  
 691  /**
 692   * Get a list of essential user navigation items.
 693   *
 694   * @param stdclass $user user object.
 695   * @param moodle_page $page page object.
 696   * @return stdClass $returnobj navigation information object, where:
 697   *
 698   *      $returnobj->navitems    array    array of links where each link is a
 699   *                                       stdClass with fields url, title, and
 700   *                                       pix
 701   *      $returnobj->metadata    array    array of useful user metadata to be
 702   *                                       used when constructing navigation;
 703   *                                       fields include:
 704   *
 705   *          ROLE FIELDS
 706   *          asotherrole    bool    whether viewing as another role
 707   *          rolename       string  name of the role
 708   *
 709   *          USER FIELDS
 710   *          These fields are for the currently-logged in user, or for
 711   *          the user that the real user is currently logged in as.
 712   *
 713   *          userid         int        the id of the user in question
 714   *          userfullname   string     the user's full name
 715   *          userprofileurl moodle_url the url of the user's profile
 716   *          useravatar     string     a HTML fragment - the rendered
 717   *                                    user_picture for this user
 718   *          userloginfail  string     an error string denoting the number
 719   *                                    of login failures since last login
 720   *
 721   *          "REAL USER" FIELDS
 722   *          These fields are for when asotheruser is true, and
 723   *          correspond to the underlying "real user".
 724   *
 725   *          asotheruser        bool    whether viewing as another user
 726   *          realuserid         int        the id of the user in question
 727   *          realuserfullname   string     the user's full name
 728   *          realuserprofileurl moodle_url the url of the user's profile
 729   *          realuseravatar     string     a HTML fragment - the rendered
 730   *                                        user_picture for this user
 731   *
 732   *          MNET PROVIDER FIELDS
 733   *          asmnetuser            bool   whether viewing as a user from an
 734   *                                       MNet provider
 735   *          mnetidprovidername    string name of the MNet provider
 736   *          mnetidproviderwwwroot string URL of the MNet provider
 737   */
 738  function user_get_user_navigation_info($user, $page) {
 739      global $OUTPUT, $DB, $SESSION, $CFG;
 740  
 741      $returnobject = new stdClass();
 742      $returnobject->navitems = array();
 743      $returnobject->metadata = array();
 744  
 745      $course = $page->course;
 746  
 747      // Query the environment.
 748      $context = context_course::instance($course->id);
 749  
 750      // Get basic user metadata.
 751      $returnobject->metadata['userid'] = $user->id;
 752      $returnobject->metadata['userfullname'] = fullname($user, true);
 753      $returnobject->metadata['userprofileurl'] = new moodle_url('/user/profile.php', array(
 754          'id' => $user->id
 755      ));
 756      $returnobject->metadata['useravatar'] = $OUTPUT->user_picture (
 757          $user,
 758          array(
 759              'link' => false,
 760              'visibletoscreenreaders' => false
 761          )
 762      );
 763      // Build a list of items for a regular user.
 764  
 765      // Query MNet status.
 766      if ($returnobject->metadata['asmnetuser'] = is_mnet_remote_user($user)) {
 767          $mnetidprovider = $DB->get_record('mnet_host', array('id' => $user->mnethostid));
 768          $returnobject->metadata['mnetidprovidername'] = $mnetidprovider->name;
 769          $returnobject->metadata['mnetidproviderwwwroot'] = $mnetidprovider->wwwroot;
 770      }
 771  
 772      // Did the user just log in?
 773      if (isset($SESSION->justloggedin)) {
 774          // Don't unset this flag as login_info still needs it.
 775          if (!empty($CFG->displayloginfailures)) {
 776              // We're already in /user/lib.php, so we don't need to include.
 777              if ($count = user_count_login_failures($user)) {
 778  
 779                  // Get login failures string.
 780                  $a = new stdClass();
 781                  $a->attempts = html_writer::tag('span', $count, array('class' => 'value'));
 782                  $returnobject->metadata['userloginfail'] =
 783                      get_string('failedloginattempts', '', $a);
 784  
 785              }
 786          }
 787      }
 788  
 789      // Links: My Home.
 790      $myhome = new stdClass();
 791      $myhome->url = new moodle_url('/my/');
 792      $myhome->title = get_string('mymoodle', 'admin');
 793      $myhome->pix = "i/course";
 794      $returnobject->navitems[] = $myhome;
 795  
 796      // Links: My Profile.
 797      $myprofile = new stdClass();
 798      $myprofile->url = new moodle_url('/user/profile.php', array('id' => $user->id));
 799      $myprofile->title = get_string('myprofile');
 800      $myprofile->pix = "i/user";
 801      $returnobject->navitems[] = $myprofile;
 802  
 803      // Links: Role-return or logout link.
 804      $lastobj = null;
 805      $buildlogout = true;
 806      $returnobject->metadata['asotherrole'] = false;
 807      if (is_role_switched($course->id)) {
 808          if ($role = $DB->get_record('role', array('id' => $user->access['rsw'][$context->path]))) {
 809              // Build role-return link instead of logout link.
 810              $rolereturn = new stdClass();
 811              $rolereturn->url = new moodle_url('/course/switchrole.php', array(
 812                  'id' => $course->id,
 813                  'sesskey' => sesskey(),
 814                  'switchrole' => 0,
 815                  'returnurl' => $page->url->out_as_local_url(false)
 816              ));
 817              $rolereturn->pix = "a/logout";
 818              $rolereturn->title = get_string('switchrolereturn');
 819              $lastobj = $rolereturn;
 820  
 821              $returnobject->metadata['asotherrole'] = true;
 822              $returnobject->metadata['rolename'] = role_get_name($role, $context);
 823  
 824              $buildlogout = false;
 825          }
 826      }
 827  
 828      if ($returnobject->metadata['asotheruser'] = \core\session\manager::is_loggedinas()) {
 829          $realuser = \core\session\manager::get_realuser();
 830  
 831          // Save values for the real user, as $user will be full of data for the
 832          // user the user is disguised as.
 833          $returnobject->metadata['realuserid'] = $realuser->id;
 834          $returnobject->metadata['realuserfullname'] = fullname($realuser, true);
 835          $returnobject->metadata['realuserprofileurl'] = new moodle_url('/user/profile.php', array(
 836              'id' => $realuser->id
 837          ));
 838          $returnobject->metadata['realuseravatar'] = $OUTPUT->user_picture (
 839              $realuser,
 840              array(
 841                  'link' => false,
 842                  'visibletoscreenreaders' => false
 843              )
 844          );
 845  
 846          // Build a user-revert link.
 847          $userrevert = new stdClass();
 848          $userrevert->url = new moodle_url('/course/loginas.php', array(
 849              'id' => $course->id,
 850              'sesskey' => sesskey()
 851          ));
 852          $userrevert->pix = "a/logout";
 853          $userrevert->title = get_string('logout');
 854          $lastobj = $userrevert;
 855  
 856          $buildlogout = false;
 857      }
 858  
 859      if ($buildlogout) {
 860          // Build a logout link.
 861          $logout = new stdClass();
 862          $logout->url = new moodle_url('/login/logout.php', array('sesskey' => sesskey()));
 863          $logout->pix = "a/logout";
 864          $logout->title = get_string('logout');
 865          $lastobj = $logout;
 866      }
 867  
 868      // Before we add the last item (usually a logout link), add any
 869      // custom-defined items.
 870      $customitems = user_convert_text_to_menu_items($CFG->customusermenuitems, $page);
 871      foreach ($customitems as $item) {
 872          $returnobject->navitems[] = $item;
 873      }
 874  
 875      // Add the last item to the list.
 876      if (!is_null($lastobj)) {
 877          $returnobject->navitems[] = $lastobj;
 878      }
 879  
 880      return $returnobject;
 881  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1