Skip to content

Commit 17ce5f5

Browse files
committed
bug symfony#19586 [TwigBundle] Fix bug where namespaced paths don't take parent bundles in account (wesleylancel)
This PR was squashed before being merged into the 2.7 branch (closes symfony#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 | symfony#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
2 parents 1c6dfce + 0c77ce2 commit 17ce5f5

File tree

6 files changed

+121
-10
lines changed

6 files changed

+121
-10
lines changed

src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,19 @@ public function load(array $configs, ContainerBuilder $container)
8888
}
8989
}
9090

91-
// register bundles as Twig namespaces
92-
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
93-
if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views')) {
94-
$this->addTwigPath($twigFilesystemLoaderDefinition, $dir, $name);
91+
$bundleHierarchy = $this->getBundleHierarchy($container);
92+
93+
foreach ($bundleHierarchy as $name => $bundle) {
94+
$namespace = $this->normalizeBundleName($name);
95+
96+
foreach ($bundle['children'] as $child) {
97+
foreach ($bundleHierarchy[$child]['paths'] as $path) {
98+
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($path, $namespace));
99+
}
95100
}
96101

97-
if (is_dir($dir = $bundle['path'].'/Resources/views')) {
98-
$this->addTwigPath($twigFilesystemLoaderDefinition, $dir, $name);
102+
foreach ($bundle['paths'] as $path) {
103+
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($path, $namespace));
99104
}
100105
}
101106

@@ -139,13 +144,69 @@ public function load(array $configs, ContainerBuilder $container)
139144
));
140145
}
141146

147+
private function getBundleHierarchy(ContainerBuilder $container)
148+
{
149+
$bundleHierarchy = array();
150+
151+
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
152+
if (!array_key_exists($name, $bundleHierarchy)) {
153+
$bundleHierarchy[$name] = array(
154+
'paths' => array(),
155+
'parents' => array(),
156+
'children' => array(),
157+
);
158+
}
159+
160+
if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views')) {
161+
$bundleHierarchy[$name]['paths'][] = $dir;
162+
}
163+
164+
if (is_dir($dir = $bundle['path'].'/Resources/views')) {
165+
$bundleHierarchy[$name]['paths'][] = $dir;
166+
}
167+
168+
if (null === $bundle['parent']) {
169+
continue;
170+
}
171+
172+
$bundleHierarchy[$name]['parents'][] = $bundle['parent'];
173+
174+
if (!array_key_exists($bundle['parent'], $bundleHierarchy)) {
175+
$bundleHierarchy[$bundle['parent']] = array(
176+
'paths' => array(),
177+
'parents' => array(),
178+
'children' => array(),
179+
);
180+
}
181+
182+
$bundleHierarchy[$bundle['parent']]['children'] = array_merge($bundleHierarchy[$name]['children'], array($name), $bundleHierarchy[$bundle['parent']]['children']);
183+
184+
foreach ($bundleHierarchy[$bundle['parent']]['parents'] as $parent) {
185+
$bundleHierarchy[$name]['parents'][] = $parent;
186+
$bundleHierarchy[$parent]['children'] = array_merge($bundleHierarchy[$name]['children'], array($name), $bundleHierarchy[$parent]['children']);
187+
}
188+
189+
foreach ($bundleHierarchy[$name]['children'] as $child) {
190+
$bundleHierarchy[$child]['parents'] = array_merge($bundleHierarchy[$child]['parents'], $bundleHierarchy[$name]['parents']);
191+
}
192+
}
193+
194+
return $bundleHierarchy;
195+
}
196+
142197
private function addTwigPath($twigFilesystemLoaderDefinition, $dir, $bundle)
143198
{
144-
$name = $bundle;
199+
$name = $this->normalizeBundleName($bundle);
200+
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($dir, $name));
201+
}
202+
203+
private function normalizeBundleName($name)
204+
{
145205
if ('Bundle' === substr($name, -6)) {
146206
$name = substr($name, 0, -6);
147207
}
148-
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($dir, $name));
208+
209+
return $name;
149210
}
150211

151212
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a layout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a layout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a layout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a layout

