Completed
Push — 1.0 ( f45751...770e00 )
by Simonas
12:41 queued 10:12
created

AbstractResultsIterator   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 320
Duplicated Lines 7.5 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 5
Bugs 1 Features 2
Metric Value
wmc 37
c 5
b 1
f 2
lcom 1
cbo 1
dl 24
loc 320
rs 8.6

21 Methods

Rating   Name   Duplication   Size   Complexity  
A getManager() 0 4 1
A __destruct() 0 7 2
A valid() 0 15 3
B __construct() 0 25 6
A getDocumentScore() 12 12 3
A getDocumentSort() 12 12 3
A getAggregations() 0 4 1
A count() 0 4 1
A current() 0 4 1
A next() 0 4 1
A key() 0 4 1
A rewind() 0 4 1
A isScrollable() 0 4 1
A getManagerConfig() 0 4 1
A getConverter() 0 4 1
A getDocument() 0 8 2
A documentExists() 0 4 1
A advanceKey() 0 10 3
A first() 0 6 1
A page() 0 13 3
convertDocument() 0 1 ?

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
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 ONGR\ElasticsearchBundle\Result;
13
14
use ONGR\ElasticsearchBundle\Service\Manager;
15
16
/**
17
 * Class AbstractResultsIterator.
18
 */
