1 | <?php |
---|
2 | /** |
---|
3 | * Smarty Internal Plugin Compile Foreach |
---|
4 | * |
---|
5 | * Compiles the {foreach} {foreachelse} {/foreach} tags |
---|
6 | * |
---|
7 | * @package Smarty |
---|
8 | * @subpackage Compiler |
---|
9 | * @author Uwe Tews |
---|
10 | */ |
---|
11 | |
---|
12 | /** |
---|
13 | * Smarty Internal Plugin Compile Foreach Class |
---|
14 | * |
---|
15 | * @package Smarty |
---|
16 | * @subpackage Compiler |
---|
17 | */ |
---|
18 | class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase { |
---|
19 | /** |
---|
20 | * Attribute definition: Overwrites base class. |
---|
21 | * |
---|
22 | * @var array |
---|
23 | * @see Smarty_Internal_CompileBase |
---|
24 | */ |
---|
25 | public $required_attributes = array('from', 'item'); |
---|
26 | /** |
---|
27 | * Attribute definition: Overwrites base class. |
---|
28 | * |
---|
29 | * @var array |
---|
30 | * @see Smarty_Internal_CompileBase |
---|
31 | */ |
---|
32 | public $optional_attributes = array('name', 'key'); |
---|
33 | /** |
---|
34 | * Attribute definition: Overwrites base class. |
---|
35 | * |
---|
36 | * @var array |
---|
37 | * @see Smarty_Internal_CompileBase |
---|
38 | */ |
---|
39 | public $shorttag_order = array('from','item','key','name'); |
---|
40 | |
---|
41 | /** |
---|
42 | * Compiles code for the {foreach} tag |
---|
43 | * |
---|
44 | * @param array $args array with attributes from parser |
---|
45 | * @param object $compiler compiler object |
---|
46 | * @param array $parameter array with compilation parameter |
---|
47 | * @return string compiled code |
---|
48 | */ |
---|
49 | public function compile($args, $compiler, $parameter) |
---|
50 | { |
---|
51 | $tpl = $compiler->template; |
---|
52 | // check and get attributes |
---|
53 | $_attr = $this->getAttributes($compiler, $args); |
---|
54 | |
---|
55 | $from = $_attr['from']; |
---|
56 | $item = $_attr['item']; |
---|
57 | if (!strncmp("\$_smarty_tpl->tpl_vars[$item]", $from, strlen($item) + 24)) { |
---|
58 | $compiler->trigger_template_error("item variable {$item} may not be the same variable as at 'from'", $compiler->lex->taglineno); |
---|
59 | } |
---|
60 | |
---|
61 | if (isset($_attr['key'])) { |
---|
62 | $key = $_attr['key']; |
---|
63 | } else { |
---|
64 | $key = null; |
---|
65 | } |
---|
66 | |
---|
67 | $this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $item, $key)); |
---|
68 | // maybe nocache because of nocache variables |
---|
69 | $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; |
---|
70 | |
---|
71 | if (isset($_attr['name'])) { |
---|
72 | $name = $_attr['name']; |
---|
73 | $has_name = true; |
---|
74 | $SmartyVarName = '$smarty.foreach.' . trim($name, '\'"') . '.'; |
---|
75 | } else { |
---|
76 | $name = null; |
---|
77 | $has_name = false; |
---|
78 | } |
---|
79 | $ItemVarName = '$' . trim($item, '\'"') . '@'; |
---|
80 | // evaluates which Smarty variables and properties have to be computed |
---|
81 | if ($has_name) { |
---|
82 | $usesSmartyFirst = strpos($tpl->source->content, $SmartyVarName . 'first') !== false; |
---|
83 | $usesSmartyLast = strpos($tpl->source->content, $SmartyVarName . 'last') !== false; |
---|
84 | $usesSmartyIndex = strpos($tpl->source->content, $SmartyVarName . 'index') !== false; |
---|
85 | $usesSmartyIteration = strpos($tpl->source->content, $SmartyVarName . 'iteration') !== false; |
---|
86 | $usesSmartyShow = strpos($tpl->source->content, $SmartyVarName . 'show') !== false; |
---|
87 | $usesSmartyTotal = strpos($tpl->source->content, $SmartyVarName . 'total') !== false; |
---|
88 | } else { |
---|
89 | $usesSmartyFirst = false; |
---|
90 | $usesSmartyLast = false; |
---|
91 | $usesSmartyTotal = false; |
---|
92 | $usesSmartyShow = false; |
---|
93 | } |
---|
94 | |
---|
95 | $usesPropFirst = $usesSmartyFirst || strpos($tpl->source->content, $ItemVarName . 'first') !== false; |
---|
96 | $usesPropLast = $usesSmartyLast || strpos($tpl->source->content, $ItemVarName . 'last') !== false; |
---|
97 | $usesPropIndex = $usesPropFirst || strpos($tpl->source->content, $ItemVarName . 'index') !== false; |
---|
98 | $usesPropIteration = $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'iteration') !== false; |
---|
99 | $usesPropShow = strpos($tpl->source->content, $ItemVarName . 'show') !== false; |
---|
100 | $usesPropTotal = $usesSmartyTotal || $usesSmartyShow || $usesPropShow || $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'total') !== false; |
---|
101 | // generate output code |
---|
102 | $output = "<?php "; |
---|
103 | $output .= " \$_smarty_tpl->tpl_vars[$item] = new Smarty_Variable; \$_smarty_tpl->tpl_vars[$item]->_loop = false;\n"; |
---|
104 | if ($key != null) { |
---|
105 | $output .= " \$_smarty_tpl->tpl_vars[$key] = new Smarty_Variable;\n"; |
---|
106 | } |
---|
107 | $output .= " \$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}\n"; |
---|
108 | if ($usesPropTotal) { |
---|
109 | $output .= " \$_smarty_tpl->tpl_vars[$item]->total= \$_smarty_tpl->_count(\$_from);\n"; |
---|
110 | } |
---|
111 | if ($usesPropIteration) { |
---|
112 | $output .= " \$_smarty_tpl->tpl_vars[$item]->iteration=0;\n"; |
---|
113 | } |
---|
114 | if ($usesPropIndex) { |
---|
115 | $output .= " \$_smarty_tpl->tpl_vars[$item]->index=-1;\n"; |
---|
116 | } |
---|
117 | if ($usesPropShow) { |
---|
118 | $output .= " \$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n"; |
---|
119 | } |
---|
120 | if ($has_name) { |
---|
121 | if ($usesSmartyTotal) { |
---|
122 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['total'] = \$_smarty_tpl->tpl_vars[$item]->total;\n"; |
---|
123 | } |
---|
124 | if ($usesSmartyIteration) { |
---|
125 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']=0;\n"; |
---|
126 | } |
---|
127 | if ($usesSmartyIndex) { |
---|
128 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']=-1;\n"; |
---|
129 | } |
---|
130 | if ($usesSmartyShow) { |
---|
131 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['show']=(\$_smarty_tpl->tpl_vars[$item]->total > 0);\n"; |
---|
132 | } |
---|
133 | } |
---|
134 | $output .= "foreach (\$_from as \$_smarty_tpl->tpl_vars[$item]->key => \$_smarty_tpl->tpl_vars[$item]->value){\n\$_smarty_tpl->tpl_vars[$item]->_loop = true;\n"; |
---|
135 | if ($key != null) { |
---|
136 | $output .= " \$_smarty_tpl->tpl_vars[$key]->value = \$_smarty_tpl->tpl_vars[$item]->key;\n"; |
---|
137 | } |
---|
138 | if ($usesPropIteration) { |
---|
139 | $output .= " \$_smarty_tpl->tpl_vars[$item]->iteration++;\n"; |
---|
140 | } |
---|
141 | if ($usesPropIndex) { |
---|
142 | $output .= " \$_smarty_tpl->tpl_vars[$item]->index++;\n"; |
---|
143 | } |
---|
144 | if ($usesPropFirst) { |
---|
145 | $output .= " \$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->index === 0;\n"; |
---|
146 | } |
---|
147 | if ($usesPropLast) { |
---|
148 | $output .= " \$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->iteration === \$_smarty_tpl->tpl_vars[$item]->total;\n"; |
---|
149 | } |
---|
150 | if ($has_name) { |
---|
151 | if ($usesSmartyFirst) { |
---|
152 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['first'] = \$_smarty_tpl->tpl_vars[$item]->first;\n"; |
---|
153 | } |
---|
154 | if ($usesSmartyIteration) { |
---|
155 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']++;\n"; |
---|
156 | } |
---|
157 | if ($usesSmartyIndex) { |
---|
158 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']++;\n"; |
---|
159 | } |
---|
160 | if ($usesSmartyLast) { |
---|
161 | $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['last'] = \$_smarty_tpl->tpl_vars[$item]->last;\n"; |
---|
162 | } |
---|
163 | } |
---|
164 | $output .= "?>"; |
---|
165 | |
---|
166 | return $output; |
---|
167 | } |
---|
168 | } |
---|
169 | |
---|
170 | /** |
---|
171 | * Smarty Internal Plugin Compile Foreachelse Class |
---|
172 | * |
---|
173 | * @package Smarty |
---|
174 | * @subpackage Compiler |
---|
175 | */ |
---|
176 | class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase { |
---|
177 | |
---|
178 | /** |
---|
179 | * Compiles code for the {foreachelse} tag |
---|
180 | * |
---|
181 | * @param array $args array with attributes from parser |
---|
182 | * @param object $compiler compiler object |
---|
183 | * @param array $parameter array with compilation parameter |
---|
184 | * @return string compiled code |
---|
185 | */ |
---|
186 | public function compile($args, $compiler, $parameter) |
---|
187 | { |
---|
188 | // check and get attributes |
---|
189 | $_attr = $this->getAttributes($compiler, $args); |
---|
190 | |
---|
191 | list($openTag, $nocache, $item, $key) = $this->closeTag($compiler, array('foreach')); |
---|
192 | $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $item, $key)); |
---|
193 | |
---|
194 | return "<?php }\nif (!\$_smarty_tpl->tpl_vars[$item]->_loop) {\n?>"; |
---|
195 | } |
---|
196 | |
---|
197 | } |
---|
198 | |
---|
199 | /** |
---|
200 | * Smarty Internal Plugin Compile Foreachclose Class |
---|
201 | * |
---|
202 | * @package Smarty |
---|
203 | * @subpackage Compiler |
---|
204 | */ |
---|
205 | class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase { |
---|
206 | |
---|
207 | /** |
---|
208 | * Compiles code for the {/foreach} tag |
---|
209 | * |
---|
210 | * @param array $args array with attributes from parser |
---|
211 | * @param object $compiler compiler object |
---|
212 | * @param array $parameter array with compilation parameter |
---|
213 | * @return string compiled code |
---|
214 | */ |
---|
215 | public function compile($args, $compiler, $parameter) |
---|
216 | { |
---|
217 | // check and get attributes |
---|
218 | $_attr = $this->getAttributes($compiler, $args); |
---|
219 | // must endblock be nocache? |
---|
220 | if ($compiler->nocache) { |
---|
221 | $compiler->tag_nocache = true; |
---|
222 | } |
---|
223 | |
---|
224 | list($openTag, $compiler->nocache, $item, $key) = $this->closeTag($compiler, array('foreach', 'foreachelse')); |
---|
225 | |
---|
226 | return "<?php } ?>"; |
---|
227 | } |
---|
228 | |
---|
229 | } |
---|
230 | |
---|
231 | ?> |
---|