|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZTemplateLoop class 00004 // 00005 // Created on: <23-Feb-2005 17:46:42 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 // private class, should not be used outside of this file 00033 class eZTemplateLoopSequence 00034 { 00035 function eZTemplateLoopSequence( $array ) 00036 { 00037 $this->ArrayRef = $array; 00038 $this->CurVal = current( $this->ArrayRef ); 00039 } 00040 00041 function val() 00042 { 00043 return $this->CurVal; 00044 } 00045 00046 function next() 00047 { 00048 if( ( $this->CurVal = next( $this->ArrayRef ) ) === false ) 00049 { 00050 reset( $this->ArrayRef ); 00051 $this->CurVal = current( $this->ArrayRef ); 00052 } 00053 } 00054 00055 public $ArrayRef; 00056 public $CurVal; 00057 } 00058 00059 /*! 00060 \class eZTemplateLoop eztemplateloop.php 00061 \ingroup eZTemplateFunctions 00062 \brief Code common for the loop functions in processed mode. 00063 */ 00064 class eZTemplateLoop 00065 { 00066 function eZTemplateLoop( $functionName, &$functionParameters, $functionChildren, $functionPlacement, 00067 $tpl, &$textElements, $rootNamespace, $currentNamespace ) 00068 { 00069 $this->SkipDelimiter = true; 00070 $this->SkipSequenceIncrement = false; 00071 $this->Delimiter = null; 00072 $this->Initialized = true; 00073 $this->SequenceVarName = null; 00074 $this->Sequence = null; 00075 $this->LoopVariablesNames = array(); 00076 00077 00078 $this->FunctionName = $functionName; 00079 $this->FunctionParameters =& $functionParameters; 00080 $this->FunctionChildren = $functionChildren; 00081 00082 $this->Tpl = $tpl; 00083 $this->TextElements =& $textElements; 00084 $this->RootNamespace = $rootNamespace; 00085 $this->CurrentNamespace = $currentNamespace; 00086 $this->FunctionPlacement = $functionPlacement; 00087 00088 $this->Initialized = $this->processFunctionParameters(); 00089 } 00090 00091 /*! 00092 \return true on success, false otherwise. 00093 */ 00094 function processFunctionParameters() 00095 { 00096 $params =& $this->FunctionParameters; 00097 00098 if ( !isset( $params['sequence_array'] ) || !count( $params['sequence_array'] ) ) 00099 return true; 00100 00101 $this->parseParamVarName( 'sequence_var', $seqVarName ); 00102 00103 if ( !$seqVarName ) 00104 { 00105 $this->Tpl->error( $this->FunctionName, "Empty sequence variable name." ); 00106 return false; 00107 } 00108 00109 $this->initLoopVariable( $seqVarName ); 00110 00111 $seqArray = $this->Tpl->elementValue( $params['sequence_array'], 00112 $this->RootNamespace, $this->CurrentNamespace, $this->FunctionPlacement ); 00113 00114 $this->Sequence = new eZTemplateLoopSequence( $seqArray ); 00115 $this->SequenceVarName = $seqVarName; 00116 00117 return true; 00118 } 00119 00120 /*! 00121 * \return true if the object has been correctly initialized, false otherwise 00122 */ 00123 function initialized() 00124 { 00125 return $this->Initialized; 00126 } 00127 00128 /*! Export current loop sequence value to the template variable 00129 * specified in loop parameters. 00130 */ 00131 function setSequenceVar() 00132 { 00133 if ( !$this->hasSequence() ) 00134 return; 00135 00136 $this->Tpl->setVariable( $this->SequenceVarName, $this->Sequence->val(), $this->RootNamespace ); 00137 } 00138 00139 /*! 00140 * Should be called each time a new iteration is started. 00141 * Resets some internal variables. 00142 */ 00143 function resetIteration() 00144 { 00145 $this->SkipDelimiter = false; 00146 $this->SkipSequenceIncrement = false; 00147 } 00148 00149 /*! 00150 * Increment current sequence value. 00151 */ 00152 function incrementSequence() 00153 { 00154 if ( $this->hasSequence() && !$this->SkipSequenceIncrement ) 00155 $this->Sequence->next(); 00156 } 00157 00158 /*! 00159 * Returns true if sequence has been specified for the loop in its parameters. 00160 */ 00161 function hasSequence() 00162 { 00163 return !is_null( $this->Sequence ); 00164 } 00165 00166 00167 /*! 00168 * Destroys template variables defined by the loop. 00169 */ 00170 function cleanup() 00171 { 00172 // destroy loop variable(s) 00173 foreach ( $this->LoopVariablesNames as $varName ) 00174 $this->Tpl->unsetVariable( $varName, $this->RootNamespace ); 00175 } 00176 00177 /* 00178 * Processes loop children, i.e. all tags and text that is 00179 * between start and end tags of the loop. 00180 * Besides, does special handling of {break}, {skip}, {continue} and {delimiter} tags. 00181 * 00182 * \return true if the caller loop should break, false otherwise 00183 */ 00184 function processChildren() 00185 { 00186 if ( !is_array( $this->FunctionChildren ) ) 00187 { 00188 return false; 00189 } 00190 foreach ( array_keys( $this->FunctionChildren ) as $childKey ) 00191 { 00192 $child = $this->FunctionChildren[$childKey]; 00193 00194 if ( $child[0] == eZTemplate::NODE_FUNCTION ) // check child type 00195 { 00196 $childFunctionName = $child[2]; 00197 00198 if ( $childFunctionName == 'break' ) 00199 return true; 00200 elseif ( $childFunctionName == 'continue' ) 00201 { 00202 $this->SkipSequenceIncrement = true; 00203 break; 00204 } 00205 elseif ( $childFunctionName == 'skip' ) 00206 { 00207 $this->SkipSequenceIncrement = true; 00208 $this->SkipDelimiter = true; 00209 break; 00210 } 00211 elseif ( $childFunctionName == 'delimiter' ) 00212 { 00213 if ( is_null( $this->Delimiter ) ) 00214 $this->Delimiter = $child; 00215 continue; 00216 } 00217 } 00218 00219 $rslt = $this->Tpl->processNode( $child, $this->TextElements, $this->RootNamespace, $this->CurrentNamespace ); 00220 00221 // break/continue/skip might be found in a child function's (usually {if}) children 00222 if ( is_array( $rslt ) ) 00223 { 00224 if ( array_key_exists( 'breakFunctionFound', $rslt ) ) 00225 return true; 00226 elseif ( array_key_exists( 'continueFunctionFound', $rslt ) ) 00227 { 00228 $this->SkipSequenceIncrement = true; 00229 break; 00230 } 00231 elseif ( array_key_exists( 'skipFunctionFound', $rslt ) ) 00232 { 00233 $this->SkipSequenceIncrement = true; 00234 $this->SkipDelimiter = true; 00235 break; 00236 } 00237 } 00238 00239 } // foreach 00240 00241 return false; 00242 } 00243 00244 /*! 00245 * If \c $loopCondition is true, shows delimiter (if one has been specified). 00246 * \param $index is needed for processing delimiter parameters such as modulo. 00247 * Is current iteration index. 00248 * \return true if the caller loop should break, false otherwise 00249 */ 00250 function processDelimiter( $index = false ) 00251 { 00252 if ( is_null( $this->Delimiter ) || $this->SkipDelimiter ) 00253 return false; 00254 00255 $delimiterChildren = $this->Delimiter[1]; 00256 $delimiterParameters = $this->Delimiter[3]; // Get parameters 00257 $delimiterMatch = true; 00258 // Check for "modulo" 00259 if ( isset( $delimiterParameters["modulo"] ) and $index !== false ) 00260 { 00261 $delimiterModulo = $delimiterParameters["modulo"]; 00262 $modulo = $this->Tpl->elementValue( $delimiterModulo, $this->RootNamespace, $this->FunctionName, $this->FunctionPlacement ); 00263 $modulo = trim( $modulo ); 00264 if ( is_numeric( $modulo ) ) 00265 $delimiterMatch = ( $index % $modulo ) == 0; 00266 } 00267 if ( $delimiterMatch ) 00268 { 00269 foreach ( $delimiterChildren as $delimiterChild ) 00270 { 00271 $this->Tpl->processNode( $delimiterChild, $this->TextElements, $this->RootNamespace, $this->CurrentNamespace ); 00272 } 00273 } 00274 00275 return false; 00276 } 00277 00278 /*! 00279 * Parses the given function parameter that is supposed to contain a variable name. 00280 * Extracted variable name is stored to $dst. 00281 * 00282 * @param $paramName Parameter name. 00283 * @param $dst Where to store parameter value. 00284 * @return false if specified parameter is not found or it is wrong, otherwise true is returned. 00285 */ 00286 function parseParamVarName( $paramName, &$dst ) 00287 { 00288 $dst = null; 00289 00290 if ( !isset( $this->FunctionParameters[$paramName] ) || 00291 !count( $this->FunctionParameters[$paramName] ) ) 00292 return false; 00293 00294 list( $varNsName, $varNsType, $varName ) = $this->FunctionParameters[$paramName][0][1]; 00295 00296 if ( $varNsType != eZTemplate::NAMESPACE_SCOPE_LOCAL || $varNsName ) 00297 { 00298 $this->Tpl->error( $this->FunctionName, 00299 'Loop variables can be defined in root namespace only (e.g. $foo, but not $#foo or $:foo.)' ); 00300 return false; 00301 } 00302 00303 $dst = $varName; 00304 return true; 00305 } 00306 00307 /*! 00308 * Parses given function parameter and makes sure that it is not a proxy object ({section} loop iterator). 00309 * 00310 * @param $paramName Parameter name. 00311 * @param $dst Where to store parameter value. 00312 * @param $isProxyObject boolean true is stored here if value of the parameter is a proxy object. 00313 * @return false if specified parameter is not found or it is wrong, otherwise true is returned. 00314 */ 00315 function parseScalarParamValue( $paramName, &$dst, &$isProxyObject ) 00316 { 00317 $dst = null; 00318 00319 if ( !isset( $this->FunctionParameters[$paramName] ) || !count( $this->FunctionParameters[$paramName] ) ) 00320 return false; 00321 00322 // get parameter value 00323 $dst = $this->Tpl->elementValue( $this->FunctionParameters[$paramName], $this->RootNamespace, 00324 $this->CurrentNamespace, $this->FunctionPlacement, false, true ); 00325 00326 // check if a proxy object ({section} loop iterator) was involved in the parameter value 00327 if ( isset( $this->FunctionParameters[$paramName]['proxy-object-found'] ) ) 00328 { 00329 $isProxyObject = true; 00330 unset( $this->FunctionParameters[$paramName]['proxy-object-found'] ); // just not to leave garbage 00331 } 00332 else 00333 $isProxyObject = false; 00334 00335 return true; 00336 } 00337 00338 /*! 00339 * Parses value the given function parameter and stores it to $dst. 00340 * 00341 * @param $paramName Parameter name. 00342 * @param $dst Where to store parameter value. 00343 * @return false if specified parameter is not found or it is wrong, otherwise true is returned. 00344 */ 00345 function parseParamValue( $paramName, &$dst ) 00346 { 00347 $dst = null; 00348 00349 if ( !isset( $this->FunctionParameters[$paramName] ) || !count( $this->FunctionParameters[$paramName] ) ) 00350 return false; 00351 00352 $dst = $this->Tpl->elementValue( $this->FunctionParameters[$paramName], $this->RootNamespace, 00353 $this->CurrentNamespace, $this->FunctionPlacement ); 00354 return true; 00355 } 00356 00357 /*! 00358 * Checks if the given loop variable already exists. If it doesn't, store its name for later cleanup. 00359 * Otherwise shows a warning message. 00360 * 00361 * @see eZTemplateLoop::$loopVariablesNames 00362 */ 00363 function initLoopVariable( $varName ) 00364 { 00365 if ( $this->Tpl->hasVariable( $varName, $this->RootNamespace ) ) 00366 $this->Tpl->warning( $this->FunctionName, "Variable '$varName' already exists." ); 00367 else 00368 $this->LoopVariablesNames[] = $varName; 00369 } 00370 00371 /// 00372 /// \privatesection 00373 /// 00374 00375 public $FunctionName; 00376 public $FunctionParameters; 00377 public $FunctionChildren; 00378 public $FunctionPlacement; 00379 00380 public $SkipDelimiter; 00381 public $SkipSequenceIncrement; 00382 public $delimiter; 00383 00384 public $Tpl; 00385 public $TextElements; 00386 public $RootNamespace; 00387 public $CurrentNamespace; 00388 00389 public $Initialized; 00390 public $Sequence; 00391 public $SequenceVarName; 00392 /*! 00393 * Before we create a new loop variable, we check if it already exists. 00394 * If it doesn't, we store its name in this array, so that we know 00395 * which variables to destroy after the loop execution finishes. 00396 */ 00397 public $LoopVariablesNames; 00398 } 00399 00400 ?>