From e0ea4a962a1d48cfa442543d536f9629058c1646 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 14 Dec 2010 14:27:28 +0100 Subject: [PATCH] fixed default() filter behavior when used with strict_variables set to on --- CHANGELOG | 1 + lib/Twig/Node/Expression/Filter.php | 40 ++++++++++++++++++++----- lib/Twig/Node/Expression/Test.php | 2 +- test/Twig/Tests/Fixtures/filters/default.test | 2 + 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index dda3a2f..397decd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ Backward incompatibilities: Changes: + * fixed default() filter behavior when used with strict_variables set to on * fixed filesystem loader compatibility with PHAR files * enhanced error messages when an unexpected token is parsed in an expression * fixed filename not being added to syntax error messages diff --git a/lib/Twig/Node/Expression/Filter.php b/lib/Twig/Node/Expression/Filter.php index 33223d5..3a29548 100644 --- a/lib/Twig/Node/Expression/Filter.php +++ b/lib/Twig/Node/Expression/Filter.php @@ -11,31 +11,55 @@ */ class Twig_Node_Expression_Filter extends Twig_Node_Expression { - public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filter_name, Twig_NodeInterface $arguments, $lineno, $tag = null) + public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) { - parent::__construct(array('node' => $node, 'filter' => $filter_name, 'arguments' => $arguments), array(), $lineno, $tag); + parent::__construct(array('node' => $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag); } public function compile($compiler) { $filterMap = $compiler->getEnvironment()->getFilters(); - $name = $this->getNode('filter')->getAttribute('value'); - $attrs = $this->getNode('arguments'); - if (!isset($filterMap[$name])) { throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine()); + } + $filter = $filterMap[$name]; + + // foo|default('bar') or foo.bar|default('bar') + // compiled to {{ foo is defined ? foo|default('bar') : 'bar' }} + if ('default' === $name && ($this->getNode('node') instanceof Twig_Node_Expression_Name || $this->getNode('node') instanceof Twig_Node_Expression_GetAttr)) { + if ($this->getNode('node') instanceof Twig_Node_Expression_Name) { + $testMap = $compiler->getEnvironment()->getTests(); + $compiler + ->raw($testMap['defined']->compile().'(') + ->repr($this->getNode('node')->getAttribute('name')) + ->raw(', $context)') + ; + } elseif ($this->getNode('node') instanceof Twig_Node_Expression_GetAttr) { + $this->getNode('node')->setAttribute('is_defined_test', true); + $compiler->subcompile($this->getNode('node')); + } + + $compiler->raw(' ? '); + $this->compileFilter($compiler, $filter); + $compiler->raw(' : '); + $compiler->subcompile($this->getNode('arguments')->getNode(0)); } else { - $compiler->raw($filterMap[$name]->compile().($filterMap[$name]->needsEnvironment() ? '($this->env, ' : '(')); + $this->compileFilter($compiler, $filter); } + } + + protected function compileFilter($compiler, $filter) + { + $compiler->raw($filter->compile().($filter->needsEnvironment() ? '($this->env, ' : '(')); $this->getNode('node')->compile($compiler); - foreach ($attrs as $node) { + foreach ($this->getNode('arguments') as $node) { $compiler ->raw(', ') ->subcompile($node) - ; + ; } $compiler->raw(')'); diff --git a/lib/Twig/Node/Expression/Test.php b/lib/Twig/Node/Expression/Test.php index 2ab9aa2..8ef498c 100644 --- a/lib/Twig/Node/Expression/Test.php +++ b/lib/Twig/Node/Expression/Test.php @@ -26,7 +26,7 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression if ('defined' === $this->getAttribute('name')) { if ($this->getNode('node') instanceof Twig_Node_Expression_Name) { $compiler - ->raw($testMap[$this->getAttribute('name')]->compile().'(') + ->raw($testMap['defined']->compile().'(') ->repr($this->getNode('node')->getAttribute('name')) ->raw(', $context)') ; diff --git a/test/Twig/Tests/Fixtures/filters/default.test b/test/Twig/Tests/Fixtures/filters/default.test index 8fd8017..0c975dd 100644 --- a/test/Twig/Tests/Fixtures/filters/default.test +++ b/test/Twig/Tests/Fixtures/filters/default.test @@ -3,8 +3,10 @@ --TEMPLATE-- {{ foo|default('bar') }} {{ bar|default('foo') }} +{{ not_defined|default('bar') }} --DATA-- return array('foo' => null, 'bar' => 'bar') --EXPECT-- bar bar +bar -- 1.7.2.5