PageRenderTime 39ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/runtime/lib/util/PropelPager.php

https://github.com/1989gaurav/Propel
PHP | 597 lines | 254 code | 54 blank | 289 comment | 27 complexity | e7dfba38574ddcb6f0385c955c8dee4e MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. /**
  10. * PropelPager
  11. *
  12. * Example Usage:
  13. *
  14. * require_once 'propel/util/PropelPager.php';
  15. * require_once 'PEACH/Propel/Poem/poemPeer.php';
  16. *
  17. * $c = new Criteria();
  18. * $c->addDescendingOrderByColumn(poemPeer::SID);
  19. *
  20. * // with join
  21. * $pager = new PropelPager($c, 'poemPeer', 'doSelectJoinPoemUsers', 1, 50);
  22. *
  23. * // without Join
  24. *
  25. * $pager = new PropelPager($c, 'poemPeer', 'doSelect', 1, 50);
  26. *
  27. * Some template:
  28. *
  29. * <p>
  30. * Total Pages: <?=$pager->getTotalPages()?> Total Records: <?=$pager->getTotalRecordCount()?>
  31. * </p>
  32. * <table>
  33. * <tr>
  34. * <td>
  35. * <?if ($link = $pager->getFirstPage):?>
  36. * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
  37. * <?endif?>
  38. * </td>
  39. * <td>
  40. * <?if ($link = $pager->getPrev()):?>
  41. * <a href="somescript?page=<?=$link?>">Previous</a>|
  42. * <?endif?>
  43. * </td>
  44. * <td>
  45. * <?foreach ($pager->getPrevLinks() as $link):?>
  46. * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
  47. * <?endforeach?>
  48. * </td>
  49. * <td><?=$pager->getPage()?></td>
  50. * <td>
  51. * <?foreach ($pager->getNextLinks() as $link):?>
  52. * | <a href="somescript?page=<?=$link?>"><?=$link?></a>
  53. * <?endforeach?>
  54. * </td>
  55. * <td>
  56. * <?if ($link = $pager->getNext()):?>
  57. * <a href="somescript?page=<?=$link?>">Last</a>|
  58. * <?endif?>
  59. * </td>
  60. * <td>
  61. * <?if ($link = $pager->getLastPage()):?>
  62. * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
  63. * <?endif?>
  64. * </td>
  65. * </tr>
  66. * </table>
  67. * <table id="latestPoems">
  68. * <tr>
  69. * <th>Title</th>
  70. * <th>Auteur</th>
  71. * <th>Date</th>
  72. * <th>comments</th>
  73. * </tr>
  74. * <?foreach ($pager->getResult() as $poem):?>
  75. * <tr>
  76. * <td><?=$poem->getTitle()?></td>
  77. * <td><?=$poem->getPoemUsers()->getUname()?></td>
  78. * <td><?=$poem->getTime()?></td>
  79. * <td><?=$poem->getComments()?></td>
  80. * </tr>
  81. * <?endforeach?>
  82. * </table>
  83. *
  84. *
  85. * @author Rob Halff <info@rhalff.com>
  86. * @author Niklas Närhinen <niklas@narhinen.net>
  87. * @version $Revision$
  88. * @copyright Copyright (c) 2004 Rob Halff: LGPL - See LICENCE
  89. * @package propel.runtime.util
  90. */
  91. class PropelPager implements Countable, Iterator
  92. {
  93. private $recordCount;
  94. private $pages;
  95. private $peerClass;
  96. private $peerSelectMethod;
  97. private $peerCountMethod;
  98. private $criteria;
  99. private $countCriteria;
  100. private $page;
  101. private $rs = null;
  102. //Iterator vars
  103. private $currentKey = 0;
  104. /** @var int Start row (offset) */
  105. protected $start = 0;
  106. /** @var int Max rows to return (0 means all) */
  107. protected $max = 0;
  108. /**
  109. * Create a new Propel Pager.
  110. * @param Criteria $c
  111. * @param string $peerClass The name of the static Peer class.
  112. * @param string $peerSelectMethod The name of the static method for selecting content from the Peer class.
  113. * @param int $page The current page (1-based).
  114. * @param int $rowsPerPage The number of rows that should be displayed per page.
  115. */
  116. public function __construct($c = null, $peerClass = null, $peerSelectMethod = null, $page = 1, $rowsPerPage = 25)
  117. {
  118. if (!isset($c)) {
  119. $c = new Criteria();
  120. }
  121. $this->setCriteria($c);
  122. $this->setPeerClass($peerClass);
  123. $this->setPeerSelectMethod($peerSelectMethod);
  124. $this->guessPeerCountMethod();
  125. $this->setPage($page);
  126. $this->setRowsPerPage($rowsPerPage);
  127. }
  128. /**
  129. * Set the criteria for this pager.
  130. * @param Criteria $c
  131. * @return void
  132. */
  133. public function setCriteria(Criteria $c)
  134. {
  135. $this->criteria = $c;
  136. }
  137. /**
  138. * Return the Criteria object for this pager.
  139. * @return Criteria
  140. */
  141. public function getCriteria()
  142. {
  143. return $this->criteria;
  144. }
  145. /**
  146. * Set the Peer Classname
  147. *
  148. * @param string $class
  149. * @return void
  150. */
  151. public function setPeerClass($class)
  152. {
  153. $this->peerClass = $class;
  154. }
  155. /**
  156. * Return the Peer Classname.
  157. * @return string
  158. */
  159. public function getPeerClass()
  160. {
  161. return $this->peerClass;
  162. }
  163. /**
  164. * Set the Peer select method.
  165. * This exists for legacy support, please use setPeerSelectMethod().
  166. * @param string $method The name of the static method to call on the Peer class.
  167. * @return void
  168. * @see setPeerSelectMethod()
  169. * @deprecated
  170. */
  171. public function setPeerMethod($method)
  172. {
  173. $this->setPeerSelectMethod($method);
  174. }
  175. /**
  176. * Return the Peer select method.
  177. * This exists for legacy support, please use getPeerSelectMethod().
  178. * @return string
  179. * @see getPeerSelectMethod()
  180. * @deprecated
  181. */
  182. public function getPeerMethod()
  183. {
  184. return $this->getPeerSelectMethod();
  185. }
  186. /**
  187. * Set the Peer select method.
  188. *
  189. * @param string $method The name of the static method to call on the Peer class.
  190. * @return void
  191. */
  192. public function setPeerSelectMethod($method)
  193. {
  194. $this->peerSelectMethod = $method;
  195. }
  196. /**
  197. * Return the Peer select method.
  198. * @return string
  199. */
  200. public function getPeerSelectMethod()
  201. {
  202. return $this->peerSelectMethod;
  203. }
  204. /**
  205. * Sets the Count method.
  206. * This is set based on the Peer method, for example if Peer method is doSelectJoin*() then the
  207. * count method will be doCountJoin*().
  208. * @param string $method The name of the static method to call on the Peer class.
  209. */
  210. public function setPeerCountMethod($method)
  211. {
  212. $this->peerCountMethod = $method;
  213. }
  214. /**
  215. * Return the Peer count method.
  216. */
  217. public function getPeerCountMethod()
  218. {
  219. return $this->peerCountMethod;
  220. }
  221. /**
  222. * Guesses the Peer count method based on the select method.
  223. */
  224. private function guessPeerCountMethod()
  225. {
  226. $selectMethod = $this->getPeerSelectMethod();
  227. if ($selectMethod == 'doSelect') {
  228. $countMethod = 'doCount';
  229. } elseif ( ($pos = stripos($selectMethod, 'doSelectJoin')) === 0) {
  230. $countMethod = 'doCount' . substr($selectMethod, strlen('doSelect'));
  231. } else {
  232. // we will fall back to doCount() if we don't understand the join
  233. // method; however, it probably won't be accurate. Maybe triggering an error would
  234. // be appropriate ...
  235. $countMethod = 'doCount';
  236. }
  237. $this->setPeerCountMethod($countMethod);
  238. }
  239. /**
  240. * Get the paged resultset
  241. *
  242. * @return mixed $rs
  243. */
  244. public function getResult()
  245. {
  246. if (!isset($this->rs)) {
  247. $this->doRs();
  248. }
  249. return $this->rs;
  250. }
  251. /**
  252. * Get the paged resultset
  253. *
  254. * Main method which creates a paged result set based on the criteria
  255. * and the requested peer select method.
  256. *
  257. */
  258. private function doRs()
  259. {
  260. $this->criteria->setOffset($this->start);
  261. $this->criteria->setLimit($this->max);
  262. $this->rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $this->criteria);
  263. }
  264. /**
  265. * Get the first page
  266. *
  267. * For now I can only think of returning 1 always.
  268. * It should probably return 0 if there are no pages
  269. *
  270. * @return int 1
  271. */
  272. public function getFirstPage()
  273. {
  274. return '1';
  275. }
  276. /**
  277. * Convenience method to indicate whether current page is the first page.
  278. *
  279. * @return boolean
  280. */
  281. public function atFirstPage()
  282. {
  283. return $this->getPage() == $this->getFirstPage();
  284. }
  285. /**
  286. * Get last page
  287. *
  288. * @return int $lastPage
  289. */
  290. public function getLastPage()
  291. {
  292. $totalPages = $this->getTotalPages();
  293. if ($totalPages == 0) {
  294. return 1;
  295. } else {
  296. return $totalPages;
  297. }
  298. }
  299. /**
  300. * Convenience method to indicate whether current page is the last page.
  301. *
  302. * @return boolean
  303. */
  304. public function atLastPage()
  305. {
  306. return $this->getPage() == $this->getLastPage();
  307. }
  308. /**
  309. * get total pages
  310. *
  311. * @return int $this->pages
  312. */
  313. public function getTotalPages() {
  314. if (!isset($this->pages)) {
  315. $recordCount = $this->getTotalRecordCount();
  316. if ($this->max > 0) {
  317. $this->pages = ceil($recordCount/$this->max);
  318. } else {
  319. $this->pages = 0;
  320. }
  321. }
  322. return $this->pages;
  323. }
  324. /**
  325. * get an array of previous id's
  326. *
  327. * @param int $range
  328. * @return array $links
  329. */
  330. public function getPrevLinks($range = 5)
  331. {
  332. $total = $this->getTotalPages();
  333. $start = $this->getPage() - 1;
  334. $end = $this->getPage() - $range;
  335. $first = $this->getFirstPage();
  336. $links = array();
  337. for ($i=$start; $i>$end; $i--) {
  338. if ($i < $first) {
  339. break;
  340. }
  341. $links[] = $i;
  342. }
  343. return array_reverse($links);
  344. }
  345. /**
  346. * get an array of next id's
  347. *
  348. * @param int $range
  349. * @return array $links
  350. */
  351. public function getNextLinks($range = 5)
  352. {
  353. $total = $this->getTotalPages();
  354. $start = $this->getPage() + 1;
  355. $end = $this->getPage() + $range;
  356. $last = $this->getLastPage();
  357. $links = array();
  358. for ($i=$start; $i<$end; $i++) {
  359. if ($i > $last) {
  360. break;
  361. }
  362. $links[] = $i;
  363. }
  364. return $links;
  365. }
  366. /**
  367. * Returns whether last page is complete
  368. *
  369. * @return bool Last page complete or not
  370. */
  371. public function isLastPageComplete()
  372. {
  373. return !($this->getTotalRecordCount() % $this->max);
  374. }
  375. /**
  376. * get previous id
  377. *
  378. * @return mixed $prev
  379. */
  380. public function getPrev() {
  381. if ($this->getPage() != $this->getFirstPage()) {
  382. $prev = $this->getPage() - 1;
  383. } else {
  384. $prev = false;
  385. }
  386. return $prev;
  387. }
  388. /**
  389. * get next id
  390. *
  391. * @return mixed $next
  392. */
  393. public function getNext() {
  394. if ($this->getPage() != $this->getLastPage()) {
  395. $next = $this->getPage() + 1;
  396. } else {
  397. $next = false;
  398. }
  399. return $next;
  400. }
  401. /**
  402. * Set the current page number (First page is 1).
  403. * @param int $page
  404. * @return void
  405. */
  406. public function setPage($page)
  407. {
  408. $this->page = $page;
  409. // (re-)calculate start rec
  410. $this->calculateStart();
  411. }
  412. /**
  413. * Get current page.
  414. * @return int
  415. */
  416. public function getPage()
  417. {
  418. return $this->page;
  419. }
  420. /**
  421. * Set the number of rows per page.
  422. * @param int $r
  423. */
  424. public function setRowsPerPage($r)
  425. {
  426. $this->max = $r;
  427. // (re-)calculate start rec
  428. $this->calculateStart();
  429. }
  430. /**
  431. * Get number of rows per page.
  432. * @return int
  433. */
  434. public function getRowsPerPage()
  435. {
  436. return $this->max;
  437. }
  438. /**
  439. * Calculate startrow / max rows based on current page and rows-per-page.
  440. * @return void
  441. */
  442. private function calculateStart()
  443. {
  444. $this->start = ( ($this->page - 1) * $this->max );
  445. }
  446. /**
  447. * Gets the total number of (un-LIMITed) records.
  448. *
  449. * This method will perform a query that executes un-LIMITed query.
  450. *
  451. * @return int Total number of records - disregarding page, maxrows, etc.
  452. */
  453. public function getTotalRecordCount()
  454. {
  455. if (!isset($this->rs)) {
  456. $this->doRs();
  457. }
  458. if (empty($this->recordCount)) {
  459. $this->countCriteria = clone $this->criteria;
  460. $this->countCriteria->setLimit(0);
  461. $this->countCriteria->setOffset(0);
  462. $this->recordCount = call_user_func(
  463. array(
  464. $this->getPeerClass(),
  465. $this->getPeerCountMethod()
  466. ),
  467. $this->countCriteria
  468. );
  469. }
  470. return $this->recordCount;
  471. }
  472. /**
  473. * Sets the start row or offset.
  474. * @param int $v
  475. */
  476. public function setStart($v)
  477. {
  478. $this->start = $v;
  479. }
  480. /**
  481. * Sets max rows (limit).
  482. * @param int $v
  483. * @return void
  484. */
  485. public function setMax($v)
  486. {
  487. $this->max = $v;
  488. }
  489. /**
  490. * Returns the count of the current page's records
  491. * @return int
  492. */
  493. public function count()
  494. {
  495. return count($this->getResult());
  496. }
  497. /**
  498. * Returns the current element of the iterator
  499. * @return mixed
  500. */
  501. public function current()
  502. {
  503. if (!isset($this->rs)) {
  504. $this->doRs();
  505. }
  506. return $this->rs[$this->currentKey];
  507. }
  508. /**
  509. * Returns the current key of the iterator
  510. * @return int
  511. */
  512. public function key()
  513. {
  514. return $this->currentKey;
  515. }
  516. /**
  517. * Advances the iterator to the next element
  518. * @return void
  519. */
  520. public function next()
  521. {
  522. $this->currentKey++;
  523. }
  524. /**
  525. * Resets the iterator to the first element
  526. * @return void
  527. */
  528. public function rewind()
  529. {
  530. $this->currentKey = 0;
  531. }
  532. /**
  533. * Checks if the current key exists in the container
  534. * @return boolean
  535. */
  536. public function valid()
  537. {
  538. if (!isset($this->rs)) {
  539. $this->doRs();
  540. }
  541. return in_array($this->currentKey, array_keys($this->rs));
  542. }
  543. }