Issues (21)

src/DataMapper/Query/AbstractConditions.php (1 issue)

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.Query/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 2
    public function limit(int $limit): AbstractConditions
39
    {
40 2
        $this->store["LIMIT"] = $limit;
41
42 2
        return $this;
43
    }
44
45
    /**
46
     * Sets the `OFFSET` clause
47
     *
48
     * @param int $offset
49
     *
50
     * @return AbstractConditions
51
     */
52 2
    public function offset(int $offset): AbstractConditions
53
    {
54 2
        $this->store["OFFSET"] = $offset;
55
56 2
        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 1
    public function andWhere(
69
        string $condition,
70
        $value = null,
71
        int $type = -1
72
    ): AbstractConditions {
73 1
        $this->where($condition, $value, $type);
74
75 1
        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 2
    public function appendWhere(
88
        string $condition,
89
        $value = null,
90
        int $type = -1
91
    ): AbstractConditions {
92 2
        $this->appendCondition("WHERE", $condition, $value, $type);
93
94 2
        return $this;
95
    }
96
97
    /**
98
     * Sets the `ORDER BY`
99
     *
100
     * @param array|string $orderBy
101
     *
102
     * @return AbstractConditions
103
     */
104 1
    public function orderBy($orderBy): AbstractConditions
105
    {
106 1
        $this->processValue("ORDER", $orderBy);
107
108 1
        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 3
    public function orWhere(
121
        string $condition,
122
        $value = null,
123
        int $type = -1
124
    ): AbstractConditions {
125 3
        $this->addCondition("WHERE", "OR ", $condition, $value, $type);
126
127 3
        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 8
    public function where(
140
        string $condition,
141
        $value = null,
142
        int $type = -1
143
    ): AbstractConditions {
144 8
        $this->addCondition("WHERE", "AND ", $condition, $value, $type);
145
146 8
        return $this;
147
    }
148
149
    /**
150
     * @param array $columnsValues
151
     *
152
     * @return AbstractConditions
153
     */
154 1
    public function whereEquals(array $columnsValues): AbstractConditions
155
    {
156 1
        foreach ($columnsValues as $key => $value) {
157 1
            if (is_numeric($key)) {
158 1
                $this->where($value);
159 1
            } elseif (null === $value) {
160 1
                $this->where($key . " IS NULL");
161 1
            } elseif (is_array($value)) {
162 1
                $this->where($key . " IN ", $value);
163
            } else {
164 1
                $this->where($key . " = ", $value);
165
            }
166
        }
167
168 1
        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 11
    protected function addCondition(
181
        string $store,
182
        string $andor,
183
        string $condition,
184
        $value = null,
185
        int $type = -1
186
    ): void {
187 11
        if (!empty($value)) {
188 4
            $condition .= $this->bindInline($value, $type);
189
        }
190
191 11
        if (empty($this->store[$store])) {
192 10
            $andor = "";
193
        }
194
195 11
        $this->store[$store][] = $andor . $condition;
196 11
    }
197
198
    /**
199
     * Builds a `BY` list
200
     *
201
     * @param string $type
202
     *
203
     * @return string
204
     */
205 30
    protected function buildBy(string $type): string
206
    {
207 30
        if (empty($this->store[$type])) {
208 30
            return "";
209
        }
210
211 2
        return " " . $type . " BY"
212 2
            . $this->indent($this->store[$type], ",");
213
    }
214
215
    /**
216
     * Builds the conditional string
217
     *
218
     * @param string $type
219
     *
220
     * @return string
221
     */
222 32
    protected function buildCondition(string $type): string
223
    {
224 32
        if (empty($this->store[$type])) {
225 30
            return "";
226
        }
227
228 11
        return " " . $type
229 11
            . $this->indent($this->store[$type]);
230
    }
231
232
    /**
233
     * Builds the early `LIMIT` clause - MS SQLServer
234
     *
235
     * @return string
236
     */
237 30
    protected function buildLimitEarly(): string
238
    {
239 30
        $limit = "";
240
241
        if (
242 30
            "sqlsrv" === $this->connection->getDriverName() &&
243 30
            $this->store["LIMIT"] > 0 &&
244 30
            0 === $this->store["OFFSET"]
245
        ) {
246 1
            $limit = " TOP " . $this->store["LIMIT"];
247
        }
248
249 30
        return $limit;
250
    }
251
252
    /**
253
     * Builds the `LIMIT` clause
254
     *
255
     * @return string
256
     */
257 30
    protected function buildLimit(): string
258
    {
259 30
        $suffix = $this->connection->getDriverName();
260
261 30
        if ("sqlsrv" !== $suffix) {
262 29
            $suffix = "common";
263
        }
264
265 30
        $method = "buildLimit" . ucfirst($suffix);
266
267 30
        return $this->{$method}();
268
    }
269
270
    /**
271
     * Builds the `LIMIT` clause for all drivers
272
     *
273
     * @return string
274
     */
275
276 29
    protected function buildLimitCommon(): string
277
    {
278 29
        $limit = "";
279
280 29
        if (0 !== $this->store["LIMIT"]) {
281 1
            $limit .= "LIMIT " . $this->store["LIMIT"];
282
        }
283
284 29
        if (0 !== $this->store["OFFSET"]) {
285 1
            $limit .= " OFFSET " . $this->store["OFFSET"];
286
        }
287
288 29
        if ("" !== $limit) {
289 1
            $limit = " " . ltrim($limit);
290
        }
291
292 29
        return ($limit);
293
    }
294
295
    /**
296
     * Builds the `LIMIT` clause for MSSQLServer
297
     *
298
     * @return string
299
     */
300 1
    protected function buildLimitSqlsrv(): string
301
    {
302 1
        $limit = "";
303
304 1
        if ($this->store["LIMIT"] > 0 && $this->store["OFFSET"] > 0) {
305 1
            $limit = " OFFSET " . $this->store["OFFSET"] . " ROWS"
306 1
                . " FETCH NEXT " . $this->store["LIMIT"] . " ROWS ONLY";
307
        }
308
309 1
        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 3
    protected function appendCondition(
321
        string $store,
322
        string $condition,
323
        $value = null,
324
        int $type = -1
325
    ): void {
326 3
        if (!empty($value)) {
327 1
            $condition .= $this->bindInline($value, $type);
328
        }
329
330 3
        if (empty($this->store[$store])) {
331 1
            $this->store[$store][] = "";
332
        }
333
334 3
        $key = Arr::lastKey($this->store[$store]);
335
336 3
        $this->store[$store][$key] = $this->store[$store][$key] . $condition;
337 3
    }
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 2
    protected function processValue(string $store, $data): void
346
    {
347 2
        if (is_string($data)) {
348 1
            $data = [$data];
349
        }
350
351 2
        if (is_array($data)) {
0 ignored issues
show
The condition is_array($data) is always true.
Loading history...
352 2
            $this->store[$store] = array_merge(
353 2
                $this->store[$store],
354
                $data
355
            );
356
        }
357 2
    }
358
}
359