CompilesFilters::bitExpressionXor()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
4
5
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
6
use Illuminate\Database\Query\Expression;
7
use Illuminate\Database\Query\JoinClause;
8
use LaravelFreelancerNL\Aranguent\Query\Builder;
9
10
trait CompilesFilters
11
{
12
    /**
13
     * Compile the "having" portions of the query.
14
     *
15
     * @param  \Illuminate\Database\Query\Builder  $query
16
     * @return string
17
     */
18 8
    protected function compileHavings(IlluminateQueryBuilder $query)
19
    {
20 8
        return 'FILTER ' . $this->removeLeadingBoolean(collect($query->havings)->map(function ($having) use ($query) {
0 ignored issues
show
Bug introduced by
It seems like removeLeadingBoolean() 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

20
        return 'FILTER ' . $this->/** @scrutinizer ignore-call */ removeLeadingBoolean(collect($query->havings)->map(function ($having) use ($query) {
Loading history...
Bug introduced by
It seems like $query->havings can also be of type array; however, parameter $value of collect() does only seem to accept Illuminate\Contracts\Support\Arrayable, maybe add an additional type check? ( Ignorable by Annotation )

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

20
        return 'FILTER ' . $this->removeLeadingBoolean(collect(/** @scrutinizer ignore-type */ $query->havings)->map(function ($having) use ($query) {
Loading history...
21 8
            return $having['boolean'] . ' ' . $this->filter($query, $having);
22 8
        })->implode(' '));
23
    }
24
25
    /**
26
     * Get an array of all the where clauses for the query.
27
     *
28
     * @param  \Illuminate\Database\Query\Builder  $query
29
     * @return array<string>
30
     */
31 389
    protected function compileWheresToArray($query)
32
    {
33 389
        return collect($query->wheres)->map(function ($where) use ($query) {
0 ignored issues
show
Bug introduced by
$query->wheres of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

33
        return collect(/** @scrutinizer ignore-type */ $query->wheres)->map(function ($where) use ($query) {
Loading history...
34 274
            return $where['boolean'] . ' ' . $this->{"filter{$where['type']}"}($query, $where);
35 389
        })->all();
36
    }
37
38
    /**
39
     * Format the where clause statements into one string.
40
     *
41
     * @param IlluminateQueryBuilder $query
42
     * @param  array<mixed>  $aql
43
     * @return string
44
     *
45
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
46
     */
47 274
    protected function concatenateWhereClauses($query, $aql)
48
    {
49 274
        return 'FILTER ' . $this->removeLeadingBoolean(implode(' ', $aql));
50
    }
51
52
    /**
53
     * @param string $type
54
     * @return string
55
     */
56 4
    protected function getOperatorByWhereType($type)
57
    {
58 4
        if (isset($this->whereTypeOperators[$type])) {
59
            return $this->whereTypeOperators[$type];
60
        }
61
62 4
        return '==';
63
    }
64
65
66
    /**
67
     * Compile a single having clause.
68
     *
69
     * @param IlluminateQueryBuilder $query
70
     * @param array<mixed> $filter
71
     * @return string
72
     * @throws \Exception
73
     */
74 8
    protected function filter(IlluminateQueryBuilder $query, array $filter)
75
    {
76
        // If the having clause is "raw", we can just return the clause straight away
77
        // without doing any more processing on it. Otherwise, we will compile the
78
        // clause into SQL based on the components that make it up from builder.
79 8
        return match ($filter['type']) {
80 1
            'Raw' => $filter['sql'],
81 1
            'between' => $this->filterBetween($query, $filter),
82 1
            'Null' => $this->filterNull($query, $filter),
83 2
            'NotNull' => $this->filterNotNull($query, $filter),
84
            'bit' => $this->filterBit($query, $filter),
85
            'Expression' => $this->filterExpression($query, $filter),
86 1
            'Nested' => $this->compileNestedHavings($filter),
0 ignored issues
show
Bug introduced by
It seems like compileNestedHavings() 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

86
            'Nested' => $this->/** @scrutinizer ignore-call */ compileNestedHavings($filter),
Loading history...
87 8
            default => $this->filterBasic($query, $filter),
88 8
        };
89
    }
90
91
    /**
92
     * Compile a basic having|filter clause.
93
     *
94
     * @param IlluminateQueryBuilder $query
95
     * @param array<mixed> $filter
96
     * @return string
97
     * @throws \Exception
98
     */
99 241
    protected function filterBasic(IlluminateQueryBuilder $query, $filter)
100
    {
101 241
        $predicate = [];
102
103 241
        $filter = $this->normalizeOperator($filter);
104
105 241
        if (!$filter['column'] instanceof expression) {
106 239
            $column = $this->normalizeColumn($query, $filter['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

106
            /** @scrutinizer ignore-call */ 
107
            $column = $this->normalizeColumn($query, $filter['column']);
Loading history...
107
        }
108 241
        if ($filter['column'] instanceof expression) {
109 2
            $column = $filter['column']->getValue($this);
0 ignored issues
show
Bug introduced by
$this of type LaravelFreelancerNL\Aran...oncerns\CompilesFilters is incompatible with the type Illuminate\Database\Grammar expected by parameter $grammar of Illuminate\Database\Query\Expression::getValue(). ( Ignorable by Annotation )

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

109
            $column = $filter['column']->getValue(/** @scrutinizer ignore-type */ $this);
Loading history...
110
        }
111
112 241
        $predicate[0] = $column;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $column does not seem to be defined for all execution paths leading up to this point.
Loading history...
113 241
        $predicate[1] = $filter['operator'];
114 241
        $predicate[2] = $this->parameter($filter['value']);
0 ignored issues
show
Bug introduced by
It seems like parameter() 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

114
        /** @scrutinizer ignore-call */ 
115
        $predicate[2] = $this->parameter($filter['value']);
Loading history...
115
116 241
        return implode(" ", $predicate);
117
    }
118
119
120
    /**
121
     * Compile a "between" filter clause.
122
     *
123
     * @param IlluminateQueryBuilder $query
124
     * @param array<mixed> $filter
125
     * @return string
126
     * @throws \Exception
127
     */
128 3
    protected function filterBetween(IlluminateQueryBuilder $query, $filter): string
129
    {
130 3
        $predicate = [];
131
132 3
        [$minOperator, $maxOperator, $boolean] = $this->getBetweenOperators($filter['not']);
133
134 3
        $min = $this->parameter(reset($filter['values']));
135 3
        $max = $this->parameter(end($filter['values']));
136
137 3
        $normalizedColumn = $this->normalizeColumn($query, $filter['column']);
138
139 3
        $predicate[0][0] = $normalizedColumn;
140 3
        $predicate[0][1] = $minOperator;
141 3
        $predicate[0][2] = $min;
142
143 3
        $predicate[1][0] = $normalizedColumn;
144 3
        $predicate[1][1] = $maxOperator;
145 3
        $predicate[1][2] = $max;
146
147 3
        return implode(" ", $predicate[0]) . " " . $boolean . " " . implode(" ", $predicate[1]);
148
    }
149
150
    /**
151
     * Compile a "between columns" filter clause.
152
     *
153
     * @param IlluminateQueryBuilder $query
154
     * @param array<mixed> $filter
155
     * @return string
156
     * @throws \Exception
157
     */
158 1
    protected function filterBetweenColumns(IlluminateQueryBuilder $query, $filter)
159
    {
160 1
        $predicate = [];
161
162 1
        [$minOperator, $maxOperator, $boolean] = $this->getBetweenOperators($filter['not']);
163
164 1
        $column = $this->normalizeColumn($query, $filter['column']);
165
166 1
        $predicate[0][0] = $column;
167 1
        $predicate[0][1] = $minOperator;
168 1
        $predicate[0][2] = $this->normalizeColumn($query, reset($filter['values']));
169
170 1
        $predicate[1][0] = $column;
171 1
        $predicate[1][1] = $maxOperator;
172 1
        $predicate[1][2] = $this->normalizeColumn($query, end($filter['values']));
173
174 1
        return implode(" ", $predicate[0]) . " " . $boolean . " " . implode(" ", $predicate[1]);
175
    }
176
177
    /**
178
     * Compile a filter clause comparing two columns..
179
     *
180
     * @param IlluminateQueryBuilder $query
181
     * @param array<mixed> $filter
182
     * @return string
183
     * @throws \Exception
184
     */
185 56
    protected function filterColumn(IlluminateQueryBuilder $query, $filter)
186
    {
187 56
        $predicate = [];
188
189 56
        $filter = $this->normalizeOperator($filter);
190 56
        $predicate[0] = $this->normalizeColumn($query, $filter['first']);
191 56
        $predicate[1] = $filter['operator'];
192 56
        $predicate[2] = $this->normalizeColumn($query, $filter['second']);
193
194 56
        return implode(" ", $predicate);
195
    }
196
197
    /**
198
     * Compile a "filter null" clause.
199
     *
200
     * @param IlluminateQueryBuilder $query
201
     * @param array<mixed> $filter
202
     * @return string
203
     * @throws \Exception
204
     */
205 25
    protected function filterNull(IlluminateQueryBuilder $query, $filter)
206
    {
207 25
        $predicate = [];
208
209 25
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
210 25
        $predicate[1] = '==';
211 25
        $predicate[2] = "null";
212
213 25
        return implode(" ", $predicate);
214
    }
215
216
    /**
217
     * Compile a "filter not null" clause.
218
     *
219
     * @param IlluminateQueryBuilder $query
220
     * @param array<mixed> $filter
221
     * @return string
222
     * @throws \Exception
223
     */
224 20
    protected function filterNotNull(IlluminateQueryBuilder $query, $filter)
225
    {
226 20
        $predicate = [];
227
228 20
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
229 20
        $predicate[1] = '!=';
230 20
        $predicate[2] = "null";
231
232 20
        return implode(" ", $predicate);
233
    }
234
235
    /**
236
     * Compile a "filter in" clause.
237
     *
238
     * @param  IlluminateQueryBuilder  $query
239
     * @param  array<mixed>  $filter
240
     * @return string
241
     */
242 19
    protected function filterIn(IlluminateQueryBuilder $query, $filter)
243
    {
244 19
        $predicate = [];
245
246 19
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
247 19
        $predicate[1] = 'IN';
248 19
        $predicate[2] = $this->parameter($filter['values']);
249
250 19
        return implode(" ", $predicate);
251
    }
252
253
    /**
254
     * Compile a "filter in raw" clause.
255
     *
256
     * For safety, filterIntegerInRaw ensures this method is only used with integer values.
257
     *
258
     * @param IlluminateQueryBuilder $query
259
     * @param array<mixed> $filter
260
     * @return string
261
     * @throws \Exception
262
     */
263 1
    protected function filterInRaw(IlluminateQueryBuilder $query, array $filter): string
264
    {
265 1
        $predicate = [];
266
267 1
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
268 1
        $predicate[1] = 'IN';
269 1
        $predicate[2] = '[' . implode(', ', $filter['values']) . ']';
270
271 1
        return implode(" ", $predicate);
272
    }
273
274
    /**
275
     * Compile a "filter not in" clause.
276
     *
277
     * @param IlluminateQueryBuilder $query
278
     * @param array<mixed> $filter
279
     * @return string
280
     * @throws \Exception
281
     */
282 1
    protected function filterNotIn(IlluminateQueryBuilder $query, array $filter): string
283
    {
284 1
        $predicate = [];
285
286 1
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
287 1
        $predicate[1] = 'NOT IN';
288 1
        $predicate[2] = $this->parameter($filter['values']);
289
290 1
        return implode(" ", $predicate);
291
    }
292
293
    /**
294
     * Compile a "filter not in raw" clause.
295
     *
296
     * For safety, filterIntegerInRaw ensures this method is only used with integer values.
297
     *
298
     * @param  IlluminateQueryBuilder  $query
299
     * @param  array<mixed>  $filter
300
     * @return string
301
     */
302 1
    protected function filterNotInRaw(IlluminateQueryBuilder $query, array $filter): string
303
    {
304 1
        $predicate = [];
305
306 1
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
307 1
        $predicate[1] = 'NOT IN';
308 1
        $predicate[2] = '[' . implode(', ', $filter['values']) . ']';
309
310 1
        return implode(" ", $predicate);
311
    }
312
313
    /**
314
     * Compile a "filter JSON contains" clause.
315
     *
316
     * @param IlluminateQueryBuilder $query
317
     * @param array<mixed> $filter
318
     * @return string
319
     * @throws \Exception
320
     */
321 1
    protected function filterJsonContains(IlluminateQueryBuilder $query, $filter)
322
    {
323 1
        $predicate = [];
324
325 1
        $operator = $filter['not'] ? 'NOT IN' : 'IN';
326
327 1
        $predicate[0] = $this->parameter($filter['value']);
328 1
        $predicate[1] = $operator;
329 1
        $predicate[2] = $this->normalizeColumn($query, $filter['column']);
330
331 1
        return implode(" ", $predicate);
332
    }
333
334
    /**
335
     * Compile a "filterJsonLength" clause.
336
     *
337
     * @param  IlluminateQueryBuilder  $query
338
     * @param  array<mixed>  $filter
339
     * @return string
340
     */
341 1
    protected function filterJsonLength(IlluminateQueryBuilder $query, array $filter): string
342
    {
343 1
        $predicate = [];
344
345 1
        $filter = $this->normalizeOperator($filter);
346
347 1
        $column = $this->normalizeColumn($query, $filter['column']);
348
349 1
        $predicate[0] = "LENGTH($column)";
350 1
        $predicate[1] = $filter['operator'];
351 1
        $predicate[2] = $this->parameter($filter['value']);
352
353 1
        return implode(" ", $predicate);
354
    }
355
356
    /**
357
     * @param array<mixed> $filter
358
     * @return mixed
359
     *
360
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
361
     */
362
    protected function filterExpression(IlluminateQueryBuilder $query, $filter)
363
    {
364
        return $filter['column']->getValue($this);
365
    }
366
367
    /**
368
     * Compile a filter date clause.
369
     *
370
     * @param IlluminateQueryBuilder $query
371
     * @param array<mixed> $filter
372
     * @return string
373
     * @throws \Exception
374
     */
375 1
    protected function filterDate(IlluminateQueryBuilder $query, $filter)
376
    {
377 1
        $predicate = [];
378
379 1
        $filter = $this->normalizeOperator($filter);
380 1
        $predicate[0] = 'DATE_FORMAT(' . $this->normalizeColumn($query, $filter['column']) . ', "%yyyy-%mm-%dd")';
381 1
        $predicate[1] = $filter['operator'];
382 1
        $predicate[2] = $this->parameter($filter['value']);
383
384 1
        return implode(' ', $predicate);
385
    }
386
387
    /**
388
     * Compile a filter year clause.
389
     *
390
     * @param IlluminateQueryBuilder $query
391
     * @param array<mixed> $filter
392
     * @return string
393
     * @throws \Exception
394
     */
395 1
    protected function filterYear(IlluminateQueryBuilder $query, $filter)
396
    {
397 1
        $predicate = [];
398
399 1
        $filter = $this->normalizeOperator($filter);
400
401 1
        $predicate[0] = 'DATE_YEAR(' . $this->normalizeColumn($query, $filter['column']) . ')';
402 1
        $predicate[1] = $filter['operator'];
403 1
        $predicate[2] = $this->parameter($filter['value']);
404
405 1
        return implode(' ', $predicate);
406
    }
407
408
    /**
409
     * Compile a filter month clause.
410
     *
411
     * @param IlluminateQueryBuilder $query
412
     * @param array<mixed> $filter
413
     * @return string
414
     * @throws \Exception
415
     */
416 4
    protected function filterLike(IlluminateQueryBuilder $query, $filter)
417
    {
418 4
        $column =  $this->normalizeColumn($query, $filter['column']);
419 4
        $value = $this->parameter($filter['value']);
420
421 4
        $predicate = [];
422
423 4
        $filter = $this->normalizeOperator($filter);
424
425 4
        $predicate[0] = ($filter['caseSensitive']) ? $column : 'LOWER(' . $column . ')';
426 4
        $predicate[1] = 'LIKE';
427 4
        $predicate[2] = ($filter['caseSensitive']) ? $value : 'LOWER(' . $value . ')';
428
429 4
        $result = implode(' ', $predicate);
430
431 4
        if ($filter['not']) {
432 2
            $result = 'NOT (' . $result . ')';
433
        }
434
435 4
        return $result;
436
    }
437
438
    /**
439
     * Compile a filter month clause.
440
     *
441
     * @param IlluminateQueryBuilder $query
442
     * @param array<mixed> $filter
443
     * @return string
444
     * @throws \Exception
445
     */
446 1
    protected function filterMonth(IlluminateQueryBuilder $query, $filter)
447
    {
448 1
        $predicate = [];
449
450 1
        $filter = $this->normalizeOperator($filter);
451
452 1
        $predicate[0] =  'DATE_MONTH(' . $this->normalizeColumn($query, $filter['column']) . ')';
453 1
        $predicate[1] = $filter['operator'];
454 1
        $predicate[2] = $this->parameter($filter['value']);
455
456 1
        return implode(' ', $predicate);
457
    }
458
459
460
    /**
461
     * Compile a filter day clause.
462
     *
463
     * @param IlluminateQueryBuilder $query
464
     * @param array<mixed> $filter
465
     * @return string
466
     * @throws \Exception
467
     */
468 1
    protected function filterDay(IlluminateQueryBuilder $query, $filter)
469
    {
470 1
        $predicate = [];
471
472 1
        $filter = $this->normalizeOperator($filter);
473
474 1
        $predicate[0] = 'DATE_DAY(' . $this->normalizeColumn($query, $filter['column']) . ')';
475 1
        $predicate[1] = $filter['operator'];
476 1
        $predicate[2] = $this->parameter($filter['value']);
477
478 1
        return implode(' ', $predicate);
479
    }
480
481
    /**
482
     * Compile a filter time clause.
483
     *
484
     * @param  IlluminateQueryBuilder  $query
485
     * @param  array<mixed>  $filter
486
     * @return string
487
     */
488 1
    protected function filterTime(IlluminateQueryBuilder $query, $filter)
489
    {
490 1
        $predicate = [];
491
492 1
        $filter = $this->normalizeOperator($filter);
493
494 1
        $predicate[0] = 'DATE_FORMAT(' . $this->normalizeColumn($query, $filter['column']) . ", '%hh:%ii:%ss')";
495 1
        $predicate[1] = $filter['operator'];
496 1
        $predicate[2] = $this->parameter($filter['value']);
497
498 1
        return implode(' ', $predicate);
499
    }
500
501
    /**
502
     * Compile a filter condition with a sub-select.
503
     *
504
     * @param IlluminateQueryBuilder $query
505
     * @param array<mixed> $filter
506
     * @return string
507
     * @throws \Exception
508
     */
509 1
    protected function filterSub(IlluminateQueryBuilder $query, $filter)
510
    {
511 1
        $predicate = [];
512
513 1
        $filter = $this->normalizeOperator($filter);
514
515 1
        $predicate[0] = $this->normalizeColumn($query, $filter['column']);
516 1
        $predicate[1] = $filter['operator'];
517 1
        $predicate[2] = $filter['subquery'];
518
519 1
        return implode(' ', $predicate);
520
    }
521
522
    /**
523
     * Compile a filter exists clause.
524
     *
525
     * @param  \Illuminate\Database\Query\Builder  $query
526
     * @param  array<mixed>  $filter
527
     * @return string
528
     *
529
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
530
     */
531 14
    protected function filterExists(IlluminateQueryBuilder $query, $filter)
532
    {
533 14
        return 'LENGTH(' . $filter['subquery'] . ') > 0';
534
    }
535
536
    /**
537
     * Compile a filter exists clause.
538
     *
539
     * @param  \Illuminate\Database\Query\Builder  $query
540
     * @param  array<mixed>  $filter
541
     * @return string
542
     *
543
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
544
     */
545 12
    protected function filterNotExists(IlluminateQueryBuilder $query, $filter)
546
    {
547 12
        return 'LENGTH(' . $filter['subquery'] . ') == 0';
548
    }
549
550
    /**
551
     * Compile a nested where clause.
552
     *
553
     * @param  \Illuminate\Database\Query\Builder  $query
554
     * @param  array<mixed>  $filter
555
     * @return string
556
     *
557
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
558
     */
559 52
    protected function filterNested(IlluminateQueryBuilder $query, $filter)
560
    {
561
        // Here we will calculate what portion of the string we need to remove. If this
562
        // is a join clause query, we need to remove the "on" portion of the SQL and
563
        // if it is a normal query we need to take the leading "where" of queries.
564 52
        $offset = $filter['query'] instanceof JoinClause ? 3 : 6;
565
566 52
        return '(' . substr($this->compileWheres($filter['query']), $offset) . ')';
0 ignored issues
show
Bug introduced by
The method compileWheres() does not exist on LaravelFreelancerNL\Aran...oncerns\CompilesFilters. Did you maybe mean compileWheresToArray()? ( Ignorable by Annotation )

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

566
        return '(' . substr($this->/** @scrutinizer ignore-call */ compileWheres($filter['query']), $offset) . ')';

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
567
    }
568
569
570
    /**
571
     * Compile a having clause involving a bit operator.
572
     *
573
     * @param IlluminateQueryBuilder $query
574
     * @param array<mixed> $filter
575
     * @return string
576
     * @throws \Exception
577
     */
578
    protected function filterBit(IlluminateQueryBuilder $query, $filter)
579
    {
580
        $column = $this->normalizeColumn($query, $filter['column']);
581
        $value = $this->parameter($filter['value']);
582
583
        $bitExpression = match ($filter['operator']) {
584
            '|' => $this->bitExpressionOr($column, $value),
585
            '^' => $this->bitExpressionXor($column, $value),
586
            '~' => $this->bitExpressionNegate($column),
587
            '&~' => $this->bitExpressionNegatedAnd($column, $value),
588
            '<<' => $this->bitExpressionLeftShift($column, $value),
589
            '>>' => $this->bitExpressionRightShift($column, $value),
590
            default =>  $this->bitExpressionAnd($column, $value),
591
        };
592
593
        return '(' . $bitExpression . ') != 0';
594
    }
595
596
    protected function bitExpressionAnd(string $column, int|string $value): string
597
    {
598
        return 'BIT_AND(' . $column . ', ' . $value . ')';
599
    }
600
601
    protected function bitExpressionOr(string $column, int|string $value): string
602
    {
603
        return 'BIT_AND(' . $column . ', ' . $value . ')';
604
    }
605
606
    protected function bitExpressionXor(string $column, int|string $value): string
607
    {
608
        return 'BIT_XOR(' . $column . ', ' . $value . ')';
609
    }
610
611
    protected function bitExpressionNegate(string $column): string
612
    {
613
        return 'BIT_NEGATE(' . $column . ', BIT_POPCOUNT(' . $column . '))';
614
    }
615
616
    protected function bitExpressionNegatedAnd(string $column, int|string $value): string
617
    {
618
        return 'BIT_AND(' . $column . ', BIT_NEGATE(' . $value . ', BIT_POPCOUNT(' . $value . '))';
619
    }
620
621
    protected function bitExpressionLeftShift(string $column, int|string $value): string
622
    {
623
        return 'BIT_SHIFT_LEFT(' . $column . ',  ' . $value . ', BIT_POPCOUNT(' . $column . '))';
624
    }
625
626
    protected function bitExpressionRightShift(string $column, int|string $value): string
627
    {
628
        return 'BIT_SHIFT_RIGHT(' . $column . ',  ' . $value . ', BIT_POPCOUNT(' . $column . '))';
629
    }
630
631
    /**
632
     * Generate operators for between and 'not between'
633
     * @param  bool  $notBetween
634
     * @return string[]
635
     */
636 4
    protected function getBetweenOperators(bool $notBetween)
637
    {
638 4
        $minOperator = '>=';
639 4
        $maxOperator = '<=';
640 4
        $boolean = 'AND';
641
642 4
        if ($notBetween) {
643 1
            $minOperator = '<';
644 1
            $maxOperator = '>';
645 1
            $boolean = 'OR';
646
        }
647
648 4
        return [$minOperator, $maxOperator, $boolean];
649
    }
650
651
    /**
652
     * @param array<mixed> $filter
653
     * @return array<mixed>
654
     */
655 262
    protected function normalizeOperator($filter)
656
    {
657 262
        if (isset($filter['operator'])) {
658 260
            $filter['operator'] = $this->translateOperator($filter['operator']);
0 ignored issues
show
Bug introduced by
It seems like translateOperator() 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

658
            /** @scrutinizer ignore-call */ 
659
            $filter['operator'] = $this->translateOperator($filter['operator']);
Loading history...
659
        }
660 262
        if (!isset($filter['operator'])) {
661 4
            $filter['operator'] = $this->getOperatorByWhereType($filter['type']);
662
        }
663
664 262
        return $filter;
665
    }
666
}
667