Passed
Pull Request — master (#17)
by
unknown
01:47
created

SelectDataReader::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 13
ccs 0
cts 13
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\DataReader;
6
7
use Countable;
8
use Cycle\ORM\Select;
9
use InvalidArgumentException;
10
use Spiral\Database\Query\QueryInterface;
11
use Spiral\Database\Query\SelectQuery;
12
use Spiral\Pagination\PaginableInterface;
13
use Yiisoft\Data\Reader\CountableDataInterface;
14
use Yiisoft\Data\Reader\DataReaderInterface;
15
use Yiisoft\Data\Reader\OffsetableDataInterface;
16
use Yiisoft\Data\Reader\Sort;
17
use Yiisoft\Data\Reader\SortableDataInterface;
18
use Yiisoft\Yii\Cycle\DataReader\Cache\CachedCount;
19
use Yiisoft\Yii\Cycle\DataReader\Cache\CachedCollection;
20
21
final class SelectDataReader implements
22
    DataReaderInterface,
23
    OffsetableDataInterface,
24
    CountableDataInterface,
25
    SortableDataInterface
26
{
27
    /** @var Select|SelectQuery */
28
    private $query;
29
    private ?int $limit = null;
30
    private ?int $offset = null;
31
    private ?Sort $sorting = null;
32
    private CachedCount $countCache;
33
    private CachedCollection $itemsCache;
34
35
    /**
36
     * @param Select|SelectQuery $query
37
     */
38
    public function __construct($query)
39
    {
40
        if (!$query instanceof Countable) {
0 ignored issues
show
introduced by
$query is always a sub-type of Countable.
Loading history...
41
            throw new InvalidArgumentException(sprintf('Query should implement %s interface', Countable::class));
42
        }
43
        if (!$query instanceof PaginableInterface) {
0 ignored issues
show
introduced by
$query is always a sub-type of Spiral\Pagination\PaginableInterface.
Loading history...
44
            throw new InvalidArgumentException(
45
                sprintf('Query should implement %s interface', PaginableInterface::class)
46
            );
47
        }
48
        $this->query = clone $query;
49
        $this->countCache = new CachedCount($this->query);
50
        $this->itemsCache = new CachedCollection();
51
    }
52
53
    public function getSort(): ?Sort
54
    {
55
        return $this->sorting;
56
    }
57
58
    public function withLimit(int $limit): self
59
    {
60
        $clone = clone $this;
61
        $clone->setLimit($limit);
62
        return $clone;
63
    }
64
65
    public function withOffset(int $offset): self
66
    {
67
        $clone = clone $this;
68
        $clone->setOffset($offset);
69
        return $clone;
70
    }
71
72
    public function withSort(?Sort $sorting): self
73
    {
74
        $clone = clone $this;
75
        $clone->setSort($sorting);
76
        return $clone;
77
    }
78
79
    public function count(): int
80
    {
81
        return $this->countCache->getCount();
82
    }
83
84
    public function read(): iterable
85
    {
86
        if ($this->itemsCache->getCollection() !== null) {
87
            return $this->itemsCache->getCollection();
88
        }
89
        $newQuery = clone $this->query;
90
        if ($this->offset !== null) {
91
            $newQuery->offset($this->offset);
92
        }
93
        if ($this->sorting !== null) {
94
            $newQuery->orderBy($this->sorting->getOrder());
95
        }
96
        if ($this->limit !== null) {
97
            $newQuery->limit($this->limit);
98
        }
99
        $this->itemsCache->setCollection($newQuery->fetchAll());
100
        return $this->itemsCache->getCollection();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->itemsCache->getCollection() targeting Yiisoft\Yii\Cycle\DataRe...ection::getCollection() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug Best Practice introduced by
The expression return $this->itemsCache->getCollection() returns the type null which is incompatible with the type-hinted return iterable.
Loading history...
101
    }
102
103
    private function setSort(?Sort $sorting): void
104
    {
105
        if ($this->sorting !== $sorting) {
106
            $this->sorting = $sorting;
107
            $this->itemsCache = new CachedCollection();
108
        }
109
    }
110
111
    private function setLimit(?int $limit): void
112
    {
113
        if ($this->limit !== $limit) {
114
            $this->limit = $limit;
115
            $this->itemsCache = new CachedCollection();
116
        }
117
    }
118
119
    private function setOffset(?int $offset): void
120
    {
121
        if ($this->offset !== $offset) {
122
            $this->offset = $offset;
123
            $this->itemsCache = new CachedCollection();
124
        }
125
    }
126
}
127