From 6f3673364e9bdd8ae96a7b242310e4931dbe68ad Mon Sep 17 00:00:00 2001 From: Robert Meijers Date: Thu, 26 May 2016 16:08:43 +0200 Subject: [PATCH] [DependencyInjection] Skip deep reference check for 'service_container' Deep checks on whether a service references another service need to exclude the 'service_container' service as it doesn't exist. Without this dumping the container will fail if a service definition references an inlined service which has a direct or indirect dependency to the service_container. --- .../DependencyInjection/Dumper/PhpDumper.php | 2 +- .../Tests/Dumper/PhpDumperTest.php | 11 ++++ .../Tests/Fixtures/php/services13.php | 54 +++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index d239b7d7d509e..d7ab4fc2b83fe 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1173,7 +1173,7 @@ private function hasReference($id, array $arguments, $deep = false, &$visited = return true; } - if ($deep && !isset($visited[(string) $argument])) { + if ($deep && !isset($visited[(string) $argument]) && 'service_container' !== (string) $argument) { $visited[(string) $argument] = true; $service = $this->container->getDefinition((string) $argument); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 311026c5e62d5..219ea63e82fd5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -226,4 +226,15 @@ public function testCircularReference() $dumper = new PhpDumper($container); $dumper->dump(); } + + public function testInlinedDefinitionReferencingServiceContainer() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addMethodCall('add', array(new Reference('service_container')))->setPublic(false); + $container->register('bar', 'stdClass')->addArgument(new Reference('foo')); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container'); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php new file mode 100644 index 0000000000000..0c33b7b3eab8d --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php @@ -0,0 +1,54 @@ +services = + $this->scopedServices = + $this->scopeStacks = array(); + $this->scopes = array(); + $this->scopeChildren = array(); + $this->methodMap = array( + 'bar' => 'getBarService', + ); + + $this->aliases = array(); + } + + /** + * Gets the 'bar' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \stdClass A stdClass instance. + */ + protected function getBarService() + { + $a = new \stdClass(); + $a->add($this); + + return $this->services['bar'] = new \stdClass($a); + } +}