extra_field_option.lib.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Declaration of the ExtraFieldOption class
  5. */
  6. /**
  7. * Handles the extra fields for various objects (users, sessions, courses)
  8. */
  9. class ExtraFieldOption extends Model {
  10. public $columns = array('id', 'field_id', 'option_value', 'option_display_text', 'option_order', 'tms');
  11. /**
  12. * Gets the table for the type of object for which we are using an extra field
  13. * @param string Type of object (course, user or session)
  14. */
  15. public function __construct($type) {
  16. $this->type = $type;
  17. switch ($this->type) {
  18. case 'course':
  19. $this->table = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_OPTIONS);
  20. break;
  21. case 'user':
  22. $this->table = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  23. break;
  24. case 'session':
  25. $this->table = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_OPTIONS);
  26. break;
  27. }
  28. }
  29. /**
  30. * Gets the number of options already available in the table for this item type
  31. * @return int Number of options available
  32. * @assert () >= 0
  33. */
  34. public function get_count() {
  35. $row = Database::select('count(*) as count', $this->table, array(), 'first');
  36. return $row['count'];
  37. }
  38. /**
  39. * Gets the number of options available for this field
  40. * @param int Field ID
  41. * @return int Number of options
  42. * @assert ('') === false
  43. * @assert (-1) == 0
  44. * @assert (0) == 0
  45. */
  46. public function get_count_by_field_id($field_id) {
  47. if (empty($field_id)) {
  48. return false;
  49. }
  50. $row = Database::select('count(*) as count', $this->table, array('where' => array('field_id = ?' => $field_id)), 'first');
  51. return $row['count'];
  52. }
  53. /**
  54. * Returns a list of options for a specific field, separated by ";"
  55. * @param int Field ID
  56. * @param bool Indicates whether we want the results to be given with their id
  57. * @param string Order by clause (without the "order by") to be added to the SQL query
  58. * @return string List of options separated by ;
  59. * @assert (-1, false, null) == ''
  60. */
  61. public function get_field_options_to_string($field_id, $add_id_in_array = false, $ordered_by = null) {
  62. $options = self::get_field_options_by_field($field_id, $add_id_in_array, $ordered_by);
  63. $new_options = array();
  64. if (!empty($options)) {
  65. foreach ($options as $option) {
  66. $new_options[] = $option['option_value'].':'.$option['option_display_text'];
  67. }
  68. $string = implode(';', $new_options);
  69. return $string;
  70. }
  71. return '';
  72. }
  73. /**
  74. * Delete all the options of a specific field
  75. * @param int Field ID
  76. * @result void
  77. * @assert (-1) === false
  78. */
  79. public function delete_all_options_by_field_id($field_id) {
  80. $field_id = intval($field_id);
  81. $sql = "DELETE FROM {$this->table} WHERE field_id = $field_id";
  82. $r = Database::query($sql);
  83. return $r;
  84. }
  85. /**
  86. * Saves an option into the corresponding *_field_options table
  87. * @param array Parameters to be considered for the insertion
  88. * @param bool Whether to show the query (sent to the parent save() method)
  89. * @return bool True on success, false on error
  90. * @assert (array('field_id'=>0), false) === false
  91. * @assert (array('field_id'=>1), false) === true
  92. */
  93. public function save($params, $show_query = false) {
  94. $field_id = intval($params['field_id']);
  95. if (empty($field_id)) {
  96. return false;
  97. }
  98. $time = api_get_utc_datetime();
  99. if (!empty($params['field_options']) &&
  100. in_array($params['field_type'], array(
  101. ExtraField::FIELD_TYPE_RADIO,
  102. ExtraField::FIELD_TYPE_SELECT,
  103. ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
  104. ExtraField::FIELD_TYPE_DOUBLE_SELECT))
  105. ) {
  106. if ($params['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
  107. //$params['field_options'] = France:Paris;Bretagne;Marseilles;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura;
  108. $options_parsed = ExtraField::extra_field_double_select_convert_string_to_array($params['field_options']);
  109. if (!empty($options_parsed)) {
  110. foreach ($options_parsed as $key => $option) {
  111. $sub_options = $option['options'];
  112. $new_params = array(
  113. 'field_id' => $field_id,
  114. 'option_value' => 0,
  115. 'option_display_text' => $option['label'],
  116. 'option_order' => 0,
  117. 'tms' => $time,
  118. );
  119. //Looking if option already exists:
  120. $option_info = self::get_field_option_by_field_id_and_option_display_text($field_id, $option['label']);
  121. if (empty($option_info)) {
  122. $sub_id = parent::save($new_params, $show_query);
  123. } else {
  124. $sub_id = $option_info['id'];
  125. $new_params['id'] = $sub_id;
  126. parent::update($new_params, $show_query);
  127. }
  128. foreach ($sub_options as $sub_option) {
  129. if (!empty($sub_option)) {
  130. $new_params = array(
  131. 'field_id' => $field_id,
  132. 'option_value' => $sub_id,
  133. 'option_display_text' => $sub_option,
  134. 'option_order' => 0,
  135. 'tms' => $time,
  136. );
  137. $option_info = self::get_field_option_by_field_id_and_option_display_text_and_option_value($field_id, $sub_option, $sub_id);
  138. if (empty($option_info)) {
  139. parent::save($new_params, $show_query);
  140. } else {
  141. $new_params['id'] = $option_info['id'];
  142. parent::update($new_params, $show_query);
  143. }
  144. }
  145. }
  146. }
  147. }
  148. $list = array();
  149. } else {
  150. $list = explode(';', $params['field_options']);
  151. }
  152. if (!empty($list)) {
  153. foreach ($list as $option) {
  154. $option_info = self::get_field_option_by_field_and_option($field_id, $option);
  155. if ($option_info == false) {
  156. $order = self::get_max_order($field_id);
  157. $new_params = array(
  158. 'field_id' => $field_id,
  159. 'option_value' => $option,
  160. 'option_display_text' => $option,
  161. 'option_order' => $order,
  162. 'tms' => $time,
  163. );
  164. parent::save($new_params, $show_query);
  165. }
  166. }
  167. }
  168. }
  169. return true;
  170. }
  171. /**
  172. * Save one option item at a time
  173. * @param array Parameters specific to the option
  174. * @param bool Whether to show the query (sent to parent save() method)
  175. * @param bool Whether to insert even if the option already exists
  176. * @return bool True on success, false on failure
  177. * @assert (array('field_id'=>0),false) === false
  178. * @assert (array('field_id'=>0),false) === true
  179. */
  180. public function save_one_item($params, $show_query = false, $insert_repeated = true) {
  181. $field_id = intval($params['field_id']);
  182. if (empty($field_id)) {
  183. return false;
  184. }
  185. $params['tms'] = api_get_utc_datetime();
  186. if (empty($params['option_order'])) {
  187. $order = self::get_max_order($field_id);
  188. $params['option_order'] = $order;
  189. }
  190. if ($insert_repeated) {
  191. parent::save($params, $show_query);
  192. } else {
  193. $check = self::get_field_option_by_field_and_option($field_id, $params['option_value']);
  194. if ($check == false) {
  195. parent::save($params, $show_query);
  196. }
  197. }
  198. return true;
  199. }
  200. /**
  201. * Get the complete row of a specific option of a specific field
  202. * @param int Field ID
  203. * @param string Value of the option
  204. * @return mixed The row on success or false on failure
  205. * @assert (0,'') === false
  206. */
  207. public function get_field_option_by_field_and_option($field_id, $option_value) {
  208. $field_id = intval($field_id);
  209. $option_value = Database::escape_string($option_value);
  210. $sql = "SELECT * FROM {$this->table} WHERE field_id = $field_id AND option_value = '".$option_value."'";
  211. $result = Database::query($sql);
  212. if (Database::num_rows($result) > 0) {
  213. return Database::store_result($result, 'ASSOC');
  214. }
  215. return false;
  216. }
  217. /**
  218. * Get the complete row of a specific option's display text of a specific field
  219. * @param int Field ID
  220. * @param string Display value of the option
  221. * @return mixed The row on success or false on failure
  222. * @assert (0, '') === false
  223. */
  224. public function get_field_option_by_field_id_and_option_display_text($field_id, $option_display_text) {
  225. $field_id = intval($field_id);
  226. $option_display_text = Database::escape_string($option_display_text);
  227. $sql = "SELECT * FROM {$this->table} WHERE field_id = $field_id AND option_display_text = '".$option_display_text."'";
  228. $result = Database::query($sql);
  229. if (Database::num_rows($result) > 0) {
  230. return Database::fetch_array($result, 'ASSOC');
  231. }
  232. return false;
  233. }
  234. /**
  235. * Get the complete row of a specific option's display text of a specific field
  236. * @param int Field ID
  237. * @param string Display value of the option
  238. * @param string Value of the option
  239. * @return mixed The row on success or false on failure
  240. * @assert (0, '', '') === false
  241. */
  242. public function get_field_option_by_field_id_and_option_display_text_and_option_value($field_id, $option_display_text, $option_value) {
  243. $field_id = intval($field_id);
  244. $option_display_text = Database::escape_string($option_display_text);
  245. $option_value = Database::escape_string($option_value);
  246. $sql = "SELECT * FROM {$this->table} WHERE field_id = $field_id AND option_display_text = '".$option_display_text."' AND option_value = '$option_value'";
  247. $result = Database::query($sql);
  248. if (Database::num_rows($result) > 0) {
  249. return Database::fetch_array($result, 'ASSOC');
  250. }
  251. return false;
  252. }
  253. /**
  254. * Gets an array of options for a specific field
  255. * @param int The field ID
  256. * @param bool Whether to add the row ID in the result
  257. * @param string Extra ordering query bit
  258. * @result mixed Row on success, false on failure
  259. * @assert (0, '') === false
  260. */
  261. public function get_field_options_by_field($field_id, $add_id_in_array = false, $ordered_by = null) {
  262. $field_id = intval($field_id);
  263. $sql = "SELECT * FROM {$this->table}
  264. WHERE field_id = $field_id ";
  265. if (!empty($ordered_by)) {
  266. $sql .= " ORDER BY $ordered_by ";
  267. }
  268. $result = Database::query($sql);
  269. if (Database::num_rows($result) > 0) {
  270. if ($add_id_in_array) {
  271. $options = array();
  272. while ($row = Database::fetch_array($result, 'ASSOC')) {
  273. $options[$row['id']] = $row;
  274. }
  275. return $options;
  276. } else {
  277. return Database::store_result($result, 'ASSOC');
  278. }
  279. }
  280. return false;
  281. }
  282. /**
  283. * Get options for a specific field as array or in JSON format suited for the double-select format
  284. * @param int Field ID
  285. * @param int Option value ID
  286. * @param bool Return format (whether it should be formatted to JSON or not)
  287. * @return mixed Row/JSON on success
  288. */
  289. public function get_second_select_field_options_by_field($field_id, $option_value_id, $to_json = false) {
  290. $field_id = intval($field_id);
  291. $option_value_id = intval($option_value_id);
  292. $options = array();
  293. $sql = "SELECT * FROM {$this->table}
  294. WHERE field_id = $field_id AND option_value = $option_value_id
  295. ORDER BY option_display_text";
  296. $result = Database::query($sql);
  297. if (Database::num_rows($result) > 0) {
  298. $options = Database::store_result($result, 'ASSOC');
  299. }
  300. if ($to_json) {
  301. $string = null;
  302. if (!empty($options)) {
  303. $array = array();
  304. foreach ($options as $option) {
  305. $array[$option['id']] = $option['option_display_text'];
  306. }
  307. $string = json_encode($array);
  308. }
  309. return $string;
  310. }
  311. return $options;
  312. }
  313. /**
  314. * Get options for a specific field as string split by ;
  315. * @param int Field ID
  316. * @param string Extra query bit for reordering
  317. * @return string HTML string of options
  318. * @assert (0, '') === null
  319. */
  320. public function get_field_options_by_field_to_string($field_id, $ordered_by = null) {
  321. $field = new ExtraField($this->type);
  322. $field_info = $field->get($field_id);
  323. $options = self::get_field_options_by_field($field_id, false, $ordered_by);
  324. $elements = array();
  325. if (!empty($options)) {
  326. switch ($field_info['field_type']) {
  327. case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
  328. $html = ExtraField::extra_field_double_select_convert_array_to_string($options);
  329. break;
  330. default:
  331. foreach ($options as $option) {
  332. $elements[]= $option['option_value'];
  333. }
  334. $html = implode(';', $elements);
  335. break;
  336. }
  337. return $html;
  338. }
  339. return null;
  340. }
  341. /**
  342. * Get the maximum order value for a specific field
  343. * @param int Field ID
  344. * @return int Current max ID + 1 (we start from 0)
  345. * @assert (0, '') === 1
  346. */
  347. public function get_max_order($field_id) {
  348. $field_id = intval($field_id);
  349. $sql = "SELECT MAX(option_order) FROM {$this->table} WHERE field_id = $field_id";
  350. $res = Database::query($sql);
  351. $max = 1;
  352. if (Database::num_rows($res) > 0) {
  353. $row = Database::fetch_array($res);
  354. $max = $row[0] + 1;
  355. }
  356. return $max;
  357. }
  358. /**
  359. * Update the option using the given params
  360. * @param array Parameters with the data to be saved
  361. */
  362. public function update($params) {
  363. parent::update($params);
  364. }
  365. /**
  366. * Display a form with the options for the field_id given in REQUEST
  367. * @return void Prints output
  368. */
  369. function display() {
  370. // action links
  371. echo '<div class="actions">';
  372. //echo '<a href="../admin/index.php">'.Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'),'', ICON_SIZE_MEDIUM).'</a>';
  373. $field_id = isset($_REQUEST['field_id']) ? intval($_REQUEST['field_id']) : null;
  374. echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'&field_id='.$field_id.'">'.Display::return_icon('add_user_fields.png',get_lang('Add'),'', ICON_SIZE_MEDIUM).'</a>';
  375. echo '</div>';
  376. echo Display::grid_html('extra_field_options');
  377. }
  378. /**
  379. * Returns an HTML form for the current field
  380. * @param string URL to send the form to (action=...)
  381. * @param string Type of action to offer through the form (edit, usually)
  382. * @return string HTML form
  383. */
  384. public function return_form($url, $action) {
  385. $form_name = $this->type.'_field';
  386. $form = new FormValidator($form_name, 'post', $url);
  387. // Settting the form elements
  388. $header = get_lang('Add');
  389. if ($action == 'edit') {
  390. $header = get_lang('Modify');
  391. }
  392. $form->addElement('header', $header);
  393. $id = isset($_GET['id']) ? intval($_GET['id']) : '';
  394. $form->addElement('hidden', 'id', $id);
  395. $form->addElement('hidden', 'type', $this->type);
  396. $form->addElement('hidden', 'field_id', $this->field_id);
  397. $form->addElement('text', 'option_display_text', get_lang('Name'), array('class' => 'span5'));
  398. $form->addElement('text', 'option_value', get_lang('Value'), array('class' => 'span5'));
  399. $form->addElement('text', 'option_order', get_lang('Order'), array('class' => 'span2'));
  400. $defaults = array();
  401. if ($action == 'edit') {
  402. // Setting the defaults
  403. $defaults = $this->get($id);
  404. $form->freeze('option_value');
  405. $form->addElement('button', 'submit', get_lang('Modify'), 'class="save"');
  406. } else {
  407. $form->addElement('button', 'submit', get_lang('Add'), 'class="save"');
  408. }
  409. $form->setDefaults($defaults);
  410. // Setting the rules
  411. $form->addRule('option_display_text', get_lang('ThisFieldIsRequired'), 'required');
  412. //$form->addRule('field_variable', get_lang('ThisFieldIsRequired'), 'required');
  413. $form->addRule('option_value', get_lang('ThisFieldIsRequired'), 'required');
  414. return $form;
  415. }
  416. }