From 89232ee5ea7bf86b97503d8ed58b83cd1612b67b Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Tue, 28 Dec 2021 14:37:08 +0100 Subject: [PATCH] [HttpKernel] Do not attempt to register enum arguments in controller service locator --- ...RegisterControllerArgumentLocatorsPass.php | 5 ++++ ...sterControllerArgumentLocatorsPassTest.php | 27 +++++++++++++++++++ .../HttpKernel/Tests/Fixtures/Suit.php | 20 ++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/Symfony/Component/HttpKernel/Tests/Fixtures/Suit.php diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php index cf4ab60284408..eef09fa82298e 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php @@ -127,6 +127,11 @@ public function process(ContainerBuilder $container) $type = ltrim($target = (string) ProxyHelper::getTypeHint($r, $p), '\\'); $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + if (is_subclass_of($type, \UnitEnum::class, true)) { + // do not attempt to register enum typed arguments + continue; + } + if (isset($arguments[$r->name][$p->name])) { $target = $arguments[$r->name][$p->name]; if ('?' !== $target[0]) { diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php index 5a0964f6c21ca..0207703d94c88 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php @@ -23,6 +23,7 @@ use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\HttpKernel\DependencyInjection\RegisterControllerArgumentLocatorsPass; +use Symfony\Component\HttpKernel\Tests\Fixtures\Suit; class RegisterControllerArgumentLocatorsPassTest extends TestCase { @@ -369,6 +370,25 @@ public function testNotTaggedControllerServiceReceivesLocatorArgument() $this->assertInstanceOf(Reference::class, $locatorArgument); } + + /** + * @requires PHP 8.1 + */ + public function testEnumArgumentIsIgnored() + { + $container = new ContainerBuilder(); + $resolver = $container->register('argument_resolver.service')->addArgument([]); + + $container->register('foo', NonNullableEnumArgumentWithDefaultController::class) + ->addTag('controller.service_arguments') + ; + + $pass = new RegisterControllerArgumentLocatorsPass(); + $pass->process($container); + + $locator = $container->getDefinition((string) $resolver->getArgument(0))->getArgument(0); + $this->assertEmpty(array_keys($locator), 'enum typed argument is ignored'); + } } class RegisterTestController @@ -430,3 +450,10 @@ public function fooAction(string $someArg) { } } + +class NonNullableEnumArgumentWithDefaultController +{ + public function fooAction(Suit $suit = Suit::Spades) + { + } +} diff --git a/src/Symfony/Component/HttpKernel/Tests/Fixtures/Suit.php b/src/Symfony/Component/HttpKernel/Tests/Fixtures/Suit.php new file mode 100644 index 0000000000000..5d9623b22598d --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Tests/Fixtures/Suit.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Tests\Fixtures; + +enum Suit: string +{ + case Hearts = 'H'; + case Diamonds = 'D'; + case Clubs = 'C'; + case Spades = 'S'; +}