diff --git a/generator/config/accumulator/accumulator.yaml b/generator/config/accumulator/accumulator.yaml index e90fbbf52..9cfdb6b53 100644 --- a/generator/config/accumulator/accumulator.yaml +++ b/generator/config/accumulator/accumulator.yaml @@ -73,7 +73,7 @@ tests: function(state, numCopies) { return { count: state.count + 1, sum: state.sum + numCopies } } - accumulateArgs: [ "$copies" ], + accumulateArgs: [ "$copies" ] merge: $code: |- function(state1, state2) { @@ -115,8 +115,7 @@ tests: } return state; } - accumulateArgs: - - '$name' + accumulateArgs: ['$name'] merge: $code: |- function(state1, state2) { diff --git a/generator/src/OperatorClassGenerator.php b/generator/src/OperatorClassGenerator.php index 7f8667751..6fd80cc41 100644 --- a/generator/src/OperatorClassGenerator.php +++ b/generator/src/OperatorClassGenerator.php @@ -135,6 +135,18 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition $constructorParam->setDefaultValue($argument->default); } + if ($type->dollarPrefixedString) { + $namespace->addUseFunction('is_string'); + $namespace->addUseFunction('str_starts_with'); + $namespace->addUse(InvalidArgumentException::class); + $constructor->addBody(<<propertyName}) && ! str_starts_with(\${$argument->propertyName}, '$')) { + throw new InvalidArgumentException('Argument \${$argument->propertyName} can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + + PHP); + } + // List type must be validated with array_is_list() if ($type->list) { $namespace->addUseFunction('is_array'); diff --git a/generator/src/OperatorGenerator.php b/generator/src/OperatorGenerator.php index 0b9c60748..ffe0bb369 100644 --- a/generator/src/OperatorGenerator.php +++ b/generator/src/OperatorGenerator.php @@ -26,6 +26,7 @@ use function ltrim; use function sort; use function sprintf; +use function str_starts_with; use function ucfirst; use function usort; @@ -71,13 +72,19 @@ final protected function getType(string $type): ExpressionDefinition * Expression types can contain class names, interface, native types or "list". * PHPDoc types are more precise than native types, so we use them systematically even if redundant. * - * @return object{native:string,doc:string,use:list,list:bool,query:bool,javascript:bool} + * @return object{native:string,doc:string,use:list,list:bool,query:bool,javascript:bool,dollarPrefixedString:bool} */ final protected function getAcceptedTypes(ArgumentDefinition $arg): stdClass { $nativeTypes = []; + $dollarPrefixedString = false; + foreach ($arg->type as $type) { + if (str_starts_with($type, 'resolvesTo')) { + $dollarPrefixedString = true; + } + $type = $this->getType($type); $nativeTypes = array_merge($nativeTypes, $type->acceptedTypes); @@ -91,6 +98,14 @@ final protected function getAcceptedTypes(ArgumentDefinition $arg): stdClass $nativeTypes[] = Optional::class; } + // If the argument accepts an expression, a $-prefixed string is accepted (field path or variable) + // Checked only if the argument does not already accept a string + if (in_array('string', $nativeTypes, true)) { + $dollarPrefixedString = false; + } elseif ($dollarPrefixedString) { + $nativeTypes[] = 'string'; + } + $docTypes = $nativeTypes = array_unique($nativeTypes); $use = []; @@ -131,6 +146,7 @@ final protected function getAcceptedTypes(ArgumentDefinition $arg): stdClass 'list' => $listCheck, 'query' => $isQuery, 'javascript' => $isJavascript, + 'dollarPrefixedString' => $dollarPrefixedString, ]; } diff --git a/src/Builder/Accumulator/AccumulatorAccumulator.php b/src/Builder/Accumulator/AccumulatorAccumulator.php index a49390fd6..f26e5f7da 100644 --- a/src/Builder/Accumulator/AccumulatorAccumulator.php +++ b/src/Builder/Accumulator/AccumulatorAccumulator.php @@ -21,6 +21,7 @@ use function array_is_list; use function is_array; use function is_string; +use function str_starts_with; /** * Defines a custom accumulator function. @@ -50,8 +51,8 @@ final class AccumulatorAccumulator implements AccumulatorInterface, OperatorInte /** @var Javascript|string $accumulate Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String. */ public readonly Javascript|string $accumulate; - /** @var BSONArray|PackedArray|ResolvesToArray|array $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $accumulateArgs; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $accumulateArgs; /** @var Javascript|string $merge Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge. */ public readonly Javascript|string $merge; @@ -59,8 +60,8 @@ final class AccumulatorAccumulator implements AccumulatorInterface, OperatorInte /** @var string $lang The language used in the $accumulator code. */ public readonly string $lang; - /** @var Optional|BSONArray|PackedArray|ResolvesToArray|array $initArgs Arguments passed to the init function. */ - public readonly Optional|PackedArray|ResolvesToArray|BSONArray|array $initArgs; + /** @var Optional|BSONArray|PackedArray|ResolvesToArray|array|string $initArgs Arguments passed to the init function. */ + public readonly Optional|PackedArray|ResolvesToArray|BSONArray|array|string $initArgs; /** @var Optional|Javascript|string $finalize Function used to update the result of the accumulation. */ public readonly Optional|Javascript|string $finalize; @@ -68,19 +69,19 @@ final class AccumulatorAccumulator implements AccumulatorInterface, OperatorInte /** * @param Javascript|string $init Function used to initialize the state. The init function receives its arguments from the initArgs array expression. You can specify the function definition as either BSON type Code or String. * @param Javascript|string $accumulate Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String. - * @param BSONArray|PackedArray|ResolvesToArray|array $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. * @param Javascript|string $merge Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge. * @param string $lang The language used in the $accumulator code. - * @param Optional|BSONArray|PackedArray|ResolvesToArray|array $initArgs Arguments passed to the init function. + * @param Optional|BSONArray|PackedArray|ResolvesToArray|array|string $initArgs Arguments passed to the init function. * @param Optional|Javascript|string $finalize Function used to update the result of the accumulation. */ public function __construct( Javascript|string $init, Javascript|string $accumulate, - PackedArray|ResolvesToArray|BSONArray|array $accumulateArgs, + PackedArray|ResolvesToArray|BSONArray|array|string $accumulateArgs, Javascript|string $merge, string $lang, - Optional|PackedArray|ResolvesToArray|BSONArray|array $initArgs = Optional::Undefined, + Optional|PackedArray|ResolvesToArray|BSONArray|array|string $initArgs = Optional::Undefined, Optional|Javascript|string $finalize = Optional::Undefined, ) { if (is_string($init)) { @@ -93,6 +94,10 @@ public function __construct( } $this->accumulate = $accumulate; + if (is_string($accumulateArgs) && ! str_starts_with($accumulateArgs, '$')) { + throw new InvalidArgumentException('Argument $accumulateArgs can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($accumulateArgs) && ! array_is_list($accumulateArgs)) { throw new InvalidArgumentException('Expected $accumulateArgs argument to be a list, got an associative array.'); } @@ -104,6 +109,10 @@ public function __construct( $this->merge = $merge; $this->lang = $lang; + if (is_string($initArgs) && ! str_starts_with($initArgs, '$')) { + throw new InvalidArgumentException('Argument $initArgs can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($initArgs) && ! array_is_list($initArgs)) { throw new InvalidArgumentException('Expected $initArgs argument to be a list, got an associative array.'); } diff --git a/src/Builder/Accumulator/AvgAccumulator.php b/src/Builder/Accumulator/AvgAccumulator.php index 4b9050117..afbb1747b 100644 --- a/src/Builder/Accumulator/AvgAccumulator.php +++ b/src/Builder/Accumulator/AvgAccumulator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns an average of numerical values. Ignores non-numeric values. @@ -29,14 +33,18 @@ final class AvgAccumulator implements AccumulatorInterface, WindowInterface, Ope public const NAME = '$avg'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Accumulator/BottomNAccumulator.php b/src/Builder/Accumulator/BottomNAccumulator.php index 94911d25e..3733889de 100644 --- a/src/Builder/Accumulator/BottomNAccumulator.php +++ b/src/Builder/Accumulator/BottomNAccumulator.php @@ -17,8 +17,12 @@ use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Returns an aggregation of the bottom n elements within a group, according to the specified sort order. If the group contains fewer than n elements, $bottomN returns all elements in the group. * New in MongoDB 5.2. @@ -33,8 +37,8 @@ final class BottomNAccumulator implements AccumulatorInterface, WindowInterface, public const NAME = '$bottomN'; public const PROPERTIES = ['n' => 'n', 'sortBy' => 'sortBy', 'output' => 'output']; - /** @var ResolvesToInt|int $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. */ + public readonly ResolvesToInt|int|string $n; /** @var Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. */ public readonly Document|Serializable|stdClass|array $sortBy; @@ -43,15 +47,19 @@ final class BottomNAccumulator implements AccumulatorInterface, WindowInterface, public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; /** - * @param ResolvesToInt|int $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. + * @param ResolvesToInt|int|string $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ public function __construct( - ResolvesToInt|int $n, + ResolvesToInt|int|string $n, Document|Serializable|stdClass|array $sortBy, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; $this->sortBy = $sortBy; $this->output = $output; diff --git a/src/Builder/Accumulator/CovariancePopAccumulator.php b/src/Builder/Accumulator/CovariancePopAccumulator.php index d9bd9173e..d845320a2 100644 --- a/src/Builder/Accumulator/CovariancePopAccumulator.php +++ b/src/Builder/Accumulator/CovariancePopAccumulator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the population covariance of two numeric expressions. @@ -28,21 +32,29 @@ final class CovariancePopAccumulator implements WindowInterface, OperatorInterfa public const NAME = '$covariancePop'; public const PROPERTIES = ['expression1' => 'expression1', 'expression2' => 'expression2']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression1 */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression1; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression1; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression2 */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression2; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression2; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression1 - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression2 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $expression1, - Decimal128|Int64|ResolvesToNumber|float|int $expression2, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression2, ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression2 = $expression2; } } diff --git a/src/Builder/Accumulator/CovarianceSampAccumulator.php b/src/Builder/Accumulator/CovarianceSampAccumulator.php index 85ba2cf28..eacd66315 100644 --- a/src/Builder/Accumulator/CovarianceSampAccumulator.php +++ b/src/Builder/Accumulator/CovarianceSampAccumulator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the sample covariance of two numeric expressions. @@ -28,21 +32,29 @@ final class CovarianceSampAccumulator implements WindowInterface, OperatorInterf public const NAME = '$covarianceSamp'; public const PROPERTIES = ['expression1' => 'expression1', 'expression2' => 'expression2']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression1 */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression1; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression1; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression2 */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression2; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression2; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression1 - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression2 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $expression1, - Decimal128|Int64|ResolvesToNumber|float|int $expression2, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression2, ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression2 = $expression2; } } diff --git a/src/Builder/Accumulator/DerivativeAccumulator.php b/src/Builder/Accumulator/DerivativeAccumulator.php index 9ede80357..7db64533f 100644 --- a/src/Builder/Accumulator/DerivativeAccumulator.php +++ b/src/Builder/Accumulator/DerivativeAccumulator.php @@ -19,6 +19,10 @@ use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\TimeUnit; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the average rate of change within the specified window. @@ -33,8 +37,8 @@ final class DerivativeAccumulator implements WindowInterface, OperatorInterface public const NAME = '$derivative'; public const PROPERTIES = ['input' => 'input', 'unit' => 'unit']; - /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $input */ - public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $input; + /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input */ + public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input; /** * @var Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". @@ -43,14 +47,18 @@ final class DerivativeAccumulator implements WindowInterface, OperatorInterface public readonly Optional|ResolvesToString|TimeUnit|string $unit; /** - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $input + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input * @param Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. */ public function __construct( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $input, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input, Optional|ResolvesToString|TimeUnit|string $unit = Optional::Undefined, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; $this->unit = $unit; } diff --git a/src/Builder/Accumulator/ExpMovingAvgAccumulator.php b/src/Builder/Accumulator/ExpMovingAvgAccumulator.php index 2bfe285f8..8df134bbc 100644 --- a/src/Builder/Accumulator/ExpMovingAvgAccumulator.php +++ b/src/Builder/Accumulator/ExpMovingAvgAccumulator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the exponential moving average for the numeric expression. @@ -29,8 +33,8 @@ final class ExpMovingAvgAccumulator implements WindowInterface, OperatorInterfac public const NAME = '$expMovingAvg'; public const PROPERTIES = ['input' => 'input', 'N' => 'N', 'alpha' => 'alpha']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $input */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $input; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $input */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $input; /** * @var Optional|int $N An integer that specifies the number of historical documents that have a significant mathematical weight in the exponential moving average calculation, with the most recent documents contributing the most weight. @@ -46,7 +50,7 @@ final class ExpMovingAvgAccumulator implements WindowInterface, OperatorInterfac public readonly Optional|Int64|float|int $alpha; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $input + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input * @param Optional|int $N An integer that specifies the number of historical documents that have a significant mathematical weight in the exponential moving average calculation, with the most recent documents contributing the most weight. * You must specify either N or alpha. You cannot specify both. * The N value is used in this formula to calculate the current result based on the expression value from the current document being read and the previous result of the calculation: @@ -54,10 +58,14 @@ final class ExpMovingAvgAccumulator implements WindowInterface, OperatorInterfac * You must specify either N or alpha. You cannot specify both. */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $input, + Decimal128|Int64|ResolvesToNumber|float|int|string $input, Optional|int $N = Optional::Undefined, Optional|Int64|float|int $alpha = Optional::Undefined, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; $this->N = $N; $this->alpha = $alpha; diff --git a/src/Builder/Accumulator/FactoryTrait.php b/src/Builder/Accumulator/FactoryTrait.php index e3ab1f24e..512ff17bf 100644 --- a/src/Builder/Accumulator/FactoryTrait.php +++ b/src/Builder/Accumulator/FactoryTrait.php @@ -40,19 +40,19 @@ trait FactoryTrait * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator/ * @param Javascript|string $init Function used to initialize the state. The init function receives its arguments from the initArgs array expression. You can specify the function definition as either BSON type Code or String. * @param Javascript|string $accumulate Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String. - * @param BSONArray|PackedArray|ResolvesToArray|array $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $accumulateArgs Arguments passed to the accumulate function. You can use accumulateArgs to specify what field value(s) to pass to the accumulate function. * @param Javascript|string $merge Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge. * @param string $lang The language used in the $accumulator code. - * @param Optional|BSONArray|PackedArray|ResolvesToArray|array $initArgs Arguments passed to the init function. + * @param Optional|BSONArray|PackedArray|ResolvesToArray|array|string $initArgs Arguments passed to the init function. * @param Optional|Javascript|string $finalize Function used to update the result of the accumulation. */ public static function accumulator( Javascript|string $init, Javascript|string $accumulate, - PackedArray|ResolvesToArray|BSONArray|array $accumulateArgs, + PackedArray|ResolvesToArray|BSONArray|array|string $accumulateArgs, Javascript|string $merge, string $lang, - Optional|PackedArray|ResolvesToArray|BSONArray|array $initArgs = Optional::Undefined, + Optional|PackedArray|ResolvesToArray|BSONArray|array|string $initArgs = Optional::Undefined, Optional|Javascript|string $finalize = Optional::Undefined, ): AccumulatorAccumulator { return new AccumulatorAccumulator($init, $accumulate, $accumulateArgs, $merge, $lang, $initArgs, $finalize); @@ -76,9 +76,9 @@ public static function addToSet( * Changed in MongoDB 5.0: Available in the $setWindowFields stage. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public static function avg(Decimal128|Int64|ResolvesToNumber|float|int $expression): AvgAccumulator + public static function avg(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AvgAccumulator { return new AvgAccumulator($expression); } @@ -104,12 +104,12 @@ public static function bottom( * Available in the $group and $setWindowFields stages. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN/ - * @param ResolvesToInt|int $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. + * @param ResolvesToInt|int|string $n Limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ public static function bottomN( - ResolvesToInt|int $n, + ResolvesToInt|int|string $n, Document|Serializable|stdClass|array $sortBy, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, ): BottomNAccumulator { @@ -133,12 +133,12 @@ public static function count(): CountAccumulator * New in MongoDB 5.0. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/covariancePop/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression1 - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression2 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ public static function covariancePop( - Decimal128|Int64|ResolvesToNumber|float|int $expression1, - Decimal128|Int64|ResolvesToNumber|float|int $expression2, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression2, ): CovariancePopAccumulator { return new CovariancePopAccumulator($expression1, $expression2); } @@ -148,12 +148,12 @@ public static function covariancePop( * New in MongoDB 5.0. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/covarianceSamp/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression1 - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression2 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression2 */ public static function covarianceSamp( - Decimal128|Int64|ResolvesToNumber|float|int $expression1, - Decimal128|Int64|ResolvesToNumber|float|int $expression2, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression2, ): CovarianceSampAccumulator { return new CovarianceSampAccumulator($expression1, $expression2); } @@ -174,12 +174,12 @@ public static function denseRank(): DenseRankAccumulator * New in MongoDB 5.0. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/derivative/ - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $input + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input * @param Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. */ public static function derivative( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $input, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input, Optional|ResolvesToString|TimeUnit|string $unit = Optional::Undefined, ): DerivativeAccumulator { return new DerivativeAccumulator($input, $unit); @@ -201,7 +201,7 @@ public static function documentNumber(): DocumentNumberAccumulator * New in MongoDB 5.0. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/expMovingAvg/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $input + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input * @param Optional|int $N An integer that specifies the number of historical documents that have a significant mathematical weight in the exponential moving average calculation, with the most recent documents contributing the most weight. * You must specify either N or alpha. You cannot specify both. * The N value is used in this formula to calculate the current result based on the expression value from the current document being read and the previous result of the calculation: @@ -209,7 +209,7 @@ public static function documentNumber(): DocumentNumberAccumulator * You must specify either N or alpha. You cannot specify both. */ public static function expMovingAvg( - Decimal128|Int64|ResolvesToNumber|float|int $input, + Decimal128|Int64|ResolvesToNumber|float|int|string $input, Optional|int $N = Optional::Undefined, Optional|Int64|float|int $alpha = Optional::Undefined, ): ExpMovingAvgAccumulator { @@ -236,11 +236,11 @@ public static function first( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN/ * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input An expression that resolves to the array from which to return n elements. - * @param ResolvesToInt|int $n A positive integral expression that is either a constant or depends on the _id value for $group. + * @param ResolvesToInt|int|string $n A positive integral expression that is either a constant or depends on the _id value for $group. */ public static function firstN( Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input, - ResolvesToInt|int $n, + ResolvesToInt|int|string $n, ): FirstNAccumulator { return new FirstNAccumulator($input, $n); } @@ -250,12 +250,12 @@ public static function firstN( * New in MongoDB 5.0. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/integral/ - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $input + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input * @param Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. */ public static function integral( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $input, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input, Optional|ResolvesToString|TimeUnit|string $unit = Optional::Undefined, ): IntegralAccumulator { return new IntegralAccumulator($input, $unit); @@ -280,12 +280,12 @@ public static function last( * If the group contains fewer than n elements, $lastN returns all elements in the group. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ public static function lastN( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToInt|int $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, ): LastNAccumulator { return new LastNAccumulator($input, $n); } @@ -296,10 +296,11 @@ public static function lastN( * New in MongoDB 5.3. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearFill/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public static function linearFill(Decimal128|Int64|ResolvesToNumber|float|int $expression): LinearFillAccumulator - { + public static function linearFill( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, + ): LinearFillAccumulator { return new LinearFillAccumulator($expression); } @@ -334,12 +335,12 @@ public static function max( * Returns the n largest values in an array. Distinct from the $maxN accumulator. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ public static function maxN( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToInt|int $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, ): MaxNAccumulator { return new MaxNAccumulator($input, $n); } @@ -353,11 +354,11 @@ public static function maxN( * It is also available as an aggregation expression. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/median/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ public static function median( - Decimal128|Int64|ResolvesToNumber|float|int $input, + Decimal128|Int64|ResolvesToNumber|float|int|string $input, string $method, ): MedianAccumulator { return new MedianAccumulator($input, $method); @@ -367,10 +368,10 @@ public static function median( * Combines multiple documents into a single document. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $document Any valid expression that resolves to a document. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $document Any valid expression that resolves to a document. */ public static function mergeObjects( - Document|Serializable|ResolvesToObject|stdClass|array $document, + Document|Serializable|ResolvesToObject|stdClass|array|string $document, ): MergeObjectsAccumulator { return new MergeObjectsAccumulator($document); } @@ -392,12 +393,12 @@ public static function min( * Returns the n smallest values in an array. Distinct from the $minN accumulator. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ public static function minN( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToInt|int $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, ): MinNAccumulator { return new MinNAccumulator($input, $n); } @@ -414,14 +415,14 @@ public static function minN( * It is also available as an aggregation expression. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. - * @param BSONArray|PackedArray|ResolvesToArray|array $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. * $percentile returns results in the same order as the elements in p. * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ public static function percentile( - Decimal128|Int64|ResolvesToNumber|float|int $input, - PackedArray|ResolvesToArray|BSONArray|array $p, + Decimal128|Int64|ResolvesToNumber|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, string $method, ): PercentileAccumulator { return new PercentileAccumulator($input, $p, $method); @@ -480,10 +481,11 @@ public static function shift( * Changed in MongoDB 5.0: Available in the $setWindowFields stage. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public static function stdDevPop(Decimal128|Int64|ResolvesToNumber|float|int $expression): StdDevPopAccumulator - { + public static function stdDevPop( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, + ): StdDevPopAccumulator { return new StdDevPopAccumulator($expression); } @@ -493,10 +495,11 @@ public static function stdDevPop(Decimal128|Int64|ResolvesToNumber|float|int $ex * Changed in MongoDB 5.0: Available in the $setWindowFields stage. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public static function stdDevSamp(Decimal128|Int64|ResolvesToNumber|float|int $expression): StdDevSampAccumulator - { + public static function stdDevSamp( + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, + ): StdDevSampAccumulator { return new StdDevSampAccumulator($expression); } @@ -505,9 +508,9 @@ public static function stdDevSamp(Decimal128|Int64|ResolvesToNumber|float|int $e * Changed in MongoDB 5.0: Available in the $setWindowFields stage. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public static function sum(Decimal128|Int64|ResolvesToNumber|float|int $expression): SumAccumulator + public static function sum(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): SumAccumulator { return new SumAccumulator($expression); } @@ -536,12 +539,12 @@ public static function top( * Available in the $group and $setWindowFields stages. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN/ - * @param ResolvesToInt|int $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. + * @param ResolvesToInt|int|string $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ public static function topN( - ResolvesToInt|int $n, + ResolvesToInt|int|string $n, Document|Serializable|stdClass|array $sortBy, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, ): TopNAccumulator { diff --git a/src/Builder/Accumulator/FirstNAccumulator.php b/src/Builder/Accumulator/FirstNAccumulator.php index 740ebc7ae..55c2809d7 100644 --- a/src/Builder/Accumulator/FirstNAccumulator.php +++ b/src/Builder/Accumulator/FirstNAccumulator.php @@ -15,8 +15,12 @@ use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Returns an aggregation of the first n elements within a group. * The elements returned are meaningful only if in a specified sort order. @@ -34,18 +38,22 @@ final class FirstNAccumulator implements AccumulatorInterface, WindowInterface, /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input An expression that resolves to the array from which to return n elements. */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input; - /** @var ResolvesToInt|int $n A positive integral expression that is either a constant or depends on the _id value for $group. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n A positive integral expression that is either a constant or depends on the _id value for $group. */ + public readonly ResolvesToInt|int|string $n; /** * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $input An expression that resolves to the array from which to return n elements. - * @param ResolvesToInt|int $n A positive integral expression that is either a constant or depends on the _id value for $group. + * @param ResolvesToInt|int|string $n A positive integral expression that is either a constant or depends on the _id value for $group. */ public function __construct( Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $input, - ResolvesToInt|int $n, + ResolvesToInt|int|string $n, ) { $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; } } diff --git a/src/Builder/Accumulator/IntegralAccumulator.php b/src/Builder/Accumulator/IntegralAccumulator.php index be34f57a2..a55a91062 100644 --- a/src/Builder/Accumulator/IntegralAccumulator.php +++ b/src/Builder/Accumulator/IntegralAccumulator.php @@ -19,6 +19,10 @@ use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\TimeUnit; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the approximation of the area under a curve. @@ -33,8 +37,8 @@ final class IntegralAccumulator implements WindowInterface, OperatorInterface public const NAME = '$integral'; public const PROPERTIES = ['input' => 'input', 'unit' => 'unit']; - /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $input */ - public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $input; + /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input */ + public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input; /** * @var Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". @@ -43,14 +47,18 @@ final class IntegralAccumulator implements WindowInterface, OperatorInterface public readonly Optional|ResolvesToString|TimeUnit|string $unit; /** - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $input + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $input * @param Optional|ResolvesToString|TimeUnit|string $unit A string that specifies the time unit. Use one of these strings: "week", "day","hour", "minute", "second", "millisecond". * If the sortBy field is not a date, you must omit a unit. If you specify a unit, you must specify a date in the sortBy field. */ public function __construct( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $input, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $input, Optional|ResolvesToString|TimeUnit|string $unit = Optional::Undefined, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; $this->unit = $unit; } diff --git a/src/Builder/Accumulator/LastNAccumulator.php b/src/Builder/Accumulator/LastNAccumulator.php index c0ddbd9bb..45a2a0f95 100644 --- a/src/Builder/Accumulator/LastNAccumulator.php +++ b/src/Builder/Accumulator/LastNAccumulator.php @@ -20,6 +20,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns an aggregation of the last n elements within a group. @@ -35,23 +37,33 @@ final class LastNAccumulator implements AccumulatorInterface, WindowInterface, O public const NAME = '$lastN'; public const PROPERTIES = ['input' => 'input', 'n' => 'n']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ + public readonly ResolvesToInt|int|string $n; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToInt|int $n) - { + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; } } diff --git a/src/Builder/Accumulator/LinearFillAccumulator.php b/src/Builder/Accumulator/LinearFillAccumulator.php index 59aade4a1..19126adbc 100644 --- a/src/Builder/Accumulator/LinearFillAccumulator.php +++ b/src/Builder/Accumulator/LinearFillAccumulator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Fills null and missing fields in a window using linear interpolation based on surrounding field values. @@ -29,14 +33,18 @@ final class LinearFillAccumulator implements WindowInterface, OperatorInterface public const NAME = '$linearFill'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Accumulator/MaxNAccumulator.php b/src/Builder/Accumulator/MaxNAccumulator.php index 04530f24e..eafbfbcfe 100644 --- a/src/Builder/Accumulator/MaxNAccumulator.php +++ b/src/Builder/Accumulator/MaxNAccumulator.php @@ -20,6 +20,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the n largest values in an array. Distinct from the $maxN accumulator. @@ -33,23 +35,33 @@ final class MaxNAccumulator implements AccumulatorInterface, WindowInterface, Op public const NAME = '$maxN'; public const PROPERTIES = ['input' => 'input', 'n' => 'n']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToInt|int $n) - { + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; } } diff --git a/src/Builder/Accumulator/MedianAccumulator.php b/src/Builder/Accumulator/MedianAccumulator.php index 358be201b..cfdd05e8a 100644 --- a/src/Builder/Accumulator/MedianAccumulator.php +++ b/src/Builder/Accumulator/MedianAccumulator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns an approximation of the median, the 50th percentile, as a scalar value. @@ -33,18 +37,22 @@ final class MedianAccumulator implements AccumulatorInterface, WindowInterface, public const NAME = '$median'; public const PROPERTIES = ['input' => 'input', 'method' => 'method']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $input; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $input; /** @var string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ public readonly string $method; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $input, string $method) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $input, string $method) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; $this->method = $method; } diff --git a/src/Builder/Accumulator/MergeObjectsAccumulator.php b/src/Builder/Accumulator/MergeObjectsAccumulator.php index 87a8e6a00..0a567b771 100644 --- a/src/Builder/Accumulator/MergeObjectsAccumulator.php +++ b/src/Builder/Accumulator/MergeObjectsAccumulator.php @@ -14,8 +14,12 @@ use MongoDB\Builder\Type\AccumulatorInterface; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Combines multiple documents into a single document. * @@ -28,14 +32,18 @@ final class MergeObjectsAccumulator implements AccumulatorInterface, OperatorInt public const NAME = '$mergeObjects'; public const PROPERTIES = ['document' => 'document']; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $document Any valid expression that resolves to a document. */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $document; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $document Any valid expression that resolves to a document. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $document; /** - * @param Document|ResolvesToObject|Serializable|array|stdClass $document Any valid expression that resolves to a document. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $document Any valid expression that resolves to a document. */ - public function __construct(Document|Serializable|ResolvesToObject|stdClass|array $document) + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $document) { + if (is_string($document) && ! str_starts_with($document, '$')) { + throw new InvalidArgumentException('Argument $document can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->document = $document; } } diff --git a/src/Builder/Accumulator/MinNAccumulator.php b/src/Builder/Accumulator/MinNAccumulator.php index 7a7dbcb37..2d5eeab7e 100644 --- a/src/Builder/Accumulator/MinNAccumulator.php +++ b/src/Builder/Accumulator/MinNAccumulator.php @@ -20,6 +20,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the n smallest values in an array. Distinct from the $minN accumulator. @@ -33,23 +35,33 @@ final class MinNAccumulator implements AccumulatorInterface, WindowInterface, Op public const NAME = '$minN'; public const PROPERTIES = ['input' => 'input', 'n' => 'n']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToInt|int $n) - { + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; } } diff --git a/src/Builder/Accumulator/PercentileAccumulator.php b/src/Builder/Accumulator/PercentileAccumulator.php index 3766d8f1d..030f13aab 100644 --- a/src/Builder/Accumulator/PercentileAccumulator.php +++ b/src/Builder/Accumulator/PercentileAccumulator.php @@ -22,6 +22,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns an array of scalar values that correspond to specified percentile values. @@ -43,30 +45,38 @@ final class PercentileAccumulator implements AccumulatorInterface, WindowInterfa public const NAME = '$percentile'; public const PROPERTIES = ['input' => 'input', 'p' => 'p', 'method' => 'method']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $input; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $input; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * @var BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. * $percentile returns results in the same order as the elements in p. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $p; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $p; /** @var string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ public readonly string $method; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. - * @param BSONArray|PackedArray|ResolvesToArray|array $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. * $percentile returns results in the same order as the elements in p. * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $input, - PackedArray|ResolvesToArray|BSONArray|array $p, + Decimal128|Int64|ResolvesToNumber|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, string $method, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; + if (is_string($p) && ! str_starts_with($p, '$')) { + throw new InvalidArgumentException('Argument $p can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($p) && ! array_is_list($p)) { throw new InvalidArgumentException('Expected $p argument to be a list, got an associative array.'); } diff --git a/src/Builder/Accumulator/StdDevPopAccumulator.php b/src/Builder/Accumulator/StdDevPopAccumulator.php index efa166707..dd234dab1 100644 --- a/src/Builder/Accumulator/StdDevPopAccumulator.php +++ b/src/Builder/Accumulator/StdDevPopAccumulator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Calculates the population standard deviation of the input values. Use if the values encompass the entire population of data you want to represent and do not wish to generalize about a larger population. $stdDevPop ignores non-numeric values. @@ -30,14 +34,18 @@ final class StdDevPopAccumulator implements AccumulatorInterface, WindowInterfac public const NAME = '$stdDevPop'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Accumulator/StdDevSampAccumulator.php b/src/Builder/Accumulator/StdDevSampAccumulator.php index d02f9e485..897e08563 100644 --- a/src/Builder/Accumulator/StdDevSampAccumulator.php +++ b/src/Builder/Accumulator/StdDevSampAccumulator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Calculates the sample standard deviation of the input values. Use if the values encompass a sample of a population of data from which to generalize about the population. $stdDevSamp ignores non-numeric values. @@ -30,14 +34,18 @@ final class StdDevSampAccumulator implements AccumulatorInterface, WindowInterfa public const NAME = '$stdDevSamp'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Accumulator/SumAccumulator.php b/src/Builder/Accumulator/SumAccumulator.php index 172915e2c..fa8cdb642 100644 --- a/src/Builder/Accumulator/SumAccumulator.php +++ b/src/Builder/Accumulator/SumAccumulator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\WindowInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns a sum of numerical values. Ignores non-numeric values. @@ -29,14 +33,18 @@ final class SumAccumulator implements AccumulatorInterface, WindowInterface, Ope public const NAME = '$sum'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Accumulator/TopNAccumulator.php b/src/Builder/Accumulator/TopNAccumulator.php index ea0ae9bc0..58e29fcaf 100644 --- a/src/Builder/Accumulator/TopNAccumulator.php +++ b/src/Builder/Accumulator/TopNAccumulator.php @@ -16,8 +16,12 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Returns an aggregation of the top n fields within a group, according to the specified sort order. * New in MongoDB 5.2. @@ -33,8 +37,8 @@ final class TopNAccumulator implements AccumulatorInterface, OperatorInterface public const NAME = '$topN'; public const PROPERTIES = ['n' => 'n', 'sortBy' => 'sortBy', 'output' => 'output']; - /** @var ResolvesToInt|int $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. */ + public readonly ResolvesToInt|int|string $n; /** @var Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. */ public readonly Document|Serializable|stdClass|array $sortBy; @@ -43,15 +47,19 @@ final class TopNAccumulator implements AccumulatorInterface, OperatorInterface public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output; /** - * @param ResolvesToInt|int $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. + * @param ResolvesToInt|int|string $n limits the number of results per group and has to be a positive integral expression that is either a constant or depends on the _id value for $group. * @param Document|Serializable|array|stdClass $sortBy Specifies the order of results, with syntax similar to $sort. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $output Represents the output for each element in the group and can be any expression. */ public function __construct( - ResolvesToInt|int $n, + ResolvesToInt|int|string $n, Document|Serializable|stdClass|array $sortBy, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $output, ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; $this->sortBy = $sortBy; $this->output = $output; diff --git a/src/Builder/Expression/AbsOperator.php b/src/Builder/Expression/AbsOperator.php index 977a05a44..817683be6 100644 --- a/src/Builder/Expression/AbsOperator.php +++ b/src/Builder/Expression/AbsOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the absolute value of a number. @@ -25,14 +29,18 @@ final class AbsOperator implements ResolvesToNumber, OperatorInterface public const NAME = '$abs'; public const PROPERTIES = ['value' => 'value']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $value */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $value; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $value */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $value; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $value + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $value */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $value) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $value) { + if (is_string($value) && ! str_starts_with($value, '$')) { + throw new InvalidArgumentException('Argument $value can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->value = $value; } } diff --git a/src/Builder/Expression/AcosOperator.php b/src/Builder/Expression/AcosOperator.php index 47ae210d3..4b5017ec1 100644 --- a/src/Builder/Expression/AcosOperator.php +++ b/src/Builder/Expression/AcosOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse cosine (arc cosine) of a value in radians. @@ -26,19 +30,23 @@ final class AcosOperator implements ResolvesToDouble, ResolvesToDecimal, Operato public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $acos returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $acos returns values as a double. $acos can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $acos returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $acos returns values as a double. $acos can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/AcoshOperator.php b/src/Builder/Expression/AcoshOperator.php index 8be5bc4a7..1da690261 100644 --- a/src/Builder/Expression/AcoshOperator.php +++ b/src/Builder/Expression/AcoshOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse hyperbolic cosine (hyperbolic arc cosine) of a value in radians. @@ -26,19 +30,23 @@ final class AcoshOperator implements ResolvesToDouble, ResolvesToDecimal, Operat public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. * $acosh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $acosh returns values as a double. $acosh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. * $acosh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $acosh returns values as a double. $acosh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/AddOperator.php b/src/Builder/Expression/AddOperator.php index 259e64b08..c7fe70d36 100644 --- a/src/Builder/Expression/AddOperator.php +++ b/src/Builder/Expression/AddOperator.php @@ -29,15 +29,16 @@ final class AddOperator implements ResolvesToInt, ResolvesToLong, ResolvesToDoub public const NAME = '$add'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. */ + /** @var list $expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. */ public readonly array $expression; /** - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int ...$expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. * @no-named-arguments */ - public function __construct(Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int ...$expression) - { + public function __construct( + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string ...$expression, + ) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); } diff --git a/src/Builder/Expression/AllElementsTrueOperator.php b/src/Builder/Expression/AllElementsTrueOperator.php index dbb74d967..282de6dfa 100644 --- a/src/Builder/Expression/AllElementsTrueOperator.php +++ b/src/Builder/Expression/AllElementsTrueOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns true if no element of a set evaluates to false, otherwise, returns false. Accepts a single argument expression. @@ -29,14 +31,18 @@ final class AllElementsTrueOperator implements ResolvesToBool, OperatorInterface public const NAME = '$allElementsTrue'; public const PROPERTIES = ['expression' => 'expression']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/AnyElementTrueOperator.php b/src/Builder/Expression/AnyElementTrueOperator.php index c8dd665b6..c3566ca9e 100644 --- a/src/Builder/Expression/AnyElementTrueOperator.php +++ b/src/Builder/Expression/AnyElementTrueOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns true if any elements of a set evaluate to true; otherwise, returns false. Accepts a single argument expression. @@ -29,14 +31,18 @@ final class AnyElementTrueOperator implements ResolvesToBool, OperatorInterface public const NAME = '$anyElementTrue'; public const PROPERTIES = ['expression' => 'expression']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/ArrayElemAtOperator.php b/src/Builder/Expression/ArrayElemAtOperator.php index a5f333359..9cbca3cfe 100644 --- a/src/Builder/Expression/ArrayElemAtOperator.php +++ b/src/Builder/Expression/ArrayElemAtOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the element at the specified array index. @@ -29,23 +31,33 @@ final class ArrayElemAtOperator implements ResolvesToAny, OperatorInterface public const NAME = '$arrayElemAt'; public const PROPERTIES = ['array' => 'array', 'idx' => 'idx']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $array */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $array; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $array */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; - /** @var ResolvesToInt|int $idx */ - public readonly ResolvesToInt|int $idx; + /** @var ResolvesToInt|int|string $idx */ + public readonly ResolvesToInt|int|string $idx; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $array - * @param ResolvesToInt|int $idx + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array + * @param ResolvesToInt|int|string $idx */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $array, ResolvesToInt|int $idx) - { + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $array, + ResolvesToInt|int|string $idx, + ) { + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($array) && ! array_is_list($array)) { throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); } $this->array = $array; + if (is_string($idx) && ! str_starts_with($idx, '$')) { + throw new InvalidArgumentException('Argument $idx can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->idx = $idx; } } diff --git a/src/Builder/Expression/ArrayToObjectOperator.php b/src/Builder/Expression/ArrayToObjectOperator.php index 657f67676..3a881363e 100644 --- a/src/Builder/Expression/ArrayToObjectOperator.php +++ b/src/Builder/Expression/ArrayToObjectOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Converts an array of key value pairs to a document. @@ -29,14 +31,18 @@ final class ArrayToObjectOperator implements ResolvesToObject, OperatorInterface public const NAME = '$arrayToObject'; public const PROPERTIES = ['array' => 'array']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $array */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $array; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $array */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $array + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $array) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $array) { + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($array) && ! array_is_list($array)) { throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/AsinOperator.php b/src/Builder/Expression/AsinOperator.php index 4f9a205e3..d814f6cf1 100644 --- a/src/Builder/Expression/AsinOperator.php +++ b/src/Builder/Expression/AsinOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse sin (arc sine) of a value in radians. @@ -26,19 +30,23 @@ final class AsinOperator implements ResolvesToDouble, ResolvesToDecimal, Operato public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $asin returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $asin returns values as a double. $asin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $asin returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $asin returns values as a double. $asin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/AsinhOperator.php b/src/Builder/Expression/AsinhOperator.php index 4e5c72ef3..edc2f2062 100644 --- a/src/Builder/Expression/AsinhOperator.php +++ b/src/Builder/Expression/AsinhOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse hyperbolic sine (hyperbolic arc sine) of a value in radians. @@ -26,19 +30,23 @@ final class AsinhOperator implements ResolvesToDouble, ResolvesToDecimal, Operat public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $asinh takes any valid expression that resolves to a number. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asinh takes any valid expression that resolves to a number. * $asinh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $asinh returns values as a double. $asinh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $asinh takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asinh takes any valid expression that resolves to a number. * $asinh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $asinh returns values as a double. $asinh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/Atan2Operator.php b/src/Builder/Expression/Atan2Operator.php index 78f56c8a8..f0af1fc97 100644 --- a/src/Builder/Expression/Atan2Operator.php +++ b/src/Builder/Expression/Atan2Operator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse tangent (arc tangent) of y / x in radians, where y and x are the first and second values passed to the expression respectively. @@ -26,26 +30,34 @@ final class Atan2Operator implements ResolvesToDouble, ResolvesToDecimal, Operat public const PROPERTIES = ['y' => 'y', 'x' => 'x']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $y $atan2 takes any valid expression that resolves to a number. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $y $atan2 takes any valid expression that resolves to a number. * $atan2 returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atan returns values as a double. $atan2 can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $y; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $y; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $x */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $x; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $x */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $x; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $y $atan2 takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $y $atan2 takes any valid expression that resolves to a number. * $atan2 returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atan returns values as a double. $atan2 can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. - * @param Decimal128|Int64|ResolvesToNumber|float|int $x + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $x */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $y, - Decimal128|Int64|ResolvesToNumber|float|int $x, + Decimal128|Int64|ResolvesToNumber|float|int|string $y, + Decimal128|Int64|ResolvesToNumber|float|int|string $x, ) { + if (is_string($y) && ! str_starts_with($y, '$')) { + throw new InvalidArgumentException('Argument $y can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->y = $y; + if (is_string($x) && ! str_starts_with($x, '$')) { + throw new InvalidArgumentException('Argument $x can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->x = $x; } } diff --git a/src/Builder/Expression/AtanOperator.php b/src/Builder/Expression/AtanOperator.php index 6362570d6..938a9b007 100644 --- a/src/Builder/Expression/AtanOperator.php +++ b/src/Builder/Expression/AtanOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse tangent (arc tangent) of a value in radians. @@ -26,19 +30,23 @@ final class AtanOperator implements ResolvesToDouble, ResolvesToDecimal, Operato public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $atan takes any valid expression that resolves to a number. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atan takes any valid expression that resolves to a number. * $atan returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atan returns values as a double. $atan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $atan takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atan takes any valid expression that resolves to a number. * $atan returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atan returns values as a double. $atan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/AtanhOperator.php b/src/Builder/Expression/AtanhOperator.php index bdfba8ad9..fde1dae12 100644 --- a/src/Builder/Expression/AtanhOperator.php +++ b/src/Builder/Expression/AtanhOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the inverse hyperbolic tangent (hyperbolic arc tangent) of a value in radians. @@ -26,19 +30,23 @@ final class AtanhOperator implements ResolvesToDouble, ResolvesToDecimal, Operat public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $atanh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atanh returns values as a double. $atanh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $atanh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atanh returns values as a double. $atanh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/AvgOperator.php b/src/Builder/Expression/AvgOperator.php index 31745f14a..52be761a9 100644 --- a/src/Builder/Expression/AvgOperator.php +++ b/src/Builder/Expression/AvgOperator.php @@ -29,14 +29,14 @@ final class AvgOperator implements ResolvesToNumber, OperatorInterface public const NAME = '$avg'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression * @no-named-arguments */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int ...$expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/BitAndOperator.php b/src/Builder/Expression/BitAndOperator.php index bf0e3cd73..eb6fffaca 100644 --- a/src/Builder/Expression/BitAndOperator.php +++ b/src/Builder/Expression/BitAndOperator.php @@ -28,14 +28,14 @@ final class BitAndOperator implements ResolvesToInt, ResolvesToLong, OperatorInt public const NAME = '$bitAnd'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param Int64|ResolvesToInt|ResolvesToLong|int ...$expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression * @no-named-arguments */ - public function __construct(Int64|ResolvesToInt|ResolvesToLong|int ...$expression) + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/BitNotOperator.php b/src/Builder/Expression/BitNotOperator.php index 6f388919f..adac4fc66 100644 --- a/src/Builder/Expression/BitNotOperator.php +++ b/src/Builder/Expression/BitNotOperator.php @@ -11,6 +11,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the result of a bitwise not operation on a single argument or an array that contains a single int or long value. @@ -25,14 +29,18 @@ final class BitNotOperator implements ResolvesToInt, ResolvesToLong, OperatorInt public const NAME = '$bitNot'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Int64|ResolvesToInt|ResolvesToLong|int $expression */ - public readonly Int64|ResolvesToInt|ResolvesToLong|int $expression; + /** @var Int64|ResolvesToInt|ResolvesToLong|int|string $expression */ + public readonly Int64|ResolvesToInt|ResolvesToLong|int|string $expression; /** - * @param Int64|ResolvesToInt|ResolvesToLong|int $expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $expression */ - public function __construct(Int64|ResolvesToInt|ResolvesToLong|int $expression) + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/BitOrOperator.php b/src/Builder/Expression/BitOrOperator.php index b2490a4f6..bc68838e9 100644 --- a/src/Builder/Expression/BitOrOperator.php +++ b/src/Builder/Expression/BitOrOperator.php @@ -28,14 +28,14 @@ final class BitOrOperator implements ResolvesToInt, ResolvesToLong, OperatorInte public const NAME = '$bitOr'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param Int64|ResolvesToInt|ResolvesToLong|int ...$expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression * @no-named-arguments */ - public function __construct(Int64|ResolvesToInt|ResolvesToLong|int ...$expression) + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/BitXorOperator.php b/src/Builder/Expression/BitXorOperator.php index 0f0bc0e5a..adbf5eb2e 100644 --- a/src/Builder/Expression/BitXorOperator.php +++ b/src/Builder/Expression/BitXorOperator.php @@ -28,14 +28,14 @@ final class BitXorOperator implements ResolvesToInt, ResolvesToLong, OperatorInt public const NAME = '$bitXor'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param Int64|ResolvesToInt|ResolvesToLong|int ...$expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression * @no-named-arguments */ - public function __construct(Int64|ResolvesToInt|ResolvesToLong|int ...$expression) + public function __construct(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/BsonSizeOperator.php b/src/Builder/Expression/BsonSizeOperator.php index 962d8c6db..37626d0d9 100644 --- a/src/Builder/Expression/BsonSizeOperator.php +++ b/src/Builder/Expression/BsonSizeOperator.php @@ -12,8 +12,12 @@ use MongoDB\BSON\Serializable; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Returns the size in bytes of a given document (i.e. BSON type Object) when encoded as BSON. * @@ -26,14 +30,19 @@ final class BsonSizeOperator implements ResolvesToInt, OperatorInterface public const NAME = '$bsonSize'; public const PROPERTIES = ['object' => 'object']; - /** @var Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass $object */ - public readonly Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null $object; + /** @var Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass|string $object */ + public readonly Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null|string $object; /** - * @param Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass $object + * @param Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass|string $object */ - public function __construct(Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null $object) - { + public function __construct( + Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null|string $object, + ) { + if (is_string($object) && ! str_starts_with($object, '$')) { + throw new InvalidArgumentException('Argument $object can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->object = $object; } } diff --git a/src/Builder/Expression/CaseOperator.php b/src/Builder/Expression/CaseOperator.php index 27da77d71..8680befdf 100644 --- a/src/Builder/Expression/CaseOperator.php +++ b/src/Builder/Expression/CaseOperator.php @@ -13,8 +13,12 @@ use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\SwitchBranchInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Represents a single case in a $switch expression * @@ -27,20 +31,24 @@ final class CaseOperator implements SwitchBranchInterface, OperatorInterface public const NAME = null; public const PROPERTIES = ['case' => 'case', 'then' => 'then']; - /** @var ResolvesToBool|bool $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. */ - public readonly ResolvesToBool|bool $case; + /** @var ResolvesToBool|bool|string $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. */ + public readonly ResolvesToBool|bool|string $case; /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then Can be any valid expression. */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then; /** - * @param ResolvesToBool|bool $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. + * @param ResolvesToBool|bool|string $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then Can be any valid expression. */ public function __construct( - ResolvesToBool|bool $case, + ResolvesToBool|bool|string $case, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then, ) { + if (is_string($case) && ! str_starts_with($case, '$')) { + throw new InvalidArgumentException('Argument $case can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->case = $case; $this->then = $then; } diff --git a/src/Builder/Expression/CeilOperator.php b/src/Builder/Expression/CeilOperator.php index c6771b81f..9f318c454 100644 --- a/src/Builder/Expression/CeilOperator.php +++ b/src/Builder/Expression/CeilOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the smallest integer greater than or equal to the specified number. @@ -25,14 +29,18 @@ final class CeilOperator implements ResolvesToInt, OperatorInterface public const NAME = '$ceil'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/ConcatArraysOperator.php b/src/Builder/Expression/ConcatArraysOperator.php index 17e736a78..12f862086 100644 --- a/src/Builder/Expression/ConcatArraysOperator.php +++ b/src/Builder/Expression/ConcatArraysOperator.php @@ -28,14 +28,14 @@ final class ConcatArraysOperator implements ResolvesToArray, OperatorInterface public const NAME = '$concatArrays'; public const PROPERTIES = ['array' => 'array']; - /** @var list $array */ + /** @var list $array */ public readonly array $array; /** - * @param BSONArray|PackedArray|ResolvesToArray|array ...$array + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$array * @no-named-arguments */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array ...$array) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$array) { if (\count($array) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $array, got %d.', 1, \count($array))); diff --git a/src/Builder/Expression/CondOperator.php b/src/Builder/Expression/CondOperator.php index 26ca336f5..7c71f3396 100644 --- a/src/Builder/Expression/CondOperator.php +++ b/src/Builder/Expression/CondOperator.php @@ -12,8 +12,12 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * A ternary operator that evaluates one expression, and depending on the result, returns the value of one of the other two expressions. Accepts either three expressions in an ordered list or three named parameters. * @@ -26,8 +30,8 @@ final class CondOperator implements ResolvesToAny, OperatorInterface public const NAME = '$cond'; public const PROPERTIES = ['if' => 'if', 'then' => 'then', 'else' => 'else']; - /** @var ResolvesToBool|bool $if */ - public readonly ResolvesToBool|bool $if; + /** @var ResolvesToBool|bool|string $if */ + public readonly ResolvesToBool|bool|string $if; /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then; @@ -36,15 +40,19 @@ final class CondOperator implements ResolvesToAny, OperatorInterface public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $else; /** - * @param ResolvesToBool|bool $if + * @param ResolvesToBool|bool|string $if * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $else */ public function __construct( - ResolvesToBool|bool $if, + ResolvesToBool|bool|string $if, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $else, ) { + if (is_string($if) && ! str_starts_with($if, '$')) { + throw new InvalidArgumentException('Argument $if can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->if = $if; $this->then = $then; $this->else = $else; diff --git a/src/Builder/Expression/CosOperator.php b/src/Builder/Expression/CosOperator.php index e06afa635..fdc5fe5f0 100644 --- a/src/Builder/Expression/CosOperator.php +++ b/src/Builder/Expression/CosOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the cosine of a value that is measured in radians. @@ -26,17 +30,21 @@ final class CosOperator implements ResolvesToDouble, ResolvesToDecimal, Operator public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $cos returns values as a double. $cos can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $cos returns values as a double. $cos can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/CoshOperator.php b/src/Builder/Expression/CoshOperator.php index c44dccb0b..3133153a7 100644 --- a/src/Builder/Expression/CoshOperator.php +++ b/src/Builder/Expression/CoshOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the hyperbolic cosine of a value that is measured in radians. @@ -26,17 +30,21 @@ final class CoshOperator implements ResolvesToDouble, ResolvesToDecimal, Operato public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $cosh returns values as a double. $cosh can also return values as a 128-bit decimal if the resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $cosh returns values as a double. $cosh can also return values as a 128-bit decimal if the resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/DateAddOperator.php b/src/Builder/Expression/DateAddOperator.php index 0c0bbf100..1c23c4a26 100644 --- a/src/Builder/Expression/DateAddOperator.php +++ b/src/Builder/Expression/DateAddOperator.php @@ -16,6 +16,10 @@ use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\TimeUnit; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Adds a number of time units to a date object. @@ -29,32 +33,40 @@ final class DateAddOperator implements ResolvesToDate, OperatorInterface public const NAME = '$dateAdd'; public const PROPERTIES = ['startDate' => 'startDate', 'unit' => 'unit', 'amount' => 'amount', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate; /** @var ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. */ public readonly ResolvesToString|TimeUnit|string $unit; - /** @var Int64|ResolvesToInt|ResolvesToLong|int $amount */ - public readonly Int64|ResolvesToInt|ResolvesToLong|int $amount; + /** @var Int64|ResolvesToInt|ResolvesToLong|int|string $amount */ + public readonly Int64|ResolvesToInt|ResolvesToLong|int|string $amount; /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. - * @param Int64|ResolvesToInt|ResolvesToLong|int $amount + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, ResolvesToString|TimeUnit|string $unit, - Int64|ResolvesToInt|ResolvesToLong|int $amount, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($startDate) && ! str_starts_with($startDate, '$')) { + throw new InvalidArgumentException('Argument $startDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->startDate = $startDate; $this->unit = $unit; + if (is_string($amount) && ! str_starts_with($amount, '$')) { + throw new InvalidArgumentException('Argument $amount can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->amount = $amount; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/DateDiffOperator.php b/src/Builder/Expression/DateDiffOperator.php index a12ea935c..24b8fb50f 100644 --- a/src/Builder/Expression/DateDiffOperator.php +++ b/src/Builder/Expression/DateDiffOperator.php @@ -15,6 +15,10 @@ use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\TimeUnit; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the difference between two dates. @@ -35,11 +39,11 @@ final class DateDiffOperator implements ResolvesToInt, OperatorInterface 'startOfWeek' => 'startOfWeek', ]; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $endDate; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $endDate; /** @var ResolvesToString|TimeUnit|string $unit The time measurement unit between the startDate and endDate */ public readonly ResolvesToString|TimeUnit|string $unit; @@ -51,20 +55,28 @@ final class DateDiffOperator implements ResolvesToInt, OperatorInterface public readonly Optional|ResolvesToString|string $startOfWeek; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The time measurement unit between the startDate and endDate * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. * @param Optional|ResolvesToString|string $startOfWeek Used when the unit is equal to week. Defaults to Sunday. The startOfWeek parameter is an expression that resolves to a case insensitive string */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate, - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $endDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $endDate, ResolvesToString|TimeUnit|string $unit, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|ResolvesToString|string $startOfWeek = Optional::Undefined, ) { + if (is_string($startDate) && ! str_starts_with($startDate, '$')) { + throw new InvalidArgumentException('Argument $startDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->startDate = $startDate; + if (is_string($endDate) && ! str_starts_with($endDate, '$')) { + throw new InvalidArgumentException('Argument $endDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->endDate = $endDate; $this->unit = $unit; $this->timezone = $timezone; diff --git a/src/Builder/Expression/DateFromPartsOperator.php b/src/Builder/Expression/DateFromPartsOperator.php index 877bfdd65..c2d32c290 100644 --- a/src/Builder/Expression/DateFromPartsOperator.php +++ b/src/Builder/Expression/DateFromPartsOperator.php @@ -13,6 +13,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Constructs a BSON Date object given the date's constituent parts. @@ -39,74 +43,114 @@ final class DateFromPartsOperator implements ResolvesToDate, OperatorInterface 'timezone' => 'timezone', ]; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $year Calendar year. Can be any expression that evaluates to a number. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $year; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year Calendar year. Can be any expression that evaluates to a number. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeekYear; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $month Month. Defaults to 1. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $month; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month Month. Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeek Week of year. Defaults to 1. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeek; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek Week of year. Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $day Day of month. Defaults to 1. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $day; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day Day of month. Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoDayOfWeek; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $hour Hour. Defaults to 0. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $hour; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour Hour. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $minute Minute. Defaults to 0. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $minute; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute Minute. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $second Second. Defaults to 0. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $second; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second Second. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second; - /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $millisecond Millisecond. Defaults to 0. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $millisecond; + /** @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond Millisecond. Defaults to 0. */ + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond; /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $year Calendar year. Can be any expression that evaluates to a number. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $month Month. Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeek Week of year. Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $day Day of month. Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $hour Hour. Defaults to 0. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $minute Minute. Defaults to 0. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $second Second. Defaults to 0. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $millisecond Millisecond. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year Calendar year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month Month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek Week of year. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day Day of month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour Hour. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute Minute. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second Second. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond Millisecond. Defaults to 0. * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - Optional|Decimal128|Int64|ResolvesToNumber|float|int $year = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeekYear = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $month = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeek = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $day = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoDayOfWeek = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $hour = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $minute = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $second = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $millisecond = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond = Optional::Undefined, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($year) && ! str_starts_with($year, '$')) { + throw new InvalidArgumentException('Argument $year can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->year = $year; + if (is_string($isoWeekYear) && ! str_starts_with($isoWeekYear, '$')) { + throw new InvalidArgumentException('Argument $isoWeekYear can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->isoWeekYear = $isoWeekYear; + if (is_string($month) && ! str_starts_with($month, '$')) { + throw new InvalidArgumentException('Argument $month can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->month = $month; + if (is_string($isoWeek) && ! str_starts_with($isoWeek, '$')) { + throw new InvalidArgumentException('Argument $isoWeek can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->isoWeek = $isoWeek; + if (is_string($day) && ! str_starts_with($day, '$')) { + throw new InvalidArgumentException('Argument $day can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->day = $day; + if (is_string($isoDayOfWeek) && ! str_starts_with($isoDayOfWeek, '$')) { + throw new InvalidArgumentException('Argument $isoDayOfWeek can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->isoDayOfWeek = $isoDayOfWeek; + if (is_string($hour) && ! str_starts_with($hour, '$')) { + throw new InvalidArgumentException('Argument $hour can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->hour = $hour; + if (is_string($minute) && ! str_starts_with($minute, '$')) { + throw new InvalidArgumentException('Argument $minute can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->minute = $minute; + if (is_string($second) && ! str_starts_with($second, '$')) { + throw new InvalidArgumentException('Argument $second can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->second = $second; + if (is_string($millisecond) && ! str_starts_with($millisecond, '$')) { + throw new InvalidArgumentException('Argument $millisecond can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->millisecond = $millisecond; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/DateSubtractOperator.php b/src/Builder/Expression/DateSubtractOperator.php index 11fbfdcfd..3deda4b37 100644 --- a/src/Builder/Expression/DateSubtractOperator.php +++ b/src/Builder/Expression/DateSubtractOperator.php @@ -16,6 +16,10 @@ use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\TimeUnit; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Subtracts a number of time units from a date object. @@ -29,32 +33,40 @@ final class DateSubtractOperator implements ResolvesToDate, OperatorInterface public const NAME = '$dateSubtract'; public const PROPERTIES = ['startDate' => 'startDate', 'unit' => 'unit', 'amount' => 'amount', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate; /** @var ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. */ public readonly ResolvesToString|TimeUnit|string $unit; - /** @var Int64|ResolvesToInt|ResolvesToLong|int $amount */ - public readonly Int64|ResolvesToInt|ResolvesToLong|int $amount; + /** @var Int64|ResolvesToInt|ResolvesToLong|int|string $amount */ + public readonly Int64|ResolvesToInt|ResolvesToLong|int|string $amount; /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. - * @param Int64|ResolvesToInt|ResolvesToLong|int $amount + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, ResolvesToString|TimeUnit|string $unit, - Int64|ResolvesToInt|ResolvesToLong|int $amount, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($startDate) && ! str_starts_with($startDate, '$')) { + throw new InvalidArgumentException('Argument $startDate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->startDate = $startDate; $this->unit = $unit; + if (is_string($amount) && ! str_starts_with($amount, '$')) { + throw new InvalidArgumentException('Argument $amount can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->amount = $amount; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/DateToPartsOperator.php b/src/Builder/Expression/DateToPartsOperator.php index 3573e59c8..14771858f 100644 --- a/src/Builder/Expression/DateToPartsOperator.php +++ b/src/Builder/Expression/DateToPartsOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns a document containing the constituent parts of a date. @@ -27,8 +31,8 @@ final class DateToPartsOperator implements ResolvesToObject, OperatorInterface public const NAME = '$dateToParts'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone', 'iso8601' => 'iso8601']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; @@ -37,15 +41,19 @@ final class DateToPartsOperator implements ResolvesToObject, OperatorInterface public readonly Optional|bool $iso8601; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. * @param Optional|bool $iso8601 If set to true, modifies the output document to use ISO week date fields. Defaults to false. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|bool $iso8601 = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; $this->iso8601 = $iso8601; diff --git a/src/Builder/Expression/DateToStringOperator.php b/src/Builder/Expression/DateToStringOperator.php index 7f9ede2d9..7861f6990 100644 --- a/src/Builder/Expression/DateToStringOperator.php +++ b/src/Builder/Expression/DateToStringOperator.php @@ -16,8 +16,12 @@ use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Returns the date as a formatted string. * @@ -30,8 +34,8 @@ final class DateToStringOperator implements ResolvesToString, OperatorInterface public const NAME = '$dateToString'; public const PROPERTIES = ['date' => 'date', 'format' => 'format', 'timezone' => 'timezone', 'onNull' => 'onNull']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** * @var Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. @@ -49,7 +53,7 @@ final class DateToStringOperator implements ResolvesToString, OperatorInterface public readonly Optional|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. * @param Optional|ResolvesToString|string $timezone The time zone to use to format the date. @@ -57,11 +61,15 @@ final class DateToStringOperator implements ResolvesToString, OperatorInterface * If unspecified, $dateToString returns null if the date is null or missing. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $format = Optional::Undefined, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->format = $format; $this->timezone = $timezone; diff --git a/src/Builder/Expression/DateTruncOperator.php b/src/Builder/Expression/DateTruncOperator.php index b5e162bba..9e84976dd 100644 --- a/src/Builder/Expression/DateTruncOperator.php +++ b/src/Builder/Expression/DateTruncOperator.php @@ -17,6 +17,10 @@ use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; use MongoDB\Builder\Type\TimeUnit; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Truncates a date. @@ -37,8 +41,8 @@ final class DateTruncOperator implements ResolvesToDate, OperatorInterface 'startOfWeek' => 'startOfWeek', ]; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** * @var ResolvesToString|TimeUnit|string $unit The unit of time, specified as an expression that must resolve to one of these strings: year, quarter, week, month, day, hour, minute, second. @@ -47,10 +51,10 @@ final class DateTruncOperator implements ResolvesToDate, OperatorInterface public readonly ResolvesToString|TimeUnit|string $unit; /** - * @var Optional|Decimal128|Int64|ResolvesToNumber|float|int $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. + * @var Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. * Together, binSize and unit specify the time period used in the $dateTrunc calculation. */ - public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int $binSize; + public readonly Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize; /** @var Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; @@ -62,24 +66,32 @@ final class DateTruncOperator implements ResolvesToDate, OperatorInterface public readonly Optional|string $startOfWeek; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The unit of time, specified as an expression that must resolve to one of these strings: year, quarter, week, month, day, hour, minute, second. * Together, binSize and unit specify the time period used in the $dateTrunc calculation. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. * Together, binSize and unit specify the time period used in the $dateTrunc calculation. * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. * @param Optional|string $startOfWeek The start of the week. Used when * unit is week. Defaults to Sunday. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, ResolvesToString|TimeUnit|string $unit, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $binSize = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize = Optional::Undefined, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|string $startOfWeek = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->unit = $unit; + if (is_string($binSize) && ! str_starts_with($binSize, '$')) { + throw new InvalidArgumentException('Argument $binSize can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->binSize = $binSize; $this->timezone = $timezone; $this->startOfWeek = $startOfWeek; diff --git a/src/Builder/Expression/DayOfMonthOperator.php b/src/Builder/Expression/DayOfMonthOperator.php index bc0ccb28f..041680cae 100644 --- a/src/Builder/Expression/DayOfMonthOperator.php +++ b/src/Builder/Expression/DayOfMonthOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the day of the month for a date as a number between 1 and 31. @@ -27,20 +31,24 @@ final class DayOfMonthOperator implements ResolvesToInt, OperatorInterface public const NAME = '$dayOfMonth'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/DayOfWeekOperator.php b/src/Builder/Expression/DayOfWeekOperator.php index e9dbbfa08..ac3a2ec6d 100644 --- a/src/Builder/Expression/DayOfWeekOperator.php +++ b/src/Builder/Expression/DayOfWeekOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). @@ -27,20 +31,24 @@ final class DayOfWeekOperator implements ResolvesToInt, OperatorInterface public const NAME = '$dayOfWeek'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/DayOfYearOperator.php b/src/Builder/Expression/DayOfYearOperator.php index 86c20ab20..dff335adb 100644 --- a/src/Builder/Expression/DayOfYearOperator.php +++ b/src/Builder/Expression/DayOfYearOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the day of the year for a date as a number between 1 and 366 (leap year). @@ -27,20 +31,24 @@ final class DayOfYearOperator implements ResolvesToInt, OperatorInterface public const NAME = '$dayOfYear'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/DegreesToRadiansOperator.php b/src/Builder/Expression/DegreesToRadiansOperator.php index b8d2bb07a..45482c733 100644 --- a/src/Builder/Expression/DegreesToRadiansOperator.php +++ b/src/Builder/Expression/DegreesToRadiansOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Converts a value from degrees to radians. @@ -26,17 +30,21 @@ final class DegreesToRadiansOperator implements ResolvesToDouble, ResolvesToDeci public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $degreesToRadians takes any valid expression that resolves to a number. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $degreesToRadians takes any valid expression that resolves to a number. * By default $degreesToRadians returns values as a double. $degreesToRadians can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $degreesToRadians takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $degreesToRadians takes any valid expression that resolves to a number. * By default $degreesToRadians returns values as a double. $degreesToRadians can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/DivideOperator.php b/src/Builder/Expression/DivideOperator.php index 74de49c20..55ba88b21 100644 --- a/src/Builder/Expression/DivideOperator.php +++ b/src/Builder/Expression/DivideOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the result of dividing the first number by the second. Accepts two argument expressions. @@ -25,21 +29,29 @@ final class DivideOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$divide'; public const PROPERTIES = ['dividend' => 'dividend', 'divisor' => 'divisor']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $dividend; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $dividend; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $divisor */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $divisor; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $divisor; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. - * @param Decimal128|Int64|ResolvesToNumber|float|int $divisor + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $dividend, - Decimal128|Int64|ResolvesToNumber|float|int $divisor, + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, ) { + if (is_string($dividend) && ! str_starts_with($dividend, '$')) { + throw new InvalidArgumentException('Argument $dividend can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->dividend = $dividend; + if (is_string($divisor) && ! str_starts_with($divisor, '$')) { + throw new InvalidArgumentException('Argument $divisor can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->divisor = $divisor; } } diff --git a/src/Builder/Expression/ExpOperator.php b/src/Builder/Expression/ExpOperator.php index 78037fb9e..5aab19c1e 100644 --- a/src/Builder/Expression/ExpOperator.php +++ b/src/Builder/Expression/ExpOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Raises e to the specified exponent. @@ -25,14 +29,18 @@ final class ExpOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$exp'; public const PROPERTIES = ['exponent' => 'exponent']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $exponent */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $exponent; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $exponent; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $exponent + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $exponent) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $exponent) { + if (is_string($exponent) && ! str_starts_with($exponent, '$')) { + throw new InvalidArgumentException('Argument $exponent can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->exponent = $exponent; } } diff --git a/src/Builder/Expression/FactoryTrait.php b/src/Builder/Expression/FactoryTrait.php index 78f460fa0..cb6ed577d 100644 --- a/src/Builder/Expression/FactoryTrait.php +++ b/src/Builder/Expression/FactoryTrait.php @@ -36,9 +36,9 @@ trait FactoryTrait * Returns the absolute value of a number. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/abs/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $value + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $value */ - public static function abs(Decimal128|Int64|ResolvesToNumber|float|int $value): AbsOperator + public static function abs(Decimal128|Int64|ResolvesToNumber|float|int|string $value): AbsOperator { return new AbsOperator($value); } @@ -47,11 +47,11 @@ public static function abs(Decimal128|Int64|ResolvesToNumber|float|int $value): * Returns the inverse cosine (arc cosine) of a value in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/acos/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acos takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $acos returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $acos returns values as a double. $acos can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function acos(Decimal128|Int64|ResolvesToNumber|float|int $expression): AcosOperator + public static function acos(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AcosOperator { return new AcosOperator($expression); } @@ -60,11 +60,11 @@ public static function acos(Decimal128|Int64|ResolvesToNumber|float|int $express * Returns the inverse hyperbolic cosine (hyperbolic arc cosine) of a value in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/acosh/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $acosh takes any valid expression that resolves to a number between 1 and +Infinity, e.g. 1 <= value <= +Infinity. * $acosh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $acosh returns values as a double. $acosh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function acosh(Decimal128|Int64|ResolvesToNumber|float|int $expression): AcoshOperator + public static function acosh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AcoshOperator { return new AcoshOperator($expression); } @@ -74,10 +74,10 @@ public static function acosh(Decimal128|Int64|ResolvesToNumber|float|int $expres * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/add/ * @no-named-arguments - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int ...$expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to either all numbers or to numbers and a date. */ public static function add( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int ...$expression, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string ...$expression, ): AddOperator { return new AddOperator(...$expression); } @@ -86,10 +86,10 @@ public static function add( * Returns true if no element of a set evaluates to false, otherwise, returns false. Accepts a single argument expression. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/allElementsTrue/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ public static function allElementsTrue( - PackedArray|ResolvesToArray|BSONArray|array $expression, + PackedArray|ResolvesToArray|BSONArray|array|string $expression, ): AllElementsTrueOperator { return new AllElementsTrueOperator($expression); } @@ -111,10 +111,10 @@ public static function and( * Returns true if any elements of a set evaluate to true; otherwise, returns false. Accepts a single argument expression. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/anyElementTrue/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ public static function anyElementTrue( - PackedArray|ResolvesToArray|BSONArray|array $expression, + PackedArray|ResolvesToArray|BSONArray|array|string $expression, ): AnyElementTrueOperator { return new AnyElementTrueOperator($expression); } @@ -123,12 +123,12 @@ public static function anyElementTrue( * Returns the element at the specified array index. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/arrayElemAt/ - * @param BSONArray|PackedArray|ResolvesToArray|array $array - * @param ResolvesToInt|int $idx + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array + * @param ResolvesToInt|int|string $idx */ public static function arrayElemAt( - PackedArray|ResolvesToArray|BSONArray|array $array, - ResolvesToInt|int $idx, + PackedArray|ResolvesToArray|BSONArray|array|string $array, + ResolvesToInt|int|string $idx, ): ArrayElemAtOperator { return new ArrayElemAtOperator($array, $idx); } @@ -137,10 +137,11 @@ public static function arrayElemAt( * Converts an array of key value pairs to a document. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/arrayToObject/ - * @param BSONArray|PackedArray|ResolvesToArray|array $array + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array */ - public static function arrayToObject(PackedArray|ResolvesToArray|BSONArray|array $array): ArrayToObjectOperator - { + public static function arrayToObject( + PackedArray|ResolvesToArray|BSONArray|array|string $array, + ): ArrayToObjectOperator { return new ArrayToObjectOperator($array); } @@ -148,11 +149,11 @@ public static function arrayToObject(PackedArray|ResolvesToArray|BSONArray|array * Returns the inverse sin (arc sine) of a value in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/asin/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asin takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $asin returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $asin returns values as a double. $asin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function asin(Decimal128|Int64|ResolvesToNumber|float|int $expression): AsinOperator + public static function asin(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AsinOperator { return new AsinOperator($expression); } @@ -161,11 +162,11 @@ public static function asin(Decimal128|Int64|ResolvesToNumber|float|int $express * Returns the inverse hyperbolic sine (hyperbolic arc sine) of a value in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/asinh/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $asinh takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $asinh takes any valid expression that resolves to a number. * $asinh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $asinh returns values as a double. $asinh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function asinh(Decimal128|Int64|ResolvesToNumber|float|int $expression): AsinhOperator + public static function asinh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AsinhOperator { return new AsinhOperator($expression); } @@ -174,11 +175,11 @@ public static function asinh(Decimal128|Int64|ResolvesToNumber|float|int $expres * Returns the inverse tangent (arc tangent) of a value in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/atan/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $atan takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atan takes any valid expression that resolves to a number. * $atan returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atan returns values as a double. $atan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function atan(Decimal128|Int64|ResolvesToNumber|float|int $expression): AtanOperator + public static function atan(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AtanOperator { return new AtanOperator($expression); } @@ -187,14 +188,14 @@ public static function atan(Decimal128|Int64|ResolvesToNumber|float|int $express * Returns the inverse tangent (arc tangent) of y / x in radians, where y and x are the first and second values passed to the expression respectively. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/atan2/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $y $atan2 takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $y $atan2 takes any valid expression that resolves to a number. * $atan2 returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atan returns values as a double. $atan2 can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. - * @param Decimal128|Int64|ResolvesToNumber|float|int $x + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $x */ public static function atan2( - Decimal128|Int64|ResolvesToNumber|float|int $y, - Decimal128|Int64|ResolvesToNumber|float|int $x, + Decimal128|Int64|ResolvesToNumber|float|int|string $y, + Decimal128|Int64|ResolvesToNumber|float|int|string $x, ): Atan2Operator { return new Atan2Operator($y, $x); } @@ -203,11 +204,11 @@ public static function atan2( * Returns the inverse hyperbolic tangent (hyperbolic arc tangent) of a value in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/atanh/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $atanh takes any valid expression that resolves to a number between -1 and 1, e.g. -1 <= value <= 1. * $atanh returns values in radians. Use $radiansToDegrees operator to convert the output value from radians to degrees. * By default $atanh returns values as a double. $atanh can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function atanh(Decimal128|Int64|ResolvesToNumber|float|int $expression): AtanhOperator + public static function atanh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): AtanhOperator { return new AtanhOperator($expression); } @@ -218,9 +219,9 @@ public static function atanh(Decimal128|Int64|ResolvesToNumber|float|int $expres * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg/ * @no-named-arguments - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression */ - public static function avg(Decimal128|Int64|ResolvesToNumber|float|int ...$expression): AvgOperator + public static function avg(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression): AvgOperator { return new AvgOperator(...$expression); } @@ -243,9 +244,9 @@ public static function binarySize( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitAnd/ * @no-named-arguments - * @param Int64|ResolvesToInt|ResolvesToLong|int ...$expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression */ - public static function bitAnd(Int64|ResolvesToInt|ResolvesToLong|int ...$expression): BitAndOperator + public static function bitAnd(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression): BitAndOperator { return new BitAndOperator(...$expression); } @@ -255,9 +256,9 @@ public static function bitAnd(Int64|ResolvesToInt|ResolvesToLong|int ...$express * New in MongoDB 6.3. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitNot/ - * @param Int64|ResolvesToInt|ResolvesToLong|int $expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $expression */ - public static function bitNot(Int64|ResolvesToInt|ResolvesToLong|int $expression): BitNotOperator + public static function bitNot(Int64|ResolvesToInt|ResolvesToLong|int|string $expression): BitNotOperator { return new BitNotOperator($expression); } @@ -268,9 +269,9 @@ public static function bitNot(Int64|ResolvesToInt|ResolvesToLong|int $expression * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitOr/ * @no-named-arguments - * @param Int64|ResolvesToInt|ResolvesToLong|int ...$expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression */ - public static function bitOr(Int64|ResolvesToInt|ResolvesToLong|int ...$expression): BitOrOperator + public static function bitOr(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression): BitOrOperator { return new BitOrOperator(...$expression); } @@ -281,9 +282,9 @@ public static function bitOr(Int64|ResolvesToInt|ResolvesToLong|int ...$expressi * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bitXor/ * @no-named-arguments - * @param Int64|ResolvesToInt|ResolvesToLong|int ...$expression + * @param Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression */ - public static function bitXor(Int64|ResolvesToInt|ResolvesToLong|int ...$expression): BitXorOperator + public static function bitXor(Int64|ResolvesToInt|ResolvesToLong|int|string ...$expression): BitXorOperator { return new BitXorOperator(...$expression); } @@ -292,10 +293,10 @@ public static function bitXor(Int64|ResolvesToInt|ResolvesToLong|int ...$express * Returns the size in bytes of a given document (i.e. BSON type Object) when encoded as BSON. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/bsonSize/ - * @param Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass $object + * @param Document|ResolvesToNull|ResolvesToObject|Serializable|array|null|stdClass|string $object */ public static function bsonSize( - Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null $object, + Document|Serializable|ResolvesToNull|ResolvesToObject|stdClass|array|null|string $object, ): BsonSizeOperator { return new BsonSizeOperator($object); } @@ -304,11 +305,11 @@ public static function bsonSize( * Represents a single case in a $switch expression * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/ - * @param ResolvesToBool|bool $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. + * @param ResolvesToBool|bool|string $case Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then Can be any valid expression. */ public static function case( - ResolvesToBool|bool $case, + ResolvesToBool|bool|string $case, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then, ): CaseOperator { return new CaseOperator($case, $then); @@ -318,9 +319,9 @@ public static function case( * Returns the smallest integer greater than or equal to the specified number. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ceil/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression If the argument resolves to a value of null or refers to a field that is missing, $ceil returns null. If the argument resolves to NaN, $ceil returns NaN. */ - public static function ceil(Decimal128|Int64|ResolvesToNumber|float|int $expression): CeilOperator + public static function ceil(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): CeilOperator { return new CeilOperator($expression); } @@ -356,10 +357,11 @@ public static function concat(ResolvesToString|string ...$expression): ConcatOpe * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays/ * @no-named-arguments - * @param BSONArray|PackedArray|ResolvesToArray|array ...$array + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$array */ - public static function concatArrays(PackedArray|ResolvesToArray|BSONArray|array ...$array): ConcatArraysOperator - { + public static function concatArrays( + PackedArray|ResolvesToArray|BSONArray|array|string ...$array, + ): ConcatArraysOperator { return new ConcatArraysOperator(...$array); } @@ -367,12 +369,12 @@ public static function concatArrays(PackedArray|ResolvesToArray|BSONArray|array * A ternary operator that evaluates one expression, and depending on the result, returns the value of one of the other two expressions. Accepts either three expressions in an ordered list or three named parameters. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/cond/ - * @param ResolvesToBool|bool $if + * @param ResolvesToBool|bool|string $if * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $then * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $else */ public static function cond( - ResolvesToBool|bool $if, + ResolvesToBool|bool|string $if, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $then, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $else, ): CondOperator { @@ -404,10 +406,10 @@ public static function convert( * Returns the cosine of a value that is measured in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/cos/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cos takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $cos returns values as a double. $cos can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. */ - public static function cos(Decimal128|Int64|ResolvesToNumber|float|int $expression): CosOperator + public static function cos(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): CosOperator { return new CosOperator($expression); } @@ -416,10 +418,10 @@ public static function cos(Decimal128|Int64|ResolvesToNumber|float|int $expressi * Returns the hyperbolic cosine of a value that is measured in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/cosh/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $cosh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $cosh returns values as a double. $cosh can also return values as a 128-bit decimal if the resolves to a 128-bit decimal value. */ - public static function cosh(Decimal128|Int64|ResolvesToNumber|float|int $expression): CoshOperator + public static function cosh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): CoshOperator { return new CoshOperator($expression); } @@ -428,15 +430,15 @@ public static function cosh(Decimal128|Int64|ResolvesToNumber|float|int $express * Adds a number of time units to a date object. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateAdd/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. - * @param Int64|ResolvesToInt|ResolvesToLong|int $amount + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function dateAdd( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, ResolvesToString|TimeUnit|string $unit, - Int64|ResolvesToInt|ResolvesToLong|int $amount, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): DateAddOperator { return new DateAddOperator($startDate, $unit, $amount, $timezone); @@ -446,15 +448,15 @@ public static function dateAdd( * Returns the difference between two dates. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateDiff/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The start of the time period. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $endDate The end of the time period. The endDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The time measurement unit between the startDate and endDate * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. * @param Optional|ResolvesToString|string $startOfWeek Used when the unit is equal to week. Defaults to Sunday. The startOfWeek parameter is an expression that resolves to a case insensitive string */ public static function dateDiff( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate, - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $endDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $endDate, ResolvesToString|TimeUnit|string $unit, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|ResolvesToString|string $startOfWeek = Optional::Undefined, @@ -466,29 +468,29 @@ public static function dateDiff( * Constructs a BSON Date object given the date's constituent parts. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromParts/ - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $year Calendar year. Can be any expression that evaluates to a number. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $month Month. Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeek Week of year. Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $day Day of month. Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $hour Hour. Defaults to 0. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $minute Minute. Defaults to 0. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $second Second. Defaults to 0. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $millisecond Millisecond. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year Calendar year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear ISO Week Date Year. Can be any expression that evaluates to a number. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month Month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek Week of year. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day Day of month. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek Day of week (Monday 1 - Sunday 7). Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour Hour. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute Minute. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second Second. Defaults to 0. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond Millisecond. Defaults to 0. * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function dateFromParts( - Optional|Decimal128|Int64|ResolvesToNumber|float|int $year = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeekYear = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $month = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoWeek = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $day = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $isoDayOfWeek = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $hour = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $minute = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $second = Optional::Undefined, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $millisecond = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $year = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeekYear = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $month = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $day = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $isoDayOfWeek = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $hour = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $minute = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $second = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $millisecond = Optional::Undefined, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): DateFromPartsOperator { return new DateFromPartsOperator($year, $isoWeekYear, $month, $isoWeek, $day, $isoDayOfWeek, $hour, $minute, $second, $millisecond, $timezone); @@ -521,15 +523,15 @@ public static function dateFromString( * Subtracts a number of time units from a date object. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateSubtract/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $startDate The beginning date, in UTC, for the addition operation. The startDate can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The unit used to measure the amount of time added to the startDate. - * @param Int64|ResolvesToInt|ResolvesToLong|int $amount + * @param Int64|ResolvesToInt|ResolvesToLong|int|string $amount * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function dateSubtract( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $startDate, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $startDate, ResolvesToString|TimeUnit|string $unit, - Int64|ResolvesToInt|ResolvesToLong|int $amount, + Int64|ResolvesToInt|ResolvesToLong|int|string $amount, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): DateSubtractOperator { return new DateSubtractOperator($startDate, $unit, $amount, $timezone); @@ -539,12 +541,12 @@ public static function dateSubtract( * Returns a document containing the constituent parts of a date. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToParts/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The input date for which to return parts. date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. * @param Optional|bool $iso8601 If set to true, modifies the output document to use ISO week date fields. Defaults to false. */ public static function dateToParts( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|bool $iso8601 = Optional::Undefined, ): DateToPartsOperator { @@ -555,7 +557,7 @@ public static function dateToParts( * Returns the date as a formatted string. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToString/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to convert to string. Must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $format The date format specification of the dateString. The format can be any expression that evaluates to a string literal, containing 0 or more format specifiers. * If unspecified, $dateFromString uses "%Y-%m-%dT%H:%M:%S.%LZ" as the default format but accepts a variety of formats and attempts to parse the dateString if possible. * @param Optional|ResolvesToString|string $timezone The time zone to use to format the date. @@ -563,7 +565,7 @@ public static function dateToParts( * If unspecified, $dateToString returns null if the date is null or missing. */ public static function dateToString( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $format = Optional::Undefined, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $onNull = Optional::Undefined, @@ -575,19 +577,19 @@ public static function dateToString( * Truncates a date. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateTrunc/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to truncate, specified in UTC. The date can be any expression that resolves to a Date, a Timestamp, or an ObjectID. * @param ResolvesToString|TimeUnit|string $unit The unit of time, specified as an expression that must resolve to one of these strings: year, quarter, week, month, day, hour, minute, second. * Together, binSize and unit specify the time period used in the $dateTrunc calculation. - * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. + * @param Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize The numeric time value, specified as an expression that must resolve to a positive non-zero number. Defaults to 1. * Together, binSize and unit specify the time period used in the $dateTrunc calculation. * @param Optional|ResolvesToString|string $timezone The timezone to carry out the operation. $timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. * @param Optional|string $startOfWeek The start of the week. Used when * unit is week. Defaults to Sunday. */ public static function dateTrunc( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, ResolvesToString|TimeUnit|string $unit, - Optional|Decimal128|Int64|ResolvesToNumber|float|int $binSize = Optional::Undefined, + Optional|Decimal128|Int64|ResolvesToNumber|float|int|string $binSize = Optional::Undefined, Optional|ResolvesToString|string $timezone = Optional::Undefined, Optional|string $startOfWeek = Optional::Undefined, ): DateTruncOperator { @@ -598,11 +600,11 @@ public static function dateTrunc( * Returns the day of the month for a date as a number between 1 and 31. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfMonth/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function dayOfMonth( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): DayOfMonthOperator { return new DayOfMonthOperator($date, $timezone); @@ -612,11 +614,11 @@ public static function dayOfMonth( * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfWeek/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function dayOfWeek( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): DayOfWeekOperator { return new DayOfWeekOperator($date, $timezone); @@ -626,11 +628,11 @@ public static function dayOfWeek( * Returns the day of the year for a date as a number between 1 and 366 (leap year). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfYear/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function dayOfYear( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): DayOfYearOperator { return new DayOfYearOperator($date, $timezone); @@ -640,11 +642,11 @@ public static function dayOfYear( * Converts a value from degrees to radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/degreesToRadians/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $degreesToRadians takes any valid expression that resolves to a number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $degreesToRadians takes any valid expression that resolves to a number. * By default $degreesToRadians returns values as a double. $degreesToRadians can also return values as a 128-bit decimal as long as the resolves to a 128-bit decimal value. */ public static function degreesToRadians( - Decimal128|Int64|ResolvesToNumber|float|int $expression, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, ): DegreesToRadiansOperator { return new DegreesToRadiansOperator($expression); } @@ -653,12 +655,12 @@ public static function degreesToRadians( * Returns the result of dividing the first number by the second. Accepts two argument expressions. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/divide/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. - * @param Decimal128|Int64|ResolvesToNumber|float|int $divisor + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. the first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ public static function divide( - Decimal128|Int64|ResolvesToNumber|float|int $dividend, - Decimal128|Int64|ResolvesToNumber|float|int $divisor, + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, ): DivideOperator { return new DivideOperator($dividend, $divisor); } @@ -681,9 +683,9 @@ public static function eq( * Raises e to the specified exponent. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/exp/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $exponent + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ - public static function exp(Decimal128|Int64|ResolvesToNumber|float|int $exponent): ExpOperator + public static function exp(Decimal128|Int64|ResolvesToNumber|float|int|string $exponent): ExpOperator { return new ExpOperator($exponent); } @@ -692,17 +694,17 @@ public static function exp(Decimal128|Int64|ResolvesToNumber|float|int $exponent * Selects a subset of the array to return an array with only the elements that match the filter condition. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input - * @param ResolvesToBool|bool $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input + * @param ResolvesToBool|bool|string $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. * @param Optional|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. - * @param Optional|ResolvesToInt|int $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. + * @param Optional|ResolvesToInt|int|string $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. */ public static function filter( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToBool|bool $cond, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToBool|bool|string $cond, Optional|string $as = Optional::Undefined, - Optional|ResolvesToInt|int $limit = Optional::Undefined, + Optional|ResolvesToInt|int|string $limit = Optional::Undefined, ): FilterOperator { return new FilterOperator($input, $cond, $as, $limit); } @@ -711,9 +713,9 @@ public static function filter( * Returns the result of an expression for the first document in an array. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/first/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ - public static function first(PackedArray|ResolvesToArray|BSONArray|array $expression): FirstOperator + public static function first(PackedArray|ResolvesToArray|BSONArray|array|string $expression): FirstOperator { return new FirstOperator($expression); } @@ -722,12 +724,12 @@ public static function first(PackedArray|ResolvesToArray|BSONArray|array $expres * Returns a specified number of elements from the beginning of an array. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN-array-element/ - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ public static function firstN( - ResolvesToInt|int $n, - PackedArray|ResolvesToArray|BSONArray|array $input, + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, ): FirstNOperator { return new FirstNOperator($n, $input); } @@ -736,9 +738,9 @@ public static function firstN( * Returns the largest integer less than or equal to the specified number. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/floor/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public static function floor(Decimal128|Int64|ResolvesToNumber|float|int $expression): FloorOperator + public static function floor(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): FloorOperator { return new FloorOperator($expression); } @@ -810,11 +812,11 @@ public static function gte( * Returns the hour for a date as a number between 0 and 23. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/hour/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function hour( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): HourOperator { return new HourOperator($date, $timezone); @@ -838,11 +840,11 @@ public static function ifNull( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/in/ * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression Any valid expression expression. - * @param BSONArray|PackedArray|ResolvesToArray|array $array Any valid expression that resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Any valid expression that resolves to an array. */ public static function in( Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, - PackedArray|ResolvesToArray|BSONArray|array $array, + PackedArray|ResolvesToArray|BSONArray|array|string $array, ): InOperator { return new InOperator($expression, $array); } @@ -851,20 +853,20 @@ public static function in( * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. Array indexes start at zero. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfArray/ - * @param BSONArray|PackedArray|ResolvesToArray|array $array Can be any valid expression as long as it resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Can be any valid expression as long as it resolves to an array. * If the array expression resolves to a value of null or refers to a field that is missing, $indexOfArray returns null. * If the array expression does not resolve to an array or null nor refers to a missing field, $indexOfArray returns an error. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $search - * @param Optional|ResolvesToInt|int $start 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. + * @param Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. - * @param Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @param Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ public static function indexOfArray( - PackedArray|ResolvesToArray|BSONArray|array $array, + PackedArray|ResolvesToArray|BSONArray|array|string $array, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $search, - Optional|ResolvesToInt|int $start = Optional::Undefined, - Optional|ResolvesToInt|int $end = Optional::Undefined, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, ): IndexOfArrayOperator { return new IndexOfArrayOperator($array, $search, $start, $end); } @@ -877,16 +879,16 @@ public static function indexOfArray( * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfBytes returns null. * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfBytes returns an error. * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. - * @param Optional|ResolvesToInt|int $start 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. + * @param Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. - * @param Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @param Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ public static function indexOfBytes( ResolvesToString|string $string, ResolvesToString|string $substring, - Optional|ResolvesToInt|int $start = Optional::Undefined, - Optional|ResolvesToInt|int $end = Optional::Undefined, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, ): IndexOfBytesOperator { return new IndexOfBytesOperator($string, $substring, $start, $end); } @@ -899,16 +901,16 @@ public static function indexOfBytes( * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfCP returns null. * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfCP returns an error. * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. - * @param Optional|ResolvesToInt|int $start 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. + * @param Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. - * @param Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @param Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ public static function indexOfCP( ResolvesToString|string $string, ResolvesToString|string $substring, - Optional|ResolvesToInt|int $start = Optional::Undefined, - Optional|ResolvesToInt|int $end = Optional::Undefined, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, ): IndexOfCPOperator { return new IndexOfCPOperator($string, $substring, $start, $end); } @@ -943,11 +945,11 @@ public static function isNumber( * Returns the weekday number in ISO 8601 format, ranging from 1 (for Monday) to 7 (for Sunday). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoDayOfWeek/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function isoDayOfWeek( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): IsoDayOfWeekOperator { return new IsoDayOfWeekOperator($date, $timezone); @@ -957,11 +959,11 @@ public static function isoDayOfWeek( * Returns the week number in ISO 8601 format, ranging from 1 to 53. Week numbers start at 1 with the week (Monday through Sunday) that contains the year's first Thursday. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeek/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function isoWeek( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): IsoWeekOperator { return new IsoWeekOperator($date, $timezone); @@ -971,11 +973,11 @@ public static function isoWeek( * Returns the year number in ISO 8601 format. The year starts with the Monday of week 1 (ISO 8601) and ends with the Sunday of the last week (ISO 8601). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeekYear/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function isoWeekYear( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): IsoWeekYearOperator { return new IsoWeekYearOperator($date, $timezone); @@ -985,9 +987,9 @@ public static function isoWeekYear( * Returns the result of an expression for the last document in an array. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/last/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ - public static function last(PackedArray|ResolvesToArray|BSONArray|array $expression): LastOperator + public static function last(PackedArray|ResolvesToArray|BSONArray|array|string $expression): LastOperator { return new LastOperator($expression); } @@ -996,12 +998,12 @@ public static function last(PackedArray|ResolvesToArray|BSONArray|array $express * Returns a specified number of elements from the end of an array. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN-array-element/ - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ public static function lastN( - ResolvesToInt|int $n, - PackedArray|ResolvesToArray|BSONArray|array $input, + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, ): LastNOperator { return new LastNOperator($n, $input); } @@ -1038,9 +1040,9 @@ public static function literal(Type|stdClass|array|bool|float|int|null|string $v * $ln is equivalent to $log: [ , Math.E ] expression, where Math.E is a JavaScript representation for Euler's number e. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/ln/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. */ - public static function ln(Decimal128|Int64|ResolvesToNumber|float|int $number): LnOperator + public static function ln(Decimal128|Int64|ResolvesToNumber|float|int|string $number): LnOperator { return new LnOperator($number); } @@ -1049,12 +1051,12 @@ public static function ln(Decimal128|Int64|ResolvesToNumber|float|int $number): * Calculates the log of a number in the specified base. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/log/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. - * @param Decimal128|Int64|ResolvesToNumber|float|int $base Any valid expression as long as it resolves to a positive number greater than 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $base Any valid expression as long as it resolves to a positive number greater than 1. */ public static function log( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Decimal128|Int64|ResolvesToNumber|float|int $base, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $base, ): LogOperator { return new LogOperator($number, $base); } @@ -1063,9 +1065,9 @@ public static function log( * Calculates the log base 10 of a number. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/log10/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. */ - public static function log10(Decimal128|Int64|ResolvesToNumber|float|int $number): Log10Operator + public static function log10(Decimal128|Int64|ResolvesToNumber|float|int|string $number): Log10Operator { return new Log10Operator($number); } @@ -1119,12 +1121,12 @@ public static function ltrim( * Applies a subexpression to each element of an array and returns the array of resulting values in order. Accepts named parameters. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/map/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to an array. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. * @param Optional|ResolvesToString|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. */ public static function map( - PackedArray|ResolvesToArray|BSONArray|array $input, + PackedArray|ResolvesToArray|BSONArray|array|string $input, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, Optional|ResolvesToString|string $as = Optional::Undefined, ): MapOperator { @@ -1149,12 +1151,12 @@ public static function max( * Returns the n largest values in an array. Distinct from the $maxN accumulator. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN-array-element/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ public static function maxN( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToInt|int $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, ): MaxNOperator { return new MaxNOperator($input, $n); } @@ -1168,11 +1170,11 @@ public static function maxN( * It is also available as an aggregation expression. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/median/ - * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ public static function median( - Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int $input, + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, string $method, ): MedianOperator { return new MedianOperator($input, $method); @@ -1183,10 +1185,10 @@ public static function median( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects/ * @no-named-arguments - * @param Document|ResolvesToObject|Serializable|array|stdClass ...$document Any valid expression that resolves to a document. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string ...$document Any valid expression that resolves to a document. */ public static function mergeObjects( - Document|Serializable|ResolvesToObject|stdClass|array ...$document, + Document|Serializable|ResolvesToObject|stdClass|array|string ...$document, ): MergeObjectsOperator { return new MergeObjectsOperator(...$document); } @@ -1206,11 +1208,11 @@ public static function meta(string $keyword): MetaOperator * Returns the milliseconds of a date as a number between 0 and 999. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/millisecond/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function millisecond( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): MillisecondOperator { return new MillisecondOperator($date, $timezone); @@ -1234,12 +1236,12 @@ public static function min( * Returns the n smallest values in an array. Distinct from the $minN accumulator. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN-array-element/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ public static function minN( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToInt|int $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, ): MinNOperator { return new MinNOperator($input, $n); } @@ -1248,11 +1250,11 @@ public static function minN( * Returns the minute for a date as a number between 0 and 59. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/minute/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function minute( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): MinuteOperator { return new MinuteOperator($date, $timezone); @@ -1262,12 +1264,12 @@ public static function minute( * Returns the remainder of the first number divided by the second. Accepts two argument expressions. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/mod/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. - * @param Decimal128|Int64|ResolvesToNumber|float|int $divisor + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ public static function mod( - Decimal128|Int64|ResolvesToNumber|float|int $dividend, - Decimal128|Int64|ResolvesToNumber|float|int $divisor, + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, ): ModOperator { return new ModOperator($dividend, $divisor); } @@ -1276,11 +1278,11 @@ public static function mod( * Returns the month for a date as a number between 1 (January) and 12 (December). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/month/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function month( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): MonthOperator { return new MonthOperator($date, $timezone); @@ -1291,11 +1293,12 @@ public static function month( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/multiply/ * @no-named-arguments - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression The arguments can be any valid expression as long as they resolve to numbers. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to numbers. * Starting in MongoDB 6.1 you can optimize the $multiply operation. To improve performance, group references at the end of the argument list. */ - public static function multiply(Decimal128|Int64|ResolvesToNumber|float|int ...$expression): MultiplyOperator - { + public static function multiply( + Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression, + ): MultiplyOperator { return new MultiplyOperator(...$expression); } @@ -1329,10 +1332,10 @@ public static function not( * Converts a document to an array of documents representing key-value pairs. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/objectToArray/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. */ public static function objectToArray( - Document|Serializable|ResolvesToObject|stdClass|array $object, + Document|Serializable|ResolvesToObject|stdClass|array|string $object, ): ObjectToArrayOperator { return new ObjectToArrayOperator($object); } @@ -1362,14 +1365,14 @@ public static function or( * It is also available as an aggregation expression. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/ - * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. - * @param BSONArray|PackedArray|ResolvesToArray|array $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. * $percentile returns results in the same order as the elements in p. * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ public static function percentile( - Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int $input, - PackedArray|ResolvesToArray|BSONArray|array $p, + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, string $method, ): PercentileOperator { return new PercentileOperator($input, $p, $method); @@ -1379,12 +1382,12 @@ public static function percentile( * Raises a number to the specified exponent. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/pow/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number - * @param Decimal128|Int64|ResolvesToNumber|float|int $exponent + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ public static function pow( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Decimal128|Int64|ResolvesToNumber|float|int $exponent, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $exponent, ): PowOperator { return new PowOperator($number, $exponent); } @@ -1393,10 +1396,10 @@ public static function pow( * Converts a value from radians to degrees. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/radiansToDegrees/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ public static function radiansToDegrees( - Decimal128|Int64|ResolvesToNumber|float|int $expression, + Decimal128|Int64|ResolvesToNumber|float|int|string $expression, ): RadiansToDegreesOperator { return new RadiansToDegreesOperator($expression); } @@ -1415,14 +1418,14 @@ public static function rand(): RandOperator * Outputs an array containing a sequence of integers according to user-defined inputs. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/range/ - * @param ResolvesToInt|int $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. - * @param ResolvesToInt|int $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. - * @param Optional|ResolvesToInt|int $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. + * @param ResolvesToInt|int|string $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. + * @param ResolvesToInt|int|string $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. + * @param Optional|ResolvesToInt|int|string $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. */ public static function range( - ResolvesToInt|int $start, - ResolvesToInt|int $end, - Optional|ResolvesToInt|int $step = Optional::Undefined, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $end, + Optional|ResolvesToInt|int|string $step = Optional::Undefined, ): RangeOperator { return new RangeOperator($start, $end, $step); } @@ -1431,7 +1434,7 @@ public static function range( * Applies an expression to each element in an array and combines them into a single value. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/reduce/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input Can be any valid expression that resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input Can be any valid expression that resolves to an array. * If the argument resolves to a value of null or refers to a missing field, $reduce returns null. * If the argument does not resolve to an array or null nor refers to a missing field, $reduce returns an error. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $initialValue The initial cumulative value set before in is applied to the first element of the input array. @@ -1441,7 +1444,7 @@ public static function range( * - this is the variable that refers to the element being processed. */ public static function reduce( - PackedArray|ResolvesToArray|BSONArray|array $input, + PackedArray|ResolvesToArray|BSONArray|array|string $input, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $initialValue, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, ): ReduceOperator { @@ -1538,10 +1541,11 @@ public static function replaceOne( * Returns an array with the elements in reverse order. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/reverseArray/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression The argument can be any valid expression as long as it resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument can be any valid expression as long as it resolves to an array. */ - public static function reverseArray(PackedArray|ResolvesToArray|BSONArray|array $expression): ReverseArrayOperator - { + public static function reverseArray( + PackedArray|ResolvesToArray|BSONArray|array|string $expression, + ): ReverseArrayOperator { return new ReverseArrayOperator($expression); } @@ -1549,13 +1553,13 @@ public static function reverseArray(PackedArray|ResolvesToArray|BSONArray|array * Rounds a number to a whole integer or to a specified decimal place. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $round returns an error if the expression resolves to a non-numeric data type. - * @param Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ public static function round( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Optional|ResolvesToInt|int $place = Optional::Undefined, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, ): RoundOperator { return new RoundOperator($number, $place); } @@ -1580,11 +1584,11 @@ public static function rtrim( * Returns the seconds for a date as a number between 0 and 60 (leap seconds). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/second/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function second( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): SecondOperator { return new SecondOperator($date, $timezone); @@ -1594,12 +1598,12 @@ public static function second( * Returns a set with elements that appear in the first set but not in the second set; i.e. performs a relative complement of the second set relative to the first. Accepts exactly two argument expressions. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setDifference/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression1 The arguments can be any valid expression as long as they each resolve to an array. - * @param BSONArray|PackedArray|ResolvesToArray|array $expression2 The arguments can be any valid expression as long as they each resolve to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 The arguments can be any valid expression as long as they each resolve to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 The arguments can be any valid expression as long as they each resolve to an array. */ public static function setDifference( - PackedArray|ResolvesToArray|BSONArray|array $expression1, - PackedArray|ResolvesToArray|BSONArray|array $expression2, + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, ): SetDifferenceOperator { return new SetDifferenceOperator($expression1, $expression2); } @@ -1609,10 +1613,11 @@ public static function setDifference( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setEquals/ * @no-named-arguments - * @param BSONArray|PackedArray|ResolvesToArray|array ...$expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression */ - public static function setEquals(PackedArray|ResolvesToArray|BSONArray|array ...$expression): SetEqualsOperator - { + public static function setEquals( + PackedArray|ResolvesToArray|BSONArray|array|string ...$expression, + ): SetEqualsOperator { return new SetEqualsOperator(...$expression); } @@ -1622,13 +1627,13 @@ public static function setEquals(PackedArray|ResolvesToArray|BSONArray|array ... * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setField/ * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. - * @param Document|ResolvesToObject|Serializable|array|stdClass $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value The value that you want to assign to field. value can be any valid expression. * Set to $$REMOVE to remove field from the input document. */ public static function setField( ResolvesToString|string $field, - Document|Serializable|ResolvesToObject|stdClass|array $input, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value, ): SetFieldOperator { return new SetFieldOperator($field, $input, $value); @@ -1639,10 +1644,10 @@ public static function setField( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIntersection/ * @no-named-arguments - * @param BSONArray|PackedArray|ResolvesToArray|array ...$expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression */ public static function setIntersection( - PackedArray|ResolvesToArray|BSONArray|array ...$expression, + PackedArray|ResolvesToArray|BSONArray|array|string ...$expression, ): SetIntersectionOperator { return new SetIntersectionOperator(...$expression); } @@ -1651,12 +1656,12 @@ public static function setIntersection( * Returns true if all elements of the first set appear in the second set, including when the first set equals the second set; i.e. not a strict subset. Accepts exactly two argument expressions. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIsSubset/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression1 - * @param BSONArray|PackedArray|ResolvesToArray|array $expression2 + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 */ public static function setIsSubset( - PackedArray|ResolvesToArray|BSONArray|array $expression1, - PackedArray|ResolvesToArray|BSONArray|array $expression2, + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, ): SetIsSubsetOperator { return new SetIsSubsetOperator($expression1, $expression2); } @@ -1666,10 +1671,11 @@ public static function setIsSubset( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/ * @no-named-arguments - * @param BSONArray|PackedArray|ResolvesToArray|array ...$expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression */ - public static function setUnion(PackedArray|ResolvesToArray|BSONArray|array ...$expression): SetUnionOperator - { + public static function setUnion( + PackedArray|ResolvesToArray|BSONArray|array|string ...$expression, + ): SetUnionOperator { return new SetUnionOperator(...$expression); } @@ -1677,10 +1683,10 @@ public static function setUnion(PackedArray|ResolvesToArray|BSONArray|array ...$ * Returns the sine of a value that is measured in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $sin returns values as a double. $sin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function sin(Decimal128|Int64|ResolvesToNumber|float|int $expression): SinOperator + public static function sin(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): SinOperator { return new SinOperator($expression); } @@ -1689,10 +1695,10 @@ public static function sin(Decimal128|Int64|ResolvesToNumber|float|int $expressi * Returns the hyperbolic sine of a value that is measured in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $sinh returns values as a double. $sinh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. */ - public static function sinh(Decimal128|Int64|ResolvesToNumber|float|int $expression): SinhOperator + public static function sinh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): SinhOperator { return new SinhOperator($expression); } @@ -1701,9 +1707,9 @@ public static function sinh(Decimal128|Int64|ResolvesToNumber|float|int $express * Returns the number of elements in the array. Accepts a single expression as argument. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression The argument for $size can be any expression as long as it resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument for $size can be any expression as long as it resolves to an array. */ - public static function size(PackedArray|ResolvesToArray|BSONArray|array $expression): SizeOperator + public static function size(PackedArray|ResolvesToArray|BSONArray|array|string $expression): SizeOperator { return new SizeOperator($expression); } @@ -1712,18 +1718,18 @@ public static function size(PackedArray|ResolvesToArray|BSONArray|array $express * Returns a subset of an array. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/slice/ - * @param BSONArray|PackedArray|ResolvesToArray|array $expression Any valid expression as long as it resolves to an array. - * @param ResolvesToInt|int $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression Any valid expression as long as it resolves to an array. + * @param ResolvesToInt|int|string $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. * If positive, $slice returns up to the first n elements in the array. If the position is specified, $slice returns the first n elements starting from the position. * If negative, $slice returns up to the last n elements in the array. n cannot resolve to a negative number if is specified. - * @param Optional|ResolvesToInt|int $position Any valid expression as long as it resolves to an integer. + * @param Optional|ResolvesToInt|int|string $position Any valid expression as long as it resolves to an integer. * If positive, $slice determines the starting position from the start of the array. If position is greater than the number of elements, the $slice returns an empty array. * If negative, $slice determines the starting position from the end of the array. If the absolute value of the is greater than the number of elements, the starting position is the start of the array. */ public static function slice( - PackedArray|ResolvesToArray|BSONArray|array $expression, - ResolvesToInt|int $n, - Optional|ResolvesToInt|int $position = Optional::Undefined, + PackedArray|ResolvesToArray|BSONArray|array|string $expression, + ResolvesToInt|int|string $n, + Optional|ResolvesToInt|int|string $position = Optional::Undefined, ): SliceOperator { return new SliceOperator($expression, $n, $position); } @@ -1732,13 +1738,13 @@ public static function slice( * Sorts the elements of an array. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortArray/ - * @param BSONArray|PackedArray|ResolvesToArray|array $input The array to be sorted. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input The array to be sorted. * The result is null if the expression: is missing, evaluates to null, or evaluates to undefined * If the expression evaluates to any other non-array value, the document returns an error. * @param Document|Serializable|Sort|array|int|stdClass $sortBy The document specifies a sort ordering. */ public static function sortArray( - PackedArray|ResolvesToArray|BSONArray|array $input, + PackedArray|ResolvesToArray|BSONArray|array|string $input, Document|Serializable|Sort|stdClass|array|int $sortBy, ): SortArrayOperator { return new SortArrayOperator($input, $sortBy); @@ -1760,9 +1766,9 @@ public static function split(ResolvesToString|string $string, ResolvesToString|s * Calculates the square root. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sqrt/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number The argument can be any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number The argument can be any valid expression as long as it resolves to a non-negative number. */ - public static function sqrt(Decimal128|Int64|ResolvesToNumber|float|int $number): SqrtOperator + public static function sqrt(Decimal128|Int64|ResolvesToNumber|float|int|string $number): SqrtOperator { return new SqrtOperator($number); } @@ -1774,10 +1780,11 @@ public static function sqrt(Decimal128|Int64|ResolvesToNumber|float|int $number) * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop/ * @no-named-arguments - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression */ - public static function stdDevPop(Decimal128|Int64|ResolvesToNumber|float|int ...$expression): StdDevPopOperator - { + public static function stdDevPop( + Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression, + ): StdDevPopOperator { return new StdDevPopOperator(...$expression); } @@ -1787,10 +1794,11 @@ public static function stdDevPop(Decimal128|Int64|ResolvesToNumber|float|int ... * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp/ * @no-named-arguments - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression */ - public static function stdDevSamp(Decimal128|Int64|ResolvesToNumber|float|int ...$expression): StdDevSampOperator - { + public static function stdDevSamp( + Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression, + ): StdDevSampOperator { return new StdDevSampOperator(...$expression); } @@ -1835,13 +1843,13 @@ public static function strLenCP(ResolvesToString|string $expression): StrLenCPOp * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/substr/ * @param ResolvesToString|string $string - * @param ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". - * @param ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ public static function substr( ResolvesToString|string $string, - ResolvesToInt|int $start, - ResolvesToInt|int $length, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, ): SubstrOperator { return new SubstrOperator($string, $start, $length); } @@ -1851,13 +1859,13 @@ public static function substr( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrBytes/ * @param ResolvesToString|string $string - * @param ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". - * @param ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ public static function substrBytes( ResolvesToString|string $string, - ResolvesToInt|int $start, - ResolvesToInt|int $length, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, ): SubstrBytesOperator { return new SubstrBytesOperator($string, $start, $length); } @@ -1867,13 +1875,13 @@ public static function substrBytes( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrCP/ * @param ResolvesToString|string $string - * @param ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". - * @param ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ public static function substrCP( ResolvesToString|string $string, - ResolvesToInt|int $start, - ResolvesToInt|int $length, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, ): SubstrCPOperator { return new SubstrCPOperator($string, $start, $length); } @@ -1882,12 +1890,12 @@ public static function substrCP( * Returns the result of subtracting the second value from the first. If the two values are numbers, return the difference. If the two values are dates, return the difference in milliseconds. If the two values are a date and a number in milliseconds, return the resulting date. Accepts two argument expressions. If the two values are a date and a number, specify the date argument first as it is not meaningful to subtract a date from a number. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtract/ - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $expression1 - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $expression2 + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression2 */ public static function subtract( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $expression1, - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $expression2, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression2, ): SubtractOperator { return new SubtractOperator($expression1, $expression2); } @@ -1898,10 +1906,10 @@ public static function subtract( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/ * @no-named-arguments - * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|array|float|int ...$expression + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|array|float|int|string ...$expression */ public static function sum( - Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|BSONArray|array|float|int ...$expression, + Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|BSONArray|array|float|int|string ...$expression, ): SumOperator { return new SumOperator(...$expression); } @@ -1928,10 +1936,10 @@ public static function switch( * Returns the tangent of a value that is measured in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tan/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $tan returns values as a double. $tan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public static function tan(Decimal128|Int64|ResolvesToNumber|float|int $expression): TanOperator + public static function tan(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): TanOperator { return new TanOperator($expression); } @@ -1940,10 +1948,10 @@ public static function tan(Decimal128|Int64|ResolvesToNumber|float|int $expressi * Returns the hyperbolic tangent of a value that is measured in radians. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tanh/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $tanh returns values as a double. $tanh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. */ - public static function tanh(Decimal128|Int64|ResolvesToNumber|float|int $expression): TanhOperator + public static function tanh(Decimal128|Int64|ResolvesToNumber|float|int|string $expression): TanhOperator { return new TanhOperator($expression); } @@ -2107,13 +2115,13 @@ public static function trim( * Truncates a number to a whole integer or to a specified decimal place. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/trunc/ - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $trunc returns an error if the expression resolves to a non-numeric data type. - * @param Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. */ public static function trunc( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Optional|ResolvesToInt|int $place = Optional::Undefined, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, ): TruncOperator { return new TruncOperator($number, $place); } @@ -2123,9 +2131,9 @@ public static function trunc( * New in MongoDB 5.1. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tsIncrement/ - * @param ResolvesToTimestamp|Timestamp|int $expression + * @param ResolvesToTimestamp|Timestamp|int|string $expression */ - public static function tsIncrement(Timestamp|ResolvesToTimestamp|int $expression): TsIncrementOperator + public static function tsIncrement(Timestamp|ResolvesToTimestamp|int|string $expression): TsIncrementOperator { return new TsIncrementOperator($expression); } @@ -2135,9 +2143,9 @@ public static function tsIncrement(Timestamp|ResolvesToTimestamp|int $expression * New in MongoDB 5.1. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/tsSecond/ - * @param ResolvesToTimestamp|Timestamp|int $expression + * @param ResolvesToTimestamp|Timestamp|int|string $expression */ - public static function tsSecond(Timestamp|ResolvesToTimestamp|int $expression): TsSecondOperator + public static function tsSecond(Timestamp|ResolvesToTimestamp|int|string $expression): TsSecondOperator { return new TsSecondOperator($expression); } @@ -2160,11 +2168,11 @@ public static function type( * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/unsetField/ * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. - * @param Document|ResolvesToObject|Serializable|array|stdClass $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ public static function unsetField( ResolvesToString|string $field, - Document|Serializable|ResolvesToObject|stdClass|array $input, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, ): UnsetFieldOperator { return new UnsetFieldOperator($field, $input); } @@ -2173,11 +2181,11 @@ public static function unsetField( * Returns the week number for a date as a number between 0 (the partial week that precedes the first Sunday of the year) and 53 (leap year). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/week/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function week( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): WeekOperator { return new WeekOperator($date, $timezone); @@ -2187,11 +2195,11 @@ public static function week( * Returns the year for a date as a number (e.g. 2014). * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/year/ - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public static function year( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ): YearOperator { return new YearOperator($date, $timezone); @@ -2201,7 +2209,7 @@ public static function year( * Merge two arrays together. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/zip/ - * @param BSONArray|PackedArray|ResolvesToArray|array $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. * If any of the inputs arrays resolves to a value of null or refers to a missing field, $zip returns null. * If any of the inputs arrays does not resolve to an array or null nor refers to a missing field, $zip returns an error. * @param Optional|bool $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array. @@ -2211,7 +2219,7 @@ public static function year( * If specifying a non-empty defaults, you must specify a default for each input array or else $zip will return an error. */ public static function zip( - PackedArray|ResolvesToArray|BSONArray|array $inputs, + PackedArray|ResolvesToArray|BSONArray|array|string $inputs, Optional|bool $useLongestLength = Optional::Undefined, Optional|PackedArray|BSONArray|array $defaults = Optional::Undefined, ): ZipOperator { diff --git a/src/Builder/Expression/FilterOperator.php b/src/Builder/Expression/FilterOperator.php index 9bd522572..b2f2df99c 100644 --- a/src/Builder/Expression/FilterOperator.php +++ b/src/Builder/Expression/FilterOperator.php @@ -17,6 +17,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Selects a subset of the array to return an array with only the elements that match the filter condition. @@ -30,41 +32,53 @@ final class FilterOperator implements ResolvesToArray, OperatorInterface public const NAME = '$filter'; public const PROPERTIES = ['input' => 'input', 'cond' => 'cond', 'as' => 'as', 'limit' => 'limit']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; - /** @var ResolvesToBool|bool $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. */ - public readonly ResolvesToBool|bool $cond; + /** @var ResolvesToBool|bool|string $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. */ + public readonly ResolvesToBool|bool|string $cond; /** @var Optional|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. */ public readonly Optional|string $as; /** - * @var Optional|ResolvesToInt|int $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. + * @var Optional|ResolvesToInt|int|string $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. */ - public readonly Optional|ResolvesToInt|int $limit; + public readonly Optional|ResolvesToInt|int|string $limit; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input - * @param ResolvesToBool|bool $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input + * @param ResolvesToBool|bool|string $cond An expression that resolves to a boolean value used to determine if an element should be included in the output array. The expression references each element of the input array individually with the variable name specified in as. * @param Optional|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. - * @param Optional|ResolvesToInt|int $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. + * @param Optional|ResolvesToInt|int|string $limit A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $input, - ResolvesToBool|bool $cond, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToBool|bool|string $cond, Optional|string $as = Optional::Undefined, - Optional|ResolvesToInt|int $limit = Optional::Undefined, + Optional|ResolvesToInt|int|string $limit = Optional::Undefined, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($cond) && ! str_starts_with($cond, '$')) { + throw new InvalidArgumentException('Argument $cond can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->cond = $cond; $this->as = $as; + if (is_string($limit) && ! str_starts_with($limit, '$')) { + throw new InvalidArgumentException('Argument $limit can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->limit = $limit; } } diff --git a/src/Builder/Expression/FirstNOperator.php b/src/Builder/Expression/FirstNOperator.php index 769c38118..9051441dc 100644 --- a/src/Builder/Expression/FirstNOperator.php +++ b/src/Builder/Expression/FirstNOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns a specified number of elements from the beginning of an array. @@ -29,19 +31,29 @@ final class FirstNOperator implements ResolvesToArray, OperatorInterface public const NAME = '$firstN'; public const PROPERTIES = ['n' => 'n', 'input' => 'input']; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ + public readonly ResolvesToInt|int|string $n; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; /** - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ - public function __construct(ResolvesToInt|int $n, PackedArray|ResolvesToArray|BSONArray|array $input) - { + public function __construct( + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/FirstOperator.php b/src/Builder/Expression/FirstOperator.php index 994de7bee..d967bf7d2 100644 --- a/src/Builder/Expression/FirstOperator.php +++ b/src/Builder/Expression/FirstOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the result of an expression for the first document in an array. @@ -29,14 +31,18 @@ final class FirstOperator implements ResolvesToAny, OperatorInterface public const NAME = '$first'; public const PROPERTIES = ['expression' => 'expression']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/FloorOperator.php b/src/Builder/Expression/FloorOperator.php index 741412330..b81d5e05f 100644 --- a/src/Builder/Expression/FloorOperator.php +++ b/src/Builder/Expression/FloorOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the largest integer less than or equal to the specified number. @@ -25,14 +29,18 @@ final class FloorOperator implements ResolvesToInt, OperatorInterface public const NAME = '$floor'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/HourOperator.php b/src/Builder/Expression/HourOperator.php index 5c68b7446..8110c09c4 100644 --- a/src/Builder/Expression/HourOperator.php +++ b/src/Builder/Expression/HourOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the hour for a date as a number between 0 and 23. @@ -27,20 +31,24 @@ final class HourOperator implements ResolvesToInt, OperatorInterface public const NAME = '$hour'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/InOperator.php b/src/Builder/Expression/InOperator.php index c2e24b9dc..2bc43265f 100644 --- a/src/Builder/Expression/InOperator.php +++ b/src/Builder/Expression/InOperator.php @@ -19,6 +19,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns a boolean indicating whether a specified value is in an array. @@ -35,18 +37,22 @@ final class InOperator implements ResolvesToBool, OperatorInterface /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression Any valid expression expression. */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression; - /** @var BSONArray|PackedArray|ResolvesToArray|array $array Any valid expression that resolves to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $array; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $array Any valid expression that resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; /** * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $expression Any valid expression expression. - * @param BSONArray|PackedArray|ResolvesToArray|array $array Any valid expression that resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Any valid expression that resolves to an array. */ public function __construct( Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $expression, - PackedArray|ResolvesToArray|BSONArray|array $array, + PackedArray|ResolvesToArray|BSONArray|array|string $array, ) { $this->expression = $expression; + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($array) && ! array_is_list($array)) { throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/IndexOfArrayOperator.php b/src/Builder/Expression/IndexOfArrayOperator.php index 15e3e4626..d364b0a10 100644 --- a/src/Builder/Expression/IndexOfArrayOperator.php +++ b/src/Builder/Expression/IndexOfArrayOperator.php @@ -20,6 +20,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. Array indexes start at zero. @@ -34,50 +36,62 @@ final class IndexOfArrayOperator implements ResolvesToInt, OperatorInterface public const PROPERTIES = ['array' => 'array', 'search' => 'search', 'start' => 'start', 'end' => 'end']; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $array Can be any valid expression as long as it resolves to an array. + * @var BSONArray|PackedArray|ResolvesToArray|array|string $array Can be any valid expression as long as it resolves to an array. * If the array expression resolves to a value of null or refers to a field that is missing, $indexOfArray returns null. * If the array expression does not resolve to an array or null nor refers to a missing field, $indexOfArray returns an error. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $array; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $array; /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $search */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $search; /** - * @var Optional|ResolvesToInt|int $start 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. + * @var Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. */ - public readonly Optional|ResolvesToInt|int $start; + public readonly Optional|ResolvesToInt|int|string $start; /** - * @var Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @var Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ - public readonly Optional|ResolvesToInt|int $end; + public readonly Optional|ResolvesToInt|int|string $end; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $array Can be any valid expression as long as it resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $array Can be any valid expression as long as it resolves to an array. * If the array expression resolves to a value of null or refers to a field that is missing, $indexOfArray returns null. * If the array expression does not resolve to an array or null nor refers to a missing field, $indexOfArray returns an error. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $search - * @param Optional|ResolvesToInt|int $start 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. + * @param Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. - * @param Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @param Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $array, + PackedArray|ResolvesToArray|BSONArray|array|string $array, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $search, - Optional|ResolvesToInt|int $start = Optional::Undefined, - Optional|ResolvesToInt|int $end = Optional::Undefined, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, ) { + if (is_string($array) && ! str_starts_with($array, '$')) { + throw new InvalidArgumentException('Argument $array can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($array) && ! array_is_list($array)) { throw new InvalidArgumentException('Expected $array argument to be a list, got an associative array.'); } $this->array = $array; $this->search = $search; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->end = $end; } } diff --git a/src/Builder/Expression/IndexOfBytesOperator.php b/src/Builder/Expression/IndexOfBytesOperator.php index 9f3d07533..e2f2a1cae 100644 --- a/src/Builder/Expression/IndexOfBytesOperator.php +++ b/src/Builder/Expression/IndexOfBytesOperator.php @@ -11,6 +11,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Searches a string for an occurrence of a substring and returns the UTF-8 byte index of the first occurrence. If the substring is not found, returns -1. @@ -35,36 +39,44 @@ final class IndexOfBytesOperator implements ResolvesToInt, OperatorInterface public readonly ResolvesToString|string $substring; /** - * @var Optional|ResolvesToInt|int $start 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. + * @var Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. */ - public readonly Optional|ResolvesToInt|int $start; + public readonly Optional|ResolvesToInt|int|string $start; /** - * @var Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @var Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ - public readonly Optional|ResolvesToInt|int $end; + public readonly Optional|ResolvesToInt|int|string $end; /** * @param ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfBytes returns null. * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfBytes returns an error. * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. - * @param Optional|ResolvesToInt|int $start 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. + * @param Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. - * @param Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @param Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ public function __construct( ResolvesToString|string $string, ResolvesToString|string $substring, - Optional|ResolvesToInt|int $start = Optional::Undefined, - Optional|ResolvesToInt|int $end = Optional::Undefined, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, ) { $this->string = $string; $this->substring = $substring; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->end = $end; } } diff --git a/src/Builder/Expression/IndexOfCPOperator.php b/src/Builder/Expression/IndexOfCPOperator.php index 735de9759..67b0c33ea 100644 --- a/src/Builder/Expression/IndexOfCPOperator.php +++ b/src/Builder/Expression/IndexOfCPOperator.php @@ -11,6 +11,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Searches a string for an occurrence of a substring and returns the UTF-8 code point index of the first occurrence. If the substring is not found, returns -1 @@ -35,36 +39,44 @@ final class IndexOfCPOperator implements ResolvesToInt, OperatorInterface public readonly ResolvesToString|string $substring; /** - * @var Optional|ResolvesToInt|int $start 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. + * @var Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. */ - public readonly Optional|ResolvesToInt|int $start; + public readonly Optional|ResolvesToInt|int|string $start; /** - * @var Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @var Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ - public readonly Optional|ResolvesToInt|int $end; + public readonly Optional|ResolvesToInt|int|string $end; /** * @param ResolvesToString|string $string Can be any valid expression as long as it resolves to a string. * If the string expression resolves to a value of null or refers to a field that is missing, $indexOfCP returns null. * If the string expression does not resolve to a string or null nor refers to a missing field, $indexOfCP returns an error. * @param ResolvesToString|string $substring Can be any valid expression as long as it resolves to a string. - * @param Optional|ResolvesToInt|int $start 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. + * @param Optional|ResolvesToInt|int|string $start 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. * If unspecified, the starting index position for the search is the beginning of the string. - * @param Optional|ResolvesToInt|int $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. + * @param Optional|ResolvesToInt|int|string $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. If you specify a index value, you should also specify a index value; otherwise, $indexOfArray uses the value as the index value instead of the value. * If unspecified, the ending index position for the search is the end of the string. */ public function __construct( ResolvesToString|string $string, ResolvesToString|string $substring, - Optional|ResolvesToInt|int $start = Optional::Undefined, - Optional|ResolvesToInt|int $end = Optional::Undefined, + Optional|ResolvesToInt|int|string $start = Optional::Undefined, + Optional|ResolvesToInt|int|string $end = Optional::Undefined, ) { $this->string = $string; $this->substring = $substring; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->end = $end; } } diff --git a/src/Builder/Expression/IsoDayOfWeekOperator.php b/src/Builder/Expression/IsoDayOfWeekOperator.php index 8bbc8dfe9..7ae8e19f1 100644 --- a/src/Builder/Expression/IsoDayOfWeekOperator.php +++ b/src/Builder/Expression/IsoDayOfWeekOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the weekday number in ISO 8601 format, ranging from 1 (for Monday) to 7 (for Sunday). @@ -27,20 +31,24 @@ final class IsoDayOfWeekOperator implements ResolvesToInt, OperatorInterface public const NAME = '$isoDayOfWeek'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/IsoWeekOperator.php b/src/Builder/Expression/IsoWeekOperator.php index 726c53537..7a500f174 100644 --- a/src/Builder/Expression/IsoWeekOperator.php +++ b/src/Builder/Expression/IsoWeekOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the week number in ISO 8601 format, ranging from 1 to 53. Week numbers start at 1 with the week (Monday through Sunday) that contains the year's first Thursday. @@ -27,20 +31,24 @@ final class IsoWeekOperator implements ResolvesToInt, OperatorInterface public const NAME = '$isoWeek'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/IsoWeekYearOperator.php b/src/Builder/Expression/IsoWeekYearOperator.php index a29e2e8a6..b558a38c0 100644 --- a/src/Builder/Expression/IsoWeekYearOperator.php +++ b/src/Builder/Expression/IsoWeekYearOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the year number in ISO 8601 format. The year starts with the Monday of week 1 (ISO 8601) and ends with the Sunday of the last week (ISO 8601). @@ -27,20 +31,24 @@ final class IsoWeekYearOperator implements ResolvesToInt, OperatorInterface public const NAME = '$isoWeekYear'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/LastNOperator.php b/src/Builder/Expression/LastNOperator.php index 0517f92d8..be714cd9b 100644 --- a/src/Builder/Expression/LastNOperator.php +++ b/src/Builder/Expression/LastNOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns a specified number of elements from the end of an array. @@ -29,19 +31,29 @@ final class LastNOperator implements ResolvesToArray, OperatorInterface public const NAME = '$lastN'; public const PROPERTIES = ['n' => 'n', 'input' => 'input']; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. */ + public readonly ResolvesToInt|int|string $n; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; /** - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return n elements. */ - public function __construct(ResolvesToInt|int $n, PackedArray|ResolvesToArray|BSONArray|array $input) - { + public function __construct( + ResolvesToInt|int|string $n, + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ) { + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/LastOperator.php b/src/Builder/Expression/LastOperator.php index e7f2b7d46..68043d7d5 100644 --- a/src/Builder/Expression/LastOperator.php +++ b/src/Builder/Expression/LastOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the result of an expression for the last document in an array. @@ -29,14 +31,18 @@ final class LastOperator implements ResolvesToAny, OperatorInterface public const NAME = '$last'; public const PROPERTIES = ['expression' => 'expression']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/LnOperator.php b/src/Builder/Expression/LnOperator.php index 6fe5993e9..1848fbec6 100644 --- a/src/Builder/Expression/LnOperator.php +++ b/src/Builder/Expression/LnOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Calculates the natural log of a number. @@ -26,14 +30,18 @@ final class LnOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$ln'; public const PROPERTIES = ['number' => 'number']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. For more information on expressions, see Expressions. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $number) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $number) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; } } diff --git a/src/Builder/Expression/Log10Operator.php b/src/Builder/Expression/Log10Operator.php index ef4a5ec3e..24ea9824d 100644 --- a/src/Builder/Expression/Log10Operator.php +++ b/src/Builder/Expression/Log10Operator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Calculates the log base 10 of a number. @@ -25,14 +29,18 @@ final class Log10Operator implements ResolvesToDouble, OperatorInterface public const NAME = '$log10'; public const PROPERTIES = ['number' => 'number']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $number) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $number) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; } } diff --git a/src/Builder/Expression/LogOperator.php b/src/Builder/Expression/LogOperator.php index 99bbfd812..b61fa3bef 100644 --- a/src/Builder/Expression/LogOperator.php +++ b/src/Builder/Expression/LogOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Calculates the log of a number in the specified base. @@ -25,21 +29,29 @@ final class LogOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$log'; public const PROPERTIES = ['number' => 'number', 'base' => 'base']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $base Any valid expression as long as it resolves to a positive number greater than 1. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $base; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $base Any valid expression as long as it resolves to a positive number greater than 1. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $base; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Any valid expression as long as it resolves to a non-negative number. - * @param Decimal128|Int64|ResolvesToNumber|float|int $base Any valid expression as long as it resolves to a positive number greater than 1. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $base Any valid expression as long as it resolves to a positive number greater than 1. */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Decimal128|Int64|ResolvesToNumber|float|int $base, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $base, ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; + if (is_string($base) && ! str_starts_with($base, '$')) { + throw new InvalidArgumentException('Argument $base can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->base = $base; } } diff --git a/src/Builder/Expression/MapOperator.php b/src/Builder/Expression/MapOperator.php index a63685a88..bafa03ef8 100644 --- a/src/Builder/Expression/MapOperator.php +++ b/src/Builder/Expression/MapOperator.php @@ -20,6 +20,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Applies a subexpression to each element of an array and returns the array of resulting values in order. Accepts named parameters. @@ -33,8 +35,8 @@ final class MapOperator implements ResolvesToArray, OperatorInterface public const NAME = '$map'; public const PROPERTIES = ['input' => 'input', 'in' => 'in', 'as' => 'as']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in; @@ -43,15 +45,19 @@ final class MapOperator implements ResolvesToArray, OperatorInterface public readonly Optional|ResolvesToString|string $as; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to an array. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $in An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. * @param Optional|ResolvesToString|string $as A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $input, + PackedArray|ResolvesToArray|BSONArray|array|string $input, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, Optional|ResolvesToString|string $as = Optional::Undefined, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/MaxNOperator.php b/src/Builder/Expression/MaxNOperator.php index f8d387257..b0da2c042 100644 --- a/src/Builder/Expression/MaxNOperator.php +++ b/src/Builder/Expression/MaxNOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the n largest values in an array. Distinct from the $maxN accumulator. @@ -29,23 +31,33 @@ final class MaxNOperator implements ResolvesToArray, OperatorInterface public const NAME = '$maxN'; public const PROPERTIES = ['input' => 'input', 'n' => 'n']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToInt|int $n) - { + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; } } diff --git a/src/Builder/Expression/MedianOperator.php b/src/Builder/Expression/MedianOperator.php index bae54c838..ec9afbdcf 100644 --- a/src/Builder/Expression/MedianOperator.php +++ b/src/Builder/Expression/MedianOperator.php @@ -18,6 +18,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns an approximation of the median, the 50th percentile, as a scalar value. @@ -36,20 +38,24 @@ final class MedianOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$median'; public const PROPERTIES = ['input' => 'input', 'method' => 'method']; - /** @var BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ - public readonly Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int $input; + /** @var BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ + public readonly Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input; /** @var string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ public readonly string $method; /** - * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. * @param string $method The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. */ public function __construct( - Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int $input, + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, string $method, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/MergeObjectsOperator.php b/src/Builder/Expression/MergeObjectsOperator.php index 45e73a59e..e17e1ae1d 100644 --- a/src/Builder/Expression/MergeObjectsOperator.php +++ b/src/Builder/Expression/MergeObjectsOperator.php @@ -29,14 +29,14 @@ final class MergeObjectsOperator implements ResolvesToObject, OperatorInterface public const NAME = '$mergeObjects'; public const PROPERTIES = ['document' => 'document']; - /** @var list $document Any valid expression that resolves to a document. */ + /** @var list $document Any valid expression that resolves to a document. */ public readonly array $document; /** - * @param Document|ResolvesToObject|Serializable|array|stdClass ...$document Any valid expression that resolves to a document. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string ...$document Any valid expression that resolves to a document. * @no-named-arguments */ - public function __construct(Document|Serializable|ResolvesToObject|stdClass|array ...$document) + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string ...$document) { if (\count($document) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $document, got %d.', 1, \count($document))); diff --git a/src/Builder/Expression/MillisecondOperator.php b/src/Builder/Expression/MillisecondOperator.php index 06d8a4bd8..c7bc41dfd 100644 --- a/src/Builder/Expression/MillisecondOperator.php +++ b/src/Builder/Expression/MillisecondOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the milliseconds of a date as a number between 0 and 999. @@ -27,20 +31,24 @@ final class MillisecondOperator implements ResolvesToInt, OperatorInterface public const NAME = '$millisecond'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/MinNOperator.php b/src/Builder/Expression/MinNOperator.php index 9d032fe3e..50b22e1fd 100644 --- a/src/Builder/Expression/MinNOperator.php +++ b/src/Builder/Expression/MinNOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the n smallest values in an array. Distinct from the $minN accumulator. @@ -29,23 +31,33 @@ final class MinNOperator implements ResolvesToArray, OperatorInterface public const NAME = '$minN'; public const PROPERTIES = ['input' => 'input', 'n' => 'n']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; - /** @var ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public readonly ResolvesToInt|int $n; + /** @var ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ + public readonly ResolvesToInt|int|string $n; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input An expression that resolves to the array from which to return the maximal n elements. - * @param ResolvesToInt|int $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input An expression that resolves to the array from which to return the maximal n elements. + * @param ResolvesToInt|int|string $n An expression that resolves to a positive integer. The integer specifies the number of array elements that $maxN returns. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToInt|int $n) - { + public function __construct( + PackedArray|ResolvesToArray|BSONArray|array|string $input, + ResolvesToInt|int|string $n, + ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; } } diff --git a/src/Builder/Expression/MinuteOperator.php b/src/Builder/Expression/MinuteOperator.php index 2be3b337d..23b1ad12d 100644 --- a/src/Builder/Expression/MinuteOperator.php +++ b/src/Builder/Expression/MinuteOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the minute for a date as a number between 0 and 59. @@ -27,20 +31,24 @@ final class MinuteOperator implements ResolvesToInt, OperatorInterface public const NAME = '$minute'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/ModOperator.php b/src/Builder/Expression/ModOperator.php index 8a2134fac..0e7a44df8 100644 --- a/src/Builder/Expression/ModOperator.php +++ b/src/Builder/Expression/ModOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the remainder of the first number divided by the second. Accepts two argument expressions. @@ -25,21 +29,29 @@ final class ModOperator implements ResolvesToInt, OperatorInterface public const NAME = '$mod'; public const PROPERTIES = ['dividend' => 'dividend', 'divisor' => 'divisor']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $dividend; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $dividend; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $divisor */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $divisor; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $divisor; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. - * @param Decimal128|Int64|ResolvesToNumber|float|int $divisor + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $dividend The first argument is the dividend, and the second argument is the divisor; i.e. first argument is divided by the second argument. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $divisor */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $dividend, - Decimal128|Int64|ResolvesToNumber|float|int $divisor, + Decimal128|Int64|ResolvesToNumber|float|int|string $dividend, + Decimal128|Int64|ResolvesToNumber|float|int|string $divisor, ) { + if (is_string($dividend) && ! str_starts_with($dividend, '$')) { + throw new InvalidArgumentException('Argument $dividend can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->dividend = $dividend; + if (is_string($divisor) && ! str_starts_with($divisor, '$')) { + throw new InvalidArgumentException('Argument $divisor can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->divisor = $divisor; } } diff --git a/src/Builder/Expression/MonthOperator.php b/src/Builder/Expression/MonthOperator.php index 36d1c2b17..e6351e1a8 100644 --- a/src/Builder/Expression/MonthOperator.php +++ b/src/Builder/Expression/MonthOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the month for a date as a number between 1 (January) and 12 (December). @@ -27,20 +31,24 @@ final class MonthOperator implements ResolvesToInt, OperatorInterface public const NAME = '$month'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/MultiplyOperator.php b/src/Builder/Expression/MultiplyOperator.php index ba2f5882e..31d781ad4 100644 --- a/src/Builder/Expression/MultiplyOperator.php +++ b/src/Builder/Expression/MultiplyOperator.php @@ -29,17 +29,17 @@ final class MultiplyOperator implements ResolvesToDecimal, OperatorInterface public const PROPERTIES = ['expression' => 'expression']; /** - * @var list $expression The arguments can be any valid expression as long as they resolve to numbers. + * @var list $expression The arguments can be any valid expression as long as they resolve to numbers. * Starting in MongoDB 6.1 you can optimize the $multiply operation. To improve performance, group references at the end of the argument list. */ public readonly array $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression The arguments can be any valid expression as long as they resolve to numbers. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression The arguments can be any valid expression as long as they resolve to numbers. * Starting in MongoDB 6.1 you can optimize the $multiply operation. To improve performance, group references at the end of the argument list. * @no-named-arguments */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int ...$expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/ObjectToArrayOperator.php b/src/Builder/Expression/ObjectToArrayOperator.php index 0685bed27..c8a260970 100644 --- a/src/Builder/Expression/ObjectToArrayOperator.php +++ b/src/Builder/Expression/ObjectToArrayOperator.php @@ -12,8 +12,12 @@ use MongoDB\BSON\Serializable; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Converts a document to an array of documents representing key-value pairs. * @@ -26,14 +30,18 @@ final class ObjectToArrayOperator implements ResolvesToArray, OperatorInterface public const NAME = '$objectToArray'; public const PROPERTIES = ['object' => 'object']; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $object; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $object; /** - * @param Document|ResolvesToObject|Serializable|array|stdClass $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $object Any valid expression as long as it resolves to a document object. $objectToArray applies to the top-level fields of its argument. If the argument is a document that itself contains embedded document fields, the $objectToArray does not recursively apply to the embedded document fields. */ - public function __construct(Document|Serializable|ResolvesToObject|stdClass|array $object) + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $object) { + if (is_string($object) && ! str_starts_with($object, '$')) { + throw new InvalidArgumentException('Argument $object can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->object = $object; } } diff --git a/src/Builder/Expression/PercentileOperator.php b/src/Builder/Expression/PercentileOperator.php index ab956bac5..c30775ca3 100644 --- a/src/Builder/Expression/PercentileOperator.php +++ b/src/Builder/Expression/PercentileOperator.php @@ -18,6 +18,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns an array of scalar values that correspond to specified percentile values. @@ -39,34 +41,42 @@ final class PercentileOperator implements ResolvesToArray, OperatorInterface public const NAME = '$percentile'; public const PROPERTIES = ['input' => 'input', 'p' => 'p', 'method' => 'method']; - /** @var BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ - public readonly Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int $input; + /** @var BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ + public readonly Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * @var BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. * $percentile returns results in the same order as the elements in p. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $p; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $p; /** @var string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ public readonly string $method; /** - * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. - * @param BSONArray|PackedArray|ResolvesToArray|array $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToNumber|array|float|int|string $input $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $p $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. * $percentile returns results in the same order as the elements in p. * @param string $method The method that mongod uses to calculate the percentile value. The method must be 'approximate'. */ public function __construct( - Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int $input, - PackedArray|ResolvesToArray|BSONArray|array $p, + Decimal128|Int64|PackedArray|ResolvesToNumber|BSONArray|array|float|int|string $input, + PackedArray|ResolvesToArray|BSONArray|array|string $p, string $method, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } $this->input = $input; + if (is_string($p) && ! str_starts_with($p, '$')) { + throw new InvalidArgumentException('Argument $p can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($p) && ! array_is_list($p)) { throw new InvalidArgumentException('Expected $p argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/PowOperator.php b/src/Builder/Expression/PowOperator.php index 8cf024023..bf132280f 100644 --- a/src/Builder/Expression/PowOperator.php +++ b/src/Builder/Expression/PowOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Raises a number to the specified exponent. @@ -25,21 +29,29 @@ final class PowOperator implements ResolvesToNumber, OperatorInterface public const NAME = '$pow'; public const PROPERTIES = ['number' => 'number', 'exponent' => 'exponent']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $number */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $exponent */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $exponent; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $exponent; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number - * @param Decimal128|Int64|ResolvesToNumber|float|int $exponent + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $exponent */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Decimal128|Int64|ResolvesToNumber|float|int $exponent, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Decimal128|Int64|ResolvesToNumber|float|int|string $exponent, ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; + if (is_string($exponent) && ! str_starts_with($exponent, '$')) { + throw new InvalidArgumentException('Argument $exponent can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->exponent = $exponent; } } diff --git a/src/Builder/Expression/RadiansToDegreesOperator.php b/src/Builder/Expression/RadiansToDegreesOperator.php index b3764f0ed..c8e4d5292 100644 --- a/src/Builder/Expression/RadiansToDegreesOperator.php +++ b/src/Builder/Expression/RadiansToDegreesOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Converts a value from radians to degrees. @@ -25,14 +29,18 @@ final class RadiansToDegreesOperator implements ResolvesToDouble, ResolvesToDeci public const NAME = '$radiansToDegrees'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $expression */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/RangeOperator.php b/src/Builder/Expression/RangeOperator.php index cbb0e32e7..1b96eb826 100644 --- a/src/Builder/Expression/RangeOperator.php +++ b/src/Builder/Expression/RangeOperator.php @@ -11,6 +11,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Outputs an array containing a sequence of integers according to user-defined inputs. @@ -24,27 +28,39 @@ final class RangeOperator implements ResolvesToArray, OperatorInterface public const NAME = '$range'; public const PROPERTIES = ['start' => 'start', 'end' => 'end', 'step' => 'step']; - /** @var ResolvesToInt|int $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. */ - public readonly ResolvesToInt|int $start; + /** @var ResolvesToInt|int|string $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. */ + public readonly ResolvesToInt|int|string $start; - /** @var ResolvesToInt|int $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. */ - public readonly ResolvesToInt|int $end; + /** @var ResolvesToInt|int|string $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. */ + public readonly ResolvesToInt|int|string $end; - /** @var Optional|ResolvesToInt|int $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. */ - public readonly Optional|ResolvesToInt|int $step; + /** @var Optional|ResolvesToInt|int|string $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. */ + public readonly Optional|ResolvesToInt|int|string $step; /** - * @param ResolvesToInt|int $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. - * @param ResolvesToInt|int $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. - * @param Optional|ResolvesToInt|int $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. + * @param ResolvesToInt|int|string $start An integer that specifies the start of the sequence. Can be any valid expression that resolves to an integer. + * @param ResolvesToInt|int|string $end An integer that specifies the exclusive upper limit of the sequence. Can be any valid expression that resolves to an integer. + * @param Optional|ResolvesToInt|int|string $step An integer that specifies the increment value. Can be any valid expression that resolves to a non-zero integer. Defaults to 1. */ public function __construct( - ResolvesToInt|int $start, - ResolvesToInt|int $end, - Optional|ResolvesToInt|int $step = Optional::Undefined, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $end, + Optional|ResolvesToInt|int|string $step = Optional::Undefined, ) { + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($end) && ! str_starts_with($end, '$')) { + throw new InvalidArgumentException('Argument $end can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->end = $end; + if (is_string($step) && ! str_starts_with($step, '$')) { + throw new InvalidArgumentException('Argument $step can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->step = $step; } } diff --git a/src/Builder/Expression/ReduceOperator.php b/src/Builder/Expression/ReduceOperator.php index c35b2b530..27d0d6398 100644 --- a/src/Builder/Expression/ReduceOperator.php +++ b/src/Builder/Expression/ReduceOperator.php @@ -19,6 +19,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Applies an expression to each element in an array and combines them into a single value. @@ -33,11 +35,11 @@ final class ReduceOperator implements ResolvesToAny, OperatorInterface public const PROPERTIES = ['input' => 'input', 'initialValue' => 'initialValue', 'in' => 'in']; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $input Can be any valid expression that resolves to an array. + * @var BSONArray|PackedArray|ResolvesToArray|array|string $input Can be any valid expression that resolves to an array. * If the argument resolves to a value of null or refers to a missing field, $reduce returns null. * If the argument does not resolve to an array or null nor refers to a missing field, $reduce returns an error. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; /** @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $initialValue The initial cumulative value set before in is applied to the first element of the input array. */ public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $initialValue; @@ -51,7 +53,7 @@ final class ReduceOperator implements ResolvesToAny, OperatorInterface public readonly Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input Can be any valid expression that resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input Can be any valid expression that resolves to an array. * If the argument resolves to a value of null or refers to a missing field, $reduce returns null. * If the argument does not resolve to an array or null nor refers to a missing field, $reduce returns an error. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $initialValue The initial cumulative value set before in is applied to the first element of the input array. @@ -61,10 +63,14 @@ final class ReduceOperator implements ResolvesToAny, OperatorInterface * - this is the variable that refers to the element being processed. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $input, + PackedArray|ResolvesToArray|BSONArray|array|string $input, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $initialValue, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $in, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/ReverseArrayOperator.php b/src/Builder/Expression/ReverseArrayOperator.php index be6a910d4..4a02b1062 100644 --- a/src/Builder/Expression/ReverseArrayOperator.php +++ b/src/Builder/Expression/ReverseArrayOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns an array with the elements in reverse order. @@ -29,14 +31,18 @@ final class ReverseArrayOperator implements ResolvesToArray, OperatorInterface public const NAME = '$reverseArray'; public const PROPERTIES = ['expression' => 'expression']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression The argument can be any valid expression as long as it resolves to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument can be any valid expression as long as it resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression The argument can be any valid expression as long as it resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument can be any valid expression as long as it resolves to an array. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/RoundOperator.php b/src/Builder/Expression/RoundOperator.php index 21638126d..0deb81104 100644 --- a/src/Builder/Expression/RoundOperator.php +++ b/src/Builder/Expression/RoundOperator.php @@ -13,6 +13,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Rounds a number to a whole integer or to a specified decimal place. @@ -27,24 +31,32 @@ final class RoundOperator implements ResolvesToInt, ResolvesToDouble, ResolvesTo public const PROPERTIES = ['number' => 'number', 'place' => 'place']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $round returns an error if the expression resolves to a non-numeric data type. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; - /** @var Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ - public readonly Optional|ResolvesToInt|int $place; + /** @var Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ + public readonly Optional|ResolvesToInt|int|string $place; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $round returns an error if the expression resolves to a non-numeric data type. - * @param Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Optional|ResolvesToInt|int $place = Optional::Undefined, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; + if (is_string($place) && ! str_starts_with($place, '$')) { + throw new InvalidArgumentException('Argument $place can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->place = $place; } } diff --git a/src/Builder/Expression/SecondOperator.php b/src/Builder/Expression/SecondOperator.php index 720d57a92..dc65f410e 100644 --- a/src/Builder/Expression/SecondOperator.php +++ b/src/Builder/Expression/SecondOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the seconds for a date as a number between 0 and 60 (leap seconds). @@ -27,20 +31,24 @@ final class SecondOperator implements ResolvesToInt, OperatorInterface public const NAME = '$second'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/SetDifferenceOperator.php b/src/Builder/Expression/SetDifferenceOperator.php index 2b4fde506..297897425 100644 --- a/src/Builder/Expression/SetDifferenceOperator.php +++ b/src/Builder/Expression/SetDifferenceOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns a set with elements that appear in the first set but not in the second set; i.e. performs a relative complement of the second set relative to the first. Accepts exactly two argument expressions. @@ -29,25 +31,33 @@ final class SetDifferenceOperator implements ResolvesToArray, OperatorInterface public const NAME = '$setDifference'; public const PROPERTIES = ['expression1' => 'expression1', 'expression2' => 'expression2']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression1 The arguments can be any valid expression as long as they each resolve to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression1; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression1 The arguments can be any valid expression as long as they each resolve to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression1; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression2 The arguments can be any valid expression as long as they each resolve to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression2; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression2 The arguments can be any valid expression as long as they each resolve to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression2; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression1 The arguments can be any valid expression as long as they each resolve to an array. - * @param BSONArray|PackedArray|ResolvesToArray|array $expression2 The arguments can be any valid expression as long as they each resolve to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 The arguments can be any valid expression as long as they each resolve to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 The arguments can be any valid expression as long as they each resolve to an array. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $expression1, - PackedArray|ResolvesToArray|BSONArray|array $expression2, + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression1) && ! array_is_list($expression1)) { throw new InvalidArgumentException('Expected $expression1 argument to be a list, got an associative array.'); } $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression2) && ! array_is_list($expression2)) { throw new InvalidArgumentException('Expected $expression2 argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/SetEqualsOperator.php b/src/Builder/Expression/SetEqualsOperator.php index b7eca0089..c743c8cca 100644 --- a/src/Builder/Expression/SetEqualsOperator.php +++ b/src/Builder/Expression/SetEqualsOperator.php @@ -28,14 +28,14 @@ final class SetEqualsOperator implements ResolvesToBool, OperatorInterface public const NAME = '$setEquals'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array ...$expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression * @no-named-arguments */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array ...$expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/SetFieldOperator.php b/src/Builder/Expression/SetFieldOperator.php index 08559253e..96e86ee60 100644 --- a/src/Builder/Expression/SetFieldOperator.php +++ b/src/Builder/Expression/SetFieldOperator.php @@ -14,8 +14,12 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\ExpressionInterface; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Adds, updates, or removes a specified field in a document. You can use $setField to add, update, or remove fields with names that contain periods (.) or start with dollar signs ($). * New in MongoDB 5.0. @@ -32,8 +36,8 @@ final class SetFieldOperator implements ResolvesToObject, OperatorInterface /** @var ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. */ public readonly ResolvesToString|string $field; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $input; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $input; /** * @var ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value The value that you want to assign to field. value can be any valid expression. @@ -43,16 +47,20 @@ final class SetFieldOperator implements ResolvesToObject, OperatorInterface /** * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. - * @param Document|ResolvesToObject|Serializable|array|stdClass $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. * @param ExpressionInterface|Type|array|bool|float|int|null|stdClass|string $value The value that you want to assign to field. value can be any valid expression. * Set to $$REMOVE to remove field from the input document. */ public function __construct( ResolvesToString|string $field, - Document|Serializable|ResolvesToObject|stdClass|array $input, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, Type|ExpressionInterface|stdClass|array|bool|float|int|null|string $value, ) { $this->field = $field; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; $this->value = $value; } diff --git a/src/Builder/Expression/SetIntersectionOperator.php b/src/Builder/Expression/SetIntersectionOperator.php index 3ec2c03dd..a27dd4e9b 100644 --- a/src/Builder/Expression/SetIntersectionOperator.php +++ b/src/Builder/Expression/SetIntersectionOperator.php @@ -28,14 +28,14 @@ final class SetIntersectionOperator implements ResolvesToArray, OperatorInterfac public const NAME = '$setIntersection'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array ...$expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression * @no-named-arguments */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array ...$expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/SetIsSubsetOperator.php b/src/Builder/Expression/SetIsSubsetOperator.php index 76263d138..8d9a63e45 100644 --- a/src/Builder/Expression/SetIsSubsetOperator.php +++ b/src/Builder/Expression/SetIsSubsetOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns true if all elements of the first set appear in the second set, including when the first set equals the second set; i.e. not a strict subset. Accepts exactly two argument expressions. @@ -29,25 +31,33 @@ final class SetIsSubsetOperator implements ResolvesToBool, OperatorInterface public const NAME = '$setIsSubset'; public const PROPERTIES = ['expression1' => 'expression1', 'expression2' => 'expression2']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression1 */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression1; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression1 */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression1; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression2 */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression2; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression2 */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression2; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression1 - * @param BSONArray|PackedArray|ResolvesToArray|array $expression2 + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression1 + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression2 */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $expression1, - PackedArray|ResolvesToArray|BSONArray|array $expression2, + PackedArray|ResolvesToArray|BSONArray|array|string $expression1, + PackedArray|ResolvesToArray|BSONArray|array|string $expression2, ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression1) && ! array_is_list($expression1)) { throw new InvalidArgumentException('Expected $expression1 argument to be a list, got an associative array.'); } $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression2) && ! array_is_list($expression2)) { throw new InvalidArgumentException('Expected $expression2 argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/SetUnionOperator.php b/src/Builder/Expression/SetUnionOperator.php index 62f2cb871..5a7af7651 100644 --- a/src/Builder/Expression/SetUnionOperator.php +++ b/src/Builder/Expression/SetUnionOperator.php @@ -28,14 +28,14 @@ final class SetUnionOperator implements ResolvesToArray, OperatorInterface public const NAME = '$setUnion'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array ...$expression + * @param BSONArray|PackedArray|ResolvesToArray|array|string ...$expression * @no-named-arguments */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array ...$expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/SinOperator.php b/src/Builder/Expression/SinOperator.php index 9ba0d998e..cc8f82357 100644 --- a/src/Builder/Expression/SinOperator.php +++ b/src/Builder/Expression/SinOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the sine of a value that is measured in radians. @@ -26,17 +30,21 @@ final class SinOperator implements ResolvesToDouble, ResolvesToDecimal, Operator public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $sin returns values as a double. $sin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sin takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $sin returns values as a double. $sin can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/SinhOperator.php b/src/Builder/Expression/SinhOperator.php index e04ff231d..763d2f94f 100644 --- a/src/Builder/Expression/SinhOperator.php +++ b/src/Builder/Expression/SinhOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the hyperbolic sine of a value that is measured in radians. @@ -26,17 +30,21 @@ final class SinhOperator implements ResolvesToDouble, ResolvesToDecimal, Operato public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $sinh returns values as a double. $sinh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $sinh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $sinh returns values as a double. $sinh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/SizeOperator.php b/src/Builder/Expression/SizeOperator.php index 7ff3b83f7..53b6cdd1a 100644 --- a/src/Builder/Expression/SizeOperator.php +++ b/src/Builder/Expression/SizeOperator.php @@ -16,6 +16,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns the number of elements in the array. Accepts a single expression as argument. @@ -29,14 +31,18 @@ final class SizeOperator implements ResolvesToInt, OperatorInterface public const NAME = '$size'; public const PROPERTIES = ['expression' => 'expression']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression The argument for $size can be any expression as long as it resolves to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument for $size can be any expression as long as it resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression The argument for $size can be any expression as long as it resolves to an array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression The argument for $size can be any expression as long as it resolves to an array. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $expression) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/SliceOperator.php b/src/Builder/Expression/SliceOperator.php index 220810428..71cc07415 100644 --- a/src/Builder/Expression/SliceOperator.php +++ b/src/Builder/Expression/SliceOperator.php @@ -17,6 +17,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns a subset of an array. @@ -30,43 +32,55 @@ final class SliceOperator implements ResolvesToArray, OperatorInterface public const NAME = '$slice'; public const PROPERTIES = ['expression' => 'expression', 'n' => 'n', 'position' => 'position']; - /** @var BSONArray|PackedArray|ResolvesToArray|array $expression Any valid expression as long as it resolves to an array. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $expression; + /** @var BSONArray|PackedArray|ResolvesToArray|array|string $expression Any valid expression as long as it resolves to an array. */ + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $expression; /** - * @var ResolvesToInt|int $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. + * @var ResolvesToInt|int|string $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. * If positive, $slice returns up to the first n elements in the array. If the position is specified, $slice returns the first n elements starting from the position. * If negative, $slice returns up to the last n elements in the array. n cannot resolve to a negative number if is specified. */ - public readonly ResolvesToInt|int $n; + public readonly ResolvesToInt|int|string $n; /** - * @var Optional|ResolvesToInt|int $position Any valid expression as long as it resolves to an integer. + * @var Optional|ResolvesToInt|int|string $position Any valid expression as long as it resolves to an integer. * If positive, $slice determines the starting position from the start of the array. If position is greater than the number of elements, the $slice returns an empty array. * If negative, $slice determines the starting position from the end of the array. If the absolute value of the is greater than the number of elements, the starting position is the start of the array. */ - public readonly Optional|ResolvesToInt|int $position; + public readonly Optional|ResolvesToInt|int|string $position; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $expression Any valid expression as long as it resolves to an array. - * @param ResolvesToInt|int $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $expression Any valid expression as long as it resolves to an array. + * @param ResolvesToInt|int|string $n Any valid expression as long as it resolves to an integer. If position is specified, n must resolve to a positive integer. * If positive, $slice returns up to the first n elements in the array. If the position is specified, $slice returns the first n elements starting from the position. * If negative, $slice returns up to the last n elements in the array. n cannot resolve to a negative number if is specified. - * @param Optional|ResolvesToInt|int $position Any valid expression as long as it resolves to an integer. + * @param Optional|ResolvesToInt|int|string $position Any valid expression as long as it resolves to an integer. * If positive, $slice determines the starting position from the start of the array. If position is greater than the number of elements, the $slice returns an empty array. * If negative, $slice determines the starting position from the end of the array. If the absolute value of the is greater than the number of elements, the starting position is the start of the array. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $expression, - ResolvesToInt|int $n, - Optional|ResolvesToInt|int $position = Optional::Undefined, + PackedArray|ResolvesToArray|BSONArray|array|string $expression, + ResolvesToInt|int|string $n, + Optional|ResolvesToInt|int|string $position = Optional::Undefined, ) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($expression) && ! array_is_list($expression)) { throw new InvalidArgumentException('Expected $expression argument to be a list, got an associative array.'); } $this->expression = $expression; + if (is_string($n) && ! str_starts_with($n, '$')) { + throw new InvalidArgumentException('Argument $n can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->n = $n; + if (is_string($position) && ! str_starts_with($position, '$')) { + throw new InvalidArgumentException('Argument $position can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->position = $position; } } diff --git a/src/Builder/Expression/SortArrayOperator.php b/src/Builder/Expression/SortArrayOperator.php index b58e2b65e..6b1d26e0f 100644 --- a/src/Builder/Expression/SortArrayOperator.php +++ b/src/Builder/Expression/SortArrayOperator.php @@ -20,6 +20,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Sorts the elements of an array. @@ -34,25 +36,29 @@ final class SortArrayOperator implements ResolvesToArray, OperatorInterface public const PROPERTIES = ['input' => 'input', 'sortBy' => 'sortBy']; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $input The array to be sorted. + * @var BSONArray|PackedArray|ResolvesToArray|array|string $input The array to be sorted. * The result is null if the expression: is missing, evaluates to null, or evaluates to undefined * If the expression evaluates to any other non-array value, the document returns an error. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $input; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $input; /** @var Document|Serializable|Sort|array|int|stdClass $sortBy The document specifies a sort ordering. */ public readonly Document|Serializable|Sort|stdClass|array|int $sortBy; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $input The array to be sorted. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $input The array to be sorted. * The result is null if the expression: is missing, evaluates to null, or evaluates to undefined * If the expression evaluates to any other non-array value, the document returns an error. * @param Document|Serializable|Sort|array|int|stdClass $sortBy The document specifies a sort ordering. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $input, + PackedArray|ResolvesToArray|BSONArray|array|string $input, Document|Serializable|Sort|stdClass|array|int $sortBy, ) { + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($input) && ! array_is_list($input)) { throw new InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); } diff --git a/src/Builder/Expression/SqrtOperator.php b/src/Builder/Expression/SqrtOperator.php index 90a907ef5..9453fb77b 100644 --- a/src/Builder/Expression/SqrtOperator.php +++ b/src/Builder/Expression/SqrtOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Calculates the square root. @@ -25,14 +29,18 @@ final class SqrtOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$sqrt'; public const PROPERTIES = ['number' => 'number']; - /** @var Decimal128|Int64|ResolvesToNumber|float|int $number The argument can be any valid expression as long as it resolves to a non-negative number. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + /** @var Decimal128|Int64|ResolvesToNumber|float|int|string $number The argument can be any valid expression as long as it resolves to a non-negative number. */ + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number The argument can be any valid expression as long as it resolves to a non-negative number. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number The argument can be any valid expression as long as it resolves to a non-negative number. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $number) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $number) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; } } diff --git a/src/Builder/Expression/StdDevPopOperator.php b/src/Builder/Expression/StdDevPopOperator.php index e966f8e84..dae7344a1 100644 --- a/src/Builder/Expression/StdDevPopOperator.php +++ b/src/Builder/Expression/StdDevPopOperator.php @@ -30,14 +30,14 @@ final class StdDevPopOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$stdDevPop'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression * @no-named-arguments */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int ...$expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/StdDevSampOperator.php b/src/Builder/Expression/StdDevSampOperator.php index 1c897728b..55af36f53 100644 --- a/src/Builder/Expression/StdDevSampOperator.php +++ b/src/Builder/Expression/StdDevSampOperator.php @@ -29,14 +29,14 @@ final class StdDevSampOperator implements ResolvesToDouble, OperatorInterface public const NAME = '$stdDevSamp'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int ...$expression + * @param Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression * @no-named-arguments */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int ...$expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string ...$expression) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/SubstrBytesOperator.php b/src/Builder/Expression/SubstrBytesOperator.php index 72d5ee8c5..ff11d234b 100644 --- a/src/Builder/Expression/SubstrBytesOperator.php +++ b/src/Builder/Expression/SubstrBytesOperator.php @@ -10,6 +10,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the substring of a string. Starts with the character at the specified UTF-8 byte index (zero-based) in the string and continues for the specified number of bytes. @@ -26,21 +30,32 @@ final class SubstrBytesOperator implements ResolvesToString, OperatorInterface /** @var ResolvesToString|string $string */ public readonly ResolvesToString|string $string; - /** @var ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". */ - public readonly ResolvesToInt|int $start; + /** @var ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". */ + public readonly ResolvesToInt|int|string $start; - /** @var ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ - public readonly ResolvesToInt|int $length; + /** @var ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ + public readonly ResolvesToInt|int|string $length; /** * @param ResolvesToString|string $string - * @param ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". - * @param ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ - public function __construct(ResolvesToString|string $string, ResolvesToInt|int $start, ResolvesToInt|int $length) - { + public function __construct( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ) { $this->string = $string; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($length) && ! str_starts_with($length, '$')) { + throw new InvalidArgumentException('Argument $length can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->length = $length; } } diff --git a/src/Builder/Expression/SubstrCPOperator.php b/src/Builder/Expression/SubstrCPOperator.php index ee01339d2..e2c7e89e0 100644 --- a/src/Builder/Expression/SubstrCPOperator.php +++ b/src/Builder/Expression/SubstrCPOperator.php @@ -10,6 +10,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the substring of a string. Starts with the character at the specified UTF-8 code point (CP) index (zero-based) in the string and continues for the number of code points specified. @@ -26,21 +30,32 @@ final class SubstrCPOperator implements ResolvesToString, OperatorInterface /** @var ResolvesToString|string $string */ public readonly ResolvesToString|string $string; - /** @var ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". */ - public readonly ResolvesToInt|int $start; + /** @var ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". */ + public readonly ResolvesToInt|int|string $start; - /** @var ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ - public readonly ResolvesToInt|int $length; + /** @var ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ + public readonly ResolvesToInt|int|string $length; /** * @param ResolvesToString|string $string - * @param ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". - * @param ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ - public function __construct(ResolvesToString|string $string, ResolvesToInt|int $start, ResolvesToInt|int $length) - { + public function __construct( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ) { $this->string = $string; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($length) && ! str_starts_with($length, '$')) { + throw new InvalidArgumentException('Argument $length can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->length = $length; } } diff --git a/src/Builder/Expression/SubstrOperator.php b/src/Builder/Expression/SubstrOperator.php index 10ece1704..3547f5331 100644 --- a/src/Builder/Expression/SubstrOperator.php +++ b/src/Builder/Expression/SubstrOperator.php @@ -10,6 +10,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Deprecated. Use $substrBytes or $substrCP. @@ -26,21 +30,32 @@ final class SubstrOperator implements ResolvesToString, OperatorInterface /** @var ResolvesToString|string $string */ public readonly ResolvesToString|string $string; - /** @var ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". */ - public readonly ResolvesToInt|int $start; + /** @var ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". */ + public readonly ResolvesToInt|int|string $start; - /** @var ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ - public readonly ResolvesToInt|int $length; + /** @var ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ + public readonly ResolvesToInt|int|string $length; /** * @param ResolvesToString|string $string - * @param ResolvesToInt|int $start If start is a negative number, $substr returns an empty string "". - * @param ResolvesToInt|int $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. + * @param ResolvesToInt|int|string $start If start is a negative number, $substr returns an empty string "". + * @param ResolvesToInt|int|string $length If length is a negative number, $substr returns a substring that starts at the specified index and includes the rest of the string. */ - public function __construct(ResolvesToString|string $string, ResolvesToInt|int $start, ResolvesToInt|int $length) - { + public function __construct( + ResolvesToString|string $string, + ResolvesToInt|int|string $start, + ResolvesToInt|int|string $length, + ) { $this->string = $string; + if (is_string($start) && ! str_starts_with($start, '$')) { + throw new InvalidArgumentException('Argument $start can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->start = $start; + if (is_string($length) && ! str_starts_with($length, '$')) { + throw new InvalidArgumentException('Argument $length can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->length = $length; } } diff --git a/src/Builder/Expression/SubtractOperator.php b/src/Builder/Expression/SubtractOperator.php index 8a7187b78..86e396ef0 100644 --- a/src/Builder/Expression/SubtractOperator.php +++ b/src/Builder/Expression/SubtractOperator.php @@ -13,6 +13,10 @@ use MongoDB\BSON\UTCDateTime; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the result of subtracting the second value from the first. If the two values are numbers, return the difference. If the two values are dates, return the difference in milliseconds. If the two values are a date and a number in milliseconds, return the resulting date. Accepts two argument expressions. If the two values are a date and a number, specify the date argument first as it is not meaningful to subtract a date from a number. @@ -26,21 +30,29 @@ final class SubtractOperator implements ResolvesToInt, ResolvesToLong, ResolvesT public const NAME = '$subtract'; public const PROPERTIES = ['expression1' => 'expression1', 'expression2' => 'expression2']; - /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $expression1 */ - public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $expression1; + /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression1 */ + public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression1; - /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $expression2 */ - public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $expression2; + /** @var Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression2 */ + public readonly Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression2; /** - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $expression1 - * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int $expression2 + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression1 + * @param Decimal128|Int64|ResolvesToDate|ResolvesToNumber|UTCDateTime|float|int|string $expression2 */ public function __construct( - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $expression1, - Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int $expression2, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression1, + Decimal128|Int64|UTCDateTime|ResolvesToDate|ResolvesToNumber|float|int|string $expression2, ) { + if (is_string($expression1) && ! str_starts_with($expression1, '$')) { + throw new InvalidArgumentException('Argument $expression1 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression1 = $expression1; + if (is_string($expression2) && ! str_starts_with($expression2, '$')) { + throw new InvalidArgumentException('Argument $expression2 can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression2 = $expression2; } } diff --git a/src/Builder/Expression/SumOperator.php b/src/Builder/Expression/SumOperator.php index 99d90de28..04bfaf06a 100644 --- a/src/Builder/Expression/SumOperator.php +++ b/src/Builder/Expression/SumOperator.php @@ -31,15 +31,15 @@ final class SumOperator implements ResolvesToNumber, OperatorInterface public const NAME = '$sum'; public const PROPERTIES = ['expression' => 'expression']; - /** @var list $expression */ + /** @var list $expression */ public readonly array $expression; /** - * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|array|float|int ...$expression + * @param BSONArray|Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|array|float|int|string ...$expression * @no-named-arguments */ public function __construct( - Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|BSONArray|array|float|int ...$expression, + Decimal128|Int64|PackedArray|ResolvesToArray|ResolvesToNumber|BSONArray|array|float|int|string ...$expression, ) { if (\count($expression) < 1) { throw new InvalidArgumentException(\sprintf('Expected at least %d values for $expression, got %d.', 1, \count($expression))); diff --git a/src/Builder/Expression/TanOperator.php b/src/Builder/Expression/TanOperator.php index bab27a3a5..c783b0392 100644 --- a/src/Builder/Expression/TanOperator.php +++ b/src/Builder/Expression/TanOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the tangent of a value that is measured in radians. @@ -26,17 +30,21 @@ final class TanOperator implements ResolvesToDouble, ResolvesToDecimal, Operator public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $tan returns values as a double. $tan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tan takes any valid expression that resolves to a number. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the result to radians. * By default $tan returns values as a double. $tan can also return values as a 128-bit decimal as long as the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/TanhOperator.php b/src/Builder/Expression/TanhOperator.php index 5e31a67d1..e6f8bb619 100644 --- a/src/Builder/Expression/TanhOperator.php +++ b/src/Builder/Expression/TanhOperator.php @@ -12,6 +12,10 @@ use MongoDB\BSON\Int64; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the hyperbolic tangent of a value that is measured in radians. @@ -26,17 +30,21 @@ final class TanhOperator implements ResolvesToDouble, ResolvesToDecimal, Operato public const PROPERTIES = ['expression' => 'expression']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $tanh returns values as a double. $tanh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $expression; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $expression; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $expression $tanh takes any valid expression that resolves to a number, measured in radians. If the expression returns a value in degrees, use the $degreesToRadians operator to convert the value to radians. * By default $tanh returns values as a double. $tanh can also return values as a 128-bit decimal if the expression resolves to a 128-bit decimal value. */ - public function __construct(Decimal128|Int64|ResolvesToNumber|float|int $expression) + public function __construct(Decimal128|Int64|ResolvesToNumber|float|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/TruncOperator.php b/src/Builder/Expression/TruncOperator.php index c6db92b34..b8e98c562 100644 --- a/src/Builder/Expression/TruncOperator.php +++ b/src/Builder/Expression/TruncOperator.php @@ -13,6 +13,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Truncates a number to a whole integer or to a specified decimal place. @@ -27,24 +31,32 @@ final class TruncOperator implements ResolvesToString, OperatorInterface public const PROPERTIES = ['number' => 'number', 'place' => 'place']; /** - * @var Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @var Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $trunc returns an error if the expression resolves to a non-numeric data type. */ - public readonly Decimal128|Int64|ResolvesToNumber|float|int $number; + public readonly Decimal128|Int64|ResolvesToNumber|float|int|string $number; - /** @var Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. */ - public readonly Optional|ResolvesToInt|int $place; + /** @var Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. */ + public readonly Optional|ResolvesToInt|int|string $place; /** - * @param Decimal128|Int64|ResolvesToNumber|float|int $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. + * @param Decimal128|Int64|ResolvesToNumber|float|int|string $number Can be any valid expression that resolves to a number. Specifically, the expression must resolve to an integer, double, decimal, or long. * $trunc returns an error if the expression resolves to a non-numeric data type. - * @param Optional|ResolvesToInt|int $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. + * @param Optional|ResolvesToInt|int|string $place Can be any valid expression that resolves to an integer between -20 and 100, exclusive. e.g. -20 < place < 100. Defaults to 0. */ public function __construct( - Decimal128|Int64|ResolvesToNumber|float|int $number, - Optional|ResolvesToInt|int $place = Optional::Undefined, + Decimal128|Int64|ResolvesToNumber|float|int|string $number, + Optional|ResolvesToInt|int|string $place = Optional::Undefined, ) { + if (is_string($number) && ! str_starts_with($number, '$')) { + throw new InvalidArgumentException('Argument $number can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->number = $number; + if (is_string($place) && ! str_starts_with($place, '$')) { + throw new InvalidArgumentException('Argument $place can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->place = $place; } } diff --git a/src/Builder/Expression/TsIncrementOperator.php b/src/Builder/Expression/TsIncrementOperator.php index b39d897bc..3e1e404c1 100644 --- a/src/Builder/Expression/TsIncrementOperator.php +++ b/src/Builder/Expression/TsIncrementOperator.php @@ -11,6 +11,10 @@ use MongoDB\BSON\Timestamp; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the incrementing ordinal from a timestamp as a long. @@ -25,14 +29,18 @@ final class TsIncrementOperator implements ResolvesToLong, OperatorInterface public const NAME = '$tsIncrement'; public const PROPERTIES = ['expression' => 'expression']; - /** @var ResolvesToTimestamp|Timestamp|int $expression */ - public readonly Timestamp|ResolvesToTimestamp|int $expression; + /** @var ResolvesToTimestamp|Timestamp|int|string $expression */ + public readonly Timestamp|ResolvesToTimestamp|int|string $expression; /** - * @param ResolvesToTimestamp|Timestamp|int $expression + * @param ResolvesToTimestamp|Timestamp|int|string $expression */ - public function __construct(Timestamp|ResolvesToTimestamp|int $expression) + public function __construct(Timestamp|ResolvesToTimestamp|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/TsSecondOperator.php b/src/Builder/Expression/TsSecondOperator.php index 71af2b803..bea14d9e1 100644 --- a/src/Builder/Expression/TsSecondOperator.php +++ b/src/Builder/Expression/TsSecondOperator.php @@ -11,6 +11,10 @@ use MongoDB\BSON\Timestamp; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the seconds from a timestamp as a long. @@ -25,14 +29,18 @@ final class TsSecondOperator implements ResolvesToLong, OperatorInterface public const NAME = '$tsSecond'; public const PROPERTIES = ['expression' => 'expression']; - /** @var ResolvesToTimestamp|Timestamp|int $expression */ - public readonly Timestamp|ResolvesToTimestamp|int $expression; + /** @var ResolvesToTimestamp|Timestamp|int|string $expression */ + public readonly Timestamp|ResolvesToTimestamp|int|string $expression; /** - * @param ResolvesToTimestamp|Timestamp|int $expression + * @param ResolvesToTimestamp|Timestamp|int|string $expression */ - public function __construct(Timestamp|ResolvesToTimestamp|int $expression) + public function __construct(Timestamp|ResolvesToTimestamp|int|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/src/Builder/Expression/UnsetFieldOperator.php b/src/Builder/Expression/UnsetFieldOperator.php index 6b040e2c4..1d0fcf9d2 100644 --- a/src/Builder/Expression/UnsetFieldOperator.php +++ b/src/Builder/Expression/UnsetFieldOperator.php @@ -12,8 +12,12 @@ use MongoDB\BSON\Serializable; use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * You can use $unsetField to remove fields with names that contain periods (.) or that start with dollar signs ($). * $unsetField is an alias for $setField using $$REMOVE to remove fields. @@ -30,18 +34,22 @@ final class UnsetFieldOperator implements ResolvesToObject, OperatorInterface /** @var ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. */ public readonly ResolvesToString|string $field; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $input; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $input; /** * @param ResolvesToString|string $field Field in the input object that you want to add, update, or remove. field can be any valid expression that resolves to a string constant. - * @param Document|ResolvesToObject|Serializable|array|stdClass $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $input Document that contains the field that you want to add or update. input must resolve to an object, missing, null, or undefined. */ public function __construct( ResolvesToString|string $field, - Document|Serializable|ResolvesToObject|stdClass|array $input, + Document|Serializable|ResolvesToObject|stdClass|array|string $input, ) { $this->field = $field; + if (is_string($input) && ! str_starts_with($input, '$')) { + throw new InvalidArgumentException('Argument $input can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->input = $input; } } diff --git a/src/Builder/Expression/WeekOperator.php b/src/Builder/Expression/WeekOperator.php index 2d58d0509..3cca670fa 100644 --- a/src/Builder/Expression/WeekOperator.php +++ b/src/Builder/Expression/WeekOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the week number for a date as a number between 0 (the partial week that precedes the first Sunday of the year) and 53 (leap year). @@ -27,20 +31,24 @@ final class WeekOperator implements ResolvesToInt, OperatorInterface public const NAME = '$week'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/YearOperator.php b/src/Builder/Expression/YearOperator.php index 57fcb35ae..2c1c649bf 100644 --- a/src/Builder/Expression/YearOperator.php +++ b/src/Builder/Expression/YearOperator.php @@ -14,6 +14,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\Optional; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Returns the year for a date as a number (e.g. 2014). @@ -27,20 +31,24 @@ final class YearOperator implements ResolvesToInt, OperatorInterface public const NAME = '$year'; public const PROPERTIES = ['date' => 'date', 'timezone' => 'timezone']; - /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ - public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date; + /** @var ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. */ + public readonly ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date; /** @var Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public readonly Optional|ResolvesToString|string $timezone; /** - * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. + * @param ObjectId|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|Timestamp|UTCDateTime|int|string $date The date to which the operator is applied. date must be a valid expression that resolves to a Date, a Timestamp, or an ObjectID. * @param Optional|ResolvesToString|string $timezone The timezone of the operation result. timezone must be a valid expression that resolves to a string formatted as either an Olson Timezone Identifier or a UTC Offset. If no timezone is provided, the result is displayed in UTC. */ public function __construct( - ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int $date, + ObjectId|Timestamp|UTCDateTime|ResolvesToDate|ResolvesToObjectId|ResolvesToTimestamp|int|string $date, Optional|ResolvesToString|string $timezone = Optional::Undefined, ) { + if (is_string($date) && ! str_starts_with($date, '$')) { + throw new InvalidArgumentException('Argument $date can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->date = $date; $this->timezone = $timezone; } diff --git a/src/Builder/Expression/ZipOperator.php b/src/Builder/Expression/ZipOperator.php index 742b7e6bf..cc98f9ecf 100644 --- a/src/Builder/Expression/ZipOperator.php +++ b/src/Builder/Expression/ZipOperator.php @@ -17,6 +17,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Merge two arrays together. @@ -31,11 +33,11 @@ final class ZipOperator implements ResolvesToArray, OperatorInterface public const PROPERTIES = ['inputs' => 'inputs', 'useLongestLength' => 'useLongestLength', 'defaults' => 'defaults']; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. + * @var BSONArray|PackedArray|ResolvesToArray|array|string $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. * If any of the inputs arrays resolves to a value of null or refers to a missing field, $zip returns null. * If any of the inputs arrays does not resolve to an array or null nor refers to a missing field, $zip returns an error. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $inputs; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $inputs; /** * @var Optional|bool $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array. @@ -51,7 +53,7 @@ final class ZipOperator implements ResolvesToArray, OperatorInterface public readonly Optional|PackedArray|BSONArray|array $defaults; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. + * @param BSONArray|PackedArray|ResolvesToArray|array|string $inputs An array of expressions that resolve to arrays. The elements of these input arrays combine to form the arrays of the output array. * If any of the inputs arrays resolves to a value of null or refers to a missing field, $zip returns null. * If any of the inputs arrays does not resolve to an array or null nor refers to a missing field, $zip returns an error. * @param Optional|bool $useLongestLength A boolean which specifies whether the length of the longest array determines the number of arrays in the output array. @@ -61,10 +63,14 @@ final class ZipOperator implements ResolvesToArray, OperatorInterface * If specifying a non-empty defaults, you must specify a default for each input array or else $zip will return an error. */ public function __construct( - PackedArray|ResolvesToArray|BSONArray|array $inputs, + PackedArray|ResolvesToArray|BSONArray|array|string $inputs, Optional|bool $useLongestLength = Optional::Undefined, Optional|PackedArray|BSONArray|array $defaults = Optional::Undefined, ) { + if (is_string($inputs) && ! str_starts_with($inputs, '$')) { + throw new InvalidArgumentException('Argument $inputs can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($inputs) && ! array_is_list($inputs)) { throw new InvalidArgumentException('Expected $inputs argument to be a list, got an associative array.'); } diff --git a/src/Builder/Query/FactoryTrait.php b/src/Builder/Query/FactoryTrait.php index 9c11b0795..e9900f935 100644 --- a/src/Builder/Query/FactoryTrait.php +++ b/src/Builder/Query/FactoryTrait.php @@ -458,10 +458,10 @@ public static function regex(Regex $regex): RegexOperator * Randomly select documents at a given rate. Although the exact number of documents selected varies on each run, the quantity chosen approximates the sample rate expressed as a percentage of the total number of documents. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/sampleRate/ - * @param Int64|ResolvesToDouble|float|int $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. + * @param Int64|ResolvesToDouble|float|int|string $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. * For example, a sample rate of 0.33 selects roughly one document in three. */ - public static function sampleRate(Int64|ResolvesToDouble|float|int $rate): SampleRateOperator + public static function sampleRate(Int64|ResolvesToDouble|float|int|string $rate): SampleRateOperator { return new SampleRateOperator($rate); } diff --git a/src/Builder/Query/SampleRateOperator.php b/src/Builder/Query/SampleRateOperator.php index 42879cead..a027972da 100644 --- a/src/Builder/Query/SampleRateOperator.php +++ b/src/Builder/Query/SampleRateOperator.php @@ -13,6 +13,10 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\QueryInterface; +use MongoDB\Exception\InvalidArgumentException; + +use function is_string; +use function str_starts_with; /** * Randomly select documents at a given rate. Although the exact number of documents selected varies on each run, the quantity chosen approximates the sample rate expressed as a percentage of the total number of documents. @@ -27,17 +31,21 @@ final class SampleRateOperator implements QueryInterface, OperatorInterface public const PROPERTIES = ['rate' => 'rate']; /** - * @var Int64|ResolvesToDouble|float|int $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. + * @var Int64|ResolvesToDouble|float|int|string $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. * For example, a sample rate of 0.33 selects roughly one document in three. */ - public readonly Int64|ResolvesToDouble|float|int $rate; + public readonly Int64|ResolvesToDouble|float|int|string $rate; /** - * @param Int64|ResolvesToDouble|float|int $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. + * @param Int64|ResolvesToDouble|float|int|string $rate The selection process uses a uniform random distribution. The sample rate is a floating point number between 0 and 1, inclusive, which represents the probability that a given document will be selected as it passes through the pipeline. * For example, a sample rate of 0.33 selects roughly one document in three. */ - public function __construct(Int64|ResolvesToDouble|float|int $rate) + public function __construct(Int64|ResolvesToDouble|float|int|string $rate) { + if (is_string($rate) && ! str_starts_with($rate, '$')) { + throw new InvalidArgumentException('Argument $rate can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->rate = $rate; } } diff --git a/src/Builder/Stage/DocumentsStage.php b/src/Builder/Stage/DocumentsStage.php index d49585ef7..c020a9cb0 100644 --- a/src/Builder/Stage/DocumentsStage.php +++ b/src/Builder/Stage/DocumentsStage.php @@ -18,6 +18,8 @@ use function array_is_list; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns literal documents from input values. @@ -32,23 +34,27 @@ final class DocumentsStage implements StageInterface, OperatorInterface public const PROPERTIES = ['documents' => 'documents']; /** - * @var BSONArray|PackedArray|ResolvesToArray|array $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * @var BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: * - system variables, such as $$NOW or $$SEARCH_META * - $let expressions * - variables in scope from $lookup expressions * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. */ - public readonly PackedArray|ResolvesToArray|BSONArray|array $documents; + public readonly PackedArray|ResolvesToArray|BSONArray|array|string $documents; /** - * @param BSONArray|PackedArray|ResolvesToArray|array $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * @param BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: * - system variables, such as $$NOW or $$SEARCH_META * - $let expressions * - variables in scope from $lookup expressions * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. */ - public function __construct(PackedArray|ResolvesToArray|BSONArray|array $documents) + public function __construct(PackedArray|ResolvesToArray|BSONArray|array|string $documents) { + if (is_string($documents) && ! str_starts_with($documents, '$')) { + throw new InvalidArgumentException('Argument $documents can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + if (is_array($documents) && ! array_is_list($documents)) { throw new InvalidArgumentException('Expected $documents argument to be a list, got an associative array.'); } diff --git a/src/Builder/Stage/FactoryTrait.php b/src/Builder/Stage/FactoryTrait.php index 7bbf3bc97..bb63bb107 100644 --- a/src/Builder/Stage/FactoryTrait.php +++ b/src/Builder/Stage/FactoryTrait.php @@ -199,13 +199,13 @@ public static function densify( * Returns literal documents from input values. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents/ - * @param BSONArray|PackedArray|ResolvesToArray|array $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * @param BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: * - system variables, such as $$NOW or $$SEARCH_META * - $let expressions * - variables in scope from $lookup expressions * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. */ - public static function documents(PackedArray|ResolvesToArray|BSONArray|array $documents): DocumentsStage + public static function documents(PackedArray|ResolvesToArray|BSONArray|array|string $documents): DocumentsStage { return new DocumentsStage($documents); } @@ -248,7 +248,7 @@ public static function fill( * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. @@ -265,7 +265,7 @@ public static function fill( * Default: false. */ public static function geoNear( - Document|Serializable|ResolvesToObject|stdClass|array $near, + Document|Serializable|ResolvesToObject|stdClass|array|string $near, Optional|string $distanceField = Optional::Undefined, Optional|Decimal128|Int64|float|int $distanceMultiplier = Optional::Undefined, Optional|string $includeLocs = Optional::Undefined, @@ -501,10 +501,10 @@ public static function redact( * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $newRoot + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot */ public static function replaceRoot( - Document|Serializable|ResolvesToObject|stdClass|array $newRoot, + Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot, ): ReplaceRootStage { return new ReplaceRootStage($newRoot); } @@ -514,10 +514,10 @@ public static function replaceRoot( * Alias for $replaceRoot. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $expression + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $expression */ public static function replaceWith( - Document|Serializable|ResolvesToObject|stdClass|array $expression, + Document|Serializable|ResolvesToObject|stdClass|array|string $expression, ): ReplaceWithStage { return new ReplaceWithStage($expression); } diff --git a/src/Builder/Stage/FluentFactoryTrait.php b/src/Builder/Stage/FluentFactoryTrait.php index 3cfd84cff..64fdc6b3c 100644 --- a/src/Builder/Stage/FluentFactoryTrait.php +++ b/src/Builder/Stage/FluentFactoryTrait.php @@ -240,13 +240,13 @@ public function densify( * Returns literal documents from input values. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents/ - * @param BSONArray|PackedArray|ResolvesToArray|array $documents $documents accepts any valid expression that resolves to an array of objects. This includes: + * @param BSONArray|PackedArray|ResolvesToArray|array|string $documents $documents accepts any valid expression that resolves to an array of objects. This includes: * - system variables, such as $$NOW or $$SEARCH_META * - $let expressions * - variables in scope from $lookup expressions * Expressions that do not resolve to a current document, like $myField or $$ROOT, will result in an error. */ - public function documents(PackedArray|ResolvesToArray|BSONArray|array $documents): static + public function documents(PackedArray|ResolvesToArray|BSONArray|array|string $documents): static { $this->pipeline[] = Stage::documents($documents); @@ -295,7 +295,7 @@ public function fill( * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. @@ -312,7 +312,7 @@ public function fill( * Default: false. */ public function geoNear( - Document|Serializable|ResolvesToObject|stdClass|array $near, + Document|Serializable|ResolvesToObject|stdClass|array|string $near, Optional|string $distanceField = Optional::Undefined, Optional|Decimal128|Int64|int|float $distanceMultiplier = Optional::Undefined, Optional|string $includeLocs = Optional::Undefined, @@ -565,9 +565,9 @@ public function redact(Type|ExpressionInterface|stdClass|array|string|int|float| * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $newRoot + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot */ - public function replaceRoot(Document|Serializable|ResolvesToObject|stdClass|array $newRoot): static + public function replaceRoot(Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot): static { $this->pipeline[] = Stage::replaceRoot($newRoot); @@ -579,9 +579,9 @@ public function replaceRoot(Document|Serializable|ResolvesToObject|stdClass|arra * Alias for $replaceRoot. * * @see https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith/ - * @param Document|ResolvesToObject|Serializable|array|stdClass $expression + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $expression */ - public function replaceWith(Document|Serializable|ResolvesToObject|stdClass|array $expression): static + public function replaceWith(Document|Serializable|ResolvesToObject|stdClass|array|string $expression): static { $this->pipeline[] = Stage::replaceWith($expression); diff --git a/src/Builder/Stage/GeoNearStage.php b/src/Builder/Stage/GeoNearStage.php index 845fd2afa..21600a5b8 100644 --- a/src/Builder/Stage/GeoNearStage.php +++ b/src/Builder/Stage/GeoNearStage.php @@ -19,9 +19,12 @@ use MongoDB\Builder\Type\QueryInterface; use MongoDB\Builder\Type\QueryObject; use MongoDB\Builder\Type\StageInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; use function is_array; +use function is_string; +use function str_starts_with; /** * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. @@ -46,8 +49,8 @@ final class GeoNearStage implements StageInterface, OperatorInterface 'spherical' => 'spherical', ]; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $near; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $near; /** @var Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. */ public readonly Optional|string $distanceField; @@ -88,7 +91,7 @@ final class GeoNearStage implements StageInterface, OperatorInterface public readonly Optional|bool $spherical; /** - * @param Document|ResolvesToObject|Serializable|array|stdClass $near The point for which to find the closest documents. + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $near The point for which to find the closest documents. * @param Optional|string $distanceField The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation. * @param Optional|Decimal128|Int64|float|int $distanceMultiplier The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth. * @param Optional|string $includeLocs This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation. @@ -105,7 +108,7 @@ final class GeoNearStage implements StageInterface, OperatorInterface * Default: false. */ public function __construct( - Document|Serializable|ResolvesToObject|stdClass|array $near, + Document|Serializable|ResolvesToObject|stdClass|array|string $near, Optional|string $distanceField = Optional::Undefined, Optional|Decimal128|Int64|float|int $distanceMultiplier = Optional::Undefined, Optional|string $includeLocs = Optional::Undefined, @@ -115,6 +118,10 @@ public function __construct( Optional|QueryInterface|array $query = Optional::Undefined, Optional|bool $spherical = Optional::Undefined, ) { + if (is_string($near) && ! str_starts_with($near, '$')) { + throw new InvalidArgumentException('Argument $near can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->near = $near; $this->distanceField = $distanceField; $this->distanceMultiplier = $distanceMultiplier; diff --git a/src/Builder/Stage/ReplaceRootStage.php b/src/Builder/Stage/ReplaceRootStage.php index f88bf07b2..2cf5c34b2 100644 --- a/src/Builder/Stage/ReplaceRootStage.php +++ b/src/Builder/Stage/ReplaceRootStage.php @@ -14,8 +14,12 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\StageInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. * @@ -28,14 +32,18 @@ final class ReplaceRootStage implements StageInterface, OperatorInterface public const NAME = '$replaceRoot'; public const PROPERTIES = ['newRoot' => 'newRoot']; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $newRoot */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $newRoot; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot; /** - * @param Document|ResolvesToObject|Serializable|array|stdClass $newRoot + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $newRoot */ - public function __construct(Document|Serializable|ResolvesToObject|stdClass|array $newRoot) + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $newRoot) { + if (is_string($newRoot) && ! str_starts_with($newRoot, '$')) { + throw new InvalidArgumentException('Argument $newRoot can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->newRoot = $newRoot; } } diff --git a/src/Builder/Stage/ReplaceWithStage.php b/src/Builder/Stage/ReplaceWithStage.php index 84d6ffda4..95746bfa9 100644 --- a/src/Builder/Stage/ReplaceWithStage.php +++ b/src/Builder/Stage/ReplaceWithStage.php @@ -14,8 +14,12 @@ use MongoDB\Builder\Type\Encode; use MongoDB\Builder\Type\OperatorInterface; use MongoDB\Builder\Type\StageInterface; +use MongoDB\Exception\InvalidArgumentException; use stdClass; +use function is_string; +use function str_starts_with; + /** * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. * Alias for $replaceRoot. @@ -29,14 +33,18 @@ final class ReplaceWithStage implements StageInterface, OperatorInterface public const NAME = '$replaceWith'; public const PROPERTIES = ['expression' => 'expression']; - /** @var Document|ResolvesToObject|Serializable|array|stdClass $expression */ - public readonly Document|Serializable|ResolvesToObject|stdClass|array $expression; + /** @var Document|ResolvesToObject|Serializable|array|stdClass|string $expression */ + public readonly Document|Serializable|ResolvesToObject|stdClass|array|string $expression; /** - * @param Document|ResolvesToObject|Serializable|array|stdClass $expression + * @param Document|ResolvesToObject|Serializable|array|stdClass|string $expression */ - public function __construct(Document|Serializable|ResolvesToObject|stdClass|array $expression) + public function __construct(Document|Serializable|ResolvesToObject|stdClass|array|string $expression) { + if (is_string($expression) && ! str_starts_with($expression, '$')) { + throw new InvalidArgumentException('Argument $expression can be an expression, field paths and variable names must be prefixed by "$" or "$$".'); + } + $this->expression = $expression; } } diff --git a/tests/Builder/FieldPathTest.php b/tests/Builder/FieldPathTest.php index afd1a15de..90ccef804 100644 --- a/tests/Builder/FieldPathTest.php +++ b/tests/Builder/FieldPathTest.php @@ -56,4 +56,18 @@ public static function provideFieldPath(): Generator yield 'number' => ['numberFieldPath', Expression\ResolvesToNumber::class]; yield 'any' => ['fieldPath', Expression\ResolvesToAny::class]; } + + public function testStringFieldPathAcceptedAsExpression(): void + { + $operator = Expression::abs('$foo'); + + $this->assertSame('$foo', $operator->value); + } + + public function testNonDollarPrefixedStringRejected(): void + { + self::expectException(InvalidArgumentException::class); + + Expression::abs('foo'); + } }