diff --git a/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php b/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php index c1ede525e0f2e..74cbcbf6ee258 100644 --- a/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php +++ b/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php @@ -35,6 +35,8 @@ public function __construct( private ManagerRegistry $registry, private ?ExpressionLanguage $expressionLanguage = null, private MapEntity $defaults = new MapEntity(), + /** @var array */ + private array $typeAliases = [], ) { } @@ -50,30 +52,35 @@ public function resolve(Request $request, ArgumentMetadata $argument): array if (!$options->class || $options->disabled) { return []; } - if (!$manager = $this->getManager($options->objectManager, $options->class)) { + + $class = array_key_exists($options->class, $this->typeAliases) + ? $this->typeAliases[$options->class] + : $options->class; + + if (!$manager = $this->getManager($options->objectManager, $class)) { return []; } $message = ''; if (null !== $options->expr) { - if (null === $object = $this->findViaExpression($manager, $request, $options)) { + if (null === $object = $this->findViaExpression($manager, $request, $options, $class)) { $message = sprintf(' The expression "%s" returned null.', $options->expr); } // find by identifier? - } elseif (false === $object = $this->find($manager, $request, $options, $argument->getName())) { + } elseif (false === $object = $this->find($manager, $request, $options, $argument->getName(), $class)) { // find by criteria - if (!$criteria = $this->getCriteria($request, $options, $manager)) { + if (!$criteria = $this->getCriteria($request, $options, $manager, $class)) { return []; } try { - $object = $manager->getRepository($options->class)->findOneBy($criteria); + $object = $manager->getRepository($class)->findOneBy($criteria); } catch (NoResultException|ConversionException) { $object = null; } } if (null === $object && !$argument->isNullable()) { - throw new NotFoundHttpException($options->message ?? (sprintf('"%s" object not found by "%s".', $options->class, self::class).$message)); + throw new NotFoundHttpException($options->message ?? (sprintf('"%s" object not found by "%s".', $class, self::class).$message)); } return [$object]; @@ -94,7 +101,7 @@ private function getManager(?string $name, string $class): ?ObjectManager return $manager->getMetadataFactory()->isTransient($class) ? null : $manager; } - private function find(ObjectManager $manager, Request $request, MapEntity $options, string $name): false|object|null + private function find(ObjectManager $manager, Request $request, MapEntity $options, string $name, string $class): false|object|null { if ($options->mapping || $options->exclude) { return false; @@ -107,13 +114,13 @@ private function find(ObjectManager $manager, Request $request, MapEntity $optio if ($options->evictCache && $manager instanceof EntityManagerInterface) { $cacheProvider = $manager->getCache(); - if ($cacheProvider && $cacheProvider->containsEntity($options->class, $id)) { - $cacheProvider->evictEntity($options->class, $id); + if ($cacheProvider && $cacheProvider->containsEntity($class, $id)) { + $cacheProvider->evictEntity($class, $id); } } try { - return $manager->getRepository($options->class)->find($id); + return $manager->getRepository($class)->find($id); } catch (NoResultException|ConversionException) { return null; } @@ -150,7 +157,7 @@ private function getIdentifier(Request $request, MapEntity $options, string $nam return false; } - private function getCriteria(Request $request, MapEntity $options, ObjectManager $manager): array + private function getCriteria(Request $request, MapEntity $options, ObjectManager $manager, string $class): array { if (null === $mapping = $options->mapping) { $mapping = $request->attributes->keys(); @@ -175,7 +182,7 @@ private function getCriteria(Request $request, MapEntity $options, ObjectManager } $criteria = []; - $metadata = $manager->getClassMetadata($options->class); + $metadata = $manager->getClassMetadata($class); foreach ($mapping as $attribute => $field) { if (!$metadata->hasField($field) && (!$metadata->hasAssociation($field) || !$metadata->isSingleValuedAssociation($field))) { @@ -192,13 +199,13 @@ 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, string $class): ?object { 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__)); } - $repository = $manager->getRepository($options->class); + $repository = $manager->getRepository($class); $variables = array_merge($request->attributes->all(), [ 'repository' => $repository, 'request' => $request, diff --git a/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php b/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php index 64ccc1656d75c..9348e48001c11 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php @@ -130,6 +130,38 @@ public function testResolveWithId(string|int $id) $this->assertSame([$object], $resolver->resolve($request, $argument)); } + /** + * @dataProvider idsProvider + */ + public function testResolveWithIdAndTypeAlias(string|int $id) + { + $manager = $this->getMockBuilder(ObjectManager::class)->getMock(); + $registry = $this->createRegistry($manager); + $resolver = new EntityValueResolver($registry, + null, + new MapEntity(), + ['stdClassAlias' => 'stdClass'], + ); + + $request = new Request(); + $request->attributes->set('id', $id); + + $argument = $this->createArgument('stdClassAlias', new MapEntity(id: 'id')); + + $repository = $this->getMockBuilder(ObjectRepository::class)->getMock(); + $repository->expects($this->once()) + ->method('find') + ->with($id) + ->willReturn($object = new \stdClass()); + + $manager->expects($this->once()) + ->method('getRepository') + ->with('stdClass') + ->willReturn($repository); + + $this->assertSame([$object], $resolver->resolve($request, $argument)); + } + public function testResolveWithNullId() { $manager = $this->getMockBuilder(ObjectManager::class)->getMock();