19
abstract class AbstractResultsIterator implements \Countable, \Iterator
20
{
21
    /**
22
     * @var array Documents.
23
     */
24
    protected $documents = [];
25
26
    /**
27
     * @var int
28
     */
29
    private $count = 0;
30
31
    /**
32
     * @var array
33
     */
34
    private $aggregations = [];
35
36
    /**
37
     * @var Converter
38
     */
39
    private $converter;
40
41
    /**
42
     * @var Manager
43
     */
44
    private $manager;
45
46
    /**
47
     * Elasticsearch manager configuration.
48
     *
49
     * @var array
50
     */
51
    private $managerConfig = [];
52
53
    /**
54
     * @var string If value is not null then results are scrollable.
55
     */
56
    private $scrollId;
57
58
    /**
59
     * @var string Scroll duration.
60
     */
61
    private $scrollDuration;
62
63
    /**
64
     * Used to count iteration.
65
     *
66
     * @var int
67
     */
68
    private $key = 0;
69
70
    /**
71
     * @param array   $rawData
72
     * @param Manager $manager
73
     * @param array   $scroll
74
     */
75
    public function __construct(
76
        array $rawData,
77
        Manager $manager,
78
        array $scroll = []
79
    ) {
80
        $this->manager = $manager;
81
        $this->converter = $manager->getConverter();
82
        $this->managerConfig = $manager->getConfig();
83
84
        if (isset($scroll['_scroll_id']) && isset($scroll['duration'])) {
85
            $this->scrollId = $scroll['_scroll_id'];
86
            $this->scrollDuration = $scroll['duration'];
87
        }
88
89
        if (isset($rawData['aggregations'])) {
90
            $this->aggregations = &$rawData['aggregations'];
91
        }
92
93
        if (isset($rawData['hits']['hits'])) {
94
            $this->documents = $rawData['hits']['hits'];
95
        }
96
        if (isset($rawData['hits']['total'])) {
97
            $this->count = $rawData['hits']['total'];
98
        }
99
    }
100
101
    /**
102
     * Destructor.
103
     */
104
    public function __destruct()
105
    {
106
        // Clear scroll if initialized
107
        if ($this->isScrollable()) {
108
            $this->manager->clearScroll($this->scrollId);
109
        }
110
    }
111
112
    /**
113
     * @return array
114
     */
115
    protected function getAggregations()
116
    {
117
        return $this->aggregations;
118
    }
119
120
    /**
121
     * @return Manager
122
     */
123
    protected function getManager()
124
    {
125
        return $this->manager;
126
    }
127
128
    /**
129
     * Returns total count of documents.
130
     *
131
     * @return int
132
     */
133
    public function count()
134
    {
135
        return $this->count;
136
    }
137
138
    /**
139
     * Return the current element.
140
     *
141
     * @return mixed
142
     */
143
    public function current()
144
    {
145
        return $this->getDocument($this->key());
146
    }
147
148
    /**
149
     * Move forward to next element.
150
     */
151
    public function next()
152
    {
153
        $this->advanceKey();
154
    }
155
156
    /**
157
     * Return the key of the current element.
158
     *
159
     * @return mixed
160
     */
161
    public function key()
162
    {
163
        return $this->key;
164
    }
165
166
    /**
167
     * Checks if current position is valid.
168
     *
169
     * @return bool
170
     */
171
    public function valid()
172
    {
173
        if (!isset($this->documents)) {
174
            return false;
175
        }
176
177
        $valid = $this->documentExists($this->key());
178
        if ($valid) {
179
            return true;
180
        }
181
182
        $this->page();
183
184
        return $this->documentExists($this->key());
185
    }
186
187
    /**
188
     * Rewind the Iterator to the first element.
189
     */
190
    public function rewind()
191
    {
192
        $this->key = 0;
193
    }
194
195
    /**
196
     * @return bool
197
     */
198
    public function isScrollable()
199
    {
200
        return !empty($this->scrollId);
201
    }
202
203
    /**
204
     * @return array
205
     */
206
    protected function getManagerConfig()
207
    {
208
        return $this->managerConfig;
209
    }
210
211
    /**
212
     * @return Converter
213
     */
214
    protected function getConverter()
215
    {
216
        return $this->converter;
217
    }
218
219
    /**
220
     * Gets document array from the container.
221
     *
222
     * @param mixed $key
223
     *
224
     * @return mixed
225
     */
226
    protected function getDocument($key)
227
    {
228
        if (!$this->documentExists($key)) {
229
            return null;
230
        }
231
232
        return $this->convertDocument($this->documents[$key]);
233
    }
234
235
    /**
236
     * Checks whether document exists in the container.
237
     *
238
     * @param mixed $key
239
     *
240
     * @return bool
241
     */
242
    protected function documentExists($key)
243
    {
244
        return array_key_exists($key, $this->documents);
245
    }
246
247
    /**
248
     * Advances key.
249
     *
250
     * @return $this
251
     */
252
    protected function advanceKey()
253
    {
254
        if ($this->isScrollable() && ($this->documents[$this->key()] == end($this->documents))) {
255
            $this->page();
256
        } else {
257
            $this->key++;
258
        }
259
260
        return $this;
261
    }
262
263
    /**
264
     * Rewind's the iteration and returns first result.
265
     *
266
     * @return mixed|null
267
     */
268
    public function first()
269
    {
270
        $this->rewind();
271
272
        return $this->getDocument($this->key());
273
    }
274
275
    /**
276
     * Advances scan page.
277
     *
278
     * @return $this
279
     */
280
    protected function page()
281
    {
282
        if ($this->key() == $this->count() || !$this->isScrollable()) {
283
            return $this;
284
        }
285
286
        $raw = $this->manager->scroll($this->scrollId, $this->scrollDuration, Result::RESULTS_RAW);
287
        $this->rewind();
288
        $this->scrollId = $raw['_scroll_id'];
289
        $this->documents = $raw['hits']['hits'];
290
291
        return $this;
292
    }
293
294
    /**
295
     * Returns score of current hit.
296
     *
297
     * @return int
298
     */
299 View Code Duplication
    public function getDocumentScore()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
300
    {
301
        if (!$this->valid()) {
302
            throw new \LogicException('Document score is available only while iterating over results.');
303
        }
304
305
        if (!isset($this->documents[$this->key]['_score'])) {
306
            return null;
307
        }
308
309
        return $this->documents[$this->key]['_score'];
310
    }
311
312
    /**
313
    * Returns sort of current hit.
314
    *
315
    * @return mixed
316
    */
317 View Code Duplication
    public function getDocumentSort()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
    {
319
        if (!$this->valid()) {
320
            throw new \LogicException('Document sort is available only while iterating over results.');
321
        }
322
323
        if (!isset($this->documents[$this->key]['sort'])) {
324
            return null;
325
        }
326
327
        return $this->documents[$this->key]['sort'][0];
328
    }
329
330
    /**
331
     * Converts raw array to document object or array, depends on iterator type.
332
     *
333
     * @param array $document
334
     *
335
     * @return object|array
336
     */
337
    abstract protected function convertDocument(array $document);
338
}
339