From 39558070786b400c3a82f22ad9da3b77eb99ceaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 7 Oct 2024 10:37:33 +0200 Subject: [PATCH] PHPORM-207 Convert arrow notation -> to dot . (#3170) --- src/Query/Builder.php | 20 +++++++++++++++++++- tests/Query/BuilderTest.php | 10 ++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Query/Builder.php b/src/Query/Builder.php index eeb5ffe8d..c62709ce5 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -66,6 +66,7 @@ use function property_exists; use function serialize; use function sprintf; +use function str_contains; use function str_ends_with; use function str_replace; use function str_starts_with; @@ -1616,7 +1617,24 @@ private function aliasIdForQuery(array $values): array } foreach ($values as $key => $value) { - if (is_string($key) && str_ends_with($key, '.id')) { + if (! is_string($key)) { + continue; + } + + // "->" arrow notation for subfields is an alias for "." dot notation + if (str_contains($key, '->')) { + $newkey = str_replace('->', '.', $key); + if (array_key_exists($newkey, $values) && $value !== $values[$newkey]) { + throw new InvalidArgumentException(sprintf('Cannot have both "%s" and "%s" fields.', $key, $newkey)); + } + + $values[$newkey] = $value; + unset($values[$key]); + $key = $newkey; + } + + // ".id" subfield are alias for "._id" + if (str_ends_with($key, '.id')) { $newkey = substr($key, 0, -3) . '._id'; if (array_key_exists($newkey, $values) && $value !== $values[$newkey]) { throw new InvalidArgumentException(sprintf('Cannot have both "%s" and "%s" fields.', $key, $newkey)); diff --git a/tests/Query/BuilderTest.php b/tests/Query/BuilderTest.php index c1587dc73..20f4a4db2 100644 --- a/tests/Query/BuilderTest.php +++ b/tests/Query/BuilderTest.php @@ -1406,6 +1406,16 @@ function (Builder $elemMatchQuery): void { ], ])->where('age', 15), ]; + + yield 'arrow notation' => [ + ['find' => [['data.format' => 1], []]], + fn (Builder $builder) => $builder->where('data->format', 1), + ]; + + yield 'arrow notation with id' => [ + ['find' => [['embedded._id' => 1], []]], + fn (Builder $builder) => $builder->where('embedded->id', 1), + ]; } #[DataProvider('provideExceptions')]