From 97e8d68a05e1457950920c2e1c05d2a20392f918 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 30 Jun 2018 09:08:55 +0200 Subject: [PATCH] [DI] Fix dumping ignore-on-uninitialized references to synthetic services --- .../DependencyInjection/Dumper/PhpDumper.php | 6 +++-- .../Tests/ContainerBuilderTest.php | 15 ++++++++++++ .../Tests/Dumper/PhpDumperTest.php | 23 +++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 7c493f62e3..d7a345bd11 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1898,8 +1898,10 @@ EOF; return '$this'; } - if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id)) && !$definition->isSynthetic()) { - if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { + if ($definition->isSynthetic()) { + $code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { $code = 'null'; if (!$definition->isShared()) { return $code; diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index f2e8368455..d8e7203028 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1434,6 +1434,21 @@ class ContainerBuilderTest extends TestCase $this->assertSame('via-argument', $container->get('foo')->class1->identifier); $this->assertSame('via-bindings', $container->get('foo')->class2->identifier); } + + public function testUninitializedSyntheticReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true); + $container->register('bar', 'stdClass')->setPublic(true)->setShared(false) + ->setProperty('foo', new Reference('foo', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)); + + $container->compile(); + + $this->assertEquals((object) array('foo' => null), $container->get('bar')); + + $container->set('foo', (object) array(123)); + $this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar')); + } } class FooClass diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 319561cf38..161bf18aaf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -913,6 +913,29 @@ class PhpDumperTest extends TestCase $this->assertInstanceOf('stdClass', $container->get('bar')); } + public function testUninitializedSyntheticReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true); + $container->register('bar', 'stdClass')->setPublic(true)->setShared(false) + ->setProperty('foo', new Reference('foo', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE)); + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(array( + 'class' => 'Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference', + 'inline_class_loader_parameter' => 'inline_requires', + ))); + + $container = new \Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference(); + + $this->assertEquals((object) array('foo' => null), $container->get('bar')); + + $container->set('foo', (object) array(123)); + $this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar')); + } + /** * @group legacy * @expectedDeprecation The "private" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.