From 379f5e08b4e432c1848afb2a60405154e6e0c04a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 4 Jun 2013 14:28:00 +0200 Subject: [PATCH] [DependencyInjection] Fix aliased access of shared services, fixes #8096 --- .../DependencyInjection/Container.php | 8 +++ .../DependencyInjection/Dumper/PhpDumper.php | 58 ++++++++++++++----- .../Tests/Fixtures/php/services9.php | 16 +++++ .../Tests/Fixtures/php/services9_compiled.php | 4 +- 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 50d413b9d2..ef561e1ded 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -69,6 +69,7 @@ class Container implements IntrospectableContainerInterface protected $services; protected $methodMap; + protected $aliases; protected $scopes; protected $scopeChildren; protected $scopedServices; @@ -253,6 +254,12 @@ class Container implements IntrospectableContainerInterface { $id = strtolower($id); + // resolve aliases + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + + // re-use shared service instance if it exists if (array_key_exists($id, $this->services)) { return $this->services[$id]; } @@ -264,6 +271,7 @@ class Container implements IntrospectableContainerInterface if (isset($this->methodMap[$id])) { $method = $this->methodMap[$id]; } elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) { + // $method is set to the right value, proceed } else { if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { if (!$id) { diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index bfe6f6d220..0dd058e9ab 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -799,6 +799,9 @@ EOF; $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n"; } + $code .= $this->addMethodMap(); + $code .= $this->addAliases(); + $code .= <<container->getDefinitions(); - ksort($definitions); - foreach ($definitions as $id => $definition) { - $code .= ' '.var_export($id, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n"; - } - $aliases = $this->container->getAliases(); - ksort($aliases); - foreach ($aliases as $alias => $id) { - $code .= ' '.var_export($alias, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n"; - } - $code .= " );\n"; + $code .= $this->addMethodMap(); + $code .= $this->addAliases(); $code .= <<container->getDefinitions()) { + return ''; + } + + $code = " \$this->methodMap = array(\n"; + ksort($definitions); + foreach ($definitions as $id => $definition) { + $code .= ' '.var_export($id, true).' => '.var_export('get'.Container::camelize($id).'Service', true).",\n"; + } + + return $code . " );\n"; + } + + /** + * Adds the aliases property definition + * + * @return string + */ + private function addAliases() + { + if (!$aliases = $this->container->getAliases()) { + return ''; + } + + $code = " \$this->aliases = array(\n"; + ksort($aliases); + foreach ($aliases as $alias => $id) { + $code .= ' '.var_export($alias, true).' => '.var_export((string) $id, true).",\n"; + } + + return $code . " );\n"; + } + /** * Adds default parameters method. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 4aad5e6e9e..0840ee8843 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -24,6 +24,22 @@ class ProjectServiceContainer extends Container public function __construct() { parent::__construct(new ParameterBag($this->getDefaultParameters())); + $this->methodMap = array( + 'bar' => 'getBarService', + 'baz' => 'getBazService', + 'depends_on_request' => 'getDependsOnRequestService', + 'factory_service' => 'getFactoryServiceService', + 'foo' => 'getFooService', + 'foo.baz' => 'getFoo_BazService', + 'foo_bar' => 'getFooBarService', + 'foo_with_inline' => 'getFooWithInlineService', + 'inlined' => 'getInlinedService', + 'method_call1' => 'getMethodCall1Service', + 'request' => 'getRequestService', + ); + $this->aliases = array( + 'alias_for_foo' => 'foo', + ); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index dde0543148..b81c4953e6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -44,7 +44,9 @@ class ProjectServiceContainer extends Container 'foo_with_inline' => 'getFooWithInlineService', 'method_call1' => 'getMethodCall1Service', 'request' => 'getRequestService', - 'alias_for_foo' => 'getFooService', + ); + $this->aliases = array( + 'alias_for_foo' => 'foo', ); }