PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/dooframework/helper/DooPager.php

http://doophp.googlecode.com/
PHP | 416 lines | 174 code | 55 blank | 187 comment | 44 complexity | e8f61244f20211aced7f9d25e36285c4 MD5 | raw file
  1. <?php
  2. /**
  3. * DooPager class file.
  4. *
  5. * @author Leng Sheng Hong <darkredz@gmail.com>
  6. * @link http://www.doophp.com/
  7. * @copyright Copyright &copy; 2009 Leng Sheng Hong
  8. * @license http://www.doophp.com/license
  9. */
  10. /**
  11. * A helper class to help generating pagination widget when displaying a list of items.
  12. *
  13. * You can change every component of the pagination widget through CSS. The CSS class name for the components can be changed if needed.
  14. *
  15. * <p>You can send GET, POST, PUT and DELETE requests with DooRestClient.
  16. * Method chaining is also supported by this class.</p>
  17. * Example usage:
  18. * <code>
  19. * Doo::loadHelper('DooPager');
  20. * Doo::loadModel('User');
  21. *
  22. * $page = $this->params['pindex'];
  23. * $total = User::getTotal();
  24. * $pager = new DooPager(Doo::conf()->APP_URL.'main/gallery', $total, 6, 10);
  25. *
  26. * #change the text of next/prev
  27. * //$pager->prevText = 'prev';
  28. * //$pager->nextText = 'next';
  29. *
  30. * #If you don't need the next/prev links
  31. * //$pager->noNextPrev();
  32. *
  33. * #Do the pagination
  34. * $pager->paginate($page);
  35. *
  36. * $limit = $pager->limit;
  37. * Doo::db()->find('User', array('limit'=>$limit));
  38. *
  39. * echo $pager->defaultCss;
  40. * //echo $pager->components['prev_link'];
  41. * echo $pager->output;
  42. * echo $pager->components['jump_menu'];
  43. * echo $pager->components['page_size'];
  44. * //echo $pager->components['next_link'];
  45. * </code>
  46. *
  47. * @author Leng Sheng Hong <darkredz@gmail.com>
  48. * @version $Id: DooPager.php 1000 2009-08-21 15:27:22
  49. * @package doo.helper
  50. * @since 1.0
  51. */
  52. class DooPager{
  53. /**
  54. * CSS class name for the Pages links
  55. * @var string
  56. */
  57. public $pagesCss='paginate';
  58. /**
  59. * CSS class name for the Pages DropDown menu
  60. * @var string
  61. */
  62. public $dropDownCss = 'pagerDropDown';
  63. /**
  64. * CSS class name for the page sizes menu
  65. * @var string
  66. */
  67. public $pageSizeCss = 'pageSize';
  68. /**
  69. * CSS class name for inactive links
  70. * @var string
  71. */
  72. public $inactivePrevCss = 'inactivePrev';
  73. /**
  74. * CSS class name for inactive links
  75. * @var string
  76. */
  77. public $inactiveNextCss = 'inactiveNext';
  78. /**
  79. * CSS class name for selected current link
  80. * @var string
  81. */
  82. public $currentCss = 'current';
  83. /**
  84. * CSS class name for next link
  85. * @var string
  86. */
  87. public $nextCss = 'next';
  88. /**
  89. * CSS class name for previous link
  90. * @var string
  91. */
  92. public $prevCss = 'prev';
  93. /**
  94. * Text for the Previous link
  95. * @var string
  96. */
  97. public $prevText = '&laquo;';
  98. /**
  99. * Text for the Next button link
  100. * @var string
  101. */
  102. public $nextText = '&raquo;';
  103. /**
  104. * Contain the list of components to be used in view. (pages, jump menu, page_size, current_page, total_page)
  105. * @var array
  106. */
  107. public $components;
  108. /**
  109. * Items to be displayed per page
  110. * @var int
  111. */
  112. public $itemPerPage=10;
  113. /**
  114. * The current page number
  115. * @var int
  116. */
  117. public $currentPage = 1;
  118. /**
  119. * Maximum Pager length
  120. * @var int
  121. */
  122. public $maxLength = 10;
  123. /**
  124. * Total items to be split in the pagination
  125. * @var int
  126. */
  127. public $totalItem;
  128. /**
  129. * Total pages in the pagination
  130. * @var int
  131. */
  132. public $totalPage;
  133. /**
  134. * The pages HTML output
  135. * @var string
  136. */
  137. public $output;
  138. /**
  139. * The URL prefix for all the pagination links
  140. * @var string
  141. */
  142. public $baseUrl;
  143. //----- for SQL use -----
  144. /**
  145. * Position of the record to begin the pagination LIMIT query
  146. * @var string
  147. */
  148. public $low;
  149. /**
  150. * Position of the record to end the pagination LIMIT query
  151. * @var string
  152. */
  153. public $high;
  154. /**
  155. * To be use with the pagination LIMIT query LIMIT $limit
  156. * @var string
  157. */
  158. public $limit;
  159. /**
  160. * To display/hide the next/prev button links
  161. * @var bool
  162. */
  163. protected $_noNextPrev=false;
  164. /**
  165. * Default css for testing
  166. * @var string
  167. */
  168. public $defaultCss = '<style>
  169. .paginate, .current, .inactivePrev, .inactiveNext, .prev, .next {
  170. font-family: Verdana,Helvetica,Arial,sans-serif;
  171. font-size:12px;
  172. border:1px solid #D8D8D8;
  173. float:left;
  174. height:20px;
  175. line-height:20px;
  176. margin-right:2px;
  177. overflow:hidden;
  178. padding:0 6px;
  179. text-decoration:none;
  180. }
  181. a:hover .paginate{
  182. border-color:#006699;
  183. }
  184. .current {
  185. border-color:#006699;
  186. background-color:#006699;
  187. color:#fff;
  188. font-weight:bold;
  189. }
  190. .inactivePrev, .inactiveNext{
  191. color:#999;
  192. }
  193. </style>';
  194. /**
  195. * Instanciate the Pager object
  196. *
  197. * @param string $baseURL Base URL to be appended to the page number
  198. * @param int $totalItems Total items to be paginate
  199. * @param int $itemPerPage Items to be shown in one page.
  200. * @param int $maxlength Number of links for the pager navigation
  201. * @param string $prevText Text for the Previous button link
  202. * @param string $nextText Text for the Next button link
  203. */
  204. function __construct($baseURL='', $totalItems=120, $itemPerPage=10, $maxlength=10, $prevText='&laquo;', $nextText='&raquo;'){
  205. $this->baseUrl = $baseURL;
  206. $this->totalItem = $totalItems;
  207. $this->maxLength = $maxlength;
  208. $this->itemPerPage = $itemPerPage;
  209. $this->prevText = $prevText;
  210. $this->nextText = $nextText;
  211. }
  212. /**
  213. * Hide next & prev links from the output
  214. */
  215. public function noNextPrev(){
  216. $this->_noNextPrev = true;
  217. }
  218. /**
  219. * Set the CSS class name for the pager components
  220. *
  221. * @param string $pagesName
  222. * @param string $inactiveName
  223. * @param string $currentName
  224. * @param string $nextName
  225. * @param string $prevName
  226. * @param string $dropDownName
  227. * @param string $pageSizeName
  228. */
  229. public function setCss($pagesName='paginate', $inactiveName='inactive', $currentName='current', $nextName='next', $prevName='prev', $dropDownName='pagerDropDown', $pageSizeName='pageSize'){
  230. $this->pagesCss = $pagesName;
  231. $this->inactiveCss = $inactiveName;
  232. $this->currentCss = $currentName;
  233. $this->nextCss = $nextName;
  234. $this->prevCss = $prevName;
  235. $this->dropDownCss = $dropDownName;
  236. $this->pageSizeCss = $pageSizeName;
  237. }
  238. /**
  239. * Paginate the list of items and prepare pager components to be use in View.
  240. *
  241. * @param int $page The current page number
  242. * @param int $itemPerPage Items per page
  243. * @return array An array of pager component, access via <strong>pages, jump_menu, page_size, current_page, total_page, next_link, prev_link</strong>
  244. */
  245. public function paginate($page, $itemPerPage=0){
  246. if($itemPerPage===0){
  247. $itemPerPage = $this->itemPerPage;
  248. }else{
  249. $this->itemPerPage = $itemPerPage;
  250. }
  251. $this->totalPage = ceil($this->totalItem/$itemPerPage);
  252. $this->currentPage = (int) $page;
  253. if($this->currentPage < 1 || !is_numeric($this->currentPage))
  254. $this->currentPage = 1;
  255. if($this->currentPage > $this->totalPage)
  256. $this->currentPage = $this->totalPage;
  257. $prev_page = $this->currentPage-1;
  258. $next_page = $this->currentPage+1;
  259. if($this->_noNextPrev)
  260. $this->components['prev_link'] = ($this->currentPage != 1 && $this->totalItem >= $this->maxLength) ? "<a class=\"{$this->prevCss}\" href=\"{$this->baseUrl}/{$prev_page}\">{$this->prevText}</a> ":"<span class=\"{$this->inactivePrevCss}\">{$this->prevText}</span> ";
  261. else
  262. $this->output = ($this->currentPage != 1 && $this->totalItem >= $this->maxLength) ? "<a class=\"{$this->prevCss}\" href=\"{$this->baseUrl}/{$prev_page}\">{$this->prevText}</a> ":"<span class=\"{$this->inactivePrevCss}\">{$this->prevText}</span> ";
  263. if($this->totalPage > $this->maxLength){
  264. $midRange = $this->maxLength-2;
  265. $start_range = $this->currentPage - floor($midRange/2);
  266. $end_range = $this->currentPage + floor($midRange/2);
  267. if($start_range <= 0){
  268. $end_range += abs($start_range)+1;
  269. $start_range = 1;
  270. }
  271. if($end_range > $this->totalPage){
  272. $start_range -= $end_range-$this->totalPage;
  273. $end_range = $this->totalPage;
  274. }
  275. while($end_range-$start_range+1<$this->maxLength-1){
  276. $end_range++;
  277. }
  278. $modulus = (int) $this->maxLength%2==0;
  279. $center = floor($this->maxLength/2);
  280. if($this->currentPage > $center ){
  281. $end_range --;
  282. }
  283. if($modulus==0 && $this->totalPage - $this->currentPage+1 <= $center){
  284. while($end_range-$start_range+1<$this->maxLength-1){
  285. $start_range--;
  286. }
  287. }
  288. $range = range($start_range,$end_range);
  289. for($i=1;$i<=$this->totalPage;$i++){
  290. // loop through all pages. if first, last, or in range, display
  291. if($i==1 || $i==$this->totalPage || in_array($i,$range)){
  292. $lastDot = '';
  293. if($modulus==1){
  294. if($i==$this->totalPage && $this->currentPage<($this->totalPage-($this->maxLength-$center-$modulus)))
  295. $lastDot = '...';
  296. }else{
  297. if($i==$this->totalPage && $this->currentPage<=($this->totalPage-($this->maxLength-$center)))
  298. $lastDot = '...';
  299. }
  300. $this->output .= ($i == $this->currentPage) ? "<a class =\"{$this->currentCss}\" href=\"javascript:void(0);\">$i":"<a class=\"{$this->pagesCss}\" href=\"{$this->baseUrl}/$i\">$lastDot $i";
  301. if($range[0] > 2 && $i == 1)
  302. $this->output .= " ...</a> ";
  303. else
  304. $this->output .= '</a> ';
  305. }
  306. }
  307. if($this->_noNextPrev)
  308. $this->components['next_link'] = ($this->currentPage != $this->totalPage && $this->totalItem >= $this->maxLength) ? "<a class=\"{$this->nextCss}\" href=\"{$this->baseUrl}/$next_page\">{$this->nextText}</a>\n" : "<span class=\"{$this->inactiveNextCss}\">{$this->nextText}</span>\n";
  309. else
  310. $this->output .= ($this->currentPage != $this->totalPage && $this->totalItem >= $this->maxLength) ? "<a class=\"{$this->nextCss}\" href=\"{$this->baseUrl}/$next_page\">{$this->nextText}</a>\n" : "<span class=\"{$this->inactiveNextCss}\">{$this->nextText}</span>\n";
  311. }
  312. else{
  313. for($i=1;$i<=$this->totalPage;$i++){
  314. $this->output .= ($i == $this->currentPage) ? "<a class=\"{$this->currentCss}\" href=\"javascript:void(0);\">$i</a> ":"<a class=\"{$this->pagesCss}\" href=\"{$this->baseUrl}/$i\">$i</a> ";
  315. }
  316. if($this->_noNextPrev)
  317. $this->components['next_link'] = ($this->currentPage != $this->totalPage && $this->totalItem >= $this->maxLength) ? "<a class=\"{$this->nextCss}\" href=\"{$this->baseUrl}/$next_page\">{$this->nextText}</a>\n" : "<span class=\"{$this->inactiveNextCss}\">{$this->nextText}</span>\n";
  318. else
  319. $this->output .= ($this->currentPage != $this->totalPage && $this->totalItem >= $this->maxLength) ? "<a class=\"{$this->nextCss}\" href=\"{$this->baseUrl}/$next_page\">{$this->nextText}</a>\n" : "<span class=\"{$this->inactiveNextCss}\">{$this->nextText}</span>\n";
  320. }
  321. $this->low = ($this->currentPage-1) * $this->itemPerPage;
  322. $this->high = ($this->currentPage * $this->itemPerPage)-1;
  323. $this->limit = " $this->low,$this->itemPerPage";
  324. $this->components['pages'] = $this->output;
  325. $this->components['jump_menu'] = $this->showJumpMenu();
  326. $this->components['page_size'] = $this->showPageSize();
  327. $this->components['current_page'] = $this->currentPage;
  328. $this->components['total_page'] = $this->totalPage;
  329. return $this->components;
  330. }
  331. /**
  332. * Generate a Drop down menu for different page sizes.
  333. *
  334. * @param array $sizeArr Array of page size
  335. * @return string Drop down menu for the page sizes
  336. */
  337. public function showPageSize($sizeArr=null){
  338. $items = '';
  339. if($sizeArr==null)
  340. $ipp_array = array(10,25,50,100);
  341. foreach($ipp_array as $ipp_opt)
  342. $items .= ($ipp_opt == $this->itemPerPage) ? "<option selected value=\"$ipp_opt\">$ipp_opt</option>\n":"<option value=\"$ipp_opt\">$ipp_opt</option>\n";
  343. return "<select class=\"{$this->pageSizeCss}\" onchange=\"window.location='{$this->baseUrl}/1/'+this[this.selectedIndex].value; return false\">$items</select>\n";
  344. }
  345. /**
  346. * Generate a Drop down menu for all page numer
  347. *
  348. * @param bool $withPageSize Navigate with page size
  349. * @return string Drop down menu for all page numer
  350. */
  351. public function showJumpMenu($withPageSize=false){
  352. $option = '';
  353. for($i=1;$i<=$this->totalPage;$i++){
  354. $option .= ($i==$this->currentPage) ? "<option value=\"$i\" selected>$i</option>\n":"<option value=\"$i\">$i</option>\n";
  355. }
  356. if($withPageSize)
  357. return "<select class=\"{$this->dropDownCss}\" onchange=\"window.location='{$this->baseUrl}/'+this[this.selectedIndex].value+'/$this->itemPerPage';return false\">$option</select>\n";
  358. return "<select class=\"{$this->dropDownCss}\" onchange=\"window.location='{$this->baseUrl}/'+this[this.selectedIndex].value;return false\">$option</select>\n";
  359. }
  360. }