mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 10:56:38 +00:00
Make a.b is defined not throw an exception if a is not defined (in strict mode)
This commit is contained in:
@@ -23,28 +23,28 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression
|
||||
throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine());
|
||||
}
|
||||
|
||||
$node = $this->getNode('node');
|
||||
|
||||
// The default filter is intercepted when the filtered value
|
||||
// is a name (like obj) or an attribute (like obj.attr)
|
||||
// In such a case, it's compiled to {{ obj is defined ? obj|default('bar') : 'bar' }}
|
||||
if ('default' === $name && ($this->getNode('node') instanceof Twig_Node_Expression_Name || $this->getNode('node') instanceof Twig_Node_Expression_GetAttr)) {
|
||||
$compiler->raw('((');
|
||||
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'));
|
||||
$this->getNode('node')->removeAttribute('is_defined_test');
|
||||
if ('default' === $name && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
|
||||
$compiler
|
||||
->raw('((')
|
||||
->subcompile(new Twig_Node_Expression_Test($node, 'defined', new Twig_Node(), $this->getLine()))
|
||||
->raw(') ? (')
|
||||
;
|
||||
|
||||
$this->compileFilter($compiler, $filter);
|
||||
|
||||
$compiler->raw(') : (');
|
||||
|
||||
if ($this->getNode('arguments')->hasNode(0)) {
|
||||
$compiler->subcompile($this->getNode('arguments')->getNode(0));
|
||||
} else {
|
||||
$compiler->string('');
|
||||
}
|
||||
|
||||
$compiler->raw(') ? (');
|
||||
$this->compileFilter($compiler, $filter);
|
||||
$compiler->raw(') : (');
|
||||
$compiler->subcompile($this->getNode('arguments')->getNode(0));
|
||||
$compiler->raw('))');
|
||||
} else {
|
||||
$this->compileFilter($compiler, $filter);
|
||||
@@ -57,10 +57,9 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression
|
||||
->raw($filter->compile().'(')
|
||||
->raw($filter->needsEnvironment() ? '$this->env, ' : '')
|
||||
->raw($filter->needsContext() ? '$context, ' : '')
|
||||
->subcompile($this->getNode('node'))
|
||||
;
|
||||
|
||||
$this->getNode('node')->compile($compiler);
|
||||
|
||||
foreach ($this->getNode('arguments') as $node) {
|
||||
$compiler
|
||||
->raw(', ')
|
||||
|
||||
@@ -18,9 +18,20 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('$this->getAttribute(');
|
||||
|
||||
if ($this->hasAttribute('is_defined_test')) {
|
||||
$compiler->subcompile(new Twig_Node_Expression_Filter(
|
||||
$this->getNode('node'),
|
||||
new Twig_Node_Expression_Constant('default', $this->getLine()),
|
||||
new Twig_Node(),
|
||||
$this->getLine()
|
||||
));
|
||||
} else {
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('$this->getAttribute(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('attribute'))
|
||||
->raw(', array(')
|
||||
|
||||
@@ -18,16 +18,26 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
if ('_self' === $this->getAttribute('name')) {
|
||||
$compiler->raw('$this');
|
||||
} elseif ('_context' === $this->getAttribute('name')) {
|
||||
$compiler->raw('$context');
|
||||
} elseif ('_charset' === $this->getAttribute('name')) {
|
||||
$compiler->raw('$this->env->getCharset()');
|
||||
static $specialVars = array(
|
||||
'_self' => '$this',
|
||||
'_context' => '$context',
|
||||
'_charset' => '$this->env->getCharset()',
|
||||
);
|
||||
|
||||
$name = $this->getAttribute('name');
|
||||
|
||||
if ($this->hasAttribute('is_defined_test')) {
|
||||
if (isset($specialVars[$name])) {
|
||||
$compiler->repr(true);
|
||||
} else {
|
||||
$compiler->raw('array_key_exists(')->repr($name)->raw(', $context)');
|
||||
}
|
||||
} elseif (isset($specialVars[$name])) {
|
||||
$compiler->raw($specialVars[$name]);
|
||||
} elseif ($compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler->raw(sprintf('$this->getContext($context, \'%s\')', $this->getAttribute('name')));
|
||||
$compiler->raw(sprintf('$this->getContext($context, \'%s\')', $name));
|
||||
} else {
|
||||
$compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $this->getAttribute('name'), $this->getAttribute('name')));
|
||||
$compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $name, $name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,19 +22,15 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression
|
||||
throw new Twig_Error_Syntax(sprintf('The test "%s" does not exist', $this->getAttribute('name')), $this->getLine());
|
||||
}
|
||||
|
||||
$name = $this->getAttribute('name');
|
||||
$node = $this->getNode('node');
|
||||
|
||||
// defined is a special case
|
||||
if ('defined' === $this->getAttribute('name')) {
|
||||
if ($this->getNode('node') instanceof Twig_Node_Expression_Name) {
|
||||
$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'))
|
||||
;
|
||||
if ('defined' === $name) {
|
||||
if ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
$compiler->subcompile($node);
|
||||
$node->removeAttribute('is_defined_test');
|
||||
} else {
|
||||
throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
|
||||
}
|
||||
@@ -42,16 +38,16 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw($testMap[$this->getAttribute('name')]->compile().'(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw($testMap[$name]->compile().'(')
|
||||
->subcompile($node)
|
||||
;
|
||||
|
||||
if (null !== $this->getNode('arguments')) {
|
||||
$compiler->raw(', ');
|
||||
|
||||
$max = count($this->getNode('arguments')) - 1;
|
||||
foreach ($this->getNode('arguments') as $i => $node) {
|
||||
$compiler->subcompile($node);
|
||||
foreach ($this->getNode('arguments') as $i => $arg) {
|
||||
$compiler->subcompile($arg);
|
||||
|
||||
if ($i != $max) {
|
||||
$compiler->raw(', ');
|
||||
|
||||
Reference in New Issue
Block a user