Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension load #589

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -29,6 +29,28 @@
*/ */
class DoctrineExtension extends AbstractDoctrineExtension 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. * Loads the DBAL configuration.
* *
Expand All @@ -39,7 +61,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
* @param array $config An array of configuration settings * @param array $config An array of configuration settings
* @param ContainerBuilder $container A ContainerBuilder instance * @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 = new XmlFileLoader($container, __DIR__.'/../Resources/config');
$loader->load('dbal.xml'); $loader->load('dbal.xml');
Expand Down Expand Up @@ -229,7 +251,7 @@ protected function loadDbalConnection(array $connection, ContainerBuilder $conta
* @param array $config An array of configuration settings * @param array $config An array of configuration settings
* @param ContainerBuilder $container A ContainerBuilder instance * @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 = new XmlFileLoader($container, __DIR__.'/../Resources/config');
$loader->load('orm.xml'); $loader->load('orm.xml');
Expand Down
Expand Up @@ -28,10 +28,7 @@ class AddClassesToAutoloadMapPass implements CompilerPassInterface
public function process(ContainerBuilder $container) public function process(ContainerBuilder $container)
{ {
$classes = array(); $classes = array();
foreach ($container->getExtensionConfigs() as $name => $configs) { foreach ($container->getExtensions() as $extension) {
list($namespace, $tag) = explode(':', $name);

$extension = $container->getExtension($namespace);
if ($extension instanceof Extension) { if ($extension instanceof Extension) {
$classes = array_merge($classes, $extension->getAutoloadClassMap()); $classes = array_merge($classes, $extension->getAutoloadClassMap());
} }
Expand Down
Expand Up @@ -28,10 +28,7 @@ class AddClassesToCachePass implements CompilerPassInterface
public function process(ContainerBuilder $container) public function process(ContainerBuilder $container)
{ {
$classes = array(); $classes = array();
foreach ($container->getExtensionConfigs() as $name => $configs) { foreach ($container->getExtensions() as $extension) {
list($namespace, $tag) = explode(':', $name);

$extension = $container->getExtension($namespace);
if ($extension instanceof Extension) { if ($extension instanceof Extension) {
$classes = array_merge($classes, $extension->getClassesToCompile()); $classes = array_merge($classes, $extension->getClassesToCompile());
} }
Expand Down
Expand Up @@ -29,7 +29,7 @@
*/ */
class FrameworkExtension extends Extension class FrameworkExtension extends Extension
{ {
public function configLoad(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container)
{ {
foreach ($configs as $config) { foreach ($configs as $config) {
$this->doConfigLoad($config, $container); $this->doConfigLoad($config, $container);
Expand Down
Expand Up @@ -35,17 +35,15 @@ class SecurityExtension extends Extension
protected $contextListeners = array(); protected $contextListeners = array();
protected $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me'); 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) { 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) $this->doConfigLoad($this->normalizeKeys($config), $container);
{
foreach ($configs as $config) {
$this->doAclLoad($this->normalizeKeys($config), $container);
} }
} }


Expand Down
Expand Up @@ -23,7 +23,7 @@
*/ */
class SwiftMailerExtension extends Extension class SwiftMailerExtension extends Extension
{ {
public function configLoad(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container)
{ {
foreach ($configs as $config) { foreach ($configs as $config) {
$this->doConfigLoad($config, $container); $this->doConfigLoad($config, $container);
Expand Down
Expand Up @@ -23,7 +23,7 @@
*/ */
class TwigExtension extends Extension 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 = new XmlFileLoader($container, __DIR__.'/../Resources/config');
$loader->load('twig.xml'); $loader->load('twig.xml');
Expand Down
Expand Up @@ -32,7 +32,7 @@
*/ */
class WebProfilerExtension extends Extension class WebProfilerExtension extends Extension
{ {
public function configLoad(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container)
{ {
foreach ($configs as $config) { foreach ($configs as $config) {
$this->doConfigLoad($config, $container); $this->doConfigLoad($config, $container);
Expand Down
Expand Up @@ -34,7 +34,7 @@ class ZendExtension extends Extension
* @param array $config An array of configuration settings * @param array $config An array of configuration settings
* @param ContainerBuilder $container A ContainerBuilder instance * @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 = new XmlFileLoader($container, __DIR__.'/../Resources/config');
$loader->load('logger.xml'); $loader->load('logger.xml');
Expand Down
Expand Up @@ -29,17 +29,17 @@ public function process(ContainerBuilder $container)
$definitions = $container->getDefinitions(); $definitions = $container->getDefinitions();
$aliases = $container->getAliases(); $aliases = $container->getAliases();


foreach ($container->getExtensionConfigs() as $name => $configs) { foreach ($container->getExtensions() as $alias => $extension) {
list($namespace, $tag) = explode(':', $name);


$extension = $container->getExtension($namespace); $configs = $container->getExtensionConfig($alias);
if ($configs !== false && method_exists($extension, 'load')) {
$tmpContainer = new ContainerBuilder($container->getParameterBag());
$tmpContainer->addObjectResource($extension);


$tmpContainer = new ContainerBuilder($container->getParameterBag()); $extension->load($configs, $tmpContainer);
$tmpContainer->addObjectResource($extension);


$extension->load($tag, $configs, $tmpContainer); $container->merge($tmpContainer);

}
$container->merge($tmpContainer);
} }


$container->addDefinitions($definitions); $container->addDefinitions($definitions);
Expand Down
46 changes: 37 additions & 9 deletions src/Symfony/Component/DependencyInjection/ContainerBuilder.php
Expand Up @@ -28,6 +28,7 @@
class ContainerBuilder extends Container implements TaggedContainerInterface class ContainerBuilder extends Container implements TaggedContainerInterface
{ {
static protected $extensions = array(); static protected $extensions = array();
static protected $extensionsByNs = array();


protected $definitions = array(); protected $definitions = array();
protected $aliases = array(); protected $aliases = array();
Expand All @@ -53,7 +54,7 @@ public function __construct(ParameterBagInterface $parameterBag = null)
*/ */
static public function registerExtension(ExtensionInterface $extension) static public function registerExtension(ExtensionInterface $extension)
{ {
static::$extensions[$extension->getAlias()] = static::$extensions[$extension->getNamespace()] = $extension; static::$extensions[$extension->getAlias()] = static::$extensionsByNs[$extension->getNamespace()] = $extension;
} }


/** /**
Expand All @@ -65,16 +66,30 @@ static public function registerExtension(ExtensionInterface $extension)
*/ */
static public function getExtension($name) static public function getExtension($name)
{ {
if (!isset(static::$extensions[$name])) { if (empty(static::$extensions[$name])) {
throw new \LogicException(sprintf('Container extension "%s" is not registered', $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]; return static::$extensions[$name];
} }


/**
* Returns extensions keyed by alias
*
* @return array ExtensionInterfaces
*/
static public function getExtensions()
{
return static::$extensions;
}

static public function hasExtension($name) static public function hasExtension($name)
{ {
return isset(static::$extensions[$name]); return isset(static::$extensions[$name]) || isset(static::$extensionsByNs[$name]);
} }


/** /**
Expand Down Expand Up @@ -118,24 +133,23 @@ public function addObjectResource($object)
* Loads the configuration for an extension. * Loads the configuration for an extension.
* *
* @param string $extension The extension alias or namespace * @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 * @param array $values An array of values that customizes the extension
* *
* @return ContainerBuilder The current instance * @return ContainerBuilder The current instance
*/ */
public function loadFromExtension($extension, $tag, array $values = array()) public function loadFromExtension($extension, array $values = array())
{ {
if (true === $this->isFrozen()) { if (true === $this->isFrozen()) {
throw new \LogicException('Cannot load from an extension on a frozen container.'); throw new \LogicException('Cannot load from an extension on a frozen container.');
} }


$namespace = $this->getExtension($extension)->getAlias(); $namespace = $this->getExtension($extension)->getAlias();


if (!isset($this->extensionConfigs[$namespace.':'.$tag])) { if (!isset($this->extensionConfigs[$namespace])) {
$this->extensionConfigs[$namespace.':'.$tag] = array(); $this->extensionConfigs[$namespace] = array();
} }


$this->extensionConfigs[$namespace.':'.$tag][] = $this->getParameterBag()->resolveValue($values); $this->extensionConfigs[$namespace][] = $this->getParameterBag()->resolveValue($values);


return $this; return $this;
} }
Expand Down Expand Up @@ -340,6 +354,20 @@ public function getExtensionConfigs()
return $this->extensionConfigs; 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 * Sets the extension configs array
* *
Expand Down
18 changes: 0 additions & 18 deletions src/Symfony/Component/DependencyInjection/Extension/Extension.php
Expand Up @@ -20,24 +20,6 @@
*/ */
abstract class Extension implements ExtensionInterface 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 * This method normalizes keys between the different configuration formats
* *
Expand Down
Expand Up @@ -23,15 +23,12 @@ interface ExtensionInterface
/** /**
* Loads a specific configuration. * Loads a specific configuration.
* *
* @param string $tag The tag name
* @param array $config An array of configuration values * @param array $config An array of configuration values
* @param ContainerBuilder $configuration A ContainerBuilder instance * @param ContainerBuilder $configuration A ContainerBuilder instance
* *
* @return ContainerBuilder A ContainerBuilder instance
*
* @throws \InvalidArgumentException When provided tag is not defined in this extension * @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). * Returns the namespace to be used for this extension (XML namespace).
Expand Down
Expand Up @@ -377,7 +377,7 @@ protected function loadFromExtensions(SimpleXMLElement $xml)
$values = array(); $values = array();
} }


$this->container->loadFromExtension($node->namespaceURI, $node->localName, $values); $this->container->loadFromExtension($node->namespaceURI, $values);
} }
} }


Expand Down
Expand Up @@ -225,22 +225,14 @@ protected function validate($content, $file)
throw new \InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file)); throw new \InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file));
} }


foreach (array_keys($content) as $key) { foreach (array_keys($content) as $namespace) {
if (in_array($key, array('imports', 'parameters', 'services', 'interfaces'))) { if (in_array($namespace, array('imports', 'parameters', 'services', 'interfaces'))) {
continue; continue;
} }


// can it be handled by an extension? if (!$this->container->hasExtension($namespace)) {
if (false !== strpos($key, '.')) { throw new \InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s).', $key, $file));
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;
} }

throw new \InvalidArgumentException(sprintf('The "%s" tag is not valid (in %s).', $key, $file));
} }


return $content; return $content;
Expand Down Expand Up @@ -274,18 +266,16 @@ protected function resolveServices($value)


protected function loadFromExtensions($content) protected function loadFromExtensions($content)
{ {
foreach ($content as $key => $values) { foreach ($content as $namespace => $values) {
if (in_array($key, array('imports', 'parameters', 'services', 'interfaces'))) { if (in_array($namespace, array('imports', 'parameters', 'services', 'interfaces'))) {
continue; continue;
} }


list($namespace, $tag) = explode('.', $key);

if (!is_array($values)) { if (!is_array($values)) {
$values = array(); $values = array();
} }


$this->container->loadFromExtension($namespace, $tag, $values); $this->container->loadFromExtension($namespace, $values);
} }
} }
} }