-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathTransTokenParser.php
More file actions
141 lines (121 loc) · 4.69 KB
/
Copy pathTransTokenParser.php
File metadata and controls
141 lines (121 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
declare(strict_types=1);
/*
* This file is part of Twig I18n extension.
*
* (c) 2010-2019 Fabien Potencier
* (c) 2019-2021 phpMyAdmin contributors
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpMyAdmin\Twig\Extensions\TokenParser;
use PhpMyAdmin\Twig\Extensions\Node\I18nNode;
use PhpMyAdmin\Twig\Extensions\Node\TransNode;
use Twig\Error\SyntaxError;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\Variable\ContextVariable;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\Node\TextNode;
use Twig\Token;
use Twig\TokenParser\AbstractTokenParser;
class TransTokenParser extends AbstractTokenParser
{
public function parse(Token $token): Node
{
[
$body,
$plural,
$count,
$context,
$notes,
$domain,
$lineno,
$tag,
] = $this->preParse($token);
return new TransNode($body, $plural, $count, $context, $notes, $domain, $lineno, $tag);
}
/** @psalm-return array{Node, Node|null, AbstractExpression|null, Node|null, Node|null, Node|null, int, string} */
protected function preParse(Token $token): array
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$domain = null;
$count = null;
$plural = null;
$notes = null;
$context = null;
/* If we aren't closing the block, do we have a domain? */
if ($stream->test(Token::NAME_TYPE)) {
$stream->expect(Token::NAME_TYPE, 'from');
$domain = $this->parser->getExpressionParser()->parseExpression();
}
if (! $stream->test(Token::BLOCK_END_TYPE)) {
$body = $this->parser->getExpressionParser()->parseExpression();
} else {
$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideForFork']);
$next = $stream->next()->getValue();
if ($next === 'plural') {
$count = $this->parser->getExpressionParser()->parseExpression();
$stream->expect(Token::BLOCK_END_TYPE);
$plural = $this->parser->subparse([$this, 'decideForFork']);
$next = $stream->next()->getValue();
if ($next === 'notes') {
$stream->expect(Token::BLOCK_END_TYPE);
$notes = $this->parser->subparse([$this, 'decideForEnd'], true);
} elseif ($next === 'context') {
$stream->expect(Token::BLOCK_END_TYPE);
$context = $this->parser->subparse([$this, 'decideForEnd'], true);
}
} elseif ($next === 'context') {
$stream->expect(Token::BLOCK_END_TYPE);
$context = $this->parser->subparse([$this, 'decideForEnd'], true);
} elseif ($next === 'notes') {
$stream->expect(Token::BLOCK_END_TYPE);
$notes = $this->parser->subparse([$this, 'decideForEnd'], true);
}
}
$stream->expect(Token::BLOCK_END_TYPE);
$this->checkTransString($body, $lineno);
if ($notes instanceof TextNode) {
// Don't use TextNode for $notes to avoid it getting merged with $body when optimizing.
$notes = new I18nNode(null, ['data' => $notes->getAttribute('data')], $notes->getTemplateLine());
}
if ($context instanceof TextNode) {
// Don't use TextNode for $context to avoid it getting merged with $body when optimizing.
$context = new I18nNode(null, ['data' => $context->getAttribute('data')], $context->getTemplateLine());
}
return [$body, $plural, $count, $context, $notes, $domain, $lineno, $this->getTag()];
}
public function decideForFork(Token $token): bool
{
return $token->test(['plural', 'context', 'notes', 'endtrans']);
}
public function decideForEnd(Token $token): bool
{
return $token->test('endtrans');
}
public function getTag(): string
{
return 'trans';
}
/** @throws SyntaxError */
protected function checkTransString(Node $body, int $lineno): void
{
foreach ($body as $i => $node) {
if (
$node instanceof TextNode
||
($node instanceof PrintNode && $node->getNode('expr') instanceof ContextVariable)
) {
continue;
}
throw new SyntaxError(
'The text to be translated with "trans" can only contain references to simple variables.',
$lineno,
);
}
}
}