Completed
Push — master ( a7b476...58257b )
by Adrian
01:51
created

Query::subSelectForJoinWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 7
rs 10
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, Bindings $bindings = null, string $indent = '')
40
    {
41
        parent::__construct($mapper->getReadConnection(), $bindings, $indent);
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->getQueryScope($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 joinWith($name): Query
86
    {
87
        if (! $this->mapper->hasRelation($name)) {
88
            throw new \InvalidArgumentException(
89
                sprintf("Relation %s, not defined for %s", $name, $this->mapper->getTable())
90
            );
91
        }
92
        $relation = $this->mapper->getRelation($name);
93
94
        return $relation->joinSubselect($this, $name);
95
    }
96
97
    public function subSelectForJoinWith(): Query
98
    {
99
        $subselect = new Query($this->mapper, $this->bindings, $this->indent . '    ');
100
        $subselect->resetFrom();
101
        $subselect->resetColumns();
102
103
        return $subselect;
104
    }
105
106
    public function first()
107
    {
108
        $row = $this->fetchOne();
109
110
        return $this->mapper->newEntityFromRow($row, $this->load);
111
    }
112
113
    public function get(): Collection
114
    {
115
        return $this->mapper->newCollectionFromRows($this->fetchAll(), $this->load);
116
    }
117
118
    public function paginate($perPage, $page): PaginatedCollection
119
    {
120
        /** @var Query $countQuery */
121
        $countQuery = clone $this;
122
        $total      = $countQuery->count();
123
124
        if ($total == 0) {
125
            $this->mapper->newPaginatedCollectionFromRows([], $total, $perPage, $page, $this->load);
126
        }
127
128
        $this->perPage($perPage);
129
        $this->page($page);
130
131
        return $this->mapper->newPaginatedCollectionFromRows($this->fetchAll(), $total, $perPage, $page, $this->load);
132
    }
133
134
    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

134
    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

134
    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...
135
    {
136
    }
137
138
    public function count()
139
    {
140
        $this->resetOrderBy();
141
        $this->resetColumns();
142
        $this->columns('COUNT(*) AS total');
143
144
        return (int)$this->fetchValue();
145
    }
146
147
    public function setGuards(array $guards)
148
    {
149
        foreach ($guards as $column => $value) {
150
            if (is_int($column)) {
151
                $this->guards[] = $value;
152
            } else {
153
                $this->guards[$column] = $value;
154
            }
155
        }
156
157
        return $this;
158
    }
159
160
    public function resetGuards()
161
    {
162
        $this->guards = [];
163
164
        return;
165
    }
166
167
    protected function applyGuards()
168
    {
169
        if (empty($this->guards)) {
170
            return;
171
        }
172
173
        $this->groupCurrentWhere();
174
        foreach ($this->guards as $column => $value) {
175
            if (is_int($column)) {
176
                $this->where($value);
177
            } else {
178
                $this->where($column, $value);
179
            }
180
        }
181
    }
182
183
    public function getStatement(): string
184
    {
185
        $this->applyGuards();
186
187
        return parent::getStatement();
188
    }
189
}
190