blob: 2fbdfe0901f9de40d5f91649abd5c1fea3d6250a [file] [log] [blame]
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +01001<?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\TokenParser;
13
14use Twig\Error\SyntaxError;
15use Twig\Node\Node;
16use Twig\Node\SetNode;
17use Twig\Token;
18
19/**
20 * Defines a variable.
21 *
22 * {% set foo = 'foo' %}
23 * {% set foo = [1, 2] %}
24 * {% set foo = {'foo': 'bar'} %}
25 * {% set foo = 'foo' ~ 'bar' %}
26 * {% set foo, bar = 'foo', 'bar' %}
27 * {% set foo %}Some content{% endset %}
28 *
29 * @internal
30 */
31final class SetTokenParser extends AbstractTokenParser
32{
33 public function parse(Token $token): Node
34 {
35 $lineno = $token->getLine();
36 $stream = $this->parser->getStream();
37 $names = $this->parser->getExpressionParser()->parseAssignmentExpression();
38
39 $capture = false;
40 if ($stream->nextIf(/* Token::OPERATOR_TYPE */ 8, '=')) {
41 $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
42
43 $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
44
45 if (\count($names) !== \count($values)) {
46 throw new SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
47 }
48 } else {
49 $capture = true;
50
51 if (\count($names) > 1) {
52 throw new SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
53 }
54
55 $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
56
57 $values = $this->parser->subparse([$this, 'decideBlockEnd'], true);
58 $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
59 }
60
61 return new SetNode($capture, $names, $values, $lineno, $this->getTag());
62 }
63
64 public function decideBlockEnd(Token $token): bool
65 {
66 return $token->test('endset');
67 }
68
69 public function getTag(): string
70 {
71 return 'set';
72 }
73}