From b3e36d655c831c63c26a710eb3c8bd82ca3b6fc5 Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Sun, 22 Feb 2009 16:53:41 +0000 Subject: - Patch #299267 by Crell: add extender support to the SELECT query builder. --- includes/pager.inc | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) (limited to 'includes/pager.inc') diff --git a/includes/pager.inc b/includes/pager.inc index 4b219a8ca..a3c80ae5e 100644 --- a/includes/pager.inc +++ b/includes/pager.inc @@ -6,6 +6,150 @@ * Functions to aid in presenting database results as a set of pages. */ + +/** + * Query extender for pager queries. + * + * This is the "default" pager mechanism. It creates a paged query with a fixed + * number of entries per page. + */ +class PagerDefault extends SelectQueryExtender { + + /** + * The highest element we've autogenerated so far. + * + * @var int + */ + static protected $maxElement = 0; + + /** + * The number of elements per page to allow. + * + * @var int + */ + protected $limit = 10; + + /** + * The unique ID of this pager on this page. + * + * @var int + */ + protected $element = NULL; + + /** + * The count query that will be used for this pager. + * + * @var SelectQueryInterface + */ + protected $customCountQuery = FALSE; + + /** + * Override the execute method. + * + * Before we run the query, we need to add pager-based range() instructions + * to it. + */ + public function execute() { + global $pager_page_array, $pager_total, $pager_total_items; + + // A NULL limit is the "kill switch" for pager queries. + if (empty($this->limit)) { + return; + } + $this->ensureElement(); + + $page = isset($_GET['page']) ? $_GET['page'] : ''; + + // Convert comma-separated $page to an array, used by other functions. + $pager_page_array = explode(',', $page); + + // We calculate the total of pages as ceil(items / limit). + $pager_total_items[$this->element] = $this->getCountQuery()->execute()->fetchField(); + $pager_total[$this->element] = ceil($pager_total_items[$this->element] / $this->limit); + $pager_page_array[$this->element] = max(0, min((int)$pager_page_array[$this->element], ((int)$pager_total[$this->element]) - 1)); + $this->range($pager_page_array[$this->element] * $this->limit, $this->limit); + + // Now that we've added our pager-based range instructions, run the query normally. + return $this->query->execute(); + } + + /** + * Ensure that there is an element associated with this query. + * + * After running this query, access $this->element to get the element for this + * query. + */ + protected function ensureElement() { + if (!empty($this->element)) { + return; + } + + $this->element = self::$maxElement++; + } + + /** + * Specify the count query object to use for this pager. + * + * You will rarely need to specify a count query directly. If not specified, + * one is generated off of the pager query itself. + * + * @param SelectQueryInterface $query + * The count query object. It must return a single row with a single column, + * which is the total number of records. + */ + public function setCountQuery(SelectQueryInterface $query) { + $this->customCountQuery = $query; + } + + /** + * Retrieve the count query for this pager. + * + * The count query may be specified manually or, by default, taken from the + * query we are extending. + * + * @return + * A count SelectQueryInterface object. + */ + protected function getCountQuery() { + if ($this->customCountQuery) { + return $this->customCountQuery; + } + else { + return $this->query->countQuery(); + } + } + + /** + * Specify the maximum number of elements per page for this query. + * + * The default if not specified is 10 items per page. + * + * @param $limit + * An integer specifying the number of elements per page. If passed a false + * value (FALSE, 0, NULL), the pager is disabled. + */ + public function limit($limit = 10) { + $this->limit = $limit; + return $this; + } + + /** + * Specify the element ID for this pager query. + * + * The element is used to differentiate different pager queries on the same + * page so that they may be operated independently. If you do not specify an + * element, every pager query on the page will get a unique element. If for + * whatever reason you want to explicitly define an element for a given query, + * you may do so here. + * + * @param $element + */ + public function element($element) { + $this->element = $element; + return $this; + } +} + /** * Perform a paged database query. * -- cgit v1.2.3