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\Attribute\FirstClassTwigCallableReady; 15use Twig\Compiler; 16use Twig\Error\SyntaxError; 17use Twig\Node\Expression\AbstractExpression; 18use Twig\Node\Expression\SupportDefinedTestInterface; 19use Twig\Node\Expression\TestExpression; 20use Twig\Node\Node; 21use Twig\TwigTest; 22 23/** 24 * Checks if a variable is defined in the current context. 25 * 26 * {# defined works with variable names and variable attributes #} 27 * {% if foo is defined %} 28 * {# ... #} 29 * {% endif %} 30 * 31 * @author Fabien Potencier <fabien@symfony.com> 32 */ 33class DefinedTest extends TestExpression 34{ 35 /** 36 * @param AbstractExpression $node 37 */ 38 #[FirstClassTwigCallableReady] 39 public function __construct(Node $node, TwigTest|string $name, ?Node $arguments, int $lineno) 40 { 41 if (!$node instanceof AbstractExpression) { 42 trigger_deprecation('twig/twig', '3.15', 'Not passing a "%s" instance to the "node" argument of "%s" is deprecated ("%s" given).', AbstractExpression::class, static::class, $node::class); 43 } 44 45 if (!$node instanceof SupportDefinedTestInterface) { 46 throw new SyntaxError('The "defined" test only works with simple variables.', $lineno); 47 } 48 49 $node->enableDefinedTest(); 50 51 if (\is_string($name) && 'defined' !== $name) { 52 trigger_deprecation('twig/twig', '3.12', 'Creating a "DefinedTest" instance with a test name that is not "defined" is deprecated.'); 53 } 54 55 parent::__construct($node, $name, $arguments, $lineno); 56 } 57 58 public function compile(Compiler $compiler): void 59 { 60 $compiler->subcompile($this->getNode('node')); 61 } 62 63 public function getStringCoercedChildNames(): array 64 { 65 // the `defined` test does not coerce its node to string (it only inspects existence) 66 return []; 67 } 68} 69