PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/user/profile/definelib.php

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