vendor/friendsofsymfony/elastica-bundle/src/Paginator/RawPaginatorAdapter.php line 177

  1. <?php
  2. /*
  3. * This file is part of the FOSElasticaBundle package.
  4. *
  5. * (c) FriendsOfSymfony <https://friendsofsymfony.github.com/>
  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 FOS\ElasticaBundle\Paginator;
  11. use Elastica\Query;
  12. use Elastica\ResultSet;
  13. use Elastica\SearchableInterface;
  14. /**
  15. * Allows pagination of Elastica\Query. Does not map results.
  16. */
  17. class RawPaginatorAdapter implements PaginatorAdapterInterface
  18. {
  19. /**
  20. * @var SearchableInterface the object to search in
  21. */
  22. private $searchable;
  23. /**
  24. * @var Query the query to search
  25. */
  26. private $query;
  27. /**
  28. * @var array<string, mixed> search options
  29. */
  30. private $options;
  31. /**
  32. * @var ?int the number of hits
  33. */
  34. private $totalHits;
  35. /**
  36. * @var array<string, mixed>|null for the aggregations
  37. */
  38. private $aggregations;
  39. /**
  40. * @var array<string, mixed>|null for the suggesters
  41. */
  42. private $suggests;
  43. /**
  44. * @var ?float
  45. */
  46. private $maxScore;
  47. /**
  48. * @see PaginatorAdapterInterface::__construct
  49. *
  50. * @param SearchableInterface $searchable the object to search in
  51. * @param Query $query the query to search
  52. * @param array<string, mixed> $options
  53. */
  54. public function __construct(SearchableInterface $searchable, Query $query, array $options = [])
  55. {
  56. $this->searchable = $searchable;
  57. $this->query = $query;
  58. $this->options = $options;
  59. }
  60. public function getResults($offset, $itemCountPerPage)
  61. {
  62. return new RawPartialResults($this->getElasticaResults($offset, $itemCountPerPage));
  63. }
  64. /**
  65. * Returns the number of results.
  66. *
  67. * If genuineTotal is provided as true, total hits is returned from the
  68. * `hits.total` value from the search results instead of just returning
  69. * the requested size.
  70. *
  71. * {@inheritdoc}
  72. *
  73. * @param bool $genuineTotal
  74. */
  75. public function getTotalHits($genuineTotal = false)
  76. {
  77. if (!isset($this->totalHits)) {
  78. $this->totalHits = $this->searchable->count($this->query);
  79. }
  80. return $this->query->hasParam('size') && !$genuineTotal
  81. ? \min($this->totalHits, (int) $this->query->getParam('size'))
  82. : $this->totalHits;
  83. }
  84. public function getAggregations()
  85. {
  86. if (!isset($this->aggregations)) {
  87. $this->aggregations = $this->searchable->search($this->query)->getAggregations();
  88. }
  89. return $this->aggregations;
  90. }
  91. public function getSuggests()
  92. {
  93. if (!isset($this->suggests)) {
  94. $this->suggests = $this->searchable->search($this->query)->getSuggests();
  95. }
  96. return $this->suggests;
  97. }
  98. /**
  99. * @return float
  100. */
  101. public function getMaxScore()
  102. {
  103. if (!isset($this->maxScore)) {
  104. $this->maxScore = $this->searchable->search($this->query)->getMaxScore();
  105. }
  106. return $this->maxScore;
  107. }
  108. /**
  109. * Returns the Query.
  110. *
  111. * @return Query the search query
  112. */
  113. public function getQuery()
  114. {
  115. return $this->query;
  116. }
  117. /**
  118. * Returns the paginated results.
  119. *
  120. * @param int $offset
  121. * @param int $itemCountPerPage
  122. *
  123. * @throws \InvalidArgumentException
  124. *
  125. * @return ResultSet
  126. */
  127. protected function getElasticaResults($offset, $itemCountPerPage)
  128. {
  129. $offset = (int) $offset;
  130. $itemCountPerPage = (int) $itemCountPerPage;
  131. $size = $this->query->hasParam('size')
  132. ? (int) $this->query->getParam('size')
  133. : null;
  134. if (null !== $size && $size < $offset + $itemCountPerPage) {
  135. $itemCountPerPage = $size - $offset;
  136. }
  137. if ($itemCountPerPage < 1) {
  138. throw new \InvalidArgumentException('$itemCountPerPage must be greater than zero');
  139. }
  140. $query = clone $this->query;
  141. $query->setFrom($offset);
  142. $query->setSize($itemCountPerPage);
  143. $resultSet = $this->searchable->search($query, $this->options);
  144. $this->totalHits = $resultSet->getTotalHits();
  145. $this->aggregations = $resultSet->getAggregations();
  146. $this->suggests = $resultSet->getSuggests();
  147. $this->maxScore = $resultSet->getMaxScore();
  148. return $resultSet;
  149. }
  150. }