From 11d675fdcf891bbfbf002d64436170d7b0151df8 Mon Sep 17 00:00:00 2001 From: ogizanagi Date: Mon, 2 Nov 2015 11:45:59 +0100 Subject: [PATCH] [FrameworkBundle][Form] Better exception message for private form tagged services --- .../DependencyInjection/Compiler/FormPass.php | 16 ++++++++- .../Compiler/FormPassTest.php | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php index ed8d0053b6..4b36468aa3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php @@ -34,6 +34,10 @@ class FormPass implements CompilerPassInterface $types = array(); foreach ($container->findTaggedServiceIds('form.type') as $serviceId => $tag) { + $serviceDefinition = $container->getDefinition($serviceId); + if (!$serviceDefinition->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as form types are lazy-loaded.', $serviceId)); + } // The following if-else block is deprecated and will be removed // in Symfony 3.0 // Deprecation errors are triggered in the form registry @@ -44,7 +48,6 @@ class FormPass implements CompilerPassInterface } // Support type access by FQCN - $serviceDefinition = $container->getDefinition($serviceId); $types[$serviceDefinition->getClass()] = $serviceId; } @@ -53,6 +56,11 @@ class FormPass implements CompilerPassInterface $typeExtensions = array(); foreach ($container->findTaggedServiceIds('form.type_extension') as $serviceId => $tag) { + $serviceDefinition = $container->getDefinition($serviceId); + if (!$serviceDefinition->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as form type extensions are lazy-loaded.', $serviceId)); + } + if (isset($tag[0]['extended_type'])) { $extendedType = $tag[0]['extended_type']; } elseif (isset($tag[0]['alias'])) { @@ -70,6 +78,12 @@ class FormPass implements CompilerPassInterface // Find all services annotated with "form.type_guesser" $guessers = array_keys($container->findTaggedServiceIds('form.type_guesser')); + foreach ($guessers as $serviceId) { + $serviceDefinition = $container->getDefinition($serviceId); + if (!$serviceDefinition->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as form type guessers are lazy-loaded.', $serviceId)); + } + } $definition->replaceArgument(3, $guessers); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php index 05158a9ed6..c79147284e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php @@ -206,6 +206,39 @@ class FormPassTest extends \PHPUnit_Framework_TestCase 'my.guesser2', ), $extDefinition->getArgument(3)); } + + /** + * @dataProvider privateTaggedServicesProvider + */ + public function testPrivateTaggedServices($id, $tagName, $expectedExceptionMessage) + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new FormPass()); + + $extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension'); + $extDefinition->setArguments(array( + new Reference('service_container'), + array(), + array(), + array(), + )); + + $container->setDefinition('form.extension', $extDefinition); + $container->register($id, 'stdClass')->setPublic(false)->addTag($tagName); + + $this->setExpectedException('\InvalidArgumentException', $expectedExceptionMessage); + + $container->compile(); + } + + public function privateTaggedServicesProvider() + { + return array( + array('my.type', 'form.type', 'The service "my.type" must be public as form types are lazy-loaded'), + array('my.type_extension', 'form.type_extension', 'The service "my.type_extension" must be public as form type extensions are lazy-loaded'), + array('my.guesser', 'form.type_guesser', 'The service "my.guesser" must be public as form type guessers are lazy-loaded'), + ); + } } class FormPassTest_Type1 extends AbstractType