Pager class

From: Date: Tue, 05 Mar 2002 09:31:27 +0000
Subject: Pager class
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-4899@lists.php.net to get a copy of this message
According to PEAR commiting rules I represent Pager class. I use it very often in my work and may be it will be useful for somebody else. Pager draws nothing itself but only calculates values necessary for drawing lists splitted into number of pages. It takes number of page and returns such values: 1. Subset of list items which must be placed on current page Pager supports 2 modes: 1. Full list mode In this mode all items in list assigned to Pager as array and result of it work is array of items which must be placed on this page. This mode can be useful when you use very complex query to database or you get items some other way then data basequery and can't specify offset and limit. 2. Limit-Offset mode In this mode class user specify only the number of items in list and then get offset of first item on page and number (limit) of items on this page. This mode can be useful when number of items in list very large and it is too expensive to underway them as single array. 2 . Data which required to draw list navigation bar - array of nearest page numbers which must be shown in bar - number of current page - number of previous and next pages which not shown in bar - number of last page for example if current page is 8 and we want to show 5 nearest pages in bar and have 17 pages at all we can draw having such data: [<<] [<] 6 7 [8] 9 10 [>][>>] where 6 7 9 10 - links to corresponding pages [8] - current page (inactive) [<] - link to page 5 [>] - link to page 11 [<<] - link to page 1 [>>] - link to page 17 (last page) if we select [<] we will get: 1 2 3 4 [5] [>][>>] where [5] - current page [>] - link to page 6 [>>] - link to page 17 and so on ... Methods of Pager class: Class Pager has constructor with 3 arguments: Pager($mode = PAGER_FULL_LIST_MODE, $itemsOnPage = 20, $pagesInBar = 10); where $mode - mode of Pager PAGER_FULL_LIST_MODE or PAGER_LIMIT_OFFSET_MODE $itemsOnPage - number of items on page $pagesInBar - number of pages in bar setItems(&$items) - set items of list where $items - in Full list mode is array of items in list in Limit-Offset mode is number of items in list &setCurrentPage($pageNumber = 1) where $pageNumber - number of page this function returns object of class which contain all necessary data Methods of PagerState class: getOuterLeftPage() - returns number of page previous to first in bar or 0 if such page does not exists getOuterRightPage() - returns number of page next to last in bar or 0 if such page does not exists getLastPage() - returns number of last page &getBar() - returns array of page numbers which must be drawn in bar getBarCurrentPage() - returns number of selected page in bar countPagesInBar() - returns number of pages in bar &getItems() in Full list mode returns array of items which must be placed on selected page in Limit-Offset mode returns associative array with 2 members: 'offset' => offset of first item on page 'limit' => number of items on page Pager class after calling setItems() method can be stored in session, or serialized in other way and then only setCurrentPage() method can be called when page is changed. If maintainers of PEAR project will be interested in this class I will prepare full documentation on it and comment sources more verbose. Andrey Djachenko This is source code for PagerState and Pager classes: <?php define('PAGER_FULL_LIST_MODE', 0); define('PAGER_LIMIT_OFFSET_MODE', 1); class PagerState { var $_leftOuterPage = 0; var $_rigthOuterPage = 0; var $_lastPage = 0; var $_bar; //array var $_barCurrentPage = 0; var $_items; //array function getOuterLeftPage() {return $this->_leftOuterPage;} function getOuterRightPage() {return $this->_rigthOuterPage;} function getLastPage() {return $this->_lastPage;} function &getBar() {return $this->_bar;} function getBarCurrentPage() {return $this->_barCurrentPage;} function countPagesInBar() {return sizeof($this->_bar);} function &getItems() {return $this->_items;} } class Pager { var $_itemsOnPage = 0; var $_pagesInBar = 1; var $_items; //array var $_itemsNumber = 0; var $_decades = 0; var $_pagesInLastDecade = 0; var $_pages = 0; var $_itemsOnLastPage = 0; var $_mode = PAGER_FULL_LIST_MODE; //////////////////////////////////////////////////////////////////////// function Pager($mode = PAGER_FULL_LIST_MODE, $itemsOnPage = 20, $pagesInBar = 10) { $this->_mode = $mode; $this->_itemsOnPage = $itemsOnPage; $this->_pagesInBar = $pagesInBar; } //////////////////////////////////////////////////////////////////////// function setItems(&$items) { if ($this->_mode == PAGER_FULL_LIST_MODE) { $this->_items = (is_array($items)) ? $items : array(); $this->_itemsNumber = sizeof($this->_items); $this->_init(); } else if ($this->_mode == PAGER_LIMIT_OFFSET_MODE) { $this->_itemsNumber = (is_numeric($items) && (int)$items > 0) ? $items : 0; $this->_init(); } } //////////////////////////////////////////////////////////////////////// function &setCurrentPage($pageNumber = 1) { if ($pageNumber < 1) { $pageNumber = 1; } if ($pageNumber > $this->_pages - 1) { $pageNumber = $this->_pages; } $current_decade = ($pageNumber - 1) / $this->_pagesInBar; $current_decade = (int)$current_decade + 1; $ps = new PagerState; //items $first = ($pageNumber != 1) ? ($pageNumber - 1) * $this->_itemsOnPage : 0; $number = ($pageNumber != $this->_pages) ? $this->_itemsOnPage : $this->_itemsOnLastPage; if ($this->_mode == PAGER_FULL_LIST_MODE) { $ps->_items = ($this->_itemsNumber > 0) ? array_slice($this->_items, $first, $number) : array(); } else if ($this->_mode == PAGER_LIMIT_OFFSET_MODE) { $ps->_items = ($this->_itemsNumber > 0) ? array('offset'=>$first, 'limit'=>$number) : array('offset'=>0, 'limit'=>0); } //pages in bar if ($this->_pages == 0) { $number = 0; } else if ($current_decade == $this->_decades) { $number = $this->_pages % $this->_pagesInBar; if ($number == 0) { $number = $this->_pagesInBar; } } else { $number = $this->_pagesInBar; } $first = $current_decade - 1; $first = (int)$first; $first = $first * $this->_pagesInBar + 1; $index = $pageNumber % $this->_pagesInBar; $index = ($index == 0) ? $this->_pagesInBar - 1 : $index - 1; for ($i = 0; $i < $number; $i++) { $s[] = $first + $i; } $ps->_bar = $s; $ps->_barCurrentPage = $ps->_bar[$index]; //left link $ps->_leftOuterPage = ($current_decade > 1) ? $first - 1 : 0; //rigth link $ps->_rigthOuterPage = ($current_decade < $this->_decades) ? $first + $number : 0; //last page $ps->_lastPage = $this->_pages; return $ps; } //////////////////////////////////////////////////////////////////////// function _init() { $this->_pages = $this->_itemsNumber / $this->_itemsOnPage; $this->_pages = (int)$this->_pages; $this->_itemsOnLastPage = $this->_itemsNumber % $this->_itemsOnPage; if ($this->_itemsOnLastPage > 0) { $this->_pages++; } else { $this->_itemsOnLastPage = $this->_itemsOnPage; } $this->_decades = $this->_pages / $this->_pagesInBar; $this->_decades = (int)$this->_decades; $this->_pagesInLastDecade = $this->_pages % $this->_pagesInBar; if ($this->_pagesInLastDecade > 0) { $this->_decades++; } else { $this->_pagesInLastDecade = $this->_pagesInBar; } } //////////////////////////////////////////////////////////////////////// } ?>

« previous php.pear.dev (#4899) next »