Completed
Pull Request — master (#6747)
by Gabriel
09:15
created

Expr::mod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Query;
6
7
use function func_get_args;
8
use function implode;
9
use function is_array;
10
use function is_bool;
11
use function is_numeric;
12
use function is_string;
13
use function str_replace;
14
15
/**
16
 * This class is used to generate DQL expressions via a set of PHP static functions.
17
 *
18
 * @todo Rename: ExpressionBuilder
19
 */
20
class Expr
21
{
22
    /**
23
     * Creates a conjunction of the given boolean expressions.
24
     *
25
     * Example:
26
     *
27
     *     [php]
28
     *     // (u.type = ?1) AND (u.role = ?2)
29
     *     $expr->andX($expr->eq('u.type', ':1'), $expr->eq('u.role', ':2'));
30
     *
31
     * @param Expr\Comparison|Expr\Func|Expr\Orx|string $x Optional clause. Defaults to null, but requires at least one
32
     *                                                     defined when converting to string.
33
     *
34
     * @return Expr\Andx
35
     */
36 5
    public function andX($x = null)
37
    {
38 5
        return new Expr\Andx(func_get_args());
39
    }
40
41
    /**
42
     * Creates a disjunction of the given boolean expressions.
43
     *
44
     * Example:
45
     *
46
     *     [php]
47
     *     // (u.type = ?1) OR (u.role = ?2)
48
     *     $q->where($q->expr()->orX('u.type = ?1', 'u.role = ?2'));
49
     *
50
     * @param mixed $x Optional clause. Defaults to null, but requires
51
     *                 at least one defined when converting to string.
52
     *
53
     * @return Expr\Orx
54
     */
55 8
    public function orX($x = null)
56
    {
57 8
        return new Expr\Orx(func_get_args());
58
    }
59
60
    /**
61
     * Creates an ASCending order expression.
62
     *
63
     * @param mixed $expr
64
     *
65
     * @return Expr\OrderBy
66
     */
67 2
    public function asc($expr)
68
    {
69 2
        return new Expr\OrderBy($expr, 'ASC');
70
    }
71
72
    /**
73
     * Creates a DESCending order expression.
74
     *
75
     * @param mixed $expr
76
     *
77
     * @return Expr\OrderBy
78
     */
79 3
    public function desc($expr)
80
    {
81 3
        return new Expr\OrderBy($expr, 'DESC');
82
    }
83
84
    /**
85
     * Creates an equality comparison expression with the given arguments.
86
     *
87
     * First argument is considered the left expression and the second is the right expression.
88
     * When converted to string, it will generated a <left expr> = <right expr>. Example:
89
     *
90
     *     [php]
91
     *     // u.id = ?1
92
     *     $expr->eq('u.id', '?1');
93
     *
94
     * @param mixed $x Left expression.
95
     * @param mixed $y Right expression.
96
     *
97
     * @return Expr\Comparison
98
     */
99 27
    public function eq($x, $y)
100
    {
101 27
        return new Expr\Comparison($x, Expr\Comparison::EQ, $y);
102
    }
103
104
    /**
105
     * Creates an instance of Expr\Comparison, with the given arguments.
106
     * First argument is considered the left expression and the second is the right expression.
107
     * When converted to string, it will generated a <left expr> <> <right expr>. Example:
108
     *
109
     *     [php]
110
     *     // u.id <> ?1
111
     *     $q->where($q->expr()->neq('u.id', '?1'));
112
     *
113
     * @param mixed $x Left expression.
114
     * @param mixed $y Right expression.
115
     *
116
     * @return Expr\Comparison
117
     */
118 1
    public function neq($x, $y)
119
    {
120 1
        return new Expr\Comparison($x, Expr\Comparison::NEQ, $y);
121
    }
122
123
    /**
124
     * Creates an instance of Expr\Comparison, with the given arguments.
125
     * First argument is considered the left expression and the second is the right expression.
126
     * When converted to string, it will generated a <left expr> < <right expr>. Example:
127
     *
128
     *     [php]
129
     *     // u.id < ?1
130
     *     $q->where($q->expr()->lt('u.id', '?1'));
131
     *
132
     * @param mixed $x Left expression.
133
     * @param mixed $y Right expression.
134
     *
135
     * @return Expr\Comparison
136
     */
137 3
    public function lt($x, $y)
138
    {
139 3
        return new Expr\Comparison($x, Expr\Comparison::LT, $y);
140
    }
141
142
    /**
143
     * Creates an instance of Expr\Comparison, with the given arguments.
144
     * First argument is considered the left expression and the second is the right expression.
145
     * When converted to string, it will generated a <left expr> <= <right expr>. Example:
146
     *
147
     *     [php]
148
     *     // u.id <= ?1
149
     *     $q->where($q->expr()->lte('u.id', '?1'));
150
     *
151
     * @param mixed $x Left expression.
152
     * @param mixed $y Right expression.
153
     *
154
     * @return Expr\Comparison
155
     */
156 1
    public function lte($x, $y)
157
    {
158 1
        return new Expr\Comparison($x, Expr\Comparison::LTE, $y);
159
    }
160
161
    /**
162
     * Creates an instance of Expr\Comparison, with the given arguments.
163
     * First argument is considered the left expression and the second is the right expression.
164
     * When converted to string, it will generated a <left expr> > <right expr>. Example:
165
     *
166
     *     [php]
167
     *     // u.id > ?1
168
     *     $q->where($q->expr()->gt('u.id', '?1'));
169
     *
170
     * @param mixed $x Left expression.
171
     * @param mixed $y Right expression.
172
     *
173
     * @return Expr\Comparison
174
     */
175 2
    public function gt($x, $y)
176
    {
177 2
        return new Expr\Comparison($x, Expr\Comparison::GT, $y);
178
    }
179
180
    /**
181
     * Creates an instance of Expr\Comparison, with the given arguments.
182
     * First argument is considered the left expression and the second is the right expression.
183
     * When converted to string, it will generated a <left expr> >= <right expr>. Example:
184
     *
185
     *     [php]
186
     *     // u.id >= ?1
187
     *     $q->where($q->expr()->gte('u.id', '?1'));
188
     *
189
     * @param mixed $x Left expression.
190
     * @param mixed $y Right expression.
191
     *
192
     * @return Expr\Comparison
193
     */
194 1
    public function gte($x, $y)
195
    {
196 1
        return new Expr\Comparison($x, Expr\Comparison::GTE, $y);
197
    }
198
199
    /**
200
     * Creates an instance of AVG() function, with the given argument.
201
     *
202
     * @param mixed $x Argument to be used in AVG() function.
203
     *
204
     * @return Expr\Func
205
     */
206 1
    public function avg($x)
207
    {
208 1
        return new Expr\Func('AVG', [$x]);
209
    }
210
211
    /**
212
     * Creates an instance of MAX() function, with the given argument.
213
     *
214
     * @param mixed $x Argument to be used in MAX() function.
215
     *
216
     * @return Expr\Func
217
     */
218 2
    public function max($x)
219
    {
220 2
        return new Expr\Func('MAX', [$x]);
221
    }
222
223
    /**
224
     * Creates an instance of MIN() function, with the given argument.
225
     *
226
     * @param mixed $x Argument to be used in MIN() function.
227
     *
228
     * @return Expr\Func
229
     */
230 1
    public function min($x)
231
    {
232 1
        return new Expr\Func('MIN', [$x]);
233
    }
234
235
    /**
236
     * Creates an instance of COUNT() function, with the given argument.
237
     *
238
     * @param mixed $x Argument to be used in COUNT() function.
239
     *
240
     * @return Expr\Func
241
     */
242 1
    public function count($x)
243
    {
244 1
        return new Expr\Func('COUNT', [$x]);
245
    }
246
247
    /**
248
     * Creates an instance of COUNT(DISTINCT) function, with the given argument.
249
     *
250
     * @param mixed $x Argument to be used in COUNT(DISTINCT) function.
251
     *
252
     * @return string
253
     */
254 2
    public function countDistinct($x)
255
    {
256 2
        return 'COUNT(DISTINCT ' . implode(', ', func_get_args()) . ')';
257
    }
258
259
    /**
260
     * Creates an instance of EXISTS() function, with the given DQL Subquery.
261
     *
262
     * @param mixed $subquery DQL Subquery to be used in EXISTS() function.
263
     *
264
     * @return Expr\Func
265
     */
266 1
    public function exists($subquery)
267
    {
268 1
        return new Expr\Func('EXISTS', [$subquery]);
269
    }
270
271
    /**
272
     * Creates an instance of ALL() function, with the given DQL Subquery.
273
     *
274
     * @param mixed $subquery DQL Subquery to be used in ALL() function.
275
     *
276
     * @return Expr\Func
277
     */
278 2
    public function all($subquery)
279
    {
280 2
        return new Expr\Func('ALL', [$subquery]);
281
    }
282
283
    /**
284
     * Creates a SOME() function expression with the given DQL subquery.
285
     *
286
     * @param mixed $subquery DQL Subquery to be used in SOME() function.
287
     *
288
     * @return Expr\Func
289
     */
290 1
    public function some($subquery)
291
    {
292 1
        return new Expr\Func('SOME', [$subquery]);
293
    }
294
295
    /**
296
     * Creates an ANY() function expression with the given DQL subquery.
297
     *
298
     * @param mixed $subquery DQL Subquery to be used in ANY() function.
299
     *
300
     * @return Expr\Func
301
     */
302 1
    public function any($subquery)
303
    {
304 1
        return new Expr\Func('ANY', [$subquery]);
305
    }
306
307
    /**
308
     * Creates a negation expression of the given restriction.
309
     *
310
     * @param mixed $restriction Restriction to be used in NOT() function.
311
     *
312
     * @return Expr\Func
313
     */
314 2
    public function not($restriction)
315
    {
316 2
        return new Expr\Func('NOT', [$restriction]);
317
    }
318
319
    /**
320
     * Creates an ABS() function expression with the given argument.
321
     *
322
     * @param mixed $x Argument to be used in ABS() function.
323
     *
324
     * @return Expr\Func
325
     */
326 1
    public function abs($x)
327
    {
328 1
        return new Expr\Func('ABS', [$x]);
329
    }
330
331
    /**
332
     * Creates a MOD($x, $y) function expression to return the remainder of $x divided by $y.
333
     *
334
     * @param mixed $x
335
     * @param mixed $y
336
     */
337 1
    public function mod($x, $y): Expr\Func
0 ignored issues
show
introduced by
There must be exactly 1 whitespace between closing parenthesis and return type colon.
Loading history...
338
    {
339 1
        return new Expr\Func('MOD', array($x, $y));
0 ignored issues
show
Coding Style introduced by
Short array syntax must be used to define arrays
Loading history...
340
    }
341
342
    /**
343
     * Creates a product mathematical expression with the given arguments.
344
     *
345
     * First argument is considered the left expression and the second is the right expression.
346
     * When converted to string, it will generated a <left expr> * <right expr>. Example:
347
     *
348
     *     [php]
349
     *     // u.salary * u.percentAnnualSalaryIncrease
350
     *     $q->expr()->prod('u.salary', 'u.percentAnnualSalaryIncrease')
351
     *
352
     * @param mixed $x Left expression.
353
     * @param mixed $y Right expression.
354
     *
355
     * @return Expr\Math
356
     */
357 1
    public function prod($x, $y)
358
    {
359 1
        return new Expr\Math($x, '*', $y);
360
    }
361
362
    /**
363
     * Creates a difference mathematical expression with the given arguments.
364
     * First argument is considered the left expression and the second is the right expression.
365
     * When converted to string, it will generated a <left expr> - <right expr>. Example:
366
     *
367
     *     [php]
368
     *     // u.monthlySubscriptionCount - 1
369
     *     $q->expr()->diff('u.monthlySubscriptionCount', '1')
370
     *
371
     * @param mixed $x Left expression.
372
     * @param mixed $y Right expression.
373
     *
374
     * @return Expr\Math
375
     */
376 2
    public function diff($x, $y)
377
    {
378 2
        return new Expr\Math($x, '-', $y);
379
    }
380
381
    /**
382
     * Creates a sum mathematical expression with the given arguments.
383
     * First argument is considered the left expression and the second is the right expression.
384
     * When converted to string, it will generated a <left expr> + <right expr>. Example:
385
     *
386
     *     [php]
387
     *     // u.numChildren + 1
388
     *     $q->expr()->sum('u.numChildren', '1')
389
     *
390
     * @param mixed $x Left expression.
391
     * @param mixed $y Right expression.
392
     *
393
     * @return Expr\Math
394
     */
395 1
    public function sum($x, $y)
396
    {
397 1
        return new Expr\Math($x, '+', $y);
398
    }
399
400
    /**
401
     * Creates a quotient mathematical expression with the given arguments.
402
     * First argument is considered the left expression and the second is the right expression.
403
     * When converted to string, it will generated a <left expr> / <right expr>. Example:
404
     *
405
     *     [php]
406
     *     // u.total / u.period
407
     *     $expr->quot('u.total', 'u.period')
408
     *
409
     * @param mixed $x Left expression.
410
     * @param mixed $y Right expression.
411
     *
412
     * @return Expr\Math
413
     */
414 3
    public function quot($x, $y)
415
    {
416 3
        return new Expr\Math($x, '/', $y);
417
    }
418
419
    /**
420
     * Creates a SQRT() function expression with the given argument.
421
     *
422
     * @param mixed $x Argument to be used in SQRT() function.
423
     *
424
     * @return Expr\Func
425
     */
426 1
    public function sqrt($x)
427
    {
428 1
        return new Expr\Func('SQRT', [$x]);
429
    }
430
431
    /**
432
     * Creates an IN() expression with the given arguments.
433
     *
434
     * @param string $x Field in string format to be restricted by IN() function.
435
     * @param mixed  $y Argument to be used in IN() function.
436
     *
437
     * @return Expr\Func
438
     */
439 9
    public function in($x, $y)
440
    {
441 9
        if (is_array($y)) {
442 8
            foreach ($y as &$literal) {
443 8
                if (! ($literal instanceof Expr\Literal)) {
444 7
                    $literal = $this->quoteLiteral($literal);
445
                }
446
            }
447
        }
448
449 9
        return new Expr\Func($x . ' IN', (array) $y);
450
    }
451
452
    /**
453
     * Creates a NOT IN() expression with the given arguments.
454
     *
455
     * @param string $x Field in string format to be restricted by NOT IN() function.
456
     * @param mixed  $y Argument to be used in NOT IN() function.
457
     *
458
     * @return Expr\Func
459
     */
460 5
    public function notIn($x, $y)
461
    {
462 5
        if (is_array($y)) {
463 4
            foreach ($y as &$literal) {
464 4
                if (! ($literal instanceof Expr\Literal)) {
465 4
                    $literal = $this->quoteLiteral($literal);
466
                }
467
            }
468
        }
469
470 5
        return new Expr\Func($x . ' NOT IN', (array) $y);
471
    }
472
473
    /**
474
     * Creates an IS NULL expression with the given arguments.
475
     *
476
     * @param string $x Field in string format to be restricted by IS NULL.
477
     *
478
     * @return string
479
     */
480 3
    public function isNull($x)
481
    {
482 3
        return $x . ' IS NULL';
483
    }
484
485
    /**
486
     * Creates an IS NOT NULL expression with the given arguments.
487
     *
488
     * @param string $x Field in string format to be restricted by IS NOT NULL.
489
     *
490
     * @return string
491
     */
492 2
    public function isNotNull($x)
493
    {
494 2
        return $x . ' IS NOT NULL';
495
    }
496
497
    /**
498
     * Creates a LIKE() comparison expression with the given arguments.
499
     *
500
     * @param string $x Field in string format to be inspected by LIKE() comparison.
501
     * @param mixed  $y Argument to be used in LIKE() comparison.
502
     *
503
     * @return Expr\Comparison
504
     */
505 4
    public function like($x, $y)
506
    {
507 4
        return new Expr\Comparison($x, 'LIKE', $y);
508
    }
509
510
    /**
511
     * Creates a NOT LIKE() comparison expression with the given arguments.
512
     *
513
     * @param string $x Field in string format to be inspected by LIKE() comparison.
514
     * @param mixed  $y Argument to be used in LIKE() comparison.
515
     *
516
     * @return Expr\Comparison
517
     */
518 1
    public function notLike($x, $y)
519
    {
520 1
        return new Expr\Comparison($x, 'NOT LIKE', $y);
521
    }
522
523
    /**
524
     * Creates a CONCAT() function expression with the given arguments.
525
     *
526
     * @param mixed $x     First argument to be used in CONCAT() function.
527
     * @param mixed $y,... Other arguments to be used in CONCAT() function.
528
     *
529
     * @return Expr\Func
530
     */
531 1
    public function concat($x, $y)
532
    {
533 1
        return new Expr\Func('CONCAT', func_get_args());
534
    }
535
536
    /**
537
     * Creates a SUBSTRING() function expression with the given arguments.
538
     *
539
     * @param mixed    $x    Argument to be used as string to be cropped by SUBSTRING() function.
540
     * @param int      $from Initial offset to start cropping string. May accept negative values.
541
     * @param int|null $len  Length of crop. May accept negative values.
542
     *
543
     * @return Expr\Func
544
     */
545 2
    public function substring($x, $from, $len = null)
546
    {
547 2
        $args = [$x, $from];
548 2
        if ($len !== null) {
549 1
            $args[] = $len;
550
        }
551
552 2
        return new Expr\Func('SUBSTRING', $args);
553
    }
554
555
    /**
556
     * Creates a LOWER() function expression with the given argument.
557
     *
558
     * @param mixed $x Argument to be used in LOWER() function.
559
     *
560
     * @return Expr\Func A LOWER function expression.
561
     */
562 1
    public function lower($x)
563
    {
564 1
        return new Expr\Func('LOWER', [$x]);
565
    }
566
567
    /**
568
     * Creates an UPPER() function expression with the given argument.
569
     *
570
     * @param mixed $x Argument to be used in UPPER() function.
571
     *
572
     * @return Expr\Func An UPPER function expression.
573
     */
574 1
    public function upper($x)
575
    {
576 1
        return new Expr\Func('UPPER', [$x]);
577
    }
578
579
    /**
580
     * Creates a LENGTH() function expression with the given argument.
581
     *
582
     * @param mixed $x Argument to be used as argument of LENGTH() function.
583
     *
584
     * @return Expr\Func A LENGTH function expression.
585
     */
586 1
    public function length($x)
587
    {
588 1
        return new Expr\Func('LENGTH', [$x]);
589
    }
590
591
    /**
592
     * Creates a literal expression of the given argument.
593
     *
594
     * @param mixed $literal Argument to be converted to literal.
595
     *
596
     * @return Expr\Literal
597
     */
598 7
    public function literal($literal)
599
    {
600 7
        return new Expr\Literal($this->quoteLiteral($literal));
601
    }
602
603
    /**
604
     * Quotes a literal value, if necessary, according to the DQL syntax.
605
     *
606
     * @param mixed $literal The literal value.
607
     *
608
     * @return string
609
     */
610 18
    private function quoteLiteral($literal)
611
    {
612 18
        if (is_numeric($literal) && ! is_string($literal)) {
613 10
            return (string) $literal;
614 8
        } elseif (is_bool($literal)) {
615 1
            return $literal ? 'true' : 'false';
616
        }
617
618 7
        return "'" . str_replace("'", "''", $literal) . "'";
619
    }
620
621
    /**
622
     * Creates an instance of BETWEEN() function, with the given argument.
623
     *
624
     * @param mixed      $val Valued to be inspected by range values.
625
     * @param int|string $x   Starting range value to be used in BETWEEN() function.
626
     * @param int|string $y   End point value to be used in BETWEEN() function.
627
     *
628
     * @return Expr\Func A BETWEEN expression.
629
     */
630 1
    public function between($val, $x, $y)
631
    {
632 1
        return $val . ' BETWEEN ' . $x . ' AND ' . $y;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $val . ' BETWEEN ' . $x . ' AND ' . $y returns the type string which is incompatible with the documented return type Doctrine\ORM\Query\Expr\Func.
Loading history...
633
    }
634
635
    /**
636
     * Creates an instance of TRIM() function, with the given argument.
637
     *
638
     * @param mixed $x Argument to be used as argument of TRIM() function.
639
     *
640
     * @return Expr\Func a TRIM expression.
641
     */
642 1
    public function trim($x)
643
    {
644 1
        return new Expr\Func('TRIM', $x);
645
    }
646
647
    /**
648
     * Creates an instance of MEMBER OF function, with the given arguments.
649
     *
650
     * @param string $x Value to be checked
651
     * @param string $y Value to be checked against
652
     *
653
     * @return Expr\Comparison
654
     */
655 1
    public function isMemberOf($x, $y)
656
    {
657 1
        return new Expr\Comparison($x, 'MEMBER OF', $y);
658
    }
659
660
    /**
661
     * Creates an instance of INSTANCE OF function, with the given arguments.
662
     *
663
     * @param string $x Value to be checked
664
     * @param string $y Value to be checked against
665
     *
666
     * @return Expr\Comparison
667
     */
668 1
    public function isInstanceOf($x, $y)
669
    {
670 1
        return new Expr\Comparison($x, 'INSTANCE OF', $y);
671
    }
672
}
673