Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

eztemplateforeachfunction.php
Go to the documentation of this file.
1 <?php
45 class eZTemplateForeachFunction
46 {
47 const FUNCTION_NAME = 'foreach';
48
52 function functionList()
53 {
54 $functionList = array( eZTemplateForeachFunction::FUNCTION_NAME );
55 return $functionList;
56 }
57
63 function attributeList()
64 {
65 return array( 'delimiter' => true,
66 'break' => false,
67 'continue' => false,
68 'skip' => false );
69 }
70
71
75 function functionTemplateHints()
76 {
77 return array( eZTemplateForeachFunction::FUNCTION_NAME => array( 'parameters' => true,
78 'static' => false,
79 'transform-parameters' => true,
80 'tree-transformation' => true ) );
81 }
82
86 function templateNodeTransformation( $functionName, &$node,
87 $tpl, $parameters, $privateData )
88 {
89 /*
90 {foreach <array> as [$keyVar =>] $itemVar
91 [sequence <array> as $sequenceVar]
92 [offset <offset>]
93 [max <max>]
94 [reverse]
95 }
96 */
97
98 $tpl->ForeachCounter++;
99 $newNodes = array();
100 $nodePlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node );
101 $uniqid = md5( $nodePlacement[2] ) . "_" . $tpl->ForeachCounter;
102
103 $loop = new eZTemplateCompiledLoop( eZTemplateForeachFunction::FUNCTION_NAME,
104 $newNodes, $parameters, $nodePlacement, $uniqid,
105 $node, $tpl, $privateData );
106
107
108
109 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach begins" );
110
111 $loop->initVars();
112
113 $array = "fe_array_$uniqid";
114 $arrayKeys = "fe_array_keys_$uniqid";
115 $nItems = "fe_n_items_$uniqid";
116 $nItemsProcessed = "fe_n_items_processed_$uniqid";
117 $i = "fe_i_$uniqid";
118 $key = "fe_key_$uniqid";
119 $val = "fe_val_$uniqid";
120 $offset = "fe_offset_$uniqid";
121 $max = "fe_max_$uniqid";
122 $reverse = "fe_reverse_$uniqid";
123 $firstVal = "fe_first_val_$uniqid";
124 $lastVal = "fe_last_val_$uniqid";
125
126 $variableStack = "fe_variable_stack_$uniqid";
127 $namesArray = array( $array, $arrayKeys, $nItems, $nItemsProcessed, $i, $key, $val, $offset, $max, $reverse, $firstVal, $lastVal );
128
129 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$array = [];" );
130 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$arrayKeys = [];" );
131 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItems = 0;" );
132 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed = 0;" );
133 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$i = 0;" );
134 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$key = 0;" );
135 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$val = 0;" );
136 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$offset = 0;" );
137 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$max = 0;" );
138 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$reverse = 0;" );
139 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$firstVal = 0;" );
140 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$lastVal = 0;" );
141
142 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( !isset( \$$variableStack ) ) \$$variableStack = [];" );
143 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$" . $variableStack ."[] = @compact( '" . implode( "', '", $namesArray ) . "' );" );
144
145 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['array'], $nodePlacement, array( 'text-result' => false ), $array );
146 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$arrayKeys = is_array( \$$array ) ? array_keys( \$$array ) : [];" );
147 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItems = count( \$$arrayKeys );" );
148 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed = 0;" );
149
150
151 // process offset, max and reverse parameters
152 if ( isset( $parameters['offset'] ) )
153 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['offset'], $nodePlacement, array( 'text-result' => false ), $offset );
154 else
155 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$offset = 0;" );
156
157 if ( isset( $parameters['max'] ) )
158 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['max'], $nodePlacement, array( 'text-result' => false ), $max );
159 else
160 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$max = \$$nItems - \$$offset;" );
161
162 if ( isset( $parameters['reverse'] ) )
163 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['reverse'], $nodePlacement, array( 'text-result' => false ), $reverse );
164 else
165 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$reverse = false;" );
166
167
168 // fix definitely incorrect offset
169 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$offset < 0 || \$$offset >= \$$nItems )\n{\n".
170 " \$$offset = ( \$$offset < 0 ) ? 0 : \$$nItems;\n".
171 " if ( \$$nItems || \$$offset < 0 )\n {\n".
172 " eZDebug::writeWarning(\"Invalid 'offset' parameter specified: '\$$offset'. Array count: \$$nItems\"); \n}\n}" );
173 // fix definitely incorrect max
174 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$max < 0 || \$$offset + \$$max > \$$nItems )\n{\n".
175 " if ( \$$max < 0 )\n eZDebug::writeWarning(\"Invalid 'max' parameter specified: \$$max\");\n".
176 " \$$max = \$$nItems - \$$offset;\n}" );
177
178 // initialize first and last indexes to iterate between them
179 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$reverse )\n" .
180 "{\n" .
181 " \$$firstVal = \$$nItems - 1 - \$$offset;\n" .
182 " \$$lastVal = 0;\n" .
183 "}\n" .
184 "else\n" .
185 "{\n" .
186 " \$$firstVal = \$$offset;\n" .
187 " \$$lastVal = \$$nItems - 1;\n" .
188 "}" );
189
190 // generate loop header
191 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach" );
192 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "for ( \$$i = \$$firstVal; " .
193 "\$$nItemsProcessed < \$$max && ( \$$reverse ? \$$i >= \$$lastVal : \$$i <= \$$lastVal ); " .
194 "\$$reverse ? \$$i-- : \$$i++ )\n" .
195 "{" );
196 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode();
197
198 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$key = \${$arrayKeys}[\$$i];" );
199 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$val = \${$array}[\$$key];" );
200
201 // export $itemVar
202 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "$val", $nodePlacement, array(),
203 $parameters['item_var'][0][1],
204 false, true, true );
205
206 // export $keyVar (if specified)
207 if ( isset( $parameters['key_var'] ) )
208 {
209 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "$key", $nodePlacement, array(),
210 $parameters['key_var'][0][1],
211 false, true, true );
212 }
213
214 $loop->processBody();
215
216 // generate loop footer
217 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed++;" );
218 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode();
219 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "} // foreach" );
220
221 $loop->cleanup();
222
223 // unset the loop variables
224 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( count( \$$variableStack ) ) extract( array_pop( \$$variableStack ) );\n" );
225 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "else\n{\n" );
226 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $array );
227 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $arrayKeys );
228 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $nItems );
229 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $nItemsProcessed );
230 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $i );
231 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $key );
232 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $val );
233 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $offset );
234 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $max );
235 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $reverse );
236 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $firstVal );
237 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $lastVal );
238
239 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $variableStack );
240 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\n" );
241
242 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach ends" );
243
244 return $newNodes;
245 }
246
250 function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
251 {
252 /*
253 {foreach <array> as [$keyVar =>] $itemVar
254 [sequence <array> as $sequenceVar]
255 [offset <offset>]
256 [max <max>]
257 [reverse]
258 }
259 */
260
261 //eZDebug::writeDebug( $functionParameters, '$functionParameters' );
262
263 $loop = new eZTemplateLoop( eZTemplateForeachFunction::FUNCTION_NAME,
264 $functionParameters, $functionChildren, $functionPlacement,
265 $tpl, $textElements, $rootNamespace, $currentNamespace );
266
267 if ( !$loop->initialized() )
268 return;
269
270 $loop->parseParamValue( 'array', $array );
271 if ( !is_array( $array ) )
272 {
273 $tpl->error( eZTemplateForeachFunction::FUNCTION_NAME, "Missing/malformed array to iterate through.", $functionPlacement );
274 return;
275 }
276
277 $loop->parseParamVarName( 'item_var', $itemVarName );
278 if ( !$itemVarName )
279 {
280 $tpl->error( eZTemplateForeachFunction::FUNCTION_NAME, "Missing/malformed item variable name.", $functionPlacement );
281 return;
282 }
283
284 $loop->parseParamVarName( 'key_var', $keyVarName );
285 $loop->parseParamValue( 'max', $max );
286 $loop->parseParamValue( 'offset', $offset );
287 $loop->parseParamValue( 'reverse', $reverse );
288
289 /*
290 * run the loop itself
291 */
292
293 /*
294 $offset and $max parameters must meet the following requirements:
295 - $offset + $max <= $nItems
296 - $offset >= 0
297 - $max >= 0
298 Otherwise they are not considered.
299 */
300
301 $arrayKeys = array_keys( $array );
302 $nItems = count( $arrayKeys );
303 $nItemsProcessed = 0;
304
305 // do nothing in case of empty array
306 if ( !$nItems )
307 return;
308
309 // fix definitely incorrect offset
310 if ( $offset === null )
311 $offset = 0;
312 elseif ( $offset < 0 || $offset >= $nItems )
313 {
314 if ( $nItems || $offset < 0 )
315 {
316 $tpl->warning( eZTemplateForeachFunction::FUNCTION_NAME, "Invalid 'offset' parameter specified.", $functionPlacement );
317 }
318 $offset = ( $offset < 0 ) ? 0 : $nItems;
319 }
320
321 // fix definitely incorrect max
322 if ( $max === null )
323 $max = $nItems - $offset;
324 elseif ( $max < 0 || $offset+$max > $nItems )
325 {
326 if ( $max <0 )
327 $tpl->warning( eZTemplateForeachFunction::FUNCTION_NAME, "Invalid 'max' parameter specified.", $functionPlacement );
328 $max = $nItems - $offset;
329 }
330
331 // process 'reverse' parameter
332 if ( $reverse === null )
333 $reverse = false;
334 if ( $reverse )
335 {
336 $firstVal = $nItems - 1 - $offset;
337 $lastVal = 0;
338 }
339 else
340 {
341 $firstVal = $offset;
342 $lastVal = $nItems - 1;
343 }
344
345 if ( $firstVal < $lastVal )
346 {
347 if ( $keyVarName && !$tpl->hasVariable( $keyVarName, $rootNamespace ) )
348 {
349 $loop->initLoopVariable( $keyVarName );
350 }
351 if ( !$tpl->hasVariable( $itemVarName, $rootNamespace ) )
352 {
353 $loop->initLoopVariable( $itemVarName );
354 }
355 }
356
357 for ( $i = $firstVal; $nItemsProcessed < $max && ( $reverse ? $i >= $lastVal : $i <= $lastVal ); )
358 {
359 $key =& $arrayKeys[$i];
360 $val =& $array[$key];
361
362 if ( $keyVarName )
363 $tpl->setVariable( $keyVarName, $key, $rootNamespace );
364 $tpl->setVariable( $itemVarName, $val, $rootNamespace );
365
366 $loop->setSequenceVar(); // set sequence variable (if specified)
367 $loop->processDelimiter( $i );
368 $loop->resetIteration();
369
370 // process loop body
371 if ( $loop->processChildren() )
372 break;
373
374 // increment loop counter here for delimiter to be processed correctly
375 $reverse ? $i-- : $i++;
376
377 $loop->incrementSequence();
378 $nItemsProcessed++;
379 }
380
381 $loop->cleanup();
382 }
383
387 function hasChildren()
388 {
389 return true;
390 }
391 }
392
393 ?>
eZTemplateCompiledLoop
Common code for compiling the loop functions.
Definition: eztemplatecompiledloop.php:17
eZTemplateForeachFunction
FOREACH loop.
Definition: eztemplateforeachfunction.php:46
eZTemplateForeachFunction\process
process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace)
Definition: eztemplateforeachfunction.php:250
eZTemplateForeachFunction\hasChildren
hasChildren()
Definition: eztemplateforeachfunction.php:387
eZTemplateForeachFunction\functionList
functionList()
Definition: eztemplateforeachfunction.php:52
eZTemplateForeachFunction\functionTemplateHints
functionTemplateHints()
Definition: eztemplateforeachfunction.php:75
eZTemplateForeachFunction\attributeList
attributeList()
Definition: eztemplateforeachfunction.php:63
eZTemplateForeachFunction\templateNodeTransformation
templateNodeTransformation( $functionName, &$node, $tpl, $parameters, $privateData)
Definition: eztemplateforeachfunction.php:86
eZTemplateForeachFunction\FUNCTION_NAME
const FUNCTION_NAME
Definition: eztemplateforeachfunction.php:47
eZTemplateLoop
Code common for the loop functions in processed mode.
Definition: eztemplateloop.php:49
eZTemplateNodeTool\createVariableNode
static createVariableNode( $originalNode=false, $variableData=false, $variablePlacement=false, $parameters=array(), $variableAssignmentName=false, $onlyExisting=false, $overWrite=true, $assignFromVariable=false, $rememberSet=false)
Definition: eztemplatenodetool.php:395
eZTemplateNodeTool\createSpacingDecreaseNode
static createSpacingDecreaseNode( $spacing=4, $parameters=array())
Definition: eztemplatenodetool.php:508
eZTemplateNodeTool\createVariableUnsetNode
static createVariableUnsetNode( $variableName, $parameters=array())
Definition: eztemplatenodetool.php:462
eZTemplateNodeTool\createCodePieceNode
static createCodePieceNode( $codePiece, $parameters=array())
Definition: eztemplatenodetool.php:457
eZTemplateNodeTool\createSpacingIncreaseNode
static createSpacingIncreaseNode( $spacing=4, $parameters=array())
Definition: eztemplatenodetool.php:503
eZTemplateNodeTool\extractFunctionNodePlacement
static extractFunctionNodePlacement(&$node)
Definition: eztemplatenodetool.php:660
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.