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 class eZTemplateCompiledLoop
00038 {
00039 function eZTemplateCompiledLoop( $name, &$newNodes, &$parameters, &$nodePlacement, $uniqid,
00040 &$node, &$tpl, &$privateData )
00041 {
00042 $this->Name =& $name;
00043 $this->Parameters =& $parameters;
00044 $this->NodePlacement =& $nodePlacement;
00045 $this->UniqID =& $uniqid;
00046 $this->NewNodes =& $newNodes;
00047 $this->Node =& $node;
00048 $this->Tpl =& $tpl;
00049 $this->PrivateData =& $privateData;
00050 }
00051
00052
00053
00054
00055 function hasSequence()
00056 {
00057 return isset( $this->Parameters['sequence_var'] );
00058 }
00059
00060
00061
00062
00063 function cleanup()
00064 {
00065 if ( $this->hasSequence() )
00066 $this->destroySequenceVars();
00067
00068 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = false;" );
00069 }
00070
00071
00072
00073
00074 function destroySequenceVars()
00075 {
00076 $fName = $this->Name;
00077 $uniqid = $this->UniqID;
00078 $this->NewNodes[] = eZTemplateNodeTool::createVariableUnsetNode( "${fName}_sequence_array_$uniqid" );
00079 $this->NewNodes[] = eZTemplateNodeTool::createVariableUnsetNode( "${fName}_sequence_var_$uniqid" );
00080 $this->NewNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $this->Parameters['sequence_var'][0][1] );
00081 }
00082
00083
00084
00085
00086
00087 function createSequenceVars()
00088 {
00089 if ( !$this->hasSequence() )
00090 return;
00091
00092 $fName = $this->Name;
00093 $uniqid = $this->UniqID;
00094 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "// creating sequence variables for \{$fName} loop" );
00095 $this->NewNodes[] = eZTemplateNodeTool::createVariableNode( false,
00096 $this->Parameters['sequence_array'],
00097 $this->NodePlacement,
00098 array( 'treat-value-as-non-object' => true, 'text-result' => false ),
00099 "${fName}_sequence_array_$uniqid" );
00100 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$${fName}_sequence_var_$uniqid = current( \$${fName}_sequence_array_$uniqid );\n" );
00101 }
00102
00103
00104
00105
00106 function setCurrentSequenceValue()
00107 {
00108 if ( !$this->hasSequence() )
00109 return;
00110
00111 $fName = $this->Name;
00112 $uniqid = $this->UniqID;
00113 $seqVar = "${fName}_sequence_var_$uniqid";
00114 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "// setting current sequence value" );
00115 $this->NewNodes[] = eZTemplateNodeTool::createVariableNode( false, $seqVar, $this->NodePlacement, array(),
00116 $this->Parameters['sequence_var'][0][1],
00117 false, true, true );
00118 }
00119
00120
00121
00122
00123 function iterateSequence()
00124 {
00125 if ( !$this->hasSequence() )
00126 return;
00127
00128 $fName = $this->Name;
00129 $uniqid = $this->UniqID;
00130 $seqArray = "${fName}_sequence_array_$uniqid";
00131 $seqVar = "${fName}_sequence_var_$uniqid";
00132 $alterSeqValCode =
00133 "if ( ( \$$seqVar = next( \$$seqArray ) ) === false )\n" .
00134 "{\n" .
00135 " reset( \$$seqArray );\n" .
00136 " \$$seqVar = current( \$$seqArray );\n" .
00137 "}\n";
00138 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "// sequence iteration" );
00139 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( $alterSeqValCode );
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 function processChildren()
00149 {
00150
00151 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $this->Node );
00152 $transformedChildren = eZTemplateCompiler::processNodeTransformationNodes( $this->Tpl, $this->Node, $children, $this->PrivateData );
00153
00154 $childrenNodes = array();
00155 $delimiter = null;
00156
00157 if ( is_array( $transformedChildren ) )
00158 {
00159 foreach ( array_keys( $transformedChildren ) as $childKey )
00160 {
00161 $child =& $transformedChildren[$childKey];
00162
00163 if ( $child[0] == EZ_TEMPLATE_NODE_FUNCTION )
00164 {
00165 $childFunctionName = $child[2];
00166 if ( $childFunctionName == 'delimiter' )
00167 {
00168
00169 $delimiter =& $child;
00170 continue;
00171 }
00172 elseif ( $childFunctionName == 'break' )
00173 {
00174 $childrenNodes[] = eZTemplateNodeTool::createCodePieceNode( "break;\n" );
00175 continue;
00176 }
00177 elseif ( $childFunctionName == 'continue' )
00178 {
00179 $childrenNodes[] = eZTemplateNodeTool::createCodePieceNode( "continue;\n" );
00180 continue;
00181 }
00182 elseif ( $childFunctionName == 'skip' )
00183 {
00184 $childrenNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = true;\ncontinue;\n" );
00185 continue;
00186 }
00187 }
00188
00189 $childrenNodes[] = $child;
00190 }
00191 }
00192
00193 if ( $delimiter )
00194 {
00195 $delimiterNodes = eZTemplateNodeTool::extractNodes( $children,
00196 array( 'match' => array( 'type' => 'equal',
00197 'matches' => array( array( 'match-keys' => array( 0 ),
00198 'match-with' => EZ_TEMPLATE_NODE_FUNCTION ),
00199 array( 'match-keys' => array( 2 ),
00200 'match-with' => 'delimiter' ) ) ) ) );
00201 $delimiterNode = false;
00202 if ( count( $delimiterNodes ) > 0 )
00203 $delimiterNode = $delimiterNodes[0];
00204
00205 $delimiterChildren = eZTemplateNodeTool::extractFunctionNodeChildren( $delimiterNode );
00206 $delimiterParameters = eZTemplateNodeTool::extractFunctionNodeParameters( $delimiterNode );
00207
00208 $checkModulo = array();
00209 $checkModuloEnd = array();
00210 $delemiterModuloValue = array();
00211 if ( isset( $delimiterParameters['modulo'] ) )
00212 {
00213 switch ( $this->Name )
00214 {
00215 case 'foreach':
00216 {
00217 $delimiterModulo = $delimiterParameters['modulo'];
00218 $delimiterModulo = eZTemplateCompiler::processElementTransformationList( $this->Tpl, $delimiterModulo, $delimiterModulo, $this->PrivateData );
00219
00220 $currentIndex = "\$fe_i_$this->UniqID";
00221
00222 if ( eZTemplateNodeTool::isStaticElement( $delimiterModulo ) )
00223 {
00224 $moduloValue = (int)eZTemplateNodeTool::elementStaticValue( $delimiterModulo );
00225 $matchCode = "( ( $currentIndex ) % $moduloValue ) == 0";
00226 }
00227 else
00228 {
00229 $delemiterModuloValue[] = eZTemplateNodeTool::createVariableNode( false, $delimiterModulo, eZTemplateNodeTool::extractFunctionNodePlacement( $this->Node ),
00230 array( 'spacing' => 0 ), 'moduloValue' );
00231 $matchCode = "( ( $currentIndex ) % \$moduloValue ) == 0";
00232 }
00233 $checkModulo[] = eZTemplateNodeTool::createCodePieceNode( "if ( $matchCode ) // Check modulo\n{" );
00234 $checkModulo[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 );
00235
00236 $checkModuloEnd[] = eZTemplateNodeTool::createSpacingDecreaseNode( 4 );
00237 $checkModuloEnd[] = eZTemplateNodeTool::createCodePieceNode( "}\n" );
00238 }
00239 }
00240 }
00241 $delimiterNodes = array();
00242 $delimiterNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$skipDelimiter )\n" .
00243 " \$skipDelimiter = false;\n" .
00244 "else\n" .
00245 "{ // delimiter begins" );
00246 $delimiterNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode();
00247 if ( is_array( $delimiter[1] ) )
00248 {
00249
00250 $delimiterNodes = array_merge( $delimiterNodes, $checkModulo );
00251
00252 foreach ( $delimiter[1] as $delimiterChild )
00253 $delimiterNodes[] = $delimiterChild;
00254
00255
00256 $delimiterNodes = array_merge( $delimiterNodes, $checkModuloEnd );
00257 }
00258
00259 $delimiterNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode();
00260 $delimiterNodes[] = eZTemplateNodeTool::createCodePieceNode( "} // delimiter ends\n" );
00261
00262
00263
00264
00265
00266 $childrenNodes = array_merge( $delemiterModuloValue, $delimiterNodes, $childrenNodes );
00267 }
00268
00269 $this->NewNodes = array_merge( $this->NewNodes, $childrenNodes );
00270 }
00271
00272
00273
00274
00275 function processBody()
00276 {
00277
00278 $this->setCurrentSequenceValue();
00279
00280
00281 $this->processChildren();
00282
00283 $this->iterateSequence();
00284 }
00285
00286
00287
00288
00289 function initVars()
00290 {
00291
00292 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = true;" );
00293
00294
00295 $this->createSequenceVars();
00296 }
00297
00298
00299
00300
00301 var $Name;
00302 var $Parameters;
00303 var $NodePlacement;
00304 var $UniqID;
00305 var $NewNodes;
00306 var $Node;
00307 var $Tpl;
00308 var $PrivateData;
00309
00310 }
00311
00312 ?>