소스 검색

[DoctrineBundle] Use a Merge Config algorithm for the ORM bundle. Simplified configuration and got rid of unnecessary ways to configure the same thing in several different ways.

Benjamin Eberlei 14 년 전
부모
커밋
29888a4a1d

+ 154 - 193
src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php

@@ -127,7 +127,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
             }
             
             foreach ($configConnections as $name => $connection) {
-                $connectionName = isset($connection['id']) ? $connection['id'] : $name;
+                $connectionName = isset($connection['name']) ? $connection['name'] : $name;
                 if (!isset($mergedConfig['connections'][$connectionName])) {
                     $mergedConfig['connections'][$connectionName] = $connectionDefaults;
                 }
@@ -202,13 +202,6 @@ class DoctrineExtension extends AbstractDoctrineExtension
         ));
     }
 
-    public function ormLoad(array $configs, ContainerBuilder $container)
-    {
-        foreach ($configs as $config) {
-            $this->doOrmLoad($config, $container);
-        }
-    }
-
     /**
      * Loads the Doctrine ORM configuration.
      *
@@ -219,64 +212,129 @@ class DoctrineExtension extends AbstractDoctrineExtension
      * @param array $config An array of configuration settings
      * @param ContainerBuilder $container A ContainerBuilder instance
      */
-    protected function doOrmLoad($config, ContainerBuilder $container)
+    public function ormLoad(array $configs, ContainerBuilder $container)
     {
-        $this->loadOrmDefaults($config, $container);
-        $this->loadOrmEntityManagers($config, $container);
-    }
+        $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
+        $loader->load('orm.xml');
 
