PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/php/html/table/sortable_table.class.php

https://bitbucket.org/chamilo/chamilo/
PHP | 812 lines | 518 code | 53 blank | 241 comment | 47 complexity | 88e4f1f4de2004f532d141863dbce012 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. namespace common\libraries;
  3. use HTML_Table;
  4. use Pager;
  5. require_once 'table_sort.class.php';
  6. /**
  7. * This class allows you to display a sortable data-table. It is possible to
  8. * split the data in several pages.
  9. * Using this class you can:
  10. * - automatically create checkboxes of the first table column
  11. * - a "select all" and "deselect all" link is added
  12. * - only if you provide a list of actions for the selected items
  13. * - click on the table header to sort the data
  14. * - choose how many items you see per page
  15. * - navigate through all data-pages
  16. */
  17. class SortableTable extends HTML_Table
  18. {
  19. const DISPLAY_PER_PAGE_LIMIT = 500;
  20. const DISPLAY_PER_INCREMENT = 10;
  21. const DISPLAY_PER_INCREMENT_INTERVAL_LIMIT = 50;
  22. const DISPLAY_ALL = 'all';
  23. /**
  24. * A name for this table
  25. */
  26. private $table_name;
  27. /**
  28. * The page to display
  29. */
  30. private $page_nr;
  31. /**
  32. * The column to sort the data
  33. */
  34. private $column;
  35. /**
  36. * The sorting direction (SORT_ASC or SORT_DESC)
  37. */
  38. private $direction;
  39. /**
  40. * Number of items to display per page
  41. */
  42. private $per_page;
  43. /**
  44. * The default number of items to display per page
  45. */
  46. private $default_items_per_page;
  47. /**
  48. * A prefix for the URL-parameters, can be used on pages with multiple
  49. * SortableTables
  50. */
  51. private $param_prefix;
  52. /**
  53. * The pager object to split the data in several pages
  54. */
  55. private $pager;
  56. /**
  57. * The total number of items in the table
  58. */
  59. private $total_number_of_items;
  60. /**
  61. * The function to get the total number of items
  62. */
  63. private $get_total_number_function;
  64. /**
  65. * The function to the the data to display
  66. */
  67. private $get_data_function;
  68. /**
  69. * An array with defined column-filters
  70. */
  71. private $column_filters;
  72. /**
  73. * A list of actions which will be available through a select list
  74. */
  75. private $form_actions;
  76. /**
  77. * Additional parameters to pass in the URL
  78. */
  79. private $additional_parameters;
  80. /**
  81. * Additional attributes for the th-tags
  82. */
  83. private $th_attributes;
  84. /**
  85. * Additional attributes for the td-tags
  86. */
  87. private $td_attributes;
  88. /**
  89. * Additional attributes for the tr-tags
  90. */
  91. private $tr_attributes;
  92. /**
  93. * Array with names of the other tables defined on the same page of this
  94. * table
  95. */
  96. private $other_tables;
  97. /**
  98. * Create a new SortableTable
  99. * @param string $table_name A name for the table (default = 'table')
  100. * @param string $get_total_number_function A user defined function to get
  101. * the total number of items in the table
  102. * @param string $get_data_function A function to get the data to display on
  103. * the current page
  104. * @param int $default_column The default column on which the data should be
  105. * sorted
  106. * @param int $default_items_per_page The default number of items to show
  107. * on one page
  108. * @param int $default_order_direction The default order direction; either
  109. * the constant SORT_ASC or SORT_DESC
  110. */
  111. function __construct($table_name = 'table', $get_total_number_function = null, $get_data_function = null, $default_column = 1, $default_items_per_page = 20, $default_order_direction = SORT_ASC, $ajax_enabled = false)
  112. {
  113. parent :: __construct(array('class' => 'data_table', 'id' => $table_name), 0, true);
  114. $this->table_name = $table_name;
  115. $this->additional_parameters = array();
  116. $this->param_prefix = $table_name . '_';
  117. $this->page_nr = isset($_SESSION[$this->param_prefix . 'page_nr']) ? $_SESSION[$this->param_prefix . 'page_nr'] : 1;
  118. $this->page_nr = Request :: get($this->param_prefix . 'page_nr') ? Request :: get($this->param_prefix . 'page_nr') : $this->page_nr;
  119. $this->column = isset($_SESSION[$this->param_prefix . 'column']) ? $_SESSION[$this->param_prefix . 'column'] : $default_column;
  120. $this->column = ! is_null(Request :: get($this->param_prefix . 'column')) ? Request :: get($this->param_prefix . 'column') : $this->column;
  121. $this->direction = isset($_SESSION[$this->param_prefix . 'direction']) ? $_SESSION[$this->param_prefix . 'direction'] : $default_order_direction;
  122. $this->direction = Request :: get($this->param_prefix . 'direction') ? Request :: get($this->param_prefix . 'direction') : $this->direction;
  123. $this->per_page = isset($_SESSION[$this->param_prefix . 'per_page']) ? $_SESSION[$this->param_prefix . 'per_page'] : $default_items_per_page;
  124. $this->per_page = Request :: get($this->param_prefix . 'per_page') ? Request :: get($this->param_prefix . 'per_page') : $this->per_page;
  125. $_SESSION[$this->param_prefix . 'per_page'] = $this->per_page;
  126. $_SESSION[$this->param_prefix . 'direction'] = $this->direction;
  127. $_SESSION[$this->param_prefix . 'page_nr'] = $this->page_nr;
  128. $_SESSION[$this->param_prefix . 'column'] = $this->column;
  129. $this->pager = null;
  130. $this->default_items_per_page = $default_items_per_page;
  131. $this->total_number_of_items = - 1;
  132. $this->get_total_number_function = $get_total_number_function;
  133. $this->total_number_of_items = $this->get_total_number_of_items();
  134. $this->get_data_function = $get_data_function;
  135. if ($this->per_page == self :: DISPLAY_ALL)
  136. {
  137. $this->per_page = $this->total_number_of_items;
  138. }
  139. $this->ajax_enabled = $ajax_enabled;
  140. $this->column_filters = array();
  141. $this->form_actions = new ObjectTableFormActions(__NAMESPACE__);
  142. $this->checkbox_name = null;
  143. $this->td_attributes = array();
  144. $this->th_attributes = array();
  145. $this->other_tables = array();
  146. }
  147. /**
  148. * Get the Pager object to split the showed data in several pages
  149. */
  150. function get_pager()
  151. {
  152. if (is_null($this->pager))
  153. {
  154. $total_number_of_items = $this->total_number_of_items;
  155. $params['mode'] = 'Sliding';
  156. $params['perPage'] = $this->per_page;
  157. $params['totalItems'] = $total_number_of_items;
  158. $params['urlVar'] = $this->param_prefix . 'page_nr';
  159. $params['prevImg'] = '<img src="' . Theme :: get_common_image_path() . 'action_prev.png" style="vertical-align: middle;"/>';
  160. $params['nextImg'] = '<img src="' . Theme :: get_common_image_path() . 'action_next.png" style="vertical-align: middle;"/>';
  161. $params['firstPageText'] = '<img src="' . Theme :: get_common_image_path() . 'action_first.png" style="vertical-align: middle;"/>';
  162. $params['lastPageText'] = '<img src="' . Theme :: get_common_image_path() . 'action_last.png" style="vertical-align: middle;"/>';
  163. $params['firstPagePre'] = '';
  164. $params['lastPagePre'] = '';
  165. $params['firstPagePost'] = '';
  166. $params['lastPagePost'] = '';
  167. $params['spacesBeforeSeparator'] = '';
  168. $params['spacesAfterSeparator'] = '';
  169. $params['currentPage'] = $this->page_nr;
  170. $query_vars = array_keys($_GET);
  171. $query_vars_needed = array($this->param_prefix . 'column', $this->param_prefix . 'direction', $this->param_prefix . 'per_page');
  172. if (count($this->additional_parameters) > 0)
  173. {
  174. $query_vars_needed = array_merge($query_vars_needed, array_keys($this->additional_parameters));
  175. }
  176. $query_vars_exclude = array_diff($query_vars, $query_vars_needed);
  177. $params['excludeVars'] = $query_vars_exclude;
  178. $params['extraVars'] = $this->additional_parameters;
  179. $this->pager = Pager :: factory($params);
  180. }
  181. return $this->pager;
  182. }
  183. /**
  184. * Displays the table, complete with navigation buttons to browse through
  185. * the data-pages.
  186. */
  187. function display()
  188. {
  189. echo $this->as_html();
  190. }
  191. /**
  192. * Returns the complete table HTML. Alias of as_html().
  193. */
  194. function toHTML()
  195. {
  196. return $this->as_html();
  197. }
  198. function toHTML_export()
  199. {
  200. return $this->as_html(true);
  201. }
  202. /**
  203. * Returns the complete table HTML.
  204. */
  205. function as_html($empty_table = false)
  206. {
  207. if ($this->total_number_of_items == 0)
  208. {
  209. $cols = $this->getHeader()->getColCount();
  210. $this->setCellAttributes(0, 0, 'style="font-style: italic;text-align:center;" colspan=' . $cols);
  211. $this->setCellContents(0, 0, Translation :: get('NoSearchResults', null, Utilities :: COMMON_LIBRARIES));
  212. $empty_table = true;
  213. }
  214. if (! $empty_table)
  215. {
  216. $form = $this->get_page_select_form();
  217. $nav = $this->get_navigation_html();
  218. $html[] = '<table style="width:100%;">';
  219. $html[] = '<tr>';
  220. $html[] = '<td style="width:25%;">';
  221. $html[] = $form;
  222. $html[] = '</td>';
  223. $html[] = '<td style="text-align:center;">';
  224. $html[] = $this->get_table_title();
  225. $html[] = '</td>';
  226. $html[] = '<td style="text-align:right;width:25%;">';
  227. $html[] = $nav;
  228. $html[] = '</td>';
  229. $html[] = '</tr>';
  230. $html[] = '</table>';
  231. if ($this->form_actions->has_form_actions())
  232. {
  233. $html[] = '<script type="text/javascript">
  234. /* <![CDATA[ */
  235. function setCheckbox(formName, value) {
  236. var d = document[formName];
  237. for (i = 0; i < d.elements.length; i++) {
  238. if (d.elements[i].type == "checkbox") {
  239. d.elements[i].checked = value;
  240. }
  241. }
  242. }
  243. /* ]]> */
  244. </script>';
  245. //
  246. // function anyCheckboxChecked(formName) {
  247. // var d = document[formName];
  248. // for (i = 0; i < d.elements.length; i++) {
  249. // if (d.elements[i].type == "checkbox" && d.elements[i].checked)
  250. // return true;
  251. // }
  252. // return false;
  253. // }
  254. // Initially replaced $this->get_sortable_table_param_string with
  255. // $this->get_sortable_table_param_string() .. but I doubt it should be there anyway?
  256. //$params = $this->get_sortable_table_param_string().'&amp;'.$this->get_additional_url_paramstring();
  257. $params = $this->get_additional_url_paramstring();
  258. //$html[] = '<form method="post" action="' . $_SERVER['PHP_SELF'] . '?' . $params . '" name="form_' . $this->table_name . '" onsubmit="return anyCheckboxChecked(\'form_' . $this->table_name . '\') &amp;&amp; confirm(\'' . addslashes(htmlentities(Translation :: get("ConfirmYourChoice"))) . '\');">';
  259. $html[] = '<form method="post" action="' . $_SERVER['PHP_SELF'] . '?' . $params . '" name="form_' . $this->table_name . '" class="table_form">';
  260. $html[] = ResourceManager :: get_instance()->get_resource_html(Path :: get_web_common_libraries_path() . 'resources/javascript/sortable_table.js');
  261. }
  262. }
  263. $html[] = $this->get_table_html();
  264. if (! $empty_table)
  265. {
  266. $html[] = '<table style="width:100%;">';
  267. $html[] = '<tr>';
  268. $html[] = '<td colspan="2">';
  269. if ($this->form_actions->has_form_actions())
  270. {
  271. $html[] = '<div class="sortable_table_selection_controls">';
  272. $html[] = '<span class="sortable_table_selection_controls_options">';
  273. $html[] = '<a href="?' . $params . '&amp;' . $this->param_prefix . 'selectall=1" onclick="javascript: setCheckbox(\'form_' . $this->table_name . '\', true); return false;">' . Translation :: get('SelectAll', null, Utilities :: COMMON_LIBRARIES) . '</a>';
  274. $html[] = '&nbsp;-&nbsp;';
  275. $html[] = '<a href="?' . $params . '" onclick="javascript: setCheckbox(\'form_' . $this->table_name . '\', false); return false;">' . Translation :: get('UnselectAll', null, Utilities :: COMMON_LIBRARIES) . '</a> ';
  276. $html[] = '</span>';
  277. $html[] = '<select id="actions_' . $this->table_name . '" name="' . $this->table_name . '_action_value">';
  278. foreach ($this->form_actions->get_form_actions() as $form_action)
  279. {
  280. if ($form_action instanceof ObjectTableFormAction)
  281. {
  282. $html[] = '<option value="' . $form_action->get_action() . '" class="' . ($form_action->get_confirm() ? 'confirm' : '') . '">' . $form_action->get_title() . '</option>';
  283. }
  284. }
  285. $html[] = '</select>';
  286. $html[] = '<input type="hidden" name="' . $this->table_name . '_action_name" value="' . $this->form_actions->get_action() . '"/>';
  287. $html[] = '<input type="hidden" name="' . $this->table_name . '_namespace" value="' . $this->form_actions->get_namespace() . '"/>';
  288. $html[] = '<input type="hidden" name="table_name" value="' . $this->table_name . '"/>';
  289. // $html[] = '<button class="normal start" type="submit" value="' . Translation :: get('Ok') . '">' . Translation :: get('Ok') . '</button>';
  290. $html[] = ' <input type="submit" value="' . Translation :: get('Ok', null, Utilities :: COMMON_LIBRARIES) . '"/>';
  291. // $html[] = '</div>';
  292. }
  293. else
  294. {
  295. $html[] = $form;
  296. }
  297. $html[] = '</td>';
  298. $html[] = '<td style="text-align:right;">';
  299. $html[] = $nav;
  300. $html[] = '</td>';
  301. $html[] = '</tr>';
  302. $html[] = '</table>';
  303. if ($this->form_actions->has_form_actions())
  304. {
  305. $html[] = '</form>';
  306. }
  307. if ($this->is_ajax_enabled())
  308. {
  309. $html[] = '<script type="text/javascript">';
  310. $html[] = '(function($){';
  311. $html[] = '';
  312. $html[] = '$(document).ready(function() {';
  313. $html[] = ' // Initialise the table';
  314. $html[] = ' $(".data_table").tableDnD({';
  315. $html[] = ' });';
  316. $html[] = '});';
  317. $html[] = '';
  318. $html[] = '})(jQuery);';
  319. $html[] = '</script>';
  320. }
  321. }
  322. return implode("\n", $html);
  323. }
  324. /**
  325. * Get the HTML-code with the navigational buttons to browse through the
  326. * data-pages.
  327. */
  328. function get_navigation_html()
  329. {
  330. $pager = $this->get_pager();
  331. $pager_links = $pager->getLinks();
  332. $showed_items = $pager->getOffsetByPageId();
  333. return $pager_links['first'] . ' ' . $pager_links['back'] . ' ' . $pager->getCurrentPageId() . ' / ' . $pager->numPages() . ' ' . $pager_links['next'] . ' ' . $pager_links['last'];
  334. }
  335. /**
  336. * Get the HTML-code with the data-table.
  337. */
  338. function get_table_html()
  339. {
  340. // Make sure the header isn't dragable or droppable
  341. //$this->setRowAttributes(0, array('class' => 'nodrag nodrop'), true);
  342. // Now process the rest of the table
  343. $pager = $this->get_pager();
  344. $offset = $pager->getOffsetByPageId();
  345. $from = $offset[0] - 1;
  346. $table_data = $this->get_table_data($from);
  347. foreach ($table_data as $index => & $row)
  348. {
  349. $row_id = $row[0];
  350. $row = $this->filter_data($row);
  351. $current_row = $this->addRow($row);
  352. $this->setRowAttributes($current_row, array('id' => 'row_' . $row_id), true);
  353. }
  354. $this->altRowAttributes(0, array('class' => 'row_even'), array('class' => 'row_odd'), true);
  355. foreach ($this->th_attributes as $column => & $attributes)
  356. {
  357. $this->setCellAttributes(0, $column, $attributes);
  358. }
  359. foreach ($this->td_attributes as $column => & $attributes)
  360. {
  361. $this->setColAttributes($column, $attributes);
  362. }
  363. return parent :: toHTML();
  364. }
  365. /**
  366. * Get the HTML-code wich represents a form to select how many items a page
  367. * should contain.
  368. */
  369. function get_page_select_form()
  370. {
  371. $total_number_of_items = $this->total_number_of_items;
  372. if ($total_number_of_items <= self :: DISPLAY_PER_INCREMENT)
  373. {
  374. return '';
  375. }
  376. $result[] = '<form method="get" action="' . $_SERVER['PHP_SELF'] . '" style="display:inline;">';
  377. $param[$this->param_prefix . 'direction'] = $this->direction;
  378. $param[$this->param_prefix . 'page_nr'] = $this->page_nr;
  379. $param[$this->param_prefix . 'column'] = $this->column;
  380. $param = array_merge($param, $this->additional_parameters);
  381. foreach ($param as $key => & $value)
  382. {
  383. if (is_array($value))
  384. {
  385. $ser = self :: serialize_array($value, $key);
  386. $result = array_merge($result, $ser);
  387. }
  388. else
  389. {
  390. $result[] = '<input type="hidden" name="' . $key . '" value="' . $value . '"/>';
  391. }
  392. }
  393. $result[] = '<select name="' . $this->param_prefix . 'per_page" onchange="javascript:this.form.submit();">';
  394. // calculate the roundup for the interval
  395. $total_number_of_items_upper_interval = ceil($total_number_of_items/self :: DISPLAY_PER_INCREMENT) * self :: DISPLAY_PER_INCREMENT;
  396. for($nr = self :: DISPLAY_PER_INCREMENT; $nr <= min(self :: DISPLAY_PER_INCREMENT_INTERVAL_LIMIT, $total_number_of_items_upper_interval); $nr += self :: DISPLAY_PER_INCREMENT)
  397. {
  398. $result[] = '<option value="' . $nr . '" ' . ($nr == $this->per_page ? 'selected="selected"' : '') . '>' . $nr . '</option>';
  399. }
  400. if ($total_number_of_items < self :: DISPLAY_PER_PAGE_LIMIT)
  401. {
  402. $all_text = Translation :: get('All', Utilities :: COMMON_LIBRARIES);
  403. $result[] = '<option value="' . self :: DISPLAY_ALL . '" ' . ($total_number_of_items == $this->per_page ? 'selected="selected"' : '') . '>' . $all_text . '</option>';
  404. }
  405. $result[] = '</select>';
  406. $result[] = '<noscript>';
  407. $result[] = '<button class="normal" type="submit" value="' . Translation :: get('Ok', null, Utilities :: COMMON_LIBRARIES) . '">' . Translation :: get('Ok', null, Utilities :: COMMON_LIBRARIES) . '</button>';
  408. $result[] = '</noscript>';
  409. $result[] = '</form>';
  410. return implode("\n", $result);
  411. }
  412. /**
  413. * Get the table title.
  414. */
  415. function get_table_title()
  416. {
  417. $showed_items = $this->get_pager()->getOffsetByPageId();
  418. return $showed_items[0] . ' - ' . $showed_items[1] . ' / ' . $this->total_number_of_items;
  419. }
  420. /**
  421. * Set the header-label
  422. * @param int $column The column number
  423. * @param string $label The label
  424. * @param boolean $sortable Is the table sortable by this column? (defatult
  425. * = true)
  426. * @param string $th_attributes Additional attributes for the th-tag of the
  427. * table header
  428. * @param string $td_attributes Additional attributes for the td-tags of the
  429. * column
  430. */
  431. function set_header($column, $label, $sortable = true, $th_attributes = null, $td_attributes = null)
  432. {
  433. $header = $this->getHeader();
  434. for($i=0;$i<count($th_attributes);$i++)
  435. {
  436. $header->setColAttributes($i, $th_attributes[$i]);
  437. }
  438. $param['direction'] = SORT_ASC;
  439. if ($this->column == $column && $this->direction == SORT_ASC)
  440. {
  441. $param['direction'] = SORT_DESC;
  442. }
  443. $param['page_nr'] = $this->page_nr;
  444. $param['per_page'] = $this->per_page;
  445. $param['column'] = $column;
  446. if ($sortable)
  447. {
  448. $link = '<a href="' . $_SERVER['PHP_SELF'] . '?';
  449. foreach ($param as $key => & $value)
  450. {
  451. $link .= $this->param_prefix . $key . '=' . urlencode($value) . '&amp;';
  452. }
  453. $link .= $this->get_additional_url_paramstring();
  454. $link .= '">' . $label . '</a>';
  455. if ($this->column == $column)
  456. {
  457. $link .= $this->direction == SORT_ASC ? ' &#8595;' : ' &#8593;';
  458. }
  459. }
  460. else
  461. {
  462. $link = $label;
  463. }
  464. $header->setHeaderContents(0, $column, $link);
  465. if (! is_null($td_attributes))
  466. {
  467. $this->td_attributes[$column] = $td_attributes;
  468. }
  469. if (! is_null($th_attributes))
  470. {
  471. $this->th_attributes[$column] = $th_attributes;
  472. }
  473. return $link;
  474. }
  475. /**
  476. * Get the parameter-string with additional parameters to use in the URLs
  477. * generated by this SortableTable
  478. */
  479. function get_additional_url_paramstring()
  480. {
  481. $param_string_parts = array();
  482. foreach ($this->additional_parameters as $key => & $value)
  483. {
  484. if (is_array($value))
  485. {
  486. $ser = self :: serialize_array($value, $key, true);
  487. $param_string_parts = array_merge($param_string_parts, $ser);
  488. }
  489. else
  490. {
  491. $param_string_parts[] = urlencode($key) . '=' . urlencode($value);
  492. }
  493. }
  494. $result = implode('&amp;', $param_string_parts);
  495. foreach ($this->other_tables as $index => & $tablename)
  496. {
  497. if (Request :: get($tablename . '_direction'))
  498. $param[$tablename . '_direction'] = Request :: get($tablename . '_direction');
  499. if (Request :: get($tablename . '_page_nr'))
  500. $param[$tablename . '_page_nr'] = Request :: get($tablename . '_page_nr');
  501. if (Request :: get($tablename . '_per_page'))
  502. $param[$tablename . '_per_page'] = Request :: get($tablename . '_per_page');
  503. if (Request :: get($tablename . '_column'))
  504. $param[$tablename . '_column'] = Request :: get($tablename . '_column');
  505. $param_string_parts = array();
  506. foreach ($param as $key => & $value)
  507. {
  508. $param_string_parts[] = urlencode($key) . '=' . urlencode($value);
  509. }
  510. if (count($param_string_parts) > 0)
  511. $result .= '&amp;' . implode('&amp;', $param_string_parts);
  512. }
  513. return $result;
  514. }
  515. /**
  516. * Get the parameter-string with the SortableTable-related parameters to use
  517. * in URLs
  518. */
  519. function get_sortable_table_param_string()
  520. {
  521. $param[$this->param_prefix . 'direction'] = $this->direction;
  522. $param[$this->param_prefix . 'page_nr'] = $this->page_nr;
  523. $param[$this->param_prefix . 'per_page'] = $this->per_page;
  524. $param[$this->param_prefix . 'column'] = $this->column;
  525. $param_string_parts = array();
  526. foreach ($param as $key => & $value)
  527. {
  528. $param_string_parts[] = urlencode($key) . '=' . urlencode($value);
  529. }
  530. return implode('&amp;', $param_string_parts);
  531. }
  532. /**
  533. * Add a filter to a column. If another filter was allready defined for the
  534. * given column, it will be overwritten.
  535. * @param int $column The number of the column
  536. * @param string $function The name of the filter-function. This should be a
  537. * function wich requires 1 parameter and returns the filtered value.
  538. */
  539. function set_column_filter($column, $function)
  540. {
  541. $this->column_filters[$column] = $function;
  542. }
  543. /**
  544. * Define a list of actions which can be performed on the table-date.
  545. * If you define a list of actions, the first column of the table will be
  546. * converted into checkboxes.
  547. * @param array $actions A list of actions. The key is the name of the
  548. * action. The value is the label to show in the select-box
  549. * @param string $checkbox_name The name of the generated checkboxes. The
  550. * value of the checkbox will be the value of the first column.
  551. */
  552. function set_form_actions(ObjectTableFormActions $actions, $checkbox_name = 'id', $select_name = 'action')
  553. {
  554. $this->form_actions = $actions;
  555. $this->checkbox_name = $checkbox_name;
  556. $this->form_actions_select_name = $select_name;
  557. }
  558. /**
  559. * Define a list of additional parameters to use in the generated URLs
  560. * @param array $parameters
  561. */
  562. function set_additional_parameters($parameters)
  563. {
  564. $this->additional_parameters = $parameters;
  565. }
  566. /**
  567. * Set other tables on the same page.
  568. * If you have other sortable tables on the page displaying this sortable
  569. * tables, you can define those other tables with this function. If you
  570. * don't define the other tables, there sorting and pagination will return
  571. * to their default state when sorting this table.
  572. * @param array $tablenames An array of table names.
  573. */
  574. function set_other_tables($tablenames)
  575. {
  576. $this->other_tables = $tablenames;
  577. }
  578. /**
  579. * Transform all data in a table-row, using the filters defined by the
  580. * function set_column_filter(...) defined elsewhere in this class.
  581. * If you've defined actions, the first element of the given row will be
  582. * converted into a checkbox
  583. * @param array $row A row from the table.
  584. */
  585. function filter_data($row)
  586. {
  587. $url_params = $this->get_sortable_table_param_string() . '&amp;' . $this->get_additional_url_paramstring();
  588. foreach ($this->column_filters as $column => $function)
  589. {
  590. $row[$column] = call_user_func($function, $row[$column], $url_params);
  591. }
  592. if ($this->form_actions->has_form_actions())
  593. {
  594. if (strlen($row[0]) > 0)
  595. {
  596. $row[0] = '<input class="' . $this->checkbox_name . '" type="checkbox" name="' . $this->checkbox_name . '[]" value="' . $row[0] . '"';
  597. if (Request :: get($this->param_prefix . 'selectall'))
  598. {
  599. $row[0] .= ' checked="checked"';
  600. }
  601. $row[0] .= '/>';
  602. }
  603. }
  604. foreach ($row as $index => & $value)
  605. {
  606. if (! is_numeric($value) && empty($value))
  607. {
  608. $value = '-';
  609. }
  610. }
  611. return $row;
  612. }
  613. /**
  614. * Get the total number of items. This function calls the function given as
  615. * 2nd argument in the constructor of a SortableTable. Make sure your
  616. * function has the same parameters as defined here.
  617. */
  618. function get_total_number_of_items()
  619. {
  620. if ($this->total_number_of_items == - 1 && ! is_null($this->get_total_number_function))
  621. {
  622. $this->total_number_of_items = call_user_func($this->get_total_number_function);
  623. }
  624. return $this->total_number_of_items;
  625. }
  626. /**
  627. * Get the data to display. This function calls the function given as
  628. * 2nd argument in the constructor of a SortableTable. Make sure your
  629. * function has the same parameters as defined here.
  630. * @param int $from Index of the first item to return.
  631. * @param int $per_page The number of items to return
  632. * @param int $column The number of the column on which the data should be
  633. * sorted
  634. * @param string $direction In which order should the data be sorted (ASC
  635. * or DESC)
  636. */
  637. function get_table_data($from = null, $per_page = null, $column = null, $direction = null)
  638. {
  639. if (! is_null($this->get_data_function))
  640. {
  641. return call_user_func($this->get_data_function, $from, $this->per_page, $this->column, $this->direction);
  642. }
  643. return array();
  644. }
  645. /**
  646. * Serializes a URL parameter passed as an array into a query string or
  647. * hidden inputs.
  648. * @param array $params The parameter's value.
  649. * @param string $key The parameter's name.
  650. * @param boolean $as_query_string True to format the result as a query
  651. * string, false for hidden inputs.
  652. * @return array The query string parts (to be joined by ampersands or
  653. * another separator), or the hidden inputs as HTML, each
  654. * array element containing a single input.
  655. */
  656. private function serialize_array($params, $key, $as_query_string = false)
  657. {
  658. $out = array();
  659. foreach ($params as $k => & $v)
  660. {
  661. if (is_array($v))
  662. {
  663. $ser = self :: serialize_array($v, $key . '[' . $k . ']', $as_query_string);
  664. $out = array_merge($out, $ser);
  665. }
  666. else
  667. {
  668. $v = urlencode($v);
  669. }
  670. if($as_query_string)
  671. {
  672. $k = urlencode($key . '[' . $k . ']');
  673. $out[] = $k . '=' . $v;
  674. }
  675. else
  676. {
  677. $k = $key . '[' . $k . ']';
  678. $out[] = '<input type="hidden" name="' . $k . '" value="' . $v . '"/>';
  679. }
  680. //$k = urlencode($key . '[' . $k . ']');
  681. //$out[] = ($as_query_string ? $k . '=' . $v : '<input type="hidden" name="' . $k . '" value="' . $v . '"/>');
  682. }
  683. return $out;
  684. }
  685. /**
  686. * Gets the AJAX status of the table
  687. *
  688. * @return boolean Whether or not the table should have AJAX functionality
  689. */
  690. function is_ajax_enabled()
  691. {
  692. return $this->ajax_enabled;
  693. }
  694. /**
  695. * Sets the table's AJAX status to true
  696. */
  697. function enable_ajax()
  698. {
  699. $this->ajax_enabled = true;
  700. }
  701. /**
  702. * Sets the table's AJAX status to false
  703. */
  704. function disable_ajax()
  705. {
  706. $this->ajax_enabled = false;
  707. }
  708. function get_per_page()
  709. {
  710. return $this->per_page;
  711. }
  712. function get_column()
  713. {
  714. return $this->column;
  715. }
  716. function get_direction()
  717. {
  718. return $this->direction;
  719. }
  720. }
  721. /**
  722. * Sortable table which can be used for data available in an array
  723. */
  724. class SortableTableFromArray extends SortableTable
  725. {
  726. /**
  727. * The array containing all data for this table
  728. */
  729. private $table_data;
  730. /**
  731. * Constructor
  732. * @param array $table_data
  733. * @param int $default_column
  734. * @param int $default_items_per_page
  735. */
  736. function __construct($table_data, $default_column = 1, $default_items_per_page = 20, $tablename = 'tablename', $default_direction = SORT_ASC)
  737. {
  738. $this->table_data = $table_data;
  739. parent :: __construct($tablename, array($this, 'get_total_number_of_items'), array($this, 'get_table_data'), $default_column, $default_items_per_page, $default_direction);
  740. }
  741. /**
  742. * Get table data to show on current page
  743. * @see SortableTable#get_table_data
  744. */
  745. function get_table_data($from = 1)
  746. {
  747. $content = TableSort :: sort_table($this->table_data, $this->get_column(), $this->get_direction());
  748. return array_slice($content, $from, $this->get_per_page());
  749. }
  750. /**
  751. * Get total number of items
  752. * @see SortableTable#get_total_number_of_items
  753. */
  754. function get_total_number_of_items()
  755. {
  756. return count($this->table_data);
  757. }
  758. }
  759. ?>