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(') ? (')
+ ;
- $compiler->raw(') ? (');
$this->compileFilter($compiler, $filter);
+
$compiler->raw(') : (');
- $compiler->subcompile($this->getNode('arguments')->getNode(0));
+
+ if ($this->getNode('arguments')->hasNode(0)) {
+ $compiler->subcompile($this->getNode('arguments')->getNode(0));
+ } else {
+ $compiler->string('');
+ }
+
$compiler->raw('))');
} else {
$this->compileFilter($compiler, $filter);
->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(', ')
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(')
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));
}
}
}
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());
}
}
$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(', ');