PropelModelPager.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. * Implements a pager based on a ModelCriteria
  11. * The code from this class heavily borrows from symfony's sfPager class
  12. *
  13. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  14. * @author François Zaninotto
  15. * @version $Revision: 1665 $
  16. * @package propel.runtime.query
  17. */
  18. class PropelModelPager implements IteratorAggregate, Countable
  19. {
  20. protected
  21. $query = null,
  22. $page = 1,
  23. $maxPerPage = 10,
  24. $lastPage = 1,
  25. $nbResults = 0,
  26. $objects = null,
  27. $parameters = array(),
  28. $currentMaxLink = 1,
  29. $parameterHolder = null,
  30. $maxRecordLimit = false,
  31. $results = null,
  32. $resultsCounter = 0;
  33. public function __construct(Criteria $query, $maxPerPage = 10)
  34. {
  35. $this->setQuery($query);
  36. $this->setMaxPerPage($maxPerPage);
  37. }
  38. public function setQuery(Criteria $query)
  39. {
  40. $this->query = $query;
  41. }
  42. public function getQuery()
  43. {
  44. return $this->query;
  45. }
  46. public function init()
  47. {
  48. $hasMaxRecordLimit = ($this->getMaxRecordLimit() !== false);
  49. $maxRecordLimit = $this->getMaxRecordLimit();
  50. $qForCount = clone $this->getQuery();
  51. $count = $qForCount
  52. ->offset(0)
  53. ->limit(0)
  54. ->count();
  55. $this->setNbResults($hasMaxRecordLimit ? min($count, $maxRecordLimit) : $count);
  56. $q = $this->getQuery()
  57. ->offset(0)
  58. ->limit(0);
  59. if (($this->getPage() == 0 || $this->getMaxPerPage() == 0)) {
  60. $this->setLastPage(0);
  61. } else {
  62. $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));
  63. $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
  64. $q->offset($offset);
  65. if ($hasMaxRecordLimit) {
  66. $maxRecordLimit = $maxRecordLimit - $offset;
  67. if ($maxRecordLimit > $this->getMaxPerPage()) {
  68. $q->limit($this->getMaxPerPage());
  69. } else {
  70. $q->limit($maxRecordLimit);
  71. }
  72. } else {
  73. $q->limit($this->getMaxPerPage());
  74. }
  75. }
  76. }
  77. /**
  78. * Get the collection of results in the page
  79. *
  80. * @return PropelObjectCollection A collection of results
  81. */
  82. public function getResults()
  83. {
  84. if (null === $this->results) {
  85. $this->results = $this->getQuery()
  86. ->setFormatter(ModelCriteria::FORMAT_OBJECT)
  87. ->find();
  88. }
  89. return $this->results;
  90. }
  91. public function getCurrentMaxLink()
  92. {
  93. return $this->currentMaxLink;
  94. }
  95. public function getMaxRecordLimit()
  96. {
  97. return $this->maxRecordLimit;
  98. }
  99. public function setMaxRecordLimit($limit)
  100. {
  101. $this->maxRecordLimit = $limit;
  102. }
  103. public function getLinks($nb_links = 5)
  104. {
  105. $links = array();
  106. $tmp = $this->page - floor($nb_links / 2);
  107. $check = $this->lastPage - $nb_links + 1;
  108. $limit = ($check > 0) ? $check : 1;
  109. $begin = ($tmp > 0) ? (($tmp > $limit) ? $limit : $tmp) : 1;
  110. $i = (int) $begin;
  111. while (($i < $begin + $nb_links) && ($i <= $this->lastPage)) {
  112. $links[] = $i++;
  113. }
  114. $this->currentMaxLink = count($links) ? $links[count($links) - 1] : 1;
  115. return $links;
  116. }
  117. /**
  118. * Test whether the number of results exceeds the max number of results per page
  119. *
  120. * @return boolean true if the pager displays only a subset of the results
  121. */
  122. public function haveToPaginate()
  123. {
  124. return (($this->getMaxPerPage() != 0) && ($this->getNbResults() > $this->getMaxPerPage()));
  125. }
  126. /**
  127. * Get the index of the first element in the page
  128. * Returns 1 on the first page, $maxPerPage +1 on the second page, etc
  129. *
  130. * @return int
  131. */
  132. public function getFirstIndex()
  133. {
  134. if ($this->page == 0) {
  135. return 1;
  136. } else {
  137. return ($this->page - 1) * $this->maxPerPage + 1;
  138. }
  139. }
  140. /**
  141. * Get the index of the last element in the page
  142. * Always less than or eaqual to $maxPerPage
  143. *
  144. * @return int
  145. */
  146. public function getLastIndex()
  147. {
  148. if ($this->page == 0) {
  149. return $this->nbResults;
  150. } else {
  151. if (($this->page * $this->maxPerPage) >= $this->nbResults) {
  152. return $this->nbResults;
  153. } else {
  154. return ($this->page * $this->maxPerPage);
  155. }
  156. }
  157. }
  158. /**
  159. * Get the total number of results of the query
  160. * This can be greater than $maxPerPage
  161. *
  162. * @return int
  163. */
  164. public function getNbResults()
  165. {
  166. return $this->nbResults;
  167. }
  168. /**
  169. * Set the total number of results of the query
  170. *
  171. * @param int $nb
  172. */
  173. protected function setNbResults($nb)
  174. {
  175. $this->nbResults = $nb;
  176. }
  177. /**
  178. * Check whether the current page is the first page
  179. *
  180. * @return boolean true if the current page is the first page
  181. */
  182. public function isFirstPage()
  183. {
  184. return $this->getPage() == $this->getFirstPage();
  185. }
  186. /**
  187. * Get the number of the first page
  188. *
  189. * @return int Always 1
  190. */
  191. public function getFirstPage()
  192. {
  193. return 1;
  194. }
  195. /**
  196. * Check whether the current page is the last page
  197. *
  198. * @return boolean true if the current page is the last page
  199. */
  200. public function isLastPage()
  201. {
  202. return $this->getPage() == $this->getLastPage();
  203. }
  204. /**
  205. * Get the number of the last page
  206. *
  207. * @return int
  208. */
  209. public function getLastPage()
  210. {
  211. return $this->lastPage;
  212. }
  213. /**
  214. * Set the number of the first page
  215. *
  216. * @param int $page
  217. */
  218. protected function setLastPage($page)
  219. {
  220. $this->lastPage = $page;
  221. if ($this->getPage() > $page) {
  222. $this->setPage($page);
  223. }
  224. }
  225. /**
  226. * Get the number of the current page
  227. *
  228. * @return int
  229. */
  230. public function getPage()
  231. {
  232. return $this->page;
  233. }
  234. /**
  235. * Set the number of the current page
  236. *
  237. * @param int $page
  238. */
  239. public function setPage($page)
  240. {
  241. $this->page = intval($page);
  242. if ($this->page <= 0) {
  243. // set first page, which depends on a maximum set
  244. $this->page = $this->getMaxPerPage() ? 1 : 0;
  245. }
  246. }
  247. /**
  248. * Get the number of the next page
  249. *
  250. * @return int
  251. */
  252. public function getNextPage()
  253. {
  254. return min($this->getPage() + 1, $this->getLastPage());
  255. }
  256. /**
  257. * Get the number of the previous page
  258. *
  259. * @return int
  260. */
  261. public function getPreviousPage()
  262. {
  263. return max($this->getPage() - 1, $this->getFirstPage());
  264. }
  265. /**
  266. * Get the maximum number results per page
  267. *
  268. * @return int
  269. */
  270. public function getMaxPerPage()
  271. {
  272. return $this->maxPerPage;
  273. }
  274. /**
  275. * Set the maximum number results per page
  276. *
  277. * @param int $max
  278. */
  279. public function setMaxPerPage($max)
  280. {
  281. if ($max > 0) {
  282. $this->maxPerPage = $max;
  283. if ($this->page == 0) {
  284. $this->page = 1;
  285. }
  286. } else if ($max == 0) {
  287. $this->maxPerPage = 0;
  288. $this->page = 0;
  289. } else {
  290. $this->maxPerPage = 1;
  291. if ($this->page == 0) {
  292. $this->page = 1;
  293. }
  294. }
  295. }
  296. public function getIterator()
  297. {
  298. return $this->getResults()->getIterator();
  299. }
  300. /**
  301. * Returns the total number of results.
  302. *
  303. * @see Countable
  304. * @return int
  305. */
  306. public function count()
  307. {
  308. return $this->getNbResults();
  309. }
  310. }