Passed
Push — master ( 5197c9...313b01 )
by Sébastien
04:05 queued 15s
created

KeyWalkStrategy::supports()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 8

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 8.4444
c 1
b 0
f 0
cc 8
nc 5
nop 3
crap 8
1
<?php
2
3
namespace Bdf\Prime\Query\Pagination\WalkStrategy;
4
5
use Bdf\Prime\Collection\CollectionInterface;
6
use Bdf\Prime\Query\Contract\Limitable;
7
use Bdf\Prime\Query\Contract\Orderable;
8
use Bdf\Prime\Query\Contract\ReadOperation;
9
use Bdf\Prime\Query\Contract\Whereable;
10
use Bdf\Prime\Query\ReadCommandInterface;
11
use InvalidArgumentException;
12
13
/**
14
 * Walk strategy using a primary key (or any unique key) as cursor
15
 * This strategy supports deleting entities during the walk, but the entity must contains a single primary key, and the query must be ordered by this key
16
 * Any sort on other attribute are not supported
0 ignored issues
show
introduced by
Doc comment short description must be on a single line, further text should be a separate paragraph
Loading history...
17
 */
18
final class KeyWalkStrategy implements WalkStrategyInterface
19
{
20
    /**
21
     * @var KeyInterface
22
     */
23
    private $key;
24
25
    /**
26
     * PrimaryKeyWalkStrategy constructor.
27
     * @param KeyInterface $key
0 ignored issues
show
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
28
     */
29 16
    public function __construct(KeyInterface $key)
30
    {
31 16
        $this->key = $key;
32 16
    }
33
34
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $startPage should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $chunkSize should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
35
     * {@inheritdoc}
36
     */
0 ignored issues
show
Coding Style Documentation introduced by
Missing @throws tag in function comment
Loading history...
37 13
    public function initialize(ReadCommandInterface $query, int $chunkSize, int $startPage): WalkCursor
38
    {
39 13
        if (!self::supports($query, $startPage, $this->key->name())) {
40 3
            throw new InvalidArgumentException('KeyWalkStrategy is not supported by this query');
41
        }
42
43
        /** @var Limitable&Orderable&ReadCommandInterface $query */
0 ignored issues
show
Coding Style introduced by
Inline doc block comments are not allowed; use "/* Comment */" or "// Comment" instead
Loading history...
Coding Style introduced by
Block comments must be started with /*
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
44 10
        $query = clone $query;
45
46 10
        if (!isset($query->getOrders()[$this->key->name()])) {
47 10
            $query->order($this->key->name(), Orderable::ORDER_ASC);
48
        }
49
50 10
        $query->limit($chunkSize);
51
52 10
        return new WalkCursor($query);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    #[ReadOperation]
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
Coding Style introduced by
Perl-style comments are not allowed; use "// Comment" instead
Loading history...
59 10
    public function next(WalkCursor $cursor): WalkCursor
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
60
    {
61 10
        $cursor = clone $cursor;
62
63 10
        if ($cursor->entities) {
64 8
            $cursor->cursor = $this->key->get(end($cursor->entities));
65
        }
66
67 10
        if ($cursor->cursor !== null) {
68 8
            $operator = $cursor->query->getOrders()[$this->key->name()] === Orderable::ORDER_ASC ? '>' : '<';
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

68
            $operator = $cursor->query->/** @scrutinizer ignore-call */ getOrders()[$this->key->name()] === Orderable::ORDER_ASC ? '>' : '<';
Loading history...
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
Coding Style introduced by
The value of a comparison must not be assigned to a variable
Loading history...
69 8
            $cursor->query->where($this->key->name(), $operator, $cursor->cursor);
0 ignored issues
show
Bug introduced by
The method where() does not exist on Bdf\Prime\Query\ReadCommandInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Bdf\Prime\Query\ReadCommandInterface. ( Ignorable by Annotation )

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

69
            $cursor->query->/** @scrutinizer ignore-call */ 
70
                            where($this->key->name(), $operator, $cursor->cursor);
Loading history...
70
        }
71
72 10
        $cursor->entities = $cursor->query->all();
73
74 10
        if ($cursor->entities instanceof CollectionInterface) {
0 ignored issues
show
introduced by
$cursor->entities is never a sub-type of Bdf\Prime\Collection\CollectionInterface.
Loading history...
75
            $cursor->entities = $cursor->entities->all();
76
        }
77
78 10
        return $cursor;
79
    }
80
81
    /**
82
     * Check if the strategy supports the given parameters
83
     *
84
     * @param ReadCommandInterface $query The query
85
     * @param int|null $startPage The start page
0 ignored issues
show
Coding Style introduced by
Expected "integer|null" but found "int|null" for parameter type
Loading history...
86
     * @param string $key The cursor key
87
     *
88
     * @return bool
0 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
89
     *
90
     * @psalm-assert-if-true Orderable&Limitable&Whereable $query
91
     */
92 16
    public static function supports(ReadCommandInterface $query, ?int $startPage, string $key): bool
93
    {
94 16
        if ($startPage !== null && $startPage !== 1) {
95 3
            return false;
96
        }
97
98 14
        if (!($query instanceof Orderable && $query instanceof Limitable && $query instanceof Whereable)) {
99 2
            return false;
100
        }
101
102 13
        $orders = $query->getOrders();
103
104 13
        return empty($orders) || (count($orders) === 1 && isset($orders[$key]));
0 ignored issues
show
Coding Style introduced by
Boolean operators are not allowed outside of control structure conditions
Loading history...
105
    }
106
}
107