diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index e6ea35b3bdc1..c741813b86bf 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -88,14 +88,19 @@ public function load(array $configs, ContainerBuilder $container) } } - // register bundles as Twig namespaces - foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) { - if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views')) { - $this->addTwigPath($twigFilesystemLoaderDefinition, $dir, $name); + $bundleHierarchy = $this->getBundleHierarchy($container); + + foreach ($bundleHierarchy as $name => $bundle) { + $namespace = $this->normalizeBundleName($name); + + foreach ($bundle['children'] as $child) { + foreach ($bundleHierarchy[$child]['paths'] as $path) { + $twigFilesystemLoaderDefinition->addMethodCall('addPath', array($path, $namespace)); + } } - if (is_dir($dir = $bundle['path'].'/Resources/views')) { - $this->addTwigPath($twigFilesystemLoaderDefinition, $dir, $name); + foreach ($bundle['paths'] as $path) { + $twigFilesystemLoaderDefinition->addMethodCall('addPath', array($path, $namespace)); } } @@ -139,13 +144,69 @@ public function load(array $configs, ContainerBuilder $container) )); } + private function getBundleHierarchy(ContainerBuilder $container) + { + $bundleHierarchy = array(); + + foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) { + if (!array_key_exists($name, $bundleHierarchy)) { + $bundleHierarchy[$name] = array( + 'paths' => array(), + 'parents' => array(), + 'children' => array(), + ); + } + + if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views')) { + $bundleHierarchy[$name]['paths'][] = $dir; + } + + if (is_dir($dir = $bundle['path'].'/Resources/views')) { + $bundleHierarchy[$name]['paths'][] = $dir; + } + + if (null === $bundle['parent']) { + continue; + } + + $bundleHierarchy[$name]['parents'][] = $bundle['parent']; + + if (!array_key_exists($bundle['parent'], $bundleHierarchy)) { + $bundleHierarchy[$bundle['parent']] = array( + 'paths' => array(), + 'parents' => array(), + 'children' => array(), + ); + } + + $bundleHierarchy[$bundle['parent']]['children'] = array_merge($bundleHierarchy[$name]['children'], array($name), $bundleHierarchy[$bundle['parent']]['children']); + + foreach ($bundleHierarchy[$bundle['parent']]['parents'] as $parent) { + $bundleHierarchy[$name]['parents'][] = $parent; + $bundleHierarchy[$parent]['children'] = array_merge($bundleHierarchy[$name]['children'], array($name), $bundleHierarchy[$parent]['children']); + } + + foreach ($bundleHierarchy[$name]['children'] as $child) { + $bundleHierarchy[$child]['parents'] = array_merge($bundleHierarchy[$child]['parents'], $bundleHierarchy[$name]['parents']); + } + } + + return $bundleHierarchy; + } + private function addTwigPath($twigFilesystemLoaderDefinition, $dir, $bundle) { - $name = $bundle; + $name = $this->normalizeBundleName($bundle); + $twigFilesystemLoaderDefinition->addMethodCall('addPath', array($dir, $name)); + } + + private function normalizeBundleName($name) + { if ('Bundle' === substr($name, -6)) { $name = substr($name, 0, -6); } - $twigFilesystemLoaderDefinition->addMethodCall('addPath', array($dir, $name)); + + return $name; } /** diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views/layout.html.twig b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views/layout.html.twig new file mode 100644 index 000000000000..bb07ecfe55a3 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views/layout.html.twig @@ -0,0 +1 @@ +This is a layout diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views/layout.html.twig b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views/layout.html.twig new file mode 100644 index 000000000000..bb07ecfe55a3 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views/layout.html.twig @@ -0,0 +1 @@ +This is a layout diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildTwigBundle/Resources/views/layout.html.twig b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildTwigBundle/Resources/views/layout.html.twig new file mode 100644 index 000000000000..bb07ecfe55a3 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildChildTwigBundle/Resources/views/layout.html.twig @@ -0,0 +1 @@ +This is a layout diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildTwigBundle/Resources/views/layout.html.twig b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildTwigBundle/Resources/views/layout.html.twig new file mode 100644 index 000000000000..bb07ecfe55a3 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/Bundle/ChildTwigBundle/Resources/views/layout.html.twig @@ -0,0 +1 @@ +This is a layout diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php index ff4103d29135..2637460ab891 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -201,8 +201,22 @@ public function testTwigLoaderPaths($format) array('namespaced_path1', 'namespace1'), array('namespaced_path2', 'namespace2'), array('namespaced_path3', 'namespace3'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildChildChildChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildChildChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'ChildChildChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'Twig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'Twig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views', 'Twig'), + array(__DIR__.'/Fixtures/Bundle/ChildTwigBundle/Resources/views', 'Twig'), array(__DIR__.'/Fixtures/Resources/TwigBundle/views', 'Twig'), array(realpath(__DIR__.'/../..').'/Resources/views', 'Twig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'ChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views', 'ChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildTwigBundle/Resources/views', 'ChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'ChildChildTwig'), + array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views', 'ChildChildTwig'), array(__DIR__.'/Fixtures/Resources/views'), ), $paths); } @@ -254,8 +268,40 @@ private function createContainer() 'kernel.root_dir' => __DIR__.'/Fixtures', 'kernel.charset' => 'UTF-8', 'kernel.debug' => false, - 'kernel.bundles' => array('TwigBundle' => 'Symfony\\Bundle\\TwigBundle\\TwigBundle'), - 'kernel.bundles_metadata' => array('TwigBundle' => array('namespace' => 'Symfony\\Bundle\\TwigBundle', 'parent' => null, 'path' => realpath(__DIR__.'/../..'))), + 'kernel.bundles' => array( + 'TwigBundle' => 'Symfony\\Bundle\\TwigBundle\\TwigBundle', + 'ChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildTwigBundle\\ChildTwigBundle', + 'ChildChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildTwigBundle\\ChildChildTwigBundle', + 'ChildChildChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildTwigBundle\\ChildChildChildTwigBundle', + 'ChildChildChildChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildChildTwigBundle\\ChildChildChildChildTwigBundle', + ), + 'kernel.bundles_metadata' => array( + 'ChildChildChildChildTwigBundle' => array( + 'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildChildTwigBundle\\ChildChildChildChildTwigBundle', + 'parent' => 'ChildChildChildTwigBundle', + 'path' => __DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle', + ), + 'TwigBundle' => array( + 'namespace' => 'Symfony\\Bundle\\TwigBundle', + 'parent' => null, + 'path' => realpath(__DIR__.'/../..'), + ), + 'ChildTwigBundle' => array( + 'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildTwigBundle\\ChildTwigBundle', + 'parent' => 'TwigBundle', + 'path' => __DIR__.'/Fixtures/Bundle/ChildTwigBundle', + ), + 'ChildChildChildTwigBundle' => array( + 'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildTwigBundle\\ChildChildChildTwigBundle', + 'parent' => 'ChildChildTwigBundle', + 'path' => __DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle', + ), + 'ChildChildTwigBundle' => array( + 'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildTwigBundle\\ChildChildTwigBundle', + 'parent' => 'ChildTwigBundle', + 'path' => __DIR__.'/Fixtures/Bundle/ChildChildTwigBundle', + ), + ), ))); return $container;