Completed
Push — master ( 11f27c...4713a5 )
by Andreas
08:33
created

Expr::requiresSwitchStatement()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.3906

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 6
cts 8
cp 0.75
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 7
nc 8
nop 1
crap 5.3906
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ODM\MongoDB\Aggregation;
21
22
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
23
use Doctrine\ODM\MongoDB\DocumentManager;
24
use Doctrine\ODM\MongoDB\Types\Type;
25
26
/**
27
 * Fluent interface for building aggregation pipelines.
28
 */
29
class Expr
30
{
31
    /**
32
     * @var DocumentManager
33
     */
34
    private $dm;
35
36
    /**
37
     * @var ClassMetadata
38
     */
39
    private $class;
40
41
    /**
42
     * @var array
43
     */
44
    private $expr = [];
45
46
    /**
47
     * The current field we are operating on.
48
     *
49
     * @var string
50
     */
51
    private $currentField;
52
53
    /**
54
     * @var array
55
     */
56
    private $switchBranch;
57
58
    /**
59
     * @inheritDoc
60
     */
61 367
    public function __construct(DocumentManager $dm, ClassMetadata $class)
62
    {
63 367
        $this->dm = $dm;
64 367
        $this->class = $class;
65 367
    }
66
67
    /**
68
     * @param string $method
69
     * @param array $args
70
     * @return $this
71
     */
72 10
    public function __call($method, $args)
73
    {
74 10
        $internalMethodName = $method . 'Internal';
75 10
        if (! is_callable([$this, $internalMethodName])) {
76
            throw new \BadMethodCallException('The method ' . $method . ' does not exist.');
77
        }
78
79 10
        return $this->$internalMethodName(...$args);
80
    }
81
82
    /**
83
     * Returns the absolute value of a number.
84
     *
85
     * The <number> argument can be any valid expression as long as it resolves
86
     * to a number.
87
     *
88
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/abs/
89
     * @param mixed|self $number
90
     * @return $this
91
     *
92
     * @since 1.3
93
     */
94 3
    public function abs($number)
95
    {
96 3
        return $this->operator('$abs', $number);
97
    }
98
99
    /**
100
     * Adds numbers together or adds numbers and a date. If one of the arguments
101
     * is a date, $add treats the other arguments as milliseconds to add to the
102
     * date.
103
     *
104
     * The arguments can be any valid expression as long as they resolve to
105
     * either all numbers or to numbers and a date.
106
     *
107
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/add/
108
     * @param mixed|self $expression1
109
     * @param mixed|self $expression2
110
     * @param mixed|self $expression3,... Additional expressions
0 ignored issues
show
Bug introduced by
There is no parameter named $expression3,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

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

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
300
     * @return $this
301
     */
302 9
    public function concat($expression1, $expression2 /* , $expression3, ... */)
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...
303
    {
304 9
        return $this->operator('$concat', func_get_args());
305
    }
306
307
    /**
308
     * Concatenates arrays to return the concatenated array.
309
     *
310
     * The <array> expressions can be any valid expression as long as they
311
     * resolve to an array.
312
     *
313
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/concatArrays/
314
     * @param mixed|self $array1
315
     * @param mixed|self $array2
316
     * @param mixed|self $array3, ... Additional expressions
0 ignored issues
show
Bug introduced by
There is no parameter named $array3,. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

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

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1078
     * @return $this
1079
     */
1080 13
    public function multiply($expression1, $expression2 /* , $expression3, ... */)
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...
1081
    {
1082 13
        return $this->operator('$multiply', func_get_args());
1083
    }
1084
1085
    /**
1086
     * Compares two values and returns:
1087
     * true when the values are not equivalent.
1088
     * false when the values are equivalent.
1089
     *
1090
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ne/
1091
     * @param mixed|self $expression1
1092
     * @param mixed|self $expression2
1093
     * @return $this
1094
     */
1095 4
    public function ne($expression1, $expression2)
1096
    {
1097 4
        return $this->operator('$ne', [$expression1, $expression2]);
1098
    }
1099
1100
    /**
1101
     * Evaluates a boolean and returns the opposite boolean value.
1102
     *
1103
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/not/
1104
     * @param mixed|self $expression
1105
     * @return $this
1106
     */
1107 3
    public function not($expression)
1108
    {
1109 3
        return $this->operator('$not', $expression);
1110
    }
1111
1112
    /**
1113
     * Raises a number to the specified exponent and returns the result.
1114
     *
1115
     * The <number> expression can be any valid expression as long as it
1116
     * resolves to a non-negative number.
1117
     * The <exponent> expression can be any valid expression as long as it
1118
     * resolves to a number.
1119
     *
1120
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/pow/
1121
     * @param mixed|self $number
1122
     * @param mixed|self $exponent
1123
     * @return $this
1124
     *
1125
     * @since 1.3
1126
     */
1127 3
    public function pow($number, $exponent)
1128
    {
1129 3
        return $this->operator('$pow', [$number, $exponent]);
1130
    }
1131
1132
    /**
1133
     * Returns an array of all values that result from applying an expression to
1134
     * each document in a group of documents that share the same group by key.
1135
     *
1136
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/push/
1137
     * @param mixed|self $expression
1138
     * @return $this
1139
     */
1140 2
    public function push($expression)
1141
    {
1142 2
        return $this->operator('$push', $expression);
1143
    }
1144
1145
    /**
1146
     * Returns an array whose elements are a generated sequence of numbers.
1147
     *
1148
     * $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.
1149
     *
1150
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/range/
1151
     * @since 1.5
1152
     * @param mixed|self $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer.
1153
     * @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.
1154
     * @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.
1155
     * @return $this
1156
     */
1157 6
    public function range($start, $end, $step = 1)
1158
    {
1159 6
        return $this->operator('$range', [$start, $end, $step]);
1160
    }
1161
1162
    /**
1163
     * Applies an expression to each element in an array and combines them into
1164
     * a single value.
1165
     *
1166
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/reduce/
1167
     * @since 1.5
1168
     * @param mixed|self $input Can be any valid expression that resolves to an array.
1169
     * @param mixed|self $initialValue The initial cumulative value set before in is applied to the first element of the input array.
1170
     * @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.
1171
     * @return $this
1172
     */
1173 3
    public function reduce($input, $initialValue, $in)
1174
    {
1175 3
        return $this->operator('$reduce', ['input' => $input, 'initialValue' => $initialValue, 'in' => $in]);
1176
    }
1177
1178
    /**
1179
     * Accepts an array expression as an argument and returns an array with the
1180
     * elements in reverse order.
1181
     *
1182
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/reverseArray/
1183
     * @since 1.5
1184
     * @param mixed|self $expression
1185
     * @return $this
1186
     */
1187 3
    public function reverseArray($expression)
1188
    {
1189 3
        return $this->operator('$reverseArray', $expression);
1190
    }
1191
1192
    /**
1193
     * Returns the second portion of a date as a number between 0 and 59, but
1194
     * can be 60 to account for leap seconds.
1195
     *
1196
     * The argument can be any expression as long as it resolves to a date.
1197
     *
1198
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/second/
1199
     * @param mixed|self $expression
1200
     * @return $this
1201
     */
1202 3
    public function second($expression)
1203
    {
1204 3
        return $this->operator('$second', $expression);
1205
    }
1206
1207
    /**
1208
     * Takes two sets and returns an array containing the elements that only
1209
     * exist in the first set.
1210
     *
1211
     * The arguments can be any valid expression as long as they each resolve to an array.
1212
     *
1213
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setDifference/
1214
     * @param mixed|self $expression1
1215
     * @param mixed|self $expression2
1216
     * @return $this
1217
     */
1218 3
    public function setDifference($expression1, $expression2)
1219
    {
1220 3
        return $this->operator('$setDifference', [$expression1, $expression2]);
1221
    }
1222
1223
    /**
1224
     * Compares two or more arrays and returns true if they have the same
1225
     * distinct elements and false otherwise.
1226
     *
1227
     * The arguments can be any valid expression as long as they each resolve to an array.
1228
     *
1229
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setEquals/
1230
     * @param mixed|self $expression1
1231
     * @param mixed|self $expression2
1232
     * @param mixed|self $expression3,...   Additional sets
0 ignored issues
show
Bug introduced by
There is no parameter named $expression3,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1233
     * @return $this
1234
     */
1235 6
    public function setEquals($expression1, $expression2 /* , $expression3, ... */)
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...
1236
    {
1237 6
        return $this->operator('$setEquals', func_get_args());
1238
    }
1239
1240
    /**
1241
     * Takes two or more arrays and returns an array that contains the elements
1242
     * that appear in every input array.
1243
     *
1244
     * The arguments can be any valid expression as long as they each resolve to an array.
1245
     *
1246
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setIntersection/
1247
     * @param mixed|self $expression1
1248
     * @param mixed|self $expression2
1249
     * @param mixed|self $expression3,...   Additional sets
0 ignored issues
show
Bug introduced by
There is no parameter named $expression3,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1250
     * @return $this
1251
     */
1252 6
    public function setIntersection($expression1, $expression2 /* , $expression3, ... */)
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...
1253
    {
1254 6
        return $this->operator('$setIntersection', func_get_args());
1255
    }
1256
1257
    /**
1258
     * Takes two arrays and returns true when the first array is a subset of the
1259
     * second, including when the first array equals the second array, and false otherwise.
1260
     *
1261
     * The arguments can be any valid expression as long as they each resolve to an array.
1262
     *
1263
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setIsSubset/
1264
     * @param mixed|self $expression1
1265
     * @param mixed|self $expression2
1266
     * @return $this
1267
     */
1268 3
    public function setIsSubset($expression1, $expression2)
1269
    {
1270 3
        return $this->operator('$setIsSubset', [$expression1, $expression2]);
1271
    }
1272
1273
    /**
1274
     * Takes two or more arrays and returns an array containing the elements
1275
     * that appear in any input array.
1276
     *
1277
     * The arguments can be any valid expression as long as they each resolve to an array.
1278
     *
1279
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/setUnion/
1280
     * @param mixed|self $expression1
1281
     * @param mixed|self $expression2
1282
     * @param mixed|self $expression3,...   Additional sets
0 ignored issues
show
Bug introduced by
There is no parameter named $expression3,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1283
     * @return $this
1284
     */
1285 6
    public function setUnion($expression1, $expression2 /* , $expression3, ... */)
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...
1286
    {
1287 6
        return $this->operator('$setUnion', func_get_args());
1288
    }
1289
1290
    /**
1291
     * Counts and returns the total the number of items in an array.
1292
     *
1293
     * The argument can be any expression as long as it resolves to an array.
1294
     *
1295
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/size/
1296
     * @param mixed|self $expression
1297
     * @return $this
1298
     */
1299 3
    public function size($expression)
1300
    {
1301 3
        return $this->operator('$size', $expression);
1302
    }
1303
1304
    /**
1305
     * Returns a subset of an array.
1306
     *
1307
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/slice/
1308
     * @param mixed|self $array
1309
     * @param mixed|self $n
1310
     * @param mixed|self|null $position
1311
     * @return $this
1312
     *
1313
     * @since 1.3
1314
     */
1315 6
    public function slice($array, $n, $position = null)
1316
    {
1317 6
        if ($position === null) {
1318 3
            return $this->operator('$slice', [$array, $n]);
1319
        } else {
1320 3
            return $this->operator('$slice', [$array, $position, $n]);
1321
        }
1322
    }
1323
1324
    /**
1325
     * Divides a string into an array of substrings based on a delimiter.
1326
     *
1327
     * $split removes the delimiter and returns the resulting substrings as
1328
     * elements of an array. If the delimiter is not found in the string, $split
1329
     * returns the original string as the only element of an array.
1330
     *
1331
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/split/
1332
     * @since 1.5
1333
     * @param mixed|self $string The string to be split. Can be any valid expression as long as it resolves to a string.
1334
     * @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.
1335
     *
1336
     * @return $this
1337
     */
1338 3
    public function split($string, $delimiter)
1339
    {
1340 3
        return $this->operator('$split', [$string, $delimiter]);
1341
    }
1342
1343
    /**
1344
     * Calculates the square root of a positive number and returns the result as
1345
     * a double.
1346
     *
1347
     * The argument can be any valid expression as long as it resolves to a
1348
     * non-negative number.
1349
     *
1350
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/sqrt/
1351
     * @param mixed|self $expression
1352
     * @return $this
1353
     */
1354 3
    public function sqrt($expression)
1355
    {
1356 3
        return $this->operator('$sqrt', $expression);
1357
    }
1358
1359
    /**
1360
     * Calculates the population standard deviation of the input values.
1361
     *
1362
     * The arguments can be any expression as long as it resolves to an array.
1363
     *
1364
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/stdDevPop/
1365
     * @param mixed|self $expression1
1366
     * @param mixed|self $expression2,... Additional samples
0 ignored issues
show
Bug introduced by
There is no parameter named $expression2,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1367
     * @return $this
1368
     *
1369
     * @since 1.3
1370
     */
1371 5
    public function stdDevPop($expression1 /* , $expression2, ... */)
1372
    {
1373 5
        $expression = (func_num_args() === 1) ? $expression1 : func_get_args();
1374
1375 5
        return $this->operator('$stdDevPop', $expression);
1376
    }
1377
1378
    /**
1379
     * Calculates the sample standard deviation of the input values.
1380
     *
1381
     * The arguments can be any expression as long as it resolves to an array.
1382
     *
1383
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/stdDevSamp/
1384
     * @param mixed|self $expression1
1385
     * @param mixed|self $expression2,... Additional samples
0 ignored issues
show
Bug introduced by
There is no parameter named $expression2,.... Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1386
     * @return $this
1387
     *
1388
     * @since 1.3
1389
     */
1390 5
    public function stdDevSamp($expression1 /* , $expression2, ... */)
1391
    {
1392 5
        $expression = (func_num_args() === 1) ? $expression1 : func_get_args();
1393
1394 5
        return $this->operator('$stdDevSamp', $expression);
1395
    }
1396
1397
    /**
1398
     * Performs case-insensitive comparison of two strings. Returns
1399
     * 1 if first string is “greater than” the second string.
1400
     * 0 if the two strings are equal.
1401
     * -1 if the first string is “less than” the second string.
1402
     *
1403
     * The arguments can be any valid expression as long as they resolve to strings.
1404
     *
1405
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/strcasecmp/
1406
     * @param mixed|self $expression1
1407
     * @param mixed|self $expression2
1408
     * @return $this
1409
     */
1410 3
    public function strcasecmp($expression1, $expression2)
1411
    {
1412 3
        return $this->operator('$strcasecmp', [$expression1, $expression2]);
1413
    }
1414
1415
    /**
1416
     * Returns the number of UTF-8 encoded bytes in the specified string.
1417
     *
1418
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/strLenBytes/
1419
     * @since 1.5
1420
     * @param mixed|self $string
1421
     *
1422
     * @return $this
1423
     */
1424 3
    public function strLenBytes($string)
1425
    {
1426 3
        return $this->operator('$strLenBytes', $string);
1427
    }
1428
1429
    /**
1430
     * Returns the number of UTF-8 code points in the specified string.
1431
     *
1432
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/strLenCP/
1433
     * @since 1.5
1434
     * @param mixed|self $string
1435
     *
1436
     * @return $this
1437
     */
1438 3
    public function strLenCP($string)
1439
    {
1440 3
        return $this->operator('$strLenCP', $string);
1441
    }
1442
1443
    /**
1444
     * Returns a substring of a string, starting at a specified index position
1445
     * and including the specified number of characters. The index is zero-based.
1446
     *
1447
     * 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.
1448
     *
1449
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/substr/
1450
     * @param mixed|self $string
1451
     * @param mixed|self $start
1452
     * @param mixed|self $length
1453
     * @return $this
1454
     */
1455 3
    public function substr($string, $start, $length)
1456
    {
1457 3
        return $this->operator('$substr', [$string, $start, $length]);
1458
    }
1459
1460
    /**
1461
     * Returns the substring of a string.
1462
     *
1463
     * The substring starts with the character at the specified UTF-8 byte index
1464
     * (zero-based) in the string and continues for the number of bytes
1465
     * specified.
1466
     *
1467
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/substrBytes/
1468
     * @since 1.5
1469
     * @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.
1470
     * @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.
1471
     * @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.
1472
     *
1473
     * @return $this
1474
     */
1475 3
    public function substrBytes($string, $start, $count)
1476
    {
1477 3
        return $this->operator('$substrBytes', [$string, $start, $count]);
1478
    }
1479
1480
    /**
1481
     * Returns the substring of a string.
1482
     *
1483
     * The substring starts with the character at the specified UTF-8 code point
1484
     * (CP) index (zero-based) in the string for the number of code points
1485
     * specified.
1486
     *
1487
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/substrBytes/
1488
     * @since 1.5
1489
     * @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.
1490
     * @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.
1491
     * @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.
1492
     *
1493
     * @return $this
1494
     */
1495 3
    public function substrCP($string, $start, $count)
1496
    {
1497 3
        return $this->operator('$substrCP', [$string, $start, $count]);
1498
    }
1499
1500
    /**
1501
     * Subtracts two numbers to return the difference. The second argument is
1502
     * subtracted from the first argument.
1503
     *
1504
     * The arguments can be any valid expression as long as they resolve to numbers and/or dates.
1505
     *
1506
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/subtract/
1507
     * @param mixed|self $expression1
1508
     * @param mixed|self $expression2
1509
     * @return $this
1510
     */
1511 3
    public function subtract($expression1, $expression2)
1512
    {
1513 3
        return $this->operator('$subtract', [$expression1, $expression2]);
1514
    }
1515
1516
    /**
1517
     * Calculates and returns the sum of all the numeric values that result from
1518
     * applying a specified expression to each document in a group of documents
1519
     * that share the same group by key. Ignores nun-numeric values.
1520
     *
1521
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/sum/
1522
     * @param mixed|self $expression
1523
     * @return $this
1524
     */
1525 9
    public function sum($expression)
1526
    {
1527 9
        return $this->operator('$sum', $expression);
1528
    }
1529
1530
    /**
1531
     * Converts a string to lowercase, returning the result.
1532
     *
1533
     * The argument can be any expression as long as it resolves to a string.
1534
     *
1535
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/toLower/
1536
     * @param mixed|self $expression
1537
     * @return $this
1538
     */
1539 3
    public function toLower($expression)
1540
    {
1541 3
        return $this->operator('$toLower', $expression);
1542
    }
1543
1544
    /**
1545
     * Converts a string to uppercase, returning the result.
1546
     *
1547
     * The argument can be any expression as long as it resolves to a string.
1548
     *
1549
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/toUpper/
1550
     * @param mixed|self $expression
1551
     * @return $this
1552
     */
1553 3
    public function toUpper($expression)
1554
    {
1555 3
        return $this->operator('$toUpper', $expression);
1556
    }
1557
1558
    /**
1559
     * Truncates a number to its integer.
1560
     *
1561
     * The <number> expression can be any valid expression as long as it
1562
     * resolves to a number.
1563
     *
1564
     * @see https://docs.mongodb.org/manual/reference/operator/aggregation/trunc/
1565
     * @param mixed|self $number
1566
     * @return $this
1567
     *
1568
     * @since 1.3
1569
     */
1570 3
    public function trunc($number)
1571
    {
1572 3
        return $this->operator('$trunc', $number);
1573
    }
1574
1575
    /**
1576
     * Returns a string that specifies the BSON type of the argument.
1577
     *
1578
     * The argument can be any valid expression.
1579
     *
1580
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/type/
1581
     * @since 1.5
1582
     * @param mixed|self $expression
1583
     *
1584
     * @return $this
1585
     */
1586 3
    public function type($expression)
1587
    {
1588 3
        return $this->operator('$type', $expression);
1589
    }
1590
1591
    /**
1592
     * Returns the week of the year for a date as a number between 0 and 53.
1593
     *
1594
     * The argument can be any expression as long as it resolves to a date.
1595
     *
1596
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/week/
1597
     * @param mixed|self $expression
1598
     * @return $this
1599
     */
1600 3
    public function week($expression)
1601
    {
1602 3
        return $this->operator('$week', $expression);
1603
    }
1604
1605
    /**
1606
     * Returns the year portion of a date.
1607
     *
1608
     * The argument can be any expression as long as it resolves to a date.
1609
     *
1610
     * @see http://docs.mongodb.org/manual/reference/operator/aggregation/year/
1611
     * @param mixed|self $expression
1612
     * @return $this
1613
     */
1614 4
    public function year($expression)
1615
    {
1616 4
        return $this->operator('$year', $expression);
1617
    }
1618
1619
    /**
1620
     * Transposes an array of input arrays so that the first element of the
1621
     * output array would be an array containing, the first element of the first
1622
     * input array, the first element of the second input array, etc.
1623
     *
1624
     * @see https://docs.mongodb.com/manual/reference/operator/aggregation/zip/
1625
     * @since 1.5
1626
     * @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.
1627
     * @param bool|null $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array.
1628
     * @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.
1629
     * @return $this
1630
     */
1631 9
    public function zip($inputs, $useLongestLength = null, $defaults = null)
1632
    {
1633 9
        $args = ['inputs' => $inputs];
1634 9
        if ($useLongestLength !== null) {
1635 6
            $args['useLongestLength'] = $useLongestLength;
1636
        }
1637 9
        if ($defaults !== null) {
1638 3
            $args['defaults'] = $defaults;
1639
        }
1640
1641 9
        return $this->operator('$zip', $args);
1642
    }
1643
1644
1645
    /**
1646
     * @param mixed|self $expression
1647
     * @return mixed
1648
     */
1649 343
    private function ensureArray($expression)
1650
    {
1651 343
        if (is_string($expression) && substr($expression, 0, 1) === '$') {
1652 341
            return '$' . $this->getDocumentPersister()->prepareFieldName(substr($expression, 1));
1653 217
        } elseif (is_array($expression)) {
1654 209
            return array_map([$this, 'ensureArray'], $expression);
1655 87
        } elseif ($expression instanceof self) {
1656 20
            return $expression->getExpression();
1657
        }
1658
1659
        // Convert PHP types to MongoDB types for everything else
1660 85
        return Type::convertPHPToDatabaseValue($expression);
1661
    }
1662
1663
    /**
1664
     * @return \Doctrine\ODM\MongoDB\Persisters\DocumentPersister
1665
     */
1666 343
    private function getDocumentPersister()
1667
    {
1668 343
        return $this->dm->getUnitOfWork()->getDocumentPersister($this->class->name);
0 ignored issues
show
Bug introduced by
Accessing name on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
1669
    }
1670
1671
    /**
1672
     * Defines an operator and value on the expression.
1673
     *
1674
     * If there is a current field, the operator will be set on it; otherwise,
1675
     * the operator is set at the top level of the query.
1676
     *
1677
     * @param string $operator
1678
     * @param array|self[]|self $expression
1679
     * @return $this
1680
     */
1681 341
    private function operator($operator, $expression)
1682
    {
1683 341
        if ($this->currentField) {
1684 137
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
1685
        } else {
1686 212
            $this->expr[$operator] = $this->ensureArray($expression);
1687
        }
1688
1689 341
        return $this;
1690
    }
1691
1692
    /**
1693
     * Ensure that a current field has been set.
1694
     *
1695
     * @param string $method
1696
     *
1697
     * @throws \LogicException if a current field has not been set
1698
     */
1699 12
    private function requiresCurrentField($method = null)
1700
    {
1701 12
        if ( ! $this->currentField) {
1702 1
            throw new \LogicException(($method ?: 'This method') . ' requires you set a current field using field().');
1703
        }
1704 11
    }
1705
1706
    /**
1707
     * @param string $method
1708
     *
1709
     * @throws \BadMethodCallException if there is no current switch operator
1710
     */
1711 8
    private function requiresSwitchStatement($method = null)
1712
    {
1713 8
        $message = ($method ?: 'This method') . ' requires a valid switch statement (call switch() first).';
1714
1715 8
        if ($this->currentField) {
1716
            if (! isset($this->expr[$this->currentField]['$switch'])) {
1717
                throw new \BadMethodCallException($message);
1718
            }
1719 8
        } elseif (! isset($this->expr['$switch'])) {
1720 4
            throw new \BadMethodCallException($message);
1721
        }
1722 4
    }
1723
1724
    /**
1725
     * Evaluates a series of case expressions. When it finds an expression which
1726
     * evaluates to true, $switch executes a specified expression and breaks out
1727
     * of the control flow.
1728
     *
1729
     * To add statements, use the {@link case()}, {@link then()} and
1730
     * {@link default()} methods.
1731
     *
1732
     * @return $this
1733
     *
1734
     * @deprecated Method will be renamed to "switch" in next major version
1735
     */
1736 4
    private function switchInternal()
1737
    {
1738 4
        $this->operator('$switch', []);
1739
1740 4
        return $this;
1741
    }
1742
1743
    /**
1744
     * Adds a case statement for the current branch of the $switch operator.
1745
     *
1746
     * Requires {@link case()} to be called first. The argument can be any valid
1747
     * expression.
1748
     *
1749
     * @param mixed|self $expression
1750
     *
1751
     * @return $this
1752
     *
1753
     * @deprecated Method will be renamed to "then" in next major version
1754
     */
1755 6
    private function thenInternal($expression)
1756
    {
1757 6
        if (! is_array($this->switchBranch)) {
1758 4
            throw new \BadMethodCallException(static::class . '::then requires a valid case statement (call case() first).');
1759
        }
1760
1761 4
        $this->switchBranch['then'] = $expression;
1762
1763 4
        if ($this->currentField) {
1764
            $this->expr[$this->currentField]['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
1765
        } else {
1766 4
            $this->expr['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
1767
        }
1768
1769 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...
1770
1771 4
        return $this;
1772
    }
1773
1774
}
1775