Completed
Pull Request — master (#1616)
by
unknown
06:41
created

RawScrollPaginatorAdapter::getTotalHits()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
dl 10
loc 10
rs 9.9332
c 0
b 0
f 0
cc 4
nc 8
nop 1
1
<?php
2
3
/*
4
 * This file is part of the FOSElasticaBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\ElasticaBundle\Paginator;
13
14
use Elastica\Query;
15
use Elastica\ResultSet;
16
use Elastica\Scroll;
17
use Elastica\SearchableInterface;
18
use InvalidArgumentException;
19
20
/**
21
 * Allows pagination of Elastica\Query. Does not map results.
22
 */
23
class RawScrollPaginatorAdapter implements PaginatorAdapterInterface
24
{
25
    /**
26
     * @var SearchableInterface the object to search in
27
     */
28
    private $searchable;
29
30
    /**
31
     * @var Query the query to search
32
     */
33
    private $query;
34
35
    /**
36
     * @var Scroll the scroll instance
37
     */
38
    private $scroll;
39
40
    /**
41
     * @var array search options
42
     */
43
    private $options;
44
45
    /**
46
     * @var int the number of hits
47
     */
48
    private $totalHits;
49
50
    /**
51
     * @var array for the aggregations
52
     */
53
    private $aggregations;
54
55
    /**
56
     * @var array for the suggesters
57
     */
58
    private $suggests;
59
60
    /**
61
     * @var float
62
     */
63
    private $maxScore;
64
65
    /**
66
     * @see PaginatorAdapterInterface::__construct
67
     *
68
     * @param SearchableInterface $searchable the object to search in
69
     * @param Query               $query      the query to search
70
     * @param array               $options
71
     */
72
    public function __construct(SearchableInterface $searchable, Query $query, array $options = [])
73
    {
74
        $this->searchable = $searchable;
75
        $this->query = $query;
76
        $this->options = $options;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function getResults($offset, $itemCountPerPage)
83
    {
84
        return new RawPartialResults($this->getElasticaResults($offset, $itemCountPerPage));
85
    }
86
87
    /**
88
     * Returns the number of results.
89
     *
90
     * If genuineTotal is provided as true, total hits is returned from the
91
     * hits.total value from the search results instead of just returning
92
     * the requested size.
93
     *
94
     * {@inheritdoc}
95
     */
96 View Code Duplication
    public function getTotalHits($genuineTotal = false)
97
    {
98
        if (!isset($this->totalHits)) {
99
            $this->totalHits = $this->searchable->count($this->query);
100
        }
101
102
        return $this->query->hasParam('size') && !$genuineTotal
103
            ? min($this->totalHits, (int) $this->query->getParam('size'))
104
            : $this->totalHits;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 View Code Duplication
    public function getAggregations()
111
    {
112
        if (!isset($this->aggregations)) {
113
            $this->aggregations = $this->searchable->search($this->query)->getAggregations();
114
        }
115
116
        return $this->aggregations;
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 View Code Duplication
    public function getSuggests()
123
    {
124
        if (!isset($this->suggests)) {
125
            $this->suggests = $this->searchable->search($this->query)->getSuggests();
126
        }
127
128
        return $this->suggests;
129
    }
130
131
    /**
132
     * @return float
133
     */
134 View Code Duplication
    public function getMaxScore()
135
    {
136
        if (!isset($this->maxScore)) {
137
            $this->maxScore = $this->searchable->search($this->query)->getMaxScore();
138
        }
139
140
        return $this->maxScore;
141
    }
142
143
    /**
144
     * Returns the Query.
145
     *
146
     * @return Query the search query
147
     */
148
    public function getQuery()
149
    {
150
        return $this->query;
151
    }
152
153
    /**
154
     * Returns the paginated results.
155
     *
156
     * @param int $offset
157
     * @param int $itemCountPerPage
158
     *
159
     * @throws \InvalidArgumentException
160
     *
161
     * @return ResultSet
162
     */
163
    protected function getElasticaResults($offset, $itemCountPerPage)
164
    {
165
        $offset = (int) $offset;
166
        $itemCountPerPage = (int) $itemCountPerPage;
167
        $size = $this->query->hasParam('size')
168
            ? (int) $this->query->getParam('size')
169
            : null;
170
171 View Code Duplication
        if (null !== $size && $size < $offset + $itemCountPerPage) {
172
            $itemCountPerPage = $size - $offset;
173
        }
174
175
        if ($itemCountPerPage < 1) {
176
            throw new InvalidArgumentException('$itemCountPerPage must be greater than zero');
177
        }
178
179
        // Initial search.
180
        if ($this->scroll === null) {
181
            $query = clone $this->query;
182
            $query->setSize($itemCountPerPage);
183
            $expiryTime = isset($this->options['expiryTime']) ? $this->options['expiryTime'] : '1m';
184
            $this->scroll = $this->searchable->createSearch($query)->scroll($expiryTime);
185
            $this->scroll->rewind();
186
        } else {
187
            $this->scroll->next();
188
        }
189
190
        $resultSet = $this->scroll->current();
191
192
        $this->totalHits = $resultSet->getTotalHits();
193
        $this->aggregations = $resultSet->getAggregations();
194
        $this->suggests = $resultSet->getSuggests();
195
        $this->maxScore = $resultSet->getMaxScore();
196
197
        return $resultSet;
198
    }
199
}
200