1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * (c) Armin Ronacher 8 * 9 * For the full copyright and license information, please view the LICENSE 10 * file that was distributed with this source code. 11 */ 12 13namespace Twig\Node\Expression; 14 15use Twig\Compiler; 16use Twig\Extension\SandboxExtension; 17use Twig\Template; 18 19class GetAttrExpression extends AbstractExpression 20{ 21 public function __construct(AbstractExpression $node, AbstractExpression $attribute, ?AbstractExpression $arguments, string $type, int $lineno) 22 { 23 $nodes = ['node' => $node, 'attribute' => $attribute]; 24 if (null !== $arguments) { 25 $nodes['arguments'] = $arguments; 26 } 27 28 parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'optimizable' => true], $lineno); 29 } 30 31 public function compile(Compiler $compiler) 32 { 33 $env = $compiler->getEnvironment(); 34 35 // optimize array calls 36 if ( 37 $this->getAttribute('optimizable') 38 && (!$env->isStrictVariables() || $this->getAttribute('ignore_strict_check')) 39 && !$this->getAttribute('is_defined_test') 40 && Template::ARRAY_CALL === $this->getAttribute('type') 41 ) { 42 $var = '$'.$compiler->getVarName(); 43 $compiler 44 ->raw('(('.$var.' = ') 45 ->subcompile($this->getNode('node')) 46 ->raw(') && is_array(') 47 ->raw($var) 48 ->raw(') || ') 49 ->raw($var) 50 ->raw(' instanceof ArrayAccess ? (') 51 ->raw($var) 52 ->raw('[') 53 ->subcompile($this->getNode('attribute')) 54 ->raw('] ?? null) : null)') 55 ; 56 57 return; 58 } 59 60 $compiler->raw('twig_get_attribute($this->env, $this->source, '); 61 62 if ($this->getAttribute('ignore_strict_check')) { 63 $this->getNode('node')->setAttribute('ignore_strict_check', true); 64 } 65 66 $compiler 67 ->subcompile($this->getNode('node')) 68 ->raw(', ') 69 ->subcompile($this->getNode('attribute')) 70 ; 71 72 if ($this->hasNode('arguments')) { 73 $compiler->raw(', ')->subcompile($this->getNode('arguments')); 74 } else { 75 $compiler->raw(', []'); 76 } 77 78 $compiler->raw(', ') 79 ->repr($this->getAttribute('type')) 80 ->raw(', ')->repr($this->getAttribute('is_defined_test')) 81 ->raw(', ')->repr($this->getAttribute('ignore_strict_check')) 82 ->raw(', ')->repr($env->hasExtension(SandboxExtension::class)) 83 ->raw(', ')->repr($this->getNode('node')->getTemplateLine()) 84 ->raw(')') 85 ; 86 } 87} 88 89class_alias('Twig\Node\Expression\GetAttrExpression', 'Twig_Node_Expression_GetAttr'); 90