SimplePager.php 4.5 KB

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