Passed
Pull Request — master (#38)
by Bas
17:19
created

CompilesWhereClauses::whereIn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 10
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
4
5
use Illuminate\Database\Query\Builder as IluminateBuilder;
6
use Illuminate\Database\Query\Expression;
7
use LaravelFreelancerNL\Aranguent\Query\Builder;
8
9
trait CompilesWhereClauses
10
{
11
    /**
12
     * Compile the "where" portions of the query.
13
     *
14
     * @param Builder $builder
15
     *
16
     * @return Builder
17
     */
18
    protected function compileWheres(Builder $builder)
19
    {
20
        if (is_null($builder->wheres)) {
0 ignored issues
show
introduced by
The condition is_null($builder->wheres) is always false.
Loading history...
21
            return $builder;
22
        }
23
24
        $predicates = $this->compileWheresToArray($builder);
25
26
        if (count($predicates) > 0) {
27
            $builder->aqb = $builder->aqb->filter($predicates);
28
        }
29
30
        return $builder;
31
    }
32
33
    /**
34
     * Get an array of all the where clauses for the query.
35
     *
36
     * @param  IluminateBuilder  $query
37
     * @return array
38
     */
39
    protected function compileWheresToArray($query)
40
    {
41
        return collect($query->wheres)->map(function ($where) use ($query) {
42
            return $this->{"where{$where['type']}"}($query, $where);
43
        })->all();
44
    }
45
46
    protected function getOperatorByWhereType($type)
47
    {
48
        if (isset($this->whereTypeOperators[$type])) {
49
            return $this->whereTypeOperators[$type];
50
        }
51
52
        return '==';
53
    }
54
55
    /**
56
     * Determine if the given value is a raw expression.
57
     *
58
     * @param  mixed  $value
59
     * @return bool
60
     */
61
    public function isExpression($value)
62
    {
63
        return $value instanceof Expression;
64
    }
65
66
    /**
67
     * Get the appropriate query parameter place-holder for a value.
68
     *
69
     * @param  IluminateBuilder  $query
70
     * @param  mixed  $value
71
     * @return object
72
     */
73
    public function parameter(IluminateBuilder $query, $value)
74
    {
75
        return $this->isExpression($value) ? $query->getValue($value) : $query->aqb->bind($value);
76
    }
77
78
    protected function normalizeOperator($where)
79
    {
80
        if (isset($where['operator'])) {
81
            $where['operator'] = $this->translateOperator($where['operator']);
82
        }
83
        if (! isset($where['operator'])) {
84
            $where['operator'] = $this->getOperatorByWhereType($where['type']);
85
        }
86
87
            return $where;
88
    }
89
90
    /**
91
     * Translate sql operators to their AQL equivalent where possible.
92
     *
93
     * @param string $operator
94
     *
95
     * @return mixed|string
96
     */
97
    private function translateOperator(string $operator)
98
    {
99
        if (isset($this->operatorTranslations[strtolower($operator)])) {
100
            $operator = $this->operatorTranslations[$operator];
101
        }
102
103
        return $operator;
104
    }
105
106
107
    /**
108
     * Compile a basic where clause.
109
     *
110
     * @param  IluminateBuilder  $query
111
     * @param  array  $where
112
     * @return array
113
     */
114
    protected function whereBasic(IluminateBuilder $query, $where)
115
    {
116
        $predicate = [];
117
118
        $where = $this->normalizeOperator($where);
119
120
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
0 ignored issues
show
Bug introduced by
It seems like normalizeColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

120
        /** @scrutinizer ignore-call */ 
121
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
Loading history...
121
        $predicate[1] = $where['operator'];
122
        $predicate[2] = $this->parameter($query, $where['value']);
123
        $predicate[3] = $where['boolean'];
124
125
        return $predicate;
126
    }
127
128
    /**
129
     * Compile a "between" where clause.
130
     *
131
     * @param  IluminateBuilder  $query
132
     * @param  array  $where
133
     * @return string
134
     */
135
    protected function whereBetween(IluminateBuilder $query, $where)
136
    {
137
        $predicate = [];
138
139
        [$minOperator, $maxOperator, $boolean] = $this->getBetweenOperators($where['not']);
140
141
        $min = $this->parameter($query, reset($where['values']));
142
143
        $max = $this->parameter($query, end($where['values']));
144
145
        $predicate[0][0] = $this->normalizeColumn($query, $where['column']);
146
        $predicate[0][1] = $minOperator;
147
        $predicate[0][2] = $min;
148
        $predicate[0][3] = $where['boolean'];
149
150
        $predicate[1][0] = $this->normalizeColumn($query, $where['column']);
151
        $predicate[1][1] = $maxOperator;
152
        $predicate[1][2] = $max;
153
        $predicate[1][3] = $boolean;
154
155
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
156
    }
157
158
    /**
159
     * Generate operators for between and 'not between'
160
     * @param  bool  $notBetween
161
     * @return string[]
162
     */
163
    protected function getBetweenOperators(bool $notBetween)
164
    {
165
        $minOperator = '>=';
166
        $maxOperator = '<=';
167
        $boolean = 'AND';
168
169
        if ($notBetween) {
170
            $minOperator = '<';
171
            $maxOperator = '>';
172
            $boolean = 'OR';
173
        }
174
175
        return [$minOperator, $maxOperator, $boolean];
176
    }
177
178
    /**
179
     * Compile a "between" where clause.
180
     *
181
     * @param  IluminateBuilder  $query
182
     * @param  array  $where
183
     * @return string
184
     */
185
    protected function whereBetweenColumns(IluminateBuilder $query, $where)
186
    {
187
        $predicate = [];
188
189
        [$minOperator, $maxOperator, $boolean] = $this->getBetweenOperators($where['not']);
190
191
        $column = $this->normalizeColumn($query, $where['column']);
192
193
        $predicate[0][0] = $column;
194
        $predicate[0][1] = $minOperator;
195
        $predicate[0][2] = $this->normalizeColumn($query, reset($where['values']));
196
        $predicate[0][3] = $where['boolean'];
197
198
        $predicate[1][0] = $column;
199
        $predicate[1][1] = $maxOperator;
200
        $predicate[1][2] = $this->normalizeColumn($query, end($where['values']));
201
        $predicate[1][3] = $boolean;
202
203
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
204
    }
205
206
207
    /**
208
     * Compile a where clause comparing two columns..
209
     *
210
     * @param  IluminateBuilder  $query
211
     * @param  array  $where
212
     * @return string
213
     */
214
    protected function whereColumn(IluminateBuilder $query, $where)
215
    {
216
        $predicate = [];
217
218
        $where = $this->normalizeOperator($where);
219
220
        $predicate[0] = $this->normalizeColumn($query, $where['first']);
221
        $predicate[1] = $where['operator'];
222
        $predicate[2] = $this->normalizeColumn($query, $where['second']);
223
        $predicate[3] = $where['boolean'];
224
225
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
226
    }
227
228
    /**
229
     * Compile a "where null" clause.
230
     *
231
     * @param  IluminateBuilder  $query
232
     * @param  array  $where
233
     * @return string
234
     */
235
    protected function whereNull(IluminateBuilder $query, $where)
236
    {
237
        $predicate = [];
238
239
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
240
        $predicate[1] = '==';
241
        $predicate[2] = null;
242
        $predicate[3] = $where['boolean'];
243
244
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
245
    }
246
247
    /**
248
     * Compile a "where not null" clause.
249
     *
250
     * @param  IluminateBuilder  $query
251
     * @param  array  $where
252
     * @return string
253
     */
254
    protected function whereNotNull(IluminateBuilder $query, $where)
255
    {
256
        $predicate = [];
257
258
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
259
        $predicate[1] = '!=';
260
        $predicate[2] = null;
261
        $predicate[3] = $where['boolean'];
262
263
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
264
    }
265
266
    /**
267
     * Compile a "where in" clause.
268
     *
269
     * @param  IluminateBuilder  $query
270
     * @param  array  $where
271
     * @return string
272
     */
273
    protected function whereIn(IluminateBuilder $query, $where)
274
    {
275
        $predicate = [];
276
277
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
278
        $predicate[1] = 'IN';
279
        $predicate[2] = $this->parameter($query, $where['values']);
280
        $predicate[3] = $where['boolean'];
281
282
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
283
    }
284
285
    /**
286
     * Compile a "where in raw" clause.
287
     *
288
     * For safety, whereIntegerInRaw ensures this method is only used with integer values.
289
     *
290
     * @param  IluminateBuilder  $query
291
     * @param  array  $where
292
     * @return string
293
     */
294
    protected function whereInRaw(IluminateBuilder $query, $where)
295
    {
296
        $predicate = [];
297
298
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
299
        $predicate[1] = 'IN';
300
        $predicate[2] = '[' . implode(', ', $where['values']) . ']';
301
        $predicate[3] = $where['boolean'];
302
303
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
304
    }
305
306
    /**
307
     * Compile a "where not in" clause.
308
     *
309
     * @param  IluminateBuilder  $query
310
     * @param  array  $where
311
     * @return string
312
     */
313
    protected function whereNotIn(IluminateBuilder $query, $where)
314
    {
315
        $predicate = [];
316
317
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
318
        $predicate[1] = 'NOT IN';
319
        $predicate[2] = $this->parameter($query, $where['values']);
320
        $predicate[3] = $where['boolean'];
321
322
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
323
    }
324
325
    /**
326
     * Compile a "where not in raw" clause.
327
     *
328
     * For safety, whereIntegerInRaw ensures this method is only used with integer values.
329
     *
330
     * @param  IluminateBuilder  $query
331
     * @param  array  $where
332
     * @return string
333
     */
334
    protected function whereNotInRaw(IluminateBuilder $query, $where)
335
    {
336
        $predicate = [];
337
338
        $predicate[0] = $this->normalizeColumn($query, $where['column']);
339
        $predicate[1] = 'NOT IN';
340
        $predicate[2] = '[' . implode(', ', $where['values']) . ']';
341
        $predicate[3] = $where['boolean'];
342
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
343
    }
344
345
    /**
346
     * Compile a "whereJsonContains" clause.
347
     *
348
     * @param  IluminateBuilder  $query
349
     * @param  array  $where
350
     * @return string
351
     */
352
    protected function whereJsonContains(IluminateBuilder $query, $where)
353
    {
354
        $predicate = [];
355
356
        $operator = $where['not'] ? 'NOT IN' : 'IN';
357
358
        $predicate[0] = $query->aqb->bind($where['value']);
359
        $predicate[1] = $operator;
360
        $predicate[2] = $this->normalizeColumn($query, $where['column']);
361
        $predicate[3] = $where['boolean'];
362
363
        return $predicate;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $predicate returns the type array which is incompatible with the documented return type string.
Loading history...
364
    }
365
366
    /**
367
     * Compile a "whereJsonContains" clause.
368
     *
369
     * @param  IluminateBuilder  $query
370
     * @param  array  $where
371
     * @return array
372
     */
373
    protected function whereJsonLength(IluminateBuilder $query, $where)
374
    {
375
        $predicate = [];
376
377
        $where = $this->normalizeOperator($where);
378
379
        $column = $this->normalizeColumn($query, $where['column']);
380
381
        $predicate[0] = $query->aqb->length($column);
382
        $predicate[1] = $where['operator'];
383
        $predicate[2] = $this->parameter($query, $where['value']);
384
        $predicate[3] = $where['boolean'];
385
386
        return $predicate;
387
    }
388
389
390
    /**
391
     * Compile a where date clause.
392
     *
393
     * @param  IluminateBuilder  $query
394
     * @param  array  $where
395
     * @return array
396
     */
397
    protected function whereDate(IluminateBuilder $query, $where)
398
    {
399
        $predicate = [];
400
401
        $where = $this->normalizeOperator($where);
402
403
        $predicate[0] = $query->aqb->dateFormat($this->normalizeColumn($query, $where['column']), "%yyyy-%mm-%dd");
404
        $predicate[1] = $where['operator'];
405
        $predicate[2] = $this->parameter($query, $where['value']);
406
        $predicate[3] = $where['boolean'];
407
408
        return $predicate;
409
    }
410
411
    /**
412
     * Compile a where year clause.
413
     *
414
     * @param  IluminateBuilder  $query
415
     * @param  array  $where
416
     * @return array
417
     */
418
    protected function whereYear(IluminateBuilder $query, $where)
419
    {
420
        $predicate = [];
421
422
        $where = $this->normalizeOperator($where);
423
424
        $predicate[0] = $query->aqb->dateYear($this->normalizeColumn($query, $where['column']));
425
        $predicate[1] = $where['operator'];
426
        $predicate[2] = $this->parameter($query, $where['value']);
427
        $predicate[3] = $where['boolean'];
428
429
        return $predicate;
430
    }
431
432
    /**
433
     * Compile a where month clause.
434
     *
435
     * @param  IluminateBuilder  $query
436
     * @param  array  $where
437
     * @return array
438
     */
439
    protected function whereMonth(IluminateBuilder $query, $where)
440
    {
441
        $predicate = [];
442
443
        $where = $this->normalizeOperator($where);
444
445
        $predicate[0] = $query->aqb->dateMonth($this->normalizeColumn($query, $where['column']));
446
        $predicate[1] = $where['operator'];
447
        $predicate[2] = $this->parameter($query, $where['value']);
448
        $predicate[3] = $where['boolean'];
449
450
        return $predicate;
451
    }
452
453
454
    /**
455
     * Compile a where day clause.
456
     *
457
     * @param  IluminateBuilder  $query
458
     * @param  array  $where
459
     * @return array
460
     */
461
    protected function whereDay(IluminateBuilder $query, $where)
462
    {
463
        $predicate = [];
464
465
        $where = $this->normalizeOperator($where);
466
467
        $predicate[0] = $query->aqb->dateDay($this->normalizeColumn($query, $where['column']));
468
        $predicate[1] = $where['operator'];
469
        $predicate[2] = $this->parameter($query, $where['value']);
470
        $predicate[3] = $where['boolean'];
471
472
        return $predicate;
473
    }
474
475
    /**
476
     * Compile a where time clause.
477
     *
478
     * @param  IluminateBuilder  $query
479
     * @param  array  $where
480
     * @return array
481
     */
482
    protected function whereTime(IluminateBuilder $query, $where)
483
    {
484
        $predicate = [];
485
486
        $where = $this->normalizeOperator($where);
487
488
        $predicate[0] = $query->aqb->dateFormat($this->normalizeColumn($query, $where['column']), "%hh:%ii:%ss");
489
        $predicate[1] = $where['operator'];
490
        $predicate[2] = $this->parameter($query, $where['value']);
491
        $predicate[3] = $where['boolean'];
492
493
        return $predicate;
494
    }
495
}
496