Passed
Push — master ( 75ea01...eacc73 )
by Adrian
01:37
created

Query::__clone()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Orm;
5
6
use Sirius\Orm\Collection\Collection;
7
use Sirius\Orm\Collection\PaginatedCollection;
8
use Sirius\Sql\Bindings;
9
use Sirius\Sql\Select;
10
11
class Query extends Select
12
{
13
14
    /**
15
     * @var Orm
16
     */
17
    protected $orm;
18
19
    /**
20
     * @var Mapper
21
     */
22
    protected $mapper;
23
24
    /**
25
     * @var array
26
     */
27
    protected $load = [];
28
29
    /**
30
     * @var array
31
     */
32
    protected $guards = [];
33
34
    /**
35
     * @var array
36
     */
37
    protected $scopes = [];
38
39
    public function __construct(Mapper $mapper)
40
    {
41
        parent::__construct($mapper->getReadConnection());
42
        $this->mapper = $mapper;
43
        $this->from($this->mapper->getTableReference());
44
        $this->resetColumns();
45
        $this->columns($this->mapper->getTableAlias(true) . '.*');
46
    }
47
48
    public function __call(string $method, array $params)
49
    {
50
        $scope = $this->mapper->getScope($method);
51
        if ($scope && is_callable($scope)) {
52
            return $scope($this, ...$params);
53
        }
54
55
        return parent::__call($method, $params);
56
    }
57
58
    public function __clone()
59
    {
60
        $vars = get_object_vars($this);
61
        unset($vars['mapper']);
62
        foreach ($vars as $name => $prop) {
63
            if (is_object($prop)) {
64
                $this->$name = clone $prop;
65
            }
66
        }
67
    }
68
69
70
    public function load(...$relations): self
71
    {
72
        foreach ($relations as $name => $callback) {
73
            if (is_int($name)) {
74
                $this->load[$callback] = null;
75
            } elseif (is_callable($callback)) {
76
                $this->load[$name] = $callback;
77
            } else {
78
                throw new \InvalidArgumentException('Invalid callable for relation');
79
            }
80
        }
81
82
        return $this;
83
    }
84
85
    public function first()
86
    {
87
        $row = $this->fetchOne();
88
89
        return $this->mapper->newEntityFromRow($row, $this->load);
90
    }
91
92
    public function get(): Collection
93
    {
94
        return $this->mapper->newCollectionFromRows($this->fetchAll(), $this->load);
95
    }
96
97
    public function paginate($perPage, $page): PaginatedCollection
98
    {
99
        /** @var Query $countQuery */
100
        $countQuery = clone $this;
101
        $total      = $countQuery->count();
102
103
        if ($total == 0) {
104
            $this->mapper->newPaginatedCollectionFromRows([], $total, $perPage, $page, $this->load);
105
        }
106
107
        $this->perPage($perPage);
108
        $this->page($page);
109
110
        return $this->mapper->newPaginatedCollectionFromRows($this->fetchAll(), $total, $perPage, $page, $this->load);
111
    }
112
113
    public function chunk($count, $callback)
0 ignored issues
show
Unused Code introduced by
The parameter $callback is not used and could be removed. ( Ignorable by Annotation )

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

113
    public function chunk($count, /** @scrutinizer ignore-unused */ $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $count is not used and could be removed. ( Ignorable by Annotation )

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

113
    public function chunk(/** @scrutinizer ignore-unused */ $count, $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
114
    {
115
    }
116
117
    public function count()
118
    {
119
        $this->resetOrderBy();
120
        $this->resetColumns();
121
        $this->columns('COUNT(*) AS total');
122
123
        return (int)$this->fetchValue();
124
    }
125
126
    public function setGuards(array $guards)
127
    {
128
        foreach ($guards as $column => $value) {
129
            if (is_int($column)) {
130
                $this->guards[] = $value;
131
            } else {
132
                $this->guards[$column] = $value;
133
            }
134
        }
135
136
        return $this;
137
    }
138
139
    public function resetGuards()
140
    {
141
        $this->guards = [];
142
143
        return;
144
    }
145
146
    protected function applyGuards()
147
    {
148
        if (empty($this->guards)) {
149
            return;
150
        }
151
152
        $this->groupCurrentWhere();
153
        foreach ($this->guards as $column => $value) {
154
            if (is_int($column)) {
155
                $this->where($value);
156
            } else {
157
                $this->where($column, $value);
158
            }
159
        }
160
    }
161
162
    public function getStatement(): string
163
    {
164
        $this->applyGuards();
165
166
        return parent::getStatement();
167
    }
168
}
169