-    /**
-     * Loads the ORM default configuration.
-     *
-     * @param array $config An array of configuration settings
-     * @param ContainerBuilder $container A ContainerBuilder instance
-     */
-    protected function loadOrmDefaults(array $config, ContainerBuilder $container)
-    {
-        // arbitrary service that is always part of the "orm" services. Its used to check if the
-        // defaults have to applied (first time run) or ignored (second or n-th run due to imports)
-        if (!$container->hasDefinition('doctrine.orm.metadata.annotation_reader')) {
-            $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
-            $loader->load('orm.xml');
+        $config = $this->mergeOrmConfig($configs, $container);
+        
+        $options = array('default_entity_manager', 'default_connection');
+        foreach ($options as $key) {
+            $container->setParameter('doctrine.orm.'.$key, $config[$key]);
         }
 
-        // Allow these application configuration options to override the defaults
-        $options = array(
-            'default_entity_manager',
-            'default_connection',
-            'metadata_cache_driver',
-            'query_cache_driver',
-            'result_cache_driver',
-            'proxy_namespace',
-            'proxy_dir',
-            'auto_generate_proxy_classes',
-            'class_metadata_factory_name',
-        );
-        foreach ($options as $key) {
-            if (isset($config[$key])) {
-                $container->setParameter('doctrine.orm.'.$key, $config[$key]);
-            }
+        foreach ($config['entity_managers'] as $entityManager) {
+            $this->loadOrmEntityManager($entityManager, $container);
 
-            $nKey = str_replace('_', '-', $key);
-            if (isset($config[$nKey])) {
-                $container->setParameter('doctrine.orm.'.$key, $config[$nKey]);
+            if ($entityManager['name'] == $config['default_entity_manager']) {
+                $container->setAlias(
+                    'doctrine.orm.entity_manager',
+                    sprintf('doctrine.orm.%s_entity_manager', $entityManager['name'])
+                );
             }
         }
     }
 
-    /**
-     * Loads the configured ORM entity managers.
-     *
-     * @param array $config An array of configuration settings
-     * @param ContainerBuilder $container A ContainerBuilder instance
-     */
-    protected function loadOrmEntityManagers(array $config, ContainerBuilder $container)
+    protected function mergeOrmConfig(array $configs, $container)
     {
-        $entityManagers = $this->getOrmEntityManagers($config, $container);
-        foreach ($entityManagers as $name => $entityManager) {
-            $entityManager['name'] = $name;
-            $this->loadOrmEntityManager($entityManager, $container);
+        $supportedEntityManagerOptions = array(
+            'metadata_cache_driver'             => 'metadata_cache_driver',
+            'query_cache_driver'                => 'query_cache_driver',
+            'result_cache_driver'               => 'result_cache_driver',
+            'class_metadata_factory_name'       => 'class_metadata_factory_name',
+            'metadata-cache-driver'             => 'metadata_cache_driver',
+            'query-cache-driver'                => 'query_cache_driver',
+            'result-cache-driver'               => 'result_cache_driver',
+            'class-metadata-factory-name'       => 'class_metadata_factory_name',
+            'connection'                        => 'connection'
+        );
+
+        $mergedConfig = array(
+            'default_entity_manager' => 'default',
+            'default_connection' => 'default',
+            'entity_managers' => array(),
+        );
+
+        $defaultManagerOptions = array(
+            'proxy_dir'                     => $container->getParameter('doctrine.orm.proxy_dir'),
+            'proxy_namespace'               => $container->getParameter('doctrine.orm.proxy_namespace'),
+            'auto_generate_proxy_classes'   => false,
+            'metadata_cache_driver'         => $container->getParameter('doctrine.orm.metadata_cache_driver'),
+            'query_cache_driver'            => $container->getParameter('doctrine.orm.query_cache_driver'),
+            'result_cache_driver'           => $container->getParameter('doctrine.orm.result_cache_driver'),
+            'configuration_class'           => $container->getParameter('doctrine.orm.configuration_class'),
+            'entity_manager_class'          => $container->getParameter('doctrine.orm.entity_manager_class'),
+            'class_metadata_factory_name'   => $container->getParameter('doctrine.orm.class_metadata_factory_name'),
+        );
+        
+        foreach ($configs AS $config) {
+            if (isset($config['default-entity-manager'])) {
+                $mergedConfig['default_entity_manager'] = $config['default-entity-manager'];
+            } else if (isset($config['default_entity_manager'])) {
+                $mergedConfig['default_entity_manager'] = $config['default_entity_manager'];
+            }
+            if (isset($config['default-connection'])) {
+                $mergedConfig['default_connection'] = $config['default-connection'];
+            } else if (isset($config['default_connection'])) {
+                $mergedConfig['default_connection'] = $config['default_connection'];
+            }
+        }
+        $defaultManagerOptions['connection'] = $mergedConfig['default_connection'];
+
+        foreach ($configs AS $config) {
+            if (isset($config['entity-managers'])) {
+                $config['entity_managers'] = $config['entity-managers'];
+            }
+
+            $entityManagers = array();
+            if (isset($config['entity_managers'])) {
+                $configEntityManagers = $config['entity_managers'];
+                if (isset($config['entity_managers']['entity-manager'])) {
+                    $config['entity_managers']['entity_manager'] = $config['entity_managers']['entity-manager'];
+                }
+                if (isset($config['entity_managers']['entity_manager']) && isset($config['entity_managers']['entity_manager'][0])) {
+                    $configEntityManagers = $config['entity_managers']['entity_manager'];
+                }
+                
+                foreach ($configEntityManagers as $name => $entityManager) {
+                    $name = isset($entityManager['name']) ? $entityManager['name'] : $name;
+                    $entityManagers[$name] = $entityManager;
+                }
+            } else {
+                $entityManagers = array($mergedConfig['default_entity_manager'] => $config);
+            }
+
+            foreach ($entityManagers AS $name => $managerConfig) {
+                if (!isset($mergedConfig['entity_managers'][$name])) {
+                    $mergedConfig['entity_managers'][$name] = $defaultManagerOptions;
+                }
+
+                foreach ($managerConfig AS $k => $v) {
+                    if (isset($supportedEntityManagerOptions[$k])) {
+                        $k = $supportedEntityManagerOptions[$k];
+                        $mergedConfig['entity_managers'][$name][$k] = $v;
+                    }
+                }
+                $mergedConfig['entity_managers'][$name]['name'] = $name;
+
+                if (isset($managerConfig['mappings'])) {
+                    foreach ($managerConfig['mappings'] AS $mappingName => $mappingConfig) {
+                        if (!isset($mergedConfig['entity_managers'][$name]['mappings'][$mappingName])) {
+                            $mergedConfig['entity_managers'][$name]['mappings'][$mappingName] = array();
+                        }
+
+                        if (is_array($mappingConfig)) {
+                            foreach ($mappingConfig AS $k => $v) {
+                                $mergedConfig['entity_managers'][$name]['mappings'][$mappingName][$k] = $v;
+                            }
+                        }
+                    }
+                }
+            }
         }
+
+        return $mergedConfig;
     }
 
     /**
@@ -286,23 +344,18 @@ class DoctrineExtension extends AbstractDoctrineExtension
      * There are two possible runtime scenarios:
      *
      * 1. If the EntityManager was defined before, override only the new calls to Doctrine\ORM\Configuration
-     * 2. If the EntityManager was not defined before, gather all the defaults for not specified options and set all the information.
+     * 2. If the EntityManager was not defined beforeefore, gather all the defaults for not specified options and set all the information.
      *
      * @param array $entityManager A configured ORM entity manager.
      * @param ContainerBuilder $container A ContainerBuilder instance
      */
     protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container)
     {
-        $defaultEntityManager = $container->getParameter('doctrine.orm.default_entity_manager');
         $configServiceName = sprintf('doctrine.orm.%s_configuration', $entityManager['name']);
 
-        if ($container->hasDefinition($configServiceName)) {
-            $ormConfigDef = $container->getDefinition($configServiceName);
-        } else {
-            $ormConfigDef = new Definition('Doctrine\ORM\Configuration');
-            $ormConfigDef->setPublic(false);
-            $container->setDefinition($configServiceName, $ormConfigDef);
-        }
+        $ormConfigDef = new Definition('Doctrine\ORM\Configuration');
+        $ormConfigDef->setPublic(false);
+        $container->setDefinition($configServiceName, $ormConfigDef);
 
         $this->loadOrmEntityManagerMappingInformation($entityManager, $ormConfigDef, $container);
         $this->loadOrmCacheDrivers($entityManager, $container);
@@ -312,76 +365,31 @@ class DoctrineExtension extends AbstractDoctrineExtension
             'setQueryCacheImpl'             => new Reference(sprintf('doctrine.orm.%s_query_cache', $entityManager['name'])),
             'setResultCacheImpl'            => new Reference(sprintf('doctrine.orm.%s_result_cache', $entityManager['name'])),
             'setMetadataDriverImpl'         => new Reference('doctrine.orm.'.$entityManager['name'].'_metadata_driver'),
-            'setProxyDir'                   => $container->getParameter('doctrine.orm.proxy_dir'),
-            'setProxyNamespace'             => $container->getParameter('doctrine.orm.proxy_namespace'),
-            'setAutoGenerateProxyClasses'   => $container->getParameter('doctrine.orm.auto_generate_proxy_classes'),
-            'setClassMetadataFactoryName'   => $container->getParameter('doctrine.orm.class_metadata_factory_name'),
+            'setProxyDir'                   => $entityManager['proxy_dir'],
+            'setProxyNamespace'             => $entityManager['proxy_namespace'],
+            'setAutoGenerateProxyClasses'   => $entityManager['auto_generate_proxy_classes'],
+            'setClassMetadataFactoryName'   => $entityManager['class_metadata_factory_name'],
         );
         foreach ($uniqueMethods as $method => $arg) {
-            if ($ormConfigDef->hasMethodCall($method)) {
-                $ormConfigDef->removeMethodCall($method);
-            }
             $ormConfigDef->addMethodCall($method, array($arg));
         }
 
         $entityManagerService = sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']);
+        $connectionName = isset($entityManager['connection']) ? $entityManager['connection'] : $entityManager['name'];
 
-        if (!$container->hasDefinition($entityManagerService) || isset($entityManager['connection'])) {
-            $connectionName = isset($entityManager['connection']) ? $entityManager['connection'] : $entityManager['name'];
-
-            $ormEmArgs = array(
-                new Reference(sprintf('doctrine.dbal.%s_connection', $connectionName)),
-                new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name']))
-            );
-            $ormEmDef = new Definition('%doctrine.orm.entity_manager_class%', $ormEmArgs);
-            $ormEmDef->setFactoryMethod('create');
-            $ormEmDef->addTag('doctrine.orm.entity_manager');
-            $container->setDefinition($entityManagerService, $ormEmDef);
-
-            if ($entityManager['name'] == $defaultEntityManager) {
-                $container->setAlias(
-                    'doctrine.orm.entity_manager',
-                    sprintf('doctrine.orm.%s_entity_manager', $entityManager['name'])
-                );
-            }
-            $container->setAlias(
-                sprintf('doctrine.orm.%s_entity_manager.event_manager', $entityManager['name']),
-                new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $connectionName), false)
-            );
-        }
-    }
-
-    /**
-     * Gets the configured entity managers.
-     *
-     * @param array $config An array of configuration settings
-     * @param ContainerBuilder $container A ContainerBuilder instance
-     */
-    protected function getOrmEntityManagers(array $config, ContainerBuilder $container)
-    {
-        $defaultEntityManager = $container->getParameter('doctrine.orm.default_entity_manager');
-        $entityManagers = array();
-        if (isset($config['entity-managers'])) {
-            $config['entity_managers'] = $config['entity-managers'];
-        }
-
-        if (isset($config['entity_managers'])) {
-            $configEntityManagers = $config['entity_managers'];
-            if (isset($config['entity_managers']['entity-manager'])) {
-                $config['entity_managers']['entity_manager'] = $config['entity_managers']['entity-manager'];
-            }
-
-            if (isset($config['entity_managers']['entity_manager']) && isset($config['entity_managers']['entity_manager'][0])) {
-                // Multiple entity managers
-                $configEntityManagers = $config['entity_managers']['entity_manager'];
-            }
-            foreach ($configEntityManagers as $name => $entityManager) {
-                $entityManagers[isset($entityManager['id']) ? $entityManager['id'] : $name] = $entityManager;
-            }
-        } else {
-            $entityManagers = array($defaultEntityManager => $config);
-        }
-        return $entityManagers;
+        $ormEmArgs = array(
+            new Reference(sprintf('doctrine.dbal.%s_connection', $connectionName)),
+            new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name']))
+        );
+        $ormEmDef = new Definition('%doctrine.orm.entity_manager_class%', $ormEmArgs);
+        $ormEmDef->setFactoryMethod('create');
+        $ormEmDef->addTag('doctrine.orm.entity_manager');
+        $container->setDefinition($entityManagerService, $ormEmDef);
+
+        $container->setAlias(
+            sprintf('doctrine.orm.%s_entity_manager.event_manager', $entityManager['name']),
+            new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $connectionName), false)
+        );
     }
 
     /**
@@ -424,17 +432,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
 
         $this->loadMappingInformation($entityManager, $container);
         $this->registerMappingDrivers($entityManager, $container);
-
-        if ($ormConfigDef->hasMethodCall('setEntityNamespaces')) {
-            // TODO: Can we make a method out of it on Definition? replaceMethodArguments() or something.
-            $calls = $ormConfigDef->getMethodCalls();
-            foreach ($calls AS $call) {
-                if ($call[0] == 'setEntityNamespaces') {
-                    $this->aliasMap = array_merge($call[1][0], $this->aliasMap);
-                }
-            }
-            $method = $ormConfigDef->removeMethodCall('setEntityNamespaces');
-        }
+        
         $ormConfigDef->addMethodCall('setEntityNamespaces', array($this->aliasMap));
     }
 
@@ -461,60 +459,25 @@ class DoctrineExtension extends AbstractDoctrineExtension
      */
     protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container)
     {
-        $this->loadOrmEntityManagerMetadataCacheDriver($entityManager, $container);
-        $this->loadOrmEntityManagerQueryCacheDriver($entityManager, $container);
-        $this->loadOrmEntityManagerResultCacheDriver($entityManager, $container);
-    }
-
-    /**
-     * Loads a configured entity managers metadata cache driver.
-     *
-     * @param array $entityManager A configured ORM entity manager.
-     * @param ContainerBuilder $container A ContainerBuilder instance
-     */
-    protected function loadOrmEntityManagerMetadataCacheDriver(array $entityManager, ContainerBuilder $container)
-    {
-        $metadataCacheDriverService = sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name']);
-        if (!$container->hasDefinition($metadataCacheDriverService) || isset($entityManager['metadata-cache-driver']) || (isset($entityManager['metadata_cache_driver']))) {
-            $cacheDriver = $container->getParameter('doctrine.orm.metadata_cache_driver');
-            $cacheDriver = isset($entityManager['metadata-cache-driver']) ? $entityManager['metadata-cache-driver'] : (isset($entityManager['metadata_cache_driver']) ? $entityManager['metadata_cache_driver'] : $cacheDriver);
-            $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $cacheDriver, $container);
-            $container->setDefinition($metadataCacheDriverService, $cacheDef);
-        }
+        $this->loadOrmEntityManagerCacheDriver($entityManager, $container, 'metadata_cache');
+        $this->loadOrmEntityManagerCacheDriver($entityManager, $container, 'result_cache');
+        $this->loadOrmEntityManagerCacheDriver($entityManager, $container, 'query_cache');
     }
 
     /**
-     * Loads a configured entity managers query cache driver.
+     * Loads a configured entity managers metadata, query or result cache driver.
      *
      * @param array $entityManager A configured ORM entity manager.
      * @param ContainerBuilder $container A ContainerBuilder instance
+     * @param string $cacheName
      */
