com.lokorin.lokorin.lib
[ class tree: com.lokorin.lokorin.lib ] [ index: com.lokorin.lokorin.lib ] [ all elements ]

Source for file lib_displayer.php

Documentation is available at lib_displayer.php

  1. <?php
  2. /*
  3. * Lokorin.com
  4. * Copyright 2004-2006
  5. * Licensed under the GNU LGPL. See COPYING for full terms.
  6. */
  7. /**
  8. * A library for displaying table contents on pages.
  9. * @author Andreas Launila
  10. * @version $Revision: 1.10 $
  11. * @package com.lokorin.lokorin.lib
  12. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  13. */
  14.  
  15. /**
  16. * For access to common constants and functions.
  17. */
  18. require_once('common.php');
  19. CssHandler::getInstance()->includeCss('table_displayer');
  20.  
  21. /**
  22. * Describes an abstract table displayer which displays and splits up table
  23. * contents over several pages. It allows pages to display menu bars so the
  24. * users can select the desired page which displays a specified number of
  25. * table rows.
  26. * @author Andreas Launila
  27. * @package com.lokorin.lokorin.lib
  28. */
  29. abstract class AbstractTableDisplayer {
  30. /**
  31. * The page index that the displayer is currently displaying, the first
  32. * page has index 0. As a special case -1 means that everything should be
  33. * displayed.
  34. * @var integer
  35. */
  36. protected $currentPage;
  37. /**
  38. * The maximum number of rows from the table that each page may display.
  39. * @var integer
  40. */
  41. protected $rowsPerPage;
  42. /**
  43. * Constructor for AbstractTableDisplayer.
  44. * @param integer $rowsPerPage The number of rows that should be displayed
  45. * per page.
  46. */
  47. public function __construct($rowsPerPage = 10) {
  48. $this->rowsPerPage = $rowsPerPage;
  49. if(!isset($_GET['page']) || !is_numeric($_GET['page'])) {
  50. $this->currentPage = 0;
  51. } else {
  52. $this->currentPage = $_GET['page'];
  53. }
  54. }
  55. /**
  56. * Gets a page menu associated with the table displayer. The menu contains
  57. * links ordered in a bar which can be used to change the current page.
  58. * @return string XHTML compliant code representing the menu bar.
  59. */
  60. public function getPageMenuBar() {
  61. $maxPages = ceil($this->getRowCount()/$this->rowsPerPage);
  62. if($maxPages == 0) {
  63. //Nothing to display.
  64. return '';
  65. }
  66. //Get the url that the links in the menu bar should use.
  67. if(strlen($_SERVER['QUERY_STRING']) == 0) {
  68. $url = '?page=%s';
  69. } elseif(strpos($_SERVER['QUERY_STRING'],'page') === false) {
  70. $url='?'.urldecode($_SERVER['QUERY_STRING']).'&page=%s';
  71. } else {
  72. $url='?'.preg_replace('/page=[^&]*/','page=%s',urldecode($_SERVER['QUERY_STRING']));
  73. }
  74.  
  75. //Create the menu bar.
  76. $output = '<div class="viewerMenuBar">';
  77. $options = array();
  78. //Left navigation arrow.
  79. if($this->currentPage > 0) {
  80. $output .= '<a href="'.htmlspecialchars(SELF.
  81. sprintf($url, $this->currentPage-1)).'">&lt;</a> ';
  82. } else {
  83. $output .= '&lt; ';
  84. }
  85. //All option.
  86. if($maxPages >= 2) {
  87. //Add the all option.
  88. if($this->currentPage == -1) {
  89. //It is already selected.
  90. $options[] = '<i>All</i>';
  91. } else {
  92. $options[] = '<a href="'.htmlspecialchars(
  93. SELF.sprintf($url, -1)).'">All</a>';
  94. }
  95. }
  96. //Page numbers.
  97. for($i=0; $i<$maxPages; $i++) {
  98. if($i != $this->currentPage) {
  99. $options[] = '<a href="'.htmlspecialchars(
  100. SELF.sprintf($url, $i)).'">'.($i+1).'</a>';
  101. } else {
  102. $options[] = '<i class="selectedPage">'.($i+1).'</i>';
  103. }
  104. }
  105. $output .= implode(', ', $options);
  106.  
  107. //Right navigation arrow.
  108. if($this->currentPage < $maxPages - 1) {
  109. $output .= ' <a href="'.htmlspecialchars(SELF.
  110. sprintf($url, $this->currentPage+1)).'">&gt;</a>';
  111. } else {
  112. $output .= ' &gt;';
  113. }
  114. $output .= '</div>'."\n";
  115. return $output;
  116. }
  117. /**
  118. * Gets the rows that should be displayed on the current page.
  119. * @param array $fields An optional param to specify the names of the
  120. * table fields that should be retrieved from the table. The default
  121. * is that all fields are retrieved. The implementation do not
  122. * necessarily have to obey this parameter, but should if possible.
  123. * @return array The selected rows and fields. The array contains one
  124. * array per row. Each of those array rows contain keys with the
  125. * specified field names along with the connected values. If no
  126. * values were found then an empty array will be returned.
  127. */
  128. public abstract function getPageRows($fields = array());
  129. /**
  130. * Gets the number of rows that the viewer can display in total. This is an
  131. * abstract implementation and should be overridden by all subclasses.
  132. * @return integer A row count.
  133. */
  134. protected abstract function getRowCount();
  135. /**
  136. * Sets the number of rows that should be displayed on each page by the
  137. * displayer.
  138. * @param integer $newRowsPerPageValue The new number of rows that should
  139. * be displayed on each page.
  140. */
  141. public function setRowsPerPage($newRowsPerPageValue) {
  142. $this->rowsPerPage = $newRowsPerPageValue;
  143. }
  144. }
  145.  
  146. /**
  147. * A displayer that takes a custom query and executes it. It can be used to
  148. * perform more advanced queries than the notmal displayer can.
  149. * @author Andreas Launila
  150. * @package com.lokorin.lokorin.lib
  151. */
  152. class CustomTableDisplayer extends AbstractTableDisplayer {
  153. /**
  154. * The SQL query that should be used for counting all the rows that should
  155. * be displayed.
  156. * @var string
  157. */
  158. private $countQuery;
  159. /**
  160. * The SQL query that should be used for selecting all the rows that should
  161. * be displayed.
  162. * @var string
  163. */
  164. private $selectQuery;
  165. /**
  166. * Constructor for CustomTableDisplayer.
  167. * @param string $countQuery The query that should be used for counting
  168. * the rows that should be displayed from the database.
  169. * @param string $selectQuery The query that should be used for selecting
  170. * the rows that should be displayed from the database. It should not
  171. * contain the LIMIT keyword.
  172. * @param integer $rowsPerPage The number of rows that should be displayed
  173. * per page.
  174. */
  175. public function __construct($countQuery, $selectQuery, $rowsPerPage = 10) {
  176. parent::__construct($rowsPerPage);
  177. $this->countQuery = $countQuery;
  178. $this->selectQuery = $selectQuery;
  179. }
  180.  
  181. /**
  182. * @see AbstractTableDisplayer.getPageRows()
  183. */
  184. public function getPageRows($fields = array()) {
  185. global $db;
  186. //We do not care about which fields that have been requested.
  187. $result = $db->query($this->getSqlQuery());
  188. $rows = array();
  189. while($row = mysql_fetch_array($result)) {
  190. $rows[] = $row;
  191. }
  192. return $rows;
  193. }
  194. /**
  195. * Gets the sql query that describes what should be retrieved for the
  196. * current page.
  197. * @return string A complete SQL query.
  198. */
  199. public function getSqlQuery() {
  200. global $db;
  201. $selectQuery = $this->selectQuery;
  202. $current = $this->currentPage;
  203. if($current != -1) {
  204. //Only a specific page should be shown, we have to restrict the
  205. //query.
  206. $rows = $this->rowsPerPage;
  207. $selectQuery .= " LIMIT ".$db->escape($current*$rows).", ".
  208. $db->escape($rows);
  209. }
  210. return $selectQuery;
  211. }
  212. /**
  213. * Gets an sql selector that describes the subset of rows that should be
  214. * selected for the current page.
  215. * @return string An sql selector.
  216. */
  217. public function getSqlSelector() {
  218. return preg_replace("/.*?(WHERE.*)/", '$1', $this->getSqlQuery());
  219. }
  220. /**
  221. * @see AbstractTableDisplayer.getRowCount()
  222. */
  223. protected function getRowCount() {
  224. global $db;
  225. list($count) = mysql_fetch_row($db->query($this->countQuery));
  226. return $count;
  227. }
  228. }
  229.  
  230. /**
  231. * Describes a table displayer which displays and splits up table contents over
  232. * several pages. It allows pages to display menu bars so the users can select
  233. * the desired page which displays a specified number of table rows.
  234. * @author Andreas Launila
  235. * @package com.lokorin.lokorin.lib
  236. */
  237. class TableDisplayer extends AbstractTableDisplayer {
  238. /**
  239. * The name of the table that the displayer should display from.
  240. * @var string
  241. */
  242. private $table;
  243. /**
  244. * The appandage to the queries, the appandage specifies what should be
  245. * displayed. The appandage is placed after 'FROM table'. I.e. to get the
  246. * query "SELECT * FROM foo WHERE MATCH (title, body) AGAINST ('bar')" one
  247. * should use "WHERE MATCH (title, body) AGAINST ('foo')".
  248. * @var string
  249. */
  250. private $queryAppandage;
  251. /**
  252. * Constructor for TableDisplayer.
  253. * @param string $tableName The name of the table that the viewer should
  254. * @param integer $rowsPerPage The number of rows that should be displayed
  255. * per page.
  256. * @param string $queryAppandage An option sql appandage that specifies a
  257. * sub set of the rows that should be displayed. The default is that
  258. * all rows are displayed.
  259. */
  260. public function __construct($tableName, $rowsPerPage = 10, $queryAppandage = '') {
  261. parent::__construct($rowsPerPage);
  262. $this->table = $tableName;
  263. $this->queryAppandage = $queryAppandage;
  264. }
  265. /**
  266. * Gets the sql selector that represents what the displayer will display
  267. * on the current page.
  268. * @return string An sql statement describing a subset of rows.
  269. */
  270. public function getSqlSelector() {
  271. global $db;
  272. $current = $this->currentPage;
  273.  
  274. if($current == -1) {
  275. //All pages should be shown, do not further restrict the query.
  276. return $this->queryAppandage;
  277. }
  278. $rows = $this->rowsPerPage;
  279. $sqlSelector = "LIMIT ".$db->escape($current*$rows).", ".
  280. $db->escape($rows);
  281. if($this->queryAppandage != '') {
  282. $sqlSelector = $this->queryAppandage." ".$sqlSelector;
  283. }
  284. return $sqlSelector;
  285. }
  286. /**
  287. * @see AbstractTableDisplayer.getPageRows()
  288. */
  289. public function getPageRows($fields = array()) {
  290. global $db;
  291. $sqlSelector = $this->getSqlSelector();
  292. if(sizeof($fields) > 0) {
  293. //Fields have been specified.
  294. return $db->querySelect($this->table, $fields, $sqlSelector);
  295. } else {
  296. //No fields selected, select everything.
  297. return $db->querySelectAll($this->table, $sqlSelector);
  298. }
  299. }
  300. /**
  301. * @see AbstractTableDisplayer.getRowCount()
  302. */
  303. protected function getRowCount() {
  304. global $db;
  305. return $db->queryCount($this->table, $this->queryAppandage);
  306. }
  307. }
  308.  
  309. ?>

Documentation generated on Sun, 16 Apr 2006 21:03:18 +0200 by phpDocumentor 1.3.0RC4