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\MethodCallExpression; 22use Twig\Node\Expression\NameExpression; 23use Twig\Node\Expression\TestExpression; 24use Twig\Node\Node; 25 26/** 27 * Checks if a variable is defined in the current context. 28 * 29 * {# defined works with variable names and variable attributes #} 30 * {% if foo is defined %} 31 * {# ... #} 32 * {% endif %} 33 * 34 * @author Fabien Potencier <fabien@symfony.com> 35 */ 36class DefinedTest extends TestExpression 37{ 38 public function __construct(Node $node, string $name, ?Node $arguments, int $lineno) 39 { 40 if ($node instanceof NameExpression) { 41 $node->setAttribute('is_defined_test', true); 42 } elseif ($node instanceof GetAttrExpression) { 43 $node->setAttribute('is_defined_test', true); 44 $this->changeIgnoreStrictCheck($node); 45 } elseif ($node instanceof BlockReferenceExpression) { 46 $node->setAttribute('is_defined_test', true); 47 } elseif ($node instanceof FunctionExpression && 'constant' === $node->getAttribute('name')) { 48 $node->setAttribute('is_defined_test', true); 49 } elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) { 50 $node = new ConstantExpression(true, $node->getTemplateLine()); 51 } elseif ($node instanceof MethodCallExpression) { 52 $node->setAttribute('is_defined_test', true); 53 } else { 54 throw new SyntaxError('The "defined" test only works with simple variables.', $lineno); 55 } 56 57 parent::__construct($node, $name, $arguments, $lineno); 58 } 59 60 private function changeIgnoreStrictCheck(GetAttrExpression $node) 61 { 62 $node->setAttribute('optimizable', false); 63 $node->setAttribute('ignore_strict_check', true); 64 65 if ($node->getNode('node') instanceof GetAttrExpression) { 66 $this->changeIgnoreStrictCheck($node->getNode('node')); 67 } 68 } 69 70 public function compile(Compiler $compiler) 71 { 72 $compiler->subcompile($this->getNode('node')); 73 } 74} 75 76class_alias('Twig\Node\Expression\Test\DefinedTest', 'Twig_Node_Expression_Test_Defined'); 77