AbstractPaginator::keys()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 6
1
<?php
2
3
namespace Bdf\Prime\Query\Pagination;
4
5
use Bdf\Prime\Collection\CollectionInterface;
6
use Bdf\Prime\Connection\ConnectionInterface;
7
use Bdf\Prime\Exception\PrimeException;
8
use Bdf\Prime\PrimeSerializable;
9
use Bdf\Prime\Query\Contract\Limitable;
10
use Bdf\Prime\Query\Contract\Orderable;
11
use Bdf\Prime\Query\Contract\Paginable;
12
use Bdf\Prime\Query\QueryInterface;
13
use Bdf\Prime\Query\ReadCommandInterface;
14
use IteratorAggregate;
15
16
/**
17
 * Abstract paginator
18
 *
19
 * Provide method for pagination
20
 *
21
 * @author  Seb
22
 * @package Bdf\Prime\Query\Pagination
23
 *
24
 *
25
 * @todo retourner une nouvelle instance du paginator sur les methodes de collection ?
26
 *
27
 * @template R as array|object
28
 * @implements PaginatorInterface<R>
29
 */
30
abstract class AbstractPaginator extends PrimeSerializable implements PaginatorInterface, IteratorAggregate
31
{
32
    public const DEFAULT_PAGE  = 1;
33
    public const DEFAULT_LIMIT = 20;
34
35
    /**
36
     * Current query
37
     *
38
     * @var ReadCommandInterface<ConnectionInterface, R>&Limitable&Orderable&Paginable
39
     */
40
    protected $query;
41
42
    /**
43
     * Current collection
44
     *
45
     * @var R[]|CollectionInterface<R>
46
     */
47
    protected $collection = [];
48
49
    /**
50
     * Total size of the collection
51
     *
52
     * @var int
53
     */
54
    protected $size;
55
56
    /**
57
     * Current page
58
     *
59
     * @var int
60
     */
61
    protected $page;
62
63
    /**
64
     * Number of entities loaded in the collection
65
     *
66
     * @var int
67
     */
68
    protected $maxRows;
69
70
71
    /**
72
     * {@inheritdoc}
73
     *
74
     * @final
75
     */
76 7
    public function collection()
77
    {
78 7
        return $this->collection;
79
    }
80
81
    /**
82
     * Get the query
83
     *
84
     * @return ReadCommandInterface<ConnectionInterface, R>&Limitable&Orderable&Paginable
85
     * @final
86
     */
87 2
    public function query()
88
    {
89 2
        return $this->query;
90
    }
91
92
    /**
93
     * Load entities
94
     *
95
     * @throws PrimeException
96
     */
97 25
    protected function loadCollection(): void
98
    {
99
        /** @var ReadCommandInterface<ConnectionInterface, R>&Limitable&Orderable&Paginable $this->query */
100 25
        if ($this->maxRows > -1) {
101 25
            $this->query->limitPage($this->page, $this->maxRows);
0 ignored issues
show
Bug introduced by
The method limitPage() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
            $this->query->/** @scrutinizer ignore-call */ 
102
                          limitPage($this->page, $this->maxRows);
Loading history...
102
        }
103
104 25
        $this->collection = $this->query->all();
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 2
    public function order($attribute = null)
111
    {
112 2
        $orders = $this->query->getOrders();
0 ignored issues
show
Bug introduced by
The method getOrders() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

112
        /** @scrutinizer ignore-call */ 
113
        $orders = $this->query->getOrders();
Loading history...
113
114 2
        if ($attribute === null) {
115 2
            return $orders;
116
        }
117
118 2
        return isset($orders[$attribute]) ? $orders[$attribute] : null;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 1
    public function limit(): ?int
125
    {
126 1
        return $this->query->getLimit();
0 ignored issues
show
Bug introduced by
The method getLimit() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

126
        return $this->query->/** @scrutinizer ignore-call */ getLimit();
Loading history...
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 1
    public function offset(): ?int
133
    {
134 1
        return $this->query->getOffset();
0 ignored issues
show
Bug introduced by
The method getOffset() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

134
        return $this->query->/** @scrutinizer ignore-call */ getOffset();
Loading history...
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 4
    public function page()
141
    {
142 4
        return $this->query->getPage();
0 ignored issues
show
Bug introduced by
The method getPage() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

142
        return $this->query->/** @scrutinizer ignore-call */ getPage();
Loading history...
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 4
    public function pageMaxRows()
149
    {
150 4
        return (int) $this->query->getLimit();
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156 8
    public function size()
157
    {
158 8
        if ($this->size === null) {
159 8
            $this->buildSize();
160
        }
161
162 8
        return $this->size;
163
    }
164
165
    /**
166
     * Find size of the collection
167
     */
168 8
    protected function buildSize(): void
169
    {
170 8
        $currentSize = $this->count();
171
172 8
        if (!$this->query->isLimitQuery()) {
0 ignored issues
show
Bug introduced by
The method isLimitQuery() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

172
        if (!$this->query->/** @scrutinizer ignore-call */ isLimitQuery()) {
Loading history...
173 3
            $this->size = $currentSize;
174 5
        } elseif ($currentSize + $this->query->getOffset() < $this->query->getLimit()) {
175 1
            $this->size = $currentSize + $this->query->getOffset();
176
        } else {
177 4
            $this->size = $this->query->paginationCount();
0 ignored issues
show
Bug introduced by
The method paginationCount() does not exist on Bdf\Prime\Query\ReadCommandInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

177
            /** @scrutinizer ignore-call */ 
178
            $this->size = $this->query->paginationCount();
Loading history...
178
        }
179
    }
180
181
    /**
182
     * SPL - Countable
183
     *
184
     * {@inheritdoc}
185
     */
186 9
    public function count(): int
187
    {
188 9
        return count($this->collection);
189
    }
190
191
    //--------- collection interface
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function pushAll(array $items)
197
    {
198
        if (!($this->collection instanceof CollectionInterface)) {
199
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
200
        }
201
202
        $this->collection->pushAll($items);
203
204
        return $this;
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210
    public function push($item)
211
    {
212
        if (!($this->collection instanceof CollectionInterface)) {
213
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
214
        }
215
216
        $this->collection->push($item);
217
218
        return $this;
219
    }
220
221
    /**
222
     * {@inheritdoc}
223
     */
224
    public function put($key, $item)
225
    {
226
        if (!($this->collection instanceof CollectionInterface)) {
227
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
228
        }
229
230
        $this->collection->put($key, $item);
231
232
        return $this;
233
    }
234
235
    /**
236
     * SPL - ArrayAccess
237
     *
238
     * {@inheritdoc}
239
     */
240
    public function offsetSet($key, $value): void
241
    {
242
        $this->collection[$key] = $value;
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248
    public function all(): array
249
    {
250
        if (!($this->collection instanceof CollectionInterface)) {
251
            return $this->collection;
252
        }
253
254
        return $this->collection->all();
255
    }
256
257
    /**
258
     * {@inheritdoc}
259
     */
260 7
    public function get($key, $default = null)
261
    {
262 7
        if (!($this->collection instanceof CollectionInterface)) {
263
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
264
        }
265
266 7
        return $this->collection->get($key, $default);
267
    }
268
269
    /**
270
     * {@inheritdoc}
271
     */
272
    #[\ReturnTypeWillChange]
273
    public function offsetGet($key)
274
    {
275
        return $this->collection[$key];
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     */
281
    public function has($key): bool
282
    {
283
        if (!($this->collection instanceof CollectionInterface)) {
284
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
285
        }
286
287
        return $this->collection->has($key);
288
    }
289
290
    /**
291
     * SPL - ArrayAccess
292
     *
293
     * {@inheritdoc}
294
     */
295
    public function offsetExists($key): bool
296
    {
297
        return isset($this->collection[$key]);
298
    }
299
300
    /**
301
     * {@inheritdoc}
302
     */
303
    public function remove($key)
304
    {
305
        if (!($this->collection instanceof CollectionInterface)) {
306
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
307
        }
308
309
        $this->collection->remove($key);
310
311
        return $this;
312
    }
313
314
    /**
315
     * SPL - ArrayAccess
316
     *
317
     * {@inheritdoc}
318
     */
319
    public function offsetUnset($key): void
320
    {
321
        unset($this->collection[$key]);
322
    }
323
324
    /**
325
     * {@inheritdoc}
326
     */
327 1
    public function clear()
328
    {
329 1
        if (!($this->collection instanceof CollectionInterface)) {
330
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
331
        }
332
333 1
        $this->collection->clear();
334
335 1
        return $this;
336
    }
337
338
    /**
339
     * {@inheritdoc}
340
     */
341
    public function keys(): array
342
    {
343
        if (!($this->collection instanceof CollectionInterface)) {
344
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
345
        }
346
347
        return $this->collection->keys();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->collection->keys() returns the type Bdf\Prime\Collection\list which is incompatible with the type-hinted return array.
Loading history...
348
    }
349
350
    /**
351
     * {@inheritdoc}
352
     */
353 2
    public function isEmpty(): bool
354
    {
355 2
        if (!($this->collection instanceof CollectionInterface)) {
356
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
357
        }
358
359 2
        return $this->collection->isEmpty();
360
    }
361
362
    /**
363
     * {@inheritdoc}
364
     *
365
     * @param callable(R):M $callback The function to run
366
     * @return static<M> The new collection
367
     *
368
     * @template M as array|object
369
     */
370 1
    public function map($callback)
371
    {
372 1
        if (!($this->collection instanceof CollectionInterface)) {
373
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
374
        }
375
376
        /** @var static<M> $this */
377 1
        $this->collection = $this->collection->map($callback);
378
379 1
        return $this;
380
    }
381
382
    /**
383
     * {@inheritdoc}
384
     */
385 1
    public function filter($callback = null)
386
    {
387 1
        if (!($this->collection instanceof CollectionInterface)) {
388
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
389
        }
390
391 1
        $this->collection = $this->collection->filter($callback);
392
393 1
        return $this;
394
    }
395
396
    /**
397
     * {@inheritdoc}
398
     */
399 1
    public function groupBy($groupBy, $mode = PaginatorInterface::GROUPBY)
400
    {
401 1
        if (!($this->collection instanceof CollectionInterface)) {
402
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
403
        }
404
405 1
        $this->collection = $this->collection->groupBy($groupBy, $mode);
406
407 1
        return $this;
408
    }
409
410
    /**
411
     * {@inheritdoc}
412
     *
413
     * @return bool
414
     */
415
    public function contains($element): bool
416
    {
417
        if (!($this->collection instanceof CollectionInterface)) {
418
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
419
        }
420
421
        return $this->collection->contains($element);
422
    }
423
424
    /**
425
     * {@inheritdoc}
426
     */
427
    public function indexOf($value, $strict = false)
428
    {
429
        if (!($this->collection instanceof CollectionInterface)) {
430
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
431
        }
432
433
        return $this->collection->indexOf($value, $strict);
434
    }
435
436
    /**
437
     * {@inheritdoc}
438
     */
439
    public function merge($items)
440
    {
441
        if (!($this->collection instanceof CollectionInterface)) {
442
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
443
        }
444
445
        $this->collection = $this->collection->merge($items);
446
447
        return $this;
448
    }
449
450
    /**
451
     * {@inheritdoc}
452
     */
453
    public function sort(callable $callback = null)
454
    {
455
        if (!($this->collection instanceof CollectionInterface)) {
456
            throw new \LogicException('Collection is not an instance of CollectionInterface. Could not call method ' . __METHOD__);
457
        }
458
459
        $this->collection = $this->collection->sort($callback);
460
461
        return $this;
462
    }
463
}
464