SimplePager.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. /*
  3. * This file is part of the Sonata package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Datagrid;
  11. use Doctrine\ORM\QueryBuilder;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. /**
  14. * Simple pager
  15. *
  16. * @author Lukas Kahwe Smith <smith@pooteeweet.org>
  17. * @author Sjoerd Peters <sjoerd.peters@gmail.com>
  18. */
  19. class SimplePager extends Pager
  20. {
  21. /**
  22. * @var boolean
  23. */
  24. protected $haveToPaginate;
  25. /**
  26. * How many pages to look forward to create links to next pages.
  27. *
  28. * @var int
  29. */
  30. protected $threshold;
  31. /**
  32. * @var int
  33. */
  34. protected $thresholdCount;
  35. /**
  36. * The threshold parameter can be used to determine how far ahead the pager
  37. * should fetch results.
  38. *
  39. * If set to 1 which is the minimal value the pager will generate a link to the next page
  40. * If set to 2 the pager will generate links to the next two pages
  41. * If set to 3 the pager will generate links to the next three pages
  42. * etc.
  43. *
  44. * @param integer $maxPerPage Number of records to display per page
  45. * @param int $threshold
  46. */
  47. public function __construct($maxPerPage = 10, $threshold = 1)
  48. {
  49. parent::__construct($maxPerPage);
  50. $this->setThreshold($threshold);
  51. }
  52. /**
  53. * Returns the exact count when there is only one page or when the current
  54. * equals the last page.
  55. *
  56. * In all other cases an estimate of the total count is returned.
  57. *
  58. * @return integer
  59. */
  60. public function getNbResults()
  61. {
  62. $n = ceil(($this->getLastPage() -1) * $this->getMaxPerPage());
  63. if ($this->getLastPage() == $this->getPage()) {
  64. return $n + $this->thresholdCount;
  65. }
  66. return $n;
  67. }
  68. /**
  69. * Get all the results for the pager instance
  70. *
  71. * @param mixed $hydrationMode A hydration mode identifier
  72. *
  73. * @return array
  74. */
  75. public function getResults($hydrationMode = null)
  76. {
  77. if ($this->results) {
  78. return $this->results;
  79. }
  80. $this->results = $this->getQuery()->execute(array(), $hydrationMode);
  81. $this->thresholdCount = count($this->results);
  82. if (count($this->results) > $this->getMaxPerPage()) {
  83. $this->haveToPaginate = true;
  84. if ($this->results instanceof ArrayCollection) {
  85. $this->results = new ArrayCollection($this->results->slice(0, $this->getMaxPerPage()));
  86. } else {
  87. $this->results = new ArrayCollection(array_slice($this->results, 0, $this->getMaxPerPage()));
  88. }
  89. } else {
  90. $this->haveToPaginate = false;
  91. }
  92. return $this->results;
  93. }
  94. /**
  95. * {@inheritDoc}
  96. */
  97. public function haveToPaginate()
  98. {
  99. return $this->haveToPaginate || $this->getPage() > 1;
  100. }
  101. /**
  102. * {@inheritDoc}
  103. */
  104. protected function resetIterator()
  105. {
  106. parent::resetIterator();
  107. $this->haveToPaginate = false;
  108. }
  109. /**
  110. * {@inheritDoc}
  111. *
  112. * @throws \RuntimeException the QueryBuilder is uninitialized.
  113. */
  114. public function init()
  115. {
  116. if (!$this->getQuery()) {
  117. throw new \RuntimeException('Uninitialized QueryBuilder');
  118. }
  119. $this->resetIterator();
  120. if (0 == $this->getPage() || 0 == $this->getMaxPerPage()) {
  121. $this->setLastPage(0);
  122. $this->getQuery()->setFirstResult(0);
  123. $this->getQuery()->setMaxResults(0);
  124. } else {
  125. $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
  126. $this->getQuery()->setFirstResult($offset);
  127. $maxOffset = $this->getThreshold() > 0
  128. ? $this->getMaxPerPage() * $this->threshold + 1 : $this->getMaxPerPage() + 1;
  129. $this->getQuery()->setMaxResults($maxOffset);
  130. $this->initializeIterator();
  131. $t = (int) ceil($this->thresholdCount / $this->getMaxPerPage()) + $this->getPage() - 1;
  132. $this->setLastPage($t);
  133. }
  134. }
  135. /**
  136. * Set how many pages to look forward to create links to next pages.
  137. *
  138. * @param int $threshold
  139. */
  140. public function setThreshold($threshold)
  141. {
  142. $this->threshold = (int) $threshold;
  143. }
  144. /**
  145. * @return int
  146. */
  147. public function getThreshold()
  148. {
  149. return $this->threshold;
  150. }
  151. }