Expr   F
last analyzed

Complexity

Total Complexity 131

Size/Duplication

Total Lines 1642
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 95.67%

Importance

Changes 0
Metric Value
wmc 131
lcom 1
cbo 5
dl 0
loc 1642
ccs 265
cts 277
cp 0.9567
rs 0.8
c 0
b 0
f 0

102 Methods

Rating   Name   Duplication   Size   Complexity  
A ceil() 0 4 1
A cmp() 0 4 1
A concat() 0 4 1
A __construct() 0 6 1
A abs() 0 4 1
A add() 0 4 1
A addAnd() 0 10 2
A addOr() 0 10 2
A addToSet() 0 4 1
A allElementsTrue() 0 4 1
A anyElementTrue() 0 4 1
A arrayElemAt() 0 4 1
A avg() 0 4 1
A case() 0 8 1
A concatArrays() 0 4 1
A cond() 0 4 1
A convertExpression() 0 14 3
A dateToString() 0 4 1
A dayOfMonth() 0 4 1
A dayOfWeek() 0 4 1
A dayOfYear() 0 4 1
A default() 0 12 2
A divide() 0 4 1
A eq() 0 4 1
A exp() 0 4 1
A expr() 0 4 1
A expression() 0 7 1
A field() 0 7 1
A filter() 0 4 1
A first() 0 4 1
A floor() 0 4 1
A getExpression() 0 4 1
A gt() 0 4 1
A gte() 0 4 1
A hour() 0 4 1
A ifNull() 0 4 1
A in() 0 4 1
A indexOfArray() 0 13 3
A indexOfBytes() 0 13 3
A indexOfCP() 0 13 3
A isArray() 0 4 1
A isoDayOfWeek() 0 4 1
A isoWeek() 0 4 1
A isoWeekYear() 0 4 1
A last() 0 4 1
A let() 0 4 1
A literal() 0 4 1
A ln() 0 4 1
A log() 0 4 1
A log10() 0 4 1
A lt() 0 4 1
A lte() 0 4 1
A map() 0 4 1
A max() 0 4 1
A meta() 0 4 1
A millisecond() 0 4 1
A min() 0 4 1
A minute() 0 4 1
A mod() 0 4 1
A month() 0 4 1
A multiply() 0 4 1
A ne() 0 4 1
A not() 0 4 1
A pow() 0 4 1
A push() 0 4 1
A range() 0 4 1
A reduce() 0 4 1
A reverseArray() 0 4 1
A second() 0 4 1
A setDifference() 0 4 1
A setEquals() 0 4 1
A setIntersection() 0 4 1
A setIsSubset() 0 4 1
A setUnion() 0 4 1
A size() 0 4 1
A slice() 0 8 2
A split() 0 4 1
A sqrt() 0 4 1
A stdDevPop() 0 6 2
A stdDevSamp() 0 6 2
A strcasecmp() 0 4 1
A strLenBytes() 0 4 1
A strLenCP() 0 4 1
A substr() 0 4 1
A substrBytes() 0 4 1
A substrCP() 0 4 1
A subtract() 0 4 1
A sum() 0 4 1
A toLower() 0 4 1
A toUpper() 0 4 1
A trunc() 0 4 1
A type() 0 4 1
A week() 0 4 1
A year() 0 4 1
A zip() 0 12 3
A ensureArray() 0 17 5
A getDocumentPersister() 0 4 1
A operator() 0 10 2
A requiresCurrentField() 0 6 3
A requiresSwitchStatement() 0 12 5
A switch() 0 6 1
A then() 0 18 3

How to fix   Complexity   

Complex Class

Complex classes like Expr often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Expr, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB\Aggregation;
6
7
use BadMethodCallException;
8
use Doctrine\ODM\MongoDB\DocumentManager;
9
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
10
use Doctrine\ODM\MongoDB\Persisters\DocumentPersister;
11
use Doctrine\ODM\MongoDB\Types\Type;
12
use Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
13
use LogicException;
14
use function array_map;
15
use function array_merge;
16
use function assert;
17
use function func_get_args;
18
use function is_array;
19
use function is_string;
20
use function substr;
21
22
/**
23
 * Fluent interface for building aggregation pipelines.
24
 */
