[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/classes/ -> user.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   * User class
  19   *
  20   * @package    core
  21   * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  /**
  28   * User class to access user details.
  29   *
  30   * @todo       move api's from user/lib.php and depreciate old ones.
  31   * @package    core
  32   * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  class core_user {
  36      /**
  37       * No reply user id.
  38       */
  39      const NOREPLY_USER = -10;
  40  
  41      /**
  42       * Support user id.
  43       */
  44      const SUPPORT_USER = -20;
  45  
  46      /** @var stdClass keep record of noreply user */
  47      public static $noreplyuser = false;
  48  
  49      /** @var stdClass keep record of support user */
  50      public static $supportuser = false;
  51  
  52      /** @var array store user fields properties cache. */
  53      protected static $propertiescache = null;
  54  
  55      /**
  56       * Return user object from db or create noreply or support user,
  57       * if userid matches corse_user::NOREPLY_USER or corse_user::SUPPORT_USER
  58       * respectively. If userid is not found, then return false.
  59       *
  60       * @param int $userid user id
  61       * @param string $fields A comma separated list of user fields to be returned, support and noreply user
  62       *                       will not be filtered by this.
  63       * @param int $strictness IGNORE_MISSING means compatible mode, false returned if user not found, debug message if more found;
  64       *                        IGNORE_MULTIPLE means return first user, ignore multiple user records found(not recommended);
  65       *                        MUST_EXIST means throw an exception if no user record or multiple records found.
  66       * @return stdClass|bool user record if found, else false.
  67       * @throws dml_exception if user record not found and respective $strictness is set.
  68       */
  69      public static function get_user($userid, $fields = '*', $strictness = IGNORE_MISSING) {
  70          global $DB;
  71  
  72          // If noreply user then create fake record and return.
  73          switch ($userid) {
  74              case self::NOREPLY_USER:
  75                  return self::get_noreply_user();
  76                  break;
  77              case self::SUPPORT_USER:
  78                  return self::get_support_user();
  79                  break;
  80              default:
  81                  return $DB->get_record('user', array('id' => $userid), $fields, $strictness);
  82          }
  83      }
  84  
  85  
  86      /**
  87       * Return user object from db based on their username.
  88       *
  89       * @param string $username The username of the user searched.
  90       * @param string $fields A comma separated list of user fields to be returned, support and noreply user.
  91       * @param int $mnethostid The id of the remote host.
  92       * @param int $strictness IGNORE_MISSING means compatible mode, false returned if user not found, debug message if more found;
  93       *                        IGNORE_MULTIPLE means return first user, ignore multiple user records found(not recommended);
  94       *                        MUST_EXIST means throw an exception if no user record or multiple records found.
  95       * @return stdClass|bool user record if found, else false.
  96       * @throws dml_exception if user record not found and respective $strictness is set.
  97       */
  98      public static function get_user_by_username($username, $fields = '*', $mnethostid = null, $strictness = IGNORE_MISSING) {
  99          global $DB, $CFG;
 100  
 101          // Because we use the username as the search criteria, we must also restrict our search based on mnet host.
 102          if (empty($mnethostid)) {
 103              // If empty, we restrict to local users.
 104              $mnethostid = $CFG->mnet_localhost_id;
 105          }
 106  
 107          return $DB->get_record('user', array('username' => $username, 'mnethostid' => $mnethostid), $fields, $strictness);
 108      }
 109  
 110      /**
 111       * Helper function to return dummy noreply user record.
 112       *
 113       * @return stdClass
 114       */
 115      protected static function get_dummy_user_record() {
 116          global $CFG;
 117  
 118          $dummyuser = new stdClass();
 119          $dummyuser->id = self::NOREPLY_USER;
 120          $dummyuser->email = $CFG->noreplyaddress;
 121          $dummyuser->firstname = get_string('noreplyname');
 122          $dummyuser->username = 'noreply';
 123          $dummyuser->lastname = '';
 124          $dummyuser->confirmed = 1;
 125          $dummyuser->suspended = 0;
 126          $dummyuser->deleted = 0;
 127          $dummyuser->picture = 0;
 128          $dummyuser->auth = 'manual';
 129          $dummyuser->firstnamephonetic = '';
 130          $dummyuser->lastnamephonetic = '';
 131          $dummyuser->middlename = '';
 132          $dummyuser->alternatename = '';
 133          $dummyuser->imagealt = '';
 134          return $dummyuser;
 135      }
 136  
 137      /**
 138       * Return noreply user record, this is currently used in messaging
 139       * system only for sending messages from noreply email.
 140       * It will return record of $CFG->noreplyuserid if set else return dummy
 141       * user object with hard-coded $user->emailstop = 1 so noreply can be sent to user.
 142       *
 143       * @return stdClass user record.
 144       */
 145      public static function get_noreply_user() {
 146          global $CFG;
 147  
 148          if (!empty(self::$noreplyuser)) {
 149              return self::$noreplyuser;
 150          }
 151  
 152          // If noreply user is set then use it, else create one.
 153          if (!empty($CFG->noreplyuserid)) {
 154              self::$noreplyuser = self::get_user($CFG->noreplyuserid);
 155              self::$noreplyuser->emailstop = 1; // Force msg stop for this user.
 156              return self::$noreplyuser;
 157          } else {
 158              // Do not cache the dummy user record to avoid language internationalization issues.
 159              $noreplyuser = self::get_dummy_user_record();
 160              $noreplyuser->maildisplay = '1'; // Show to all.
 161              $noreplyuser->emailstop = 1;
 162              return $noreplyuser;
 163          }
 164      }
 165  
 166      /**
 167       * Return support user record, this is currently used in messaging
 168       * system only for sending messages to support email.
 169       * $CFG->supportuserid is set then returns user record
 170       * $CFG->supportemail is set then return dummy record with $CFG->supportemail
 171       * else return admin user record with hard-coded $user->emailstop = 0, so user
 172       * gets support message.
 173       *
 174       * @return stdClass user record.
 175       */
 176      public static function get_support_user() {
 177          global $CFG;
 178  
 179          if (!empty(self::$supportuser)) {
 180              return self::$supportuser;
 181          }
 182  
 183          // If custom support user is set then use it, else if supportemail is set then use it, else use noreply.
 184          if (!empty($CFG->supportuserid)) {
 185              self::$supportuser = self::get_user($CFG->supportuserid, '*', MUST_EXIST);
 186          } else if (empty(self::$supportuser) && !empty($CFG->supportemail)) {
 187              // Try sending it to support email if support user is not set.
 188              $supportuser = self::get_dummy_user_record();
 189              $supportuser->id = self::SUPPORT_USER;
 190              $supportuser->email = $CFG->supportemail;
 191              if ($CFG->supportname) {
 192                  $supportuser->firstname = $CFG->supportname;
 193              }
 194              $supportuser->username = 'support';
 195              $supportuser->maildisplay = '1'; // Show to all.
 196              // Unset emailstop to make sure support message is sent.
 197              $supportuser->emailstop = 0;
 198              return $supportuser;
 199          }
 200  
 201          // Send support msg to admin user if nothing is set above.
 202          if (empty(self::$supportuser)) {
 203              self::$supportuser = get_admin();
 204          }
 205  
 206          // Unset emailstop to make sure support message is sent.
 207          self::$supportuser->emailstop = 0;
 208          return self::$supportuser;
 209      }
 210  
 211      /**
 212       * Reset self::$noreplyuser and self::$supportuser.
 213       * This is only used by phpunit, and there is no other use case for this function.
 214       * Please don't use it outside phpunit.
 215       */
 216      public static function reset_internal_users() {
 217          if (PHPUNIT_TEST) {
 218              self::$noreplyuser = false;
 219              self::$supportuser = false;
 220          } else {
 221              debugging('reset_internal_users() should not be used outside phpunit.', DEBUG_DEVELOPER);
 222          }
 223      }
 224  
 225      /**
 226       * Return true is user id is greater than self::NOREPLY_USER and
 227       * alternatively check db.
 228       *
 229       * @param int $userid user id.
 230       * @param bool $checkdb if true userid will be checked in db. By default it's false, and
 231       *                      userid is compared with NOREPLY_USER for performance.
 232       * @return bool true is real user else false.
 233       */
 234      public static function is_real_user($userid, $checkdb = false) {
 235          global $DB;
 236  
 237          if ($userid < 0) {
 238              return false;
 239          }
 240          if ($checkdb) {
 241              return $DB->record_exists('user', array('id' => $userid));
 242          } else {
 243              return true;
 244          }
 245      }
 246  
 247      /**
 248       * Check if the given user is an active user in the site.
 249       *
 250       * @param  stdClass  $user         user object
 251       * @param  boolean $checksuspended whether to check if the user has the account suspended
 252       * @param  boolean $checknologin   whether to check if the user uses the nologin auth method
 253       * @throws moodle_exception
 254       * @since  Moodle 3.0
 255       */
 256      public static function require_active_user($user, $checksuspended = false, $checknologin = false) {
 257  
 258          if (!self::is_real_user($user->id)) {
 259              throw new moodle_exception('invaliduser', 'error');
 260          }
 261  
 262          if ($user->deleted) {
 263              throw new moodle_exception('userdeleted');
 264          }
 265  
 266          if (empty($user->confirmed)) {
 267              throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username);
 268          }
 269  
 270          if (isguestuser($user)) {
 271              throw new moodle_exception('guestsarenotallowed', 'error');
 272          }
 273  
 274          if ($checksuspended and $user->suspended) {
 275              throw new moodle_exception('suspended', 'auth');
 276          }
 277  
 278          if ($checknologin and $user->auth == 'nologin') {
 279              throw new moodle_exception('suspended', 'auth');
 280          }
 281      }
 282  
 283      /**
 284       * Updates the provided users profile picture based upon the expected fields returned from the edit or edit_advanced forms.
 285       *
 286       * @param stdClass $usernew An object that contains some information about the user being updated
 287       * @param array $filemanageroptions
 288       * @return bool True if the user was updated, false if it stayed the same.
 289       */
 290      public static function update_picture(stdClass $usernew, $filemanageroptions = array()) {
 291          global $CFG, $DB;
 292          require_once("$CFG->libdir/gdlib.php");
 293  
 294          $context = context_user::instance($usernew->id, MUST_EXIST);
 295          $user = core_user::get_user($usernew->id, 'id, picture', MUST_EXIST);
 296  
 297          $newpicture = $user->picture;
 298          // Get file_storage to process files.
 299          $fs = get_file_storage();
 300          if (!empty($usernew->deletepicture)) {
 301              // The user has chosen to delete the selected users picture.
 302              $fs->delete_area_files($context->id, 'user', 'icon'); // Drop all images in area.
 303              $newpicture = 0;
 304  
 305          } else {
 306              // Save newly uploaded file, this will avoid context mismatch for newly created users.
 307              file_save_draft_area_files($usernew->imagefile, $context->id, 'user', 'newicon', 0, $filemanageroptions);
 308              if (($iconfiles = $fs->get_area_files($context->id, 'user', 'newicon')) && count($iconfiles) == 2) {
 309                  // Get file which was uploaded in draft area.
 310                  foreach ($iconfiles as $file) {
 311                      if (!$file->is_directory()) {
 312                          break;
 313                      }
 314                  }
 315                  // Copy file to temporary location and the send it for processing icon.
 316                  if ($iconfile = $file->copy_content_to_temp()) {
 317                      // There is a new image that has been uploaded.
 318                      // Process the new image and set the user to make use of it.
 319                      // NOTE: Uploaded images always take over Gravatar.
 320                      $newpicture = (int)process_new_icon($context, 'user', 'icon', 0, $iconfile);
 321                      // Delete temporary file.
 322                      @unlink($iconfile);
 323                      // Remove uploaded file.
 324                      $fs->delete_area_files($context->id, 'user', 'newicon');
 325                  } else {
 326                      // Something went wrong while creating temp file.
 327                      // Remove uploaded file.
 328                      $fs->delete_area_files($context->id, 'user', 'newicon');
 329                      return false;
 330                  }
 331              }
 332          }
 333  
 334          if ($newpicture != $user->picture) {
 335              $DB->set_field('user', 'picture', $newpicture, array('id' => $user->id));
 336              return true;
 337          } else {
 338              return false;
 339          }
 340      }
 341  
 342  
 343  
 344      /**
 345       * Definition of user profile fields and the expected parameter type for data validation.
 346       *
 347       * array(
 348       *     'property_name' => array(       // The user property to be checked. Should match the field on the user table.
 349       *          'null' => NULL_ALLOWED,    // Defaults to NULL_NOT_ALLOWED. Takes NULL_NOT_ALLOWED or NULL_ALLOWED.
 350       *          'type' => PARAM_TYPE,      // Expected parameter type of the user field.
 351       *          'choices' => array(1, 2..) // An array of accepted values of the user field.
 352       *          'default' => $CFG->setting // An default value for the field.
 353       *     )
 354       * )
 355       *
 356       * The fields choices and default are optional.
 357       *
 358       * @return void
 359       */
 360      protected static function fill_properties_cache() {
 361          global $CFG;
 362          if (self::$propertiescache !== null) {
 363              return;
 364          }
 365  
 366          // Array of user fields properties and expected parameters.
 367          // Every new field on the user table should be added here otherwise it won't be validated.
 368          $fields = array();
 369          $fields['id'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 370          $fields['auth'] = array('type' => PARAM_AUTH, 'null' => NULL_NOT_ALLOWED);
 371          $fields['confirmed'] = array('type' => PARAM_BOOL, 'null' => NULL_NOT_ALLOWED);
 372          $fields['policyagreed'] = array('type' => PARAM_BOOL, 'null' => NULL_NOT_ALLOWED);
 373          $fields['deleted'] = array('type' => PARAM_BOOL, 'null' => NULL_NOT_ALLOWED);
 374          $fields['suspended'] = array('type' => PARAM_BOOL, 'null' => NULL_NOT_ALLOWED);
 375          $fields['mnethostid'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 376          $fields['username'] = array('type' => PARAM_USERNAME, 'null' => NULL_NOT_ALLOWED);
 377          $fields['password'] = array('type' => PARAM_RAW, 'null' => NULL_NOT_ALLOWED);
 378          $fields['idnumber'] = array('type' => PARAM_RAW, 'null' => NULL_NOT_ALLOWED);
 379          $fields['firstname'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 380          $fields['lastname'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 381          $fields['surname'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 382          $fields['email'] = array('type' => PARAM_RAW_TRIMMED, 'null' => NULL_NOT_ALLOWED);
 383          $fields['emailstop'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 384          $fields['icq'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 385          $fields['skype'] = array('type' => PARAM_NOTAGS, 'null' => NULL_ALLOWED);
 386          $fields['aim'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 387          $fields['yahoo'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 388          $fields['msn'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 389          $fields['phone1'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 390          $fields['phone2'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 391          $fields['institution'] = array('type' => PARAM_TEXT, 'null' => NULL_NOT_ALLOWED);
 392          $fields['department'] = array('type' => PARAM_TEXT, 'null' => NULL_NOT_ALLOWED);
 393          $fields['address'] = array('type' => PARAM_TEXT, 'null' => NULL_NOT_ALLOWED);
 394          $fields['city'] = array('type' => PARAM_TEXT, 'null' => NULL_NOT_ALLOWED, 'default' => $CFG->defaultcity);
 395          $fields['country'] = array('type' => PARAM_ALPHA, 'null' => NULL_NOT_ALLOWED, 'default' => $CFG->country,
 396                  'choices' => array_merge(array('' => ''), get_string_manager()->get_list_of_countries(true, true)));
 397          $fields['lang'] = array('type' => PARAM_LANG, 'null' => NULL_NOT_ALLOWED, 'default' => $CFG->lang,
 398                  'choices' => array_merge(array('' => ''), get_string_manager()->get_list_of_translations(false)));
 399          $fields['calendartype'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED, 'default' => $CFG->calendartype,
 400                  'choices' => array_merge(array('' => ''), \core_calendar\type_factory::get_list_of_calendar_types()));
 401          $fields['theme'] = array('type' => PARAM_THEME, 'null' => NULL_NOT_ALLOWED,
 402                  'default' => theme_config::DEFAULT_THEME, 'choices' => array_merge(array('' => ''), get_list_of_themes()));
 403          $fields['timezone'] = array('type' => PARAM_TIMEZONE, 'null' => NULL_NOT_ALLOWED,
 404                  'default' => core_date::get_server_timezone()); // Must not use choices here: timezones can come and go.
 405          $fields['firstaccess'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 406          $fields['lastaccess'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 407          $fields['lastlogin'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 408          $fields['currentlogin'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 409          $fields['lastip'] = array('type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED);
 410          $fields['secret'] = array('type' => PARAM_RAW, 'null' => NULL_NOT_ALLOWED);
 411          $fields['picture'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 412          $fields['url'] = array('type' => PARAM_URL, 'null' => NULL_NOT_ALLOWED);
 413          $fields['description'] = array('type' => PARAM_RAW, 'null' => NULL_ALLOWED);
 414          $fields['descriptionformat'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 415          $fields['mailformat'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED,
 416                  'default' => $CFG->defaultpreference_mailformat);
 417          $fields['maildigest'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED,
 418                  'default' => $CFG->defaultpreference_maildigest);
 419          $fields['maildisplay'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED,
 420                  'default' => $CFG->defaultpreference_maildisplay);
 421          $fields['autosubscribe'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED,
 422                  'default' => $CFG->defaultpreference_autosubscribe);
 423          $fields['trackforums'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED,
 424                  'default' => $CFG->defaultpreference_trackforums);
 425          $fields['timecreated'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 426          $fields['timemodified'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 427          $fields['trustbitmask'] = array('type' => PARAM_INT, 'null' => NULL_NOT_ALLOWED);
 428          $fields['imagealt'] = array('type' => PARAM_TEXT, 'null' => NULL_ALLOWED);
 429          $fields['lastnamephonetic'] = array('type' => PARAM_NOTAGS, 'null' => NULL_ALLOWED);
 430          $fields['firstnamephonetic'] = array('type' => PARAM_NOTAGS, 'null' => NULL_ALLOWED);
 431          $fields['middlename'] = array('type' => PARAM_NOTAGS, 'null' => NULL_ALLOWED);
 432          $fields['alternatename'] = array('type' => PARAM_NOTAGS, 'null' => NULL_ALLOWED);
 433  
 434          self::$propertiescache = $fields;
 435      }
 436  
 437      /**
 438       * Get properties of a user field.
 439       *
 440       * @param string $property property name to be retrieved.
 441       * @throws coding_exception if the requested property name is invalid.
 442       * @return array the property definition.
 443       */
 444      public static function get_property_definition($property) {
 445  
 446          self::fill_properties_cache();
 447  
 448          if (!array_key_exists($property, self::$propertiescache)) {
 449              throw new coding_exception('Invalid property requested.');
 450          }
 451  
 452          return self::$propertiescache[$property];
 453      }
 454  
 455      /**
 456       * Validate user data.
 457       *
 458       * This method just validates each user field and return an array of errors. It doesn't clean the data,
 459       * the methods clean() and clean_field() should be used for this purpose.
 460       *
 461       * @param stdClass|array $data user data object or array to be validated.
 462       * @return array|true $errors array of errors found on the user object, true if the validation passed.
 463       */
 464      public static function validate($data) {
 465          // Get all user profile fields definition.
 466          self::fill_properties_cache();
 467  
 468          foreach ($data as $property => $value) {
 469              try {
 470                  if (isset(self::$propertiescache[$property])) {
 471                      validate_param($value, self::$propertiescache[$property]['type'], self::$propertiescache[$property]['null']);
 472                  }
 473                  // Check that the value is part of a list of allowed values.
 474                  if (!empty(self::$propertiescache[$property]['choices']) &&
 475                          !isset(self::$propertiescache[$property]['choices'][$value])) {
 476                      throw new invalid_parameter_exception($value);
 477                  }
 478              } catch (invalid_parameter_exception $e) {
 479                  $errors[$property] = $e->getMessage();
 480              }
 481          }
 482  
 483          return empty($errors) ? true : $errors;
 484      }
 485  
 486      /**
 487       * Clean the properties cache.
 488       *
 489       * During unit tests we need to be able to reset all caches so that each new test starts in a known state.
 490       * Intended for use only for testing, phpunit calls this before every test.
 491       */
 492      public static function reset_caches() {
 493          self::$propertiescache = null;
 494      }
 495  
 496      /**
 497       * Clean the user data.
 498       *
 499       * @param stdClass|array $user the user data to be validated against properties definition.
 500       * @return stdClass $user the cleaned user data.
 501       */
 502      public static function clean_data($user) {
 503          if (empty($user)) {
 504              return $user;
 505          }
 506  
 507          foreach ($user as $field => $value) {
 508              // Get the property parameter type and do the cleaning.
 509              try {
 510                  $user->$field = core_user::clean_field($value, $field);
 511              } catch (coding_exception $e) {
 512                  debugging("The property '$field' could not be cleaned.", DEBUG_DEVELOPER);
 513              }
 514          }
 515  
 516          return $user;
 517      }
 518  
 519      /**
 520       * Clean a specific user field.
 521       *
 522       * @param string $data the user field data to be cleaned.
 523       * @param string $field the user field name on the property definition cache.
 524       * @return string the cleaned user data.
 525       */
 526      public static function clean_field($data, $field) {
 527          if (empty($data) || empty($field)) {
 528              return $data;
 529          }
 530  
 531          try {
 532              $type = core_user::get_property_type($field);
 533  
 534              if (isset(self::$propertiescache[$field]['choices'])) {
 535                  if (!array_key_exists($data, self::$propertiescache[$field]['choices'])) {
 536                      if (isset(self::$propertiescache[$field]['default'])) {
 537                          $data = self::$propertiescache[$field]['default'];
 538                      } else {
 539                          $data = '';
 540                      }
 541                  } else {
 542                      return $data;
 543                  }
 544              } else {
 545                  $data = clean_param($data, $type);
 546              }
 547          } catch (coding_exception $e) {
 548              debugging("The property '$field' could not be cleaned.", DEBUG_DEVELOPER);
 549          }
 550  
 551          return $data;
 552      }
 553  
 554      /**
 555       * Get the parameter type of the property.
 556       *
 557       * @param string $property property name to be retrieved.
 558       * @throws coding_exception if the requested property name is invalid.
 559       * @return int the property parameter type.
 560       */
 561      public static function get_property_type($property) {
 562  
 563          self::fill_properties_cache();
 564  
 565          if (!array_key_exists($property, self::$propertiescache)) {
 566              throw new coding_exception('Invalid property requested: ' . $property);
 567          }
 568  
 569          return self::$propertiescache[$property]['type'];
 570      }
 571  
 572      /**
 573       * Discover if the property is NULL_ALLOWED or NULL_NOT_ALLOWED.
 574       *
 575       * @param string $property property name to be retrieved.
 576       * @throws coding_exception if the requested property name is invalid.
 577       * @return bool true if the property is NULL_ALLOWED, false otherwise.
 578       */
 579      public static function get_property_null($property) {
 580  
 581          self::fill_properties_cache();
 582  
 583          if (!array_key_exists($property, self::$propertiescache)) {
 584              throw new coding_exception('Invalid property requested: ' . $property);
 585          }
 586  
 587          return self::$propertiescache[$property]['null'];
 588      }
 589  
 590      /**
 591       * Get the choices of the property.
 592       *
 593       * This is a helper method to validate a value against a list of acceptable choices.
 594       * For instance: country, language, themes and etc.
 595       *
 596       * @param string $property property name to be retrieved.
 597       * @throws coding_exception if the requested property name is invalid or if it does not has a list of choices.
 598       * @return array the property parameter type.
 599       */
 600      public static function get_property_choices($property) {
 601  
 602          self::fill_properties_cache();
 603  
 604          if (!array_key_exists($property, self::$propertiescache) && !array_key_exists('choices',
 605                  self::$propertiescache[$property])) {
 606  
 607              throw new coding_exception('Invalid property requested, or the property does not has a list of choices.');
 608          }
 609  
 610          return self::$propertiescache[$property]['choices'];
 611      }
 612  
 613      /**
 614       * Get the property default.
 615       *
 616       * This method gets the default value of a field (if exists).
 617       *
 618       * @param string $property property name to be retrieved.
 619       * @throws coding_exception if the requested property name is invalid or if it does not has a default value.
 620       * @return string the property default value.
 621       */
 622      public static function get_property_default($property) {
 623  
 624          self::fill_properties_cache();
 625  
 626          if (!array_key_exists($property, self::$propertiescache) || !isset(self::$propertiescache[$property]['default'])) {
 627              throw new coding_exception('Invalid property requested, or the property does not has a default value.');
 628          }
 629  
 630          return self::$propertiescache[$property]['default'];
 631      }
 632  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1