diff --git a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php index 3cf4d8ecb57ab..d9d697b04e8f1 100644 --- a/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php +++ b/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php @@ -328,20 +328,19 @@ protected function loadOrmEntityManagerBundlesMappingInformation(array $entityMa // configure metadata driver for each bundle based on the type of mapping files found $mappingDriverDef = new Definition('%doctrine.orm.metadata.driver_chain_class%'); $bundleEntityMappings = array(); - $bundleDirs = $container->getParameter('kernel.bundle_dirs'); $aliasMap = array(); foreach ($container->getParameter('kernel.bundles') as $className) { $tmp = dirname(str_replace('\\', '/', $className)); $namespace = str_replace('/', '\\', dirname($tmp)); $class = basename($tmp); - if (!isset($bundleDirs[$namespace])) { + if (! $bundleDir = $this->findBundleDirForNamespace($namespace, $container)) { continue; } - $type = $this->detectMetadataDriver($bundleDirs[$namespace].'/'.$class, $container); + $type = $this->detectMetadataDriver($bundleDir.'/'.$class, $container); - if (is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Entity')) { + if (is_dir($dir = $bundleDir.'/'.$class.'/Entity')) { if ($type === null) { $type = 'annotation'; } @@ -443,6 +442,31 @@ protected function getEntityManagerCacheDefinition(array $entityManager, $cacheD return $cacheDef; } + /** + * Finds the bundle directory for a namespace. + * + * If the namespace does not yield a direct match, this method will attempt + * to match parent namespaces exhaustively. + * + * @param string $namespace A bundle namespace omitting the bundle name part + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @return string|false The bundle directory if found, false otherwise + */ + protected function findBundleDirForNamespace($namespace, ContainerBuilder $container) + { + $bundleDirs = $container->getParameter('kernel.bundle_dirs'); + $segment = $namespace; + + do { + if (isset($bundleDirs[$segment])) { + return $bundleDirs[$segment] . str_replace('\\', '/', substr($namespace, strlen($segment))); + } + } while ($segment = substr($segment, 0, ($pos = strrpos($segment, '\\')))); + + return false; + } + /** * Finds existing bundle subpaths. * diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php index 99894957c55ce..bc995866b3fbc 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php @@ -385,6 +385,24 @@ public function testAnnotationsBundleMappingDetection() $this->assertEquals('DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\AnnotationsBundle\Entity', $calls[0][1][1]); } + public function testAnnotationsBundleMappingDetectionWithVendorNamespace() + { + $container = $this->getContainer('AnnotationsBundle', 'Vendor'); + $loader = new DoctrineExtension(); + + $loader->dbalLoad(array(), $container); + $loader->ormLoad(array(), $container); + + $this->assertEquals(array(), $container->getParameter('doctrine.orm.metadata_driver.mapping_dirs')); + $this->assertEquals('%doctrine.orm.metadata_driver.mapping_dirs%', $container->getParameter('doctrine.orm.xml_mapping_dirs')); + $this->assertEquals('%doctrine.orm.metadata_driver.mapping_dirs%', $container->getParameter('doctrine.orm.yml_mapping_dirs')); + $this->assertEquals(array(__DIR__.'/Fixtures/Bundles/Vendor/AnnotationsBundle/Entity'), $container->getParameter('doctrine.orm.metadata_driver.entity_dirs')); + + $calls = $container->getDefinition('doctrine.orm.metadata_driver')->getMethodCalls(); + $this->assertEquals('doctrine.orm.metadata_driver.annotation', (string) $calls[0][1][0]); + $this->assertEquals('DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]); + } + public function testEntityManagerMetadataCacheDriverConfiguration() { $container = $this->getContainer(); @@ -442,13 +460,13 @@ public function testDependencyInjectionImportsOverrideDefaults() $this->assertTrue($container->getParameter('doctrine.orm.auto_generate_proxy_classes')); } - protected function getContainer($bundle = 'YamlBundle') + protected function getContainer($bundle = 'YamlBundle', $vendor = null) { - require_once __DIR__.'/Fixtures/Bundles/'.$bundle.'/'.$bundle.'.php'; + require_once __DIR__.'/Fixtures/Bundles/'.($vendor ? $vendor.'/' : '').$bundle.'/'.$bundle.'.php'; return new ContainerBuilder(new ParameterBag(array( 'kernel.bundle_dirs' => array('DoctrineBundle\\Tests\\DependencyInjection\\Fixtures\\Bundles' => __DIR__.'/Fixtures/Bundles'), - 'kernel.bundles' => array('DoctrineBundle\\Tests\DependencyInjection\\Fixtures\\Bundles\\'.$bundle.'\\'.$bundle), + 'kernel.bundles' => array('DoctrineBundle\\Tests\DependencyInjection\\Fixtures\\Bundles\\'.($vendor ? $vendor.'\\' : '').$bundle.'\\'.$bundle), 'kernel.cache_dir' => sys_get_temp_dir(), ))); } diff --git a/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php new file mode 100644 index 0000000000000..53c3293c58c3d --- /dev/null +++ b/src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/Bundles/Vendor/AnnotationsBundle/AnnotationsBundle.php @@ -0,0 +1,9 @@ +getParameter('kernel.bundle_dirs'); $aliasMap = array(); foreach ($container->getParameter('kernel.bundles') as $className) { $tmp = dirname(str_replace('\\', '/', $className)); $namespace = str_replace('/', '\\', dirname($tmp)); $class = basename($tmp); - if (!isset($bundleDirs[$namespace])) { + if (! $bundleDir = $this->findBundleDirForNamespace($namespace, $container)) { continue; } - $type = $this->detectMetadataDriver($bundleDirs[$namespace].'/'.$class, $container); + $type = $this->detectMetadataDriver($bundleDir.'/'.$class, $container); - if (is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Document')) { + if (is_dir($dir = $bundleDir.'/'.$class.'/Document')) { if ($type === null) { $type = 'annotation'; } @@ -294,6 +293,31 @@ protected function getConnections(array $config, ContainerBuilder $container) return $connections; } + /** + * Finds the bundle directory for a namespace. + * + * If the namespace does not yield a direct match, this method will attempt + * to match parent namespaces exhaustively. + * + * @param string $namespace A bundle namespace omitting the bundle name part + * @param ContainerBuilder $container A ContainerBuilder instance + * + * @return string|false The bundle directory if found, false otherwise + */ + protected function findBundleDirForNamespace($namespace, ContainerBuilder $container) + { + $bundleDirs = $container->getParameter('kernel.bundle_dirs'); + $segment = $namespace; + + do { + if (isset($bundleDirs[$segment])) { + return $bundleDirs[$segment] . str_replace('\\', '/', substr($namespace, strlen($segment))); + } + } while ($segment = substr($segment, 0, ($pos = strrpos($segment, '\\')))); + + return false; + } + /** * Finds existing bundle subpaths. * diff --git a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Profiler/mongodb_menu.php b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Profiler/mongodb_menu.php index 346740c9802ef..1e6e3653ee553 100644 --- a/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Profiler/mongodb_menu.php +++ b/src/Symfony/Bundle/DoctrineMongoDBBundle/Resources/views/Profiler/mongodb_menu.php @@ -1,2 +1,3 @@