PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/tablelib.php

https://bitbucket.org/ceu/moodle_demo
PHP | 811 lines | 535 code | 94 blank | 182 comment | 146 complexity | 36e18743929ddd10b858a60d6b99d905 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, LGPL-2.1
  1. <?php // $Id: tablelib.php,v 1.24.2.7 2010/04/26 15:47:55 tjhunt Exp $
  2. define('TABLE_VAR_SORT', 1);
  3. define('TABLE_VAR_HIDE', 2);
  4. define('TABLE_VAR_SHOW', 3);
  5. define('TABLE_VAR_IFIRST', 4);
  6. define('TABLE_VAR_ILAST', 5);
  7. define('TABLE_VAR_PAGE', 6);
  8. class flexible_table {
  9. var $uniqueid = NULL;
  10. var $attributes = array();
  11. var $headers = array();
  12. var $columns = array();
  13. var $column_style = array();
  14. var $column_class = array();
  15. var $column_suppress = array();
  16. var $column_nosort = array('userpic');
  17. var $setup = false;
  18. var $sess = NULL;
  19. var $baseurl = NULL;
  20. var $request = array();
  21. var $is_collapsible = false;
  22. var $is_sortable = false;
  23. var $use_pages = false;
  24. var $use_initials = false;
  25. var $maxsortkeys = 2;
  26. var $pagesize = 30;
  27. var $currpage = 0;
  28. var $totalrows = 0;
  29. var $sort_default_column = NULL;
  30. var $sort_default_order = SORT_ASC;
  31. /**
  32. * Constructor
  33. * @param int $uniqueid
  34. * @todo Document properly
  35. */
  36. function flexible_table($uniqueid) {
  37. $this->uniqueid = $uniqueid;
  38. $this->request = array(
  39. TABLE_VAR_SORT => 'tsort',
  40. TABLE_VAR_HIDE => 'thide',
  41. TABLE_VAR_SHOW => 'tshow',
  42. TABLE_VAR_IFIRST => 'tifirst',
  43. TABLE_VAR_ILAST => 'tilast',
  44. TABLE_VAR_PAGE => 'page'
  45. );
  46. }
  47. /**
  48. * Sets the is_sortable variable to the given boolean, sort_default_column to
  49. * the given string, and the sort_default_order to the given integer.
  50. * @param bool $bool
  51. * @param string $defaultcolumn
  52. * @param int $defaultorder
  53. * @return void
  54. */
  55. function sortable($bool, $defaultcolumn = NULL, $defaultorder = SORT_ASC) {
  56. $this->is_sortable = $bool;
  57. $this->sort_default_column = $defaultcolumn;
  58. $this->sort_default_order = $defaultorder;
  59. }
  60. /**
  61. * Do not sort using this column
  62. * @param string column name
  63. */
  64. function no_sorting($column) {
  65. $this->column_nosort[] = $column;
  66. }
  67. /**
  68. * Is the column sortable?
  69. * @param string column name, null means table
  70. * @return bool
  71. */
  72. function is_sortable($column=null) {
  73. if (empty($column)) {
  74. return $this->is_sortable;
  75. }
  76. if (!$this->is_sortable) {
  77. return false;
  78. }
  79. return !in_array($column, $this->column_nosort);
  80. }
  81. /**
  82. * Sets the is_collapsible variable to the given boolean.
  83. * @param bool $bool
  84. * @return void
  85. */
  86. function collapsible($bool) {
  87. $this->is_collapsible = $bool;
  88. }
  89. /**
  90. * Sets the use_pages variable to the given boolean.
  91. * @param bool $bool
  92. * @return void
  93. */
  94. function pageable($bool) {
  95. $this->use_pages = $bool;
  96. }
  97. /**
  98. * Sets the use_initials variable to the given boolean.
  99. * @param bool $bool
  100. * @return void
  101. */
  102. function initialbars($bool) {
  103. $this->use_initials = $bool;
  104. }
  105. /**
  106. * Sets the pagesize variable to the given integer, the totalrows variable
  107. * to the given integer, and the use_pages variable to true.
  108. * @param int $perpage
  109. * @param int $total
  110. * @return void
  111. */
  112. function pagesize($perpage, $total) {
  113. $this->pagesize = $perpage;
  114. $this->totalrows = $total;
  115. $this->use_pages = true;
  116. }
  117. /**
  118. * Assigns each given variable in the array to the corresponding index
  119. * in the request class variable.
  120. * @param array $variables
  121. * @return void
  122. */
  123. function set_control_variables($variables) {
  124. foreach($variables as $what => $variable) {
  125. if(isset($this->request[$what])) {
  126. $this->request[$what] = $variable;
  127. }
  128. }
  129. }
  130. /**
  131. * Gives the given $value to the $attribute index of $this->attributes.
  132. * @param string $attribute
  133. * @param mixed $value
  134. * @return void
  135. */
  136. function set_attribute($attribute, $value) {
  137. $this->attributes[$attribute] = $value;
  138. }
  139. /**
  140. * I think that what this method does is set the column so that if the same data appears in
  141. * consecutive rows, then it is not repeated.
  142. *
  143. * For example, in the quiz overview report, the fullname column is set to be suppressed, so
  144. * that when one student has made multiple attempts, their name is only printed in the row
  145. * for their first attempt.
  146. * @param integer $column the index of a column.
  147. */
  148. function column_suppress($column) {
  149. if(isset($this->column_suppress[$column])) {
  150. $this->column_suppress[$column] = true;
  151. }
  152. }
  153. /**
  154. * Sets the given $column index to the given $classname in $this->column_class.
  155. * @param integer $column
  156. * @param string $classname
  157. * @return void
  158. */
  159. function column_class($column, $classname) {
  160. if(isset($this->column_class[$column])) {
  161. $this->column_class[$column] = ' '.$classname; // This space needed so that classnames don't run together in the HTML
  162. }
  163. }
  164. /**
  165. * Sets the given $column index and $property index to the given $value in $this->column_style.
  166. * @param integer $column
  167. * @param string $property
  168. * @param mixed $value
  169. * @return void
  170. */
  171. function column_style($column, $property, $value) {
  172. if(isset($this->column_style[$column])) {
  173. $this->column_style[$column][$property] = $value;
  174. }
  175. }
  176. /**
  177. * Sets all columns of the given $property to the given $value in $this->column_style.
  178. * @param integer $property
  179. * @param string $value
  180. * @return void
  181. */
  182. function column_style_all($property, $value) {
  183. foreach(array_keys($this->columns) as $column) {
  184. $this->column_style[$column][$property] = $value;
  185. }
  186. }
  187. /**
  188. * Sets $this->reseturl to the given $url, and $this->baseurl to the given $url plus ? or &amp;
  189. * @param type? $url
  190. * @return type?
  191. */
  192. function define_baseurl($url) {
  193. $this->reseturl = $url;
  194. if (!strpos($url, '?')) {
  195. $this->baseurl = $url.'?';
  196. } else {
  197. $this->baseurl = $url.'&amp;';
  198. }
  199. }
  200. /**
  201. * @todo Document
  202. * @return type?
  203. */
  204. function define_columns($columns) {
  205. $this->columns = array();
  206. $this->column_style = array();
  207. $this->column_class = array();
  208. $colnum = 0;
  209. foreach($columns as $column) {
  210. $this->columns[$column] = $colnum++;
  211. $this->column_style[$column] = array();
  212. $this->column_class[$column] = '';
  213. $this->column_suppress[$column] = false;
  214. }
  215. }
  216. /**
  217. * @todo Document
  218. * @return type?
  219. */
  220. function define_headers($headers) {
  221. $this->headers = $headers;
  222. }
  223. /**
  224. * @todo Document
  225. * @return type?
  226. */
  227. function make_styles_string(&$styles) {
  228. if(empty($styles)) {
  229. return '';
  230. }
  231. $string = ' style="';
  232. foreach($styles as $property => $value) {
  233. $string .= $property.':'.$value.';';
  234. }
  235. $string .= '"';
  236. return $string;
  237. }
  238. /**
  239. * @todo Document
  240. * @return type?
  241. */
  242. function make_attributes_string(&$attributes) {
  243. if(empty($attributes)) {
  244. return '';
  245. }
  246. $string = ' ';
  247. foreach($attributes as $attr => $value) {
  248. $string .= ($attr.'="'.$value.'" ');
  249. }
  250. return $string;
  251. }
  252. /**
  253. * @todo Document
  254. * @return type?
  255. */
  256. function setup() {
  257. global $SESSION, $CFG;
  258. if(empty($this->columns) || empty($this->uniqueid)) {
  259. return false;
  260. }
  261. if (!isset($SESSION->flextable)) {
  262. $SESSION->flextable = array();
  263. }
  264. if(!isset($SESSION->flextable[$this->uniqueid])) {
  265. $SESSION->flextable[$this->uniqueid] = new stdClass;
  266. $SESSION->flextable[$this->uniqueid]->uniqueid = $this->uniqueid;
  267. $SESSION->flextable[$this->uniqueid]->collapse = array();
  268. $SESSION->flextable[$this->uniqueid]->sortby = array();
  269. $SESSION->flextable[$this->uniqueid]->i_first = '';
  270. $SESSION->flextable[$this->uniqueid]->i_last = '';
  271. }
  272. $this->sess = &$SESSION->flextable[$this->uniqueid];
  273. if(!empty($_GET[$this->request[TABLE_VAR_SHOW]]) && isset($this->columns[$_GET[$this->request[TABLE_VAR_SHOW]]])) {
  274. // Show this column
  275. $this->sess->collapse[$_GET[$this->request[TABLE_VAR_SHOW]]] = false;
  276. }
  277. else if(!empty($_GET[$this->request[TABLE_VAR_HIDE]]) && isset($this->columns[$_GET[$this->request[TABLE_VAR_HIDE]]])) {
  278. // Hide this column
  279. $this->sess->collapse[$_GET[$this->request[TABLE_VAR_HIDE]]] = true;
  280. if(array_key_exists($_GET[$this->request[TABLE_VAR_HIDE]], $this->sess->sortby)) {
  281. unset($this->sess->sortby[$_GET[$this->request[TABLE_VAR_HIDE]]]);
  282. }
  283. }
  284. // Now, update the column attributes for collapsed columns
  285. foreach(array_keys($this->columns) as $column) {
  286. if(!empty($this->sess->collapse[$column])) {
  287. $this->column_style[$column]['width'] = '10px';
  288. }
  289. }
  290. if(
  291. !empty($_GET[$this->request[TABLE_VAR_SORT]]) && $this->is_sortable($_GET[$this->request[TABLE_VAR_SORT]]) &&
  292. (isset($this->columns[$_GET[$this->request[TABLE_VAR_SORT]]]) ||
  293. (($_GET[$this->request[TABLE_VAR_SORT]] == 'firstname' || $_GET[$this->request[TABLE_VAR_SORT]] == 'lastname') && isset($this->columns['fullname']))
  294. ))
  295. {
  296. if(empty($this->sess->collapse[$_GET[$this->request[TABLE_VAR_SORT]]])) {
  297. if(array_key_exists($_GET[$this->request[TABLE_VAR_SORT]], $this->sess->sortby)) {
  298. // This key already exists somewhere. Change its sortorder and bring it to the top.
  299. $sortorder = $this->sess->sortby[$_GET[$this->request[TABLE_VAR_SORT]]] == SORT_ASC ? SORT_DESC : SORT_ASC;
  300. unset($this->sess->sortby[$_GET[$this->request[TABLE_VAR_SORT]]]);
  301. $this->sess->sortby = array_merge(array($_GET[$this->request[TABLE_VAR_SORT]] => $sortorder), $this->sess->sortby);
  302. }
  303. else {
  304. // Key doesn't exist, so just add it to the beginning of the array, ascending order
  305. $this->sess->sortby = array_merge(array($_GET[$this->request[TABLE_VAR_SORT]] => SORT_ASC), $this->sess->sortby);
  306. }
  307. // Finally, make sure that no more than $this->maxsortkeys are present into the array
  308. if(!empty($this->maxsortkeys) && ($sortkeys = count($this->sess->sortby)) > $this->maxsortkeys) {
  309. while($sortkeys-- > $this->maxsortkeys) {
  310. array_pop($this->sess->sortby);
  311. }
  312. }
  313. }
  314. }
  315. // If we didn't sort just now, then use the default sort order if one is defined and the column exists
  316. if(empty($this->sess->sortby) && !empty($this->sort_default_column) && (isset($this->columns[$this->sort_default_column])
  317. || (in_array('fullname',$this->columns)
  318. && in_array($this->sort_default_column,
  319. array('firstname','lastname'))))) {
  320. $this->sess->sortby = array ($this->sort_default_column => ($this->sort_default_order == SORT_DESC ? SORT_DESC : SORT_ASC));
  321. }
  322. if(isset($_GET[$this->request[TABLE_VAR_ILAST]])) {
  323. if(empty($_GET[$this->request[TABLE_VAR_ILAST]]) || is_numeric(strpos(get_string('alphabet'), $_GET[$this->request[TABLE_VAR_ILAST]]))) {
  324. $this->sess->i_last = $_GET[$this->request[TABLE_VAR_ILAST]];
  325. }
  326. }
  327. if(isset($_GET[$this->request[TABLE_VAR_IFIRST]])) {
  328. if(empty($_GET[$this->request[TABLE_VAR_IFIRST]]) || is_numeric(strpos(get_string('alphabet'), $_GET[$this->request[TABLE_VAR_IFIRST]]))) {
  329. $this->sess->i_first = $_GET[$this->request[TABLE_VAR_IFIRST]];
  330. }
  331. }
  332. if(empty($this->baseurl)) {
  333. $getcopy = $_GET;
  334. unset($getcopy[$this->request[TABLE_VAR_SHOW]]);
  335. unset($getcopy[$this->request[TABLE_VAR_HIDE]]);
  336. unset($getcopy[$this->request[TABLE_VAR_SORT]]);
  337. unset($getcopy[$this->request[TABLE_VAR_IFIRST]]);
  338. unset($getcopy[$this->request[TABLE_VAR_ILAST]]);
  339. unset($getcopy[$this->request[TABLE_VAR_PAGE]]);
  340. $strippedurl = strip_querystring(qualified_me());
  341. if(!empty($getcopy)) {
  342. $first = false;
  343. $querystring = '';
  344. foreach($getcopy as $var => $val) {
  345. if(!$first) {
  346. $first = true;
  347. $querystring .= '?'.$var.'='.$val;
  348. }
  349. else {
  350. $querystring .= '&amp;'.$var.'='.$val;
  351. }
  352. }
  353. $this->reseturl = $strippedurl.$querystring;
  354. $querystring .= '&amp;';
  355. }
  356. else {
  357. $this->reseturl = $strippedurl;
  358. $querystring = '?';
  359. }
  360. $this->baseurl = strip_querystring(qualified_me()) . $querystring;
  361. }
  362. // If it's "the first time" we 've been here, forget the previous initials filters
  363. if(qualified_me() == $this->reseturl) {
  364. $this->sess->i_first = '';
  365. $this->sess->i_last = '';
  366. }
  367. $this->currpage = optional_param($this->request[TABLE_VAR_PAGE], 0);
  368. $this->setup = true;
  369. /// Always introduce the "flexible" class for the table if not specified
  370. /// No attributes, add flexible class
  371. if (empty($this->attributes)) {
  372. $this->attributes['class'] = 'flexible';
  373. /// No classes, add flexible class
  374. } else if (!isset($this->attributes['class'])) {
  375. $this->attributes['class'] = 'flexible';
  376. /// No flexible class in passed classes, add flexible class
  377. } else if (!in_array('flexible', explode(' ', $this->attributes['class']))) {
  378. $this->attributes['class'] = trim('flexible ' . $this->attributes['class']);
  379. }
  380. }
  381. /**
  382. * @todo Document
  383. * @return type?
  384. */
  385. function get_sql_sort($uniqueid = NULL) {
  386. if($uniqueid === NULL) {
  387. // "Non-static" function call
  388. if(!$this->setup) {
  389. return false;
  390. }
  391. $sess = &$this->sess;
  392. }
  393. else {
  394. // "Static" function call
  395. global $SESSION;
  396. if(empty($SESSION->flextable[$uniqueid])) {
  397. return '';
  398. }
  399. $sess = &$SESSION->flextable[$uniqueid];
  400. }
  401. if(!empty($sess->sortby)) {
  402. $sortstring = '';
  403. foreach($sess->sortby as $column => $order) {
  404. if(!empty($sortstring)) {
  405. $sortstring .= ', ';
  406. }
  407. $sortstring .= $column.($order == SORT_ASC ? ' ASC' : ' DESC');
  408. }
  409. return $sortstring;
  410. }
  411. return '';
  412. }
  413. /**
  414. * @todo Document
  415. * @return type?
  416. */
  417. function get_page_start() {
  418. if(!$this->use_pages) {
  419. return '';
  420. }
  421. return $this->currpage * $this->pagesize;
  422. }
  423. /**
  424. * @todo Document
  425. * @return type?
  426. */
  427. function get_page_size() {
  428. if(!$this->use_pages) {
  429. return '';
  430. }
  431. return $this->pagesize;
  432. }
  433. /**
  434. * @todo Document
  435. * @return type?
  436. */
  437. function get_sql_where() {
  438. if(!isset($this->columns['fullname'])) {
  439. return '';
  440. }
  441. $LIKE = sql_ilike();
  442. if(!empty($this->sess->i_first) && !empty($this->sess->i_last)) {
  443. return 'firstname '.$LIKE.' \''.$this->sess->i_first.'%\' AND lastname '.$LIKE.' \''.$this->sess->i_last.'%\'';
  444. }
  445. else if(!empty($this->sess->i_first)) {
  446. return 'firstname '.$LIKE.' \''.$this->sess->i_first.'%\'';
  447. }
  448. else if(!empty($this->sess->i_last)) {
  449. return 'lastname '.$LIKE.' \''.$this->sess->i_last.'%\'';
  450. }
  451. return '';
  452. }
  453. /**
  454. * @todo Document
  455. * @return type?
  456. */
  457. function get_initial_first() {
  458. if(!$this->use_initials) {
  459. return NULL;
  460. }
  461. return $this->sess->i_first;
  462. }
  463. /**
  464. * @todo Document
  465. * @return type?
  466. */
  467. function get_initial_last() {
  468. if(!$this->use_initials) {
  469. return NULL;
  470. }
  471. return $this->sess->i_last;
  472. }
  473. /**
  474. * @todo Document
  475. * @return type?
  476. */
  477. function print_html() {
  478. global $CFG;
  479. if(!$this->setup) {
  480. return false;
  481. }
  482. $colcount = count($this->columns);
  483. // Do we need to print initial bars?
  484. if($this->use_initials && isset($this->columns['fullname'])) {
  485. $strall = get_string('all');
  486. $alpha = explode(',', get_string('alphabet'));
  487. // Bar of first initials
  488. echo '<div class="initialbar firstinitial">'.get_string('firstname').' : ';
  489. if(!empty($this->sess->i_first)) {
  490. echo '<a href="'.$this->baseurl.$this->request[TABLE_VAR_IFIRST].'=">'.$strall.'</a>';
  491. } else {
  492. echo '<strong>'.$strall.'</strong>';
  493. }
  494. foreach ($alpha as $letter) {
  495. if (isset($this->sess->i_first) && $letter == $this->sess->i_first) {
  496. echo ' <strong>'.$letter.'</strong>';
  497. } else {
  498. echo ' <a href="'.$this->baseurl.$this->request[TABLE_VAR_IFIRST].'='.$letter.'">'.$letter.'</a>';
  499. }
  500. }
  501. echo '</div>';
  502. // Bar of last initials
  503. echo '<div class="initialbar lastinitial">'.get_string('lastname').' : ';
  504. if(!empty($this->sess->i_last)) {
  505. echo '<a href="'.$this->baseurl.$this->request[TABLE_VAR_ILAST].'=">'.$strall.'</a>';
  506. } else {
  507. echo '<strong>'.$strall.'</strong>';
  508. }
  509. foreach ($alpha as $letter) {
  510. if (isset($this->sess->i_last) && $letter == $this->sess->i_last) {
  511. echo ' <strong>'.$letter.'</strong>';
  512. } else {
  513. echo ' <a href="'.$this->baseurl.$this->request[TABLE_VAR_ILAST].'='.$letter.'">'.$letter.'</a>';
  514. }
  515. }
  516. echo '</div>';
  517. }
  518. // End of initial bars code
  519. // Paging bar
  520. if($this->use_pages) {
  521. print_paging_bar($this->totalrows, $this->currpage, $this->pagesize, $this->baseurl, $this->request[TABLE_VAR_PAGE]);
  522. }
  523. if (empty($this->data)) {
  524. print_heading(get_string('nothingtodisplay'));
  525. return true;
  526. }
  527. $suppress_enabled = array_sum($this->column_suppress);
  528. $suppress_lastrow = NULL;
  529. // Start of main data table
  530. echo '<table'.$this->make_attributes_string($this->attributes).'>';
  531. echo '<tr>';
  532. foreach($this->columns as $column => $index) {
  533. $icon_hide = '';
  534. $icon_sort = '';
  535. if($this->is_collapsible) {
  536. if(!empty($this->sess->collapse[$column])) {
  537. // some headers contain < br/> tags, do not include in title
  538. $icon_hide = ' <a href="'.$this->baseurl.$this->request[TABLE_VAR_SHOW].'='.$column.'"><img src="'.$CFG->pixpath.'/t/switch_plus.gif" title="'.get_string('show').' '.strip_tags($this->headers[$index]).'" alt="'.get_string('show').'" /></a>';
  539. }
  540. else if($this->headers[$index] !== NULL) {
  541. // some headers contain < br/> tags, do not include in title
  542. $icon_hide = ' <a href="'.$this->baseurl.$this->request[TABLE_VAR_HIDE].'='.$column.'"><img src="'.$CFG->pixpath.'/t/switch_minus.gif" title="'.get_string('hide').' '.strip_tags($this->headers[$index]).'" alt="'.get_string('hide').'" /></a>';
  543. }
  544. }
  545. $primary_sort_column = '';
  546. $primary_sort_order = '';
  547. if(reset($this->sess->sortby)) {
  548. $primary_sort_column = key($this->sess->sortby);
  549. $primary_sort_order = current($this->sess->sortby);
  550. }
  551. switch($column) {
  552. case 'fullname':
  553. if($this->is_sortable($column)) {
  554. $icon_sort_first = $icon_sort_last = '';
  555. if($primary_sort_column == 'firstname') {
  556. $lsortorder = get_string('asc');
  557. if($primary_sort_order == SORT_ASC) {
  558. $icon_sort_first = ' <img src="'.$CFG->pixpath.'/t/down.gif" alt="'.get_string('asc').'" />';
  559. $fsortorder = get_string('asc');
  560. }
  561. else {
  562. $icon_sort_first = ' <img src="'.$CFG->pixpath.'/t/up.gif" alt="'.get_string('desc').'" />';
  563. $fsortorder = get_string('desc');
  564. }
  565. }
  566. else if($primary_sort_column == 'lastname') {
  567. $fsortorder = get_string('asc');
  568. if($primary_sort_order == SORT_ASC) {
  569. $icon_sort_last = ' <img src="'.$CFG->pixpath.'/t/down.gif" alt="'.get_string('asc').'" />';
  570. $lsortorder = get_string('asc');
  571. }
  572. else {
  573. $icon_sort_last = ' <img src="'.$CFG->pixpath.'/t/up.gif" alt="'.get_string('desc').'" />';
  574. $lsortorder = get_string('desc');
  575. }
  576. } else {
  577. $fsortorder = get_string('asc');
  578. $lsortorder = get_string('asc');
  579. }
  580. $override = new object();
  581. $override->firstname = 'firstname';
  582. $override->lastname = 'lastname';
  583. $fullnamelanguage = get_string('fullnamedisplay', '', $override);
  584. if (($CFG->fullnamedisplay == 'firstname lastname') or
  585. ($CFG->fullnamedisplay == 'firstname') or
  586. ($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'firstname lastname' )) {
  587. $this->headers[$index] = '<a href="'.$this->baseurl.$this->request[TABLE_VAR_SORT].'=firstname">'.get_string('firstname').get_accesshide(get_string('sortby').' '.get_string('firstname').' '.$fsortorder).'</a> '.$icon_sort_first.' / '.
  588. '<a href="'.$this->baseurl.$this->request[TABLE_VAR_SORT].'=lastname">'.get_string('lastname').get_accesshide(get_string('sortby').' '.get_string('lastname').' '.$lsortorder).'</a> '.$icon_sort_last;
  589. } else {
  590. $this->headers[$index] = '<a href="'.$this->baseurl.$this->request[TABLE_VAR_SORT].'=lastname">'.get_string('lastname').get_accesshide(get_string('sortby').' '.get_string('lastname').' '.$lsortorder).'</a> '.$icon_sort_last.' / '.
  591. '<a href="'.$this->baseurl.$this->request[TABLE_VAR_SORT].'=firstname">'.get_string('firstname').get_accesshide(get_string('sortby').' '.get_string('firstname').' '.$fsortorder).'</a> '.$icon_sort_first;
  592. }
  593. }
  594. break;
  595. case 'userpic':
  596. // do nothing, do not display sortable links
  597. break;
  598. default:
  599. if($this->is_sortable($column)) {
  600. if($primary_sort_column == $column) {
  601. if($primary_sort_order == SORT_ASC) {
  602. $icon_sort = ' <img src="'.$CFG->pixpath.'/t/down.gif" alt="'.get_string('asc').'" />';
  603. $localsortorder = get_string('asc');
  604. }
  605. else {
  606. $icon_sort = ' <img src="'.$CFG->pixpath.'/t/up.gif" alt="'.get_string('desc').'" />';
  607. $localsortorder = get_string('desc');
  608. }
  609. } else {
  610. $localsortorder = get_string('asc');
  611. }
  612. $this->headers[$index] = '<a href="'.$this->baseurl.$this->request[TABLE_VAR_SORT].'='.$column.'">'.$this->headers[$index].get_accesshide(get_string('sortby').' '.$this->headers[$index].' '.$localsortorder).'</a>';
  613. }
  614. }
  615. if($this->headers[$index] === NULL) {
  616. echo '<th class="header c'.$index.$this->column_class[$column].'" scope="col">&nbsp;</th>';
  617. }
  618. else if(!empty($this->sess->collapse[$column])) {
  619. echo '<th class="header c'.$index.$this->column_class[$column].'" scope="col">'.$icon_hide.'</th>';
  620. }
  621. else {
  622. // took out nowrap for accessibility, might need replacement
  623. if (!is_array($this->column_style[$column])) {
  624. // $usestyles = array('white-space:nowrap');
  625. $usestyles = '';
  626. } else {
  627. // $usestyles = $this->column_style[$column]+array('white-space'=>'nowrap');
  628. $usestyles = $this->column_style[$column];
  629. }
  630. echo '<th class="header c'.$index.$this->column_class[$column].'" '.$this->make_styles_string($usestyles).' scope="col">'.$this->headers[$index].$icon_sort.'<div class="commands">'.$icon_hide.'</div></th>';
  631. }
  632. }
  633. echo '</tr>';
  634. if(!empty($this->data)) {
  635. $oddeven = 1;
  636. $colbyindex = array_flip($this->columns);
  637. foreach($this->data as $row) {
  638. $oddeven = $oddeven ? 0 : 1;
  639. echo '<tr class="r'.$oddeven.'">';
  640. // If we have a separator, print it
  641. if($row === NULL && $colcount) {
  642. echo '<td colspan="'.$colcount.'"><div class="tabledivider"></div></td>';
  643. }
  644. else {
  645. foreach($row as $index => $data) {
  646. if($index >= $colcount) {
  647. break;
  648. }
  649. $column = $colbyindex[$index];
  650. echo '<td class="cell c'.$index.$this->column_class[$column].'"'.$this->make_styles_string($this->column_style[$column]).'>';
  651. if(empty($this->sess->collapse[$column])) {
  652. if($this->column_suppress[$column] && $suppress_lastrow !== NULL && $suppress_lastrow[$index] === $data) {
  653. echo '&nbsp;';
  654. }
  655. else {
  656. echo $data;
  657. }
  658. }
  659. else {
  660. echo '&nbsp;';
  661. }
  662. echo '</td>';
  663. }
  664. }
  665. echo '</tr>';
  666. if($suppress_enabled) {
  667. $suppress_lastrow = $row;
  668. }
  669. }
  670. }
  671. echo '</table>';
  672. // Paging bar
  673. if($this->use_pages) {
  674. print_paging_bar($this->totalrows, $this->currpage, $this->pagesize, $this->baseurl, $this->request[TABLE_VAR_PAGE]);
  675. }
  676. }
  677. /**
  678. * @todo Document
  679. * @return type?
  680. */
  681. function add_data($row) {
  682. if(!$this->setup) {
  683. return false;
  684. }
  685. $this->data[] = $row;
  686. }
  687. /**
  688. * @todo Document
  689. * @return type?
  690. */
  691. function add_separator() {
  692. if(!$this->setup) {
  693. return false;
  694. }
  695. $this->data[] = NULL;
  696. }
  697. /**
  698. * Add a row of data to the table. This function takes an array with
  699. * column names as keys.
  700. * It ignores any elements with keys that are not defined as columns. It
  701. * puts in empty strings into the row when there is no element in the passed
  702. * array corresponding to a column in the table. It puts the row elements in
  703. * the proper order.
  704. * @param $rowwithkeys array
  705. */
  706. function add_data_keyed($rowwithkeys){
  707. foreach (array_keys($this->columns) as $column){
  708. if (isset($rowwithkeys[$column])){
  709. $row [] = $rowwithkeys[$column];
  710. } else {
  711. $row[] ='';
  712. }
  713. }
  714. $this->add_data($row);
  715. }
  716. }
  717. ?>