2024-06-20 14:10:42 +00:00
< ? php
/*
* This file is part of Twig .
*
* ( c ) Fabien Potencier
* ( c ) Armin Ronacher
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Twig\Node\Expression ;
use Twig\Compiler ;
use Twig\Extension\SandboxExtension ;
use Twig\Template ;
class GetAttrExpression extends AbstractExpression
{
2025-01-13 09:56:01 +00:00
/**
* @ param ArrayExpression | NameExpression | null $arguments
*/
2024-06-20 14:10:42 +00:00
public function __construct ( AbstractExpression $node , AbstractExpression $attribute , ? AbstractExpression $arguments , string $type , int $lineno )
{
$nodes = [ 'node' => $node , 'attribute' => $attribute ];
if ( null !== $arguments ) {
$nodes [ 'arguments' ] = $arguments ;
}
2025-01-13 09:56:01 +00:00
if ( $arguments && ! $arguments instanceof ArrayExpression && ! $arguments instanceof NameExpression ) {
trigger_deprecation ( 'twig/twig' , '3.15' , \sprintf ( 'Not passing a "%s" instance as the "arguments" argument of the "%s" constructor is deprecated ("%s" given).' , ArrayExpression :: class , static :: class , $arguments :: class ));
}
2024-06-20 14:10:42 +00:00
parent :: __construct ( $nodes , [ 'type' => $type , 'is_defined_test' => false , 'ignore_strict_check' => false , 'optimizable' => true ], $lineno );
}
public function compile ( Compiler $compiler ) : void
{
$env = $compiler -> getEnvironment ();
2025-01-13 09:56:01 +00:00
$arrayAccessSandbox = false ;
2024-06-20 14:10:42 +00:00
// optimize array calls
if (
$this -> getAttribute ( 'optimizable' )
&& ( ! $env -> isStrictVariables () || $this -> getAttribute ( 'ignore_strict_check' ))
&& ! $this -> getAttribute ( 'is_defined_test' )
&& Template :: ARRAY_CALL === $this -> getAttribute ( 'type' )
) {
$var = '$' . $compiler -> getVarName ();
$compiler
-> raw ( '((' . $var . ' = ' )
-> subcompile ( $this -> getNode ( 'node' ))
-> raw ( ') && is_array(' )
2025-01-13 09:56:01 +00:00
-> raw ( $var );
if ( ! $env -> hasExtension ( SandboxExtension :: class )) {
$compiler
-> raw ( ') || ' )
-> raw ( $var )
-> raw ( ' instanceof ArrayAccess ? (' )
-> raw ( $var )
-> raw ( '[' )
-> subcompile ( $this -> getNode ( 'attribute' ))
-> raw ( '] ?? null) : null)' )
;
return ;
}
$arrayAccessSandbox = true ;
$compiler
2024-06-20 14:10:42 +00:00
-> raw ( ') || ' )
-> raw ( $var )
2025-01-13 09:56:01 +00:00
-> raw ( ' instanceof ArrayAccess && in_array(' )
-> raw ( $var . '::class' )
-> raw ( ', CoreExtension::ARRAY_LIKE_CLASSES, true) ? (' )
2024-06-20 14:10:42 +00:00
-> raw ( $var )
-> raw ( '[' )
-> subcompile ( $this -> getNode ( 'attribute' ))
2025-01-13 09:56:01 +00:00
-> raw ( '] ?? null) : ' )
2024-06-20 14:10:42 +00:00
;
}
$compiler -> raw ( 'CoreExtension::getAttribute($this->env, $this->source, ' );
if ( $this -> getAttribute ( 'ignore_strict_check' )) {
$this -> getNode ( 'node' ) -> setAttribute ( 'ignore_strict_check' , true );
}
$compiler
-> subcompile ( $this -> getNode ( 'node' ))
-> raw ( ', ' )
-> subcompile ( $this -> getNode ( 'attribute' ))
;
if ( $this -> hasNode ( 'arguments' )) {
$compiler -> raw ( ', ' ) -> subcompile ( $this -> getNode ( 'arguments' ));
} else {
$compiler -> raw ( ', []' );
}
$compiler -> raw ( ', ' )
-> repr ( $this -> getAttribute ( 'type' ))
-> raw ( ', ' ) -> repr ( $this -> getAttribute ( 'is_defined_test' ))
-> raw ( ', ' ) -> repr ( $this -> getAttribute ( 'ignore_strict_check' ))
-> raw ( ', ' ) -> repr ( $env -> hasExtension ( SandboxExtension :: class ))
-> raw ( ', ' ) -> repr ( $this -> getNode ( 'node' ) -> getTemplateLine ())
-> raw ( ')' )
;
2025-01-13 09:56:01 +00:00
if ( $arrayAccessSandbox ) {
$compiler -> raw ( ')' );
}
2024-06-20 14:10:42 +00:00
}
}