Просмотр исходного кода

changed all framework extensions to take advantage of the new extension configuration inheritance from previous commit

Fabien Potencier 15 лет назад
Родитель
Сommit
a7e5f81803
20 измененных файлов с 486 добавлено и 160 удалено
  1. 48 57
      src/Symfony/Framework/DoctrineBundle/DependencyInjection/DoctrineExtension.php
  2. 1 0
      src/Symfony/Framework/DoctrineBundle/Resources/config/dbal.xml
  3. 1 0
      src/Symfony/Framework/DoctrineBundle/Resources/config/orm.xml
  4. 49 0
      src/Symfony/Framework/DoctrineBundle/Tests/DependencyInjection/DoctrineExtensionTest.php
  5. 7 6
      src/Symfony/Framework/ProfilerBundle/DependencyInjection/ProfilerExtension.php
  6. 32 0
      src/Symfony/Framework/ProfilerBundle/Tests/DependencyInjection/ProfilerExtensionTest.php
  7. 46 30
      src/Symfony/Framework/PropelBundle/DependencyInjection/PropelExtension.php
  8. 1 0
      src/Symfony/Framework/PropelBundle/Resources/config/propel.xml
  9. 67 0
      src/Symfony/Framework/PropelBundle/Tests/DependencyInjection/PropelExtensionTest.php
  10. 24 20
      src/Symfony/Framework/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php
  11. 1 0
      src/Symfony/Framework/SwiftmailerBundle/Resources/config/swiftmailer.xml
  12. 33 0
      src/Symfony/Framework/SwiftmailerBundle/Tests/DependencyInjection/SwiftmailerExtensionTest.php
  13. 6 6
      src/Symfony/Framework/TwigBundle/DependencyInjection/TwigExtension.php
  14. 7 7
      src/Symfony/Framework/TwigBundle/Resources/config/twig.xml
  15. 33 0
      src/Symfony/Framework/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
  16. 43 26
      src/Symfony/Framework/WebBundle/DependencyInjection/WebExtension.php
  17. 2 0
      src/Symfony/Framework/WebBundle/Resources/config/templating.xml
  18. 46 0
      src/Symfony/Framework/WebBundle/Tests/DependencyInjection/WebExtensionTest.php
  19. 8 8
      src/Symfony/Framework/ZendBundle/DependencyInjection/ZendExtension.php
  20. 31 0
      src/Symfony/Framework/ZendBundle/Tests/DependencyInjection/ZendExtensionTest.php

+ 48 - 57
src/Symfony/Framework/DoctrineBundle/DependencyInjection/DoctrineExtension.php

@@ -26,17 +26,17 @@ use Symfony\Components\DependencyInjection\Reference;
  */
 class DoctrineExtension extends LoaderExtension
 {
-    protected $resources = array(
-        'dbal' => 'dbal.xml',
-        'orm'  => 'orm.xml',
-    );
-
+    protected $resources;
     protected $alias;
     protected $bundleDirs;
     protected $bundles;
 
     public function __construct(array $bundleDirs, array $bundles)
     {
+        $this->resources = array(
+            'dbal' => 'dbal.xml',
+            'orm'  => 'orm.xml',
+        );
         $this->bundleDirs = $bundleDirs;
         $this->bundles = $bundles;
     }
@@ -57,12 +57,12 @@ class DoctrineExtension extends LoaderExtension
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function dbalLoad($config)
+    public function dbalLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['dbal']));
+        if (!$configuration->hasDefinition('doctrine.dbal.logger')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['dbal']));
+        }
 
         $defaultConnection = array(
             'driver'              => 'PDOMySql',
@@ -76,7 +76,9 @@ class DoctrineExtension extends LoaderExtension
             'options'             => array()
         );
 
