|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZTemplateForFunction class 00004 // 00005 // Created on: <21-Feb-2005 12:38:26 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 \class eZTemplateForFunction eztemplateforfunction.php 00033 \ingroup eZTemplateFunctions 00034 \brief FOR loop 00035 00036 Syntax: 00037 \code 00038 {for <number> to <number> as $itemVar [sequence <array> as $seqVar]} 00039 [{delimiter}...{/delimiter}] 00040 [{break}] 00041 [{continue}] 00042 [{skip}] 00043 {/for} 00044 \endcode 00045 00046 Examples: 00047 \code 00048 {for 1 to 5 as $i} 00049 i: {$i}<br/> 00050 {/for} 00051 00052 {for 5 to 1 as $i} 00053 i: {$i}<br/> 00054 {/for} 00055 \endcode 00056 */ 00057 00058 class eZTemplateForFunction 00059 { 00060 const FUNCTION_NAME = 'for'; 00061 00062 /*! 00063 * Returns an array of the function names, required for eZTemplate::registerFunctions. 00064 */ 00065 function &functionList() 00066 { 00067 $functionList = array( eZTemplateForFunction::FUNCTION_NAME ); 00068 return $functionList; 00069 } 00070 00071 /*! 00072 * Returns the attribute list. 00073 * key: parameter name 00074 * value: can have children 00075 */ 00076 function attributeList() 00077 { 00078 return array( 'delimiter' => true, 00079 'break' => false, 00080 'continue' => false, 00081 'skip' => false ); 00082 } 00083 00084 00085 /*! 00086 * Returns the array with hits for the template compiler. 00087 */ 00088 function functionTemplateHints() 00089 { 00090 return array( eZTemplateForFunction::FUNCTION_NAME => array( 'parameters' => true, 00091 'static' => false, 00092 'transform-parameters' => true, 00093 'tree-transformation' => true ) ); 00094 } 00095 00096 /*! 00097 * Compiles the function and its children into PHP code. 00098 */ 00099 function templateNodeTransformation( $functionName, &$node, 00100 $tpl, $parameters, $privateData ) 00101 { 00102 // {for <first_val> to <last_val> as $<loop_var> [sequence <sequence_array> as $<sequence_var>]} 00103 00104 $newNodes = array(); 00105 $tpl->ForCounter++; 00106 $nodePlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node ); 00107 $uniqid = md5( $nodePlacement[2] ) . "_" . $tpl->ForCounter; 00108 00109 require_once( 'lib/eztemplate/classes/eztemplatecompiledloop.php' ); 00110 $loop = new eZTemplateCompiledLoop( eZTemplateForFunction::FUNCTION_NAME, 00111 $newNodes, $parameters, $nodePlacement, $uniqid, 00112 $node, $tpl, $privateData ); 00113 00114 $variableStack = "for_variable_stack_$uniqid"; 00115 $namesArray = array( "for_firstval_$uniqid", "for_lastval_$uniqid", "for_i_$uniqid" ); 00116 00117 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// for begins" ); 00118 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( !isset( \$$variableStack ) ) \$$variableStack = array();" ); 00119 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$" . $variableStack ."[] = compact( '" . implode( "', '", $namesArray ) . "' );" ); 00120 00121 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['first_val'], $nodePlacement, array( 'treat-value-as-non-object' => true ), "for_firstval_$uniqid" ); 00122 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['last_val'], $nodePlacement, array( 'treat-value-as-non-object' => true ), "for_lastval_$uniqid" ); 00123 00124 $loop->initVars(); 00125 00126 // loop header 00127 $modifyLoopCounterCode = "\$for_firstval_$uniqid < \$for_lastval_$uniqid ? \$for_i_${uniqid}++ : \$for_i_${uniqid}--"; // . ";\n"; 00128 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "for ( \$for_i_$uniqid = \$for_firstval_$uniqid ; ; $modifyLoopCounterCode )\n{" ); 00129 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode(); 00130 // Check for index 00131 $indexArray = isset( $parameters['loop_var'][0][1] ) ? $parameters['loop_var'][0][1] : array( "", 2, "default_index_$uniqid" ); 00132 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, "for_i_$uniqid", $nodePlacement, 00133 array( 'text-result' => true ), $indexArray, false, true, true ); 00134 00135 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( !( \$for_firstval_$uniqid < \$for_lastval_$uniqid ? " . 00136 "\$for_i_$uniqid <= \$for_lastval_$uniqid : " . 00137 "\$for_i_$uniqid >= \$for_lastval_$uniqid ) )\n" . 00138 " break;\n" ); 00139 00140 $loop->processBody(); 00141 00142 // loop footer 00143 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode(); 00144 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "} // for" ); 00145 00146 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( count( \$$variableStack ) ) extract( array_pop( \$$variableStack ) );\n" ); 00147 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "else\n{\n" ); 00148 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $indexArray ); 00149 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( "for_firstval_$uniqid" ); 00150 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( "for_lastval_$uniqid" ); 00151 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( "for_i_$uniqid" ); 00152 $newNodes[] = eZTemplateNodeTool::createVariableUnsetNode( $variableStack ); 00153 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\n" ); 00154 $loop->cleanup(); 00155 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// for ends\n" ); 00156 00157 return $newNodes; 00158 } 00159 00160 /*! 00161 * Actually executes the function and its children (in processed mode). 00162 */ 00163 function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace ) 00164 { 00165 /* 00166 * Check function parameters 00167 */ 00168 00169 require_once( 'lib/eztemplate/classes/eztemplateloop.php' ); 00170 $loop = new eZTemplateLoop( eZTemplateForFunction::FUNCTION_NAME, 00171 $functionParameters, $functionChildren, $functionPlacement, 00172 $tpl, $textElements, $rootNamespace, $currentNamespace ); 00173 00174 if ( !$loop->initialized() ) 00175 return; 00176 00177 $loop->parseScalarParamValue( 'first_val', $firstVal, $firstValIsProxy ); 00178 $loop->parseScalarParamValue( 'last_val', $lastVal, $lastValIsProxy ); 00179 00180 if ( $firstValIsProxy || $lastValIsProxy ) 00181 { 00182 $tpl->error( eZTemplateForFunction::FUNCTION_NAME, 00183 "Proxy objects ({section} loop iterators) cannot be used to specify the range \n" . 00184 "(this will lead to indefinite loops in compiled mode).\n" . 00185 "Please explicitly dereference the proxy object like this: \$current_node.item." ); 00186 return; 00187 } 00188 00189 $loop->parseParamVarName( 'loop_var' , $loopVarName ); 00190 00191 if ( is_null( $firstVal ) || is_null( $lastVal ) || !$loopVarName ) 00192 { 00193 $tpl->error( eZTemplateForFunction::FUNCTION_NAME, "Wrong arguments passed." ); 00194 return; 00195 } 00196 00197 if ( !is_numeric( $firstVal ) || !is_numeric( $lastVal ) ) 00198 { 00199 $tpl->error( eZTemplateForFunction::FUNCTION_NAME, "Both 'from' and 'to' values can only be numeric." ); 00200 return; 00201 } 00202 00203 $loop->initLoopVariable( $loopVarName ); 00204 00205 /* 00206 * Everything is ok, run the 'for' loop itself 00207 */ 00208 for ( $i = $firstVal; $firstVal < $lastVal ? $i <= $lastVal : $i >= $lastVal; ) 00209 { 00210 // set loop variable 00211 $tpl->setVariable( $loopVarName, $i, $rootNamespace ); 00212 00213 $loop->setSequenceVar(); // set sequence variable (if specified) 00214 $loop->processDelimiter(); 00215 $loop->resetIteration(); 00216 00217 if ( $loop->processChildren() ) 00218 break; 00219 00220 // increment loop variable here for delimiter to be processed correctly 00221 $firstVal < $lastVal ? $i++ : $i--; 00222 00223 $loop->incrementSequence(); 00224 } // for 00225 00226 $loop->cleanup(); 00227 } 00228 00229 /*! 00230 * Returns true, telling the template parser that the function can have children. 00231 */ 00232 function hasChildren() 00233 { 00234 return true; 00235 } 00236 } 00237 00238 ?>