1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Twig\Node\Expression\Test;
13
14use Twig\Compiler;
15use Twig\Error\SyntaxError;
16use Twig\Node\Expression\ArrayExpression;
17use Twig\Node\Expression\BlockReferenceExpression;
18use Twig\Node\Expression\ConstantExpression;
19use Twig\Node\Expression\FunctionExpression;
20use Twig\Node\Expression\GetAttrExpression;
21use Twig\Node\Expression\NameExpression;
22use Twig\Node\Expression\TestExpression;
23
24/**
25 * Checks if a variable is defined in the current context.
26 *
27 *    {# defined works with variable names and variable attributes #}
28 *    {% if foo is defined %}
29 *        {# ... #}
30 *    {% endif %}
31 *
32 * @author Fabien Potencier <fabien@symfony.com>
33 */
34class DefinedTest extends TestExpression
35{
36    public function __construct(\Twig_NodeInterface $node, $name, \Twig_NodeInterface $arguments = null, $lineno)
37    {
38        if ($node instanceof NameExpression) {
39            $node->setAttribute('is_defined_test', true);
40        } elseif ($node instanceof GetAttrExpression) {
41            $node->setAttribute('is_defined_test', true);
42            $this->changeIgnoreStrictCheck($node);
43        } elseif ($node instanceof BlockReferenceExpression) {
44            $node->setAttribute('is_defined_test', true);
45        } elseif ($node instanceof FunctionExpression && 'constant' === $node->getAttribute('name')) {
46            $node->setAttribute('is_defined_test', true);
47        } elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) {
48            $node = new ConstantExpression(true, $node->getTemplateLine());
49        } else {
50            throw new SyntaxError('The "defined" test only works with simple variables.', $this->getTemplateLine(), null, null, false);
51        }
52
53        parent::__construct($node, $name, $arguments, $lineno);
54    }
55
56    protected function changeIgnoreStrictCheck(GetAttrExpression $node)
57    {
58        $node->setAttribute('ignore_strict_check', true);
59
60        if ($node->getNode('node') instanceof GetAttrExpression) {
61            $this->changeIgnoreStrictCheck($node->getNode('node'));
62        }
63    }
64
65    public function compile(Compiler $compiler)
66    {
67        $compiler->subcompile($this->getNode('node'));
68    }
69}
70
71class_alias('Twig\Node\Expression\Test\DefinedTest', 'Twig_Node_Expression_Test_Defined');
72