|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZTemplateCompiledLoop class 00004 // 00005 // Created on: <17-Mar-2005 11:26:59 vs> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 00032 /*! 00033 \class eZTemplateCompiledLoop eztemplatecompiledloop.php 00034 \ingroup eZTemplateFunctions 00035 \brief Common code for compiling the loop functions 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 * Returns true if sequence has been specified for the loop in its parameters. 00054 */ 00055 function hasSequence() 00056 { 00057 return isset( $this->Parameters['sequence_var'] ); 00058 } 00059 00060 /*! 00061 * Destroys PHP and template variables defined by the loop. 00062 */ 00063 function cleanup() 00064 { 00065 if ( $this->hasSequence() ) 00066 $this->destroySequenceVars(); 00067 00068 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = false;" ); 00069 } 00070 00071 /*! 00072 \private 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 * Create PHP and template variables representing sequence specified for the loop. 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 * Export current sequence value to the template variable specified in loop parameters. 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 * Increments loop sequence. 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 * Compiles loop children (=code residing between start and end tags of the loop). 00145 * Besides, does special handling of {break}, {continue}, {skip} and {delimiter} functions. 00146 * \return true if the caller loop should break, false otherwise 00147 */ 00148 function processChildren() 00149 { 00150 // process the loop body 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 ( $transformedChildren as $child ) 00160 { 00161 if ( $child[0] == eZTemplate::NODE_FUNCTION ) // check child type 00162 { 00163 $childFunctionName = $child[2]; 00164 if ( $childFunctionName == 'delimiter' ) 00165 { 00166 // save delimiter for it to be processed below 00167 $delimiter = $child; 00168 continue; 00169 } 00170 elseif ( $childFunctionName == 'break' ) 00171 { 00172 $childrenNodes[] = eZTemplateNodeTool::createCodePieceNode( "break;\n" ); 00173 continue; 00174 } 00175 elseif ( $childFunctionName == 'continue' ) 00176 { 00177 $childrenNodes[] = eZTemplateNodeTool::createCodePieceNode( "continue;\n" ); 00178 continue; 00179 } 00180 elseif ( $childFunctionName == 'skip' ) 00181 { 00182 $childrenNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = true;\ncontinue;\n" ); 00183 continue; 00184 } 00185 } 00186 00187 $childrenNodes[] = $child; 00188 } 00189 } 00190 00191 if ( $delimiter ) // if delimiter is specified 00192 { 00193 $delimiterNodes = eZTemplateNodeTool::extractNodes( $children, 00194 array( 'match' => array( 'type' => 'equal', 00195 'matches' => array( array( 'match-keys' => array( 0 ), 00196 'match-with' => eZTemplate::NODE_FUNCTION ), 00197 array( 'match-keys' => array( 2 ), 00198 'match-with' => 'delimiter' ) ) ) ) ); 00199 $delimiterNode = false; 00200 if ( count( $delimiterNodes ) > 0 ) 00201 $delimiterNode = $delimiterNodes[0]; 00202 00203 $delimiterChildren = eZTemplateNodeTool::extractFunctionNodeChildren( $delimiterNode ); 00204 $delimiterParameters = eZTemplateNodeTool::extractFunctionNodeParameters( $delimiterNode ); 00205 00206 $checkModulo = array(); 00207 $checkModuloEnd = array(); 00208 $delemiterModuloValue = array(); 00209 if ( isset( $delimiterParameters['modulo'] ) ) 00210 { 00211 switch ( $this->Name ) 00212 { 00213 case 'foreach': 00214 { 00215 $delimiterModulo = $delimiterParameters['modulo']; 00216 $delimiterModulo = eZTemplateCompiler::processElementTransformationList( $this->Tpl, $delimiterModulo, $delimiterModulo, $this->PrivateData ); 00217 // Get unique index 00218 $currentIndex = "\$fe_i_$this->UniqID"; 00219 00220 if ( eZTemplateNodeTool::isStaticElement( $delimiterModulo ) ) 00221 { 00222 $moduloValue = (int)eZTemplateNodeTool::elementStaticValue( $delimiterModulo ); 00223 $matchCode = "( ( $currentIndex ) % $moduloValue ) == 0"; 00224 } 00225 else 00226 { 00227 $delemiterModuloValue[] = eZTemplateNodeTool::createVariableNode( false, $delimiterModulo, eZTemplateNodeTool::extractFunctionNodePlacement( $this->Node ), 00228 array( 'spacing' => 0 ), 'moduloValue' ); 00229 $matchCode = "( ( $currentIndex ) % \$moduloValue ) == 0"; 00230 } 00231 $checkModulo[] = eZTemplateNodeTool::createCodePieceNode( "if ( $matchCode ) // Check modulo\n{" ); 00232 $checkModulo[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 ); 00233 00234 $checkModuloEnd[] = eZTemplateNodeTool::createSpacingDecreaseNode( 4 ); 00235 $checkModuloEnd[] = eZTemplateNodeTool::createCodePieceNode( "}\n" ); 00236 } 00237 } 00238 } 00239 $delimiterNodes = array(); 00240 $delimiterNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$skipDelimiter )\n" . 00241 " \$skipDelimiter = false;\n" . 00242 "else\n" . 00243 "{ // delimiter begins" ); 00244 $delimiterNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode(); 00245 if ( is_array( $delimiter[1] ) ) // if delimiter has children 00246 { 00247 // If modulo is specified 00248 $delimiterNodes = array_merge( $delimiterNodes, $checkModulo ); 00249 00250 foreach ( $delimiter[1] as $delimiterChild ) 00251 $delimiterNodes[] = $delimiterChild; 00252 00253 // Set end of checking for modulo 00254 $delimiterNodes = array_merge( $delimiterNodes, $checkModuloEnd ); 00255 } 00256 00257 $delimiterNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode(); 00258 $delimiterNodes[] = eZTemplateNodeTool::createCodePieceNode( "} // delimiter ends\n" ); 00259 00260 // we place its code right before other loop children, 00261 // if delemiter and modulo are specified and value of modulo is not static 00262 // $delemiterModuloValue is initialization of variable 00263 // we should place initialization of moduloValue before checking for delimiter 00264 $childrenNodes = array_merge( $delemiterModuloValue, $delimiterNodes, $childrenNodes ); 00265 } 00266 00267 $this->NewNodes = array_merge( $this->NewNodes, $childrenNodes ); 00268 } 00269 00270 /*! 00271 * Generates loop body. 00272 */ 00273 function processBody() 00274 { 00275 // export current sequence value to the specified template variable <$sequence_var> 00276 $this->setCurrentSequenceValue(); 00277 00278 // process the loop body 00279 $this->processChildren(); 00280 00281 $this->iterateSequence(); 00282 } 00283 00284 /*! 00285 * create PHP and template variables needed for the loop. 00286 */ 00287 function initVars() 00288 { 00289 // initialize delimiter processing 00290 $this->NewNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = true;" ); 00291 00292 // initialize sequence 00293 $this->createSequenceVars(); 00294 } 00295 00296 /// 00297 /// \privatesection 00298 /// 00299 public $Name; 00300 public $Parameters; 00301 public $NodePlacement; 00302 public $UniqID; 00303 public $NewNodes; 00304 public $Node; 00305 public $Tpl; 00306 public $PrivateData; 00307 00308 } 00309 00310 ?>