-        $config['default_connection'] = isset($config['default_connection']) ? $config['default_connection'] : 'default';
+        $defaultConnectionName = isset($config['default_connection']) ? $config['default_connection'] : $configuration->getParameter('doctrine.dbal.default_connection');
+        $configuration->setAlias('database_connection', null !== $this->alias ? $this->alias : sprintf('doctrine.dbal.%s_connection', $defaultConnectionName));
+        $configuration->setParameter('doctrine.dbal.default_connection', $defaultConnectionName);
 
         $connections = array();
         if (isset($config['connections'])) {
@@ -84,35 +86,34 @@ class DoctrineExtension extends LoaderExtension
                 $connections[isset($connection['id']) ? $connection['id'] : $name] = $connection;
             }
         } else {
-            $connections = array($config['default_connection'] => $config);
+            $connections = array($defaultConnectionName => $config);
         }
 
         foreach ($connections as $name => $connection) {
-            $connection = array_merge($defaultConnection, $connection);
-            $configurationClass = isset($connection['configuration_class']) ?
-                $connection['configuration_class'] : 'Doctrine\DBAL\Configuration';
-
-            $configurationDef = new Definition($configurationClass);
-            $configurationDef->addMethodCall('setSqlLogger', array(
-                new Reference('doctrine.dbal.logger')
-            ));
-            $configuration->setDefinition(
-                sprintf('doctrine.dbal.%s_connection.configuration', $name),
-                $configurationDef
-            );
-
-            $eventManagerDef = new Definition($connection['event_manager_class']);
-            $configuration->setDefinition(
-                sprintf('doctrine.dbal.%s_connection.event_manager', $name),
-                $eventManagerDef
-            );
+            // previously registered?
+            if ($configuration->hasDefinition(sprintf('doctrine.dbal.%s_connection', $name))) {
+                $driverDef = $configuration->getDefinition(sprintf('doctrine.dbal.%s_connection', $name));
+                $arguments = $driverDef->getArguments();
+                $driverOptions = $arguments[0];
+            } else {
+                $connection = array_merge($defaultConnection, $connection);
+
+                $configurationClass = isset($connection['configuration_class']) ? $connection['configuration_class'] : 'Doctrine\DBAL\Configuration';
+                $configurationDef = new Definition($configurationClass);
+                $configurationDef->addMethodCall('setSqlLogger', array(new Reference('doctrine.dbal.logger')));
+                $configuration->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), $configurationDef);
+
+                $eventManagerDef = new Definition($connection['event_manager_class']);
+                $configuration->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), $eventManagerDef);
+
+                $driverOptions = array();
+                $driverDef = new Definition('Doctrine\DBAL\DriverManager');
+                $driverDef->setConstructor('getConnection');
+                $configuration->setDefinition(sprintf('doctrine.dbal.%s_connection', $name), $driverDef);
+            }
 
-            $driverOptions = array();
             if (isset($connection['driver'])) {
-                $driverOptions['driverClass'] = sprintf(
-                    'Doctrine\\DBAL\\Driver\\%s\\Driver',
-                    $connection['driver']
-                );
+                $driverOptions['driverClass'] = sprintf('Doctrine\\DBAL\\Driver\\%s\\Driver', $connection['driver']);
             }
             if (isset($connection['wrapper_class'])) {
                 $driverOptions['wrapperClass'] = $connection['wrapper_class'];
@@ -125,22 +126,14 @@ class DoctrineExtension extends LoaderExtension
                     $driverOptions[$key] = $connection[$key];
                 }
             }
-            $driverArgs = array(
+
+            $driverDef->setArguments(array(
                 $driverOptions,
                 new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)),
                 new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name))
-            );
-            $driverDef = new Definition('Doctrine\DBAL\DriverManager', $driverArgs);
-            $driverDef->setConstructor('getConnection');
-            $configuration->setDefinition(sprintf('doctrine.dbal.%s_connection', $name), $driverDef);
+            ));
         }
 
-        $configuration->setAlias('database_connection',
-            null !== $this->alias ? $this->alias : sprintf(
-                'doctrine.dbal.%s_connection', $config['default_connection']
-            )
-        );
-
         return $configuration;
     }
 
@@ -151,28 +144,26 @@ class DoctrineExtension extends LoaderExtension
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function ormLoad($config)
+    public function ormLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
         $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
         $configuration->merge($loader->load($this->resources['orm']));
 
-        $config['default_entity_manager'] = isset($config['default_entity_manager']) ? $config['default_entity_manager'] : 'default';
+        if (isset($config['default_entity_manager'])) {
+            $configuration->getParameter('doctrine.orm.default_entity_manager', $config['default_entity_manager']);
+        }
+        $defaultEntityManager = $configuration->getParameter('doctrine.orm.default_entity_manager');
+
         foreach (array('metadata_driver', 'cache_driver') as $key) {
             if (isset($config[$key])) {
                 $configuration->setParameter('doctrine.orm.'.$key, $config[$key]);
             }
         }
 
