diff --git a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php index bb9dc214e6a50..def72ad142530 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php @@ -59,11 +59,48 @@ public function registerClasses(Definition $prototype, $namespace, $resource) } $classes = $this->findClasses($namespace, $resource); + + $unusedArguments = array(); + foreach ($prototype->getArguments() as $key => $argument) { + if ('' === $key || '$' !== $key[0]) { + continue; + } + + $unusedArguments[$key] = true; + } + // prepare for deep cloning $prototype = serialize($prototype); - foreach ($classes as $class) { - $this->setDefinition($class, unserialize($prototype)); + foreach ($classes as $class => $reflectionClass) { + $parameters = array(); + if ($reflectionClass->hasMethod('__construct')) { + foreach ($reflectionClass->getMethod('__construct')->getParameters() as $parameter) { + $parameters['$'.$parameter->name] = true; + } + } + + $definition = unserialize($prototype); + + $arguments = array(); + foreach ($definition->getArguments() as $key => $argument) { + if ('' !== $key && '$' === $key[0]) { + if (!isset($parameters[$key])) { + continue; + } + + unset($unusedArguments[$key]); + } + + $arguments[$key] = $argument; + } + $definition->setArguments($arguments); + + $this->setDefinition($class, $definition); + } + + if ($unusedArguments) { + throw new InvalidArgumentException(sprintf('Unused named arguments in a prototype: "%s".', implode('", "', array_keys($unusedArguments)))); } } @@ -104,7 +141,7 @@ private function findClasses($namespace, $resource) continue; } if (!$r->isInterface() && !$r->isTrait()) { - $classes[] = $class; + $classes[$class] = $r; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php index 1e4f283c8f16e..5520c2fd1dbf4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php @@ -4,4 +4,7 @@ class Foo { + public function __construct($bar = null) + { + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/prototype_named_args.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/prototype_named_args.yml new file mode 100644 index 0000000000000..005085b30b3bc --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/prototype_named_args.yml @@ -0,0 +1,5 @@ +services: + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\: + resource: ../Prototype + arguments: + $bar: foo diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/prototype_unused_named_args.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/prototype_unused_named_args.yml new file mode 100644 index 0000000000000..6baa759d72fc1 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/prototype_unused_named_args.yml @@ -0,0 +1,6 @@ +services: + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\: + resource: ../Prototype + arguments: + $invalid: foo + $invalid2: quz diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index a30aa12c52712..ee04d03a8926b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -24,7 +24,6 @@ use Symfony\Component\Config\Resource\DirectoryResource; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype; use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; use Symfony\Component\ExpressionLanguage\Expression; @@ -450,6 +449,33 @@ public function testNamedArguments() $this->assertEquals(array(array('setApiKey', array('123'))), $container->getDefinition('another_one')->getMethodCalls()); } + public function testNamedArgumentsInPrototypes() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('prototype_named_args.yml'); + + $fooDefinition = $container->getDefinition('Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo'); + $this->assertEquals(array('$bar' => 'foo'), $fooDefinition->getArguments()); + + $this->assertEmpty($container->getDefinition('Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar')->getArguments()); + + $container->compile(); + + $this->assertEquals(array('foo'), $fooDefinition->getArguments()); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @expectedExceptionMessage Unused named arguments in a prototype: "$invalid", "$invalid2". + */ + public function testUnusedNamedArgumentsInPrototypes() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('prototype_unused_named_args.yml'); + } + public function testInstanceof() { $container = new ContainerBuilder();
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: