1. sfPager.class.php
  2. /** * sfPager class. * * @package symfony * @subpackage addon * @author Fabien Potencier * @version SVN: $Id: sfPager.class.php 24533 2009-11-29 15:58:01Z Kris.Wallsmith $ */
  3. abstract class sfPager implements Iterator, Countable
  4. {
  5. protected
  6. $page = 1,
  7. $maxPerPage = 0,
  8. $lastPage = 1,
  9. $nbResults = 0,
  10. $class = '',
  11. $tableName = '',
  12. $objects = null,
  13. $cursor = 1,
  14. $parameters = array(),
  15. $currentMaxLink = 1,
  16. $parameterHolder = null,
  17. $maxRecordLimit = false,
  18. $results = null,
  19. $resultsCounter = 0;
  20. /**
  21. * Constructor.
  22. *
  23. * @param string $class The model class
  24. * @param integer $maxPerPage Number of records to display per page
  25. */
  26. public function __construct($class, $maxPerPage = 10)
  27. {
  28. $this->setClass($class);
  29. $this->setMaxPerPage($maxPerPage);
  30. $this->parameterHolder = new sfParameterHolder();
  31. }
  32. /**
  33. * Initialize the pager.
  34. *
  35. * Function to be called after parameters have been set.
  36. */
  37. abstract public function init();
  38. /**
  39. * Returns an array of results on the given page.
  40. *
  41. * @return array
  42. */
  43. abstract public function getResults();
  44. /**
  45. * Returns an object at a certain offset.
  46. *
  47. * Used internally by {@link getCurrent()}.
  48. *
  49. * @return mixed
  50. */
  51. abstract protected function retrieveObject($offset);
  52. /**
  53. * Returns the current pager's max link.
  54. *
  55. * @return integer
  56. */
  57. public function getCurrentMaxLink()
  58. {
  59. return $this->currentMaxLink;
  60. }
  61. /**
  62. * Returns the current pager's max record limit.
  63. *
  64. * @return integer
  65. */
  66. public function getMaxRecordLimit()
  67. {
  68. return $this->maxRecordLimit;
  69. }
  70. /**
  71. * Sets the current pager's max record limit.
  72. *
  73. * @param integer $limit
  74. */
  75. public function setMaxRecordLimit($limit)
  76. {
  77. $this->maxRecordLimit = $limit;
  78. }
  79. /**
  80. * Returns an array of page numbers to use in pagination links.
  81. *
  82. * @param integer $nb_links The maximum number of page numbers to return
  83. *
  84. * @return array
  85. */
  86. public function getLinks($nb_links = 5)
  87. {
  88. $links = array();
  89. $tmp = $this->page - floor($nb_links / 2);
  90. $check = $this->lastPage - $nb_links + 1;
  91. $limit = $check > 0 ? $check : 1;
  92. $begin = $tmp > 0 ? ($tmp > $limit ? $limit : $tmp) : 1;
  93. $i = (int) $begin;
  94. while ($i < $begin + $nb_links && $i <= $this->lastPage)
  95. {
  96. $links[] = $i++;
  97. }
  98. $this->currentMaxLink = count($links) ? $links[count($links) - 1] : 1;
  99. return $links;
  100. }
  101. /**
  102. * Returns true if the current query requires pagination.
  103. *
  104. * @return boolean
  105. */
  106. public function haveToPaginate()
  107. {
  108. return $this->getMaxPerPage() && $this->getNbResults() > $this->getMaxPerPage();
  109. }
  110. /**
  111. * Returns the current cursor.
  112. *
  113. * @return integer
  114. */
  115. public function getCursor()
  116. {
  117. return $this->cursor;
  118. }
  119. /**
  120. * Sets the current cursor.
  121. *
  122. * @param integer $pos
  123. */
  124. public function setCursor($pos)
  125. {
  126. if ($pos < 1)
  127. {
  128. $this->cursor = 1;
  129. }
  130. else if ($pos > $this->nbResults)
  131. {
  132. $this->cursor = $this->nbResults;
  133. }
  134. else
  135. {
  136. $this->cursor = $pos;
  137. }
  138. }
  139. /**
  140. * Returns an object by cursor position.
  141. *
  142. * @param integer $pos
  143. *
  144. * @return mixed
  145. */
  146. public function getObjectByCursor($pos)
  147. {
  148. $this->setCursor($pos);
  149. return $this->getCurrent();
  150. }
  151. /**
  152. * Returns the current object.
  153. *
  154. * @return mixed
  155. */
  156. public function getCurrent()
  157. {
  158. return $this->retrieveObject($this->cursor);
  159. }
  160. /**
  161. * Returns the next object.
  162. *
  163. * @return mixed|null
  164. */
  165. public function getNext()
  166. {
  167. if ($this->cursor + 1 > $this->nbResults)
  168. {
  169. return null;
  170. }
  171. else
  172. {
  173. return $this->retrieveObject($this->cursor + 1);
  174. }
  175. }
  176. /**
  177. * Returns the previous object.
  178. *
  179. * @return mixed|null
  180. */
  181. public function getPrevious()
  182. {
  183. if ($this->cursor - 1 < 1)
  184. {
  185. return null;
  186. }
  187. else
  188. {
  189. return $this->retrieveObject($this->cursor - 1);
  190. }
  191. }
  192. /**
  193. * Returns the first index on the current page.
  194. *
  195. * @return integer
  196. */
  197. public function getFirstIndice()
  198. {
  199. if ($this->page == 0)
  200. {
  201. return 1;
  202. }
  203. else
  204. {
  205. return ($this->page - 1) * $this->maxPerPage + 1;
  206. }
  207. }
  208. /**
  209. * Returns the last index on the current page.
  210. *
  211. * @return integer
  212. */
  213. public function getLastIndice()
  214. {
  215. if ($this->page == 0)
  216. {
  217. return $this->nbResults;
  218. }
  219. else
  220. {
  221. if ($this->page * $this->maxPerPage >= $this->nbResults)
  222. {
  223. return $this->nbResults;
  224. }
  225. else
  226. {
  227. return $this->page * $this->maxPerPage;
  228. }
  229. }
  230. }
  231. /**
  232. * Returns the current class.
  233. *
  234. * @return string
  235. */
  236. public function getClass()
  237. {
  238. return $this->class;
  239. }
  240. /**
  241. * Sets the current class.
  242. *
  243. * @param string $class
  244. */
  245. public function setClass($class)
  246. {
  247. $this->class = $class;
  248. }
  249. /**
  250. * Returns the number of results.
  251. *
  252. * @return integer
  253. */
  254. public function getNbResults()
  255. {
  256. return $this->nbResults;
  257. }
  258. /**
  259. * Sets the number of results.
  260. *
  261. * @param integer $nb
  262. */
  263. protected function setNbResults($nb)
  264. {
  265. $this->nbResults = $nb;
  266. }
  267. /**
  268. * Returns the first page number.
  269. *
  270. * @return integer
  271. */
  272. public function getFirstPage()
  273. {
  274. return 1;
  275. }
  276. /**
  277. * Returns the last page number.
  278. *
  279. * @return integer
  280. */
  281. public function getLastPage()
  282. {
  283. return $this->lastPage;
  284. }
  285. /**
  286. * Sets the last page number.
  287. *
  288. * @param integer $page
  289. */
  290. protected function setLastPage($page)
  291. {
  292. $this->lastPage = $page;
  293. if ($this->getPage() > $page)
  294. {
  295. $this->setPage($page);
  296. }
  297. }
  298. /**
  299. * Returns the current page.
  300. *
  301. * @return integer
  302. */
  303. public function getPage()
  304. {
  305. return $this->page;
  306. }
  307. /**
  308. * Returns the next page.
  309. *
  310. * @return integer
  311. */
  312. public function getNextPage()
  313. {
  314. return min($this->getPage() + 1, $this->getLastPage());
  315. }
  316. /**
  317. * Returns the previous page.
  318. *
  319. * @return integer
  320. */
  321. public function getPreviousPage()
  322. {
  323. return max($this->getPage() - 1, $this->getFirstPage());
  324. }
  325. /**
  326. * Sets the current page.
  327. *
  328. * @param integer $page
  329. */
  330. public function setPage($page)
  331. {
  332. $this->page = intval($page);
  333. if ($this->page <= 0)
  334. {
  335. // set first page, which depends on a maximum set
  336. $this->page = $this->getMaxPerPage() ? 1 : 0;
  337. }
  338. }
  339. /**
  340. * Returns the maximum number of results per page.
  341. *
  342. * @return integer
  343. */
  344. public function getMaxPerPage()
  345. {
  346. return $this->maxPerPage;
  347. }
  348. /**
  349. * Sets the maximum number of results per page.
  350. *
  351. * @param integer $max
  352. */
  353. public function setMaxPerPage($max)
  354. {
  355. if ($max > 0)
  356. {
  357. $this->maxPerPage = $max;
  358. if ($this->page == 0)
  359. {
  360. $this->page = 1;
  361. }
  362. }
  363. else if ($max == 0)
  364. {
  365. $this->maxPerPage = 0;
  366. $this->page = 0;
  367. }
  368. else
  369. {
  370. $this->maxPerPage = 1;
  371. if ($this->page == 0)
  372. {
  373. $this->page = 1;
  374. }
  375. }
  376. }
  377. /**
  378. * Returns true if on the first page.
  379. *
  380. * @return boolean
  381. */
  382. public function isFirstPage()
  383. {
  384. return 1 == $this->page;
  385. }
  386. /**
  387. * Returns true if on the last page.
  388. *
  389. * @return boolean
  390. */
  391. public function isLastPage()
  392. {
  393. return $this->page == $this->lastPage;
  394. }
  395. /**
  396. * Returns the current pager's parameter holder.
  397. *
  398. * @return sfParameterHolder
  399. */
  400. public function getParameterHolder()
  401. {
  402. return $this->parameterHolder;
  403. }
  404. /**
  405. * Returns a parameter.
  406. *
  407. * @param string $name
  408. * @param mixed $default
  409. *
  410. * @return mixed
  411. */
  412. public function getParameter($name, $default = null)
  413. {
  414. return $this->parameterHolder->get($name, $default);
  415. }
  416. /**
  417. * Checks whether a parameter has been set.
  418. *
  419. * @param string $name
  420. *
  421. * @return boolean
  422. */
  423. public function hasParameter($name)
  424. {
  425. return $this->parameterHolder->has($name);
  426. }
  427. /**
  428. * Sets a parameter.
  429. *
  430. * @param string $name
  431. * @param mixed $value
  432. */
  433. public function setParameter($name, $value)
  434. {
  435. $this->parameterHolder->set($name, $value);
  436. }
  437. /**
  438. * Returns the current result.
  439. *
  440. * @see Iterator
  441. */
  442. public function current()
  443. {
  444. if (null === $this->results)
  445. {
  446. $this->results = $this->getResults();
  447. $this->resultsCounter = count($this->results);
  448. }
  449. return current($this->results);
  450. }
  451. /**
  452. * Returns the current key.
  453. *
  454. * @see Iterator
  455. */
  456. public function key()
  457. {
  458. if (null === $this->results)
  459. {
  460. $this->results = $this->getResults();
  461. $this->resultsCounter = count($this->results);
  462. }
  463. return key($this->results);
  464. }
  465. /**
  466. * Advances the internal pointer and returns the current result.
  467. *
  468. * @see Iterator
  469. */
  470. public function next()
  471. {
  472. if (null === $this->results)
  473. {
  474. $this->results = $this->getResults();
  475. $this->resultsCounter = count($this->results);
  476. }
  477. --$this->resultsCounter;
  478. return next($this->results);
  479. }
  480. /**
  481. * Resets the internal pointer and returns the current result.
  482. *
  483. * @see Iterator
  484. */
  485. public function rewind()
  486. {
  487. if (null === $this->results)
  488. {
  489. $this->results = $this->getResults();
  490. $this->resultsCounter = count($this->results);
  491. }
  492. return reset($this->results);
  493. }
  494. /**
  495. * Returns true if pointer is within bounds.
  496. *
  497. * @see Iterator
  498. */
  499. public function valid()
  500. {
  501. if (null === $this->results)
  502. {
  503. $this->results = $this->getResults();
  504. $this->resultsCounter = count($this->results);
  505. }
  506. return $this->resultsCounter > 0;
  507. }
  508. /**
  509. * Returns the total number of results.
  510. *
  511. * @see Countable
  512. */
  513. public function count()
  514. {
  515. return $this->getNbResults();
  516. }
  517. }

Debug toolbar