diff --git a/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php b/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php index c1ede525e0f2e..7ba19b3e6150f 100644 --- a/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php +++ b/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php @@ -192,7 +192,7 @@ private function getCriteria(Request $request, MapEntity $options, ObjectManager return $criteria; } - private function findViaExpression(ObjectManager $manager, Request $request, MapEntity $options): ?object + private function findViaExpression(ObjectManager $manager, Request $request, MapEntity $options): object|iterable|null { if (!$this->expressionLanguage) { throw new \LogicException(sprintf('You cannot use the "%s" if the ExpressionLanguage component is not available. Try running "composer require symfony/expression-language".', __CLASS__)); diff --git a/src/Symfony/Bridge/Doctrine/CHANGELOG.md b/src/Symfony/Bridge/Doctrine/CHANGELOG.md index d50f2a2821717..fee531ebfd1eb 100644 --- a/src/Symfony/Bridge/Doctrine/CHANGELOG.md +++ b/src/Symfony/Bridge/Doctrine/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Deprecate the `DoctrineExtractor::getTypes()` method, use `DoctrineExtractor::getType()` instead + * Allow `EntityValueResolver` to return a list of entities 7.0 --- diff --git a/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php b/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php index 64ccc1656d75c..78994626c231a 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php @@ -298,6 +298,7 @@ public function testExpressionFailureReturns404() $manager->expects($this->once()) ->method('getRepository') + ->with(\stdClass::class) ->willReturn($repository); $language->expects($this->once()) @@ -329,6 +330,7 @@ public function testExpressionMapsToArgument() $manager->expects($this->once()) ->method('getRepository') + ->with(\stdClass::class) ->willReturn($repository); $language->expects($this->once()) @@ -343,6 +345,48 @@ public function testExpressionMapsToArgument() $this->assertSame([$object], $resolver->resolve($request, $argument)); } + public function testExpressionMapsToIterableArgument() + { + $manager = $this->createMock(ObjectManager::class); + $registry = $this->createRegistry($manager); + $language = $this->createMock(ExpressionLanguage::class); + $resolver = new EntityValueResolver($registry, $language); + + $request = new Request(); + $request->attributes->set('id', 5); + $request->query->set('sort', 'ASC'); + $request->query->set('limit', 10); + $argument = $this->createArgument( + 'iterable', + new MapEntity( + class: \stdClass::class, + expr: $expr = 'repository.findBy({"author": id}, {"createdAt": request.query.get("sort", "DESC")}, request.query.getInt("limit", 10))', + ), + 'arg1', + ); + + $repository = $this->createMock(ObjectRepository::class); + // find should not be attempted on this repository as a fallback + $repository->expects($this->never()) + ->method('find'); + + $manager->expects($this->once()) + ->method('getRepository') + ->with(\stdClass::class) + ->willReturn($repository); + + $language->expects($this->once()) + ->method('evaluate') + ->with($expr, [ + 'repository' => $repository, + 'request' => $request, + 'id' => 5, + ]) + ->willReturn($objects = [new \stdClass(), new \stdClass()]); + + $this->assertSame([$objects], $resolver->resolve($request, $argument)); + } + public function testExpressionSyntaxErrorThrowsException() { $manager = $this->getMockBuilder(ObjectManager::class)->getMock(); @@ -364,6 +408,7 @@ public function testExpressionSyntaxErrorThrowsException() $manager->expects($this->once()) ->method('getRepository') + ->with(\stdClass::class) ->willReturn($repository); $language->expects($this->once())