-        $config['entity_managers'] = isset($config['entity_managers']) ?
-            $config['entity_managers'] : array($config['default_entity_manager'] => array())
-        ;
+        $config['entity_managers'] = isset($config['entity_managers']) ? $config['entity_managers'] : array($defaultEntityManager => array());
         foreach ($config['entity_managers'] as $name => $connection) {
             $ormConfigDef = new Definition('Doctrine\ORM\Configuration');
-            $configuration->setDefinition(
-                sprintf('doctrine.orm.%s_configuration', $name), $ormConfigDef
-            );
+            $configuration->setDefinition(sprintf('doctrine.orm.%s_configuration', $name), $ormConfigDef);
 
             $drivers = array('metadata', 'query', 'result');
             foreach ($drivers as $driver) {
@@ -249,7 +240,7 @@ class DoctrineExtension extends LoaderExtension
                 $ormEmDef
             );
 
-            if ($name == $config['default_entity_manager']) {
+            if ($name == $defaultEntityManager) {
                 $configuration->setAlias(
                     'doctrine.orm.entity_manager',
                     sprintf('doctrine.orm.%s_entity_manager', $name)

+ 1 - 0
src/Symfony/Framework/DoctrineBundle/Resources/config/dbal.xml

@@ -6,6 +6,7 @@
 
   <parameters>
     <parameter key="doctrine.data_collector.class">Symfony\Framework\DoctrineBundle\DataCollector\DoctrineDataCollector</parameter>
+    <parameter key="doctrine.dbal.default_connection">default</parameter>
   </parameters>
 
   <services>

+ 1 - 0
src/Symfony/Framework/DoctrineBundle/Resources/config/orm.xml

@@ -8,6 +8,7 @@
     <parameter key="doctrine.orm.cache_driver">array</parameter>
     <parameter key="doctrine.orm.cache.memcache.host">localhost</parameter>
     <parameter key="doctrine.orm.cache.memcache.port">11211</parameter>
+    <parameter key="doctrine.orm.default_entity_manager">default</parameter>
   </parameters>
 
   <services>

+ 49 - 0
src/Symfony/Framework/DoctrineBundle/Tests/DependencyInjection/DoctrineExtensionTest.php

@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\DoctrineBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\DoctrineBundle\Tests\TestCase;
+use Symfony\Framework\DoctrineBundle\DependencyInjection\DoctrineExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class DoctrineExtensionTest extends TestCase
+{
+    public function testDbalLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new DoctrineExtension(array(), array());
+
+        $configuration = $loader->dbalLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\DoctrineBundle\\DataCollector\\DoctrineDataCollector', $configuration->getParameter('doctrine.data_collector.class'), '->dbalLoad() loads the dbal.xml file if not already loaded');
+
+        // doctrine.dbal.default_connection
+        $this->assertEquals('default', $configuration->getParameter('doctrine.dbal.default_connection'), '->dbalLoad() overrides existing configuration options');
+        $configuration = $loader->dbalLoad(array('default_connection' => 'foo'), $configuration);
+        $this->assertEquals('foo', $configuration->getParameter('doctrine.dbal.default_connection'), '->dbalLoad() overrides existing configuration options');
+        $configuration = $loader->dbalLoad(array(), $configuration);
+        $this->assertEquals('foo', $configuration->getParameter('doctrine.dbal.default_connection'), '->dbalLoad() overrides existing configuration options');
+
+        $configuration = new BuilderConfiguration();
+        $loader = new DoctrineExtension(array(), array());
+        $configuration = $loader->dbalLoad(array('password' => 'foo'), $configuration);
+
+        $arguments = $configuration->getDefinition('doctrine.dbal.default_connection')->getArguments();
+        $config = $arguments[0];
+
+        $this->assertEquals('foo', $config['password']);
+        $this->assertEquals('root', $config['user']);
+
+        $configuration = $loader->dbalLoad(array('user' => 'foo'), $configuration);
+        $this->assertEquals('foo', $config['password']);
+        $this->assertEquals('root', $config['user']);
+    }
+}

+ 7 - 6
src/Symfony/Framework/ProfilerBundle/DependencyInjection/ProfilerExtension.php

@@ -24,14 +24,15 @@ use Symfony\Components\DependencyInjection\BuilderConfiguration;
  */
 class ProfilerExtension extends LoaderExtension
 {
-    public function configLoad($config)
+    public function configLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load('collectors.xml'));
+        if (!$configuration->hasDefinition('data_collector_manager')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load('collectors.xml'));
+        }
 
-        if (isset($config['toolbar']) && $config['toolbar']) {
+        if (isset($config['toolbar']) && $config['toolbar'] && !$configuration->hasDefinition('debug.toolbar')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
             $configuration->merge($loader->load('toolbar.xml'));
         }
 

+ 32 - 0
src/Symfony/Framework/ProfilerBundle/Tests/DependencyInjection/ProfilerExtensionTest.php

@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\ProfilerBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\ProfilerBundle\Tests\TestCase;
+use Symfony\Framework\ProfilerBundle\DependencyInjection\ProfilerExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class ProfilerExtensionTest extends TestCase
+{
+    public function testLoggerLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new ProfilerExtension();
+
+        $configuration = $loader->configLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\ProfilerBundle\\DataCollector\\DataCollectorManager', $configuration->getParameter('data_collector_manager.class'), '->configLoad() loads the collectors.xml file if not already loaded');
+        $this->assertFalse($configuration->hasParameter('debug.toolbar.class'), '->configLoad() does not load the toolbar.xml file');
+
+        $configuration = $loader->configLoad(array('toolbar' => true), $configuration);
+        $this->assertEquals('Symfony\\Framework\\ProfilerBundle\\Listener\\WebDebugToolbar', $configuration->getParameter('debug.toolbar.class'), '->configLoad() loads the collectors.xml file if the toolbar option is given');
+    }
+}

+ 46 - 30
src/Symfony/Framework/PropelBundle/DependencyInjection/PropelExtension.php

@@ -21,14 +21,20 @@ class PropelExtension extends LoaderExtension
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function configLoad($config)
+    public function configLoad($config, BuilderConfiguration $configuration)
     {
-        if (!isset($config['path'])) {
-            throw new \InvalidArgumentException('The "path" parameter is mandatory.');
+        if (!$configuration->hasParameter('propel.path')) {
+            if (!isset($config['path'])) {
+                throw new \InvalidArgumentException('The "path" parameter is mandatory.');
+            }
+
+            $configuration->setParameter('propel.path', $config['path']);
         }
 
-        $configuration = new BuilderConfiguration();
-        $configuration->setParameter('propel.path', $config['path']);
+        if (isset($config['path']))
+        {
+            $configuration->setParameter('propel.path', $config['path']);
+        }
 
         if (isset($config['phing_path']))
         {
@@ -45,12 +51,12 @@ class PropelExtension extends LoaderExtension
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function dbalLoad($config)
+    public function dbalLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['propel']));
+        if (!$configuration->hasDefinition('propel')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['propel']));
+        }
 
         $defaultConnection = array(
             'driver'              => 'mysql',
@@ -65,7 +71,8 @@ class PropelExtension extends LoaderExtension
             'settings'            => array('charset' => array('value' => 'UTF8')),
         );
 
-        $config['default_connection'] = isset($config['default_connection']) ? $config['default_connection'] : 'default';
+        $defaultConnectionName = isset($config['default_connection']) ? $config['default_connection'] : $configuration->getParameter('propel.dbal.default_connection');
+        $configuration->setParameter('propel.dbal.default_connection', $defaultConnectionName);
 
         $connections = array();
         if (isset($config['connections'])) {
@@ -73,31 +80,40 @@ class PropelExtension extends LoaderExtension
                 $connections[isset($connection['id']) ? $connection['id'] : $name] = $connection;
             }
         } else {
-            $connections = array($config['default_connection'] => $config);
+            $connections = array($defaultConnectionName => $config);
         }
 
