Passed
Push — master ( ef1328...91a1d1 )
by Bas
13:32 queued 09:25
created

CompilesWhereClauses::translateOperator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
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 Illuminate\Database\Query\JoinClause;
8
use LaravelFreelancerNL\Aranguent\Query\Builder;
9
10
trait CompilesWhereClauses
11
{
12
    /**
13
     * Compile the "where" portions of the query.
14
     *
15
     * @param Builder $builder
16
     *
17
     * @return Builder
18
     */
19 95
    protected function compileWheres(Builder $builder)
20
    {
21 95
        if (is_null($builder->wheres)) {
0 ignored issues
show
introduced by
The condition is_null($builder->wheres) is always false.
Loading history...
22
            return $builder;
23
        }
24
25 95
        $predicates = $this->compileWheresToArray($builder);
26
27 95
        if (count($predicates) > 0) {
28 78
            $builder->aqb = $builder->aqb->filter($predicates);
29
        }
30
31 95
        return $builder;
32
    }
33
34
    /**
35
     * Get an array of all the where clauses for the query.
36
     *
37
     * @param  IluminateBuilder  $query
38
     * @return array
39
     */
40 95
    protected function compileWheresToArray(IluminateBuilder $query): array
41
    {
42 95
        return collect($query->wheres)->map(function ($where) use ($query) {
43 78
            return $this->{"where{$where['type']}"}($query, $where);
44 95
        })->all();
45
    }
46
47
    protected function getOperatorByWhereType($type)
48
    {
49
        if (isset($this->whereTypeOperators[$type])) {
50
            return $this->whereTypeOperators[$type];
51
        }
52
53
        return '==';
54
    }
55
56
    /**
57
     * Determine if the given value is a raw expression.
58
     *
59
     * @param  mixed  $value
60
     * @return bool
61
     */
62 63
    public function isExpression($value)
63
    {
64 63
        return $value instanceof Expression;
65
    }
66
67
    /**
68
     * Get the appropriate query parameter place-holder for a value.
69
     *
70
     * @param  IluminateBuilder  $query
71
     * @param  mixed  $value
72
     * @return object
73
     */
74 63
    public function parameter(IluminateBuilder $query, $value)
75
    {
76 63
        return $this->isExpression($value) ? $this->getValue($value) : $query->aqb->bind($value);
0 ignored issues
show
Bug introduced by
It seems like getValue() 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

76
        return $this->isExpression($value) ? $this->/** @scrutinizer ignore-call */ getValue($value) : $query->aqb->bind($value);
Loading history...
77
    }
78
79 68
    protected function normalizeOperator($where)
80
    {
81 68
        if (isset($where['operator'])) {
82 68
            $where['operator'] = $this->translateOperator($where['operator']);
83
        }
84 68
        if (! isset($where['operator'])) {
85
            $where['operator'] = $this->getOperatorByWhereType($where['type']);
86
        }
87
88 68
            return $where;
89
    }
90
91
    /**
92
     * Translate sql operators to their AQL equivalent where possible.
93
     *
94
     * @param string $operator
95
     *
96
     * @return mixed|string
97
     */
98 68
    private function translateOperator(string $operator)
99
    {
100 68
        if (isset($this->operatorTranslations[strtolower($operator)])) {
101 65
            $operator = $this->operatorTranslations[$operator];
102
        }
103
104 68
        return $operator;
105
    }
106
107
108
    /**
109
     * Compile a basic where clause.
110
     *
111
     * @param  IluminateBuilder  $query
112
     * @param  array  $where
113
     * @return array
114
     */
115 53
    protected function whereBasic(IluminateBuilder $query, $where)
116
    {
117 53
        $predicate = [];
118
119 53
        $where = $this->normalizeOperator($where);
120
121 53
        $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

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