浏览代码

[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?");
+    }
+}