-        $c = array(
+        $arguments = $configuration->getDefinition('propel.configuration')->getArguments();
+        if (count($arguments)) {
+            $c = $arguments[0];
+        } else {
+            $c = array(
 // FIXME: should be the same value as %zend.logger.priority%
-            'log'         => array('level' => 7),
-            'datasources' => array(),
-        );
-        foreach ($connections as $name => $connection) {
-            $connection = array_replace($defaultConnection, $connection);
-
-            $c['datasources'][$name] = array(
-              'adapter'    => $connection['driver'],
-              'connection' => array(
-                'dsn'        => $connection['dsn'],
-                'user'       => $connection['user'],
-                'password'   => $connection['password'],
-                'classname'  => $connection['classname'],
-                'options'    => $connection['options'],
-                'attributes' => $connection['attributes'],
-                'settings'   => $connection['settings'],
-              ),
+                'log'         => array('level' => 7),
+                'datasources' => array(),
             );
         }
 
+        foreach ($connections as $name => $connection) {
+            if (isset($c['datasources'][$name])) {
+            } else {
+                $connection = array_replace($defaultConnection, $connection);
+
+                $c['datasources'][$name] = array(
+                  'connection' => array(),
+                );
+            }
+
+            if (isset($connection['driver'])) {
+                $c['datasources'][$name]['adapter'] = $connection['driver'];
+            }
+            foreach (array('dsn', 'user', 'password', 'classname', 'options', 'attributes', 'settings') as $att) {
+                if (isset($connection[$att])) {
+                    $c['datasources'][$name]['connection'][$att] = $connection[$att];
+                }
+            }
+        }
+
         $configuration->getDefinition('propel.configuration')->setArguments(array($c));
 
         return $configuration;

+ 1 - 0
src/Symfony/Framework/PropelBundle/Resources/config/propel.xml

@@ -8,6 +8,7 @@
     <parameter key="propel.class">Propel</parameter>
     <parameter key="propel.configuration.class">PropelConfiguration</parameter>
     <parameter key="propel.logger.class">Symfony\Framework\PropelBundle\Logger\PropelLogger</parameter>
+    <parameter key="propel.dbal.default_connection">default</parameter>
   </parameters>
 
   <services>

+ 67 - 0
src/Symfony/Framework/PropelBundle/Tests/DependencyInjection/PropelExtensionTest.php

@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\PropelBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\PropelBundle\Tests\TestCase;
+use Symfony\Framework\PropelBundle\DependencyInjection\PropelExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class PropelExtensionTest extends TestCase
+{
+    public function testConfigLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new PropelExtension();
+
+        try {
+            $configuration = $loader->configLoad(array(), $configuration);
+            $this->fail();
+        } catch (\Exception $e) {
+            $this->assertInstanceOf('InvalidArgumentException', $e, '->configLoad() throws an \InvalidArgumentException if the Propel path is not set.');
+        }
+
+        $configuration = $loader->configLoad(array('path' => '/propel'), $configuration);
+        $this->assertEquals('/propel', $configuration->getParameter('propel.path'), '->configLoad() sets the Propel path');
+
+        $configuration = $loader->configLoad(array(), $configuration);
+        $this->assertEquals('/propel', $configuration->getParameter('propel.path'), '->configLoad() sets the Propel path');
+    }
+
+    public function testDbalLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new PropelExtension();
+
+        $configuration = $loader->dbalLoad(array(), $configuration);
+        $this->assertEquals('Propel', $configuration->getParameter('propel.class'), '->dbalLoad() loads the propel.xml file if not already loaded');
+
+        // propel.dbal.default_connection
+        $this->assertEquals('default', $configuration->getParameter('propel.dbal.default_connection'), '->dbalLoad() overrides existing configuration options');
+        $configuration = $loader->dbalLoad(array('default_connection' => 'foo'), $configuration);
+        $this->assertEquals('foo', $configuration->getParameter('propel.dbal.default_connection'), '->dbalLoad() overrides existing configuration options');
+        $configuration = $loader->dbalLoad(array(), $configuration);
+        $this->assertEquals('foo', $configuration->getParameter('propel.dbal.default_connection'), '->dbalLoad() overrides existing configuration options');
+
+        $configuration = new BuilderConfiguration();
+        $loader = new PropelExtension();
+        $configuration = $loader->dbalLoad(array('password' => 'foo'), $configuration);
+
+        $arguments = $configuration->getDefinition('propel.configuration')->getArguments();
+        $config = $arguments[0];
+        $this->assertEquals('foo', $config['datasources']['default']['connection']['password']);
+        $this->assertEquals('root', $config['datasources']['default']['connection']['user']);
+
+        $configuration = $loader->dbalLoad(array('user' => 'foo'), $configuration);
+        $this->assertEquals('foo', $config['datasources']['default']['connection']['password']);
+        $this->assertEquals('root', $config['datasources']['default']['connection']['user']);
+    }
+}

