00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 include_once( 'lib/eztemplate/classes/eztemplatesectioniterator.php' );
00078
00079 class eZTemplateSectionFunction
00080 {
00081
00082
00083
00084
00085 function eZTemplateSectionFunction( $name = "section" )
00086 {
00087 $this->Name = $name;
00088 }
00089
00090
00091
00092
00093
00094 function attributeList()
00095 {
00096 return array( "delimiter" => true,
00097 "section-exclude" => false,
00098 "section-include" => false,
00099 $this->Name . "-else" => false );
00100 }
00101
00102
00103
00104
00105
00106 function functionList()
00107 {
00108 return array( $this->Name );
00109 }
00110
00111 function functionTemplateHints()
00112 {
00113 return array( $this->Name => array( 'parameters' => true,
00114 'static' => false,
00115 'transform-children' => false,
00116 'tree-transformation' => true,
00117 'transform-parameters' => true ) );
00118 }
00119
00120 function functionTemplateStatistics( $functionName, &$node, &$tpl, $resourceData, $namespace, &$stats )
00121 {
00122 if ( $functionName != $this->Name )
00123 return false;
00124 $newNamespace = $namespace;
00125 $parameters = eZTemplateNodeTool::extractFunctionNodeParameters( $node );
00126 if ( isset( $parameters['name'] ) )
00127 {
00128 $nameData = $parameters['name'];
00129 $nameDataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
00130 $nameData, false,
00131 $resourceData );
00132 if ( $nameDataInspection['is-constant'] and
00133 !$nameDataInspection['has-operators'] and
00134 !$nameDataInspection['has-attributes'] )
00135 {
00136 $parameterNamespace = $nameDataInspection['new-data'][0][1];
00137 $newNamespace = $tpl->mergeNamespace( $namespace, $parameterNamespace );
00138 }
00139 }
00140 $parameterNames = array( 'loop', 'show', 'var', 'last-value', 'reverse', 'sequence', 'max', 'offset' );
00141 foreach ( $parameterNames as $parameterName )
00142 {
00143 if ( isset( $parameters[$parameterName] ) )
00144 {
00145 eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $parameters[$parameterName], false, $resourceData, $namespace, $stats );
00146 }
00147 }
00148
00149 if ( !isset( $parameters['var'] ) )
00150 {
00151 if ( isset( $parameters['loop'] ) )
00152 {
00153 $newVariables = array( 'key', 'item', 'index', 'number' );
00154 foreach ( $newVariables as $newVariableName )
00155 {
00156 eZTemplateCompiler::setVariableStatistics( $stats, $newNamespace, $newVariableName, array( 'is_created' => true,
00157 'is_removed' => true ) );
00158 }
00159 }
00160 if ( isset( $parameters['sequence'] ) )
00161 {
00162 $newVariables = array( 'sequence' );
00163 foreach ( $newVariables as $newVariableName )
00164 {
00165 eZTemplateCompiler::setVariableStatistics( $stats, $newNamespace, $newVariableName, array( 'is_created' => true,
00166 'is_removed' => true ) );
00167 }
00168 }
00169 }
00170 else
00171 {
00172 if ( isset( $parameters['loop'] ) )
00173 {
00174 $varDataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
00175 $parameters['var'], false,
00176 $resourceData );
00177 if ( $varDataInspection['is-constant'] and
00178 !$varDataInspection['has-operators'] and
00179 !$varDataInspection['has-attributes'] )
00180 {
00181 $varName = $varDataInspection['new-data'][0][1];
00182 eZTemplateCompiler::setVariableStatistics( $stats, $newNamespace, $varName, array( 'is_created' => true,
00183 'is_removed' => true ) );
00184 }
00185 }
00186 }
00187
00188 $functionChildren = eZTemplateNodeTool::extractFunctionNodeChildren( $node );
00189 if ( is_array( $functionChildren ) )
00190 {
00191 eZTemplateCompiler::calculateVariableStatisticsChildren( $tpl, $functionChildren, $resourceData, $newNamespace, $stats );
00192 }
00193 }
00194
00195 function templateNodeTransformation( $functionName, &$node,
00196 &$tpl, $parameters, $privateData )
00197 {
00198 $useLastValue = false;
00199 if ( isset( $parameters['last-value'] ) and
00200 !eZTemplateNodeTool::isStaticElement( $parameters['last-value'] ) )
00201 return false;
00202 if ( isset( $parameters['name'] ) and
00203 !eZTemplateNodeTool::isStaticElement( $parameters['name'] ) )
00204 return false;
00205 if ( isset( $parameters['var'] ) and
00206 !eZTemplateNodeTool::isStaticElement( $parameters['var'] ) )
00207 return false;
00208 if ( isset( $parameters['reverse'] ) and
00209 !eZTemplateNodeTool::isStaticElement( $parameters['reverse'] ) )
00210 return false;
00211
00212 $varName = false;
00213 if ( isset( $parameters['var'] ) )
00214 $varName = eZTemplateNodeTool::elementStaticValue( $parameters['var'] );
00215 if ( isset( $parameters['last-value'] ) )
00216 $useLastValue = (bool)eZTemplateNodeTool::elementStaticValue( $parameters['last-value'] );
00217 if ( !$varName )
00218 $useLastValue = false;
00219 $reverseLoop = false;
00220 if ( isset( $parameters['reverse'] ) )
00221 $reverseLoop = eZTemplateNodeTool::elementStaticValue( $parameters['reverse'] );
00222
00223 $useLoop = isset( $parameters['loop'] );
00224 $allowLoop = true;
00225 $newNodes = array();
00226
00227 $maxText = "false";
00228 $useMax = false;
00229 $maxPopText = false;
00230 if ( isset( $parameters['max'] ) )
00231 {
00232 if ( eZTemplateNodeTool::isStaticElement( $parameters['max'] ) )
00233 {
00234 $maxValue = eZTemplateNodeTool::elementStaticValue( $parameters['max'] );
00235 if ( $maxValue > 0 )
00236 {
00237 $maxText = eZPHPCreator::variableText( $maxValue );
00238 $useMax = true;
00239 }
00240 else
00241 return array( eZTemplateNodeTool::createTextNode( '' ) );
00242 }
00243 else
00244 {
00245 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['max'], eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00246 array(), 'max' );
00247 $maxText = "\$max";
00248 $maxPopText = ", \$max";
00249 $useMax = true;
00250 }
00251 }
00252
00253
00254 $useShow = false;
00255
00256 $useMain = true;
00257
00258 $useElse = false;
00259
00260 $spacing = 0;
00261 if ( isset( $parameters['show'] ) )
00262 {
00263 if ( eZTemplateNodeTool::isStaticElement( $parameters['show'] ) )
00264 {
00265 $showValue = eZTemplateNodeTool::elementStaticValue( $parameters['show'] );
00266 if ( $showValue )
00267 {
00268 $useMain = true;
00269 $useElse = false;
00270 $useShow = false;
00271 }
00272 else
00273 {
00274 $useMain = false;
00275 $useElse = true;
00276 $useShow = false;
00277 }
00278 $newNodes[] = eZTemplateNodeTool::createTextNode( '' );
00279 }
00280 else
00281 {
00282 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['show'], eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00283 array(), 'show' );
00284 $spacing = 4;
00285 $useElse = true;
00286 $useShow = true;
00287 }
00288 }
00289
00290 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node );
00291 if ( $useShow )
00292 {
00293 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$show )\n{\n" );
00294 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( $spacing );
00295 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( 'show' );
00296 }
00297 if ( isset( $parameters['name'] ) and !$useLoop )
00298 $newNodes[] = eZTemplateNodeTool::createNamespaceChangeNode( $parameters['name'] );
00299 $mainNodes = eZTemplateNodeTool::extractNodes( $children,
00300 array( 'match' => array( 'type' => 'before',
00301 'matches' => array( array( 'match-keys' => array( 0 ),
00302 'match-with' => EZ_TEMPLATE_NODE_FUNCTION ),
00303 array( 'match-keys' => array( 2 ),
00304 'match-with' => 'section-else' ) ),
00305 'filter' => array( array( array( 'match-keys' => array( 0 ),
00306 'match-with' => EZ_TEMPLATE_NODE_FUNCTION ),
00307 array( 'match-keys' => array( 2 ),
00308 'match-with' => array( 'delimiter', 'section-exclude', 'section-include' ) ) ) ) ) ) );
00309 $delimiterNodes = eZTemplateNodeTool::extractNodes( $children,
00310 array( 'match' => array( 'type' => 'equal',
00311 'matches' => array( array( 'match-keys' => array( 0 ),
00312 'match-with' => EZ_TEMPLATE_NODE_FUNCTION ),
00313 array( 'match-keys' => array( 2 ),
00314 'match-with' => 'delimiter' ) ) ) ) );
00315 $filterNodes = eZTemplateNodeTool::extractNodes( $children,
00316 array( 'match' => array( 'type' => 'equal',
00317 'matches' => array( array( 'match-keys' => array( 0 ),
00318 'match-with' => EZ_TEMPLATE_NODE_FUNCTION ),
00319 array( 'match-keys' => array( 2 ),
00320 'match-with' => array( 'section-exclude', 'section-include' ) ) ) ) ) );
00321
00322 $delimiterNode = false;
00323 if ( count( $delimiterNodes ) > 0 )
00324 $delimiterNode = $delimiterNodes[0];
00325
00326 if ( $useMain )
00327 {
00328
00329 $mainNodes = eZTemplateCompiler::processNodeTransformationNodes( $tpl, $node, $mainNodes, $privateData );
00330 }
00331
00332 if ( $useLoop and $useMain )
00333 {
00334 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['loop'], eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00335 array(), 'loopItem' );
00336 $hasSequence = false;
00337 if ( isset( $parameters['sequence'] ) )
00338 {
00339 $sequenceParameter = $parameters['sequence'];
00340 $hasSequence = true;
00341 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $sequenceParameter, eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00342 array(), 'sequence' );
00343 }
00344
00345 if ( isset( $parameters['name'] ) )
00346 $newNodes[] = eZTemplateNodeTool::createNamespaceChangeNode( $parameters['name'] );
00347
00348 $code = ( "if ( !isset( \$sectionStack ) )\n" .
00349 " \$sectionStack = array();\n" );
00350
00351 $variableValuePushText = '';
00352 $variableValuePopText = '';
00353 if ( $varName )
00354 {
00355 $code .= ( "include_once( 'lib/eztemplate/classes/eztemplatesectioniterator.php' );\n" .
00356 "\$variableValue = new eZTemplateSectionIterator();\n" .
00357 "\$lastVariableValue = false;\n" );
00358 $variableValuePushText = "&\$variableValue, ";
00359 $variableValuePopText = "\$variableValue, ";
00360 }
00361 $code .= ( "\$index = 0;\n" .
00362 "\$currentIndex = 1;\n" );
00363
00364
00365 $arrayCode = '';
00366 $numericCode = '';
00367 $stringCode = '';
00368 $offsetText = '0';
00369 if ( isset( $parameters['offset'] ) )
00370 {
00371 $offsetParameter = $parameters['offset'];
00372 if ( eZTemplateNodeTool::isStaticElement( $offsetParameter ) )
00373 {
00374 $iterationValue = (int)eZTemplateNodeTool::elementStaticValue( $offsetParameter );
00375 if ( $iterationValue > 0 )
00376 {
00377 $arrayCode = " \$loopKeys = array_splice( \$loopKeys, $iterationValue );\n";
00378 }
00379 $offsetText = $iterationValue;
00380 }
00381 else
00382 {
00383 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $offsetParameter, eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00384 array(), 'offset' );
00385 $arrayCode = ( " if ( \$offset > 0 )\n" .
00386 " \$loopKeys = array_splice( \$loopKeys, \$offset );\n" );
00387 $offsetText = "\$offset";
00388 }
00389 }
00390
00391
00392 $code .= ( "if ( is_array( \$loopItem ) )\n{\n" .
00393 " \$loopKeys = array_keys( \$loopItem );\n" );
00394 if ( $reverseLoop )
00395 $code .= " \$loopKeys = array_reverse( \$loopKeys );\n";
00396 $code .= $arrayCode;
00397 $code .= " \$loopCount = count( \$loopKeys );\n";
00398 $code .= "}\n";
00399
00400
00401 $code .= ( "else if ( is_numeric( \$loopItem ) )\n{\n" .
00402 " \$loopKeys = false;\n" .
00403 $numericCode .
00404 " if ( \$loopItem < 0 )\n" .
00405 " \$loopCountValue = -\$loopItem;\n" .
00406 " else\n" .
00407 " \$loopCountValue = \$loopItem;\n" .
00408 " \$loopCount = \$loopCountValue - $offsetText;\n" .
00409 "}\n" );
00410
00411
00412 $code .= ( "else if ( is_string( \$loopItem ) )\n{\n" .
00413 " \$loopKeys = false;\n" .
00414 $stringCode .
00415 " \$loopCount = strlen( \$loopItem ) - $offsetText;\n" .
00416 "}\n" );
00417
00418 $code .= ( "else\n{\n" .
00419 " \$loopKeys = false;\n" .
00420 " \$loopCount = 0;\n" .
00421 "}" );
00422
00423
00424
00425
00426 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code );
00427 $code = ( "while ( \$index < \$loopCount )\n" .
00428 "{\n" );
00429 if ( $useMax )
00430 $code .= ( " if ( \$currentIndex > $maxText )\n" .
00431 " break;\n" .
00432 " unset( \$item );\n" );
00433
00434
00435
00436 $code .= ( " if ( is_array( \$loopItem ) )\n" .
00437 " {\n" .
00438 " \$loopKey = \$loopKeys[\$index];\n" .
00439 " unset( \$item );\n" .
00440 " \$item = \$loopItem[\$loopKey];\n" .
00441 " }\n" );
00442
00443
00444 $code .= ( " else if ( is_numeric( \$loopItem ) )\n" .
00445 " {\n" .
00446 " unset( \$item );\n" );
00447 if ( $reverseLoop )
00448 $code .= " \$item = \$loopCountValue - \$index - $offsetText;\n";
00449 else
00450 $code .= " \$item = \$index + $offsetText + 1;\n";
00451 $code .= ( " if ( \$loopItem < 0 )\n" .
00452 " \$item = -\$item;\n" );
00453 if ( $reverseLoop )
00454 $code .= " \$loopKey = \$loopCountValue - \$index - $offsetText - 1;\n";
00455 else
00456 $code .= " \$loopKey = \$index + $offsetText;\n";
00457 $code .= " }\n";
00458
00459
00460 $code .= ( " else if ( is_string( \$loopItem ) )\n" .
00461 " {\n" .
00462 " unset( \$item );\n" );
00463 if ( $reverseLoop )
00464 $code .= " \$loopKey = \$loopCount - \$index - $offsetText + 1;\n";
00465 else
00466 $code .= " \$loopKey = \$index + $offsetText;\n";
00467 $code .= ( " \$item = \$loopItem[\$loopKey];\n" .
00468 " }\n" );
00469
00470
00471 $code .= ( " unset( \$last );\n" .
00472 " \$last = false;\n" );
00473 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code );
00474 $code = '';
00475 if ( $useLastValue )
00476 {
00477 $code .= ( " if ( \$currentIndex > 1 )\n" .
00478 " {\n" .
00479 " \$last = \$lastVariableValue;\n" .
00480 " \$variableValue = new eZTemplateSectionIterator();\n" .
00481 " }\n" );
00482 }
00483 if ( $varName )
00484 {
00485 $code .= " \$variableValue->setIteratorValues( \$item, \$loopKey, \$currentIndex - 1, \$currentIndex, false, \$last );";
00486 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code );
00487 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'variableValue', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00488 array( 'spacing' => 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, $varName ), false, true, true );
00489 }
00490 else
00491 {
00492 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'loopKey', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00493 array( 'spacing' => 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, 'key' ), false, true, true );
00494 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'item', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00495 array( 'spacing' => 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, 'item' ), false, true, true );
00496 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$currentIndexInc = \$currentIndex - 1;\n" );
00497 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'currentIndexInc', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00498 array( 'spacing' => 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, 'index' ), false, true, true );
00499 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'currentIndex', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00500 array( 'spacing' => 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, 'number' ), false, true, true );
00501 }
00502
00503 $mainSpacing = 0;
00504 $hasFilter = false;
00505 if ( count( $filterNodes ) > 0 )
00506 {
00507 $newFilterNodes = array();
00508 $matchValue = true;
00509 $hasDynamicFilter = false;
00510 foreach ( $filterNodes as $filterNode )
00511 {
00512 $filterParameters = eZTemplateNodeTool::extractFunctionNodeParameters( $filterNode );
00513 if ( !isset( $filterParameters['match'] ) )
00514 continue;
00515 $hasFilter = true;
00516 $filterParameterMatch = $filterParameters['match'];
00517 $filterParameterMatch = eZTemplateCompiler::processElementTransformationList( $tpl, $filterNode, $filterParameterMatch, $privateData );
00518 if ( eZTemplateNodeTool::isStaticElement( $filterParameterMatch ) )
00519 {
00520 $matchValue = eZTemplateNodeTool::elementStaticValue( $filterParameterMatch );
00521 if ( eZTemplateNodeTool::extractFunctionNodeName( $filterNode ) == 'section-exclude' )
00522 {
00523 if ( $matchValue )
00524 $matchValue = false;
00525 }
00526 else
00527 {
00528 if ( $matchValue )
00529 $matchValue = true;
00530 }
00531 $newFilterNodes = array();
00532 $hasDynamicFilter = false;
00533 }
00534 else
00535 {
00536 $newFilterNodes[] = eZTemplateNodeTool::createVariableNode( false, $filterParameterMatch, eZTemplateNodeTool::extractFunctionNodePlacement( $filterNode ),
00537 array( 'spacing' => 4 ), 'tmpMatchValue' );
00538 if ( eZTemplateNodeTool::extractFunctionNodeName( $filterNode ) == 'section-exclude' )
00539 {
00540 $newFilterNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$tmpMatchValue )\n \$matchValue = false;",
00541 array( 'spacing' => 4 ) );
00542 }
00543 else
00544 {
00545 $newFilterNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$tmpMatchValue )\n \$matchValue = true;",
00546 array( 'spacing' => 4 ) );
00547 }
00548 $hasDynamicFilter = true;
00549 }
00550 }
00551 if ( $hasFilter )
00552 {
00553 $mainSpacing += 4;
00554 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $matchValue, eZTemplateNodeTool::extractFunctionNodePlacement( $filterNode ),
00555 array( 'spacing' => 4 ), 'matchValue' );
00556 if ( $hasDynamicFilter )
00557 {
00558 $newNodes = array_merge( $newNodes, $newFilterNodes );
00559 }
00560 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$matchValue )\n{\n", array( 'spacing' => 4 ) );
00561 }
00562 }
00563
00564 $sequencePopText = '';
00565 if ( $hasSequence )
00566 {
00567 $sequencePopText = ", \$sequence";
00568 if ( $varName )
00569 {
00570 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( is_array( \$sequence ) )\n" .
00571 "{\n" .
00572 " \$sequenceValue = array_shift( \$sequence );\n" .
00573 " \$variableValue->setSequence( \$sequenceValue );\n" .
00574 " \$sequence[] = \$sequenceValue;\n" .
00575 " unset( \$sequenceValue );\n" .
00576 "}", array( 'spacing' => $mainSpacing + 4 ) );
00577 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'variableValue', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00578 array( 'spacing' => 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, $varName ), false, true, true );
00579 }
00580 else
00581 {
00582 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( is_array( \$sequence ) )\n" .
00583 "{\n" .
00584 " \$sequenceValue = array_shift( \$sequence );\n", array( 'spacing' => $mainSpacing + 4 ) );
00585 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, 'sequenceValue', eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00586 array( 'spacing' => $mainSpacing + 4 ), array( '', EZ_TEMPLATE_NAMESPACE_SCOPE_RELATIVE, 'sequence' ), false, true, true );
00587 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( " \$sequence[] = \$sequenceValue;\n" .
00588 " unset( \$sequenceValue );\n" .
00589 "}", array( 'spacing' => $mainSpacing + 4 ) );
00590 }
00591 }
00592 $code = ( "\$sectionStack[] = array( " . $variableValuePushText . "&\$loopItem, \$loopKeys, \$loopCount, \$currentIndex, \$index" . $sequencePopText . $maxPopText . " );\n" .
00593 "unset( \$loopItem, \$loopKeys );\n" );
00594 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code, array( 'spacing' => $mainSpacing + 4 ) );
00595
00596 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( $mainSpacing + 4 );
00597
00598 if ( $delimiterNode )
00599 {
00600 $delimiterChildren = eZTemplateNodeTool::extractFunctionNodeChildren( $delimiterNode );
00601 $delimiterParameters = eZTemplateNodeTool::extractFunctionNodeParameters( $delimiterNode );
00602 $delimiterChildren = eZTemplateCompiler::processNodeTransformationNodes( $tpl, $node, $delimiterChildren, $privateData );
00603 $delimiterModulo = false;
00604 $matchCode = false;
00605 $useModulo = true;
00606 if ( isset( $delimiterParameters['match'] ) )
00607 {
00608 $delimiterMatch = $delimiterParameters['match'];
00609 $delimiterMatch = eZTemplateCompiler::processElementTransformationList( $tpl, $delimiterNode, $delimiterMatch, $privateData );
00610 if ( eZTemplateNodeTool::isStaticElement( $delimiterMatch ) )
00611 {
00612 $moduloValue = eZTemplateNodeTool::elementStaticValue( $delimiterMatch );
00613 $useModulo = false;
00614 }
00615 else
00616 {
00617 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $delimiterMatch, eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00618 array( 'spacing' => 0 ), 'matchValue' );
00619 $matchCode = " and \$matchValue";
00620 }
00621 }
00622 else if ( isset( $delimiterParameters['modulo'] ) )
00623 {
00624 $delimiterModulo = $delimiterParameters['modulo'];
00625 $delimiterModulo = eZTemplateCompiler::processElementTransformationList( $tpl, $delimiterModulo, $delimiterModulo, $privateData );
00626 if ( eZTemplateNodeTool::isStaticElement( $delimiterModulo ) )
00627 {
00628 $moduloValue = (int)eZTemplateNodeTool::elementStaticValue( $delimiterModulo );
00629 $matchCode = " and ( ( \$currentIndex - 1 ) % $moduloValue ) == 0";
00630 }
00631 else
00632 {
00633 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $delimiterModulo, eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
00634 array( 'spacing' => 0 ), 'moduloValue' );
00635 $matchCode = " and ( ( \$currentIndex - 1 ) % \$moduloValue ) == 0";
00636 }
00637 }
00638 if ( $useModulo )
00639 {
00640 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$currentIndex > 1$matchCode )\n{" );
00641
00642 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 );
00643 $newNodes = array_merge( $newNodes, $delimiterChildren );
00644 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( 4 );
00645
00646 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\n" );
00647 }
00648 }
00649 $newNodes = array_merge( $newNodes, $mainNodes );
00650 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( $mainSpacing + 4 );
00651
00652 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "list( " . $variableValuePopText . "\$loopItem, \$loopKeys, \$loopCount, \$currentIndex, \$index" . $sequencePopText. $maxPopText . " ) = array_pop( \$sectionStack );",
00653 array( 'spacing' => $mainSpacing + 4 ) );
00654 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "++\$currentIndex;\n", array( 'spacing' => $mainSpacing + 4 ) );
00655 if ( $varName )
00656 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$lastVariableValue = \$variableValue;", array( 'spacing' => $mainSpacing + 4 ) );
00657 if ( $hasFilter )
00658 {
00659 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( " }" );
00660 $mainSpacing -= 4;
00661 }
00662 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "++\$index;\n", array( 'spacing' => $mainSpacing + 4 ) );
00663 $code = ( "}\n" .
00664 "unset( \$loopKeys, \$loopCount, \$index, \$last, \$loopIndex, \$loopItem" );
00665 if ( $hasSequence )
00666 $code .= ", \$sequence";
00667 $code .= " );";
00668 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code );
00669 }
00670 else if ( $useMain )
00671 {
00672 $newNodes = array_merge( $newNodes, $mainNodes );
00673 }
00674
00675 if ( isset( $parameters['name'] ) )
00676 $newNodes[] = eZTemplateNodeTool::createNamespaceRestoreNode();
00677
00678 if ( $useShow )
00679 {
00680 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( $spacing );
00681 }
00682
00683 if ( $useElse )
00684 {
00685 $elseNodes = eZTemplateNodeTool::extractNodes( $children,
00686 array( 'match' => array( 'type' => 'after',
00687 'matches' => array( array( 'match-keys' => array( 0 ),
00688 'match-with' => EZ_TEMPLATE_NODE_FUNCTION ),
00689 array( 'match-keys' => array( 2 ),
00690 'match-with' => 'section-else' ) )
00691 ) ) );
00692 $elseNodes = eZTemplateCompiler::processNodeTransformationNodes( $tpl, $node, $elseNodes, $privateData );
00693 if ( count( $elseNodes ) > 0 )
00694 {
00695 if ( $useShow )
00696 {
00697
00698 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\nelse\n{\n" );
00699 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( $spacing );
00700 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( 'show' );
00701 }
00702
00703 if ( isset( $parameters['name'] ) )
00704 $newNodes[] = eZTemplateNodeTool::createNamespaceChangeNode( $parameters['name'] );
00705 $newNodes = array_merge( $newNodes, $elseNodes );
00706 if ( isset( $parameters['name'] ) )
00707 $newNodes[] = eZTemplateNodeTool::createNamespaceRestoreNode();
00708
00709 if ( $useShow )
00710 {
00711
00712 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( $spacing );
00713 }
00714 }
00715
00716 if ( $useShow )
00717 {
00718
00719 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\n" );
00720 }
00721 }
00722 return $newNodes;
00723 }
00724
00725
00726
00727
00728 function process( &$tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
00729 {
00730 $children = $functionChildren;
00731 $parameters = $functionParameters;
00732 $name = null;
00733 if ( isset( $parameters["name"] ) )
00734 $name = $tpl->elementValue( $parameters["name"], $rootNamespace, $currentNamespace, $functionPlacement );
00735 if ( $name === null )
00736 {
00737 $name = $currentNamespace;
00738 }
00739 else
00740 {
00741 if ( $currentNamespace != "" )
00742 $name = "$currentNamespace:$name";
00743 }
00744
00745 $loopItem = null;
00746 $hasLoopItemParameter = false;
00747 if ( isset( $parameters["loop"] ) )
00748 {
00749 $hasLoopItemParameter = true;
00750 $loopItem =& $tpl->elementValue( $parameters["loop"], $rootNamespace, $currentNamespace, $functionPlacement );
00751 }
00752
00753 $variableIterator = null;
00754 if ( isset( $parameters['var'] ) )
00755 {
00756 $variableIterator =& $tpl->elementValue( $parameters['var'], $rootNamespace, $currentNamespace, $functionPlacement );
00757 }
00758
00759 $noLastValue = true;
00760 if ( isset( $parameters['last-value'] ) )
00761 {
00762 $lastValue =& $tpl->elementValue( $parameters['last-value'], $rootNamespace, $currentNamespace, $functionPlacement );
00763 $noLastValue = !$lastValue;
00764 }
00765
00766 $reverseLoop = false;
00767 if ( isset( $parameters['reverse'] ) )
00768 {
00769 $reverseLoop =& $tpl->elementValue( $parameters['reverse'], $rootNamespace, $currentNamespace, $functionPlacement );
00770 }
00771 if ( $hasLoopItemParameter and $loopItem === null )
00772 return;
00773
00774 $showItem = null;
00775 $showSet = isset( $parameters["show"] );
00776 if ( $showSet )
00777 $showItem =& $tpl->elementValue( $parameters["show"], $rootNamespace, $currentNamespace, $functionPlacement );
00778
00779 $sequenceStructure = null;
00780 if ( isset( $parameters["sequence"] ) )
00781 $sequenceStructure = $tpl->elementValue( $parameters["sequence"], $rootNamespace, $currentNamespace, $functionPlacement );
00782
00783 $iterationMaxCount = false;
00784 if ( isset( $parameters["max"] ) )
00785 {
00786 $iterationMaxCount =& $tpl->elementValue( $parameters["max"], $rootNamespace, $currentNamespace, $functionPlacement );
00787 if ( is_array( $iterationMaxCount ) )
00788 {
00789 $iterationMaxCount = count( $iterationMaxCount );
00790 }
00791 else if ( !is_numeric( $iterationMaxCount ) )
00792 {
00793 $tpl->warning( $functionName, "Wrong parameter type '" . gettype( $iterationMaxCount ) . "' for 'max', use either numericals or arrays", $functionPlacement );
00794 }
00795 $iterationMaxCount = (int)$iterationMaxCount;
00796 }
00797
00798 $iterationOffset = false;
00799 if ( isset( $parameters["offset"] ) )
00800 {
00801 $iterationOffset =& $tpl->elementValue( $parameters["offset"], $rootNamespace, $currentNamespace, $functionPlacement );
00802 if ( is_array( $iterationOffset ) )
00803 {
00804 $iterationOffset = count( $iterationOffset );
00805 }
00806 else if ( !is_numeric( $iterationOffset ) )
00807 {
00808 $tpl->warning( $functionName, "Wrong parameter type '" . gettype( $iterationOffset ) . "' for 'offset', use either numericals or arrays", $functionPlacement );
00809 }
00810 $iterationOffset = (int)$iterationOffset;
00811 if ( $iterationOffset < 0 )
00812 {
00813 $tpl->warning( $functionName, "The 'offset' parameter can only be negative, $iterationOffset is not accepteed, the value will be reset to 0", $functionPlacement );
00814 $iterationOffset = 0;
00815 }
00816 }
00817
00818 $elseName = $functionName . "-else";
00819 $delimiterStructure = null;
00820 $filterStructure = array();
00821 $else = null;
00822 $shown = 1;
00823 $items = array();
00824 $items[0] = array();
00825 $items[1] = array();
00826 if ( is_array( $children ) )
00827 {
00828 foreach ( array_keys( $children ) as $childKey )
00829 {
00830 $child =& $children[$childKey];
00831 $childType = $child[0];
00832 if ( $childType == EZ_TEMPLATE_NODE_FUNCTION )
00833 {
00834 switch ( $child[2] )
00835 {
00836 case "delimiter":
00837 {
00838 if ( $shown === 1 and $delimiterStructure === null )
00839 {
00840 $delimiterStructure =& $child;
00841 }
00842 } break;
00843 case "section-exclude":
00844 case "section-include":
00845 {
00846 if ( $shown === 1 )
00847 $filterStructure[] =& $child;
00848 } break;
00849 case $elseName:
00850 {
00851 $else =& $child;
00852 $shown = 0;
00853 } break;
00854 default:
00855 {
00856 $items[$shown][] =& $child;
00857 } break;
00858 }
00859 }
00860 else
00861 {
00862 $items[$shown][] =& $child;
00863 }
00864 }
00865 }
00866
00867 $canShowBlock = true;
00868 if( $showSet and ( ( is_array( $showItem ) and count( $showItem ) == 0 ) or
00869 ( is_numeric( $showItem ) and $showItem == 0 ) or
00870 ( is_string( $showItem ) > 0 and strlen( $showItem ) == 0 ) or
00871 !$showItem ) )
00872 $canShowBlock = false;
00873
00874 if ( ( !$showSet or ( $showSet and $canShowBlock ) ) and $loopItem === null )
00875 {
00876 $this->processChildrenOnce( $textElements, $items[1], $tpl, $rootNamespace, $name );
00877 }
00878 else
00879 {
00880 $iteratorData = array( 'iterator' => false );
00881 $showMainBody = true;
00882 if ( $showSet )
00883 {
00884 if( !$canShowBlock )
00885 $showMainBody = false;
00886 }
00887 if ( $showMainBody )
00888 {
00889 $isFirstRun = true;
00890 $index = 0;
00891 if ( is_array( $loopItem ) )
00892 {
00893 $array =& $loopItem;
00894 $arrayKeys = array_keys( $array );
00895 if ( $reverseLoop )
00896 $arrayKeys = array_reverse( $arrayKeys );
00897 if ( $iterationOffset !== false )
00898 $arrayKeys = array_splice( $arrayKeys, $iterationOffset );
00899 $currentCount = 0;
00900 foreach ( $arrayKeys as $key )
00901 {
00902 unset( $item );
00903 $item =& $array[$key];
00904 $usedElement = $this->processChildren( $textElements, $items[1], $key, $item, $index, $isFirstRun,
00905 $delimiterStructure, $sequenceStructure, $filterStructure,
00906 $tpl, $rootNamespace, $name, $functionPlacement,
00907 $variableIterator, $noLastValue,
00908 $iteratorData );
00909 if ( $usedElement )
00910 {
00911 if ( $iterationMaxCount !== false )
00912 {
00913 ++$currentCount;
00914 if ( $currentCount >= $iterationMaxCount )
00915 break;
00916 }
00917 }
00918 }
00919 }
00920 else if ( is_numeric( $loopItem ) )
00921 {
00922 $value = $loopItem;
00923 $count = $value;
00924 if ( $value < 0 )
00925 $count = -$count;
00926 $loopStart = 0;
00927 if ( $iterationOffset !== false )
00928 $loopStart = $iterationOffset;
00929 $currentCount = 0;
00930 for ( $i = $loopStart; $i < $count; ++$i )
00931 {
00932 unset( $iterator );
00933 if ( $reverseLoop )
00934 $iterator = ( $count - $i ) - 1;
00935 else
00936 $iterator = $i;
00937 unset( $key );
00938 unset( $item );
00939 if ( $value < 0 )
00940 {
00941 $key = $iterator;
00942 $item = -$iterator - 1;
00943 }
00944 else
00945 {
00946 $key = $iterator;
00947 $item = $iterator + 1;
00948 }
00949 $usedElement = $this->processChildren( $textElements, $items[1], $key, $item, $index, $isFirstRun,
00950 $delimiterStructure, $sequenceStructure, $filterStructure,
00951 $tpl, $rootNamespace, $name, $functionPlacement,
00952 $variableIterator, $noLastValue,
00953 $iteratorData );
00954 if ( $usedElement )
00955 {
00956 if ( $iterationMaxCount !== false )
00957 {
00958 ++$currentCount;
00959 if ( $currentCount >= $iterationMaxCount )
00960 break;
00961 }
00962 }
00963 }
00964 }
00965 else if ( is_string( $loopItem ) )
00966 {
00967 $text =& $loopItem;
00968 $stringLength = strlen( $text );
00969 $loopStart = 0;
00970 if ( $iterationOffset !== false )
00971 $loopStart = $iterationOffset;
00972 $currentCount = 0;
00973 for ( $i = $loopStart; $i < $stringLength; ++$i )
00974 {
00975 if ( $reverseLoop )
00976 $iterator = ($stringLength - $i) - 1;
00977 else
00978 $iterator = $i;
00979 unset( $key );
00980 unset( $item );
00981 $key = $iterator;
00982 $item = $text[$iterator];
00983 $usedElement = $this->processChildren( $textElements, $items[1], $key, $item, $index, $isFirstRun,
00984 $delimiterStructure, $sequenceStructure, $filterStructure,
00985 $tpl, $rootNamespace, $name, $functionPlacement,
00986 $variableIterator, $noLastValue,
00987 $iteratorData );
00988 if ( $usedElement )
00989 {
00990 if ( $iterationMaxCount !== false )
00991 {
00992 ++$currentCount;
00993 if ( $currentCount >= $iterationMaxCount )
00994 break;
00995 }
00996 }
00997 }
00998 }
00999 if ( !$isFirstRun )
01000 {
01001 if ( $variableIterator !== null )
01002 {
01003 $tpl->unsetVariable( $variableIterator, $name );
01004 }
01005 else
01006 {
01007 $tpl->unsetVariable( "key", $name );
01008 $tpl->unsetVariable( "item", $name );
01009 $tpl->unsetVariable( "index", $name );
01010 $tpl->unsetVariable( "number", $name );
01011 if ( $sequenceStructure !== null and is_array( $sequenceStructure ) )
01012 $tpl->unsetVariable( "sequence", $name );
01013 }
01014 }
01015 }
01016 else
01017 {
01018 $this->processChildrenOnce( $textElements, $items[0], $tpl, $rootNamespace, $name );
01019 }
01020 }
01021 }
01022
01023
01024
01025
01026
01027
01028 function processChildrenOnce( &$textElements, &$children, &$tpl, $rootNamespace, $name )
01029 {
01030 foreach ( array_keys( $children ) as $childKey )
01031 {
01032 $child =& $children[$childKey];
01033 $tpl->processNode( $child, $textElements, $rootNamespace, $name );
01034 }
01035 return true;
01036 }
01037
01038
01039
01040
01041
01042
01043
01044 function processChildren( &$textElements,
01045 &$children, $key, &$item, &$index, &$isFirstRun,
01046 &$delimiterStructure, &$sequenceStructure, &$filterStructure,
01047 &$tpl, $rootNamespace, $name, $functionPlacement,
01048 &$variableIterator, $noLastValue,
01049 &$iteratorData )
01050 {
01051 if ( $variableIterator !== null )
01052 {
01053 unset( $last );
01054 if ( !$noLastValue and $iteratorData['iterator'] !== false )
01055 {
01056 $last =& $iteratorData['iterator'];
01057 }
01058 else
01059 {
01060 $last = false;
01061 }
01062 unset( $iteratorData['iterator'] );
01063 $iteratorData['iterator'] = new eZTemplateSectionIterator();
01064 $iteratorData['iterator']->setIteratorValues( $item, $key, $index, $index + 1, false, $last );
01065 unset( $last );
01066
01067 $iteratorObject =& $iteratorData['iterator'];
01068 $tpl->setVariableRef( $variableIterator, $iteratorObject, $name );
01069 }
01070 else
01071 {
01072 $tpl->setVariable( "key", $key, $name );
01073 $tpl->setVariable( "item", $item, $name );
01074 $tpl->setVariable( "index", $index, $name );
01075 $tpl->setVariable( "number", $index + 1, $name );
01076 }
01077 if ( count( $filterStructure ) > 0 )
01078 {
01079 $filterCount = count( $filterStructure );
01080 $includeElement = true;
01081 for ( $i = 0; $i < $filterCount; ++$i )
01082 {
01083 $filterElement =& $filterStructure[$i];
01084 $filterParameters =& $filterElement[3];
01085 $filterName = $filterElement[2];
01086 $filterMatch = null;
01087 if ( isset( $filterParameters["match"] ) )
01088 {
01089 $filterMatch = $tpl->elementValue( $filterParameters["match"], $rootNamespace, $name, $functionPlacement );
01090 if ( $filterMatch )
01091 $includeElement = $filterName == "section-exclude" ? false : true;
01092 }
01093 else
01094 $tpl->missingParameter( "section:$filterName", "match" );
01095 }
01096 if ( !$includeElement )
01097 return false;
01098 }
01099 if ( $delimiterStructure !== null and !$isFirstRun )
01100 {
01101 $delimiterParameters = $delimiterStructure[3];
01102 $delimiterMatch = true;
01103 if ( isset( $delimiterParameters["modulo"] ) )
01104 {
01105 $delimiterModulo = $delimiterParameters["modulo"];
01106 $modulo = $tpl->elementValue( $delimiterModulo, $rootNamespace, $name, $functionPlacement );
01107 $modulo = trim( $modulo );
01108 if ( is_numeric( $modulo ) )
01109 $delimiterMatch = ( $index % $modulo ) == 0;
01110 }
01111 if ( isset( $delimiterParameters["match"] ) )
01112 {
01113 $delimiterMatchParameter = $delimiterParameters["match"];
01114 $delimiterMatch = $tpl->elementValue( $delimiterMatchParameter, $rootNamespace, $name, $functionPlacement );
01115 }
01116 if ( $delimiterMatch )
01117 {
01118 $delimiterChildren =& $delimiterStructure[1];
01119 if ( is_array( $delimiterChildren ) )
01120 {
01121 foreach ( array_keys( $delimiterChildren ) as $delimiterChildKey )
01122 {
01123 $delimiterChild =& $delimiterChildren[$delimiterChildKey];
01124 $tpl->processNode( $delimiterChild, $textElements, $rootNamespace, $name );
01125 }
01126 }
01127 }
01128 }
01129 $isFirstRun = false;
01130 if ( $sequenceStructure !== null and is_array( $sequenceStructure ) )
01131 {
01132 $sequenceValue = array_shift( $sequenceStructure );
01133 if ( $variableIterator !== null )
01134 {
01135 $iteratorData['iterator']->setSequence( $sequenceValue );
01136 }
01137 else
01138 {
01139 $tpl->setVariable( "sequence", $sequenceValue, $name );
01140 }
01141 $sequenceStructure[] = $sequenceValue;
01142 }
01143 foreach ( array_keys( $children ) as $childKey )
01144 {
01145 $child =& $children[$childKey];
01146 $tpl->processNode( $child, $textElements, $rootNamespace, $name );
01147 }
01148 ++$index;
01149 return true;
01150 }
01151
01152
01153
01154
01155 function hasChildren()
01156 {
01157 return true;
01158 }
01159
01160
01161
01162 var $Name;
01163 }
01164
01165 ?>