fixed "include" with "ignore missing" when an error loading occurs in the included template (again)

This commit is contained in:
Fabien Potencier
2019-04-06 14:02:52 +02:00
parent 49725a1e8e
commit 8ea68e06e4
9 changed files with 53 additions and 61 deletions
+1 -17
View File
@@ -83,7 +83,6 @@ class Environment
private $runtimeLoaders = [];
private $runtimes = [];
private $optionsHash;
private $loading = [];
/**
* Constructor.
@@ -507,22 +506,7 @@ class Environment
$this->initRuntime();
}
if (isset($this->loading[$cls])) {
throw new RuntimeError(sprintf('Circular reference detected for Twig template "%s", path: %s.', $name, implode(' -> ', array_merge($this->loading, [$name]))));
}
$this->loading[$cls] = $name;
try {
$this->loadedTemplates[$cls] = new $cls($this);
unset($this->loading[$cls]);
} catch (\Exception $e) {
unset($this->loading[$cls]);
throw $e;
}
return $this->loadedTemplates[$cls];
return $this->loadedTemplates[$cls] = new $cls($this);
}
/**
+10 -2
View File
@@ -1570,12 +1570,20 @@ function twig_include(Environment $env, $context, $template, $variables = [], $w
}
try {
return $loaded ? $loaded->render($variables) : '';
} finally {
$ret = $loaded ? $loaded->render($variables) : '';
} catch (\Exception $e) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}
throw $e;
}
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}
return $ret;
}
/**
+10 -11
View File
@@ -198,17 +198,6 @@ class ModuleNode extends Node
// parent
if (!$this->hasNode('parent')) {
$compiler->write("\$this->parent = false;\n\n");
} elseif (($parent = $this->getNode('parent')) && $parent instanceof ConstantExpression) {
$compiler
->addDebugInfo($parent)
->write('$this->parent = $this->loadTemplate(')
->subcompile($parent)
->raw(', ')
->repr($this->source->getName())
->raw(', ')
->repr($parent->getTemplateLine())
->raw(");\n")
;
}
$countTraits = \count($this->getNode('traits'));
@@ -331,8 +320,18 @@ class ModuleNode extends Node
if ($this->hasNode('parent')) {
$parent = $this->getNode('parent');
$compiler->addDebugInfo($parent);
if ($parent instanceof ConstantExpression) {
$compiler
->write('$this->parent = $this->loadTemplate(')
->subcompile($parent)
->raw(', ')
->repr($this->source->getName())
->raw(', ')
->repr($parent->getTemplateLine())
->raw(");\n")
;
$compiler->write('$this->parent');
} else {
$compiler->write('$this->getParent($context)');
-27
View File
@@ -498,33 +498,6 @@ EOF
$this->assertEquals('foo', $twig->render('func_string_named_args'));
}
/**
* @expectedException \Twig\Error\RuntimeError
* @expectedExceptionMessage Circular reference detected for Twig template "base.html.twig", path: base.html.twig -> base.html.twig in "base.html.twig" at line 1
*/
public function testFailLoadTemplateOnCircularReference()
{
$twig = new Environment(new ArrayLoader([
'base.html.twig' => '{% extends "base.html.twig" %}',
]));
$twig->load('base.html.twig');
}
/**
* @expectedException \Twig\Error\RuntimeError
* @expectedExceptionMessage Circular reference detected for Twig template "base1.html.twig", path: base1.html.twig -> base2.html.twig -> base1.html.twig in "base1.html.twig" at line 1
*/
public function testFailLoadTemplateOnComplexCircularReference()
{
$twig = new Environment(new ArrayLoader([
'base1.html.twig' => '{% extends "base2.html.twig" %}',
'base2.html.twig' => '{% extends "base1.html.twig" %}',
]));
$twig->load('base1.html.twig');
}
protected function getMockLoader($templateName, $templateContent)
{
// to be removed in 2.0
@@ -4,5 +4,7 @@ Exception for an undefined parent
{% extends 'foo.html' %}
{% set foo = "foo" %}
--DATA--
return []
--EXCEPTION--
Twig\Error\LoaderError: Template "foo.html" is not defined in "index.twig" at line 2.
@@ -9,7 +9,7 @@ version_compare(phpversion(), '7.0.0', '>=')
{{ val2 is same as (0.0) ? 'Yes' : 'No' }}
{{ val is same as (val2) ? 'Yes' : 'No' }}
--DATA--
return array('val' => 0.0)
return ['val' => 0.0]
--EXPECT--
Yes
Yes
@@ -0,0 +1,13 @@
--TEST--
"include" function
--TEMPLATE--
{{ include(['bad.twig', 'good.twig'], ignore_missing = true) }}
NOT DISPLAYED
--TEMPLATE(bad.twig)--
{% extends 'DOES NOT EXIST' %}
--TEMPLATE(good.twig)--
NOT DISPLAYED
--DATA--
return []
--EXCEPTION--
Twig\Error\LoaderError: Template "DOES NOT EXIST" is not defined in "bad.twig" at line 2.
@@ -0,0 +1,13 @@
--TEST--
"include" tag
--TEMPLATE--
{% include ['bad.twig', 'good.twig'] ignore missing %}
NOT DISPLAYED
--TEMPLATE(bad.twig)--
{% extends 'DOES NOT EXIST' %}
--TEMPLATE(good.twig)--
NOT DISPLAYED
--DATA--
return []
--EXCEPTION--
Twig\Error\LoaderError: Template "DOES NOT EXIST" is not defined in "bad.twig" at line 2.
+3 -3
View File
@@ -140,14 +140,13 @@ class __TwigTemplate_%x extends \Twig\Template
{
parent::__construct(\$env);
// line 1
\$this->parent = \$this->loadTemplate("layout.twig", "foo.twig", 1);
\$this->blocks = [
];
}
protected function doGetParent(array \$context)
{
// line 1
return "layout.twig";
}
@@ -156,6 +155,7 @@ class __TwigTemplate_%x extends \Twig\Template
// line 2
\$context["macro"] = \$this->loadTemplate("foo.twig", "foo.twig", 2);
// line 1
\$this->parent = \$this->loadTemplate("layout.twig", "foo.twig", 1);
\$this->parent->display(\$context, array_merge(\$this->blocks, \$blocks));
}
@@ -171,7 +171,7 @@ class __TwigTemplate_%x extends \Twig\Template
public function getDebugInfo()
{
return array ( 37 => 1, 35 => 2, 22 => 1,);
return array ( 36 => 1, 34 => 2, 28 => 1,);
}
/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */