Passed
Push — master ( 157485...b7615a )
by Nikolaos
09:23
created

AbstractConditions   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 326
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 38
eloc 74
c 0
b 0
f 0
dl 0
loc 326
rs 9.36

17 Methods

Rating   Name   Duplication   Size   Complexity  
A appendWhere() 0 8 1
A limit() 0 5 1
A buildLimitSqlsrv() 0 10 3
A buildLimitEarly() 0 13 4
A processValue() 0 10 3
A buildCondition() 0 8 2
A appendCondition() 0 17 3
A orderBy() 0 5 1
A buildLimitCommon() 0 17 4
A orWhere() 0 8 1
A buildLimit() 0 11 2
A addCondition() 0 16 3
A andWhere() 0 8 1
A buildBy() 0 8 2
A whereEquals() 0 15 5
A offset() 0 5 1
A where() 0 8 1
1
<?php
2
3
/**
4
 * This file is part of the Phalcon Framework.
5
 *
6
 * (c) Phalcon Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 *
11
 * Implementation of this file has been influenced by AtlasPHP
12
 *
13
 * @link    https://github.com/atlasphp/Atlas.Query
14
 * @license https://github.com/atlasphp/Atlas.Qyert/blob/1.x/LICENSE.md
15
 */
16
17
declare(strict_types=1);
18
19
namespace Phalcon\DataMapper\Query;
20
21
use Phalcon\Helper\Arr;
22
23
use function is_array;
24
use function is_string;
25
26
/**
27
 * Class AbstractConditions
28
 */
