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\Binary; 13 14use Twig\Compiler; 15use Twig\Error\SyntaxError; 16use Twig\Extension\SandboxExtension; 17use Twig\Node\Expression\AbstractExpression; 18use Twig\Node\Expression\ArrayExpression; 19use Twig\Node\Expression\Variable\ContextVariable; 20use Twig\Node\Node; 21 22/** 23 * @internal 24 */ 25class ObjectDestructuringSetBinary extends AbstractBinary 26{ 27 /** @var list<array{property: string, variable: string}> */ 28 private array $mappings = []; 29 30 /** 31 * @param ArrayExpression $left The array expression containing object/mapping destructuring properties 32 * @param AbstractExpression $right The expression providing values for assignment 33 */ 34 public function __construct(Node $left, Node $right, int $lineno) 35 { 36 if (!$left instanceof ArrayExpression) { 37 throw new \LogicException('Left side must be ArrayExpression for object/mapping destructuring.'); 38 } 39 foreach ($left->getKeyValuePairs() as $pair) { 40 if (!$pair['value'] instanceof ContextVariable) { 41 throw new SyntaxError(\sprintf('Cannot assign to "%s", only variables can be assigned in object/mapping destructuring.', $pair['value']::class), $lineno); 42 } 43 44 $this->mappings[] = [ 45 'property' => $pair['key']->getAttribute('value'), 46 'variable' => $pair['value']->getAttribute('name'), 47 ]; 48 } 49 50 parent::__construct($left, $right, $lineno); 51 } 52 53 public function compile(Compiler $compiler): void 54 { 55 $compiler->addDebugInfo($this); 56 $compiler->raw('['); 57 foreach ($this->mappings as $i => $mapping) { 58 if ($i) { 59 $compiler->raw(', '); 60 } 61 $compiler->raw('$context[')->repr($mapping['variable'])->raw(']'); 62 } 63 $compiler->raw('] = ['); 64 foreach ($this->mappings as $i => $mapping) { 65 if ($i) { 66 $compiler->raw(', '); 67 } 68 $compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ')->subcompile($this->getNode('right'))->raw(', ')->repr($mapping['property'])->raw(', [], \\Twig\\Template::ANY_CALL, false, false, ')->repr($compiler->getEnvironment()->hasExtension(SandboxExtension::class))->raw(', ')->repr($this->getNode('right')->getTemplateLine())->raw(')'); 69 } 70 $compiler->raw(']'); 71 } 72 73 public function operator(Compiler $compiler): Compiler 74 { 75 return $compiler->raw('='); 76 } 77} 78