Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ForTokenParser.php
001 <?php
002
003 /*
004 * This file is part of Twig.
005 *
006 * (c) Fabien Potencier
007 * (c) Armin Ronacher
008 *
009 * For the full copyright and license information, please view the LICENSE
010 * file that was distributed with this source code.
011 */
012
013 namespace Twig\TokenParser;
014
015 use Twig\Error\SyntaxError;
016 use Twig\Node\Expression\AssignNameExpression;
017 use Twig\Node\Expression\ConstantExpression;
018 use Twig\Node\Expression\GetAttrExpression;
019 use Twig\Node\Expression\NameExpression;
020 use Twig\Node\ForNode;
021 use Twig\Node\Node;
022 use Twig\Token;
023 use Twig\TokenStream;
024
025 /**
026 * Loops over each item of a sequence.
027 *
028 * <ul>
029 * {% for user in users %}
030 * <li>{{ user.username|e }}</li>
031 * {% endfor %}
032 * </ul>
033 */
034 final class ForTokenParser extends AbstractTokenParser
035 {
036 public function parse(Token $token)
037 {
038 $lineno = $token->getLine();
039 $stream = $this->parser->getStream();
040 $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
041 $stream->expect(/* Token::OPERATOR_TYPE */ 8, 'in');
042 $seq = $this->parser->getExpressionParser()->parseExpression();
043
044 $ifexpr = null;
045 if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'if')) {
046 @trigger_error(sprintf('Using an "if" condition on "for" tag in "%s" at line %d is deprecated since Twig 2.10.0, use a "filter" filter or an "if" condition inside the "for" body instead (if your condition depends on a variable updated inside the loop).', $stream->getSourceContext()->getName(), $lineno), \E_USER_DEPRECATED);
047
048 $ifexpr = $this->parser->getExpressionParser()->parseExpression();
049 }
050
051 $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
052 $body = $this->parser->subparse([$this, 'decideForFork']);
053 if ('else' == $stream->next()->getValue()) {
054 $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
055 $else = $this->parser->subparse([$this, 'decideForEnd'], true);
056 } else {
057 $else = null;
058 }
059 $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
060
061 if (\count($targets) > 1) {
062 $keyTarget = $targets->getNode(0);
063 $keyTarget = new AssignNameExpression($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
064 $valueTarget = $targets->getNode(1);
065 $valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
066 } else {
067 $keyTarget = new AssignNameExpression('_key', $lineno);
068 $valueTarget = $targets->getNode(0);
069 $valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
070 }
071
072 if ($ifexpr) {
073 $this->checkLoopUsageCondition($stream, $ifexpr);
074 $this->checkLoopUsageBody($stream, $body);
075 }
076
077 return new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
078 }
079
080 public function decideForFork(Token $token)
081 {
082 return $token->test(['else', 'endfor']);
083 }
084
085 public function decideForEnd(Token $token)
086 {
087 return $token->test('endfor');
088 }
089
090 // the loop variable cannot be used in the condition
091 private function checkLoopUsageCondition(TokenStream $stream, Node $node)
092 {
093 if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
094 throw new SyntaxError('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext());
095 }
096
097 foreach ($node as $n) {
098 if (!$n) {
099 continue;
100 }
101
102 $this->checkLoopUsageCondition($stream, $n);
103 }
104 }
105
106 // check usage of non-defined loop-items
107 // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include)
108 private function checkLoopUsageBody(TokenStream $stream, Node $node)
109 {
110 if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
111 $attribute = $node->getNode('attribute');
112 if ($attribute instanceof ConstantExpression && \in_array($attribute->getAttribute('value'), ['length', 'revindex0', 'revindex', 'last'])) {
113 throw new SyntaxError(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext());
114 }
115 }
116
117 // should check for parent.loop.XXX usage
118 if ($node instanceof ForNode) {
119 return;
120 }
121
122 foreach ($node as $n) {
123 if (!$n) {
124 continue;
125 }
126
127 $this->checkLoopUsageBody($stream, $n);
128 }
129 }
130
131 public function getTag()
132 {
133 return 'for';
134 }
135 }
136
137 class_alias('Twig\TokenParser\ForTokenParser', 'Twig_TokenParser_For');
138