+ 24 - 20
src/Symfony/Framework/SwiftmailerBundle/DependencyInjection/SwiftmailerExtension.php

@@ -44,25 +44,31 @@ class SwiftMailerExtension extends LoaderExtension
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function mailerLoad($config)
+    public function mailerLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['mailer']));
-
-        if (isset($config['transport']) && null === $config['transport']) {
-            $config['transport'] = 'null';
-        } elseif (!isset($config['transport'])) {
-            $config['transport'] = 'smtp';
-        } elseif ('gmail' === $config['transport']) {
-            $config['encryption'] = 'ssl';
-            $config['auth_mode'] = 'login';
-            $config['host'] = 'smtp.gmail.com';
-            $config['transport'] = 'smtp';
+        if (!$configuration->hasDefinition('swiftmailer.mailer')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['mailer']));
+            $configuration->setAlias('mailer', 'swiftmailer.mailer');
         }
 
-        $configuration->setAlias('swiftmailer.transport', 'swiftmailer.transport.'.$config['transport']);
+        $transport = $configuration->getParameter('swiftmailer.transport.name');
+        if (array_key_exists('transport', $config)) {
+            if (null === $config['transport']) {
+                $transport = 'null';
+            } elseif ('gmail' === $config['transport']) {
+                $config['encryption'] = 'ssl';
+                $config['auth_mode'] = 'login';
+                $config['host'] = 'smtp.gmail.com';
+                $transport = 'smtp';
+            } else {
+                $transport = $config['transport'];
+            }
+
+            $configuration->setParameter('swiftmailer.transport.name', $transport);
+        }
+
+        $configuration->setAlias('swiftmailer.transport', 'swiftmailer.transport.'.$transport);
 
         if (isset($config['encryption']) && 'ssl' === $config['encryption'] && !isset($config['port'])) {
             $config['port'] = 465;
@@ -70,7 +76,7 @@ class SwiftMailerExtension extends LoaderExtension
 
         foreach (array('encryption', 'port', 'host', 'username', 'password', 'auth_mode') as $key) {
             if (isset($config[$key])) {
-                $configuration->setParameter('swiftmailer.transport.'.$config['transport'].'.'.$key, $config[$key]);
+                $configuration->setParameter('swiftmailer.transport.'.$transport.'.'.$key, $config[$key]);
             }
         }
 
@@ -78,7 +84,7 @@ class SwiftMailerExtension extends LoaderExtension
         if (isset($config['spool'])) {
             $type = isset($config['type']) ? $config['type'] : 'file';
 
-            $configuration->setAlias('swiftmailer.transport.real', 'swiftmailer.transport.'.$config['transport']);
+            $configuration->setAlias('swiftmailer.transport.real', 'swiftmailer.transport.'.$transport);
             $configuration->setAlias('swiftmailer.transport', 'swiftmailer.transport.spool');
             $configuration->setAlias('swiftmailer.spool', 'swiftmailer.spool.'.$type);
 
@@ -98,8 +104,6 @@ class SwiftMailerExtension extends LoaderExtension
             $configuration->findDefinition('swiftmailer.transport')->addMethodCall('registerPlugin', array(new Reference('swiftmailer.plugin.blackhole')));
         }
 
-        $configuration->setAlias('mailer', 'swiftmailer.mailer');
-
         return $configuration;
     }
 

+ 1 - 0
src/Symfony/Framework/SwiftmailerBundle/Resources/config/swiftmailer.xml

@@ -7,6 +7,7 @@
   <parameters>
     <parameter key="swiftmailer.class">Swift_Mailer</parameter>
 
+    <parameter key="swiftmailer.transport.name">smtp</parameter>
     <parameter key="swiftmailer.transport.smtp.class">Swift_Transport_EsmtpTransport</parameter>
     <parameter key="swiftmailer.transport.sendmail.class">Swift_Transport_SendmailTransport</parameter>
     <parameter key="swiftmailer.transport.mail.class">Swift_Transport_MailTransport</parameter>

+ 33 - 0
src/Symfony/Framework/SwiftmailerBundle/Tests/DependencyInjection/SwiftmailerExtensionTest.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\SwiftmailerBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\SwiftmailerBundle\Tests\TestCase;
+use Symfony\Framework\SwiftmailerBundle\DependencyInjection\SwiftmailerExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class SwiftmailerExtensionTest extends TestCase
+{
+    public function testMailerLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new SwiftmailerExtension();
+
+        $configuration = $loader->mailerLoad(array(), $configuration);
+        $this->assertEquals('Swift_Mailer', $configuration->getParameter('swiftmailer.class'), '->mailerLoad() loads the swiftmailer.xml file if not already loaded');
+
+        $configuration = $loader->mailerLoad(array('transport' => 'sendmail'), $configuration);
+        $this->assertEquals('sendmail', $configuration->getParameter('swiftmailer.transport.name'), '->mailerLoad() overrides existing configuration options');
+        $configuration = $loader->mailerLoad(array(), $configuration);
+        $this->assertEquals('sendmail', $configuration->getParameter('swiftmailer.transport.name'), '->mailerLoad() overrides existing configuration options');
+    }
+}

+ 6 - 6
src/Symfony/Framework/TwigBundle/DependencyInjection/TwigExtension.php

@@ -24,14 +24,14 @@ use Symfony\Components\DependencyInjection\BuilderConfiguration;
  */
 class TwigExtension extends LoaderExtension
 {
-    public function configLoad($config)
+    public function configLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
+        if (!$configuration->hasDefinition('twig')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load('twig.xml'));
+        }
 
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load('twig.xml'));
-
-        $configuration->setParameter('twig_options', array_replace($configuration->getParameter('twig_options'), $config));
+        $configuration->setParameter('twig.options', array_replace($configuration->getParameter('twig.options'), $config));
 
         return $configuration;
     }

+ 7 - 7
src/Symfony/Framework/TwigBundle/Resources/config/twig.xml

@@ -6,29 +6,29 @@
 
   <parameters>
     <parameter key="twig.class">Symfony\Framework\TwigBundle\Environment</parameter>
-    <parameter key="twig_options" type="collection">
+    <parameter key="twig.options" type="collection">
         <parameter key="charset">%kernel.charset%</parameter>
         <parameter key="debug">%kernel.debug%</parameter>
         <parameter key="cache">%kernel.cache_dir%/twig</parameter>
     </parameter>
-    <parameter key="twig_loader.class">Symfony\Framework\TwigBundle\Loader\Loader</parameter>
-    <parameter key="twig_renderer.class">Symfony\Framework\TwigBundle\Renderer\Renderer</parameter>
+    <parameter key="twig.loader.class">Symfony\Framework\TwigBundle\Loader\Loader</parameter>
+    <parameter key="twig.renderer.class">Symfony\Framework\TwigBundle\Renderer\Renderer</parameter>
   </parameters>
 
   <services>
     <service id="twig" class="%twig.class%">
       <argument type="service" id="service_container" />
-      <argument type="service" id="twig_loader" />
-      <argument>%twig_options%</argument>
+      <argument type="service" id="twig.loader" />
+      <argument>%twig.options%</argument>
     </service>
 
-    <service id="twig_loader" class="%twig_loader.class%">
+    <service id="twig_loader" class="%twig.loader.class%">
       <call method="setEngine">
         <argument type="service" id="templating" />
       </call>
     </service>
 
-    <service id="twig_renderer" class="%twig_renderer.class%">
+    <service id="twig_renderer" class="%twig.renderer.class%">
       <annotation name="templating.renderer" alias="twig" />
       <argument type="service" id="twig" />
     </service>

+ 33 - 0
src/Symfony/Framework/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\TwigBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\TwigBundle\Tests\TestCase;
+use Symfony\Framework\TwigBundle\DependencyInjection\TwigExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class TwigExtensionTest extends TestCase
+{
+    public function testConfigLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new TwigExtension();
+
+        $configuration = $loader->configLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\TwigBundle\\Environment', $configuration->getParameter('twig.class'), '->configLoad() loads the twig.xml file if not already loaded');
+
+        $configuration = $loader->configLoad(array('charset' => 'ISO-8859-1'), $configuration);
+        $options = $configuration->getParameter('twig.options');
+        $this->assertEquals('ISO-8859-1', $options['charset'], '->configLoad() overrides existing configuration options');
+        $this->assertEquals('%kernel.debug%', $options['debug'], '->configLoad() merges the new values with the old ones');
+    }
+}

+ 43 - 26
src/Symfony/Framework/WebBundle/DependencyInjection/WebExtension.php

@@ -31,12 +31,20 @@ class WebExtension extends LoaderExtension
         'user'       => 'user.xml',
     );
 
-    public function webLoad($config)
+    /**
+     * Loads the web configuration.
+     *
+     * @param array                $config        A configuration array
+     * @param BuilderConfiguration $configuration A BuilderConfiguration instance
+     *
+     * @return BuilderConfiguration A BuilderConfiguration instance
+     */
+    public function webLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['web']));
+        if (!$configuration->hasDefinition('controller_manager')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['web']));
+        }
 
         if (isset($config['ide']) && 'textmate' === $config['ide']) {
             $configuration->setParameter('debug.file_link_format', 'txmt://open?url=file://%%f&line=%%l');
@@ -45,12 +53,20 @@ class WebExtension extends LoaderExtension
         return $configuration;
     }
 
-    public function userLoad($config)
+    /**
+     * Loads the user configuration.
+     *
+     * @param array                $config        A configuration array
+     * @param BuilderConfiguration $configuration A BuilderConfiguration instance
+     *
+     * @return BuilderConfiguration A BuilderConfiguration instance
+     */
+    public function userLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['user']));
+        if (!$configuration->hasDefinition('user')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['user']));
+        }
 
         if (isset($config['default_culture'])) {
             $configuration->setParameter('user.default_culture', $config['default_culture']);
@@ -85,15 +101,20 @@ class WebExtension extends LoaderExtension
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function templatingLoad($config)
+    public function templatingLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
+        if (!$configuration->hasDefinition('templating')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['templating']));
+        }
 
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['templating']));
+        if (array_key_exists('escaping', $config)) {
+            $configuration->setParameter('templating.output_escaper', $config['escaping']);
+        }
 
-        $configuration->setParameter('templating.output_escaper', array_key_exists('escaping', $config) ? $config['escaping'] : false);
-        $configuration->setParameter('templating.assets.version', array_key_exists('assets_version', $config) ? $config['assets_version'] : null);
+        if (array_key_exists('assets_version', $config)) {
+            $configuration->setParameter('templating.assets.version', $config['assets_version']);
+        }
 
         // path for the filesystem loader
         if (isset($config['path'])) {
@@ -107,17 +128,13 @@ class WebExtension extends LoaderExtension
             foreach ($ids as $id) {
                 $loaders[] = new Reference($id);
             }
-        } else {
-            $loaders = array(
-                new Reference('templating.loader.filesystem'),
-            );
-        }
 
