Completed
Pull Request — master (#1811)
by Marcos
15:49
created

Expr::substr()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB\Aggregation;
6
7
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
8
use Doctrine\ODM\MongoDB\DocumentManager;
9
use Doctrine\ODM\MongoDB\Persisters\DocumentPersister;
10
use Doctrine\ODM\MongoDB\Types\Type;
11
use function array_map;
12
use function array_merge;
13
use function func_get_args;
14
use function is_array;
15
use function is_string;
16
use function substr;
17
18
/**
19
 * Fluent interface for building aggregation pipelines.
20
 */
21
class Expr
22
{
23
    /** @var DocumentManager */
24
    private $dm;
25
26
    /** @var ClassMetadata */
27
    private $class;
28
29
    /** @var array */
30
    private $expr = [];
31
32
    /**
33
     * The current field we are operating on.
34
     *
35
     * @var string
36
     */
37
    private $currentField;
38
39
    /** @var array */
40
    private $switchBranch;
41
42
    /**
43
     * @inheritDoc
44
     */
45 367
    public function __construct(DocumentManager $dm, ClassMetadata $class)
46
    {
47 367
        $this->dm = $dm;
48 367
        $this->class = $class;
49 367
    }
50
51
    /**
52
     * Returns the absolute value of a number.
53
     *
54
     * The <number> argument can be any valid expression as long as it resolves
55
     * to a number.
56
     *
57
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/abs/
58
     * @param mixed|self $number
59
     * @return $this
60
     *
61
     */
62 3
    public function abs($number)
63
    {
64 3
        return $this->operator('$abs', $number);
65
    }
66
67
    /**
68
     * Adds numbers together or adds numbers and a date. If one of the arguments
69
     * is a date, $add treats the other arguments as milliseconds to add to the
70
     * date.
71
     *
72
     * The arguments can be any valid expression as long as they resolve to
73
     * either all numbers or to numbers and a date.
74
     *
75
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/add/
76
     * @param mixed|self $expression1
77
     * @param mixed|self $expression2
78
     * @param mixed|self ...$expressions Additional expressions
79
     * @return $this
80
     */
81 15
    public function add($expression1, $expression2, ...$expressions)
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...
82
    {
83 15
        return $this->operator('$add', func_get_args());
84
    }
85
86
    /**
87
     * Adds one or more $and clauses to the current expression.
88
     *
89
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/and/
90
     * @param array|self $expression
91
     * @param array|self ...$expressions
92
     * @return $this
93
     */
94 1 View Code Duplication
    public function addAnd($expression, ...$expressions)
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...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
95
    {
96 1
        if (! isset($this->expr['$and'])) {
97 1
            $this->expr['$and'] = [];
98
        }
99
100 1
        $this->expr['$and'] = array_merge($this->expr['$and'], array_map([$this, 'ensureArray'], func_get_args()));
101
102 1
        return $this;
103
    }
104
105
    /**
106
     * Adds one or more $or clause to the current expression.
107
     *
108
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/or/
109
     * @param array|self $expression
110
     * @param array|self ...$expressions
111
     * @return $this
112
     */
113 View Code Duplication
    public function addOr($expression, ...$expressions)
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...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
114
    {
115
        if (! isset($this->expr['$or'])) {
116
            $this->expr['$or'] = [];
117
        }
118
119
        $this->expr['$or'] = array_merge($this->expr['$or'], array_map([$this, 'ensureArray'], func_get_args()));
120
121
        return $this;
122
    }
123
124
    /**
125
     * Returns an array of all unique values that results from applying an
126
     * expression to each document in a group of documents that share the same
127
     * group by key. Order of the elements in the output array is unspecified.
128
     *
129
     * AddToSet is an accumulator operation only available in the group stage.
130
     *
131
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/addToSet/
132
     * @param mixed|self $expression
133
     * @return $this
134
     */
135 2
    public function addToSet($expression)
136
    {
137 2
        return $this->operator('$addToSet', $expression);
138
    }
139
140
    /**
141
     * Evaluates an array as a set and returns true if no element in the array
142
     * is false. Otherwise, returns false. An empty array returns true.
143
     *
144
     * The expression must resolve to an array.
145
     *
146
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/allElementsTrue/
147
     * @param mixed|self $expression
148
     * @return $this
149
     */
150 3
    public function allElementsTrue($expression)
151
    {
152 3
        return $this->operator('$allElementsTrue', $expression);
153
    }
154
155
    /**
156
     * Evaluates an array as a set and returns true if any of the elements are
157
     * true and false otherwise. An empty array returns false.
158
     *
159
     * The expression must resolve to an array.
160
     *
161
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/anyElementTrue/
162
     * @param array|self $expression
163
     * @return $this
164
     */
165 3
    public function anyElementTrue($expression)
166
    {
167 3
        return $this->operator('$anyElementTrue', $expression);
168
    }
169
170
    /**
171
     * Returns the element at the specified array index.
172
     *
173
     * The <array> expression can be any valid expression as long as it resolves
174
     * to an array.
175
     * The <idx> expression can be any valid expression as long as it resolves
176
     * to an integer.
177
     *
178
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/arrayElemAt/
179
     * @param mixed|self $array
180
     * @param mixed|self $index
181
     * @return $this
182
     *
183
     */
184 3
    public function arrayElemAt($array, $index)
185
    {
186 3
        return $this->operator('$arrayElemAt', [$array, $index]);
187
    }
188
189
    /**
190
     * Converts an array into a single document.
191
     *
192
     * The <expression> can be any valid expression that resolves to an array of 
193
     * two-element arrays or array of documents that contains “k” and “v” fields.
194
     *
195
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/arrayToObject/
196
     * @param mixed|self $expression
197
     * @return $this
198
     */
199
    public function arrayToObject($expression)
200
    {
201
        return $this->operator('$arrayToObject', $expression);
202
    }
203
    
204
    /**
205
     * Returns the average value of the numeric values that result from applying
206
     * a specified expression to each document in a group of documents that
207
     * share the same group by key. Ignores nun-numeric values.
208
     *
209
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/avg/
210
     * @param mixed|self $expression
211
     * @return $this
212
     */
213 10
    public function avg($expression)
214
    {
215 10
        return $this->operator('$avg', $expression);
216
    }
217
218
    /**
219
     * Adds a case statement for a branch of the $switch operator.
220
     *
221
     * Requires {@link switch()} to be called first. The argument can be any
222
     * valid expression that resolves to a boolean. If the result is not a
223
     * boolean, it is coerced to a boolean value.
224
     *
225
     * @param mixed|self $expression
226
     *
227
     * @return $this
228
     */
229 6
    public function case($expression)
230
    {
231 6
        $this->requiresSwitchStatement(static::class . '::case');
232
233 4
        $this->switchBranch = ['case' => $expression];
234
235 4
        return $this;
236
    }
237
238
    /**
239
     * Returns the smallest integer greater than or equal to the specified number.
240
     *
241
     * The <number> expression can be any valid expression as long as it
242
     * resolves to a number.
243
     *
244
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/ceil/
245
     * @param mixed|self $number
246
     * @return $this
247
     *
248
     */
249 3
    public function ceil($number)
250
    {
251 3
        return $this->operator('$ceil', $number);
252
    }
253
254
    /**
255
     * Compares two values and returns:
256
     * -1 if the first value is less than the second.
257
     * 1 if the first value is greater than the second.
258
     * 0 if the two values are equivalent.
259
     *
260
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/cmp/
261
     * @param mixed|self $expression1
262
     * @param mixed|self $expression2
263
     * @return $this
264
     */
265 3
    public function cmp($expression1, $expression2)
266
    {
267 3
        return $this->operator('$cmp', [$expression1, $expression2]);
268
    }
269
270
    /**
271
     * Concatenates strings and returns the concatenated string.
272
     *
273
     * The arguments can be any valid expression as long as they resolve to
274
     * strings. If the argument resolves to a value of null or refers to a field
275
     * that is missing, $concat returns null.
276
     *
277
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/concat/
278
     * @param mixed|self $expression1
279
     * @param mixed|self $expression2
280
     * @param mixed|self ...$expressions Additional expressions
281
     * @return $this
282
     */
283 9
    public function concat($expression1, $expression2, ...$expressions)
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...
284
    {
285 9
        return $this->operator('$concat', func_get_args());
286
    }
287
288
    /**
289
     * Concatenates arrays to return the concatenated array.
290
     *
291
     * The <array> expressions can be any valid expression as long as they
292
     * resolve to an array.
293
     *
294
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/concatArrays/
295
     * @param mixed|self $array1
296
     * @param mixed|self $array2
297
     * @param mixed|self ...$arrays Additional expressions
298
     * @return $this
299
     *
300
     */
301 6
    public function concatArrays($array1, $array2, ...$arrays)
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...
302
    {
303 6
        return $this->operator('$concatArrays', func_get_args());
304
    }
305
306
    /**
307
     * Evaluates a boolean expression to return one of the two specified return
308
     * expressions.
309
     *
310
     * The arguments can be any valid expression.
311
     *
312
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/cond/
313
     * @param mixed|self $if
314
     * @param mixed|self $then
315
     * @param mixed|self $else
316
     * @return $this
317
     */
318 10
    public function cond($if, $then, $else)
319
    {
320 10
        return $this->operator('$cond', ['if' => $if, 'then' => $then, 'else' => $else]);
321
    }
322
323
    /**
324
     * Converts an expression object into an array, recursing into nested items
325
     *
326
     * For expression objects, it calls getExpression on the expression object.
327
     * For arrays, it recursively calls itself for each array item. Other values
328
     * are returned directly.
329
     *
330
     * @param mixed|self $expression
331
     * @return string|array
332
     * @internal
333
     */
334 1
    public static function convertExpression($expression)
335
    {
336 1
        if (is_array($expression)) {
337
            return array_map(['static', 'convertExpression'], $expression);
338 1
        } elseif ($expression instanceof self) {
339 1
            return $expression->getExpression();
340
        }
341
342
        return $expression;
343
    }
344
345
    /**
346
     * Converts a date object to a string according to a user-specified format.
347
     *
348
     * The format string can be any string literal, containing 0 or more format
349
     * specifiers.
350
     * The date argument can be any expression as long as it resolves to a date.
351
     *
352
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dateToString/
353
     * @param string     $format
354
     * @param mixed|self $expression
355
     * @return $this
356
     */
357 3
    public function dateToString($format, $expression)
358
    {
359 3
        return $this->operator('$dateToString', ['format' => $format, 'date' => $expression]);
360
    }
361
362
    /**
363
     * Returns the day of the month for a date as a number between 1 and 31.
364
     *
365
     * The argument can be any expression as long as it resolves to a date.
366
     *
367
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfMonth/
368
     * @param mixed|self $expression
369
     * @return $this
370
     */
371 7
    public function dayOfMonth($expression)
372
    {
373 7
        return $this->operator('$dayOfMonth', $expression);
374
    }
375
376
    /**
377
     * Returns the day of the week for a date as a number between 1 (Sunday) and
378
     * 7 (Saturday).
379
     *
380
     * The argument can be any expression as long as it resolves to a date.
381
     *
382
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfWeek/
383
     * @param mixed|self $expression
384
     * @return $this
385
     */
386 7
    public function dayOfWeek($expression)
387
    {
388 7
        return $this->operator('$dayOfWeek', $expression);
389
    }
390
391
    /**
392
     * Returns the day of the year for a date as a number between 1 and 366.
393
     *
394
     * The argument can be any expression as long as it resolves to a date.
395
     *
396
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfYear/
397
     * @param mixed|self $expression
398
     * @return $this
399
     */
400 3
    public function dayOfYear($expression)
401
    {
402 3
        return $this->operator('$dayOfYear', $expression);
403
    }
404
405
    /**
406
     * Adds a default statement for the current $switch operator.
407
     *
408
     * Requires {@link switch()} to be called first. The argument can be any
409
     * valid expression.
410
     *
411
     * Note: if no default is specified and no branch evaluates to true, the
412
     * $switch operator throws an error.
413
     *
414
     * @param mixed|self $expression
415
     *
416
     * @return $this
417
     */
418 4
    public function default($expression)
419
    {
420 4
        $this->requiresSwitchStatement(static::class . '::default');
421
422 2
        if ($this->currentField) {
423
            $this->expr[$this->currentField]['$switch']['default'] = $this->ensureArray($expression);
424
        } else {
425 2
            $this->expr['$switch']['default'] = $this->ensureArray($expression);
426
        }
427
428 2
        return $this;
429
    }
430
431
    /**
432
     * Divides one number by another and returns the result. The first argument
433
     * is divided by the second argument.
434
     *
435
     * The arguments can be any valid expression as long as the resolve to numbers.
436
     *
437
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/divide/
438
     * @param mixed|self $expression1
439
     * @param mixed|self $expression2
440
     * @return $this
441
     */
442 3
    public function divide($expression1, $expression2)
443
    {
444 3
        return $this->operator('$divide', [$expression1, $expression2]);
445
    }
446
447
    /**
448
     * Compares two values and returns whether the are equivalent.
449
     *
450
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/eq/
451
     * @param mixed|self $expression1
452
     * @param mixed|self $expression2
453
     * @return $this
454
     */
455 9
    public function eq($expression1, $expression2)
456
    {
457 9
        return $this->operator('$eq', [$expression1, $expression2]);
458
    }
459
460
    /**
461
     * Raises Euler’s number to the specified exponent and returns the result.
462
     *
463
     * The <exponent> expression can be any valid expression as long as it
464
     * resolves to a number.
465
     *
466
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/exp/
467
     * @param mixed|self $exponent
468
     * @return $this
469
     *
470
     */
471 3
    public function exp($exponent)
472
    {
473 3
        return $this->operator('$exp', $exponent);
474
    }
475
476
    /**
477
     * Returns a new expression object
478
     *
479
     * @return static
480
     *
481
     */
482 4
    public function expr()
483
    {
484 4
        return new static($this->dm, $this->class);
485
    }
486
487
    /**
488
     * Allows any expression to be used as a field value.
489
     *
490
     * @see http://docs.mongodb.org/manual/meta/aggregation-quick-reference/#aggregation-expressions
491
     * @param mixed|self $value
492
     * @return $this
493
     */
494 12
    public function expression($value)
495
    {
496 12
        $this->requiresCurrentField(__METHOD__);
497 11
        $this->expr[$this->currentField] = $this->ensureArray($value);
498
499 11
        return $this;
500
    }
501
502
    /**
503
     * Set the current field for building the expression.
504
     *
505
     * @param string $fieldName
506
     * @return $this
507
     */
508 139
    public function field($fieldName)
509
    {
510 139
        $fieldName = $this->getDocumentPersister()->prepareFieldName($fieldName);
511 139
        $this->currentField = (string) $fieldName;
512
513 139
        return $this;
514
    }
515
516
    /**
517
     * Selects a subset of the array to return based on the specified condition.
518
     *
519
     * Returns an array with only those elements that match the condition. The
520
     * returned elements are in the original order.
521
     *
522
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/filter/
523
     * @param mixed|self $input
524
     * @param mixed|self $as
525
     * @param mixed|self $cond
526
     * @return $this
527
     *
528
     */
529 3
    public function filter($input, $as, $cond)
530
    {
531 3
        return $this->operator('$filter', ['input' => $input, 'as' => $as, 'cond' => $cond]);
532
    }
533
534
    /**
535
     * Returns the value that results from applying an expression to the first
536
     * document in a group of documents that share the same group by key. Only
537
     * meaningful when documents are in a defined order.
538
     *
539
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/first/
540
     * @param mixed|self $expression
541
     * @return $this
542
     */
543 2
    public function first($expression)
544
    {
545 2
        return $this->operator('$first', $expression);
546
    }
547
548
    /**
549
     * Returns the largest integer less than or equal to the specified number.
550
     *
551
     * The <number> expression can be any valid expression as long as it
552
     * resolves to a number.
553
     *
554
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/floor/
555
     * @param mixed|self $number
556
     * @return $this
557
     *
558
     */
559 3
    public function floor($number)
560
    {
561 3
        return $this->operator('$floor', $number);
562
    }
563
564
    /**
565
     * @return array
566
     */
567 339
    public function getExpression()
568
    {
569 339
        return $this->expr;
570
    }
571
572
    /**
573
     * Compares two values and returns:
574
     * true when the first value is greater than the second value.
575
     * false when the first value is less than or equivalent to the second
576
     * value.
577
     *
578
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/gt/
579
     * @param mixed|self $expression1
580
     * @param mixed|self $expression2
581
     * @return $this
582
     */
583 3
    public function gt($expression1, $expression2)
584
    {
585 3
        return $this->operator('$gt', [$expression1, $expression2]);
586
    }
587
588
    /**
589
     * Compares two values and returns:
590
     * true when the first value is greater than or equivalent to the second
591
     * value.
592
     * false when the first value is less than the second value.
593
     *
594
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/gte/
595
     * @param mixed|self $expression1
596
     * @param mixed|self $expression2
597
     * @return $this
598
     */
599 6
    public function gte($expression1, $expression2)
600
    {
601 6
        return $this->operator('$gte', [$expression1, $expression2]);
602
    }
603
604
    /**
605
     * Returns the hour portion of a date as a number between 0 and 23.
606
     *
607
     * The argument can be any expression as long as it resolves to a date.
608
     *
609
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/hour/
610
     * @param mixed|self $expression
611
     * @return $this
612
     */
613 3
    public function hour($expression)
614
    {
615 3
        return $this->operator('$hour', $expression);
616
    }
617
618
    /**
619
     * Evaluates an expression and returns the value of the expression if the
620
     * expression evaluates to a non-null value. If the expression evaluates to
621
     * a null value, including instances of undefined values or missing fields,
622
     * returns the value of the replacement expression.
623
     *
624
     * The arguments can be any valid expression.
625
     *
626
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ifNull/
627
     * @param mixed|self $expression
628
     * @param mixed|self $replacementExpression
629
     * @return $this
630
     */
631 3
    public function ifNull($expression, $replacementExpression)
632
    {
633 3
        return $this->operator('$ifNull', [$expression, $replacementExpression]);
634
    }
635
636
    /**
637
     * Returns a boolean indicating whether a specified value is in an array.
638
     *
639
     * Unlike the $in query operator, the aggregation $in operator does not
640
     * support matching by regular expressions.
641
     *
642
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/in/
643
     * @param mixed|self $expression
644
     * @param mixed|self $arrayExpression
645
     * @return $this
646
     */
647 3
    public function in($expression, $arrayExpression)
648
    {
649 3
        return $this->operator('$in', [$expression, $arrayExpression]);
650
    }
651
652
    /**
653
     * Searches an array for an occurrence of a specified value and returns the
654
     * array index (zero-based) of the first occurrence. If the value is not
655
     * found, returns -1.
656
     *
657
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfArray/
658
     * @param mixed|self $arrayExpression  Can be any valid expression as long as it resolves to an array.
659
     * @param mixed|self $searchExpression Can be any valid expression.
660
     * @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.
661
     * @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.
662
     * @return $this
663
     */
664 12 View Code Duplication
    public function indexOfArray($arrayExpression, $searchExpression, $start = null, $end = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
665
    {
666 12
        $args = [$arrayExpression, $searchExpression];
667 12
        if ($start !== null) {
668 6
            $args[] = $start;
669
670 6
            if ($end !== null) {
671 3
                $args[] = $end;
672
            }
673
        }
674
675 12
        return $this->operator('$indexOfArray', $args);
676
    }
677
678
    /**
679
     * Searches a string for an occurrence of a substring and returns the UTF-8
680
     * byte index (zero-based) of the first occurrence. If the substring is not
681
     * found, returns -1.
682
     *
683
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfBytes/
684
     * @param mixed|self $stringExpression    Can be any valid expression as long as it resolves to a string.
685
     * @param mixed|self $substringExpression Can be any valid expression as long as it resolves to a string.
686
     * @param 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.
687
     * @param 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.
688
     *
689
     * @return $this
690
     */
691 12 View Code Duplication
    public function indexOfBytes($stringExpression, $substringExpression, $start = null, $end = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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('$indexOfBytes', $args);
703
    }
704
705
    /**
706
     * Searches a string for an occurrence of a substring and returns the UTF-8
707
     * code point index (zero-based) of the first occurrence. If the substring is
708
     * not found, returns -1.
709
     *
710
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfCP/
711
     * @param mixed|self $stringExpression    Can be any valid expression as long as it resolves to a string.
712
     * @param mixed|self $substringExpression Can be any valid expression as long as it resolves to a string.
713
     * @param 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.
714
     * @param 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.
715
     *
716
     * @return $this
717
     */
718 12 View Code Duplication
    public function indexOfCP($stringExpression, $substringExpression, $start = null, $end = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
719
    {
720 12
        $args = [$stringExpression, $substringExpression];
721 12
        if ($start !== null) {
722 6
            $args[] = $start;
723
724 6
            if ($end !== null) {
725 3
                $args[] = $end;
726
            }
727
        }
728
729 12
        return $this->operator('$indexOfCP', $args);
730
    }
731
732
    /**
733
     * Determines if the operand is an array. Returns a boolean.
734
     *
735
     * The <expression> can be any valid expression.
736
     *
737
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/isArray/
738
     * @param mixed|self $expression
739
     * @return $this
740
     *
741
     */
742 3
    public function isArray($expression)
743
    {
744 3
        return $this->operator('$isArray', $expression);
745
    }
746
747
    /**
748
     * Returns the weekday number in ISO 8601 format, ranging from 1 (for Monday)
749
     * to 7 (for Sunday).
750
     *
751
     * The argument can be any expression as long as it resolves to a date.
752
     *
753
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/isoDayOfWeek/
754
     * @param mixed|self $expression
755
     * @return $this
756
     */
757 3
    public function isoDayOfWeek($expression)
758
    {
759 3
        return $this->operator('$isoDayOfWeek', $expression);
760
    }
761
762
    /**
763
     * Returns the week number in ISO 8601 format, ranging from 1 to 53.
764
     *
765
     * Week numbers start at 1 with the week (Monday through Sunday) that
766
     * contains the year’s first Thursday.
767
     *
768
     * The argument can be any expression as long as it resolves to a date.
769
     *
770
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/isoWeek/
771
     * @param mixed|self $expression
772
     * @return $this
773
     */
774 3
    public function isoWeek($expression)
775
    {
776 3
        return $this->operator('$isoWeek', $expression);
777
    }
778
779
    /**
780
     * Returns the year number in ISO 8601 format.
781
     *
782
     * The year starts with the Monday of week 1 (ISO 8601) and ends with the
783
     * Sunday of the last week (ISO 8601).
784
     *
785
     * The argument can be any expression as long as it resolves to a date.
786
     *
787
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/isoWeek/
788
     * @param mixed|self $expression
789
     * @return $this
790
     */
791 3
    public function isoWeekYear($expression)
792
    {
793 3
        return $this->operator('$isoWeekYear', $expression);
794
    }
795
796
    /**
797
     * Returns the value that results from applying an expression to the last
798
     * document in a group of documents that share the same group by a field.
799
     * Only meaningful when documents are in a defined order.
800
     *
801
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/last/
802
     * @param mixed|self $expression
803
     * @return $this
804
     */
805 2
    public function last($expression)
806
    {
807 2
        return $this->operator('$last', $expression);
808
    }
809
810
    /**
811
     * Binds variables for use in the specified expression, and returns the
812
     * result of the expression.
813
     *
814
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/let/
815
     * @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.
816
     * @param mixed|self $in   The expression to evaluate.
817
     * @return $this
818
     */
819 3
    public function let($vars, $in)
820
    {
821 3
        return $this->operator('$let', ['vars' => $vars, 'in' => $in]);
822
    }
823
824
    /**
825
     * Returns a value without parsing. Use for values that the aggregation
826
     * pipeline may interpret as an expression.
827
     *
828
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/literal/
829
     * @param mixed|self $value
830
     * @return $this
831
     */
832 3
    public function literal($value)
833
    {
834 3
        return $this->operator('$literal', $value);
835
    }
836
837
    /**
838
     * Calculates the natural logarithm ln (i.e loge) of a number and returns
839
     * the result as a double.
840
     *
841
     * The <number> expression can be any valid expression as long as it
842
     * resolves to a non-negative number.
843
     *
844
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/log/
845
     * @param mixed|self $number
846
     * @return $this
847
     *
848
     */
849 3
    public function ln($number)
850
    {
851 3
        return $this->operator('$ln', $number);
852
    }
853
854
    /**
855
     * Calculates the log of a number in the specified base and returns the
856
     * result as a double.
857
     *
858
     * The <number> expression can be any valid expression as long as it
859
     * resolves to a non-negative number.
860
     * The <base> expression can be any valid expression as long as it resolves
861
     * to a positive number greater than 1.
862
     *
863
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/log/
864
     * @param mixed|self $number
865
     * @param mixed|self $base
866
     * @return $this
867
     *
868
     */
869 3
    public function log($number, $base)
870
    {
871 3
        return $this->operator('$log', [$number, $base]);
872
    }
873
874
    /**
875
     * Calculates the log base 10 of a number and returns the result as a double.
876
     *
877
     * The <number> expression can be any valid expression as long as it
878
     * resolves to a non-negative number.
879
     *
880
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/log10/
881
     * @param mixed|self $number
882
     * @return $this
883
     *
884
     */
885 3
    public function log10($number)
886
    {
887 3
        return $this->operator('$log10', $number);
888
    }
889
890
    /**
891
     * Compares two values and returns:
892
     * true when the first value is less than the second value.
893
     * false when the first value is greater than or equivalent to the second
894
     * value.
895
     *
896
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/lt/
897
     * @param mixed|self $expression1
898
     * @param mixed|self $expression2
899
     * @return $this
900
     */
901 4
    public function lt($expression1, $expression2)
902
    {
903 4
        return $this->operator('$lt', [$expression1, $expression2]);
904
    }
905
906
    /**
907
     * Compares two values and returns:
908
     * true when the first value is less than or equivalent to the second value.
909
     * false when the first value is greater than the second value.
910
     *
911
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/lte/
912
     * @param mixed|self $expression1
913
     * @param mixed|self $expression2
914
     * @return $this
915
     */
916 6
    public function lte($expression1, $expression2)
917
    {
918 6
        return $this->operator('$lte', [$expression1, $expression2]);
919
    }
920
921
    /**
922
     * Applies an expression to each item in an array and returns an array with
923
     * the applied results.
924
     *
925
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/map/
926
     * @param mixed|self $input An expression that resolves to an array.
927
     * @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.
928
     * @param mixed|self $in    The expression to apply to each item in the input array. The expression accesses the item by its variable name.
929
     * @return $this
930
     */
931 3
    public function map($input, $as, $in)
932
    {
933 3
        return $this->operator('$map', ['input' => $input, 'as' => $as, 'in' => $in]);
934
    }
935
936
    /**
937
     * Returns the highest value that results from applying an expression to
938
     * each document in a group of documents that share the same group by key.
939
     *
940
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/max/
941
     * @param mixed|self $expression
942
     * @return $this
943
     */
944 3
    public function max($expression)
945
    {
946 3
        return $this->operator('$max', $expression);
947
    }
948
949
    /**
950
     * Returns the metadata associated with a document in a pipeline operations.
951
     *
952
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/meta/
953
     * @param mixed|self $metaDataKeyword
954
     * @return $this
955
     */
956 3
    public function meta($metaDataKeyword)
957
    {
958 3
        return $this->operator('$meta', $metaDataKeyword);
959
    }
960
961
    /**
962
     * Returns the millisecond portion of a date as an integer between 0 and 999.
963
     *
964
     * The argument can be any expression as long as it resolves to a date.
965
     *
966
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/millisecond/
967
     * @param mixed|self $expression
968
     * @return $this
969
     */
970 3
    public function millisecond($expression)
971
    {
972 3
        return $this->operator('$millisecond', $expression);
973
    }
974
975
    /**
976
     * Returns the lowest value that results from applying an expression to each
977
     * document in a group of documents that share the same group by key.
978
     *
979
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/min/
980
     * @param mixed|self $expression
981
     * @return $this
982
     */
983 3
    public function min($expression)
984
    {
985 3
        return $this->operator('$min', $expression);
986
    }
987
988
    /**
989
     * Returns the minute portion of a date as a number between 0 and 59.
990
     *
991
     * The argument can be any expression as long as it resolves to a date.
992
     *
993
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/minute/
994
     * @param mixed|self $expression
995
     * @return $this
996
     */
997 3
    public function minute($expression)
998
    {
999 3
        return $this->operator('$minute', $expression);
1000
    }
1001
1002
    /**
1003
     * Divides one number by another and returns the remainder. The first
1004
     * argument is divided by the second argument.
1005
     *
1006
     * The arguments can be any valid expression as long as they resolve to numbers.
1007
     *
1008
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/mod/
1009
     * @param mixed|self $expression1
1010
     * @param mixed|self $expression2
1011
     * @return $this
1012
     */
1013 3
    public function mod($expression1, $expression2)
1014
    {
1015 3
        return $this->operator('$mod', [$expression1, $expression2]);
1016
    }
1017
1018
    /**
1019
     * Returns the month of a date as a number between 1 and 12.
1020
     *
1021
     * The argument can be any expression as long as it resolves to a date.
1022
     *
1023
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/month/
1024
     * @param mixed|self $expression
1025
     * @return $this
1026
     */
1027 3
    public function month($expression)
1028
    {
1029 3
        return $this->operator('$month', $expression);
1030
    }
1031
1032
    /**
1033
     * Multiplies numbers together and returns the result.
1034
     *
1035
     * The arguments can be any valid expression as long as they resolve to numbers.
1036
     *
1037
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/multiply/
1038
     * @param mixed|self $expression1
1039
     * @param mixed|self $expression2
1040
     * @param mixed|self ...$expressions Additional expressions
1041
     * @return $this
1042
     */
1043 13
    public function multiply($expression1, $expression2, ...$expressions)
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...
1044
    {
1045 13
        return $this->operator('$multiply', func_get_args());
1046
    }
1047
1048
    /**
1049
     * Compares two values and returns:
1050
     * true when the values are not equivalent.
1051
     * false when the values are equivalent.
1052
     *
1053
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ne/
1054
     * @param mixed|self $expression1
1055
     * @param mixed|self $expression2
1056
     * @return $this
1057
     */
1058 4
    public function ne($expression1, $expression2)
1059
    {
1060 4
        return $this->operator('$ne', [$expression1, $expression2]);
1061
    }
1062
1063
    /**
1064
     * Evaluates a boolean and returns the opposite boolean value.
1065
     *
1066
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/not/
1067
     * @param mixed|self $expression
1068
     * @return $this
1069
     */
1070 3
    public function not($expression)
1071
    {
1072 3
        return $this->operator('$not', $expression);
1073
    }
1074
1075
    /**
1076
     * Raises a number to the specified exponent and returns the result.
1077
     *
1078
     * The <number> expression can be any valid expression as long as it
1079
     * resolves to a non-negative number.
1080
     * The <exponent> expression can be any valid expression as long as it
1081
     * resolves to a number.
1082
     *
1083
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/pow/
1084
     * @param mixed|self $number
1085
     * @param mixed|self $exponent
1086
     * @return $this
1087
     *
1088
     */
1089 3
    public function pow($number, $exponent)
1090
    {
1091 3
        return $this->operator('$pow', [$number, $exponent]);
1092
    }
1093
1094
    /**
1095
     * Returns an array of all values that result from applying an expression to
1096
     * each document in a group of documents that share the same group by key.
1097
     *
1098
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/push/
1099
     * @param mixed|self $expression
1100
     * @return $this
1101
     */
1102 2
    public function push($expression)
1103
    {
1104 2
        return $this->operator('$push', $expression);
1105
    }
1106
1107
    /**
1108
     * Returns an array whose elements are a generated sequence of numbers.
1109
     *
1110
     * $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.
1111
     *
1112
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/range/
1113
     * @param mixed|self $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer.
1114
     * @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.
1115
     * @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.
1116
     * @return $this
1117
     */
1118 6
    public function range($start, $end, $step = 1)
1119
    {
1120 6
        return $this->operator('$range', [$start, $end, $step]);
1121
    }
1122
1123
    /**
1124
     * Applies an expression to each element in an array and combines them into
1125
     * a single value.
1126
     *
1127
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/reduce/
1128
     * @param mixed|self $input        Can be any valid expression that resolves to an array.
1129
     * @param mixed|self $initialValue The initial cumulative value set before in is applied to the first element of the input array.
1130
     * @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.
1131
     * @return $this
1132
     */
1133 3
    public function reduce($input, $initialValue, $in)
1134
    {
1135 3
        return $this->operator('$reduce', ['input' => $input, 'initialValue' => $initialValue, 'in' => $in]);
1136
    }
1137
1138
    /**
1139
     * Accepts an array expression as an argument and returns an array with the
1140
     * elements in reverse order.
1141
     *
1142
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/reverseArray/
1143
     * @param mixed|self $expression
1144
     * @return $this
1145
     */
1146 3
    public function reverseArray($expression)
1147
    {
1148 3
        return $this->operator('$reverseArray', $expression);
1149
    }
1150
1151
    /**
1152
     * Returns the second portion of a date as a number between 0 and 59, but
1153
     * can be 60 to account for leap seconds.
1154
     *
1155
     * The argument can be any expression as long as it resolves to a date.
1156
     *
1157
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/second/
1158
     * @param mixed|self $expression
1159
     * @return $this
1160
     */
1161 3
    public function second($expression)
1162
    {
1163 3
        return $this->operator('$second', $expression);
1164
    }
1165
1166
    /**
1167
     * Takes two sets and returns an array containing the elements that only
1168
     * exist in the first set.
1169
     *
1170
     * The arguments can be any valid expression as long as they each resolve to an array.
1171
     *
1172
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setDifference/
1173
     * @param mixed|self $expression1
1174
     * @param mixed|self $expression2
1175
     * @return $this
1176
     */
1177 3
    public function setDifference($expression1, $expression2)
1178
    {
1179 3
        return $this->operator('$setDifference', [$expression1, $expression2]);
1180
    }
1181
1182
    /**
1183
     * Compares two or more arrays and returns true if they have the same
1184
     * distinct elements and false otherwise.
1185
     *
1186
     * The arguments can be any valid expression as long as they each resolve to an array.
1187
     *
1188
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setEquals/
1189
     * @param mixed|self $expression1
1190
     * @param mixed|self $expression2
1191
     * @param mixed|self ...$expressions Additional sets
1192
     * @return $this
1193
     */
1194 6
    public function setEquals($expression1, $expression2, ...$expressions)
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...
1195
    {
1196 6
        return $this->operator('$setEquals', func_get_args());
1197
    }
1198
1199
    /**
1200
     * Takes two or more arrays and returns an array that contains the elements
1201
     * that appear in every input array.
1202
     *
1203
     * The arguments can be any valid expression as long as they each resolve to an array.
1204
     *
1205
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setIntersection/
1206
     * @param mixed|self $expression1
1207
     * @param mixed|self $expression2
1208
     * @param mixed|self ...$expressions Additional sets
1209
     * @return $this
1210
     */
1211 6
    public function setIntersection($expression1, $expression2, ...$expressions)
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...
1212
    {
1213 6
        return $this->operator('$setIntersection', func_get_args());
1214
    }
1215
1216
    /**
1217
     * Takes two arrays and returns true when the first array is a subset of the
1218
     * second, including when the first array equals the second array, and false otherwise.
1219
     *
1220
     * The arguments can be any valid expression as long as they each resolve to an array.
1221
     *
1222
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setIsSubset/
1223
     * @param mixed|self $expression1
1224
     * @param mixed|self $expression2
1225
     * @return $this
1226
     */
1227 3
    public function setIsSubset($expression1, $expression2)
1228
    {
1229 3
        return $this->operator('$setIsSubset', [$expression1, $expression2]);
1230
    }
1231
1232
    /**
1233
     * Takes two or more arrays and returns an array containing the elements
1234
     * that appear in any input array.
1235
     *
1236
     * The arguments can be any valid expression as long as they each resolve to an array.
1237
     *
1238
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setUnion/
1239
     * @param mixed|self $expression1
1240
     * @param mixed|self $expression2
1241
     * @param mixed|self ...$expressions Additional sets
1242
     * @return $this
1243
     */
1244 6
    public function setUnion($expression1, $expression2, ...$expressions)
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...
1245
    {
1246 6
        return $this->operator('$setUnion', func_get_args());
1247
    }
1248
1249
    /**
1250
     * Counts and returns the total the number of items in an array.
1251
     *
1252
     * The argument can be any expression as long as it resolves to an array.
1253
     *
1254
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/size/
1255
     * @param mixed|self $expression
1256
     * @return $this
1257
     */
1258 3
    public function size($expression)
1259
    {
1260 3
        return $this->operator('$size', $expression);
1261
    }
1262
1263
    /**
1264
     * Returns a subset of an array.
1265
     *
1266
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/slice/
1267
     * @param mixed|self      $array
1268
     * @param mixed|self      $n
1269
     * @param mixed|self|null $position
1270
     * @return $this
1271
     *
1272
     */
1273 6
    public function slice($array, $n, $position = null)
1274
    {
1275 6
        if ($position === null) {
1276 3
            return $this->operator('$slice', [$array, $n]);
1277
        }
1278
1279 3
        return $this->operator('$slice', [$array, $position, $n]);
1280
    }
1281
1282
    /**
1283
     * Divides a string into an array of substrings based on a delimiter.
1284
     *
1285
     * $split removes the delimiter and returns the resulting substrings as
1286
     * elements of an array. If the delimiter is not found in the string, $split
1287
     * returns the original string as the only element of an array.
1288
     *
1289
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/split/
1290
     * @param mixed|self $string    The string to be split. Can be any valid expression as long as it resolves to a string.
1291
     * @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.
1292
     *
1293
     * @return $this
1294
     */
1295 3
    public function split($string, $delimiter)
1296
    {
1297 3
        return $this->operator('$split', [$string, $delimiter]);
1298
    }
1299
1300
    /**
1301
     * Calculates the square root of a positive number and returns the result as
1302
     * a double.
1303
     *
1304
     * The argument can be any valid expression as long as it resolves to a
1305
     * non-negative number.
1306
     *
1307
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/sqrt/
1308
     * @param mixed|self $expression
1309
     * @return $this
1310
     */
1311 3
    public function sqrt($expression)
1312
    {
1313 3
        return $this->operator('$sqrt', $expression);
1314
    }
1315
1316
    /**
1317
     * Calculates the population standard deviation of the input values.
1318
     *
1319
     * The arguments can be any expression as long as it resolves to an array.
1320
     *
1321
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/stdDevPop/
1322
     * @param mixed|self $expression1
1323
     * @param mixed|self ...$expressions Additional samples
1324
     * @return $this
1325
     *
1326
     */
1327 5
    public function stdDevPop($expression1, ...$expressions)
1328
    {
1329 5
        $expression = (empty($expressions)) ? $expression1 : func_get_args();
1330
1331 5
        return $this->operator('$stdDevPop', $expression);
1332
    }
1333
1334
    /**
1335
     * Calculates the sample standard deviation of the input values.
1336
     *
1337
     * The arguments can be any expression as long as it resolves to an array.
1338
     *
1339
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/stdDevSamp/
1340
     * @param mixed|self $expression1
1341
     * @param mixed|self ...$expressions Additional samples
1342
     * @return $this
1343
     *
1344
     */
1345 5
    public function stdDevSamp($expression1, ...$expressions)
1346
    {
1347 5
        $expression = (empty($expressions)) ? $expression1 : func_get_args();
1348
1349 5
        return $this->operator('$stdDevSamp', $expression);
1350
    }
1351
1352
    /**
1353
     * Performs case-insensitive comparison of two strings. Returns
1354
     * 1 if first string is “greater than” the second string.
1355
     * 0 if the two strings are equal.
1356
     * -1 if the first string is “less than” the second string.
1357
     *
1358
     * The arguments can be any valid expression as long as they resolve to strings.
1359
     *
1360
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/strcasecmp/
1361
     * @param mixed|self $expression1
1362
     * @param mixed|self $expression2
1363
     * @return $this
1364
     */
1365 3
    public function strcasecmp($expression1, $expression2)
1366
    {
1367 3
        return $this->operator('$strcasecmp', [$expression1, $expression2]);
1368
    }
1369
1370
    /**
1371
     * Returns the number of UTF-8 encoded bytes in the specified string.
1372
     *
1373
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/strLenBytes/
1374
     * @param mixed|self $string
1375
     *
1376
     * @return $this
1377
     */
1378 3
    public function strLenBytes($string)
1379
    {
1380 3
        return $this->operator('$strLenBytes', $string);
1381
    }
1382
1383
    /**
1384
     * Returns the number of UTF-8 code points in the specified string.
1385
     *
1386
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/strLenCP/
1387
     * @param mixed|self $string
1388
     *
1389
     * @return $this
1390
     */
1391 3
    public function strLenCP($string)
1392
    {
1393 3
        return $this->operator('$strLenCP', $string);
1394
    }
1395
1396
    /**
1397
     * Returns a substring of a string, starting at a specified index position
1398
     * and including the specified number of characters. The index is zero-based.
1399
     *
1400
     * 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.
1401
     *
1402
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/substr/
1403
     * @param mixed|self $string
1404
     * @param mixed|self $start
1405
     * @param mixed|self $length
1406
     * @return $this
1407
     */
1408 3
    public function substr($string, $start, $length)
1409
    {
1410 3
        return $this->operator('$substr', [$string, $start, $length]);
1411
    }
1412
1413
    /**
1414
     * Returns the substring of a string.
1415
     *
1416
     * The substring starts with the character at the specified UTF-8 byte index
1417
     * (zero-based) in the string and continues for the number of bytes
1418
     * specified.
1419
     *
1420
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/substrBytes/
1421
     * @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.
1422
     * @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.
1423
     * @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.
1424
     *
1425
     * @return $this
1426
     */
1427 3
    public function substrBytes($string, $start, $count)
1428
    {
1429 3
        return $this->operator('$substrBytes', [$string, $start, $count]);
1430
    }
1431
1432
    /**
1433
     * Returns the substring of a string.
1434
     *
1435
     * The substring starts with the character at the specified UTF-8 code point
1436
     * (CP) index (zero-based) in the string for the number of code points
1437
     * specified.
1438
     *
1439
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/substrBytes/
1440
     * @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.
1441
     * @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.
1442
     * @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.
1443
     *
1444
     * @return $this
1445
     */
1446 3
    public function substrCP($string, $start, $count)
1447
    {
1448 3
        return $this->operator('$substrCP', [$string, $start, $count]);
1449
    }
1450
1451
    /**
1452
     * Subtracts two numbers to return the difference. The second argument is
1453
     * subtracted from the first argument.
1454
     *
1455
     * The arguments can be any valid expression as long as they resolve to numbers and/or dates.
1456
     *
1457
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/subtract/
1458
     * @param mixed|self $expression1
1459
     * @param mixed|self $expression2
1460
     * @return $this
1461
     */
1462 3
    public function subtract($expression1, $expression2)
1463
    {
1464 3
        return $this->operator('$subtract', [$expression1, $expression2]);
1465
    }
1466
1467
    /**
1468
     * Calculates and returns the sum of all the numeric values that result from
1469
     * applying a specified expression to each document in a group of documents
1470
     * that share the same group by key. Ignores nun-numeric values.
1471
     *
1472
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/sum/
1473
     * @param mixed|self $expression
1474
     * @return $this
1475
     */
1476 9
    public function sum($expression)
1477
    {
1478 9
        return $this->operator('$sum', $expression);
1479
    }
1480
1481
    /**
1482
     * Converts a string to lowercase, returning the result.
1483
     *
1484
     * The argument can be any expression as long as it resolves to a string.
1485
     *
1486
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/toLower/
1487
     * @param mixed|self $expression
1488
     * @return $this
1489
     */
1490 3
    public function toLower($expression)
1491
    {
1492 3
        return $this->operator('$toLower', $expression);
1493
    }
1494
1495
    /**
1496
     * Converts a string to uppercase, returning the result.
1497
     *
1498
     * The argument can be any expression as long as it resolves to a string.
1499
     *
1500
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/toUpper/
1501
     * @param mixed|self $expression
1502
     * @return $this
1503
     */
1504 3
    public function toUpper($expression)
1505
    {
1506 3
        return $this->operator('$toUpper', $expression);
1507
    }
1508
1509
    /**
1510
     * Truncates a number to its integer.
1511
     *
1512
     * The <number> expression can be any valid expression as long as it
1513
     * resolves to a number.
1514
     *
1515
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/trunc/
1516
     * @param mixed|self $number
1517
     * @return $this
1518
     *
1519
     */
1520 3
    public function trunc($number)
1521
    {
1522 3
        return $this->operator('$trunc', $number);
1523
    }
1524
1525
    /**
1526
     * Returns a string that specifies the BSON type of the argument.
1527
     *
1528
     * The argument can be any valid expression.
1529
     *
1530
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/type/
1531
     * @param mixed|self $expression
1532
     *
1533
     * @return $this
1534
     */
1535 3
    public function type($expression)
1536
    {
1537 3
        return $this->operator('$type', $expression);
1538
    }
1539
1540
    /**
1541
     * Returns the week of the year for a date as a number between 0 and 53.
1542
     *
1543
     * The argument can be any expression as long as it resolves to a date.
1544
     *
1545
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/week/
1546
     * @param mixed|self $expression
1547
     * @return $this
1548
     */
1549 3
    public function week($expression)
1550
    {
1551 3
        return $this->operator('$week', $expression);
1552
    }
1553
1554
    /**
1555
     * Returns the year portion of a date.
1556
     *
1557
     * The argument can be any expression as long as it resolves to a date.
1558
     *
1559
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/year/
1560
     * @param mixed|self $expression
1561
     * @return $this
1562
     */
1563 4
    public function year($expression)
1564
    {
1565 4
        return $this->operator('$year', $expression);
1566
    }
1567
1568
    /**
1569
     * Transposes an array of input arrays so that the first element of the
1570
     * output array would be an array containing, the first element of the first
1571
     * input array, the first element of the second input array, etc.
1572
     *
1573
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/zip/
1574
     * @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.
1575
     * @param bool|null       $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array.
1576
     * @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.
1577
     * @return $this
1578
     */
1579 9
    public function zip($inputs, $useLongestLength = null, $defaults = null)
1580
    {
1581 9
        $args = ['inputs' => $inputs];
1582 9
        if ($useLongestLength !== null) {
1583 6
            $args['useLongestLength'] = $useLongestLength;
1584
        }
1585 9
        if ($defaults !== null) {
1586 3
            $args['defaults'] = $defaults;
1587
        }
1588
1589 9
        return $this->operator('$zip', $args);
1590
    }
1591
1592
1593
    /**
1594
     * @param mixed|self $expression
1595
     * @return mixed
1596
     */
1597 343
    private function ensureArray($expression)
1598
    {
1599 343
        if (is_string($expression) && substr($expression, 0, 1) === '$') {
1600 341
            return '$' . $this->getDocumentPersister()->prepareFieldName(substr($expression, 1));
1601 217
        } elseif (is_array($expression)) {
1602 209
            return array_map([$this, 'ensureArray'], $expression);
1603 87
        } elseif ($expression instanceof self) {
1604 20
            return $expression->getExpression();
1605
        }
1606
1607
        // Convert PHP types to MongoDB types for everything else
1608 85
        return Type::convertPHPToDatabaseValue($expression);
1609
    }
1610
1611
    /**
1612
     * @return DocumentPersister
1613
     */
1614 343
    private function getDocumentPersister()
1615
    {
1616 343
        return $this->dm->getUnitOfWork()->getDocumentPersister($this->class->name);
1617
    }
1618
1619
    /**
1620
     * Defines an operator and value on the expression.
1621
     *
1622
     * If there is a current field, the operator will be set on it; otherwise,
1623
     * the operator is set at the top level of the query.
1624
     *
1625
     * @param string            $operator
1626
     * @param array|self[]|self $expression
1627
     * @return $this
1628
     */
1629 341
    private function operator($operator, $expression)
1630
    {
1631 341
        if ($this->currentField) {
1632 137
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
1633
        } else {
1634 212
            $this->expr[$operator] = $this->ensureArray($expression);
1635
        }
1636
1637 341
        return $this;
1638
    }
1639
1640
    /**
1641
     * Ensure that a current field has been set.
1642
     *
1643
     * @param string $method
1644
     *
1645
     * @throws \LogicException If a current field has not been set.
1646
     */
1647 12
    private function requiresCurrentField($method = null)
1648
    {
1649 12
        if (! $this->currentField) {
1650 1
            throw new \LogicException(($method ?: 'This method') . ' requires you set a current field using field().');
1651
        }
1652 11
    }
1653
1654
    /**
1655
     * @param string $method
1656
     *
1657
     * @throws \BadMethodCallException If there is no current switch operator.
1658
     */
1659 8
    private function requiresSwitchStatement($method = null)
1660
    {
1661 8
        $message = ($method ?: 'This method') . ' requires a valid switch statement (call switch() first).';
1662
1663 8
        if ($this->currentField) {
1664
            if (! isset($this->expr[$this->currentField]['$switch'])) {
1665
                throw new \BadMethodCallException($message);
1666
            }
1667 8
        } elseif (! isset($this->expr['$switch'])) {
1668 4
            throw new \BadMethodCallException($message);
1669
        }
1670 4
    }
1671
1672
    /**
1673
     * Evaluates a series of case expressions. When it finds an expression which
1674
     * evaluates to true, $switch executes a specified expression and breaks out
1675
     * of the control flow.
1676
     *
1677
     * To add statements, use the {@link case()}, {@link then()} and
1678
     * {@link default()} methods.
1679
     *
1680
     * @return $this
1681
     */
1682 4
    public function switch()
1683
    {
1684 4
        $this->operator('$switch', []);
1685
1686 4
        return $this;
1687
    }
1688
1689
    /**
1690
     * Adds a case statement for the current branch of the $switch operator.
1691
     *
1692
     * Requires {@link case()} to be called first. The argument can be any valid
1693
     * expression.
1694
     *
1695
     * @param mixed|self $expression
1696
     *
1697
     * @return $this
1698
     */
1699 6
    public function then($expression)
1700
    {
1701 6
        if (! is_array($this->switchBranch)) {
1702 4
            throw new \BadMethodCallException(static::class . '::then requires a valid case statement (call case() first).');
1703
        }
1704
1705 4
        $this->switchBranch['then'] = $expression;
1706
1707 4
        if ($this->currentField) {
1708
            $this->expr[$this->currentField]['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
1709
        } else {
1710 4
            $this->expr['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
1711
        }
1712
1713 4
        $this->switchBranch = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $switchBranch.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1714
1715 4
        return $this;
1716
    }
1717
}
1718