pager.class.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. <?php
  2. /**
  3. * ZenTaoPHP的分页类。
  4. * The pager class file of ZenTaoPHP framework.
  5. *
  6. * The author disclaims copyright to this source code. In place of
  7. * a legal notice, here is a blessing:
  8. *
  9. * May you do good and not evil.
  10. * May you find forgiveness for yourself and forgive others.
  11. * May you share freely, never taking more than you give.
  12. */
  13. /**
  14. * pager类.
  15. * Pager class.
  16. *
  17. * @package framework
  18. */
  19. class basePager
  20. {
  21. /**
  22. * 每页的默认显示记录数。
  23. * The default counts of per page.
  24. *
  25. * @public int
  26. */
  27. const DEFAULT_REC_PER_PAGE = 20;
  28. /**
  29. * 总个数。
  30. * The total counts.
  31. *
  32. * @var int
  33. * @access public
  34. */
  35. public $recTotal;
  36. /**
  37. * 每页的记录数。
  38. * Record count per page.
  39. *
  40. * @var int
  41. * @access public
  42. */
  43. public $recPerPage;
  44. /**
  45. * The cookie name of recPerPage.
  46. *
  47. * @var string
  48. * @access public
  49. */
  50. public $pageCookie;
  51. /**
  52. * 总页面数。
  53. * Page count.
  54. *
  55. * @var string
  56. * @access public
  57. */
  58. public $pageTotal;
  59. /**
  60. * 当前页码。
  61. * Current page id.
  62. *
  63. * @var string
  64. * @access public
  65. */
  66. public $pageID;
  67. /**
  68. * 全局变量$app。
  69. * The global $app.
  70. *
  71. * @var object
  72. * @access public
  73. */
  74. public $app;
  75. /**
  76. * 全局变量$lang。
  77. * The global $lang.
  78. *
  79. * @var object
  80. * @access public
  81. */
  82. public $lang;
  83. /**
  84. * 当前的模块名。
  85. * Current module name.
  86. *
  87. * @var string
  88. * @access public
  89. */
  90. public $moduleName;
  91. /**
  92. * 当前的方法名。
  93. * Current method.
  94. *
  95. * @var string
  96. * @access public
  97. */
  98. public $methodName;
  99. /**
  100. * 参数信息。
  101. * The params.
  102. *
  103. * @public array
  104. */
  105. public $params;
  106. /**
  107. * 构造方法。
  108. * The construct function.
  109. *
  110. * @param int $recTotal
  111. * @param int $recPerPage
  112. * @param int $pageID
  113. * @access public
  114. * @return void
  115. */
  116. public function __construct($recTotal = 0, $recPerPage = 20, $pageID = 1)
  117. {
  118. $this->setApp();
  119. $this->setLang();
  120. $this->setModuleName();
  121. $this->setMethodName();
  122. $this->setRecTotal((int)$recTotal);
  123. $this->setRecPerPage((int)$recPerPage);
  124. $this->setPageTotal();
  125. $this->setPageID((int)$pageID);
  126. }
  127. /**
  128. * 构造方法。
  129. * The factory function.
  130. *
  131. * @param int $recTotal
  132. * @param int $recPerPage
  133. * @param int $pageID
  134. * @access public
  135. * @return object
  136. */
  137. public static function init($recTotal = 0, $recPerPage = 20, $pageID = 1)
  138. {
  139. return new pager($recTotal, $recPerPage, $pageID);
  140. }
  141. /**
  142. * 设置总记录数。
  143. * Set the recTotal property.
  144. *
  145. * @param int $recTotal
  146. * @access public
  147. * @return void
  148. */
  149. public function setRecTotal($recTotal = 0)
  150. {
  151. $this->recTotal = (int)$recTotal;
  152. }
  153. /**
  154. * 设置每页记录数。
  155. * Set the recPerPage property.
  156. *
  157. * @param int $recPerPage
  158. * @access public
  159. * @return void
  160. */
  161. public function setRecPerPage($recPerPage)
  162. {
  163. /* Set the cookie name. */
  164. if(!(defined('RUN_MODE') and RUN_MODE == 'api') && $this->app->getViewType() != 'json')
  165. {
  166. $this->pageCookie = 'pager' . ucfirst($this->app->rawModule) . ucfirst($this->app->rawMethod);
  167. if(isset($_COOKIE[$this->pageCookie])) $recPerPage = $_COOKIE[$this->pageCookie];
  168. }
  169. $this->recPerPage = ($recPerPage > 0) ? (int)$recPerPage : PAGER::DEFAULT_REC_PER_PAGE;
  170. }
  171. /**
  172. * 设置总页数。
  173. * Set the pageTotal property.
  174. *
  175. * @access public
  176. * @return void
  177. */
  178. public function setPageTotal()
  179. {
  180. $this->pageTotal = ceil($this->recTotal / $this->recPerPage);
  181. }
  182. /**
  183. * 设置页码。
  184. * Set the page id.
  185. *
  186. * @param int $pageID
  187. * @access public
  188. * @return void
  189. */
  190. public function setPageID($pageID)
  191. {
  192. if($pageID > 0 and ($this->pageTotal == 0 or $pageID <= $this->pageTotal))
  193. {
  194. $this->pageID = $pageID;
  195. }
  196. else
  197. {
  198. $this->pageID = 1;
  199. }
  200. }
  201. /**
  202. * 设置全局变量$app。
  203. * Set the $app property;
  204. *
  205. * @access public
  206. * @return void
  207. */
  208. public function setApp()
  209. {
  210. global $app;
  211. $this->app = $app;
  212. }
  213. /**
  214. * 设置全局变量$lang。
  215. * Set the $lang property.
  216. *
  217. * @access public
  218. * @return void
  219. */
  220. public function setLang()
  221. {
  222. global $lang;
  223. $this->lang = $lang;
  224. }
  225. /**
  226. * 设置模块名。
  227. * Set the $moduleName property.
  228. *
  229. * @access public
  230. * @return void
  231. */
  232. public function setModuleName()
  233. {
  234. $this->moduleName = $this->app->getModuleName();
  235. }
  236. /**
  237. * 设置方法名。
  238. * Set the $methodName property.
  239. *
  240. * @access public
  241. * @return void
  242. */
  243. public function setMethodName()
  244. {
  245. $this->methodName = $this->app->getMethodName();
  246. }
  247. /**
  248. * 从请求网址中获取记录总数、每页记录数、页码。
  249. * Get recTotal, recPerpage, pageID from the request params, and add them to params.
  250. *
  251. * @access public
  252. * @return void
  253. */
  254. public function setParams($params = array())
  255. {
  256. $this->params = $params ? $params : $this->app->getParams();
  257. foreach($this->params as $key => $value)
  258. {
  259. if(strtolower($key) == 'rectotal') $this->params[$key] = $this->recTotal;
  260. if(strtolower($key) == 'recperpage') $this->params[$key] = $this->recPerPage;
  261. if(strtolower($key) == 'pageid') $this->params[$key] = $this->pageID;
  262. }
  263. }
  264. /**
  265. * 创建limit语句。
  266. * Create the limit string.
  267. *
  268. * @access public
  269. * @return string
  270. */
  271. public function limit()
  272. {
  273. $limit = '';
  274. if($this->pageTotal > 1) $limit = ' lImiT ' . ($this->pageID - 1) * $this->recPerPage . ", $this->recPerPage";
  275. return $limit;
  276. }
  277. /**
  278. * 向页面显示分页信息。
  279. * Print the pager's html.
  280. *
  281. * @param string $align
  282. * @param string $type
  283. * @access public
  284. * @return void
  285. */
  286. public function show($align = 'right', $type = 'full')
  287. {
  288. if($align === 'justify')
  289. {
  290. echo $this->getJustify($type);
  291. }
  292. else
  293. {
  294. echo $this->get($align, $type);
  295. }
  296. }
  297. /**
  298. * 获取优化后的分页。
  299. * Get the justify pager html string
  300. *
  301. * @access public
  302. * @return [type] [description]
  303. */
  304. public function getJustify()
  305. {
  306. if($this->recTotal <= 0) return '';
  307. $this->setParams();
  308. $pager = '';
  309. $pager .= "<li class='previous" . ($this->pageID == 1 ? ' disabled' : '') . "'>";
  310. $this->params['pageID'] = 1;
  311. $pager .= $this->createLink('« ' . $this->lang->pager->previousPage) . '</li>';
  312. $pager .= "<li class='caption'>";
  313. $firstId = $this->recPerPage * ($this->pageID - 1) + 1;
  314. $pager .= sprintf($this->lang->pager->summery, $firstId, max(min($this->recPerPage * $this->pageID, $this->recTotal), $firstId), $this->recTotal);
  315. $pager .= '</li>';
  316. $pager .= "<li class='next" . (($this->pageID == $this->pageTotal || $this->pageTotal <= 1) ? ' disabled' : '') . "'>";
  317. $this->params['pageID'] = min($this->pageTotal, $this->pageID + 1);
  318. $pager .= $this->createLink($this->lang->pager->nextPage . ' »') . '</li>';
  319. return "<ul class='pager pager-justify'>{$pager}</ul>";
  320. }
  321. /**
  322. * 设置分页信息的样式。
  323. * Get the pager html string.
  324. *
  325. * @param string $align
  326. * @param string $type the pager type, full|short|shortest
  327. * @access public
  328. * @return string
  329. */
  330. public function get($align = 'right', $type = 'full')
  331. {
  332. /* 如果记录个数为0,返回没有记录。 */
  333. /* If the RecTotal is zero, return with no record. */
  334. if($this->recTotal == 0) return $type == 'mobile' ? '' : "<div style='float:$align; clear:none;' class='page'>{$this->lang->pager->noRecord}</div>";
  335. /* Set the params. */
  336. $this->setParams();
  337. /* 创建前一页和后一页链接。 */
  338. /* Create the prePage and nextpage, all types have them. */
  339. $pager = $this->createPrePage($type);
  340. $pager .= $this->createNextPage($type);
  341. /* 简单和完全模式。 The short and full type. */
  342. if($type !== 'shortest' and $type !== 'mobile')
  343. {
  344. $pager = $this->createFirstPage() . $pager;
  345. $pager .= $this->createLastPage();
  346. }
  347. if($type == 'mobile')
  348. {
  349. $position = $this->pageTotal == 1 ? '' : $this->pageID . '/' . $this->pageTotal;
  350. $pager = $pager . ' ' . $position;
  351. }
  352. else if($type != 'full')
  353. {
  354. $pager = $this->pageID . '/' . $this->pageTotal . ' ' . $pager;
  355. }
  356. /* 只是完全模式。 Only the full type . */
  357. if($type == 'full')
  358. {
  359. $pager = $this->createDigest() . $pager;
  360. $pager .= $this->createGoTo();
  361. $pager .= $this->createRecPerPageJS();
  362. }
  363. return "<div style='float:$align; clear:none;' class='pager form-inline'>$pager</div>";
  364. }
  365. /**
  366. * 生成分页摘要信息。
  367. * Create the digest code.
  368. *
  369. * @access public
  370. * @return string
  371. */
  372. public function createDigest()
  373. {
  374. return sprintf($this->lang->pager->digest, $this->recTotal, $this->createRecPerPageList(), $this->pageID, $this->pageTotal);
  375. }
  376. /**
  377. * 创建首页链接。
  378. * Create the first page.
  379. *
  380. * @access public
  381. * @return string
  382. */
  383. public function createFirstPage()
  384. {
  385. if($this->pageID == 1) return $this->lang->pager->first . ' ';
  386. $this->params['pageID'] = 1;
  387. return $this->createLink($this->lang->pager->first);
  388. }
  389. /**
  390. * 创建前一页链接。
  391. * Create the pre page html.
  392. *
  393. * @param string $type
  394. * @access public
  395. * @return string
  396. */
  397. public function createPrePage($type = 'full')
  398. {
  399. if($type == 'mobile')
  400. {
  401. if($this->pageID == 1) return '';
  402. $this->params['pageID'] = $this->pageID - 1;
  403. return $this->createLink($this->lang->pager->pre);
  404. }
  405. else
  406. {
  407. if($this->pageID == 1) return $this->lang->pager->pre . ' ';
  408. $this->params['pageID'] = $this->pageID - 1;
  409. return $this->createLink($this->lang->pager->pre);
  410. }
  411. }
  412. /**
  413. * 创建下一页链接。
  414. * Create the next page html.
  415. *
  416. * @param string $type
  417. * @access public
  418. * @return string
  419. */
  420. public function createNextPage($type = 'full')
  421. {
  422. if($type == 'mobile')
  423. {
  424. if($this->pageID == $this->pageTotal) return '';
  425. $this->params['pageID'] = $this->pageID + 1;
  426. return $this->createLink($this->lang->pager->next);
  427. }
  428. else
  429. {
  430. if($this->pageID == $this->pageTotal) return $this->lang->pager->next . ' ';
  431. $this->params['pageID'] = $this->pageID + 1;
  432. return $this->createLink($this->lang->pager->next);
  433. }
  434. }
  435. /**
  436. * 创建最后一页链接。
  437. * Create the last page
  438. *
  439. * @access public
  440. * @return string
  441. */
  442. public function createLastPage()
  443. {
  444. if($this->pageID == $this->pageTotal) return $this->lang->pager->last . ' ';
  445. $this->params['pageID'] = $this->pageTotal;
  446. return $this->createLink($this->lang->pager->last);
  447. }
  448. /**
  449. * 创建每页显示记录数的select标签。
  450. * Create the select object of record perpage.
  451. *
  452. * @access public
  453. * @return string
  454. */
  455. public function createRecPerPageJS()
  456. {
  457. /*
  458. * 替换recTotal, recPerPage, pageID为特殊的字符串,然后用js代码替换掉。
  459. * Replace the recTotal, recPerPage, pageID to special string, and then replace them with values by JS.
  460. **/
  461. $params = $this->params;
  462. foreach($params as $key => $value)
  463. {
  464. if(strtolower($key) == 'rectotal') $params[$key] = '_recTotal_';
  465. if(strtolower($key) == 'recperpage') $params[$key] = '_recPerPage_';
  466. if(strtolower($key) == 'pageid') $params[$key] = '_pageID_';
  467. }
  468. $vars = '';
  469. foreach($params as $key => $value) $vars .= "$key=$value&";
  470. $vars = rtrim($vars, '&');
  471. $js = <<<EOT
  472. <script language='Javascript'>
  473. vars = '$vars';
  474. pageCookie = '$this->pageCookie';
  475. function submitPage(mode, perPage)
  476. {
  477. pageTotal = parseInt(document.getElementById('_pageTotal').value);
  478. pageID = document.getElementById('_pageID').value;
  479. recPerPage = document.getElementById('_recPerPage').getAttribute('data-value');
  480. recTotal = document.getElementById('_recTotal').value;
  481. if(mode == 'changePageID')
  482. {
  483. if(pageID > pageTotal) pageID = pageTotal;
  484. if(pageID < 1) pageID = 1;
  485. }
  486. else if(mode == 'changeRecPerPage')
  487. {
  488. recPerPage = perPage;
  489. pageID = 1;
  490. }
  491. $.cookie(pageCookie, recPerPage, {expires:config.cookieLife, path:config.webRoot});
  492. vars = vars.replace('_recTotal_', recTotal)
  493. vars = vars.replace('_recPerPage_', recPerPage)
  494. vars = vars.replace('_pageID_', pageID);
  495. location.href=createLink('$this->moduleName', '$this->methodName', vars);
  496. }
  497. </script>
  498. EOT;
  499. return $js;
  500. }
  501. /**
  502. * 生成每页显示记录数的select列表。
  503. * Create the select list of RecPerPage.
  504. *
  505. * @access public
  506. * @return string
  507. */
  508. public function createRecPerPageList()
  509. {
  510. for($i = 5; $i <= 50; $i += 5) $range[$i] = $i;
  511. $range[100] = 100;
  512. $range[200] = 200;
  513. $range[500] = 500;
  514. $range[1000] = 1000;
  515. $range[2000] = 2000;
  516. $html = "<div class='dropdown dropup'><a href='javascript:;' data-toggle='dropdown' id='_recPerPage' data-value='{$this->recPerPage}'>" . (sprintf($this->lang->pager->recPerPage, $this->recPerPage)) . "<span class='caret'></span></a><ul class='dropdown-menu'>";
  517. foreach ($range as $key => $value)
  518. {
  519. $html .= '<li' . ($this->recPerPage == $value ? " class='active'" : '') .'>' . "<a href='javascript:submitPage(\"changeRecPerPage\", $value)'>{$value}</a>" . '</li>';
  520. }
  521. $html .= '</ul></div>';
  522. return $html;
  523. }
  524. /**
  525. * 生成跳转到指定页码的部分。
  526. * Create the goto part html.
  527. *
  528. * @access public
  529. * @return string
  530. */
  531. public function createGoTo()
  532. {
  533. $goToHtml = "<input type='hidden' id='_recTotal' value='$this->recTotal' />\n";
  534. $goToHtml .= "<input type='hidden' id='_pageTotal' value='$this->pageTotal' />\n";
  535. $goToHtml .= "<input type='text' id='_pageID' value='$this->pageID' style='text-align:center;width:30px;' class='form-control' /> \n";
  536. $goToHtml .= "<input type='button' id='goto' value='{$this->lang->pager->locate}' onclick='submitPage(\"changePageID\");' class='btn'/>";
  537. return $goToHtml;
  538. }
  539. /**
  540. * 创建链接。
  541. * Create link.
  542. *
  543. * @param string $title
  544. * @access public
  545. * @return string
  546. */
  547. public function createLink($title)
  548. {
  549. return html::a(helper::createLink($this->moduleName, $this->methodName, $this->params), $title);
  550. }
  551. }