vendor/twig/lib/Twig/Node/For.php
author ymh <ymh.work@gmail.com>
Sat, 24 Sep 2011 15:40:41 +0200
changeset 0 7f95f8617b0b
permissions -rwxr-xr-x
first commit
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
/*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * This file is part of Twig.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * (c) 2009 Fabien Potencier
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * (c) 2009 Armin Ronacher
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * For the full copyright and license information, please view the LICENSE
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * file that was distributed with this source code.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
/**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 * Represents a for node.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * @package    twig
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 * @author     Fabien Potencier <fabien@symfony.com>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
class Twig_Node_For extends Twig_Node
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
        parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true), $lineno, $tag);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
     * Compiles the node to PHP.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
     * @param Twig_Compiler A Twig_Compiler instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
    public function compile(Twig_Compiler $compiler)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
        $compiler
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
            ->addDebugInfo($this)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
            // the (array) cast bypasses a PHP 5.2.6 bug
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
            ->write("\$context['_parent'] = (array) \$context;\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
            ->write("\$context['_seq'] = twig_ensure_traversable(")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
            ->subcompile($this->getNode('seq'))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
            ->raw(");\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
        ;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
        if (null !== $this->getNode('else')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
            $compiler->write("\$context['_iterated'] = false;\n");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
        if ($this->getAttribute('with_loop')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
            $compiler
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
                ->write("\$context['loop'] = array(\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
                ->write("  'parent' => \$context['_parent'],\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
                ->write("  'index0' => 0,\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
                ->write("  'index'  => 1,\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
                ->write("  'first'  => true,\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
                ->write(");\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
                ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
                ->indent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
                ->write("\$length = count(\$context['_seq']);\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
                ->write("\$context['loop']['revindex0'] = \$length - 1;\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
                ->write("\$context['loop']['revindex'] = \$length;\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
                ->write("\$context['loop']['length'] = \$length;\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
                ->write("\$context['loop']['last'] = 1 === \$length;\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
                ->outdent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
                ->write("}\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
            ;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        $compiler
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
            ->write("foreach (\$context['_seq'] as ")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
            ->subcompile($this->getNode('key_target'))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
            ->raw(" => ")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
            ->subcompile($this->getNode('value_target'))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
            ->raw(") {\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
            ->indent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        ;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        $compiler->subcompile($this->getNode('body'));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        if (null !== $this->getNode('else')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
            $compiler->write("\$context['_iterated'] = true;\n");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        if ($this->getAttribute('with_loop')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
            $compiler
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
                ->write("++\$context['loop']['index0'];\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
                ->write("++\$context['loop']['index'];\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
                ->write("\$context['loop']['first'] = false;\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
                ->write("if (isset(\$context['loop']['length'])) {\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
                ->indent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
                ->write("--\$context['loop']['revindex0'];\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
                ->write("--\$context['loop']['revindex'];\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
                ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
                ->outdent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
                ->write("}\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
            ;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        $compiler
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
            ->outdent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
            ->write("}\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
        ;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
        if (null !== $this->getNode('else')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
            $compiler
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
                ->write("if (!\$context['_iterated']) {\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
                ->indent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
                ->subcompile($this->getNode('else'))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
                ->outdent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
                ->write("}\n")
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
            ;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
        $compiler->write("\$_parent = \$context['_parent'];\n");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
        // remove some "private" loop variables (needed for nested loops)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
        $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");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
        // keep the values set in the inner context for variables defined in the outer context
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
        $compiler->write("\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent));\n");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
}