[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * Profile field API library file. 19 * 20 * @package core_user 21 * @copyright 2007 onwards Shane Elliot {@link http://pukunui.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 define ('PROFILE_VISIBLE_ALL', '2'); // Only visible for users with moodle/user:update capability. 26 define ('PROFILE_VISIBLE_PRIVATE', '1'); // Either we are viewing our own profile or we have moodle/user:update capability. 27 define ('PROFILE_VISIBLE_NONE', '0'); // Only visible for moodle/user:update capability. 28 29 /** 30 * Base class for the customisable profile fields. 31 * 32 * @package core_user 33 * @copyright 2007 onwards Shane Elliot {@link http://pukunui.com} 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class profile_field_base { 37 38 // These 2 variables are really what we're interested in. 39 // Everything else can be extracted from them. 40 41 /** @var int */ 42 public $fieldid; 43 44 /** @var int */ 45 public $userid; 46 47 /** @var stdClass */ 48 public $field; 49 50 /** @var string */ 51 public $inputname; 52 53 /** @var mixed */ 54 public $data; 55 56 /** @var string */ 57 public $dataformat; 58 59 /** 60 * Constructor method. 61 * @param int $fieldid id of the profile from the user_info_field table 62 * @param int $userid id of the user for whom we are displaying data 63 */ 64 public function profile_field_base($fieldid=0, $userid=0) { 65 global $USER; 66 67 $this->set_fieldid($fieldid); 68 $this->set_userid($userid); 69 $this->load_data(); 70 } 71 72 /** 73 * Abstract method: Adds the profile field to the moodle form class 74 * @abstract The following methods must be overwritten by child classes 75 * @param moodleform $mform instance of the moodleform class 76 */ 77 public function edit_field_add($mform) { 78 print_error('mustbeoveride', 'debug', '', 'edit_field_add'); 79 } 80 81 /** 82 * Display the data for this field 83 * @return string 84 */ 85 public function display_data() { 86 $options = new stdClass(); 87 $options->para = false; 88 return format_text($this->data, FORMAT_MOODLE, $options); 89 } 90 91 /** 92 * Print out the form field in the edit profile page 93 * @param moodleform $mform instance of the moodleform class 94 * @return bool 95 */ 96 public function edit_field($mform) { 97 if ($this->field->visible != PROFILE_VISIBLE_NONE 98 or has_capability('moodle/user:update', context_system::instance())) { 99 100 $this->edit_field_add($mform); 101 $this->edit_field_set_default($mform); 102 $this->edit_field_set_required($mform); 103 return true; 104 } 105 return false; 106 } 107 108 /** 109 * Tweaks the edit form 110 * @param moodleform $mform instance of the moodleform class 111 * @return bool 112 */ 113 public function edit_after_data($mform) { 114 if ($this->field->visible != PROFILE_VISIBLE_NONE 115 or has_capability('moodle/user:update', context_system::instance())) { 116 $this->edit_field_set_locked($mform); 117 return true; 118 } 119 return false; 120 } 121 122 /** 123 * Saves the data coming from form 124 * @param stdClass $usernew data coming from the form 125 * @return mixed returns data id if success of db insert/update, false on fail, 0 if not permitted 126 */ 127 public function edit_save_data($usernew) { 128 global $DB; 129 130 if (!isset($usernew->{$this->inputname})) { 131 // Field not present in form, probably locked and invisible - skip it. 132 return; 133 } 134 135 $data = new stdClass(); 136 137 $usernew->{$this->inputname} = $this->edit_save_data_preprocess($usernew->{$this->inputname}, $data); 138 139 $data->userid = $usernew->id; 140 $data->fieldid = $this->field->id; 141 $data->data = $usernew->{$this->inputname}; 142 143 if ($dataid = $DB->get_field('user_info_data', 'id', array('userid' => $data->userid, 'fieldid' => $data->fieldid))) { 144 $data->id = $dataid; 145 $DB->update_record('user_info_data', $data); 146 } else { 147 $DB->insert_record('user_info_data', $data); 148 } 149 } 150 151 /** 152 * Validate the form field from profile page 153 * 154 * @param stdClass $usernew 155 * @return string contains error message otherwise null 156 */ 157 public function edit_validate_field($usernew) { 158 global $DB; 159 160 $errors = array(); 161 // Get input value. 162 if (isset($usernew->{$this->inputname})) { 163 if (is_array($usernew->{$this->inputname}) && isset($usernew->{$this->inputname}['text'])) { 164 $value = $usernew->{$this->inputname}['text']; 165 } else { 166 $value = $usernew->{$this->inputname}; 167 } 168 } else { 169 $value = ''; 170 } 171 172 // Check for uniqueness of data if required. 173 if ($this->is_unique() && (($value !== '') || $this->is_required())) { 174 $data = $DB->get_records_sql(' 175 SELECT id, userid 176 FROM {user_info_data} 177 WHERE fieldid = ? 178 AND ' . $DB->sql_compare_text('data', 255) . ' = ' . $DB->sql_compare_text('?', 255), 179 array($this->field->id, $value)); 180 if ($data) { 181 $existing = false; 182 foreach ($data as $v) { 183 if ($v->userid == $usernew->id) { 184 $existing = true; 185 break; 186 } 187 } 188 if (!$existing) { 189 $errors[$this->inputname] = get_string('valuealreadyused'); 190 } 191 } 192 } 193 return $errors; 194 } 195 196 /** 197 * Sets the default data for the field in the form object 198 * @param moodleform $mform instance of the moodleform class 199 */ 200 public function edit_field_set_default($mform) { 201 if (!empty($default)) { 202 $mform->setDefault($this->inputname, $this->field->defaultdata); 203 } 204 } 205 206 /** 207 * Sets the required flag for the field in the form object 208 * 209 * @param moodleform $mform instance of the moodleform class 210 */ 211 public function edit_field_set_required($mform) { 212 global $USER; 213 if ($this->is_required() && ($this->userid == $USER->id)) { 214 $mform->addRule($this->inputname, get_string('required'), 'required', null, 'client'); 215 } 216 } 217 218 /** 219 * HardFreeze the field if locked. 220 * @param moodleform $mform instance of the moodleform class 221 */ 222 public function edit_field_set_locked($mform) { 223 if (!$mform->elementExists($this->inputname)) { 224 return; 225 } 226 if ($this->is_locked() and !has_capability('moodle/user:update', context_system::instance())) { 227 $mform->hardFreeze($this->inputname); 228 $mform->setConstant($this->inputname, $this->data); 229 } 230 } 231 232 /** 233 * Hook for child classess to process the data before it gets saved in database 234 * @param stdClass $data 235 * @param stdClass $datarecord The object that will be used to save the record 236 * @return mixed 237 */ 238 public function edit_save_data_preprocess($data, $datarecord) { 239 return $data; 240 } 241 242 /** 243 * Loads a user object with data for this field ready for the edit profile 244 * form 245 * @param stdClass $user a user object 246 */ 247 public function edit_load_user_data($user) { 248 if ($this->data !== null) { 249 $user->{$this->inputname} = $this->data; 250 } 251 } 252 253 /** 254 * Check if the field data should be loaded into the user object 255 * By default it is, but for field types where the data may be potentially 256 * large, the child class should override this and return false 257 * @return bool 258 */ 259 public function is_user_object_data() { 260 return true; 261 } 262 263 /** 264 * Accessor method: set the userid for this instance 265 * @internal This method should not generally be overwritten by child classes. 266 * @param integer $userid id from the user table 267 */ 268 public function set_userid($userid) { 269 $this->userid = $userid; 270 } 271 272 /** 273 * Accessor method: set the fieldid for this instance 274 * @internal This method should not generally be overwritten by child classes. 275 * @param integer $fieldid id from the user_info_field table 276 */ 277 public function set_fieldid($fieldid) { 278 $this->fieldid = $fieldid; 279 } 280 281 /** 282 * Accessor method: Load the field record and user data associated with the 283 * object's fieldid and userid 284 * @internal This method should not generally be overwritten by child classes. 285 */ 286 public function load_data() { 287 global $DB; 288 289 // Load the field object. 290 if (($this->fieldid == 0) or (!($field = $DB->get_record('user_info_field', array('id' => $this->fieldid))))) { 291 $this->field = null; 292 $this->inputname = ''; 293 } else { 294 $this->field = $field; 295 $this->inputname = 'profile_field_'.$field->shortname; 296 } 297 298 if (!empty($this->field)) { 299 $params = array('userid' => $this->userid, 'fieldid' => $this->fieldid); 300 if ($data = $DB->get_record('user_info_data', $params, 'data, dataformat')) { 301 $this->data = $data->data; 302 $this->dataformat = $data->dataformat; 303 } else { 304 $this->data = $this->field->defaultdata; 305 $this->dataformat = FORMAT_HTML; 306 } 307 } else { 308 $this->data = null; 309 } 310 } 311 312 /** 313 * Check if the field data is visible to the current user 314 * @internal This method should not generally be overwritten by child classes. 315 * @return bool 316 */ 317 public function is_visible() { 318 global $USER; 319 320 switch ($this->field->visible) { 321 case PROFILE_VISIBLE_ALL: 322 return true; 323 case PROFILE_VISIBLE_PRIVATE: 324 if ($this->userid == $USER->id) { 325 return true; 326 } else { 327 return has_capability('moodle/user:viewalldetails', 328 context_user::instance($this->userid)); 329 } 330 default: 331 return has_capability('moodle/user:viewalldetails', 332 context_user::instance($this->userid)); 333 } 334 } 335 336 /** 337 * Check if the field data is considered empty 338 * @internal This method should not generally be overwritten by child classes. 339 * @return boolean 340 */ 341 public function is_empty() { 342 return ( ($this->data != '0') and empty($this->data)); 343 } 344 345 /** 346 * Check if the field is required on the edit profile page 347 * @internal This method should not generally be overwritten by child classes. 348 * @return bool 349 */ 350 public function is_required() { 351 return (boolean)$this->field->required; 352 } 353 354 /** 355 * Check if the field is locked on the edit profile page 356 * @internal This method should not generally be overwritten by child classes. 357 * @return bool 358 */ 359 public function is_locked() { 360 return (boolean)$this->field->locked; 361 } 362 363 /** 364 * Check if the field data should be unique 365 * @internal This method should not generally be overwritten by child classes. 366 * @return bool 367 */ 368 public function is_unique() { 369 return (boolean)$this->field->forceunique; 370 } 371 372 /** 373 * Check if the field should appear on the signup page 374 * @internal This method should not generally be overwritten by child classes. 375 * @return bool 376 */ 377 public function is_signup_field() { 378 return (boolean)$this->field->signup; 379 } 380 } 381 382 /** 383 * Loads user profile field data into the user object. 384 * @param stdClass $user 385 */ 386 function profile_load_data($user) { 387 global $CFG, $DB; 388 389 if ($fields = $DB->get_records('user_info_field')) { 390 foreach ($fields as $field) { 391 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 392 $newfield = 'profile_field_'.$field->datatype; 393 $formfield = new $newfield($field->id, $user->id); 394 $formfield->edit_load_user_data($user); 395 } 396 } 397 } 398 399 /** 400 * Print out the customisable categories and fields for a users profile 401 * 402 * @param moodleform $mform instance of the moodleform class 403 * @param int $userid id of user whose profile is being edited. 404 */ 405 function profile_definition($mform, $userid = 0) { 406 global $CFG, $DB; 407 408 // If user is "admin" fields are displayed regardless. 409 $update = has_capability('moodle/user:update', context_system::instance()); 410 411 if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) { 412 foreach ($categories as $category) { 413 if ($fields = $DB->get_records('user_info_field', array('categoryid' => $category->id), 'sortorder ASC')) { 414 415 // Check first if *any* fields will be displayed. 416 $display = false; 417 foreach ($fields as $field) { 418 if ($field->visible != PROFILE_VISIBLE_NONE) { 419 $display = true; 420 } 421 } 422 423 // Display the header and the fields. 424 if ($display or $update) { 425 $mform->addElement('header', 'category_'.$category->id, format_string($category->name)); 426 foreach ($fields as $field) { 427 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 428 $newfield = 'profile_field_'.$field->datatype; 429 $formfield = new $newfield($field->id, $userid); 430 $formfield->edit_field($mform); 431 } 432 } 433 } 434 } 435 } 436 } 437 438 /** 439 * Adds profile fields to user edit forms. 440 * @param moodleform $mform 441 * @param int $userid 442 */ 443 function profile_definition_after_data($mform, $userid) { 444 global $CFG, $DB; 445 446 $userid = ($userid < 0) ? 0 : (int)$userid; 447 448 if ($fields = $DB->get_records('user_info_field')) { 449 foreach ($fields as $field) { 450 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 451 $newfield = 'profile_field_'.$field->datatype; 452 $formfield = new $newfield($field->id, $userid); 453 $formfield->edit_after_data($mform); 454 } 455 } 456 } 457 458 /** 459 * Validates profile data. 460 * @param stdClass $usernew 461 * @param array $files 462 * @return array 463 */ 464 function profile_validation($usernew, $files) { 465 global $CFG, $DB; 466 467 $err = array(); 468 if ($fields = $DB->get_records('user_info_field')) { 469 foreach ($fields as $field) { 470 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 471 $newfield = 'profile_field_'.$field->datatype; 472 $formfield = new $newfield($field->id, $usernew->id); 473 $err += $formfield->edit_validate_field($usernew, $files); 474 } 475 } 476 return $err; 477 } 478 479 /** 480 * Saves profile data for a user. 481 * @param stdClass $usernew 482 */ 483 function profile_save_data($usernew) { 484 global $CFG, $DB; 485 486 if ($fields = $DB->get_records('user_info_field')) { 487 foreach ($fields as $field) { 488 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 489 $newfield = 'profile_field_'.$field->datatype; 490 $formfield = new $newfield($field->id, $usernew->id); 491 $formfield->edit_save_data($usernew); 492 } 493 } 494 } 495 496 /** 497 * Display profile fields. 498 * @param int $userid 499 */ 500 function profile_display_fields($userid) { 501 global $CFG, $USER, $DB; 502 503 if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) { 504 foreach ($categories as $category) { 505 if ($fields = $DB->get_records('user_info_field', array('categoryid' => $category->id), 'sortorder ASC')) { 506 foreach ($fields as $field) { 507 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 508 $newfield = 'profile_field_'.$field->datatype; 509 $formfield = new $newfield($field->id, $userid); 510 if ($formfield->is_visible() and !$formfield->is_empty()) { 511 echo html_writer::tag('dt', format_string($formfield->field->name)); 512 echo html_writer::tag('dd', $formfield->display_data()); 513 } 514 } 515 } 516 } 517 } 518 } 519 520 /** 521 * Adds code snippet to a moodle form object for custom profile fields that 522 * should appear on the signup page 523 * @param moodleform $mform moodle form object 524 */ 525 function profile_signup_fields($mform) { 526 global $CFG, $DB; 527 528 // Only retrieve required custom fields (with category information) 529 // results are sort by categories, then by fields. 530 $sql = "SELECT uf.id as fieldid, ic.id as categoryid, ic.name as categoryname, uf.datatype 531 FROM {user_info_field} uf 532 JOIN {user_info_category} ic 533 ON uf.categoryid = ic.id AND uf.signup = 1 AND uf.visible<>0 534 ORDER BY ic.sortorder ASC, uf.sortorder ASC"; 535 536 if ( $fields = $DB->get_records_sql($sql)) { 537 foreach ($fields as $field) { 538 // Check if we change the categories. 539 if (!isset($currentcat) || $currentcat != $field->categoryid) { 540 $currentcat = $field->categoryid; 541 $mform->addElement('header', 'category_'.$field->categoryid, format_string($field->categoryname)); 542 } 543 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 544 $newfield = 'profile_field_'.$field->datatype; 545 $formfield = new $newfield($field->fieldid); 546 $formfield->edit_field($mform); 547 } 548 } 549 } 550 551 /** 552 * Returns an object with the custom profile fields set for the given user 553 * @param integer $userid 554 * @return stdClass 555 */ 556 function profile_user_record($userid) { 557 global $CFG, $DB; 558 559 $usercustomfields = new stdClass(); 560 561 if ($fields = $DB->get_records('user_info_field')) { 562 foreach ($fields as $field) { 563 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 564 $newfield = 'profile_field_'.$field->datatype; 565 $formfield = new $newfield($field->id, $userid); 566 if ($formfield->is_user_object_data()) { 567 $usercustomfields->{$field->shortname} = $formfield->data; 568 } 569 } 570 } 571 572 return $usercustomfields; 573 } 574 575 /** 576 * Obtains a list of all available custom profile fields, indexed by id. 577 * 578 * Some profile fields are not included in the user object data (see 579 * profile_user_record function above). Optionally, you can obtain only those 580 * fields that are included in the user object. 581 * 582 * To be clear, this function returns the available fields, and does not 583 * return the field values for a particular user. 584 * 585 * @param bool $onlyinuserobject True if you only want the ones in $USER 586 * @return array Array of field objects from database (indexed by id) 587 * @since Moodle 2.7.1 588 */ 589 function profile_get_custom_fields($onlyinuserobject = false) { 590 global $DB, $CFG; 591 592 // Get all the fields. 593 $fields = $DB->get_records('user_info_field', null, 'id ASC'); 594 595 // If only doing the user object ones, unset the rest. 596 if ($onlyinuserobject) { 597 foreach ($fields as $id => $field) { 598 require_once($CFG->dirroot . '/user/profile/field/' . 599 $field->datatype . '/field.class.php'); 600 $newfield = 'profile_field_' . $field->datatype; 601 $formfield = new $newfield(); 602 if (!$formfield->is_user_object_data()) { 603 unset($fields[$id]); 604 } 605 } 606 } 607 608 return $fields; 609 } 610 611 /** 612 * Load custom profile fields into user object 613 * 614 * Please note originally in 1.9 we were using the custom field names directly, 615 * but it was causing unexpected collisions when adding new fields to user table, 616 * so instead we now use 'profile_' prefix. 617 * 618 * @param stdClass $user user object 619 */ 620 function profile_load_custom_fields($user) { 621 $user->profile = (array)profile_user_record($user->id); 622 } 623 624
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |