Преглед на файлове

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

Fabien Potencier преди 15 години
родител
ревизия
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');
+    }
+}