From e47336e3d760f7403900bbd9a736f031b00a9fe2 Mon Sep 17 00:00:00 2001 From: Lukas Kahwe Smith Date: Sat, 5 Feb 2011 19:42:07 +0100 Subject: [PATCH 1/3] implicitly load all registered bundles, all loading is now handled by load(), disable loading of an extension explcitly via setting the extension config to false (for now only Yaml is implemented) --- .../DependencyInjection/DoctrineExtension.php | 26 ++++++++++- .../Compiler/AddClassesToAutoloadMapPass.php | 5 +- .../Compiler/AddClassesToCachePass.php | 5 +- .../FrameworkExtension.php | 2 +- .../DependencyInjection/SecurityExtension.php | 14 +++--- .../SwiftmailerExtension.php | 2 +- .../DependencyInjection/TwigExtension.php | 2 +- .../WebProfilerExtension.php | 2 +- .../DependencyInjection/ZendExtension.php | 2 +- .../MergeExtensionConfigurationPass.php | 16 +++---- .../DependencyInjection/ContainerBuilder.php | 46 +++++++++++++++---- .../Extension/Extension.php | 18 -------- .../Extension/ExtensionInterface.php | 5 +- .../Loader/YamlFileLoader.php | 24 +++------- 14 files changed, 90 insertions(+), 79 deletions(-) diff --git a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php index 813c6033727a7..81ffca5a4e6c2 100755 --- a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php +++ b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php @@ -29,6 +29,28 @@ */ class DoctrineExtension extends AbstractDoctrineExtension { + public function load(array $configs, ContainerBuilder $container) + { + $dbal = $orm = array(); + foreach ($configs as $config) { + if (isset($config['dbal'])) { + $dbal[] = $config['dbal']; + } + + if (isset($config['orm'])) { + $orm[] = $config['orm']; + } + } + + if (!empty($dbal)) { + $this->dbalLoad($dbal, $container); + } + + if (!empty($orm)) { + $this->ormLoad($orm, $container); + } + } + /** * Loads the DBAL configuration. * @@ -39,7 +61,7 @@ class DoctrineExtension extends AbstractDoctrineExtension * @param array $config An array of configuration settings * @param ContainerBuilder $container A ContainerBuilder instance */ - public function dbalLoad(array $configs, ContainerBuilder $container) + protected function dbalLoad(array $configs, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config'); $loader->load('dbal.xml'); @@ -229,7 +251,7 @@ protected function loadDbalConnection(array $connection, ContainerBuilder $conta * @param array $config An array of configuration settings * @param ContainerBuilder $container A ContainerBuilder instance */ - public function ormLoad(array $configs, ContainerBuilder $container) + protected function ormLoad(array $configs, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config'); $loader->load('orm.xml'); diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToAutoloadMapPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToAutoloadMapPass.php index 726e40b4af0ea..683c5eb6cc891 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToAutoloadMapPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToAutoloadMapPass.php @@ -28,10 +28,7 @@ class AddClassesToAutoloadMapPass implements CompilerPassInterface public function process(ContainerBuilder $container) { $classes = array(); - foreach ($container->getExtensionConfigs() as $name => $configs) { - list($namespace, $tag) = explode(':', $name); - - $extension = $container->getExtension($namespace); + foreach ($container->getExtensions() as $extension) { if ($extension instanceof Extension) { $classes = array_merge($classes, $extension->getAutoloadClassMap()); } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToCachePass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToCachePass.php index f45c5d1667b17..c3282022d5fbe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToCachePass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddClassesToCachePass.php @@ -28,10 +28,7 @@ class AddClassesToCachePass implements CompilerPassInterface public function process(ContainerBuilder $container) { $classes = array(); - foreach ($container->getExtensionConfigs() as $name => $configs) { - list($namespace, $tag) = explode(':', $name); - - $extension = $container->getExtension($namespace); + foreach ($container->getExtensions() as $extension) { if ($extension instanceof Extension) { $classes = array_merge($classes, $extension->getClassesToCompile()); } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index ecbeae5bb72d7..1ed622c3dd398 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -29,7 +29,7 @@ */ class FrameworkExtension extends Extension { - public function configLoad(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { foreach ($configs as $config) { $this->doConfigLoad($config, $container); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index edc27e69f21da..f83f4659e96d2 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -35,17 +35,15 @@ class SecurityExtension extends Extension protected $contextListeners = array(); protected $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me'); - public function configLoad(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { foreach ($configs as $config) { - $this->doConfigLoad($this->normalizeKeys($config), $container); - } - } + if (isset($config['acl'])) { + $this->doAclLoad($this->normalizeKeys($config['acl']), $container); + unset($config['acl']); + } - public function aclLoad(array $configs, ContainerBuilder $container) - { - foreach ($configs as $config) { - $this->doAclLoad($this->normalizeKeys($config), $container); + $this->doConfigLoad($this->normalizeKeys($config), $container); } } diff --git a/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php b/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php index 6dbac79e9417e..97882ea6fde5d 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php +++ b/src/Symfony/Bundle/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php @@ -23,7 +23,7 @@ */ class SwiftMailerExtension extends Extension { - public function configLoad(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { foreach ($configs as $config) { $this->doConfigLoad($config, $container); diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index 99408646849fe..53ce938131af0 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -23,7 +23,7 @@ */ class TwigExtension extends Extension { - public function configLoad(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config'); $loader->load('twig.xml'); diff --git a/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php b/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php index 9674c1a8e498f..fecd7d0246a16 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php +++ b/src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php @@ -32,7 +32,7 @@ */ class WebProfilerExtension extends Extension { - public function configLoad(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { foreach ($configs as $config) { $this->doConfigLoad($config, $container); diff --git a/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php b/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php index 48d59f5e4a6d4..876d068f4a512 100644 --- a/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php +++ b/src/Symfony/Bundle/ZendBundle/DependencyInjection/ZendExtension.php @@ -34,7 +34,7 @@ class ZendExtension extends Extension * @param array $config An array of configuration settings * @param ContainerBuilder $container A ContainerBuilder instance */ - public function configLoad(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config'); $loader->load('logger.xml'); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 0cdef1f6ecc47..dc6205a8f0359 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -29,17 +29,17 @@ public function process(ContainerBuilder $container) $definitions = $container->getDefinitions(); $aliases = $container->getAliases(); - foreach ($container->getExtensionConfigs() as $name => $configs) { - list($namespace, $tag) = explode(':', $name); + foreach ($container->getExtensions() as $alias => $extension) { - $extension = $container->getExtension($namespace); + $configs = $container->getExtensionConfig($alias); + if ($configs !== false) { + $tmpContainer = new ContainerBuilder($container->getParameterBag()); + $tmpContainer->addObjectResource($extension); - $tmpContainer = new ContainerBuilder($container->getParameterBag()); - $tmpContainer->addObjectResource($extension); + $extension->load($configs, $tmpContainer); - $extension->load($tag, $configs, $tmpContainer); - - $container->merge($tmpContainer); + $container->merge($tmpContainer); + } } $container->addDefinitions($definitions); diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 8bf948e67b9e4..a789635fac055 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -28,6 +28,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface { static protected $extensions = array(); + static protected $extensionsByNs = array(); protected $definitions = array(); protected $aliases = array(); @@ -53,7 +54,7 @@ public function __construct(ParameterBagInterface $parameterBag = null) */ static public function registerExtension(ExtensionInterface $extension) { - static::$extensions[$extension->getAlias()] = static::$extensions[$extension->getNamespace()] = $extension; + static::$extensions[$extension->getAlias()] = static::$extensionsByNs[$extension->getNamespace()] = $extension; } /** @@ -65,16 +66,30 @@ static public function registerExtension(ExtensionInterface $extension) */ static public function getExtension($name) { - if (!isset(static::$extensions[$name])) { - throw new \LogicException(sprintf('Container extension "%s" is not registered', $name)); + if (empty(static::$extensions[$name])) { + if (empty(static::$extensionsByNs[$name])) { + throw new \LogicException(sprintf('Container extension "%s" is not registered', $name)); + } + + return static::$extensionsByNs[$name]; } return static::$extensions[$name]; } + /** + * Returns extensions keyed by alias + * + * @return array ExtensionInterfaces + */ + static public function getExtensions() + { + return static::$extensions; + } + static public function hasExtension($name) { - return isset(static::$extensions[$name]); + return isset(static::$extensions[$name]) || isset(static::$extensionsByNs[$name]); } /** @@ -118,12 +133,11 @@ public function addObjectResource($object) * Loads the configuration for an extension. * * @param string $extension The extension alias or namespace - * @param string $tag The extension tag to load (without the namespace - namespace.tag) * @param array $values An array of values that customizes the extension * * @return ContainerBuilder The current instance */ - public function loadFromExtension($extension, $tag, array $values = array()) + public function loadFromExtension($extension, array $values = array()) { if (true === $this->isFrozen()) { throw new \LogicException('Cannot load from an extension on a frozen container.'); @@ -131,11 +145,11 @@ public function loadFromExtension($extension, $tag, array $values = array()) $namespace = $this->getExtension($extension)->getAlias(); - if (!isset($this->extensionConfigs[$namespace.':'.$tag])) { - $this->extensionConfigs[$namespace.':'.$tag] = array(); + if (!isset($this->extensionConfigs[$namespace])) { + $this->extensionConfigs[$namespace] = array(); } - $this->extensionConfigs[$namespace.':'.$tag][] = $this->getParameterBag()->resolveValue($values); + $this->extensionConfigs[$namespace][] = $this->getParameterBag()->resolveValue($values); return $this; } @@ -340,6 +354,20 @@ public function getExtensionConfigs() return $this->extensionConfigs; } + /** + * Returns the containers for the registered extensions by alias. + * + * @return ExtensionInterface extension container + */ + public function getExtensionConfig($name) + { + if (empty($this->extensionConfigs[$name])) { + return array(array()); + } + + return $this->extensionConfigs[$name]; + } + /** * Sets the extension configs array * diff --git a/src/Symfony/Component/DependencyInjection/Extension/Extension.php b/src/Symfony/Component/DependencyInjection/Extension/Extension.php index bf56be455f1f0..0380c252fac49 100644 --- a/src/Symfony/Component/DependencyInjection/Extension/Extension.php +++ b/src/Symfony/Component/DependencyInjection/Extension/Extension.php @@ -20,24 +20,6 @@ */ abstract class Extension implements ExtensionInterface { - /** - * Loads a specific configuration. - * - * @param string $tag The tag name - * @param array $config An array of configuration values - * @param ContainerBuilder $configuration A ContainerBuilder instance - * - * @throws \InvalidArgumentException When provided tag is not defined in this extension - */ - public function load($tag, array $config, ContainerBuilder $configuration) - { - if (!method_exists($this, $method = $tag.'Load')) { - throw new \InvalidArgumentException(sprintf('The tag "%s:%s" is not defined in the "%s" extension.', $this->getAlias(), $tag, $this->getAlias())); - } - - $this->$method($config, $configuration); - } - /** * This method normalizes keys between the different configuration formats * diff --git a/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php b/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php index c0df405f45072..58befbc087204 100644 --- a/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php +++ b/src/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php @@ -23,15 +23,12 @@ interface ExtensionInterface /** * Loads a specific configuration. * - * @param string $tag The tag name * @param array $config An array of configuration values * @param ContainerBuilder $configuration A ContainerBuilder instance * - * @return ContainerBuilder A ContainerBuilder instance - * * @throws \InvalidArgumentException When provided tag is not defined in this extension */ - function load($tag, array $config, ContainerBuilder $configuration); + function load(array $config, ContainerBuilder $configuration); /** * Returns the namespace to be used for this extension (XML namespace). diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 65def0455f834..3d309845a53b2 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -225,22 +225,14 @@ protected function validate($content, $file) throw new \InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file)); } - foreach (array_keys($content) as $key) { - if (in_array($key, array('imports', 'parameters', 'services', 'interfaces'))) { + foreach (array_keys($content) as $namespace) { + if (in_array($namespace, array('imports', 'parameters', 'services', 'interfaces'))) { continue; } - // can it be handled by an extension? - if (false !== strpos($key, '.')) { - list($namespace, $tag) = explode('.', $key); - if (!$this->container->hasExtension($namespace)) { - throw new \InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s).', $key, $file)); - } - - continue; + if (!$this->container->hasExtension($namespace)) { + throw new \InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s).', $key, $file)); } - - throw new \InvalidArgumentException(sprintf('The "%s" tag is not valid (in %s).', $key, $file)); } return $content; @@ -274,18 +266,16 @@ protected function resolveServices($value) protected function loadFromExtensions($content) { - foreach ($content as $key => $values) { - if (in_array($key, array('imports', 'parameters', 'services', 'interfaces'))) { + foreach ($content as $namespace => $values) { + if (in_array($namespace, array('imports', 'parameters', 'services', 'interfaces'))) { continue; } - list($namespace, $tag) = explode('.', $key); - if (!is_array($values)) { $values = array(); } - $this->container->loadFromExtension($namespace, $tag, $values); + $this->container->loadFromExtension($namespace, $values); } } } From 6d05039864f300ce23b20e2554d8023949afdc1f Mon Sep 17 00:00:00 2001 From: Lukas Kahwe Smith Date: Sat, 5 Feb 2011 21:11:12 +0100 Subject: [PATCH 2/3] only call load() if its actually callable --- .../Compiler/MergeExtensionConfigurationPass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index dc6205a8f0359..35aeebd574da1 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -32,7 +32,7 @@ public function process(ContainerBuilder $container) foreach ($container->getExtensions() as $alias => $extension) { $configs = $container->getExtensionConfig($alias); - if ($configs !== false) { + if ($configs !== false && method_exists($extension, 'load')) { $tmpContainer = new ContainerBuilder($container->getParameterBag()); $tmpContainer->addObjectResource($extension); From 63a3371a39065ac270e124284ad0c31aebc4b4af Mon Sep 17 00:00:00 2001 From: Lukas Kahwe Smith Date: Sat, 5 Feb 2011 22:48:10 +0100 Subject: [PATCH 3/3] also made things work for Xml --- .../Component/DependencyInjection/Loader/XmlFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index ec0a10625ee25..67e3f50c53bb5 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -377,7 +377,7 @@ protected function loadFromExtensions(SimpleXMLElement $xml) $values = array(); } - $this->container->loadFromExtension($node->namespaceURI, $node->localName, $values); + $this->container->loadFromExtension($node->namespaceURI, $values); } }