shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

For.php (4299B)


      1 <?php
      2 
      3 /*
      4  * This file is part of Twig.
      5  *
      6  * (c) 2009 Fabien Potencier
      7  * (c) 2009 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 /**
     14  * Represents a for node.
     15  *
     16  * @author Fabien Potencier <fabien@symfony.com>
     17  */
     18 class Twig_Node_For extends Twig_Node
     19 {
     20     protected $loop;
     21 
     22     public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_Node_Expression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
     23     {
     24         $body = new Twig_Node(array($body, $this->loop = new Twig_Node_ForLoop($lineno, $tag)));
     25 
     26         if (null !== $ifexpr) {
     27             $body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag);
     28         }
     29 
     30         parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag);
     31     }
     32 
     33     public function compile(Twig_Compiler $compiler)
     34     {
     35         $compiler
     36             ->addDebugInfo($this)
     37             ->write("\$context['_parent'] = \$context;\n")
     38             ->write("\$context['_seq'] = twig_ensure_traversable(")
     39             ->subcompile($this->getNode('seq'))
     40             ->raw(");\n")
     41         ;
     42 
     43         if (null !== $this->getNode('else')) {
     44             $compiler->write("\$context['_iterated'] = false;\n");
     45         }
     46 
     47         if ($this->getAttribute('with_loop')) {
     48             $compiler
     49                 ->write("\$context['loop'] = array(\n")
     50                 ->write("  'parent' => \$context['_parent'],\n")
     51                 ->write("  'index0' => 0,\n")
     52                 ->write("  'index'  => 1,\n")
     53                 ->write("  'first'  => true,\n")
     54                 ->write(");\n")
     55             ;
     56 
     57             if (!$this->getAttribute('ifexpr')) {
     58                 $compiler
     59                     ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n")
     60                     ->indent()
     61                     ->write("\$length = count(\$context['_seq']);\n")
     62                     ->write("\$context['loop']['revindex0'] = \$length - 1;\n")
     63                     ->write("\$context['loop']['revindex'] = \$length;\n")
     64                     ->write("\$context['loop']['length'] = \$length;\n")
     65                     ->write("\$context['loop']['last'] = 1 === \$length;\n")
     66                     ->outdent()
     67                     ->write("}\n")
     68                 ;
     69             }
     70         }
     71 
     72         $this->loop->setAttribute('else', null !== $this->getNode('else'));
     73         $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
     74         $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
     75 
     76         $compiler
     77             ->write("foreach (\$context['_seq'] as ")
     78             ->subcompile($this->getNode('key_target'))
     79             ->raw(' => ')
     80             ->subcompile($this->getNode('value_target'))
     81             ->raw(") {\n")
     82             ->indent()
     83             ->subcompile($this->getNode('body'))
     84             ->outdent()
     85             ->write("}\n")
     86         ;
     87 
     88         if (null !== $this->getNode('else')) {
     89             $compiler
     90                 ->write("if (!\$context['_iterated']) {\n")
     91                 ->indent()
     92                 ->subcompile($this->getNode('else'))
     93                 ->outdent()
     94                 ->write("}\n")
     95             ;
     96         }
     97 
     98         $compiler->write("\$_parent = \$context['_parent'];\n");
     99 
    100         // remove some "private" loop variables (needed for nested loops)
    101         $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");
    102 
    103         // keep the values set in the inner context for variables defined in the outer context
    104         $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
    105     }
    106 }