aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/template/twig/node/begin.php
blob: 34fd16dd7308e8c50056f0ce2af26f5777429a8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php

/*
 * This file is part of Twig.
 *
 * (c) 2009 Fabien Potencier
 * (c) 2009 Armin Ronacher
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * Represents a for node.
 *
 * @package    twig
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
 */
class phpbb_template_twig_node_begin extends Twig_Node
{
    public function __construct($beginName, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null)
    {
        parent::__construct(array('body' => $body, 'else' => $else), array('beginName' => $beginName), $lineno, $tag);
    }

    /**
     * Compiles the node to PHP.
     *
     * @param Twig_Compiler A Twig_Compiler instance
     */
    public function compile(Twig_Compiler $compiler)
    {
		$compiler
			->write("if (!isset(\$phpbb_blocks)) {\n")
			->indent()
				->write("\$phpbb_blocks = array();\n")
				->write("\$parent = \$context['_phpbb_blocks'];\n")
			->outdent()
			->write("}\n")
			->write("\$phpbb_blocks[] = '" . $this->getAttribute('beginName') . "';\n")
		;

        $compiler
			->write("foreach (\$parent['" . $this->getAttribute('beginName') . "'] as \$" . $this->getAttribute('beginName') . ") {\n")
			->indent()
				// Set up $context correctly so that Twig can get the correct data with $this->getAttribute
				->write("\$this->getEnvironment()->context_recursive_loop_builder(\$" . $this->getAttribute('beginName') . ", \$phpbb_blocks, \$context);\n")

				// We store the parent so that we can do this recursively
				->write("\$parent = \$" . $this->getAttribute('beginName') . ";\n")
        ;

        $compiler->subcompile($this->getNode('body'));

        $compiler
            ->outdent()
            ->write("}\n")

            // Remove the last item from the blocks storage as we've completed iterating over them all
            ->write("array_pop(\$phpbb_blocks);\n")

            // If we've gone through all of the blocks, we're back at the main level and have completed, so unset the var
            ->write("if (empty(\$phpbb_blocks)) { unset(\$phpbb_blocks); }\n")
        ;
    }

    /**
     * Compiles the node to PHP.
     *
     * Uses anonymous functions to compile the loops, which seems nicer to me, but requires PHP 5.4 (since subcompile uses $this, which is not available in 5.3)
     *
     * @param Twig_Compiler A Twig_Compiler instance
     *
    public function compile(Twig_Compiler $compiler)
    {
        $compiler->addDebugInfo($this);

		$compiler
			// name -> loop name
			// local context -> parent template variable context
			// global context -> global template variable context
			// variable chain -> full chain of variables to output template vars properly in subloops
			//		e.g. [foo][bar][foobar]
			// current chain location -> current location in subloop
			//		e.g. [foobar] of [foo][bar]
			->write("\$iterator = function (\$name, \$local_context, \$global_context, &\$variable_chain, &\$current_chain_location) {\n")
			->indent()
				//->write("var_dump(\$name, \$local_context);\n")
				// Try to find the loop in the
				// local context (child of local context passed, in case of a child loop)
				// global context (root template var)
				->write("if (isset(\$local_context[\$name])) {\n")
				->indent()
					->write("\$local_context = \$local_context[\$name];\n")
				->outdent()
				->write("}\n")
				->write("else if (isset(\$global_context[\$name])) {\n")
				->indent()
					->write("\$local_context = \$global_context[\$name];\n")
				->outdent()
				->write("} else { return; }\n")

				->write("if (!is_array(\$local_context) || empty(\$local_context)) { return; }\n")

				->write("foreach (\$local_context as \$for_context) {\n")
				->indent()
					// Some hackish stuff for Twig to properly subcompile
					->write("\$current_chain_location[\$name] = \$for_context;\n")
					->write("\$context = array_merge(\$global_context, \$variable_chain);\n")

					// Children
					->subcompile($this->getNode('body'))
				->outdent()
				->write("}\n")
			->outdent()
			->write("};\n")
			->write("if (isset(\$global_context)) {\n")
			->indent()
				// We are already inside an anonymous function
				->write("\$iterator('" . $this->getAttribute('beginName') . "', \$for_context, \$global_context, \$variable_chain, \$current_chain_location[\$name]);\n")
			->outdent()
			->write("} else {\n")
			->indent()
				// We are not inside the anonymous function (first level)
				->write("\$variable_chain = array();\n")
				->write("\$current_chain_location = array();\n")
				->write("\$iterator('" . $this->getAttribute('beginName') . "', array(), \$context, \$variable_chain, \$variable_chain);\n")
			->outdent()
			->write("}\n");
    }
    */
}