-    protected function loadOrmEntityManagerQueryCacheDriver(array $entityManager, ContainerBuilder $container)
+    protected function loadOrmEntityManagerCacheDriver(array $entityManager, ContainerBuilder $container, $cacheName)
     {
-        $queryCacheDriverService = sprintf('doctrine.orm.%s_query_cache', $entityManager['name']);
-        if (!$container->hasDefinition($queryCacheDriverService) || isset($entityManager['query-cache-driver']) || isset($entityManager['query_cache_driver'])) {
-            $cacheDriver = $container->getParameter('doctrine.orm.query_cache_driver');
-            $cacheDriver = isset($entityManager['query-cache-driver']) ? $entityManager['query-cache-driver'] : (isset($entityManager['query_cache_driver']) ? $entityManager['query_cache_driver'] : $cacheDriver);
-            $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $cacheDriver, $container);
-            $container->setDefinition($queryCacheDriverService, $cacheDef);
-        }
-    }
+        $cacheDriverService = sprintf('doctrine.orm.%s_%s', $entityManager['name'], $cacheName);
 
-    /**
-     * Loads a configured entity managers result cache driver.
-     *
-     * @param array $entityManager A configured ORM entity manager.
-     * @param ContainerBuilder $container A ContainerBuilder instance
-     */
-    protected function loadOrmEntityManagerResultCacheDriver(array $entityManager, ContainerBuilder $container)
-    {
-        $resultCacheDriverService = sprintf('doctrine.orm.%s_result_cache', $entityManager['name']);
-        if (!$container->hasDefinition($resultCacheDriverService) || isset($entityManager['result-cache-driver']) || isset($entityManager['result_cache_driver'])) {
-            $cacheDriver = $container->getParameter('doctrine.orm.result_cache_driver');
-            $cacheDriver = isset($entityManager['result-cache-driver']) ? $entityManager['result-cache-driver'] : (isset($entityManager['result_cache_driver']) ? $entityManager['result_cache_driver'] : $cacheDriver);
-            $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $cacheDriver, $container);
-            $container->setDefinition($resultCacheDriverService, $cacheDef);
-        }
+        $driver = $cacheName."_driver";
+        $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $entityManager[$driver], $container);
+        $container->setDefinition($cacheDriverService, $cacheDef);
     }
 
     /**
@@ -529,20 +492,18 @@ class DoctrineExtension extends AbstractDoctrineExtension
     {
         $type = is_array($cacheDriver) && isset($cacheDriver['type']) ? $cacheDriver['type'] : $cacheDriver;
         if ('memcache' === $type) {
-            $memcacheClass = isset($cacheDriver['class']) ? $cacheDriver['class'] : '%'.sprintf('doctrine.orm.cache.%s_class', $type).'%';
-            $cacheDef = new Definition($memcacheClass);
-            $cacheDef->setPublic(false);
-            $memcacheHost = is_array($cacheDriver) && isset($cacheDriver['host']) ? $cacheDriver['host'] : '%doctrine.orm.cache.memcache_host%';
-            $memcachePort = is_array($cacheDriver) && isset($cacheDriver['port']) ? $cacheDriver['port'] : '%doctrine.orm.cache.memcache_port%';
-            $memcacheInstanceClass = is_array($cacheDriver) && isset($cacheDriver['instance-class']) ? $cacheDriver['instance-class'] : (is_array($cacheDriver) && isset($cacheDriver['instance_class']) ? $cacheDriver['instance_class'] : '%doctrine.orm.cache.memcache_instance_class%');
-            $memcacheInstance = new Definition($memcacheInstanceClass);
-            $memcacheInstance->addMethodCall('connect', array($memcacheHost, $memcachePort));
+            $cacheDef = new Definition('%doctrine.orm.cache.memcache_class%');
+            $memcacheInstance = new Definition('%doctrine.orm.cache.memcache_instance_class%');
+            $memcacheInstance->addMethodCall('connect', array(
+                '%doctrine.orm.cache.memcache_host%', '%doctrine.orm.cache.memcache_port%'
+            ));
             $container->setDefinition(sprintf('doctrine.orm.%s_memcache_instance', $entityManager['name']), $memcacheInstance);
             $cacheDef->addMethodCall('setMemcache', array(new Reference(sprintf('doctrine.orm.%s_memcache_instance', $entityManager['name']))));
-        } else {
+        } else if (in_array($type, array('apc', 'array', 'xcache'))) {
             $cacheDef = new Definition('%'.sprintf('doctrine.orm.cache.%s_class', $type).'%');
-            $cacheDef->setPublic(false);
         }
+        $cacheDef->setPublic(false);
+        $cacheDef->addMethodCall('setNamespace', array('sf2orm_'.$entityManager['name']));
         return $cacheDef;
     }
 

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

@@ -15,7 +15,6 @@
         <!-- proxies -->
         <parameter key="doctrine.orm.proxy_namespace">Proxies</parameter>
         <parameter key="doctrine.orm.proxy_dir">%kernel.cache_dir%/doctrine/orm/Proxies</parameter>
-        <parameter key="doctrine.orm.auto_generate_proxy_classes">false</parameter>
 
         <!-- cache -->
         <parameter key="doctrine.orm.cache.array_class">Doctrine\Common\Cache\ArrayCache</parameter>

+ 11 - 4
src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd

@@ -38,7 +38,7 @@
     </xsd:complexType>
 
     <xsd:complexType name="connection">
-        <xsd:attribute name="id" type="xsd:string" use="required" />
+        <xsd:attribute name="name" type="xsd:string" use="required" />
         <xsd:attribute name="dbname" type="xsd:string" use="required" />
         <xsd:attribute name="host" type="xsd:string" />
         <xsd:attribute name="port" type="xsd:integer" />
@@ -78,12 +78,15 @@
         <xsd:all>
             <xsd:element name="entity-managers" type="entity_managers" minOccurs="0" maxOccurs="1" />
             <xsd:element name="mappings" type="mappings" minOccurs="0" maxOccurs="1" />
-            <xsd:element name="auto-generate-proxy-classes" type="xsd:string" minOccurs="0" maxOccurs="1" />
         </xsd:all>
 
         <xsd:attribute name="default-entity-manager" type="xsd:string" />
-        <xsd:attribute name="metadata-driver" type="xsd:string" />
-        <xsd:attribute name="cache-driver" type="xsd:string" />
+        <xsd:attribute name="default-connection" type="xsd:string" />
+
+        <xsd:attribute name="auto-generate-proxy-classes" type="xsd:boolean" default="false" />
+        <xsd:attribute name="result-cache-driver" type="xsd:string" />
+        <xsd:attribute name="metadata-cache-driver" type="xsd:string" />
+        <xsd:attribute name="query-cache-driver" type="xsd:string" />
     </xsd:complexType>
 
     <xsd:complexType name="entity_managers">
@@ -98,5 +101,9 @@
         </xsd:all>
 
         <xsd:attribute name="connection" type="xsd:string" />
+        <xsd:attribute name="name" type="xsd:string" />
+        <xsd:attribute name="result-cache-driver" type="xsd:string" />
+        <xsd:attribute name="metadata-cache-driver" type="xsd:string" />
+        <xsd:attribute name="query-cache-driver" type="xsd:string" />
     </xsd:complexType>
 </xsd:schema>

+ 10 - 9
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php

@@ -123,7 +123,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $this->assertEquals('Doctrine\ORM\Configuration', $container->getParameter('doctrine.orm.configuration_class'));
         $this->assertEquals('Doctrine\ORM\EntityManager', $container->getParameter('doctrine.orm.entity_manager_class'));
         $this->assertEquals('Proxies', $container->getParameter('doctrine.orm.proxy_namespace'));
-        $this->assertEquals(false, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
         $this->assertEquals('Doctrine\Common\Cache\ArrayCache', $container->getParameter('doctrine.orm.cache.array_class'));
         $this->assertEquals('Doctrine\Common\Cache\ApcCache', $container->getParameter('doctrine.orm.cache.apc_class'));
         $this->assertEquals('Doctrine\Common\Cache\MemcacheCache', $container->getParameter('doctrine.orm.cache.memcache_class'));
@@ -147,9 +146,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $loader->dbalLoad(array(array()), $container);
         $loader->ormLoad(array($config), $container);
 
-        $this->assertEquals('MyProxies', $container->getParameter('doctrine.orm.proxy_namespace'));
-        $this->assertEquals(true, $container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
-
         $definition = $container->getDefinition('doctrine.dbal.default_connection');
         $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
 
@@ -490,14 +486,16 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $container->compile();
 
         $definition = $container->getDefinition('doctrine.orm.default_metadata_cache');
-        $this->assertDICDefinitionClass($definition, 'Doctrine\Common\Cache\MemcacheCache');
+        $this->assertDICDefinitionClass($definition, '%doctrine.orm.cache.memcache_class%');
         $this->assertDICDefinitionMethodCallOnce($definition, 'setMemcache',
             array(new Reference('doctrine.orm.default_memcache_instance'))
         );
 
         $definition = $container->getDefinition('doctrine.orm.default_memcache_instance');
-        $this->assertDICDefinitionClass($definition, 'Memcache');
-        $this->assertDICDefinitionMethodCallOnce($definition, 'connect', array('localhost', 11211));
+        $this->assertDICDefinitionClass($definition, '%doctrine.orm.cache.memcache_instance_class%');
+        $this->assertDICDefinitionMethodCallOnce($definition, 'connect', array(
+            '%doctrine.orm.cache.memcache_host%', '%doctrine.orm.cache.memcache_port%'
+        ));
     }
 
     public function testDependencyInjectionImportsOverrideDefaults()
@@ -512,8 +510,11 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $container->getCompilerPassConfig()->setRemovingPasses(array());
         $container->compile();
 
-        $this->assertEquals('apc', $container->getParameter('doctrine.orm.metadata_cache_driver'));
-        $this->assertTrue($container->getParameter('doctrine.orm.auto_generate_proxy_classes'));
+        $cacheDefinition = $container->getDefinition('doctrine.orm.default_metadata_cache');
+        $this->assertEquals('%doctrine.orm.cache.apc_class%', $cacheDefinition->getClass());
+
+        $configDefinition = $container->getDefinition('doctrine.orm.default_configuration');
+        $this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', array(false));
     }
 
     public function testSingleEntityManagerMultipleMappingBundleDefinitions()

+ 3 - 3
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_multiple_connections.xml

@@ -9,20 +9,20 @@
     <doctrine:dbal>
       <doctrine:connections>
         <doctrine:connection
-            id="mysql"
+            name="mysql"
             dbname="mysql_db"
             user="mysql_user"
             password="mysql_s3cr3t"
             unix-socket="/path/to/mysqld.sock" /><!--  -->
         <doctrine:connection
-            id="sqlite"
+            name="sqlite"
             driver="pdo_sqlite"
             dbname="sqlite_db"
             user="sqlite_user"
             password="sqlite_s3cr3t"
             memory="true" />
         <doctrine:connection
-            id="oci"
+            name="oci"
             driver="oci8"
             dbname="oracle_db"
             user="oracle_user"

+ 1 - 1
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_service_single_connection.xml

@@ -9,7 +9,7 @@
     <doctrine:dbal>
       <doctrine:connections>
         <doctrine:connection
-            id="mysql"
+            name="mysql"
             dbname="mysql_db"
             user="mysql_user"
             password="mysql_s3cr3t"

+ 2 - 2
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_multiple_em_bundle_mappings.xml

@@ -9,12 +9,12 @@
 
     <doctrine:orm>
         <doctrine:entity-managers>
-            <doctrine:entity-manager id="em1">
+            <doctrine:entity-manager name="em1">
                 <mappings>
                     <mapping name="AnnotationsBundle" />
                 </mappings>
             </doctrine:entity-manager>
-            <doctrine:entity-manager id="em2">
+            <doctrine:entity-manager name="em2">
                 <mappings>
                     <mapping name="YamlBundle" dir="Resources/config/doctrine/metadata" alias="yml" />
                     <mapping name="manual" type="xml" prefix="DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\XmlBundle"

+ 9 - 11
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_multiple_entity_managers.xml

@@ -7,17 +7,21 @@
                         http://www.symfony-project.org/schema/dic/doctrine/orm http://www.symfony-project.org/schema/dic/doctrine/orm/doctrine-1.0.xsd
                         http://www.symfony-project.org/schema/dic/doctrine/dbal http://www.symfony-project.org/schema/dic/doctrine/dbal/doctrine-1.0.xsd">
 
+    <parameters>
+        <parameter key="doctrine.orm.proxy_namespace">Proxies</parameter>
+    </parameters>
+
     <doctrine:dbal>
         <doctrine:connections>
             <doctrine:connection
-                id="conn1"
+                name="conn1"
                 driver="pdo_sqlite"
                 dbname="sqlite_db"
                 user="sqlite_user"
                 password="sqlite_s3cr3t"
                 memory="true" />
             <doctrine:connection
-                id="conn2"
+                name="conn2"
                 driver="pdo_sqlite"
                 dbname="sqlite_db"
                 user="sqlite_user"
@@ -26,16 +30,10 @@
         </doctrine:connections>
     </doctrine:dbal>
 
-    <doctrine:orm
-            metadata-cache-driver="apc"
-            default-entity-manager="dm2"
-            default-connection="conn1"
-            proxy-namespace="Proxies"
-            auto-generate-proxy-classes="true"
-        >
+    <doctrine:orm default-entity-manager="dm2" default-connection="conn1" auto-generate-proxy-classes="true">
         <doctrine:entity-managers>
-            <doctrine:entity-manager id="dm1" metadata-cache-driver="xcache" connection="conn1" />
-            <doctrine:entity-manager id="dm2" connection="conn2" />
+            <doctrine:entity-manager name="dm1" metadata-cache-driver="xcache" connection="conn1" />
+            <doctrine:entity-manager name="dm2" connection="conn2" metadata-cache-driver="apc" />
         </doctrine:entity-managers>
     </doctrine:orm>
 </container>

+ 6 - 3
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_service_single_entity_manager.xml

@@ -7,10 +7,14 @@
                         http://www.symfony-project.org/schema/dic/doctrine/orm http://www.symfony-project.org/schema/dic/doctrine/orm/doctrine-1.0.xsd
                         http://www.symfony-project.org/schema/dic/doctrine/dbal http://www.symfony-project.org/schema/dic/doctrine/dbal/doctrine-1.0.xsd">
 
+    <parameters>
+        <parameter key="doctrine.orm.proxy_namespace">Proxies</parameter>
+    </parameters>
+
     <doctrine:dbal>
         <doctrine:connections>
             <doctrine:connection
-                id="default"
+                name="default"
                 driver="pdo_sqlite"
                 dbname="sqlite_db"
                 user="sqlite_user"
@@ -23,11 +27,10 @@
             metadata-cache-driver="apc"
             default-entity-manager="dm2"
             default-connection="conn1"
-            proxy-namespace="Proxies"
             auto-generate-proxy-classes="true"
         >
         <doctrine:entity-managers>
-            <doctrine:entity-manager id="default" connection="default">
+            <doctrine:entity-manager name="default" connection="default">
                 <metadata-cache-driver type="memcache">
                     <class>Doctrine\Common\Cache\MemcacheCache</class>
                     <host>localhost</host>

+ 4 - 2
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_service_multiple_entity_managers.yml

@@ -1,3 +1,6 @@
+parameters:
+  doctrine.orm.proxy_namespace: Proxies
+
 doctrine.dbal:
   connections:
     conn1:
@@ -14,14 +17,13 @@ doctrine.dbal:
       memory: true
 
 doctrine.orm:
-  metadata_cache_driver: apc
   default_entity_manager: dm2
   default_connection: conn1
-  proxy_namespace: Proxies
   auto_generate_proxy_classes: true
   entity_managers:
     dm1:
       metadata_cache_driver: xcache
       connection: conn1
     dm2:
+      metadata_cache_driver: apc
       connection: conn2

+ 54 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/XMLSchemaTest.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection;
+
+class XMLSchemaTest extends \PHPUnit_Framework_TestCase
+{
+    static public function dataValidateSchemaFiles()
+    {
+        $schemaFiles = array();
+        $di = new \DirectoryIterator(__DIR__ . "/Fixtures/config/xml");
+        foreach ($di AS $element) {
+            if ($element->isFile() && strpos($element->getFilename(), ".xml") !== false) {
+                $schemaFiles[] = array($element->getPathname());
+            }
+        }
+        return $schemaFiles;
+    }
+
+    /**
+     * @dataProvider dataValidateSchemaFiles
+     * @param string $file
+     */
+    public function testValidateSchema($file)
+    {
+        $found = false;
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->load($file);
+
+
+        $dbalElements = $dom->getElementsByTagNameNS("http://www.symfony-project.org/schema/dic/doctrine", "dbal");
+        if ($dbalElements->length) {
+            $dbalDom = new \DOMDocument('1.0', 'UTF-8');
+            $dbalNode = $dbalDom->importNode($dbalElements->item(0));
+            $dbalDom->appendChild($dbalNode);
+
+            $ret = $dbalDom->schemaValidate(__DIR__ . "/../../Resources/config/schema/doctrine-1.0.xsd");
+            $this->assertTrue($ret, "DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance.");
+            $found = true;
+        }
+
+        $ormElements = $dom->getElementsByTagNameNS("http://www.symfony-project.org/schema/dic/doctrine", "orm");
+        if ($ormElements->length) {
+            $ormDom = new \DOMDocument('1.0', 'UTF-8');
+            $ormNode = $ormDom->importNode($ormElements->item(0));
+            $ormDom->appendChild($ormNode);
+
+            $ret = $ormDom->schemaValidate(__DIR__ . "/../../Resources/config/schema/doctrine-1.0.xsd");
+            $this->assertTrue($ret, "DoctrineBundle Dependency Injection XMLSchema did not validate this XML instance.");
+            $found = true;
+        }
+
+        $this->assertTrue($found, "Neither <doctrine:orm> nor <doctrine:dbal> elements found in given XML. Are namespace sconfigured correctly?");
+    }
+}