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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ForTokenParser.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 4.95 KiB


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