diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 0597bd8c426ad..da7669ffcd3bd 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -525,9 +525,9 @@ private function addServiceOverriddenGetters($id, Definition $definition) } if (!$r->isFinal()) { if (0 < $r->getNumberOfParameters()) { - $getters = implode('($container'.$this->salt.', ', explode('(', $this->generateSignature($r), 2)); + $getters = implode('__construct($container'.$this->salt.', ', explode('(', $this->generateSignature($r), 2)); } else { - $getters = '($container'.$this->salt.')'; + $getters = '__construct($container'.$this->salt.')'; } $getters = sprintf("\n public function %s\n {\n \$this->container%3\$s = \$container%3\$s;\n parent::%s;\n }\n", $getters, $this->generateCall($r), $this->salt); } else { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 7877a64436071..a93522bd96caf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -344,6 +344,27 @@ public function testDumpOverridenGetters() $this->assertSame('baz', $r->invoke($baz)); } + public function testDumpOverridenGettersWithConstructor() + { + $container = include self::$fixturesPath.'/containers/container_dump_overriden_getters_with_constructor.php'; + $container->compile(); + $container->getDefinition('foo') + ->setOverriddenGetter('getInvalid', array(new Reference('bar', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE))); + $dumper = new PhpDumper($container); + + $dump = $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor')); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dump_overriden_getters_with_constructor.php', $dump); + $resources = array_map('strval', $container->getResources()); + $this->assertContains(realpath(self::$fixturesPath.'/containers/container_dump_overriden_getters_with_constructor.php'), $resources); + + $baz = $container->get('baz'); + $r = new \ReflectionMethod($baz, 'getBaz'); + $r->setAccessible(true); + + $this->assertTrue($r->isProtected()); + $this->assertSame('baz', $r->invoke($baz)); + } + /** * @dataProvider provideBadOverridenGetters * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_dump_overriden_getters_with_constructor.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_dump_overriden_getters_with_constructor.php new file mode 100644 index 0000000000000..8c25f0cfe37ab --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_dump_overriden_getters_with_constructor.php @@ -0,0 +1,64 @@ +bar = $bar; + } + + abstract public function getPublic(); + abstract protected function getProtected(); + + public function getSelf() + { + return 123; + } + + public function getInvalid() + { + return 456; + } + + public function getGetProtected() + { + return $this->getProtected(); + } + } + + class Baz + { + final public function __construct() + { + } + + protected function getBaz() + { + return 234; + } + } +} + +$container = new ContainerBuilder(); + +$container + ->register('foo', Foo::class) + ->setOverriddenGetter('getPublic', 'public') + ->setOverriddenGetter('getProtected', 'protected') + ->setOverriddenGetter('getSelf', new Reference('foo')) +; + +$container + ->register('baz', Baz::class) + ->setOverriddenGetter('getBaz', 'baz') +; + +return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_dump_overriden_getters_with_constructor.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_dump_overriden_getters_with_constructor.php new file mode 100644 index 0000000000000..e1119248470cf --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_dump_overriden_getters_with_constructor.php @@ -0,0 +1,153 @@ +services = array(); + $this->methodMap = array( + 'baz' => 'getBazService', + 'foo' => 'getFooService', + ); + + $this->aliases = array(); + } + + /** + * {@inheritdoc} + */ + public function compile() + { + throw new LogicException('You cannot compile a dumped frozen container.'); + } + + /** + * {@inheritdoc} + */ + public function isFrozen() + { + return true; + } + + /** + * Gets the 'baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz A Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz instance + */ + protected function getBazService() + { + return $this->services['baz'] = $this->instantiateProxy(SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883::class, array(), true); + } + + /** + * Gets the 'foo' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo A Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo instance + */ + protected function getFooService() + { + return $this->services['foo'] = new SymfonyProxy_cbcc1d1a7dc6a97b54a307ad6a012531($this); + } + + private function instantiateProxy($class, $args, $useConstructor) + { + static $reflectionCache; + + if (null === $r = &$reflectionCache[$class]) { + $r[0] = new \ReflectionClass($class); + $r[1] = $r[0]->getProperty('containerg3aCmsigw5jaB68sqMSEQQ'); + $r[1]->setAccessible(true); + $r[2] = $r[0]->getConstructor(); + } + $service = $useConstructor ? $r[0]->newInstanceWithoutConstructor() : $r[0]->newInstanceArgs($args); + $r[1]->setValue($service, $this); + if ($r[2] && $useConstructor) { + $r[2]->invokeArgs($service, $args); + } + + return $service; + } +} + +class SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface +{ + private $containerg3aCmsigw5jaB68sqMSEQQ; + private $gettersg3aCmsigw5jaB68sqMSEQQ; + + protected function getBaz() + { + return 'baz'; + } +} + +class SymfonyProxy_cbcc1d1a7dc6a97b54a307ad6a012531 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface +{ + private $containerg3aCmsigw5jaB68sqMSEQQ; + private $gettersg3aCmsigw5jaB68sqMSEQQ; + + public function __construct($containerg3aCmsigw5jaB68sqMSEQQ, $bar = 'bar') + { + $this->containerg3aCmsigw5jaB68sqMSEQQ = $containerg3aCmsigw5jaB68sqMSEQQ; + parent::__construct($bar); + } + + public function getPublic() + { + return 'public'; + } + + protected function getProtected() + { + return 'protected'; + } + + public function getSelf() + { + if (null === $g = &$this->gettersg3aCmsigw5jaB68sqMSEQQ[__FUNCTION__]) { + $g = \Closure::bind(function () { return ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}; }, $this->containerg3aCmsigw5jaB68sqMSEQQ, $this->containerg3aCmsigw5jaB68sqMSEQQ); + } + + return $g(); + } + + public function getInvalid() + { + if (null === $g = &$this->gettersg3aCmsigw5jaB68sqMSEQQ[__FUNCTION__]) { + $g = \Closure::bind(function () { return array(0 => $this->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE)); }, $this->containerg3aCmsigw5jaB68sqMSEQQ, $this->containerg3aCmsigw5jaB68sqMSEQQ); + } + + if ($this->containerg3aCmsigw5jaB68sqMSEQQ->has('bar')) { + return $g(); + } + + return parent::getInvalid(); + } +}