- <?php
- /*
- * Lokorin.com
- * Copyright 2004-2006
- * Licensed under the GNU LGPL. See COPYING for full terms.
- */
- /**
- * A library for displaying table contents on pages.
- * @author Andreas Launila
- * @version $Revision: 1.10 $
- * @package com.lokorin.lokorin.lib
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
- */
-
- /**
- * For access to common constants and functions.
- */
- require_once('common.php');
- CssHandler::getInstance()->includeCss('table_displayer');
-
- /**
- * Describes an abstract table displayer which displays and splits up table
- * contents over several pages. It allows pages to display menu bars so the
- * users can select the desired page which displays a specified number of
- * table rows.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- abstract class AbstractTableDisplayer {
- /**
- * The page index that the displayer is currently displaying, the first
- * page has index 0. As a special case -1 means that everything should be
- * displayed.
- * @var integer
- */
- protected $currentPage;
- /**
- * The maximum number of rows from the table that each page may display.
- * @var integer
- */
- protected $rowsPerPage;
-
- /**
- * Constructor for AbstractTableDisplayer.
- * @param integer $rowsPerPage The number of rows that should be displayed
- * per page.
- */
- public function __construct($rowsPerPage = 10) {
- $this->rowsPerPage = $rowsPerPage;
- if(!isset($_GET['page']) || !is_numeric($_GET['page'])) {
- $this->currentPage = 0;
- } else {
- $this->currentPage = $_GET['page'];
- }
- }
-
- /**
- * Gets a page menu associated with the table displayer. The menu contains
- * links ordered in a bar which can be used to change the current page.
- * @return string XHTML compliant code representing the menu bar.
- */
- public function getPageMenuBar() {
- $maxPages = ceil($this->getRowCount()/$this->rowsPerPage);
- if($maxPages == 0) {
- //Nothing to display.
- return '';
- }
-
- //Get the url that the links in the menu bar should use.
- if(strlen($_SERVER['QUERY_STRING']) == 0) {
- $url = '?page=%s';
- } elseif(strpos($_SERVER['QUERY_STRING'],'page') === false) {
- $url='?'.urldecode($_SERVER['QUERY_STRING']).'&page=%s';
- } else {
- $url='?'.preg_replace('/page=[^&]*/','page=%s',urldecode($_SERVER['QUERY_STRING']));
- }
-
- //Create the menu bar.
- $output = '<div class="viewerMenuBar">';
- $options = array();
-
- //Left navigation arrow.
- if($this->currentPage > 0) {
- $output .= '<a href="'.htmlspecialchars(SELF.
- sprintf($url, $this->currentPage-1)).'"><</a> ';
- } else {
- $output .= '< ';
- }
-
- //All option.
- if($maxPages >= 2) {
- //Add the all option.
- if($this->currentPage == -1) {
- //It is already selected.
- $options[] = '<i>All</i>';
- } else {
- $options[] = '<a href="'.htmlspecialchars(
- SELF.sprintf($url, -1)).'">All</a>';
- }
- }
-
- //Page numbers.
- for($i=0; $i<$maxPages; $i++) {
- if($i != $this->currentPage) {
- $options[] = '<a href="'.htmlspecialchars(
- SELF.sprintf($url, $i)).'">'.($i+1).'</a>';
- } else {
- $options[] = '<i class="selectedPage">'.($i+1).'</i>';
- }
- }
- $output .= implode(', ', $options);
-
- //Right navigation arrow.
- if($this->currentPage < $maxPages - 1) {
- $output .= ' <a href="'.htmlspecialchars(SELF.
- sprintf($url, $this->currentPage+1)).'">></a>';
- } else {
- $output .= ' >';
- }
-
- $output .= '</div>'."\n";
- return $output;
- }
-
- /**
- * Gets the rows that should be displayed on the current page.
- * @param array $fields An optional param to specify the names of the
- * table fields that should be retrieved from the table. The default
- * is that all fields are retrieved. The implementation do not
- * necessarily have to obey this parameter, but should if possible.
- * @return array The selected rows and fields. The array contains one
- * array per row. Each of those array rows contain keys with the
- * specified field names along with the connected values. If no
- * values were found then an empty array will be returned.
- */
- public abstract function getPageRows($fields = array());
-
- /**
- * Gets the number of rows that the viewer can display in total. This is an
- * abstract implementation and should be overridden by all subclasses.
- * @return integer A row count.
- */
- protected abstract function getRowCount();
-
- /**
- * Sets the number of rows that should be displayed on each page by the
- * displayer.
- * @param integer $newRowsPerPageValue The new number of rows that should
- * be displayed on each page.
- */
- public function setRowsPerPage($newRowsPerPageValue) {
- $this->rowsPerPage = $newRowsPerPageValue;
- }
- }
-
- /**
- * A displayer that takes a custom query and executes it. It can be used to
- * perform more advanced queries than the notmal displayer can.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class CustomTableDisplayer extends AbstractTableDisplayer {
- /**
- * The SQL query that should be used for counting all the rows that should
- * be displayed.
- * @var string
- */
- private $countQuery;
- /**
- * The SQL query that should be used for selecting all the rows that should
- * be displayed.
- * @var string
- */
- private $selectQuery;
-
- /**
- * Constructor for CustomTableDisplayer.
- * @param string $countQuery The query that should be used for counting
- * the rows that should be displayed from the database.
- * @param string $selectQuery The query that should be used for selecting
- * the rows that should be displayed from the database. It should not
- * contain the LIMIT keyword.
- * @param integer $rowsPerPage The number of rows that should be displayed
- * per page.
- */
- public function __construct($countQuery, $selectQuery, $rowsPerPage = 10) {
- parent::__construct($rowsPerPage);
- $this->countQuery = $countQuery;
- $this->selectQuery = $selectQuery;
- }
-
- /**
- * @see AbstractTableDisplayer.getPageRows()
- */
- public function getPageRows($fields = array()) {
- global $db;
-
- //We do not care about which fields that have been requested.
- $result = $db->query($this->getSqlQuery());
- $rows = array();
- while($row = mysql_fetch_array($result)) {
- $rows[] = $row;
- }
- return $rows;
- }
-
- /**
- * Gets the sql query that describes what should be retrieved for the
- * current page.
- * @return string A complete SQL query.
- */
- public function getSqlQuery() {
- global $db;
-
- $selectQuery = $this->selectQuery;
- $current = $this->currentPage;
- if($current != -1) {
- //Only a specific page should be shown, we have to restrict the
- //query.
- $rows = $this->rowsPerPage;
- $selectQuery .= " LIMIT ".$db->escape($current*$rows).", ".
- $db->escape($rows);
- }
- return $selectQuery;
- }
-
- /**
- * Gets an sql selector that describes the subset of rows that should be
- * selected for the current page.
- * @return string An sql selector.
- */
- public function getSqlSelector() {
- return preg_replace("/.*?(WHERE.*)/", '$1', $this->getSqlQuery());
- }
-
- /**
- * @see AbstractTableDisplayer.getRowCount()
- */
- protected function getRowCount() {
- global $db;
-
- list($count) = mysql_fetch_row($db->query($this->countQuery));
- return $count;
- }
- }
-
- /**
- * Describes a table displayer which displays and splits up table contents over
- * several pages. It allows pages to display menu bars so the users can select
- * the desired page which displays a specified number of table rows.
- * @author Andreas Launila
- * @package com.lokorin.lokorin.lib
- */
- class TableDisplayer extends AbstractTableDisplayer {
- /**
- * The name of the table that the displayer should display from.
- * @var string
- */
- private $table;
- /**
- * The appandage to the queries, the appandage specifies what should be
- * displayed. The appandage is placed after 'FROM table'. I.e. to get the
- * query "SELECT * FROM foo WHERE MATCH (title, body) AGAINST ('bar')" one
- * should use "WHERE MATCH (title, body) AGAINST ('foo')".
- * @var string
- */
- private $queryAppandage;
-
- /**
- * Constructor for TableDisplayer.
- * @param string $tableName The name of the table that the viewer should
- * @param integer $rowsPerPage The number of rows that should be displayed
- * per page.
- * @param string $queryAppandage An option sql appandage that specifies a
- * sub set of the rows that should be displayed. The default is that
- * all rows are displayed.
- */
- public function __construct($tableName, $rowsPerPage = 10, $queryAppandage = '') {
- parent::__construct($rowsPerPage);
- $this->table = $tableName;
- $this->queryAppandage = $queryAppandage;
- }
-
- /**
- * Gets the sql selector that represents what the displayer will display
- * on the current page.
- * @return string An sql statement describing a subset of rows.
- */
- public function getSqlSelector() {
- global $db;
-
- $current = $this->currentPage;
-
- if($current == -1) {
- //All pages should be shown, do not further restrict the query.
- return $this->queryAppandage;
- }
-
- $rows = $this->rowsPerPage;
- $sqlSelector = "LIMIT ".$db->escape($current*$rows).", ".
- $db->escape($rows);
- if($this->queryAppandage != '') {
- $sqlSelector = $this->queryAppandage." ".$sqlSelector;
- }
- return $sqlSelector;
- }
-
- /**
- * @see AbstractTableDisplayer.getPageRows()
- */
- public function getPageRows($fields = array()) {
- global $db;
-
- $sqlSelector = $this->getSqlSelector();
- if(sizeof($fields) > 0) {
- //Fields have been specified.
- return $db->querySelect($this->table, $fields, $sqlSelector);
- } else {
- //No fields selected, select everything.
- return $db->querySelectAll($this->table, $sqlSelector);
- }
- }
-
- /**
- * @see AbstractTableDisplayer.getRowCount()
- */
- protected function getRowCount() {
- global $db;
-
- return $db->queryCount($this->table, $this->queryAppandage);
- }
- }
-
- ?>