files MDL-20635 Added support for cleaning up files associated with a context when...
[moodle.git] / user / profile / definelib.php
CommitLineData
bb6d3d34 1<?php //$Id$
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
34 $form->addElement('htmleditor', 'description', get_string('profiledescription', 'admin'));
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'));
42
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
177}
178
179
180
181/**
182 * Reorder the profile fields within a given category starting
183 * at the field at the given startorder
184 */
185function profile_reorder_fields() {
5d910388 186 global $DB;
187
188 if ($categories = $DB->get_records('user_info_category')) {
bb6d3d34 189 foreach ($categories as $category) {
258db59a 190 $i = 1;
5d910388 191 if ($fields = $DB->get_records('user_info_field', array('categoryid'=>$category->id), 'sortorder ASC')) {
bb6d3d34 192 foreach ($fields as $field) {
193 $f = new object();
258db59a 194 $f->id = $field->id;
bb6d3d34 195 $f->sortorder = $i++;
5d910388 196 $DB->update_record('user_info_field', $f);
bb6d3d34 197 }
198 }
199 }
200 }
201}
202
203/**
204 * Reorder the profile categoriess starting at the category
205 * at the given startorder
206 */
207function profile_reorder_categories() {
5d910388 208 global $DB;
209
bb6d3d34 210 $i = 1;
5d910388 211 if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) {
bb6d3d34 212 foreach ($categories as $cat) {
213 $c = new object();
214 $c->id = $cat->id;
215 $c->sortorder = $i++;
5d910388 216 $DB->update_record('user_info_category', $c);
bb6d3d34 217 }
218 }
219}
220
221/**
222 * Delete a profile category
223 * @param integer id of the category to be deleted
224 * @return boolean success of operation
225 */
226function profile_delete_category($id) {
5d910388 227 global $DB;
228
bb6d3d34 229 /// Retrieve the category
5d910388 230 if (!$category = $DB->get_record('user_info_category', array('id'=>$id))) {
d3248238 231 print_error('invalidcategoryid');
bb6d3d34 232 }
233
5d910388 234 if (!$categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) {
d3248238 235 print_error('nocate', 'debug');
bb6d3d34 236 }
237
238 unset($categories[$category->id]);
239
240 if (!count($categories)) {
241 return; //we can not delete the last category
242 }
243
244 /// Does the category contain any fields
c7da4357 245 if ($DB->count_records('user_info_field', array('categoryid'=>$category->id))) {
bb6d3d34 246 if (array_key_exists($category->sortorder-1, $categories)) {
247 $newcategory = $categories[$category->sortorder-1];
248 } else if (array_key_exists($category->sortorder+1, $categories)) {
249 $newcategory = $categories[$category->sortorder+1];
250 } else {
251 $newcategory = reset($categories); // get first category if sortorder broken
252 }
253
5d910388 254 $sortorder = $DB->count_records('user_info_field', array('categoryid'=>$newcategory->id)) + 1;
bb6d3d34 255
5d910388 256 if ($fields = $DB->get_records('user_info_field', array('categoryid'=>$category->id), 'sortorder ASC')) {
bb6d3d34 257 foreach ($fields as $field) {
258 $f = new object();
259 $f->id = $field->id;
260 $f->sortorder = $sortorder++;
261 $f->categoryid = $newcategory->id;
5d910388 262 $DB->update_record('user_info_field', $f);
263 //echo "<pre>";var_dump($f);echo"</pre>";
bb6d3d34 264 }
265 }
266 }
267
268 /// Finally we get to delete the category
bf8e93d7 269 $DB->delete_records('user_info_category', array('id'=>$category->id));
bb6d3d34 270 profile_reorder_categories();
271 return true;
272}
273
274
275function profile_delete_field($id) {
5d910388 276 global $DB;
bb6d3d34 277
278 /// Remove any user data associated with this field
5d910388 279 if (!$DB->delete_records('user_info_data', array('fieldid'=>$id))) {
d3248238 280 print_error('cannotdeletecustomfield');
bb6d3d34 281 }
282
283 /// Try to remove the record from the database
5d910388 284 $DB->delete_records('user_info_field', array('id'=>$id));
bb6d3d34 285
286 /// Reorder the remaining fields in the same category
287 profile_reorder_fields();
288}
289
290/**
291 * Change the sortorder of a field
292 * @param integer id of the field
293 * @param string direction of move
294 * @return boolean success of operation
295 */
a5d3b072 296function profile_move_field($id, $move) {
5d910388 297 global $DB;
298
bb6d3d34 299 /// Get the field object
5d910388 300 if (!$field = $DB->get_record('user_info_field', array('id'=>$id), 'id, sortorder, categoryid')) {
bb6d3d34 301 return false;
302 }
303 /// Count the number of fields in this category
5d910388 304 $fieldcount = $DB->count_records('user_info_field', array('categoryid'=>$field->categoryid));
bb6d3d34 305
306 /// Calculate the new sortorder
307 if ( ($move == 'up') and ($field->sortorder > 1)) {
308 $neworder = $field->sortorder - 1;
309 } elseif ( ($move == 'down') and ($field->sortorder < $fieldcount)) {
310 $neworder = $field->sortorder + 1;
311 } else {
312 return false;
313 }
314
315 /// Retrieve the field object that is currently residing in the new position
5d910388 316 if ($swapfield = $DB->get_record('user_info_field', array('categoryid'=>$field->categoryid, 'sortorder'=>$neworder), 'id, sortorder')) {
bb6d3d34 317
318 /// Swap the sortorders
319 $swapfield->sortorder = $field->sortorder;
320 $field->sortorder = $neworder;
321
322 /// Update the field records
5d910388 323 $DB->update_record('user_info_field', $field);
324 $DB->update_record('user_info_field', $swapfield);
bb6d3d34 325 }
326
327 profile_reorder_fields();
328}
329
330/**
331 * Change the sortorder of a category
332 * @param integer id of the category
333 * @param string direction of move
334 * @return boolean success of operation
335 */
a5d3b072 336function profile_move_category($id, $move) {
5d910388 337 global $DB;
bb6d3d34 338 /// Get the category object
5d910388 339 if (!($category = $DB->get_record('user_info_category', array('id'=>$id), 'id, sortorder'))) {
bb6d3d34 340 return false;
341 }
342
343 /// Count the number of categories
5d910388 344 $categorycount = $DB->count_records('user_info_category');
bb6d3d34 345
346 /// Calculate the new sortorder
347 if ( ($move == 'up') and ($category->sortorder > 1)) {
348 $neworder = $category->sortorder - 1;
349 } elseif ( ($move == 'down') and ($category->sortorder < $categorycount)) {
350 $neworder = $category->sortorder + 1;
351 } else {
352 return false;
353 }
354
355 /// Retrieve the category object that is currently residing in the new position
5d910388 356 if ($swapcategory = $DB->get_record('user_info_category', array('sortorder'=>$neworder),'id, sortorder')) {
bb6d3d34 357
358 /// Swap the sortorders
359 $swapcategory->sortorder = $category->sortorder;
360 $category->sortorder = $neworder;
361
362 /// Update the category records
5d910388 363 if ($DB->update_record('user_info_category', $category) and $DB->update_record('user_info_category', $swapcategory)) {
bb6d3d34 364 return true;
365 }
366 }
367
368 return false;
369}
370
371/**
372 * Retrieve a list of all the available data types
373 * @return array a list of the datatypes suitable to use in a select statement
374 */
375function profile_list_datatypes() {
376 global $CFG;
377
378 $datatypes = array();
379
380 if ($dirlist = get_directory_list($CFG->dirroot.'/user/profile/field', '', false, true, false)) {
381 foreach ($dirlist as $type) {
b77bbd2f 382 $datatypes[$type] = get_string('profilefieldtype'.$type, 'profilefield_'.$type);
383 if (strpos($datatypes[$type], '[[') !== false) {
384 $datatypes[$type] = get_string('profilefieldtype'.$type, 'admin');
385 }
bb6d3d34 386 }
387 }
b77bbd2f 388 asort($datatypes);
389
bb6d3d34 390 return $datatypes;
391}
392
393/**
394 * Retrieve a list of categories and ids suitable for use in a form
395 * @return array
396 */
397function profile_list_categories() {
5d910388 398 global $DB;
399 if (!$categories = $DB->get_records_menu('user_info_category', NULL, 'sortorder ASC', 'id, name')) {
bb6d3d34 400 $categories = array();
401 }
402 return $categories;
403}
404
405
406/// Are we adding or editing a cateogory?
1ae083e4 407function profile_edit_category($id, $redirect) {
8fa89bfd 408 global $CFG, $DB, $OUTPUT;
bb6d3d34 409
410 require_once('index_category_form.php');
411 $categoryform = new category_form();
412
5d910388 413 if ($category = $DB->get_record('user_info_category', array('id'=>$id))) {
bb6d3d34 414 $categoryform->set_data($category);
415 }
416
417 if ($categoryform->is_cancelled()) {
418 redirect($redirect);
419 } else {
294ce987 420 if ($data = $categoryform->get_data()) {
bb6d3d34 421 if (empty($data->id)) {
422 unset($data->id);
c7da4357 423 $data->sortorder = $DB->count_records('user_info_category') + 1;
90ee78e2 424 $DB->insert_record('user_info_category', $data, false);
bb6d3d34 425 } else {
90ee78e2 426 $DB->update_record('user_info_category', $data);
bb6d3d34 427 }
428 profile_reorder_categories();
429 redirect($redirect);
430
431 }
432
433 if (empty($id)) {
434 $strheading = get_string('profilecreatenewcategory', 'admin');
435 } else {
6ba65fa0 436 $strheading = get_string('profileeditcategory', 'admin', format_string($category->name));
bb6d3d34 437 }
438
439 /// Print the page
1ae083e4 440 admin_externalpage_print_header();
f24ca3ce 441 echo $OUTPUT->heading($strheading);
bb6d3d34 442 $categoryform->display();
f24ca3ce 443 echo $OUTPUT->footer();
bb6d3d34 444 die;
445 }
446
447}
448
1ae083e4 449function profile_edit_field($id, $datatype, $redirect) {
8fa89bfd 450 global $CFG, $DB, $OUTPUT;
bb6d3d34 451
5d910388 452 if (!$field = $DB->get_record('user_info_field', array('id'=>$id))) {
bb6d3d34 453 $field = new object();
454 $field->datatype = $datatype;
455 }
456
457 require_once('index_field_form.php');
458 $fieldform = new field_form(null, $field->datatype);
459 $fieldform->set_data($field);
460
461 if ($fieldform->is_cancelled()) {
462 redirect($redirect);
463
464 } else {
465 if ($data = $fieldform->get_data()) {
466 require_once($CFG->dirroot.'/user/profile/field/'.$datatype.'/define.class.php');
467 $newfield = 'profile_define_'.$datatype;
468 $formfield = new $newfield();
469 $formfield->define_save($data);
470 profile_reorder_fields();
471 profile_reorder_categories();
472 redirect($redirect);
473 }
474
475 $datatypes = profile_list_datatypes();
476
477 if (empty($id)) {
478 $strheading = get_string('profilecreatenewfield', 'admin', $datatypes[$datatype]);
479 } else {
480 $strheading = get_string('profileeditfield', 'admin', $field->name);
481 }
482
483 /// Print the page
1ae083e4 484 admin_externalpage_print_header();
f24ca3ce 485 echo $OUTPUT->heading($strheading);
bb6d3d34 486 $fieldform->display();
f24ca3ce 487 echo $OUTPUT->footer();
bb6d3d34 488 die;
489 }
490}
491
62ebb000 492?>