MDL-22061 converting profile fields to real plugins with lang packs
[moodle.git] / user / profile / definelib.php
CommitLineData
8bdc9cac 1<?php
bb6d3d34 2
3class profile_define_base {
4
5 /**
6 * Prints out the form snippet for creating or editing a profile field
7 * @param object instance of the moodleform class
8 */
9 function define_form(&$form) {
10 $form->addElement('header', '_commonsettings', get_string('profilecommonsettings', 'admin'));
11 $this->define_form_common($form);
12
13 $form->addElement('header', '_specificsettings', get_string('profilespecificsettings', 'admin'));
14 $this->define_form_specific($form);
15 }
16
17 /**
18 * Prints out the form snippet for the part of creating or
19 * editing a profile field common to all data types
20 * @param object instance of the moodleform class
21 */
22 function define_form_common(&$form) {
23
24 $strrequired = get_string('required');
25
1bf65e58 26 $form->addElement('text', 'shortname', get_string('profileshortname', 'admin'), 'maxlength="100" size="25"');
bb6d3d34 27 $form->addRule('shortname', $strrequired, 'required', null, 'client');
28 $form->setType('shortname', PARAM_ALPHANUM);
29
1bf65e58 30 $form->addElement('text', 'name', get_string('profilename', 'admin'), 'size="50"');
bb6d3d34 31 $form->addRule('name', $strrequired, 'required', null, 'client');
32 $form->setType('name', PARAM_MULTILANG);
33
8bdc9cac 34 $form->addElement('editor', 'description', get_string('profiledescription', 'admin'), null, null);
80f69dc0 35 $form->setHelpButton('description', array('text2', get_string('helptext')));
bb6d3d34 36
37 $form->addElement('selectyesno', 'required', get_string('profilerequired', 'admin'));
38
39 $form->addElement('selectyesno', 'locked', get_string('profilelocked', 'admin'));
40
62ebb000 41 $form->addElement('selectyesno', 'forceunique', get_string('profileforceunique', 'admin'));
aa6c1ced 42
62ebb000 43 $form->addElement('selectyesno', 'signup', get_string('profilesignup', 'admin'));
44
bb6d3d34 45 $choices = array();
46 $choices[PROFILE_VISIBLE_NONE] = get_string('profilevisiblenone', 'admin');
47 $choices[PROFILE_VISIBLE_PRIVATE] = get_string('profilevisibleprivate', 'admin');
48 $choices[PROFILE_VISIBLE_ALL] = get_string('profilevisibleall', 'admin');
49 $form->addElement('select', 'visible', get_string('profilevisible', 'admin'), $choices);
50 $form->setHelpButton('visible', array('profilevisible', get_string('profilevisible','admin')));
51 $form->setDefault('visible', PROFILE_VISIBLE_ALL);
52
53 $choices = profile_list_categories();
54 $form->addElement('select', 'categoryid', get_string('profilecategory', 'admin'), $choices);
55 }
56
57 /**
58 * Prints out the form snippet for the part of creating or
59 * editing a profile field specific to the current data type
60 * @param object instance of the moodleform class
61 */
62 function define_form_specific(&$form) {
63 /// do nothing - overwrite if necessary
64 }
65
66 /**
67 * Validate the data from the add/edit profile field form.
68 * Generally this method should not be overwritten by child
69 * classes.
70 * @param object data from the add/edit profile field form
71 * @return array associative array of error messages
72 */
a78890d5 73 function define_validate($data, $files) {
bb6d3d34 74
75 $data = (object)$data;
76 $err = array();
77
a78890d5 78 $err += $this->define_validate_common($data, $files);
79 $err += $this->define_validate_specific($data, $files);
bb6d3d34 80
a78890d5 81 return $err;
bb6d3d34 82 }
83
84 /**
85 * Validate the data from the add/edit profile field form
86 * that is common to all data types. Generally this method
87 * should not be overwritten by child classes.
88 * @param object data from the add/edit profile field form
89 * @return array associative array of error messages
90 */
a78890d5 91 function define_validate_common($data, $files) {
5d910388 92 global $USER, $DB;
093c3b90 93
bb6d3d34 94 $err = array();
95
1bf65e58 96 /// Check the shortname was not truncated by cleaning
97 if (empty($data->shortname)) {
98 $err['shortname'] = get_string('required');
99
093c3b90 100 } else {
101 /// Fetch field-record from DB
5d910388 102 $field = $DB->get_record('user_info_field', array('shortname'=>$data->shortname));
bb6d3d34 103 /// Check the shortname is unique
093c3b90 104 if ($field and $field->id <> $data->id) {
105 $err['shortname'] = get_string('profileshortnamenotunique', 'admin');
cfdb1706 106
107 /// Shortname must also be unique compared to the standard user fields
093c3b90 108 } else if (!$field and isset($USER->{$data->shortname})) {
109 $err['shortname'] = get_string('profileshortnamenotunique', 'admin');
110 }
bb6d3d34 111 }
112
113 /// No further checks necessary as the form class will take care of it
bb6d3d34 114 return $err;
115 }
116
117 /**
118 * Validate the data from the add/edit profile field form
119 * that is specific to the current data type
120 * @param object data from the add/edit profile field form
121 * @return array associative array of error messages
122 */
a78890d5 123 function define_validate_specific($data, $files) {
bb6d3d34 124 /// do nothing - overwrite if necessary
125 return array();
126 }
127
128 /**
129 * Alter form based on submitted or existing data
130 * @param object form
131 */
132 function define_after_data(&$mform) {
133 /// do nothing - overwrite if necessary
134 }
135
136 /**
137 * Add a new profile field or save changes to current field
138 * @param object data from the add/edit profile field form
139 * @return boolean status of the insert/update record
140 */
141 function define_save($data) {
5d910388 142 global $DB;
bb6d3d34 143
144 $data = $this->define_save_preprocess($data); /// hook for child classes
145
f787e105 146 $old = false;
147 if (!empty($data->id)) {
148 $old = $DB->get_record('user_info_field', array('id'=>(int)$data->id));
149 }
bb6d3d34 150
151 /// check to see if the category has changed
152 if (!$old or $old->categoryid != $data->categoryid) {
5d910388 153 $data->sortorder = $DB->count_records('user_info_field', array('categoryid'=>$data->categoryid)) + 1;
bb6d3d34 154 }
155
156
157 if (empty($data->id)) {
158 unset($data->id);
90ee78e2 159 $data->id = $DB->insert_record('user_info_field', $data);
bb6d3d34 160 } else {
90ee78e2 161 $DB->update_record('user_info_field', $data);
bb6d3d34 162 }
163 }
164
165 /**
166 * Preprocess data from the add/edit profile field form
167 * before it is saved. This method is a hook for the child
168 * classes to overwrite.
169 * @param object data from the add/edit profile field form
170 * @return object processed data object
171 */
172 function define_save_preprocess($data) {
173 /// do nothing - overwrite if necessary
174 return $data;
175 }
176
8bdc9cac
SH
177 /**
178 * Provides a method by which we can allow the default data in profile_define_*
179 * to use an editor
180 *
181 * This should return an array of editor names (which will need to be formatted/cleaned)
182 *
183 * @return array
184 */
185 function define_editors() {
186 return array();
187 }
bb6d3d34 188}
189
190
191
192/**
193 * Reorder the profile fields within a given category starting
194 * at the field at the given startorder
195 */
196function profile_reorder_fields() {
5d910388 197 global $DB;
198
199 if ($categories = $DB->get_records('user_info_category')) {
bb6d3d34 200 foreach ($categories as $category) {
258db59a 201 $i = 1;
5d910388 202 if ($fields = $DB->get_records('user_info_field', array('categoryid'=>$category->id), 'sortorder ASC')) {
bb6d3d34 203 foreach ($fields as $field) {
204 $f = new object();
258db59a 205 $f->id = $field->id;
bb6d3d34 206 $f->sortorder = $i++;
5d910388 207 $DB->update_record('user_info_field', $f);
bb6d3d34 208 }
209 }
210 }
211 }
212}
213
214/**
215 * Reorder the profile categoriess starting at the category
216 * at the given startorder
217 */
218function profile_reorder_categories() {
5d910388 219 global $DB;
220
bb6d3d34 221 $i = 1;
5d910388 222 if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) {
bb6d3d34 223 foreach ($categories as $cat) {
224 $c = new object();
225 $c->id = $cat->id;
226 $c->sortorder = $i++;
5d910388 227 $DB->update_record('user_info_category', $c);
bb6d3d34 228 }
229 }
230}
231
232/**
233 * Delete a profile category
234 * @param integer id of the category to be deleted
235 * @return boolean success of operation
236 */
237function profile_delete_category($id) {
5d910388 238 global $DB;
239
bb6d3d34 240 /// Retrieve the category
5d910388 241 if (!$category = $DB->get_record('user_info_category', array('id'=>$id))) {
d3248238 242 print_error('invalidcategoryid');
bb6d3d34 243 }
244
5d910388 245 if (!$categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) {
d3248238 246 print_error('nocate', 'debug');
bb6d3d34 247 }
248
249 unset($categories[$category->id]);
250
251 if (!count($categories)) {
252 return; //we can not delete the last category
253 }
254
255 /// Does the category contain any fields
c7da4357 256 if ($DB->count_records('user_info_field', array('categoryid'=>$category->id))) {
bb6d3d34 257 if (array_key_exists($category->sortorder-1, $categories)) {
258 $newcategory = $categories[$category->sortorder-1];
259 } else if (array_key_exists($category->sortorder+1, $categories)) {
260 $newcategory = $categories[$category->sortorder+1];
261 } else {
262 $newcategory = reset($categories); // get first category if sortorder broken
263 }
264
5d910388 265 $sortorder = $DB->count_records('user_info_field', array('categoryid'=>$newcategory->id)) + 1;
bb6d3d34 266
5d910388 267 if ($fields = $DB->get_records('user_info_field', array('categoryid'=>$category->id), 'sortorder ASC')) {
bb6d3d34 268 foreach ($fields as $field) {
269 $f = new object();
270 $f->id = $field->id;
271 $f->sortorder = $sortorder++;
272 $f->categoryid = $newcategory->id;
5d910388 273 $DB->update_record('user_info_field', $f);
274 //echo "<pre>";var_dump($f);echo"</pre>";
bb6d3d34 275 }
276 }
277 }
278
279 /// Finally we get to delete the category
bf8e93d7 280 $DB->delete_records('user_info_category', array('id'=>$category->id));
bb6d3d34 281 profile_reorder_categories();
282 return true;
283}
284
285
286function profile_delete_field($id) {
5d910388 287 global $DB;
bb6d3d34 288
289 /// Remove any user data associated with this field
5d910388 290 if (!$DB->delete_records('user_info_data', array('fieldid'=>$id))) {
d3248238 291 print_error('cannotdeletecustomfield');
bb6d3d34 292 }
293
294 /// Try to remove the record from the database
5d910388 295 $DB->delete_records('user_info_field', array('id'=>$id));
bb6d3d34 296
297 /// Reorder the remaining fields in the same category
298 profile_reorder_fields();
299}
300
301/**
302 * Change the sortorder of a field
303 * @param integer id of the field
304 * @param string direction of move
305 * @return boolean success of operation
306 */
a5d3b072 307function profile_move_field($id, $move) {
5d910388 308 global $DB;
309
bb6d3d34 310 /// Get the field object
5d910388 311 if (!$field = $DB->get_record('user_info_field', array('id'=>$id), 'id, sortorder, categoryid')) {
bb6d3d34 312 return false;
313 }
314 /// Count the number of fields in this category
5d910388 315 $fieldcount = $DB->count_records('user_info_field', array('categoryid'=>$field->categoryid));
bb6d3d34 316
317 /// Calculate the new sortorder
318 if ( ($move == 'up') and ($field->sortorder > 1)) {
319 $neworder = $field->sortorder - 1;
320 } elseif ( ($move == 'down') and ($field->sortorder < $fieldcount)) {
321 $neworder = $field->sortorder + 1;
322 } else {
323 return false;
324 }
325
326 /// Retrieve the field object that is currently residing in the new position
5d910388 327 if ($swapfield = $DB->get_record('user_info_field', array('categoryid'=>$field->categoryid, 'sortorder'=>$neworder), 'id, sortorder')) {
bb6d3d34 328
329 /// Swap the sortorders
330 $swapfield->sortorder = $field->sortorder;
331 $field->sortorder = $neworder;
332
333 /// Update the field records
5d910388 334 $DB->update_record('user_info_field', $field);
335 $DB->update_record('user_info_field', $swapfield);
bb6d3d34 336 }
337
338 profile_reorder_fields();
339}
340
341/**
342 * Change the sortorder of a category
343 * @param integer id of the category
344 * @param string direction of move
345 * @return boolean success of operation
346 */
a5d3b072 347function profile_move_category($id, $move) {
5d910388 348 global $DB;
bb6d3d34 349 /// Get the category object
5d910388 350 if (!($category = $DB->get_record('user_info_category', array('id'=>$id), 'id, sortorder'))) {
bb6d3d34 351 return false;
352 }
353
354 /// Count the number of categories
5d910388 355 $categorycount = $DB->count_records('user_info_category');
bb6d3d34 356
357 /// Calculate the new sortorder
358 if ( ($move == 'up') and ($category->sortorder > 1)) {
359 $neworder = $category->sortorder - 1;
360 } elseif ( ($move == 'down') and ($category->sortorder < $categorycount)) {
361 $neworder = $category->sortorder + 1;
362 } else {
363 return false;
364 }
365
366 /// Retrieve the category object that is currently residing in the new position
5d910388 367 if ($swapcategory = $DB->get_record('user_info_category', array('sortorder'=>$neworder),'id, sortorder')) {
bb6d3d34 368
369 /// Swap the sortorders
370 $swapcategory->sortorder = $category->sortorder;
371 $category->sortorder = $neworder;
372
373 /// Update the category records
5d910388 374 if ($DB->update_record('user_info_category', $category) and $DB->update_record('user_info_category', $swapcategory)) {
bb6d3d34 375 return true;
376 }
377 }
378
379 return false;
380}
381
382/**
383 * Retrieve a list of all the available data types
384 * @return array a list of the datatypes suitable to use in a select statement
385 */
386function profile_list_datatypes() {
387 global $CFG;
388
389 $datatypes = array();
390
859b00d0
PS
391 $plugins = get_plugin_list('profilefield');
392 foreach ($plugins as $type=>$unused) {
393 $datatypes[$type] = get_string('pluginname', 'profilefield_'.$type);
bb6d3d34 394 }
b77bbd2f 395 asort($datatypes);
396
bb6d3d34 397 return $datatypes;
398}
399
400/**
401 * Retrieve a list of categories and ids suitable for use in a form
402 * @return array
403 */
404function profile_list_categories() {
5d910388 405 global $DB;
406 if (!$categories = $DB->get_records_menu('user_info_category', NULL, 'sortorder ASC', 'id, name')) {
bb6d3d34 407 $categories = array();
408 }
409 return $categories;
410}
411
412
413/// Are we adding or editing a cateogory?
1ae083e4 414function profile_edit_category($id, $redirect) {
8fa89bfd 415 global $CFG, $DB, $OUTPUT;
bb6d3d34 416
417 require_once('index_category_form.php');
418 $categoryform = new category_form();
419
5d910388 420 if ($category = $DB->get_record('user_info_category', array('id'=>$id))) {
bb6d3d34 421 $categoryform->set_data($category);
422 }
423
424 if ($categoryform->is_cancelled()) {
425 redirect($redirect);
426 } else {
294ce987 427 if ($data = $categoryform->get_data()) {
bb6d3d34 428 if (empty($data->id)) {
429 unset($data->id);
c7da4357 430 $data->sortorder = $DB->count_records('user_info_category') + 1;
90ee78e2 431 $DB->insert_record('user_info_category', $data, false);
bb6d3d34 432 } else {
90ee78e2 433 $DB->update_record('user_info_category', $data);
bb6d3d34 434 }
435 profile_reorder_categories();
436 redirect($redirect);
437
438 }
439
440 if (empty($id)) {
441 $strheading = get_string('profilecreatenewcategory', 'admin');
442 } else {
6ba65fa0 443 $strheading = get_string('profileeditcategory', 'admin', format_string($category->name));
bb6d3d34 444 }
445
446 /// Print the page
61ef8f9f 447 echo $OUTPUT->header();
f24ca3ce 448 echo $OUTPUT->heading($strheading);
bb6d3d34 449 $categoryform->display();
f24ca3ce 450 echo $OUTPUT->footer();
bb6d3d34 451 die;
452 }
453
454}
455
1ae083e4 456function profile_edit_field($id, $datatype, $redirect) {
8bdc9cac 457 global $CFG, $DB, $OUTPUT, $PAGE;
bb6d3d34 458
5d910388 459 if (!$field = $DB->get_record('user_info_field', array('id'=>$id))) {
bb6d3d34 460 $field = new object();
461 $field->datatype = $datatype;
8bdc9cac
SH
462 $field->description = '';
463 $field->descriptionformat = FORMAT_HTML;
464 $field->defaultdata = '';
465 $field->defaultdataformat = FORMAT_HTML;
bb6d3d34 466 }
467
8bdc9cac
SH
468
469 // Clean and prepare description for the editor
470 $field->description = clean_text($field->description, $field->descriptionformat);
471 $field->description = array('text'=>$field->description, 'format'=>$field->descriptionformat, 'itemid'=>0);
472
bb6d3d34 473 require_once('index_field_form.php');
474 $fieldform = new field_form(null, $field->datatype);
8bdc9cac
SH
475
476 // Convert the data format for
477 if (is_array($fieldform->editors())) {
478 foreach ($fieldform->editors() as $editor) {
479 if (isset($field->$editor)) {
480 $field->$editor = clean_text($field->$editor, $field->{$editor.'format'});
481 $field->$editor = array('text'=>$field->$editor, 'format'=>$field->{$editor.'format'}, 'itemid'=>0);
482 }
483 }
484 }
485
bb6d3d34 486 $fieldform->set_data($field);
487
488 if ($fieldform->is_cancelled()) {
489 redirect($redirect);
490
491 } else {
492 if ($data = $fieldform->get_data()) {
493 require_once($CFG->dirroot.'/user/profile/field/'.$datatype.'/define.class.php');
494 $newfield = 'profile_define_'.$datatype;
495 $formfield = new $newfield();
8bdc9cac
SH
496
497 // Collect the description and format back into the proper data structure from the editor
498 // Note: This field will ALWAYS be an editor
499 $data->descriptionformat = $data->description['format'];
500 $data->description = $data->description['text'];
501
502 // Check whether the default data is an editor, this is (currently) only the
503 // textarea field type
504 if (is_array($data->defaultdata) && array_key_exists('text', $data->defaultdata)) {
505 // Collect the default data and format back into the proper data structure from the editor
506 $data->defaultdataformat = $data->defaultdata['format'];
507 $data->defaultdata = $data->defaultdata['text'];
508 }
509
510 // Convert the data format for
511 if (is_array($fieldform->editors())) {
512 foreach ($fieldform->editors() as $editor) {
513 if (isset($field->$editor)) {
514 $field->{$editor.'format'} = $field->{$editor}['format'];
515 $field->$editor = $field->{$editor}['text'];
516 }
517 }
518 }
519
bb6d3d34 520 $formfield->define_save($data);
521 profile_reorder_fields();
522 profile_reorder_categories();
523 redirect($redirect);
524 }
525
526 $datatypes = profile_list_datatypes();
527
528 if (empty($id)) {
529 $strheading = get_string('profilecreatenewfield', 'admin', $datatypes[$datatype]);
530 } else {
531 $strheading = get_string('profileeditfield', 'admin', $field->name);
532 }
533
534 /// Print the page
8bdc9cac 535 $PAGE->navbar->add($strheading);
61ef8f9f 536 echo $OUTPUT->header();
f24ca3ce 537 echo $OUTPUT->heading($strheading);
bb6d3d34 538 $fieldform->display();
f24ca3ce 539 echo $OUTPUT->footer();
bb6d3d34 540 die;
541 }
542}
543
aa6c1ced 544