-        if (1 === count($loaders)) {
-            $configuration->setAlias('templating.loader', (string) $loaders[0]);
-        } else {
-            $configuration->getDefinition('templating.loader.chain')->addArgument($loaders);
-            $configuration->setAlias('templating.loader', 'templating.loader.chain');
+            if (1 === count($loaders)) {
+                $configuration->setAlias('templating.loader', (string) $loaders[0]);
+            } else {
+                $configuration->getDefinition('templating.loader.chain')->addArgument($loaders);
+                $configuration->setAlias('templating.loader', 'templating.loader.chain');
+            }
         }
 
         // cache?

+ 2 - 0
src/Symfony/Framework/WebBundle/Resources/config/templating.xml

@@ -17,6 +17,8 @@
     <parameter key="templating.helper.router.class">Symfony\Framework\WebBundle\Helper\RouterHelper</parameter>
     <parameter key="templating.helper.request.class">Symfony\Framework\WebBundle\Helper\RequestHelper</parameter>
     <parameter key="templating.helper.user.class">Symfony\Framework\WebBundle\Helper\UserHelper</parameter>
+    <parameter key="templating.output_escaper">false</parameter>
+    <parameter key="templating.assets.version">null</parameter>
   </parameters>
 
   <services>

+ 46 - 0
src/Symfony/Framework/WebBundle/Tests/DependencyInjection/WebExtensionTest.php

@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\WebBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\WebBundle\Tests\TestCase;
+use Symfony\Framework\WebBundle\DependencyInjection\WebExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class WebExtensionTest extends TestCase
+{
+    public function testWebLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new WebExtension();
+
+        $configuration = $loader->webLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\WebBundle\\Listener\\RequestParser', $configuration->getParameter('request_parser.class'), '->webLoad() loads the web.xml file if not already loaded');
+    }
+
+    public function testUserLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new WebExtension();
+
+        $configuration = $loader->userLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\WebBundle\\User', $configuration->getParameter('user.class'), '->userLoad() loads the user.xml file if not already loaded');
+    }
+
+    public function testTemplatingLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new WebExtension();
+
+        $configuration = $loader->templatingLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\WebBundle\\Templating\\Engine', $configuration->getParameter('templating.engine.class'), '->templatingLoad() loads the templating.xml file if not already loaded');
+    }
+}

+ 8 - 8
src/Symfony/Framework/ZendBundle/DependencyInjection/ZendExtension.php

@@ -35,16 +35,18 @@ class ZendExtension extends LoaderExtension
      *
      *      <zend:logger priority="info" path="/path/to/some.log" />
      *
-     * @param array $config A configuration array
+     * @param array                $config        A configuration array
+     * @param BuilderConfiguration $configuration A BuilderConfiguration instance
      *
      * @return BuilderConfiguration A BuilderConfiguration instance
      */
-    public function loggerLoad($config)
+    public function loggerLoad($config, BuilderConfiguration $configuration)
     {
-        $configuration = new BuilderConfiguration();
-
-        $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
-        $configuration->merge($loader->load($this->resources['logger']));
+        if (!$configuration->hasDefinition('zend.logger')) {
+            $loader = new XmlFileLoader(__DIR__.'/../Resources/config');
+            $configuration->merge($loader->load($this->resources['logger']));
+            $configuration->setAlias('logger', 'zend.logger');
+        }
 
         if (isset($config['priority'])) {
             $configuration->setParameter('zend.logger.priority', is_int($config['priority']) ? $config['priority'] : constant('\Zend_Log::'.strtoupper($config['priority'])));
@@ -54,8 +56,6 @@ class ZendExtension extends LoaderExtension
             $configuration->setParameter('zend.logger.path', $config['path']);
         }
 
-        $configuration->setAlias('logger', 'zend.logger');
-
         return $configuration;
     }
 

+ 31 - 0
src/Symfony/Framework/ZendBundle/Tests/DependencyInjection/ZendExtensionTest.php

@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Framework\ZendBundle\Tests\DependencyInjection;
+
+use Symfony\Framework\ZendBundle\Tests\TestCase;
+use Symfony\Framework\ZendBundle\DependencyInjection\ZendExtension;
+use Symfony\Components\DependencyInjection\BuilderConfiguration;
+
+class ZendExtensionTest extends TestCase
+{
+    public function testLoggerLoad()
+    {
+        $configuration = new BuilderConfiguration();
+        $loader = new ZendExtension();
+
+        $configuration = $loader->loggerLoad(array(), $configuration);
+        $this->assertEquals('Symfony\\Framework\\ZendBundle\\Logger\\Logger', $configuration->getParameter('zend.logger.class'), '->loggerLoad() loads the logger.xml file if not already loaded');
+
+        $configuration = $loader->loggerLoad(array('priority' => 3), $configuration);
+        $this->assertEquals(3, $configuration->getParameter('zend.logger.priority'), '->loggerLoad() overrides existing configuration options');
+    }
+}