[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

/vendor/twig/twig/src/Node/ -> ForNode.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of Twig.
   5   *
   6   * (c) Fabien Potencier
   7   * (c) Armin Ronacher
   8   *
   9   * For the full copyright and license information, please view the LICENSE
  10   * file that was distributed with this source code.
  11   */
  12  
  13  namespace Twig\Node;
  14  
  15  use Twig\Compiler;
  16  use Twig\Node\Expression\AbstractExpression;
  17  use Twig\Node\Expression\AssignNameExpression;
  18  
  19  /**
  20   * Represents a for node.
  21   *
  22   * @author Fabien Potencier <fabien@symfony.com>
  23   */
  24  class ForNode extends Node
  25  {
  26      private $loop;
  27  
  28      public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, ?AbstractExpression $ifexpr, Node $body, ?Node $else, int $lineno, string $tag = null)
  29      {
  30          $body = new Node([$body, $this->loop = new ForLoopNode($lineno, $tag)]);
  31  
  32          if (null !== $ifexpr) {
  33              $body = new IfNode(new Node([$ifexpr, $body]), null, $lineno, $tag);
  34          }
  35  
  36          $nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body];
  37          if (null !== $else) {
  38              $nodes['else'] = $else;
  39          }
  40  
  41          parent::__construct($nodes, ['with_loop' => true, 'ifexpr' => null !== $ifexpr], $lineno, $tag);
  42      }
  43  
  44      public function compile(Compiler $compiler)
  45      {
  46          $compiler
  47              ->addDebugInfo($this)
  48              ->write("\$context['_parent'] = \$context;\n")
  49              ->write("\$context['_seq'] = twig_ensure_traversable(")
  50              ->subcompile($this->getNode('seq'))
  51              ->raw(");\n")
  52          ;
  53  
  54          if ($this->hasNode('else')) {
  55              $compiler->write("\$context['_iterated'] = false;\n");
  56          }
  57  
  58          if ($this->getAttribute('with_loop')) {
  59              $compiler
  60                  ->write("\$context['loop'] = [\n")
  61                  ->write("  'parent' => \$context['_parent'],\n")
  62                  ->write("  'index0' => 0,\n")
  63                  ->write("  'index'  => 1,\n")
  64                  ->write("  'first'  => true,\n")
  65                  ->write("];\n")
  66              ;
  67  
  68              if (!$this->getAttribute('ifexpr')) {
  69                  $compiler
  70                      ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \Countable)) {\n")
  71                      ->indent()
  72                      ->write("\$length = count(\$context['_seq']);\n")
  73                      ->write("\$context['loop']['revindex0'] = \$length - 1;\n")
  74                      ->write("\$context['loop']['revindex'] = \$length;\n")
  75                      ->write("\$context['loop']['length'] = \$length;\n")
  76                      ->write("\$context['loop']['last'] = 1 === \$length;\n")
  77                      ->outdent()
  78                      ->write("}\n")
  79                  ;
  80              }
  81          }
  82  
  83          $this->loop->setAttribute('else', $this->hasNode('else'));
  84          $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
  85          $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
  86  
  87          $compiler
  88              ->write("foreach (\$context['_seq'] as ")
  89              ->subcompile($this->getNode('key_target'))
  90              ->raw(' => ')
  91              ->subcompile($this->getNode('value_target'))
  92              ->raw(") {\n")
  93              ->indent()
  94              ->subcompile($this->getNode('body'))
  95              ->outdent()
  96              ->write("}\n")
  97          ;
  98  
  99          if ($this->hasNode('else')) {
 100              $compiler
 101                  ->write("if (!\$context['_iterated']) {\n")
 102                  ->indent()
 103                  ->subcompile($this->getNode('else'))
 104                  ->outdent()
 105                  ->write("}\n")
 106              ;
 107          }
 108  
 109          $compiler->write("\$_parent = \$context['_parent'];\n");
 110  
 111          // remove some "private" loop variables (needed for nested loops)
 112          $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n");
 113  
 114          // keep the values set in the inner context for variables defined in the outer context
 115          $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
 116      }
 117  }
 118  
 119  class_alias('Twig\Node\ForNode', 'Twig_Node_For');


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1