Commit | Line | Data |
---|---|---|
8bdc9cac | 1 | <?php |
a2ed6e69 SH |
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/>. | |
6b64d3b3 | 16 | |
a2ed6e69 SH |
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 | */ | |
334415e9 | 24 | |
a2ed6e69 SH |
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. | |
334415e9 | 28 | |
d052a813 | 29 | /** |
a1248ca4 | 30 | * Base class for the customisable profile fields. |
a2ed6e69 SH |
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 | |
d052a813 | 35 | */ |
6b64d3b3 | 36 | class profile_field_base { |
37 | ||
a2ed6e69 SH |
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; | |
aa6c1ced | 52 | |
a2ed6e69 SH |
53 | /** @var mixed */ |
54 | public $data; | |
55 | ||
56 | /** @var string */ | |
57 | public $dataformat; | |
6b64d3b3 | 58 | |
b1c70023 | 59 | /** |
60 | * Constructor method. | |
a2ed6e69 SH |
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 | |
b1c70023 | 63 | */ |
c4d0b752 | 64 | public function __construct($fieldid=0, $userid=0) { |
334415e9 | 65 | global $USER; |
b1c70023 | 66 | |
334415e9 | 67 | $this->set_fieldid($fieldid); |
68 | $this->set_userid($userid); | |
69 | $this->load_data(); | |
b1c70023 | 70 | } |
71 | ||
c4d0b752 MG |
72 | /** |
73 | * Old syntax of class constructor. Deprecated in PHP7. | |
74 | * | |
75 | * @deprecated since Moodle 3.1 | |
76 | */ | |
77 | public function profile_field_base($fieldid=0, $userid=0) { | |
78 | debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); | |
79 | self::__construct($fieldid, $userid); | |
80 | } | |
81 | ||
6b64d3b3 | 82 | /** |
334415e9 | 83 | * Abstract method: Adds the profile field to the moodle form class |
a2ed6e69 SH |
84 | * @abstract The following methods must be overwritten by child classes |
85 | * @param moodleform $mform instance of the moodleform class | |
6b64d3b3 | 86 | */ |
a2ed6e69 | 87 | public function edit_field_add($mform) { |
d3248238 | 88 | print_error('mustbeoveride', 'debug', '', 'edit_field_add'); |
6b64d3b3 | 89 | } |
90 | ||
334415e9 | 91 | /** |
92 | * Display the data for this field | |
a2ed6e69 | 93 | * @return string |
334415e9 | 94 | */ |
a2ed6e69 | 95 | public function display_data() { |
bf718f50 | 96 | $options = new stdClass(); |
3212d2f2 | 97 | $options->para = false; |
98 | return format_text($this->data, FORMAT_MOODLE, $options); | |
334415e9 | 99 | } |
aa6c1ced | 100 | |
6b64d3b3 | 101 | /** |
334415e9 | 102 | * Print out the form field in the edit profile page |
a2ed6e69 SH |
103 | * @param moodleform $mform instance of the moodleform class |
104 | * @return bool | |
6b64d3b3 | 105 | */ |
a2ed6e69 | 106 | public function edit_field($mform) { |
bb6d3d34 | 107 | if ($this->field->visible != PROFILE_VISIBLE_NONE |
43731030 | 108 | or has_capability('moodle/user:update', context_system::instance())) { |
6b64d3b3 | 109 | |
334415e9 | 110 | $this->edit_field_add($mform); |
111 | $this->edit_field_set_default($mform); | |
112 | $this->edit_field_set_required($mform); | |
63466095 | 113 | return true; |
114 | } | |
115 | return false; | |
116 | } | |
117 | ||
118 | /** | |
119 | * Tweaks the edit form | |
a2ed6e69 SH |
120 | * @param moodleform $mform instance of the moodleform class |
121 | * @return bool | |
63466095 | 122 | */ |
a2ed6e69 | 123 | public function edit_after_data($mform) { |
63466095 | 124 | if ($this->field->visible != PROFILE_VISIBLE_NONE |
43731030 | 125 | or has_capability('moodle/user:update', context_system::instance())) { |
334415e9 | 126 | $this->edit_field_set_locked($mform); |
17a99a13 | 127 | return true; |
9ac33264 | 128 | } |
17a99a13 | 129 | return false; |
b1c70023 | 130 | } |
6b64d3b3 | 131 | |
b1c70023 | 132 | /** |
bb6d3d34 | 133 | * Saves the data coming from form |
a2ed6e69 SH |
134 | * @param stdClass $usernew data coming from the form |
135 | * @return mixed returns data id if success of db insert/update, false on fail, 0 if not permitted | |
b1c70023 | 136 | */ |
a2ed6e69 | 137 | public function edit_save_data($usernew) { |
5d910388 | 138 | global $DB; |
6b64d3b3 | 139 | |
bb6d3d34 | 140 | if (!isset($usernew->{$this->inputname})) { |
a2ed6e69 | 141 | // Field not present in form, probably locked and invisible - skip it. |
bb6d3d34 | 142 | return; |
143 | } | |
6b64d3b3 | 144 | |
bf718f50 | 145 | $data = new stdClass(); |
aa6c1ced | 146 | |
8bdc9cac SH |
147 | $usernew->{$this->inputname} = $this->edit_save_data_preprocess($usernew->{$this->inputname}, $data); |
148 | ||
bb6d3d34 | 149 | $data->userid = $usernew->id; |
150 | $data->fieldid = $this->field->id; | |
151 | $data->data = $usernew->{$this->inputname}; | |
9ac33264 | 152 | |
a2ed6e69 | 153 | if ($dataid = $DB->get_field('user_info_data', 'id', array('userid' => $data->userid, 'fieldid' => $data->fieldid))) { |
bb6d3d34 | 154 | $data->id = $dataid; |
bf8e93d7 | 155 | $DB->update_record('user_info_data', $data); |
bb6d3d34 | 156 | } else { |
5d910388 | 157 | $DB->insert_record('user_info_data', $data); |
bb6d3d34 | 158 | } |
6b64d3b3 | 159 | } |
160 | ||
9ac33264 | 161 | /** |
bb6d3d34 | 162 | * Validate the form field from profile page |
a2ed6e69 SH |
163 | * |
164 | * @param stdClass $usernew | |
165 | * @return string contains error message otherwise null | |
166 | */ | |
167 | public function edit_validate_field($usernew) { | |
6a08c830 | 168 | global $DB; |
169 | ||
35a261eb | 170 | $errors = array(); |
3ac4ad00 RT |
171 | // Get input value. |
172 | if (isset($usernew->{$this->inputname})) { | |
173 | if (is_array($usernew->{$this->inputname}) && isset($usernew->{$this->inputname}['text'])) { | |
174 | $value = $usernew->{$this->inputname}['text']; | |
175 | } else { | |
176 | $value = $usernew->{$this->inputname}; | |
177 | } | |
178 | } else { | |
179 | $value = ''; | |
180 | } | |
181 | ||
182 | // Check for uniqueness of data if required. | |
183 | if ($this->is_unique() && (($value !== '') || $this->is_required())) { | |
af0a06cb PS |
184 | $data = $DB->get_records_sql(' |
185 | SELECT id, userid | |
25f44c72 TH |
186 | FROM {user_info_data} |
187 | WHERE fieldid = ? | |
ffcb8379 | 188 | AND ' . $DB->sql_compare_text('data', 255) . ' = ' . $DB->sql_compare_text('?', 255), |
af0a06cb PS |
189 | array($this->field->id, $value)); |
190 | if ($data) { | |
191 | $existing = false; | |
192 | foreach ($data as $v) { | |
193 | if ($v->userid == $usernew->id) { | |
194 | $existing = true; | |
195 | break; | |
196 | } | |
197 | } | |
198 | if (!$existing) { | |
199 | $errors[$this->inputname] = get_string('valuealreadyused'); | |
200 | } | |
35a261eb | 201 | } |
202 | } | |
203 | return $errors; | |
9ac33264 | 204 | } |
205 | ||
9ac33264 | 206 | /** |
bb6d3d34 | 207 | * Sets the default data for the field in the form object |
a2ed6e69 | 208 | * @param moodleform $mform instance of the moodleform class |
9ac33264 | 209 | */ |
a2ed6e69 | 210 | public function edit_field_set_default($mform) { |
bb6d3d34 | 211 | if (!empty($default)) { |
a5d3b072 | 212 | $mform->setDefault($this->inputname, $this->field->defaultdata); |
bb6d3d34 | 213 | } |
6b64d3b3 | 214 | } |
215 | ||
216 | /** | |
bb6d3d34 | 217 | * Sets the required flag for the field in the form object |
a2ed6e69 SH |
218 | * |
219 | * @param moodleform $mform instance of the moodleform class | |
6b64d3b3 | 220 | */ |
a2ed6e69 | 221 | public function edit_field_set_required($mform) { |
fc3aa0fb | 222 | global $USER; |
8ef7eade | 223 | if ($this->is_required() && ($this->userid == $USER->id || isguestuser())) { |
a5d3b072 | 224 | $mform->addRule($this->inputname, get_string('required'), 'required', null, 'client'); |
bb6d3d34 | 225 | } |
6b64d3b3 | 226 | } |
227 | ||
228 | /** | |
bb6d3d34 | 229 | * HardFreeze the field if locked. |
a2ed6e69 | 230 | * @param moodleform $mform instance of the moodleform class |
6b64d3b3 | 231 | */ |
a2ed6e69 | 232 | public function edit_field_set_locked($mform) { |
63466095 | 233 | if (!$mform->elementExists($this->inputname)) { |
234 | return; | |
235 | } | |
43731030 | 236 | if ($this->is_locked() and !has_capability('moodle/user:update', context_system::instance())) { |
a5d3b072 | 237 | $mform->hardFreeze($this->inputname); |
cc444336 | 238 | $mform->setConstant($this->inputname, $this->data); |
6b64d3b3 | 239 | } |
6b64d3b3 | 240 | } |
241 | ||
242 | /** | |
243 | * Hook for child classess to process the data before it gets saved in database | |
a2ed6e69 SH |
244 | * @param stdClass $data |
245 | * @param stdClass $datarecord The object that will be used to save the record | |
6b64d3b3 | 246 | * @return mixed |
247 | */ | |
a2ed6e69 | 248 | public function edit_save_data_preprocess($data, $datarecord) { |
6b64d3b3 | 249 | return $data; |
250 | } | |
6b64d3b3 | 251 | |
334415e9 | 252 | /** |
253 | * Loads a user object with data for this field ready for the edit profile | |
254 | * form | |
a2ed6e69 | 255 | * @param stdClass $user a user object |
334415e9 | 256 | */ |
a2ed6e69 SH |
257 | public function edit_load_user_data($user) { |
258 | if ($this->data !== null) { | |
334415e9 | 259 | $user->{$this->inputname} = $this->data; |
260 | } | |
261 | } | |
262 | ||
91cddbc4 | 263 | /** |
264 | * Check if the field data should be loaded into the user object | |
265 | * By default it is, but for field types where the data may be potentially | |
266 | * large, the child class should override this and return false | |
a2ed6e69 | 267 | * @return bool |
91cddbc4 | 268 | */ |
a2ed6e69 | 269 | public function is_user_object_data() { |
91cddbc4 | 270 | return true; |
271 | } | |
272 | ||
334415e9 | 273 | /** |
274 | * Accessor method: set the userid for this instance | |
a2ed6e69 SH |
275 | * @internal This method should not generally be overwritten by child classes. |
276 | * @param integer $userid id from the user table | |
334415e9 | 277 | */ |
a2ed6e69 | 278 | public function set_userid($userid) { |
334415e9 | 279 | $this->userid = $userid; |
280 | } | |
281 | ||
282 | /** | |
283 | * Accessor method: set the fieldid for this instance | |
a2ed6e69 SH |
284 | * @internal This method should not generally be overwritten by child classes. |
285 | * @param integer $fieldid id from the user_info_field table | |
334415e9 | 286 | */ |
a2ed6e69 | 287 | public function set_fieldid($fieldid) { |
334415e9 | 288 | $this->fieldid = $fieldid; |
289 | } | |
290 | ||
291 | /** | |
292 | * Accessor method: Load the field record and user data associated with the | |
293 | * object's fieldid and userid | |
a2ed6e69 | 294 | * @internal This method should not generally be overwritten by child classes. |
334415e9 | 295 | */ |
a2ed6e69 | 296 | public function load_data() { |
5d910388 | 297 | global $DB; |
298 | ||
a2ed6e69 SH |
299 | // Load the field object. |
300 | if (($this->fieldid == 0) or (!($field = $DB->get_record('user_info_field', array('id' => $this->fieldid))))) { | |
301 | $this->field = null; | |
334415e9 | 302 | $this->inputname = ''; |
303 | } else { | |
304 | $this->field = $field; | |
305 | $this->inputname = 'profile_field_'.$field->shortname; | |
306 | } | |
307 | ||
308 | if (!empty($this->field)) { | |
a2ed6e69 SH |
309 | $params = array('userid' => $this->userid, 'fieldid' => $this->fieldid); |
310 | if ($data = $DB->get_record('user_info_data', $params, 'data, dataformat')) { | |
8bdc9cac SH |
311 | $this->data = $data->data; |
312 | $this->dataformat = $data->dataformat; | |
334415e9 | 313 | } else { |
314 | $this->data = $this->field->defaultdata; | |
8bdc9cac | 315 | $this->dataformat = FORMAT_HTML; |
334415e9 | 316 | } |
317 | } else { | |
a2ed6e69 | 318 | $this->data = null; |
334415e9 | 319 | } |
320 | } | |
321 | ||
322 | /** | |
323 | * Check if the field data is visible to the current user | |
a2ed6e69 SH |
324 | * @internal This method should not generally be overwritten by child classes. |
325 | * @return bool | |
334415e9 | 326 | */ |
a2ed6e69 | 327 | public function is_visible() { |
334415e9 | 328 | global $USER; |
329 | ||
330 | switch ($this->field->visible) { | |
331 | case PROFILE_VISIBLE_ALL: | |
332 | return true; | |
333 | case PROFILE_VISIBLE_PRIVATE: | |
76727901 | 334 | if ($this->userid == $USER->id) { |
335 | return true; | |
336 | } else { | |
6d153e67 | 337 | return has_capability('moodle/user:viewalldetails', |
43731030 | 338 | context_user::instance($this->userid)); |
76727901 | 339 | } |
334415e9 | 340 | default: |
6d153e67 | 341 | return has_capability('moodle/user:viewalldetails', |
43731030 | 342 | context_user::instance($this->userid)); |
334415e9 | 343 | } |
344 | } | |
345 | ||
4a7030e0 | 346 | /** |
347 | * Check if the field data is considered empty | |
a2ed6e69 SH |
348 | * @internal This method should not generally be overwritten by child classes. |
349 | * @return boolean | |
4a7030e0 | 350 | */ |
a2ed6e69 | 351 | public function is_empty() { |
4a7030e0 | 352 | return ( ($this->data != '0') and empty($this->data)); |
353 | } | |
354 | ||
334415e9 | 355 | /** |
356 | * Check if the field is required on the edit profile page | |
a2ed6e69 SH |
357 | * @internal This method should not generally be overwritten by child classes. |
358 | * @return bool | |
334415e9 | 359 | */ |
a2ed6e69 | 360 | public function is_required() { |
334415e9 | 361 | return (boolean)$this->field->required; |
362 | } | |
363 | ||
364 | /** | |
365 | * Check if the field is locked on the edit profile page | |
a2ed6e69 SH |
366 | * @internal This method should not generally be overwritten by child classes. |
367 | * @return bool | |
334415e9 | 368 | */ |
a2ed6e69 | 369 | public function is_locked() { |
334415e9 | 370 | return (boolean)$this->field->locked; |
371 | } | |
372 | ||
62ebb000 | 373 | /** |
374 | * Check if the field data should be unique | |
a2ed6e69 SH |
375 | * @internal This method should not generally be overwritten by child classes. |
376 | * @return bool | |
62ebb000 | 377 | */ |
a2ed6e69 | 378 | public function is_unique() { |
501ca377 | 379 | return (boolean)$this->field->forceunique; |
62ebb000 | 380 | } |
381 | ||
382 | /** | |
383 | * Check if the field should appear on the signup page | |
a2ed6e69 SH |
384 | * @internal This method should not generally be overwritten by child classes. |
385 | * @return bool | |
62ebb000 | 386 | */ |
a2ed6e69 | 387 | public function is_signup_field() { |
62ebb000 | 388 | return (boolean)$this->field->signup; |
389 | } | |
a2ed6e69 | 390 | } |
aa6c1ced | 391 | |
a2ed6e69 SH |
392 | /** |
393 | * Loads user profile field data into the user object. | |
394 | * @param stdClass $user | |
395 | */ | |
c990e4bf | 396 | function profile_load_data($user) { |
5d910388 | 397 | global $CFG, $DB; |
bb6d3d34 | 398 | |
5d910388 | 399 | if ($fields = $DB->get_records('user_info_field')) { |
bb6d3d34 | 400 | foreach ($fields as $field) { |
401 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
402 | $newfield = 'profile_field_'.$field->datatype; | |
334415e9 | 403 | $formfield = new $newfield($field->id, $user->id); |
404 | $formfield->edit_load_user_data($user); | |
bb6d3d34 | 405 | } |
406 | } | |
407 | } | |
408 | ||
7240a6ea | 409 | /** |
410 | * Print out the customisable categories and fields for a users profile | |
a2ed6e69 SH |
411 | * |
412 | * @param moodleform $mform instance of the moodleform class | |
fc3aa0fb | 413 | * @param int $userid id of user whose profile is being edited. |
7240a6ea | 414 | */ |
fc3aa0fb | 415 | function profile_definition($mform, $userid = 0) { |
5d910388 | 416 | global $CFG, $DB; |
7240a6ea | 417 | |
a2ed6e69 | 418 | // If user is "admin" fields are displayed regardless. |
43731030 | 419 | $update = has_capability('moodle/user:update', context_system::instance()); |
85576776 | 420 | |
5d910388 | 421 | if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) { |
7240a6ea | 422 | foreach ($categories as $category) { |
a2ed6e69 | 423 | if ($fields = $DB->get_records('user_info_field', array('categoryid' => $category->id), 'sortorder ASC')) { |
aa6c1ced | 424 | |
a2ed6e69 | 425 | // Check first if *any* fields will be displayed. |
85576776 | 426 | $display = false; |
7240a6ea | 427 | foreach ($fields as $field) { |
85576776 | 428 | if ($field->visible != PROFILE_VISIBLE_NONE) { |
429 | $display = true; | |
17a99a13 | 430 | } |
431 | } | |
85576776 | 432 | |
a2ed6e69 | 433 | // Display the header and the fields. |
85576776 | 434 | if ($display or $update) { |
17a99a13 | 435 | $mform->addElement('header', 'category_'.$category->id, format_string($category->name)); |
85576776 | 436 | foreach ($fields as $field) { |
437 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
438 | $newfield = 'profile_field_'.$field->datatype; | |
fc3aa0fb | 439 | $formfield = new $newfield($field->id, $userid); |
85576776 | 440 | $formfield->edit_field($mform); |
441 | } | |
7240a6ea | 442 | } |
bb6d3d34 | 443 | } |
9ac33264 | 444 | } |
445 | } | |
9ac33264 | 446 | } |
447 | ||
a2ed6e69 SH |
448 | /** |
449 | * Adds profile fields to user edit forms. | |
450 | * @param moodleform $mform | |
451 | * @param int $userid | |
452 | */ | |
c990e4bf | 453 | function profile_definition_after_data($mform, $userid) { |
5d910388 | 454 | global $CFG, $DB; |
63466095 | 455 | |
456 | $userid = ($userid < 0) ? 0 : (int)$userid; | |
457 | ||
5d910388 | 458 | if ($fields = $DB->get_records('user_info_field')) { |
bb6d3d34 | 459 | foreach ($fields as $field) { |
460 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
461 | $newfield = 'profile_field_'.$field->datatype; | |
63466095 | 462 | $formfield = new $newfield($field->id, $userid); |
463 | $formfield->edit_after_data($mform); | |
d052a813 | 464 | } |
63466095 | 465 | } |
d052a813 | 466 | } |
467 | ||
a2ed6e69 SH |
468 | /** |
469 | * Validates profile data. | |
470 | * @param stdClass $usernew | |
471 | * @param array $files | |
472 | * @return array | |
473 | */ | |
a78890d5 | 474 | function profile_validation($usernew, $files) { |
5d910388 | 475 | global $CFG, $DB; |
d052a813 | 476 | |
bb6d3d34 | 477 | $err = array(); |
5d910388 | 478 | if ($fields = $DB->get_records('user_info_field')) { |
bb6d3d34 | 479 | foreach ($fields as $field) { |
480 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
481 | $newfield = 'profile_field_'.$field->datatype; | |
334415e9 | 482 | $formfield = new $newfield($field->id, $usernew->id); |
a78890d5 | 483 | $err += $formfield->edit_validate_field($usernew, $files); |
d052a813 | 484 | } |
485 | } | |
bb6d3d34 | 486 | return $err; |
d052a813 | 487 | } |
488 | ||
a2ed6e69 SH |
489 | /** |
490 | * Saves profile data for a user. | |
491 | * @param stdClass $usernew | |
492 | */ | |
bb6d3d34 | 493 | function profile_save_data($usernew) { |
5d910388 | 494 | global $CFG, $DB; |
d052a813 | 495 | |
5849cfe2 | 496 | if ($fields = $DB->get_records('user_info_field')) { |
bb6d3d34 | 497 | foreach ($fields as $field) { |
498 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
499 | $newfield = 'profile_field_'.$field->datatype; | |
334415e9 | 500 | $formfield = new $newfield($field->id, $usernew->id); |
501 | $formfield->edit_save_data($usernew); | |
bb6d3d34 | 502 | } |
9ac33264 | 503 | } |
9ac33264 | 504 | } |
505 | ||
a2ed6e69 SH |
506 | /** |
507 | * Display profile fields. | |
508 | * @param int $userid | |
509 | */ | |
334415e9 | 510 | function profile_display_fields($userid) { |
5d910388 | 511 | global $CFG, $USER, $DB; |
d052a813 | 512 | |
5d910388 | 513 | if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) { |
334415e9 | 514 | foreach ($categories as $category) { |
a2ed6e69 | 515 | if ($fields = $DB->get_records('user_info_field', array('categoryid' => $category->id), 'sortorder ASC')) { |
334415e9 | 516 | foreach ($fields as $field) { |
517 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
518 | $newfield = 'profile_field_'.$field->datatype; | |
519 | $formfield = new $newfield($field->id, $userid); | |
4a7030e0 | 520 | if ($formfield->is_visible() and !$formfield->is_empty()) { |
6e5d002e JF |
521 | echo html_writer::tag('dt', format_string($formfield->field->name)); |
522 | echo html_writer::tag('dd', $formfield->display_data()); | |
334415e9 | 523 | } |
524 | } | |
525 | } | |
526 | } | |
527 | } | |
528 | } | |
d052a813 | 529 | |
831d450e | 530 | /** |
531 | * Adds code snippet to a moodle form object for custom profile fields that | |
532 | * should appear on the signup page | |
a2ed6e69 | 533 | * @param moodleform $mform moodle form object |
831d450e | 534 | */ |
c990e4bf | 535 | function profile_signup_fields($mform) { |
5d910388 | 536 | global $CFG, $DB; |
416afdbb | 537 | |
a2ed6e69 SH |
538 | // Only retrieve required custom fields (with category information) |
539 | // results are sort by categories, then by fields. | |
416afdbb | 540 | $sql = "SELECT uf.id as fieldid, ic.id as categoryid, ic.name as categoryname, uf.datatype |
351d5250 | 541 | FROM {user_info_field} uf |
542 | JOIN {user_info_category} ic | |
aa6c1ced | 543 | ON uf.categoryid = ic.id AND uf.signup = 1 AND uf.visible<>0 |
416afdbb | 544 | ORDER BY ic.sortorder ASC, uf.sortorder ASC"; |
545 | ||
546 | if ( $fields = $DB->get_records_sql($sql)) { | |
831d450e | 547 | foreach ($fields as $field) { |
a2ed6e69 | 548 | // Check if we change the categories. |
416afdbb | 549 | if (!isset($currentcat) || $currentcat != $field->categoryid) { |
550 | $currentcat = $field->categoryid; | |
551 | $mform->addElement('header', 'category_'.$field->categoryid, format_string($field->categoryname)); | |
552 | } | |
831d450e | 553 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); |
554 | $newfield = 'profile_field_'.$field->datatype; | |
416afdbb | 555 | $formfield = new $newfield($field->fieldid); |
831d450e | 556 | $formfield->edit_field($mform); |
557 | } | |
558 | } | |
559 | } | |
d052a813 | 560 | |
66643c0a | 561 | /** |
562 | * Returns an object with the custom profile fields set for the given user | |
a2ed6e69 | 563 | * @param integer $userid |
da1296dd | 564 | * @param bool $onlyinuserobject True if you only want the ones in $USER. |
a2ed6e69 | 565 | * @return stdClass |
66643c0a | 566 | */ |
da1296dd | 567 | function profile_user_record($userid, $onlyinuserobject = true) { |
5d910388 | 568 | global $CFG, $DB; |
66643c0a | 569 | |
bf718f50 | 570 | $usercustomfields = new stdClass(); |
66643c0a | 571 | |
5d910388 | 572 | if ($fields = $DB->get_records('user_info_field')) { |
66643c0a | 573 | foreach ($fields as $field) { |
574 | require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); | |
575 | $newfield = 'profile_field_'.$field->datatype; | |
576 | $formfield = new $newfield($field->id, $userid); | |
da1296dd | 577 | if (!$onlyinuserobject || $formfield->is_user_object_data()) { |
a1248ca4 PS |
578 | $usercustomfields->{$field->shortname} = $formfield->data; |
579 | } | |
66643c0a | 580 | } |
581 | } | |
582 | ||
fb79269b | 583 | return $usercustomfields; |
66643c0a | 584 | } |
585 | ||
abdbfc76 | 586 | /** |
587 | * Obtains a list of all available custom profile fields, indexed by id. | |
588 | * | |
589 | * Some profile fields are not included in the user object data (see | |
590 | * profile_user_record function above). Optionally, you can obtain only those | |
591 | * fields that are included in the user object. | |
592 | * | |
593 | * To be clear, this function returns the available fields, and does not | |
594 | * return the field values for a particular user. | |
595 | * | |
596 | * @param bool $onlyinuserobject True if you only want the ones in $USER | |
597 | * @return array Array of field objects from database (indexed by id) | |
598 | * @since Moodle 2.7.1 | |
599 | */ | |
600 | function profile_get_custom_fields($onlyinuserobject = false) { | |
601 | global $DB, $CFG; | |
602 | ||
603 | // Get all the fields. | |
604 | $fields = $DB->get_records('user_info_field', null, 'id ASC'); | |
605 | ||
606 | // If only doing the user object ones, unset the rest. | |
607 | if ($onlyinuserobject) { | |
608 | foreach ($fields as $id => $field) { | |
609 | require_once($CFG->dirroot . '/user/profile/field/' . | |
610 | $field->datatype . '/field.class.php'); | |
611 | $newfield = 'profile_field_' . $field->datatype; | |
612 | $formfield = new $newfield(); | |
613 | if (!$formfield->is_user_object_data()) { | |
614 | unset($fields[$id]); | |
615 | } | |
616 | } | |
617 | } | |
618 | ||
619 | return $fields; | |
620 | } | |
621 | ||
a1248ca4 PS |
622 | /** |
623 | * Load custom profile fields into user object | |
624 | * | |
625 | * Please note originally in 1.9 we were using the custom field names directly, | |
626 | * but it was causing unexpected collisions when adding new fields to user table, | |
627 | * so instead we now use 'profile_' prefix. | |
628 | * | |
a2ed6e69 | 629 | * @param stdClass $user user object |
a1248ca4 | 630 | */ |
c990e4bf | 631 | function profile_load_custom_fields($user) { |
a1248ca4 PS |
632 | $user->profile = (array)profile_user_record($user->id); |
633 | } | |
66643c0a | 634 | |
d1b23838 JL |
635 | /** |
636 | * Trigger a user profile viewed event. | |
637 | * | |
638 | * @param stdClass $user user object | |
639 | * @param stdClass $context context object (course or user) | |
640 | * @param stdClass $course course object | |
641 | * @since Moodle 2.9 | |
642 | */ | |
643 | function profile_view($user, $context, $course = null) { | |
644 | ||
645 | $eventdata = array( | |
646 | 'objectid' => $user->id, | |
647 | 'relateduserid' => $user->id, | |
648 | 'context' => $context | |
649 | ); | |
650 | ||
651 | if (!empty($course)) { | |
652 | $eventdata['courseid'] = $course->id; | |
653 | $eventdata['other'] = array( | |
654 | 'courseid' => $course->id, | |
655 | 'courseshortname' => $course->shortname, | |
656 | 'coursefullname' => $course->fullname | |
657 | ); | |
658 | } | |
659 | ||
660 | $event = \core\event\user_profile_viewed::create($eventdata); | |
661 | $event->add_record_snapshot('user', $user); | |
662 | $event->trigger(); | |
663 | } | |
aa6c1ced | 664 | |
8df850ad DM |
665 | /** |
666 | * Does the user have all required custom fields set? | |
667 | * | |
668 | * Internal, to be exclusively used by {@link user_not_fully_set_up()} only. | |
669 | * | |
670 | * Note that if users have no way to fill a required field via editing their | |
671 | * profiles (e.g. the field is not visible or it is locked), we still return true. | |
672 | * So this is actually checking if we should redirect the user to edit their | |
673 | * profile, rather than whether there is a value in the database. | |
674 | * | |
675 | * @param int $userid | |
676 | * @return bool | |
677 | */ | |
678 | function profile_has_required_custom_fields_set($userid) { | |
679 | global $DB; | |
680 | ||
681 | $sql = "SELECT f.id | |
682 | FROM {user_info_field} f | |
683 | LEFT JOIN {user_info_data} d ON (d.fieldid = f.id AND d.userid = ?) | |
684 | WHERE f.required = 1 AND f.visible > 0 AND f.locked = 0 AND d.id IS NULL"; | |
685 | ||
686 | if ($DB->record_exists_sql($sql, [$userid])) { | |
687 | return false; | |
688 | } | |
689 | ||
690 | return true; | |
691 | } |