[ Index ] |
|
Code source de eZ Publish 3.9.0 |
1 <?php 2 // 3 // Definition of eZTemplateForeachFunction class 4 // 5 // Created on: <24-Feb-2005 15:47:35 vs> 6 // 7 // SOFTWARE NAME: eZ publish 8 // SOFTWARE RELEASE: 3.9.0 9 // BUILD VERSION: 17785 10 // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS 11 // SOFTWARE LICENSE: GNU General Public License v2.0 12 // NOTICE: > 13 // This program is free software; you can redistribute it and/or 14 // modify it under the terms of version 2.0 of the GNU General 15 // Public License as published by the Free Software Foundation. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of version 2.0 of the GNU General 23 // Public License along with this program; if not, write to the Free 24 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 25 // MA 02110-1301, USA. 26 // 27 // 28 29 /*! 30 \class eZTemplateForeachFunction eztemplateforeachfunction.php 31 \ingroup eZTemplateFunctions 32 \brief FOREACH loop 33 34 Syntax: 35 \code 36 {foreach <array> as [$keyVar =>] $itemVar 37 [sequence <array> as $sequenceVar] 38 [offset <offset>] 39 [max <max>] 40 [reverse]} 41 42 [{delimiter}...{/delimiter}] 43 [{break}] 44 [{continue}] 45 [{skip}] 46 {/foreach} 47 \endcode 48 49 Example: 50 \code 51 {foreach $objects as $object} 52 <tr> 53 {foreach $object.nodes as $node sequence array(dark,light) as $class} 54 <td class=$class> 55 {$node.name|wash} 56 </td> 57 {/foreach} 58 </tr> 59 {/foreach} 60 \endcode 61 */ 62 63 define ( 'EZ_TEMPLATE_FOREACH_FUNCTION_NAME', 'foreach' ); 64 class eZTemplateForeachFunction 65 { 66 /*! 67 * Returns an array of the function names, required for eZTemplate::registerFunctions(). 68 */ 69 function &functionList() 70 { 71 $functionList = array( EZ_TEMPLATE_FOREACH_FUNCTION_NAME ); 72 return $functionList; 73 } 74 75 /*! 76 * Returns the attribute list. 77 * key: parameter name 78 * value: can have children 79 */ 80 function attributeList() 81 { 82 return array( 'delimiter' => true, 83 'break' => false, 84 'continue' => false, 85 'skip' => false ); 86 } 87 88 89 /*! 90 * Returns the array with hits for the template compiler. 91 */ 92 function functionTemplateHints() 93 { 94 return array( EZ_TEMPLATE_FOREACH_FUNCTION_NAME => array( 'parameters' => true, 95 'static' => false, 96 'transform-parameters' => true, 97 'tree-transformation' => true ) ); 98 } 99 100 /*! 101 * Compiles the function and its children into PHP code. 102 */ 103 function templateNodeTransformation( $functionName, &$node, 104 &$tpl, $parameters, $privateData ) 105 { 106 /* 107 {foreach <array> as [$keyVar =>] $itemVar 108 [sequence <array> as $sequenceVar] 109 [offset <offset>] 110 [max <max>] 111 [reverse] 112 } 113 */ 114 115 $tpl->ForeachCounter++; 116 $newNodes = array(); 117 $nodePlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node ); 118 $uniqid = md5( $nodePlacement[2] ) . "_" . $tpl->ForeachCounter; 119 120 require_once ( 'lib/eztemplate/classes/eztemplatecompiledloop.php' ); 121 $loop = new eZTemplateCompiledLoop( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, 122 $newNodes, $parameters, $nodePlacement, $uniqid, 123 $node, $tpl, $privateData ); 124 125 126 127 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach begins" ); 128 129 $loop->initVars(); 130 131 $array = "fe_array_$uniqid"; 132 $arrayKeys = "fe_array_keys_$uniqid"; 133 $nItems = "fe_n_items_$uniqid"; 134 $nItemsProcessed = "fe_n_items_processed_$uniqid"; 135 $i = "fe_i_$uniqid"; 136 $key = "fe_key_$uniqid"; 137 $val = "fe_val_$uniqid"; 138 $offset = "fe_offset_$uniqid"; 139 $max = "fe_max_$uniqid"; 140 $reverse = "fe_reverse_$uniqid"; 141 $firstVal = "fe_first_val_$uniqid"; 142 $lastVal = "fe_last_val_$uniqid"; 143 144 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['array'], $nodePlacement, array( 'text-result' => false ), $array ); 145 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$arrayKeys = is_array( \$$array ) ? array_keys( \$$array ) : array();" ); 146 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItems = count( \$$arrayKeys );" ); 147 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed = 0;" ); 148 149 150 // process offset, max and reverse parameters 151 if ( isset( $parameters['offset'] ) ) 152 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['offset'], $nodePlacement, array( 'text-result' => false ), $offset ); 153 else 154 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$offset = 0;" ); 155 156 if ( isset( $parameters['max'] ) ) 157 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['max'], $nodePlacement, array( 'text-result' => false ), $max ); 158 else 159 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$max = \$$nItems - \$$offset;" ); 160 161 if ( isset( $parameters['reverse'] ) ) 162 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['reverse'], $nodePlacement, array( 'text-result' => false ), $reverse ); 163 else 164 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$reverse = false;" ); 165 166 167 // fix definitely incorrect offset 168 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$offset < 0 || \$$offset >= \$$nItems )\n{\n". 169 " \$$offset = ( \$$offset < 0 ) ? 0 : \$$nItems;\n". 170 " if ( \$$nItems || \$$offset < 0 )\n {\n". 171 " eZDebug::writeWarning(\"Invalid 'offset' parameter specified.\"); \n}\n}" ); 172 // fix definitely incorrect max 173 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$max < 0 || \$$offset + \$$max > \$$nItems )\n{\n". 174 " if ( \$$max < 0 )\n eZDebug::writeWarning(\"Invalid 'max' parameter specified.\");\n". 175 " \$$max = \$$nItems - \$$offset;\n}" ); 176 177 // initialize first and last indexes to iterate between them 178 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$$reverse )\n" . 179 "{\n" . 180 " \$$firstVal = \$$nItems - 1 - \$$offset;\n" . 181 " \$$lastVal = 0;\n" . 182 "}\n" . 183 "else\n" . 184 "{\n" . 185 " \$$firstVal = \$$offset;\n" . 186 " \$$lastVal = \$$nItems - 1;\n" . 187 "}" ); 188 189 // generate loop header 190 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// foreach" ); 191 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "for ( \$$i = \$$firstVal; " . 192 "\$$nItemsProcessed < \$$max && ( \$$reverse ? \$$i >= \$$lastVal : \$$i <= \$$lastVal ); " . 193 "\$$reverse ? \$$i-- : \$$i++ )\n" . 194 "{" ); 195 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode(); 196 197 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$key = \$$arrayKeys}[\$$i];" ); 198 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$val = \$$array}[\$$key];" ); 199 200 // export $itemVar 201 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "$val", $nodePlacement, array(), 202 $parameters['item_var'][0][1], 203 false, true, true ); 204 205 // export $keyVar (if specified) 206 if ( isset( $parameters['key_var'] ) ) 207 { 208 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "$key", $nodePlacement, array(), 209 $parameters['key_var'][0][1], 210 false, true, true ); 211 } 212 213 $loop->processBody(); 214 215 // generate loop footer 216 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$$nItemsProcessed++;" ); 217 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode(); 218 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "} // foreach" ); 219 220 $loop->cleanup(); 221 222 // unset the loop variables 223 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $parameters['item_var'][0][1] ); 224 if ( isset( $parameters['key_var'] ) ) 225 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $parameters['key_var'][0][1] ); 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::createCodePieceNode( "// foreach ends" ); 240 241 return $newNodes; 242 } 243 244 /*! 245 * Actually executes the function and its children (in processed mode). 246 */ 247 function process( &$tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace ) 248 { 249 /* 250 {foreach <array> as [$keyVar =>] $itemVar 251 [sequence <array> as $sequenceVar] 252 [offset <offset>] 253 [max <max>] 254 [reverse] 255 } 256 */ 257 258 //eZDebug::writeDebug( $functionParameters, '$functionParameters' ); 259 260 require_once ( 'lib/eztemplate/classes/eztemplateloop.php' ); 261 $loop = new eZTemplateLoop( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, 262 $functionParameters, $functionChildren, $functionPlacement, 263 $tpl, $textElements, $rootNamespace, $currentNamespace ); 264 265 if ( !$loop->initialized() ) 266 return; 267 268 $loop->parseParamValue( 'array', $array ); 269 if ( !is_array( $array ) ) 270 { 271 $tpl->error( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Missing/malformed array to iterate through." ); 272 return; 273 } 274 275 $loop->parseParamVarName( 'item_var', $itemVarName ); 276 if ( !$itemVarName ) 277 { 278 $tpl->error( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Missing/malformed item variable name." ); 279 return; 280 } 281 282 $loop->parseParamVarName( 'key_var', $keyVarName ); 283 $loop->parseParamValue( 'max', $max ); 284 $loop->parseParamValue( 'offset', $offset ); 285 $loop->parseParamValue( 'reverse', $reverse ); 286 287 /* 288 * run the loop itself 289 */ 290 291 /* 292 $offset and $max parameters must meet the following requirements: 293 - $offset + $max <= $nItems 294 - $offset >= 0 295 - $max >= 0 296 Otherwise they are not considered. 297 */ 298 299 $arrayKeys = array_keys( $array ); 300 $nItems = count( $arrayKeys ); 301 $nItemsProcessed = 0; 302 303 // do nothing in case of empty array 304 if ( !$nItems ) 305 return; 306 307 // fix definitely incorrect offset 308 if ( is_null( $offset ) ) 309 $offset = 0; 310 elseif ( $offset < 0 || $offset >= $nItems ) 311 { 312 if ( $nItems || $offset < 0 ) 313 { 314 $tpl->warning( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Invalid 'offset' parameter specified." ); 315 } 316 $offset = ( $offset < 0 ) ? 0 : $nItems; 317 } 318 319 // fix definitely incorrect max 320 if ( is_null( $max ) ) 321 $max = $nItems - $offset; 322 elseif ( $max < 0 || $offset+$max > $nItems ) 323 { 324 if ( $max <0 ) 325 $tpl->warning( EZ_TEMPLATE_FOREACH_FUNCTION_NAME, "Invalid 'max' parameter specified." ); 326 $max = $nItems - $offset; 327 } 328 329 // process 'reverse' parameter 330 if ( is_null( $reverse ) ) 331 $reverse = false; 332 if ( $reverse ) 333 { 334 $firstVal = $nItems - 1 - $offset; 335 $lastVal = 0; 336 } 337 else 338 { 339 $firstVal = $offset; 340 $lastVal = $nItems - 1; 341 } 342 343 if ( $firstVal < $lastVal ) 344 { 345 if ( $keyVarName ) 346 $loop->initLoopVariable( $keyVarName ); 347 $loop->initLoopVariable( $itemVarName ); 348 } 349 350 for ( $i = $firstVal; $nItemsProcessed < $max && ( $reverse ? $i >= $lastVal : $i <= $lastVal ); ) 351 { 352 $key =& $arrayKeys[$i]; 353 $val =& $array[$key]; 354 355 if ( $keyVarName ) 356 $tpl->setVariable( $keyVarName, $key, $rootNamespace ); 357 $tpl->setVariable( $itemVarName, $val, $rootNamespace ); 358 359 $loop->setSequenceVar(); // set sequence variable (if specified) 360 $loop->processDelimiter( $i ); 361 $loop->resetIteration(); 362 363 // process loop body 364 if ( $loop->processChildren() ) 365 break; 366 367 // increment loop counter here for delimiter to be processed correctly 368 $reverse ? $i-- : $i++; 369 370 $loop->incrementSequence(); 371 $nItemsProcessed++; 372 } 373 374 $loop->cleanup(); 375 } 376 377 /*! 378 * Returns true, telling the template parser that the function can have children. 379 */ 380 function hasChildren() 381 { 382 return true; 383 } 384 } 385 386 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sat Feb 24 10:30:04 2007 | par Balluche grâce à PHPXref 0.7 |