浏览代码

added an exception when trying to extend a template with a decorator that uses a different renderer (for instance when a Twig template tries to extend a PHP one)

Fabien Potencier 14 年之前
父节点
当前提交
bf3659d5bb
共有 2 个文件被更改,包括 15 次插入3 次删除
  1. 4 0
      src/Symfony/Bundle/TwigBundle/Loader/Loader.php
  2. 11 3
      src/Symfony/Component/Templating/Engine.php

+ 4 - 0
src/Symfony/Bundle/TwigBundle/Loader/Loader.php

@@ -43,6 +43,10 @@ class Loader implements \Twig_LoaderInterface
 
         list($name, $options) = $this->engine->splitTemplateName($name);
 
+        if ('twig' !== $options['renderer']) {
+            throw new \LogicException(sprintf('A "%s" template cannot extend a "Twig" template.', $options['renderer']));
+        }
+
         $template = $this->engine->getLoader()->load($name, $options);
 
         if (false === $template) {

+ 11 - 3
src/Symfony/Component/Templating/Engine.php

@@ -26,6 +26,7 @@ class Engine implements \ArrayAccess
     protected $loader;
     protected $renderers;
     protected $current;
+    protected $currentRenderer;
     protected $helpers;
     protected $parents;
     protected $stack;
@@ -94,16 +95,21 @@ class Engine implements \ArrayAccess
             $this->cache[$name] = array($tpl, $options, $template);
         }
 
-        $this->current = $name;
-        $this->parents[$name] = null;
-
         // renderer
         $renderer = $template->getRenderer() ? $template->getRenderer() : $options['renderer'];
 
+        // a decorator must use the same renderer as its children
+        if (null !== $this->currentRenderer && $renderer !== $this->currentRenderer) {
+            throw new \LogicException(sprintf('A "%s" template cannot extend a "%s" template.', $this->currentRenderer, $renderer));
+        }
+
         if (!isset($this->renderers[$options['renderer']])) {
             throw new \InvalidArgumentException(sprintf('The renderer "%s" is not registered.', $renderer));
         }
 
+        $this->current = $name;
+        $this->parents[$name] = null;
+
         // render
         if (false === $content = $this->renderers[$renderer]->evaluate($template, $parameters)) {
             throw new \RuntimeException(sprintf('The template "%s" cannot be rendered (renderer: %s).', $name, $renderer));
@@ -115,7 +121,9 @@ class Engine implements \ArrayAccess
             $this->stack[] = $slots->get('_content');
             $slots->set('_content', $content);
 
+            $this->currentRenderer = $renderer;
             $content = $this->render($this->parents[$name], $parameters);
+            $this->currentRenderer = null;
 
             $slots->set('_content', array_pop($this->stack));
         }