src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,22 @@ public function testTwigLoaderPaths($format)
201201
array('namespaced_path1', 'namespace1'),
202202
array('namespaced_path2', 'namespace2'),
203203
array('namespaced_path3', 'namespace3'),
204+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildChildChildChildTwig'),
205+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildChildChildTwig'),
206+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'ChildChildChildTwig'),
207+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'Twig'),
208+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'Twig'),
209+
array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views', 'Twig'),
210+
array(__DIR__.'/Fixtures/Bundle/ChildTwigBundle/Resources/views', 'Twig'),
204211
array(__DIR__.'/Fixtures/Resources/TwigBundle/views', 'Twig'),
205212
array(realpath(__DIR__.'/../..').'/Resources/views', 'Twig'),
213+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildTwig'),
214+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'ChildTwig'),
215+
array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views', 'ChildTwig'),
216+
array(__DIR__.'/Fixtures/Bundle/ChildTwigBundle/Resources/views', 'ChildTwig'),
217+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle/Resources/views', 'ChildChildTwig'),
218+
array(__DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle/Resources/views', 'ChildChildTwig'),
219+
array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views', 'ChildChildTwig'),
206220
array(__DIR__.'/Fixtures/Resources/views'),
207221
), $paths);
208222
}
@@ -254,8 +268,40 @@ private function createContainer()
254268
'kernel.root_dir' => __DIR__.'/Fixtures',
255269
'kernel.charset' => 'UTF-8',
256270
'kernel.debug' => false,
257-
'kernel.bundles' => array('TwigBundle' => 'Symfony\\Bundle\\TwigBundle\\TwigBundle'),
258-
'kernel.bundles_metadata' => array('TwigBundle' => array('namespace' => 'Symfony\\Bundle\\TwigBundle', 'parent' => null, 'path' => realpath(__DIR__.'/../..'))),
271+
'kernel.bundles' => array(
272+
'TwigBundle' => 'Symfony\\Bundle\\TwigBundle\\TwigBundle',
273+
'ChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildTwigBundle\\ChildTwigBundle',
274+
'ChildChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildTwigBundle\\ChildChildTwigBundle',
275+
'ChildChildChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildTwigBundle\\ChildChildChildTwigBundle',
276+
'ChildChildChildChildTwigBundle' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildChildTwigBundle\\ChildChildChildChildTwigBundle',
277+
),
278+
'kernel.bundles_metadata' => array(
279+
'ChildChildChildChildTwigBundle' => array(
280+
'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildChildTwigBundle\\ChildChildChildChildTwigBundle',
281+
'parent' => 'ChildChildChildTwigBundle',
282+
'path' => __DIR__.'/Fixtures/Bundle/ChildChildChildChildTwigBundle',
283+
),
284+
'TwigBundle' => array(
285+
'namespace' => 'Symfony\\Bundle\\TwigBundle',
286+
'parent' => null,
287+
'path' => realpath(__DIR__.'/../..'),
288+
),
289+
'ChildTwigBundle' => array(
290+
'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildTwigBundle\\ChildTwigBundle',
291+
'parent' => 'TwigBundle',
292+
'path' => __DIR__.'/Fixtures/Bundle/ChildTwigBundle',
293+
),
294+
'ChildChildChildTwigBundle' => array(
295+
'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildChildTwigBundle\\ChildChildChildTwigBundle',
296+
'parent' => 'ChildChildTwigBundle',
297+
'path' => __DIR__.'/Fixtures/Bundle/ChildChildChildTwigBundle',
298+
),
299+
'ChildChildTwigBundle' => array(
300+
'namespace' => 'Symfony\\Bundle\\TwigBundle\\Tests\\DependencyInjection\\Fixtures\\Bundle\\ChildChildTwigBundle\\ChildChildTwigBundle',
301+
'parent' => 'ChildTwigBundle',
302+
'path' => __DIR__.'/Fixtures/Bundle/ChildChildTwigBundle',
303+
),
304+
),
259305
)));
260306

261307
return $container;

0 commit comments

Comments
 (0)