Skip to content

Commit

Permalink
bug #19586 [TwigBundle] Fix bug where namespaced paths don't take par…
Browse files Browse the repository at this point in the history
…ent bundles in account (wesleylancel)

This PR was squashed before being merged into the 2.7 branch (closes #19586).

Discussion
----------

[TwigBundle] Fix bug where namespaced paths don't take parent bundles in account

| Q | A |
| --- | --- |
| Branch? | 2.7 |
| Bug fix? | yes |
| New feature? | no |
| BC breaks? | no |
| Deprecations? | no |
| Tests pass? | yes |
| Fixed tickets | #6919 |
| License | MIT |
| Doc PR |  |

Currently namespaced paths for templates such as `{% extends '@App/Layout/layout.html.twig' %}` do not work with bundles that have overruled templates using the `getParent()` method in another bundle. See attached ticket. This change prepends the path of the bundle implementing `getParent()` to the paths of the namespace of bundle returned as a parent.

Commits
-------

0c77ce2 [TwigBundle] Fix bug where namespaced paths don't take parent bundles in account
  • Loading branch information
fabpot committed Jan 11, 2017
2 parents 1c6dfce + 0c77ce2 commit 17ce5f5
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 10 deletions.
Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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;
}

/**
Expand Down
@@ -0,0 +1 @@
This is a layout
@@ -0,0 +1 @@
This is a layout
@@ -0,0 +1 @@
This is a layout
@@ -0,0 +1 @@
This is a layout
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 17ce5f5

Please sign in to comment.