25
class Expr
26
{
27
    /** @var DocumentManager */
28
    private $dm;
29
30
    /** @var ClassMetadata */
31
    private $class;
32
33
    /** @var array */
34
    private $expr = [];
35
36
    /**
37
     * The current field we are operating on.
38
     *
39
     * @var string
40
     */
41
    private $currentField;
42
43
    /** @var array|null */
44
    private $switchBranch;
45
46
    /**
47
     * @inheritDoc
48
     */
49 378
    public function __construct(DocumentManager $dm, ClassMetadataInterface $class)
50
    {
51 378
        assert($class instanceof ClassMetadata);
52 378
        $this->dm    = $dm;
53 378
        $this->class = $class;
54 378
    }
55
56
    /**
57
     * Returns the absolute value of a number.
58
     *
59
     * The <number> argument can be any valid expression as long as it resolves
60
     * to a number.
61
     *
62
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/abs/
63
     *
64
     * @param mixed|self $number
65
     */
66 3
    public function abs($number) : self
67
    {
68 3
        return $this->operator('$abs', $number);
69
    }
70
71
    /**
72
     * Adds numbers together or adds numbers and a date. If one of the arguments
73
     * is a date, $add treats the other arguments as milliseconds to add to the
74
     * date.
75
     *
76
     * The arguments can be any valid expression as long as they resolve to
77
     * either all numbers or to numbers and a date.
78
     *
79
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/add/
80
     *
81
     * @param mixed|self $expression1
82
     * @param mixed|self $expression2
83
     * @param mixed|self ...$expressions Additional expressions
84
     */
85 15
    public function add($expression1, $expression2, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expression2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
86
    {
87 15
        return $this->operator('$add', func_get_args());
88
    }
89
90
    /**
91
     * Adds one or more $and clauses to the current expression.
92
     *
93
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/and/
94
     *
95
     * @param array|self $expression
96
     * @param array|self ...$expressions
97
     */
98 1
    public function addAnd($expression, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
99
    {
100 1
        if (! isset($this->expr['$and'])) {
101 1
            $this->expr['$and'] = [];
102
        }
103
104 1
        $this->expr['$and'] = array_merge($this->expr['$and'], array_map([$this, 'ensureArray'], func_get_args()));
105
106 1
        return $this;
107
    }
108
109
    /**
110
     * Adds one or more $or clause to the current expression.
111
     *
112
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/or/
113
     *
114
     * @param array|self $expression
115
     * @param array|self ...$expressions
116
     */
117
    public function addOr($expression, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
118
    {
119
        if (! isset($this->expr['$or'])) {
120
            $this->expr['$or'] = [];
121
        }
122
123
        $this->expr['$or'] = array_merge($this->expr['$or'], array_map([$this, 'ensureArray'], func_get_args()));
124
125
        return $this;
126
    }
127
128
    /**
129
     * Returns an array of all unique values that results from applying an
130
     * expression to each document in a group of documents that share the same
131
     * group by key. Order of the elements in the output array is unspecified.
132
     *
133
     * AddToSet is an accumulator operation only available in the group stage.
134
     *
135
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/addToSet/
136
     *
137
     * @param mixed|self $expression
138
     */
139 2
    public function addToSet($expression) : self
140
    {
141 2
        return $this->operator('$addToSet', $expression);
142
    }
143
144
    /**
145
     * Evaluates an array as a set and returns true if no element in the array
146
     * is false. Otherwise, returns false. An empty array returns true.
147
     *
148
     * The expression must resolve to an array.
149
     *
150
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/allElementsTrue/
151
     *
152
     * @param mixed|self $expression
153
     */
154 3
    public function allElementsTrue($expression) : self
155
    {
156 3
        return $this->operator('$allElementsTrue', $expression);
157
    }
158
159
    /**
160
     * Evaluates an array as a set and returns true if any of the elements are
161
     * true and false otherwise. An empty array returns false.
162
     *
163
     * The expression must resolve to an array.
164
     *
165
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/anyElementTrue/
166
     *
167
     * @param array|self $expression
168
     */
169 3
    public function anyElementTrue($expression) : self
170
    {
171 3
        return $this->operator('$anyElementTrue', $expression);
172
    }
173
174
    /**
175
     * Returns the element at the specified array index.
176
     *
177
     * The <array> expression can be any valid expression as long as it resolves
178
     * to an array.
179
     * The <idx> expression can be any valid expression as long as it resolves
180
     * to an integer.
181
     *
182
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/arrayElemAt/
183
     *
184
     * @param mixed|self $array
185
     * @param mixed|self $index
186
     */
187 3
    public function arrayElemAt($array, $index) : self
188
    {
189 3
        return $this->operator('$arrayElemAt', [$array, $index]);
190
    }
191
192
    /**
193
     * Returns the average value of the numeric values that result from applying
194
     * a specified expression to each document in a group of documents that
195
     * share the same group by key. Ignores nun-numeric values.
196
     *
197
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/avg/
198
     *
199
     * @param mixed|self $expression
200
     */
201 10
    public function avg($expression) : self
202
    {
203 10
        return $this->operator('$avg', $expression);
204
    }
205
206
    /**
207
     * Adds a case statement for a branch of the $switch operator.
208
     *
209
     * Requires {@link switch()} to be called first. The argument can be any
210
     * valid expression that resolves to a boolean. If the result is not a
211
     * boolean, it is coerced to a boolean value.
212
     *
213
     * @param mixed|self $expression
214
     */
215 6
    public function case($expression) : self
216
    {
217 6
        $this->requiresSwitchStatement(static::class . '::case');
218
219 4
        $this->switchBranch = ['case' => $expression];
220
221 4
        return $this;
222
    }
223
224
    /**
225
     * Returns the smallest integer greater than or equal to the specified number.
226
     *
227
     * The <number> expression can be any valid expression as long as it
228
     * resolves to a number.
229
     *
230
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/ceil/
231
     *
232
     * @param mixed|self $number
233
     */
234 3
    public function ceil($number) : self
235
    {
236 3
        return $this->operator('$ceil', $number);
237
    }
238
239
    /**
240
     * Compares two values and returns:
241
     * -1 if the first value is less than the second.
242
     * 1 if the first value is greater than the second.
243
     * 0 if the two values are equivalent.
244
     *
245
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/cmp/
246
     *
247
     * @param mixed|self $expression1
248
     * @param mixed|self $expression2
249
     */
250 3
    public function cmp($expression1, $expression2) : self
251
    {
252 3
        return $this->operator('$cmp', [$expression1, $expression2]);
253
    }
254
255
    /**
256
     * Concatenates strings and returns the concatenated string.
257
     *
258
     * The arguments can be any valid expression as long as they resolve to
259
     * strings. If the argument resolves to a value of null or refers to a field
260
     * that is missing, $concat returns null.
261
     *
262
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/concat/
263
     *
264
     * @param mixed|self $expression1
265
     * @param mixed|self $expression2
266
     * @param mixed|self ...$expressions Additional expressions
267
     */
268 9
    public function concat($expression1, $expression2, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expression2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
269
    {
270 9
        return $this->operator('$concat', func_get_args());
271
    }
272
273
    /**
274
     * Concatenates arrays to return the concatenated array.
275
     *
276
     * The <array> expressions can be any valid expression as long as they
277
     * resolve to an array.
278
     *
279
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/concatArrays/
280
     *
281
     * @param mixed|self $array1
282
     * @param mixed|self $array2
283
     * @param mixed|self ...$arrays Additional expressions
284
     */
285 6
    public function concatArrays($array1, $array2, ...$arrays) : self
0 ignored issues
show
Unused Code introduced by
The parameter $array1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $array2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $arrays is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
286
    {
287 6
        return $this->operator('$concatArrays', func_get_args());
288
    }
289
290
    /**
291
     * Evaluates a boolean expression to return one of the two specified return
292
     * expressions.
293
     *
294
     * The arguments can be any valid expression.
295
     *
296
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/cond/
297
     *
298
     * @param mixed|self $if
299
     * @param mixed|self $then
300
     * @param mixed|self $else
301
     */
302 10
    public function cond($if, $then, $else) : self
303
    {
304 10
        return $this->operator('$cond', ['if' => $if, 'then' => $then, 'else' => $else]);
305
    }
306
307
    /**
308
     * Converts an expression object into an array, recursing into nested items
309
     *
310
     * For expression objects, it calls getExpression on the expression object.
311
     * For arrays, it recursively calls itself for each array item. Other values
312
     * are returned directly.
313
     *
314
     * @internal
315
     *
316
     * @param mixed|self $expression
317
     *
318
     * @return string|array
319
     */
320 1
    public static function convertExpression($expression)
321
    {
322 1
        if (is_array($expression)) {
323
            return array_map(static function ($expression) {
324
                return static::convertExpression($expression);
325
            }, $expression);
326
        }
327
328 1
        if ($expression instanceof self) {
329 1
            return $expression->getExpression();
330
        }
331
332
        return $expression;
333
    }
334
335
    /**
336
     * Converts a date object to a string according to a user-specified format.
337
     *
338
     * The format string can be any string literal, containing 0 or more format
339
     * specifiers.
340
     * The date argument can be any expression as long as it resolves to a date.
341
     *
342
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dateToString/
343
     *
344
     * @param mixed|self $expression
345
     */
346 3
    public function dateToString(string $format, $expression) : self
347
    {
348 3
        return $this->operator('$dateToString', ['format' => $format, 'date' => $expression]);
349
    }
350
351
    /**
352
     * Returns the day of the month for a date as a number between 1 and 31.
353
     *
354
     * The argument can be any expression as long as it resolves to a date.
355
     *
356
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfMonth/
357
     *
358
     * @param mixed|self $expression
359
     */
360 7
    public function dayOfMonth($expression) : self
361
    {
362 7
        return $this->operator('$dayOfMonth', $expression);
363
    }
364
365
    /**
366
     * Returns the day of the week for a date as a number between 1 (Sunday) and
367
     * 7 (Saturday).
368
     *
369
     * The argument can be any expression as long as it resolves to a date.
370
     *
371
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfWeek/
372
     *
373
     * @param mixed|self $expression
374
     */
375 7
    public function dayOfWeek($expression) : self
376
    {
377 7
        return $this->operator('$dayOfWeek', $expression);
378
    }
379
380
    /**
381
     * Returns the day of the year for a date as a number between 1 and 366.
382
     *
383
     * The argument can be any expression as long as it resolves to a date.
384
     *
385
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfYear/
386
     *
387
     * @param mixed|self $expression
388
     */
389 3
    public function dayOfYear($expression) : self
390
    {
391 3
        return $this->operator('$dayOfYear', $expression);
392
    }
393
394
    /**
395
     * Adds a default statement for the current $switch operator.
396
     *
397
     * Requires {@link switch()} to be called first. The argument can be any
398
     * valid expression.
399
     *
400
     * Note: if no default is specified and no branch evaluates to true, the
401
     * $switch operator throws an error.
402
     *
403
     * @param mixed|self $expression
404
     */
405 4
    public function default($expression) : self
406
    {
407 4
        $this->requiresSwitchStatement(static::class . '::default');
408
409 2
        if ($this->currentField) {
410
            $this->expr[$this->currentField]['$switch']['default'] = $this->ensureArray($expression);
411
        } else {
412 2
            $this->expr['$switch']['default'] = $this->ensureArray($expression);
413
        }
414
415 2
        return $this;
416
    }
417
418
    /**
419
     * Divides one number by another and returns the result. The first argument
420
     * is divided by the second argument.
421
     *
422
     * The arguments can be any valid expression as long as the resolve to numbers.
423
     *
424
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/divide/
425
     *
426
     * @param mixed|self $expression1
427
     * @param mixed|self $expression2
428
     */
429 3
    public function divide($expression1, $expression2) : self
430
    {
431 3
        return $this->operator('$divide', [$expression1, $expression2]);
432
    }
433
434
    /**
435
     * Compares two values and returns whether the are equivalent.
436
     *
437
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/eq/
438
     *
439
     * @param mixed|self $expression1
440
     * @param mixed|self $expression2
441
     */
442 9
    public function eq($expression1, $expression2) : self
443
    {
444 9
        return $this->operator('$eq', [$expression1, $expression2]);
445
    }
446
447
    /**
448
     * Raises Euler’s number to the specified exponent and returns the result.
449
     *
450
     * The <exponent> expression can be any valid expression as long as it
451
     * resolves to a number.
452
     *
453
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/exp/
454
     *
455
     * @param mixed|self $exponent
456
     */
457 3
    public function exp($exponent) : self
458
    {
459 3
        return $this->operator('$exp', $exponent);
460
    }
461
462
    /**
463
     * Returns a new expression object
464
     */
465 4
    public function expr() : self
466
    {
467 4
        return new static($this->dm, $this->class);
468
    }
469
470
    /**
471
     * Allows any expression to be used as a field value.
472
     *
473
     * @see http://docs.mongodb.org/manual/meta/aggregation-quick-reference/#aggregation-expressions
474
     *
475
     * @param mixed|self $value
476
     */
477 23
    public function expression($value) : self
478
    {
479 23
        $this->requiresCurrentField(__METHOD__);
480 22
        $this->expr[$this->currentField] = $this->ensureArray($value);
481
482 22
        return $this;
483
    }
484
485
    /**
486
     * Set the current field for building the expression.
487
     */
488 150
    public function field(string $fieldName) : self
489
    {
490 150
        $fieldName          = $this->getDocumentPersister()->prepareFieldName($fieldName);
491 150
        $this->currentField = $fieldName;
492
493 150
        return $this;
494
    }
495
496
    /**
497
     * Selects a subset of the array to return based on the specified condition.
498
     *
499
     * Returns an array with only those elements that match the condition. The
500
     * returned elements are in the original order.
501
     *
502
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/filter/
503
     *
504
     * @param mixed|self $input
505
     * @param mixed|self $as
506
     * @param mixed|self $cond
507
     */
508 3
    public function filter($input, $as, $cond) : self
509
    {
510 3
        return $this->operator('$filter', ['input' => $input, 'as' => $as, 'cond' => $cond]);
511
    }
512
513
    /**
514
     * Returns the value that results from applying an expression to the first
515
     * document in a group of documents that share the same group by key. Only
516
     * meaningful when documents are in a defined order.
517
     *
518
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/first/
519
     *
520
     * @param mixed|self $expression
521
     */
522 2
    public function first($expression) : self
523
    {
524 2
        return $this->operator('$first', $expression);
525
    }
526
527
    /**
528
     * Returns the largest integer less than or equal to the specified number.
529
     *
530
     * The <number> expression can be any valid expression as long as it
531
     * resolves to a number.
532
     *
533
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/floor/
534
     *
535
     * @param mixed|self $number
536
     */
537 3
    public function floor($number) : self
538
    {
539 3
        return $this->operator('$floor', $number);
540
    }
541
542 350
    public function getExpression() : array
543
    {
544 350
        return $this->expr;
545
    }
546
547
    /**
548
     * Compares two values and returns:
549
     * true when the first value is greater than the second value.
550
     * false when the first value is less than or equivalent to the second
551
     * value.
552
     *
553
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/gt/
554
     *
555
     * @param mixed|self $expression1
556
     * @param mixed|self $expression2
557
     */
558 3
    public function gt($expression1, $expression2) : self
559
    {
560 3
        return $this->operator('$gt', [$expression1, $expression2]);
561
    }
562
563
    /**
564
     * Compares two values and returns:
565
     * true when the first value is greater than or equivalent to the second
566
     * value.
567
     * false when the first value is less than the second value.
568
     *
569
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/gte/
570
     *
571
     * @param mixed|self $expression1
572
     * @param mixed|self $expression2
573
     */
574 6
    public function gte($expression1, $expression2) : self
575
    {
576 6
        return $this->operator('$gte', [$expression1, $expression2]);
577
    }
578
579
    /**
580
     * Returns the hour portion of a date as a number between 0 and 23.
581
     *
582
     * The argument can be any expression as long as it resolves to a date.
583
     *
584
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/hour/
585
     *
586
     * @param mixed|self $expression
587
     */
588 3
    public function hour($expression) : self
589
    {
590 3
        return $this->operator('$hour', $expression);
591
    }
592
593
    /**
594
     * Evaluates an expression and returns the value of the expression if the
595
     * expression evaluates to a non-null value. If the expression evaluates to
596
     * a null value, including instances of undefined values or missing fields,
597
     * returns the value of the replacement expression.
598
     *
599
     * The arguments can be any valid expression.
600
     *
601
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ifNull/
602
     *
603
     * @param mixed|self $expression
604
     * @param mixed|self $replacementExpression
605
     */
606 3
    public function ifNull($expression, $replacementExpression) : self
607
    {
608 3
        return $this->operator('$ifNull', [$expression, $replacementExpression]);
609
    }
610
611
    /**
612
     * Returns a boolean indicating whether a specified value is in an array.
613
     *
614
     * Unlike the $in query operator, the aggregation $in operator does not
615
     * support matching by regular expressions.
616
     *
617
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/in/
618
     *
619
     * @param mixed|self $expression
620
     * @param mixed|self $arrayExpression
621
     */
622 3
    public function in($expression, $arrayExpression) : self
623
    {
624 3
        return $this->operator('$in', [$expression, $arrayExpression]);
625
    }
626
627
    /**
628
     * Searches an array for an occurrence of a specified value and returns the
629
     * array index (zero-based) of the first occurrence. If the value is not
630
     * found, returns -1.
631
     *
632
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfArray/
633
     *
634
     * @param mixed|self $arrayExpression  Can be any valid expression as long as it resolves to an array.
635
     * @param mixed|self $searchExpression Can be any valid expression.
636
     * @param mixed|self $start            Optional. An integer, or a number that can be represented as integers (such as 2.0), that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number.
637
     * @param mixed|self $end              An integer, or a number that can be represented as integers (such as 2.0), that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number.
638
     */
639 12
    public function indexOfArray($arrayExpression, $searchExpression, $start = null, $end = null) : self
640
    {
641 12
        $args = [$arrayExpression, $searchExpression];
642 12
        if ($start !== null) {
643 6
            $args[] = $start;
644
645 6
            if ($end !== null) {
646 3
                $args[] = $end;
647
            }
648
        }
649
650 12
        return $this->operator('$indexOfArray', $args);
651
    }
652
653
    /**
654
     * Searches a string for an occurrence of a substring and returns the UTF-8
655
     * byte index (zero-based) of the first occurrence. If the substring is not
656
     * found, returns -1.
657
     *
658
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfBytes/
659
     *
660
     * @param mixed|self      $stringExpression    Can be any valid expression as long as it resolves to a string.
661
     * @param mixed|self      $substringExpression Can be any valid expression as long as it resolves to a string.
662
     * @param string|int|null $start               An integral number that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number.
663
     * @param string|int|null $end                 An integral number that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number.
664
     */
665 12
    public function indexOfBytes($stringExpression, $substringExpression, $start = null, $end = null) : self
666
    {
667 12
        $args = [$stringExpression, $substringExpression];
668 12
        if ($start !== null) {
669 6
            $args[] = $start;
670
671 6
            if ($end !== null) {
672 3
                $args[] = $end;
673
            }
674
        }
675
676 12
        return $this->operator('$indexOfBytes', $args);
677
    }
678
679
    /**
680
     * Searches a string for an occurrence of a substring and returns the UTF-8
681
     * code point index (zero-based) of the first occurrence. If the substring is
682
     * not found, returns -1.
683
     *
684
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfCP/
685
     *
686
     * @param mixed|self      $stringExpression    Can be any valid expression as long as it resolves to a string.
687
     * @param mixed|self      $substringExpression Can be any valid expression as long as it resolves to a string.
688
     * @param string|int|null $start               An integral number that specifies the starting index position for the search. Can be any valid expression that resolves to a non-negative integral number.
689
     * @param string|int|null $end                 An integral number that specifies the ending index position for the search. Can be any valid expression that resolves to a non-negative integral number.
690
     */
691 12
    public function indexOfCP($stringExpression, $substringExpression, $start = null, $end = null) : self
692
    {
693 12
        $args = [$stringExpression, $substringExpression];
694 12
        if ($start !== null) {
695 6
            $args[] = $start;
696
697 6
            if ($end !== null) {
698 3
                $args[] = $end;
699
            }
700
        }
701
702 12
        return $this->operator('$indexOfCP', $args);
703
    }
704
705
    /**
706
     * Determines if the operand is an array. Returns a boolean.
707
     *
708
     * The <expression> can be any valid expression.
709
     *
710
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/isArray/
711
     *
712
     * @param mixed|self $expression
713
     */
714 3
    public function isArray($expression) : self
715
    {
716 3
        return $this->operator('$isArray', $expression);
717
    }
718
719
    /**
720
     * Returns the weekday number in ISO 8601 format, ranging from 1 (for Monday)
721
     * to 7 (for Sunday).
722
     *
723
     * The argument can be any expression as long as it resolves to a date.
724
     *
725
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/isoDayOfWeek/
726
     *
727
     * @param mixed|self $expression
728
     */
729 3
    public function isoDayOfWeek($expression) : self
730
    {
731 3
        return $this->operator('$isoDayOfWeek', $expression);
732
    }
733
734
    /**
735
     * Returns the week number in ISO 8601 format, ranging from 1 to 53.
736
     *
737
     * Week numbers start at 1 with the week (Monday through Sunday) that
738
     * contains the year’s first Thursday.
739
     *
740
     * The argument can be any expression as long as it resolves to a date.
741
     *
742
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/isoWeek/
743
     *
744
     * @param mixed|self $expression
745
     */
746 3
    public function isoWeek($expression) : self
747
    {
748 3
        return $this->operator('$isoWeek', $expression);
749
    }
750
751
    /**
752
     * Returns the year number in ISO 8601 format.
753
     *
754
     * The year starts with the Monday of week 1 (ISO 8601) and ends with the
755
     * Sunday of the last week (ISO 8601).
756
     *
757
     * The argument can be any expression as long as it resolves to a date.
758
     *
759
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/isoWeek/
760
     *
761
     * @param mixed|self $expression
762
     */
763 3
    public function isoWeekYear($expression) : self
764
    {
765 3
        return $this->operator('$isoWeekYear', $expression);
766
    }
767
768
    /**
769
     * Returns the value that results from applying an expression to the last
770
     * document in a group of documents that share the same group by a field.
771
     * Only meaningful when documents are in a defined order.
772
     *
773
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/last/
774
     *
775
     * @param mixed|self $expression
776
     */
777 2
    public function last($expression) : self
778
    {
779 2
        return $this->operator('$last', $expression);
780
    }
781
782
    /**
783
     * Binds variables for use in the specified expression, and returns the
784
     * result of the expression.
785
     *
786
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/let/
787
     *
788
     * @param mixed|self $vars Assignment block for the variables accessible in the in expression. To assign a variable, specify a string for the variable name and assign a valid expression for the value.
789
     * @param mixed|self $in   The expression to evaluate.
790
     */
791 3
    public function let($vars, $in) : self
792
    {
793 3
        return $this->operator('$let', ['vars' => $vars, 'in' => $in]);
794
    }
795
796
    /**
797
     * Returns a value without parsing. Use for values that the aggregation
798
     * pipeline may interpret as an expression.
799
     *
800
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/literal/
801
     *
802
     * @param mixed|self $value
803
     */
804 3
    public function literal($value) : self
805
    {
806 3
        return $this->operator('$literal', $value);
807
    }
808
809
    /**
810
     * Calculates the natural logarithm ln (i.e loge) of a number and returns
811
     * the result as a double.
812
     *
813
     * The <number> expression can be any valid expression as long as it
814
     * resolves to a non-negative number.
815
     *
816
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/log/
817
     *
818
     * @param mixed|self $number
819
     */
820 3
    public function ln($number) : self
821
    {
822 3
        return $this->operator('$ln', $number);
823
    }
824
825
    /**
826
     * Calculates the log of a number in the specified base and returns the
827
     * result as a double.
828
     *
829
     * The <number> expression can be any valid expression as long as it
830
     * resolves to a non-negative number.
831
     * The <base> expression can be any valid expression as long as it resolves
832
     * to a positive number greater than 1.
833
     *
834
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/log/
835
     *
836
     * @param mixed|self $number
837
     * @param mixed|self $base
838
     */
839 3
    public function log($number, $base) : self
840
    {
841 3
        return $this->operator('$log', [$number, $base]);
842
    }
843
844
    /**
845
     * Calculates the log base 10 of a number and returns the result as a double.
846
     *
847
     * The <number> expression can be any valid expression as long as it
848
     * resolves to a non-negative number.
849
     *
850
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/log10/
851
     *
852
     * @param mixed|self $number
853
     */
854 3
    public function log10($number) : self
855
    {
856 3
        return $this->operator('$log10', $number);
857
    }
858
859
    /**
860
     * Compares two values and returns:
861
     * true when the first value is less than the second value.
862
     * false when the first value is greater than or equivalent to the second
863
     * value.
864
     *
865
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/lt/
866
     *
867
     * @param mixed|self $expression1
868
     * @param mixed|self $expression2
869
     */
870 4
    public function lt($expression1, $expression2) : self
871
    {
872 4
        return $this->operator('$lt', [$expression1, $expression2]);
873
    }
874
875
    /**
876
     * Compares two values and returns:
877
     * true when the first value is less than or equivalent to the second value.
878
     * false when the first value is greater than the second value.
879
     *
880
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/lte/
881
     *
882
     * @param mixed|self $expression1
883
     * @param mixed|self $expression2
884
     */
885 6
    public function lte($expression1, $expression2) : self
886
    {
887 6
        return $this->operator('$lte', [$expression1, $expression2]);
888
    }
889
890
    /**
891
     * Applies an expression to each item in an array and returns an array with
892
     * the applied results.
893
     *
894
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/map/
895
     *
896
     * @param mixed|self $input An expression that resolves to an array.
897
     * @param string     $as    The variable name for the items in the input array. The in expression accesses each item in the input array by this variable.
898
     * @param mixed|self $in    The expression to apply to each item in the input array. The expression accesses the item by its variable name.
899
     */
900 3
    public function map($input, $as, $in) : self
901
    {
902 3
        return $this->operator('$map', ['input' => $input, 'as' => $as, 'in' => $in]);
903
    }
904
905
    /**
906
     * Returns the highest value that results from applying an expression to
907
     * each document in a group of documents that share the same group by key.
908
     *
909
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/max/
910
     *
911
     * @param mixed|self $expression
912
     */
913 3
    public function max($expression) : self
914
    {
915 3
        return $this->operator('$max', $expression);
916
    }
917
918
    /**
919
     * Returns the metadata associated with a document in a pipeline operations.
920
     *
921
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/meta/
922
     *
923
     * @param mixed|self $metaDataKeyword
924
     */
925 3
    public function meta($metaDataKeyword) : self
926
    {
927 3
        return $this->operator('$meta', $metaDataKeyword);
928
    }
929
930
    /**
931
     * Returns the millisecond portion of a date as an integer between 0 and 999.
932
     *
933
     * The argument can be any expression as long as it resolves to a date.
934
     *
935
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/millisecond/
936
     *
937
     * @param mixed|self $expression
938
     */
939 3
    public function millisecond($expression) : self
940
    {
941 3
        return $this->operator('$millisecond', $expression);
942
    }
943
944
    /**
945
     * Returns the lowest value that results from applying an expression to each
946
     * document in a group of documents that share the same group by key.
947
     *
948
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/min/
949
     *
950
     * @param mixed|self $expression
951
     */
952 3
    public function min($expression) : self
953
    {
954 3
        return $this->operator('$min', $expression);
955
    }
956
957
    /**
958
     * Returns the minute portion of a date as a number between 0 and 59.
959
     *
960
     * The argument can be any expression as long as it resolves to a date.
961
     *
962
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/minute/
963
     *
964
     * @param mixed|self $expression
965
     */
966 3
    public function minute($expression) : self
967
    {
968 3
        return $this->operator('$minute', $expression);
969
    }
970
971
    /**
972
     * Divides one number by another and returns the remainder. The first
973
     * argument is divided by the second argument.
974
     *
975
     * The arguments can be any valid expression as long as they resolve to numbers.
976
     *
977
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/mod/
978
     *
979
     * @param mixed|self $expression1
980
     * @param mixed|self $expression2
981
     */
982 3
    public function mod($expression1, $expression2) : self
983
    {
984 3
        return $this->operator('$mod', [$expression1, $expression2]);
985
    }
986
987
    /**
988
     * Returns the month of a date as a number between 1 and 12.
989
     *
990
     * The argument can be any expression as long as it resolves to a date.
991
     *
992
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/month/
993
     *
994
     * @param mixed|self $expression
995
     */
996 3
    public function month($expression) : self
997
    {
998 3
        return $this->operator('$month', $expression);
999
    }
1000
1001
    /**
1002
     * Multiplies numbers together and returns the result.
1003
     *
1004
     * The arguments can be any valid expression as long as they resolve to numbers.
1005
     *
1006
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/multiply/
1007
     *
1008
     * @param mixed|self $expression1
1009
     * @param mixed|self $expression2
1010
     * @param mixed|self ...$expressions Additional expressions
1011
     */
1012 13
    public function multiply($expression1, $expression2, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expression2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1013
    {
1014 13
        return $this->operator('$multiply', func_get_args());
1015
    }
1016
1017
    /**
1018
     * Compares two values and returns:
1019
     * true when the values are not equivalent.
1020
     * false when the values are equivalent.
1021
     *
1022
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ne/
1023
     *
1024
     * @param mixed|self $expression1
1025
     * @param mixed|self $expression2
1026
     */
1027 4
    public function ne($expression1, $expression2) : self
1028
    {
1029 4
        return $this->operator('$ne', [$expression1, $expression2]);
1030
    }
1031
1032
    /**
1033
     * Evaluates a boolean and returns the opposite boolean value.
1034
     *
1035
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/not/
1036
     *
1037
     * @param mixed|self $expression
1038
     */
1039 3
    public function not($expression) : self
1040
    {
1041 3
        return $this->operator('$not', $expression);
1042
    }
1043
1044
    /**
1045
     * Raises a number to the specified exponent and returns the result.
1046
     *
1047
     * The <number> expression can be any valid expression as long as it
1048
     * resolves to a non-negative number.
1049
     * The <exponent> expression can be any valid expression as long as it
1050
     * resolves to a number.
1051
     *
1052
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/pow/
1053
     *
1054
     * @param mixed|self $number
1055
     * @param mixed|self $exponent
1056
     */
1057 3
    public function pow($number, $exponent) : self
1058
    {
1059 3
        return $this->operator('$pow', [$number, $exponent]);
1060
    }
1061
1062
    /**
1063
     * Returns an array of all values that result from applying an expression to
1064
     * each document in a group of documents that share the same group by key.
1065
     *
1066
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/push/
1067
     *
1068
     * @param mixed|self $expression
1069
     */
1070 2
    public function push($expression) : self
1071
    {
1072 2
        return $this->operator('$push', $expression);
1073
    }
1074
1075
    /**
1076
     * Returns an array whose elements are a generated sequence of numbers.
1077
     *
1078
     * $range generates the sequence from the specified starting number by successively incrementing the starting number by the specified step value up to but not including the end point.
1079
     *
1080
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/range/
1081
     *
1082
     * @param mixed|self $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer.
1083
     * @param mixed|self $end   An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer.
1084
     * @param mixed|self $step  Optional. An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1.
1085
     */
1086 6
    public function range($start, $end, $step = 1) : self
1087
    {
1088 6
        return $this->operator('$range', [$start, $end, $step]);
1089
    }
1090
1091
    /**
1092
     * Applies an expression to each element in an array and combines them into
1093
     * a single value.
1094
     *
1095
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/reduce/
1096
     *
1097
     * @param mixed|self $input        Can be any valid expression that resolves to an array.
1098
     * @param mixed|self $initialValue The initial cumulative value set before in is applied to the first element of the input array.
1099
     * @param mixed|self $in           A valid expression that $reduce applies to each element in the input array in left-to-right order. Wrap the input value with $reverseArray to yield the equivalent of applying the combining expression from right-to-left.
1100
     */
1101 3
    public function reduce($input, $initialValue, $in) : self
1102
    {
1103 3
        return $this->operator('$reduce', ['input' => $input, 'initialValue' => $initialValue, 'in' => $in]);
1104
    }
1105
1106
    /**
1107
     * Accepts an array expression as an argument and returns an array with the
1108
     * elements in reverse order.
1109
     *
1110
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/reverseArray/
1111
     *
1112
     * @param mixed|self $expression
1113
     */
1114 3
    public function reverseArray($expression) : self
1115
    {
1116 3
        return $this->operator('$reverseArray', $expression);
1117
    }
1118
1119
    /**
1120
     * Returns the second portion of a date as a number between 0 and 59, but
1121
     * can be 60 to account for leap seconds.
1122
     *
1123
     * The argument can be any expression as long as it resolves to a date.
1124
     *
1125
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/second/
1126
     *
1127
     * @param mixed|self $expression
1128
     */
1129 3
    public function second($expression) : self
1130
    {
1131 3
        return $this->operator('$second', $expression);
1132
    }
1133
1134
    /**
1135
     * Takes two sets and returns an array containing the elements that only
1136
     * exist in the first set.
1137
     *
1138
     * The arguments can be any valid expression as long as they each resolve to an array.
1139
     *
1140
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setDifference/
1141
     *
1142
     * @param mixed|self $expression1
1143
     * @param mixed|self $expression2
1144
     */
1145 3
    public function setDifference($expression1, $expression2) : self
1146
    {
1147 3
        return $this->operator('$setDifference', [$expression1, $expression2]);
1148
    }
1149
1150
    /**
1151
     * Compares two or more arrays and returns true if they have the same
1152
     * distinct elements and false otherwise.
1153
     *
1154
     * The arguments can be any valid expression as long as they each resolve to an array.
1155
     *
1156
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setEquals/
1157
     *
1158
     * @param mixed|self $expression1
1159
     * @param mixed|self $expression2
1160
     * @param mixed|self ...$expressions Additional sets
1161
     */
1162 6
    public function setEquals($expression1, $expression2, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expression2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1163
    {
1164 6
        return $this->operator('$setEquals', func_get_args());
1165
    }
1166
1167
    /**
1168
     * Takes two or more arrays and returns an array that contains the elements
1169
     * that appear in every input array.
1170
     *
1171
     * The arguments can be any valid expression as long as they each resolve to an array.
1172
     *
1173
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setIntersection/
1174
     *
1175
     * @param mixed|self $expression1
1176
     * @param mixed|self $expression2
1177
     * @param mixed|self ...$expressions Additional sets
1178
     */
1179 6
    public function setIntersection($expression1, $expression2, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expression2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1180
    {
1181 6
        return $this->operator('$setIntersection', func_get_args());
1182
    }
1183
1184
    /**
1185
     * Takes two arrays and returns true when the first array is a subset of the
1186
     * second, including when the first array equals the second array, and false otherwise.
1187
     *
1188
     * The arguments can be any valid expression as long as they each resolve to an array.
1189
     *
1190
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setIsSubset/
1191
     *
1192
     * @param mixed|self $expression1
1193
     * @param mixed|self $expression2
1194
     */
1195 3
    public function setIsSubset($expression1, $expression2) : self
1196
    {
1197 3
        return $this->operator('$setIsSubset', [$expression1, $expression2]);
1198
    }
1199
1200
    /**
1201
     * Takes two or more arrays and returns an array containing the elements
1202
     * that appear in any input array.
1203
     *
1204
     * The arguments can be any valid expression as long as they each resolve to an array.
1205
     *
1206
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setUnion/
1207
     *
1208
     * @param mixed|self $expression1
1209
     * @param mixed|self $expression2
1210
     * @param mixed|self ...$expressions Additional sets
1211
     */
1212 6
    public function setUnion($expression1, $expression2, ...$expressions) : self
0 ignored issues
show
Unused Code introduced by
The parameter $expression1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expression2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expressions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1213
    {
1214 6
        return $this->operator('$setUnion', func_get_args());
1215
    }
1216
1217
    /**
1218
     * Counts and returns the total the number of items in an array.
1219
     *
1220
     * The argument can be any expression as long as it resolves to an array.
1221
     *
1222
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/size/
1223
     *
1224
     * @param mixed|self $expression
1225
     */
1226 3
    public function size($expression) : self
1227
    {
1228 3
        return $this->operator('$size', $expression);
1229
    }
1230
1231
    /**
1232
     * Returns a subset of an array.
1233
     *
1234
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/slice/
1235
     *
1236
     * @param mixed|self      $array
1237
     * @param mixed|self      $n
1238
     * @param mixed|self|null $position
1239
     */
1240 6
    public function slice($array, $n, $position = null) : self
1241
    {
1242 6
        if ($position === null) {
1243 3
            return $this->operator('$slice', [$array, $n]);
1244
        }
1245
1246 3
        return $this->operator('$slice', [$array, $position, $n]);
1247
    }
1248
1249
    /**
1250
     * Divides a string into an array of substrings based on a delimiter.
1251
     *
1252
     * $split removes the delimiter and returns the resulting substrings as
1253
     * elements of an array. If the delimiter is not found in the string, $split
1254
     * returns the original string as the only element of an array.
1255
     *
1256
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/split/
1257
     *
1258
     * @param mixed|self $string    The string to be split. Can be any valid expression as long as it resolves to a string.
1259
     * @param mixed|self $delimiter The delimiter to use when splitting the string expression. Can be any valid expression as long as it resolves to a string.
1260
     */
1261 3
    public function split($string, $delimiter) : self
1262
    {
1263 3
        return $this->operator('$split', [$string, $delimiter]);
1264
    }
1265
1266
    /**
1267
     * Calculates the square root of a positive number and returns the result as
1268
     * a double.
1269
     *
1270
     * The argument can be any valid expression as long as it resolves to a
1271
     * non-negative number.
1272
     *
1273
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/sqrt/
1274
     *
1275
     * @param mixed|self $expression
1276
     */
1277 3
    public function sqrt($expression) : self
1278
    {
1279 3
        return $this->operator('$sqrt', $expression);
1280
    }
1281
1282
    /**
1283
     * Calculates the population standard deviation of the input values.
1284
     *
1285
     * The arguments can be any expression as long as it resolves to an array.
1286
     *
1287
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/stdDevPop/
1288
     *
1289
     * @param mixed|self $expression1
1290
     * @param mixed|self ...$expressions Additional samples
1291
     */
1292 5
    public function stdDevPop($expression1, ...$expressions) : self
1293
    {
1294 5
        $expression = empty($expressions) ? $expression1 : func_get_args();
1295
1296 5
        return $this->operator('$stdDevPop', $expression);
1297
    }
1298
1299
    /**
1300
     * Calculates the sample standard deviation of the input values.
1301
     *
1302
     * The arguments can be any expression as long as it resolves to an array.
1303
     *
1304
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/stdDevSamp/
1305
     *
1306
     * @param mixed|self $expression1
1307
     * @param mixed|self ...$expressions Additional samples
1308
     */
1309 5
    public function stdDevSamp($expression1, ...$expressions) : self
1310
    {
1311 5
        $expression = empty($expressions) ? $expression1 : func_get_args();
1312
1313 5
        return $this->operator('$stdDevSamp', $expression);
1314
    }
1315
1316
    /**
1317
     * Performs case-insensitive comparison of two strings. Returns
1318
     * 1 if first string is “greater than” the second string.
1319
     * 0 if the two strings are equal.
1320
     * -1 if the first string is “less than” the second string.
1321
     *
1322
     * The arguments can be any valid expression as long as they resolve to strings.
1323
     *
1324
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/strcasecmp/
1325
     *
1326
     * @param mixed|self $expression1
1327
     * @param mixed|self $expression2
1328
     */
1329 3
    public function strcasecmp($expression1, $expression2) : self
1330
    {
1331 3
        return $this->operator('$strcasecmp', [$expression1, $expression2]);
1332
    }
1333
1334
    /**
1335
     * Returns the number of UTF-8 encoded bytes in the specified string.
1336
     *
1337
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/strLenBytes/
1338
     *
1339
     * @param mixed|self $string
1340
     */
1341 3
    public function strLenBytes($string) : self
1342
    {
1343 3
        return $this->operator('$strLenBytes', $string);
1344
    }
1345
1346
    /**
1347
     * Returns the number of UTF-8 code points in the specified string.
1348
     *
1349
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/strLenCP/
1350
     *
1351
     * @param mixed|self $string
1352
     */
1353 3
    public function strLenCP($string) : self
1354
    {
1355 3
        return $this->operator('$strLenCP', $string);
1356
    }
1357
1358
    /**
1359
     * Returns a substring of a string, starting at a specified index position
1360
     * and including the specified number of characters. The index is zero-based.
1361
     *
1362
     * The arguments can be any valid expression as long as long as the first argument resolves to a string, and the second and third arguments resolve to integers.
1363
     *
1364
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/substr/
1365
     *
1366
     * @param mixed|self $string
1367
     * @param mixed|self $start
1368
     * @param mixed|self $length
1369
     */
1370 3
    public function substr($string, $start, $length) : self
1371
    {
1372 3
        return $this->operator('$substr', [$string, $start, $length]);
1373
    }
1374
1375
    /**
1376
     * Returns the substring of a string.
1377
     *
1378
     * The substring starts with the character at the specified UTF-8 byte index
1379
     * (zero-based) in the string and continues for the number of bytes
1380
     * specified.
1381
     *
1382
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/substrBytes/
1383
     *
1384
     * @param mixed|self $string The string from which the substring will be extracted. Can be any valid expression as long as it resolves to a string.
1385
     * @param mixed|self $start  Indicates the starting point of the substring. Can be any valid expression as long as it resolves to a non-negative integer or number that can be represented as an integer.
1386
     * @param mixed|self $count  Can be any valid expression as long as it resolves to a non-negative integer or number that can be represented as an integer.
1387
     */
1388 3
    public function substrBytes($string, $start, $count) : self
1389
    {
1390 3
        return $this->operator('$substrBytes', [$string, $start, $count]);
1391
    }
1392
1393
    /**
1394
     * Returns the substring of a string.
1395
     *
1396
     * The substring starts with the character at the specified UTF-8 code point
1397
     * (CP) index (zero-based) in the string for the number of code points
1398
     * specified.
1399
     *
1400
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/substrBytes/
1401
     *
1402
     * @param mixed|self $string The string from which the substring will be extracted. Can be any valid expression as long as it resolves to a string.
1403
     * @param mixed|self $start  Indicates the starting point of the substring. Can be any valid expression as long as it resolves to a non-negative integer or number that can be represented as an integer.
1404
     * @param mixed|self $count  Can be any valid expression as long as it resolves to a non-negative integer or number that can be represented as an integer.
1405
     */
1406 3
    public function substrCP($string, $start, $count) : self
1407
    {
1408 3
        return $this->operator('$substrCP', [$string, $start, $count]);
1409
    }
1410
1411
    /**
1412
     * Subtracts two numbers to return the difference. The second argument is
1413
     * subtracted from the first argument.
1414
     *
1415
     * The arguments can be any valid expression as long as they resolve to numbers and/or dates.
1416
     *
1417
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/subtract/
1418
     *
1419
     * @param mixed|self $expression1
1420
     * @param mixed|self $expression2
1421
     */
1422 3
    public function subtract($expression1, $expression2) : self
1423
    {
1424 3
        return $this->operator('$subtract', [$expression1, $expression2]);
1425
    }
1426
1427
    /**
1428
     * Calculates and returns the sum of all the numeric values that result from
1429
     * applying a specified expression to each document in a group of documents
1430
     * that share the same group by key. Ignores nun-numeric values.
1431
     *
1432
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/sum/
1433
     *
1434
     * @param mixed|self $expression
1435
     */
1436 9
    public function sum($expression) : self
1437
    {
1438 9
        return $this->operator('$sum', $expression);
1439
    }
1440
1441
    /**
1442
     * Converts a string to lowercase, returning the result.
1443
     *
1444
     * The argument can be any expression as long as it resolves to a string.
1445
     *
1446
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/toLower/
1447
     *
1448
     * @param mixed|self $expression
1449
     */
1450 3
    public function toLower($expression) : self
1451
    {
1452 3
        return $this->operator('$toLower', $expression);
1453
    }
1454
1455
    /**
1456
     * Converts a string to uppercase, returning the result.
1457
     *
1458
     * The argument can be any expression as long as it resolves to a string.
1459
     *
1460
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/toUpper/
1461
     *
1462
     * @param mixed|self $expression
1463
     */
1464 3
    public function toUpper($expression) : self
1465
    {
1466 3
        return $this->operator('$toUpper', $expression);
1467
    }
1468
1469
    /**
1470
     * Truncates a number to its integer.
1471
     *
1472
     * The <number> expression can be any valid expression as long as it
1473
     * resolves to a number.
1474
     *
1475
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/trunc/
1476
     *
1477
     * @param mixed|self $number
1478
     */
1479 3
    public function trunc($number) : self
1480
    {
1481 3
        return $this->operator('$trunc', $number);
1482
    }
1483
1484
    /**
1485
     * Returns a string that specifies the BSON type of the argument.
1486
     *
1487
     * The argument can be any valid expression.
1488
     *
1489
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/type/
1490
     *
1491
     * @param mixed|self $expression
1492
     */
1493 3
    public function type($expression) : self
1494
    {
1495 3
        return $this->operator('$type', $expression);
1496
    }
1497
1498
    /**
1499
     * Returns the week of the year for a date as a number between 0 and 53.
1500
     *
1501
     * The argument can be any expression as long as it resolves to a date.
1502
     *
1503
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/week/
1504
     *
1505
     * @param mixed|self $expression
1506
     */
1507 3
    public function week($expression) : self
1508
    {
1509 3
        return $this->operator('$week', $expression);
1510
    }
1511
1512
    /**
1513
     * Returns the year portion of a date.
1514
     *
1515
     * The argument can be any expression as long as it resolves to a date.
1516
     *
1517
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/year/
1518
     *
1519
     * @param mixed|self $expression
1520
     */
1521 4
    public function year($expression) : self
1522
    {
1523 4
        return $this->operator('$year', $expression);
1524
    }
1525
1526
    /**
1527
     * Transposes an array of input arrays so that the first element of the
1528
     * output array would be an array containing, the first element of the first
1529
     * input array, the first element of the second input array, etc.
1530
     *
1531
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/zip/
1532
     *
1533
     * @param mixed|self      $inputs           An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array.
1534
     * @param bool|null       $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array.
1535
     * @param mixed|self|null $defaults         An array of default element values to use if the input arrays have different lengths. You must specify useLongestLength: true along with this field, or else $zip will return an error.
1536
     */
1537 9
    public function zip($inputs, ?bool $useLongestLength = null, $defaults = null) : self
1538
    {
1539 9
        $args = ['inputs' => $inputs];
1540 9
        if ($useLongestLength !== null) {
1541 6
            $args['useLongestLength'] = $useLongestLength;
1542
        }
1543 9
        if ($defaults !== null) {
1544 3
            $args['defaults'] = $defaults;
1545
        }
1546
1547 9
        return $this->operator('$zip', $args);
1548
    }
1549
1550
    /**
1551
     * @param mixed|self $expression
1552
     *
1553
     * @return mixed
1554
     */
1555 354
    private function ensureArray($expression)
1556
    {
1557 354
        if (is_string($expression) && substr($expression, 0, 1) === '$') {
1558 341
            return '$' . $this->getDocumentPersister()->prepareFieldName(substr($expression, 1));
1559
        }
1560
1561 228
        if (is_array($expression)) {
1562 209
            return array_map([$this, 'ensureArray'], $expression);
1563
        }
1564
1565 98
        if ($expression instanceof self) {
1566 20
            return $expression->getExpression();
1567
        }
1568
1569
        // Convert PHP types to MongoDB types for everything else
1570 96
        return Type::convertPHPToDatabaseValue($expression);
1571
    }
1572
1573 354
    private function getDocumentPersister() : DocumentPersister
1574
    {
1575 354
        return $this->dm->getUnitOfWork()->getDocumentPersister($this->class->name);
1576
    }
1577
1578
    /**
1579
     * Defines an operator and value on the expression.
1580
     *
1581
     * If there is a current field, the operator will be set on it; otherwise,
1582
     * the operator is set at the top level of the query.
1583
     *
1584
     * @param array|self $expression
1585
     */
1586 341
    private function operator(string $operator, $expression) : self
1587
    {
1588 341
        if ($this->currentField) {
1589 137
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
1590
        } else {
1591 212
            $this->expr[$operator] = $this->ensureArray($expression);
1592
        }
1593
1594 341
        return $this;
1595
    }
1596
1597
    /**
1598
     * Ensure that a current field has been set.
1599
     *
1600
     * @throws LogicException If a current field has not been set.
1601
     */
1602 23
    private function requiresCurrentField(?string $method = null) : void
1603
    {
1604 23
        if (! $this->currentField) {
1605 1
            throw new LogicException(($method ?: 'This method') . ' requires you set a current field using field().');
1606
        }
1607 22
    }
1608
1609
    /**
1610
     * @throws BadMethodCallException If there is no current switch operator.
1611
     */
1612 8
    private function requiresSwitchStatement(?string $method = null) : void
1613
    {
1614 8
        $message = ($method ?: 'This method') . ' requires a valid switch statement (call switch() first).';
1615
1616 8
        if ($this->currentField) {
1617
            if (! isset($this->expr[$this->currentField]['$switch'])) {
1618
                throw new BadMethodCallException($message);
1619
            }
1620 8
        } elseif (! isset($this->expr['$switch'])) {
1621 4
            throw new BadMethodCallException($message);
1622
        }
1623 4
    }
1624
1625
    /**
1626
     * Evaluates a series of case expressions. When it finds an expression which
1627
     * evaluates to true, $switch executes a specified expression and breaks out
1628
     * of the control flow.
1629
     *
1630
     * To add statements, use the {@link case()}, {@link then()} and
1631
     * {@link default()} methods.
1632
     */
1633 4
    public function switch() : self
1634
    {
1635 4
        $this->operator('$switch', []);
1636
1637 4
        return $this;
1638
    }
1639
1640
    /**
1641
     * Adds a case statement for the current branch of the $switch operator.
1642
     *
1643
     * Requires {@link case()} to be called first. The argument can be any valid
1644
     * expression.
1645
     *
1646
     * @param mixed|self $expression
1647
     */
1648 6
    public function then($expression) : self
1649
    {
1650 6
        if (! is_array($this->switchBranch)) {
1651 4
            throw new BadMethodCallException(static::class . '::then requires a valid case statement (call case() first).');
1652
        }
1653
1654 4
        $this->switchBranch['then'] = $expression;
1655
1656 4
        if ($this->currentField) {
1657
            $this->expr[$this->currentField]['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
1658
        } else {
1659 4
            $this->expr['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
1660
        }
1661
1662 4
        $this->switchBranch = null;
1663
1664 4
        return $this;
1665
    }
1666
}
1667