29
abstract class AbstractConditions extends AbstractQuery
30
{
31
    /**
32
     * Sets the `LIMIT` clause
33
     *
34
     * @param int $limit
35
     *
36
     * @return AbstractConditions
37
     */
38
    public function limit(int $limit): AbstractConditions
39
    {
40
        $this->store["LIMIT"] = $limit;
41
42
        return $this;
43
    }
44
45
    /**
46
     * Sets the `OFFSET` clause
47
     *
48
     * @param int $offset
49
     *
50
     * @return AbstractConditions
51
     */
52
    public function offset(int $offset): AbstractConditions
53
    {
54
        $this->store["OFFSET"] = $offset;
55
56
        return $this;
57
    }
58
59
    /**
60
     * Sets a `AND` for a `WHERE` condition
61
     *
62
     * @param string     $condition
63
     * @param mixed|null $value
64
     * @param int        $type
65
     *
66
     * @return AbstractConditions
67
     */
68
    public function andWhere(
69
        string $condition,
70
        $value = null,
71
        int $type = -1
72
    ): AbstractConditions {
73
        $this->where($condition, $value, $type);
74
75
        return $this;
76
    }
77
78
    /**
79
     * Concatenates to the most recent `WHERE` clause
80
     *
81
     * @param string     $condition
82
     * @param mixed|null $value
83
     * @param int        $type
84
     *
85
     * @return AbstractConditions
86
     */
87
    public function appendWhere(
88
        string $condition,
89
        $value = null,
90
        int $type = -1
91
    ): AbstractConditions {
92
        $this->appendCondition("WHERE", $condition, $value, $type);
93
94
        return $this;
95
    }
96
97
    /**
98
     * Sets the `ORDER BY`
99
     *
100
     * @param array|string $orderBy
101
     *
102
     * @return AbstractConditions
103
     */
104
    public function orderBy($orderBy): AbstractConditions
105
    {
106
        $this->processValue("ORDER", $orderBy);
107
108
        return $this;
109
    }
110
111
    /**
112
     * Sets a `OR` for a `WHERE` condition
113
     *
114
     * @param string     $condition
115
     * @param mixed|null $value
116
     * @param int        $type
117
     *
118
     * @return AbstractConditions
119
     */
120
    public function orWhere(
121
        string $condition,
122
        $value = null,
123
        int $type = -1
124
    ): AbstractConditions {
125
        $this->addCondition("WHERE", "OR ", $condition, $value, $type);
126
127
        return $this;
128
    }
129
130
    /**
131
     * Sets a `WHERE` condition
132
     *
133
     * @param string     $condition
134
     * @param mixed|null $value
135
     * @param int        $type
136
     *
137
     * @return AbstractConditions
138
     */
139
    public function where(
140
        string $condition,
141
        $value = null,
142
        int $type = -1
143
    ): AbstractConditions {
144
        $this->addCondition("WHERE", "AND ", $condition, $value, $type);
145
146
        return $this;
147
    }
148
149
    /**
150
     * @param array $columnsValues
151
     *
152
     * @return AbstractConditions
153
     */
154
    public function whereEquals(array $columnsValues): AbstractConditions
155
    {
156
        foreach ($columnsValues as $key => $value) {
157
            if (is_numeric($key)) {
158
                $this->where($value);
159
            } elseif (null === $value) {
160
                $this->where($key . " IS NULL");
161
            } elseif (is_array($value)) {
162
                $this->where($key . " IN ", $value);
163
            } else {
164
                $this->where($key . " = ", $value);
165
            }
166
        }
167
168
        return $this;
169
    }
170
171
    /**
172
     * Appends a conditional
173
     *
174
     * @param string     $store
175
     * @param string     $andor
176
     * @param string     $condition
177
     * @param mixed|null $value
178
     * @param int        $type
179
     */
180
    protected function addCondition(
181
        string $store,
182
        string $andor,
183
        string $condition,
184
        $value = null,
185
        int $type = -1
186
    ): void {
187
        if (!empty($value)) {
188
            $condition .= $this->bindInline($value, $type);
189
        }
190
191
        if (empty($this->store[$store])) {
192
            $andor = "";
193
        }
194
195
        $this->store[$store][] = $andor . $condition;
196
    }
197
198
    /**
199
     * Builds a `BY` list
200
     *
201
     * @param string $type
202
     *
203
     * @return string
204
     */
205
    protected function buildBy(string $type): string
206
    {
207
        if (empty($this->store[$type])) {
208
            return "";
209
        }
210
211
        return " " . $type . " BY"
212
            . $this->indent($this->store[$type], ",");
213
    }
214
215
    /**
216
     * Builds the conditional string
217
     *
218
     * @param string $type
219
     *
220
     * @return string
221
     */
222
    protected function buildCondition(string $type): string
223
    {
224
        if (empty($this->store[$type])) {
225
            return "";
226
        }
227
228
        return " " . $type
229
            . $this->indent($this->store[$type]);
230
    }
231
232
    /**
233
     * Builds the early `LIMIT` clause - MS SQLServer
234
     *
235
     * @return string
236
     */
237
    protected function buildLimitEarly(): string
238
    {
239
        $limit = "";
240
241
        if (
242
            "sqlsrv" === $this->connection->getDriverName() &&
243
            $this->store["LIMIT"] > 0 &&
244
            0 === $this->store["OFFSET"]
245
        ) {
246
            $limit = " TOP " . $this->store["LIMIT"];
247
        }
248
249
        return $limit;
250
    }
251
252
    /**
253
     * Builds the `LIMIT` clause
254
     *
255
     * @return string
256
     */
257
    protected function buildLimit(): string
258
    {
259
        $suffix = $this->connection->getDriverName();
260
261
        if ("sqlsrv" !== $suffix) {
262
            $suffix = "common";
263
        }
264
265
        $method = "buildLimit" . ucfirst($suffix);
266
267
        return $this->{$method}();
268
    }
269
270
    /**
271
     * Builds the `LIMIT` clause for all drivers
272
     *
273
     * @return string
274
     */
275
276
    protected function buildLimitCommon(): string
277
    {
278
        $limit = "";
279
280
        if (0 !== $this->store["LIMIT"]) {
281
            $limit .= "LIMIT " . $this->store["LIMIT"];
282
        }
283
284
        if (0 !== $this->store["OFFSET"]) {
285
            $limit .= " OFFSET " . $this->store["OFFSET"];
286
        }
287
288
        if ("" !== $limit) {
289
            $limit = " " . ltrim($limit);
290
        }
291
292
        return ($limit);
293
    }
294
295
    /**
296
     * Builds the `LIMIT` clause for MSSQLServer
297
     *
298
     * @return string
299
     */
300
    protected function buildLimitSqlsrv(): string
301
    {
302
        $limit = "";
303
304
        if ($this->store["LIMIT"] > 0 && $this->store["OFFSET"] > 0) {
305
            $limit = " OFFSET " . $this->store["OFFSET"] . " ROWS"
306
                . " FETCH NEXT " . $this->store["LIMIT"] . " ROWS ONLY";
307
        }
308
309
        return $limit;
310
    }
311
312
    /**
313
     * Concatenates a conditional
314
     *
315
     * @param string $store
316
     * @param string $condition
317
     * @param mixed  $value
318
     * @param int    $type
319
     */
320
    protected function appendCondition(
321
        string $store,
322
        string $condition,
323
        $value = null,
324
        int $type = -1
325
    ): void {
326
        if (!empty($value)) {
327
            $condition .= $this->bindInline($value, $type);
328
        }
329
330
        if (empty($this->store[$store])) {
331
            $this->store[$store][] = "";
332
        }
333
334
        $key = Arr::lastKey($this->store[$store]);
335
336
        $this->store[$store][$key] = $this->store[$store][$key] . $condition;
337
    }
338
339
    /**
340
     * Processes a value (array or string) and merges it with the store
341
     *
342
     * @param string       $store
343
     * @param array|string $data
344
     */
345
    protected function processValue(string $store, $data): void
346
    {
347
        if (is_string($data)) {
348
            $data = [$data];
349
        }
350
351
        if (is_array($data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always true.
Loading history...
352
            $this->store[$store] = array_merge(
353
                $this->store[$store],
354
                $data
355
            );
356
        }
357
    }
358
}
359