|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZTemplateIfFunction class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package lib 00009 */ 00010 00011 /*! 00012 \class eZTemplateIfFunction eztemplateiffunction.php 00013 \ingroup eZTemplateFunctions 00014 \brief Conditional execution in templates 00015 00016 This class allows to execute on of two or more code pieces depending 00017 on a condition. 00018 00019 Syntax: 00020 \code 00021 {if <condition>} 00022 [{elseif <condition>}] 00023 [{else}] 00024 {/if} 00025 \endcode 00026 00027 Example: 00028 \code 00029 {if eq( $var, true() )} 00030 Hello world 00031 {else} 00032 No world here, move along. 00033 {/if} 00034 \endcode 00035 */ 00036 00037 class eZTemplateIfFunction 00038 { 00039 const FUNCTION_NAME = 'if'; 00040 00041 /*! 00042 * Returns an array of the function names, required for eZTemplate::registerFunctions. 00043 */ 00044 function functionList() 00045 { 00046 //eZDebug::writeDebug( "if::functionList()" ); 00047 $functionList = array( eZTemplateIfFunction::FUNCTION_NAME ); 00048 return $functionList; 00049 } 00050 00051 /*! 00052 * Returns the attribute list which is 'delimiter', 'elseif' and 'else'. 00053 * key: parameter name 00054 * value: can have children 00055 */ 00056 function attributeList() 00057 { 00058 return array( 'elseif' => false, 00059 'else' => false ); 00060 } 00061 00062 00063 /*! 00064 * Returns the array with hits for the template compiler. 00065 */ 00066 function functionTemplateHints() 00067 { 00068 return array( eZTemplateIfFunction::FUNCTION_NAME => array( 'parameters' => true, 00069 'static' => false, 00070 'transform-parameters' => true, 00071 'tree-transformation' => true ) ); 00072 } 00073 00074 /*! 00075 * Compiles the function and its children into PHP code. 00076 */ 00077 function templateNodeTransformation( $functionName, &$node, 00078 $tpl, $parameters, $privateData ) 00079 { 00080 $tpl->ElseifCounter++; 00081 $newNodes = array(); 00082 $nodesToPrepend = array(); 00083 $nodesToAppend = array(); 00084 $nodePlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node ); 00085 $uniqid = md5( $nodePlacement[2] ) . "_" . $tpl->ElseifCounter; 00086 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node ); 00087 00088 00089 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// if begins" ); 00090 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['condition'], $nodePlacement, array( 'treat-value-as-non-object' => true ), 'if_cond' ); 00091 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$if_cond )\n{" ); 00092 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode(); 00093 00094 if ( is_array( $children ) ) 00095 { 00096 foreach ( array_keys( $children ) as $childKey ) 00097 { 00098 $child =& $children[$childKey]; 00099 00100 if ( $child[0] == eZTemplate::NODE_FUNCTION ) 00101 { 00102 $childFunctionName =& $child[2]; 00103 $childChildren = eZTemplateNodeTool::extractFunctionNodeChildren( $child ); 00104 $childFunctionArgs =& $child[3]; 00105 00106 if ( $childFunctionName == 'elseif' ) 00107 { 00108 $compiledElseifCondition = eZTemplateCompiler::processElementTransformationList( $tpl, $child, $childFunctionArgs['condition'], $privateData ); 00109 $nodesToPrepend[] = eZTemplateNodeTool::createVariableNode( false, $compiledElseifCondition, 00110 $nodePlacement, 00111 array( 'text-result' => true ), 00112 "elseif_cond_$uniqid" ); 00113 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode(); 00114 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\nelseif ( \$elseif_cond_$uniqid )\n{" ); 00115 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode(); 00116 $nodesToAppend[] = eZTemplateNodeTool::createVariableUnsetNode( "elseif_cond_$uniqid" ); 00117 // increment unique elseif counter 00118 $uniqid = md5( $nodePlacement[2] ) . "_" . ++$tpl->ElseifCounter; 00119 } 00120 elseif ( $childFunctionName == 'else' ) 00121 { 00122 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode(); 00123 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\nelse\n{" ); 00124 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode(); 00125 } 00126 elseif ( $childFunctionName == 'break' ) 00127 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "break;\n" ); 00128 elseif ( $childFunctionName == 'continue' ) 00129 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "continue;\n" ); 00130 elseif ( $childFunctionName == 'skip' ) 00131 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = true;\ncontinue;\n" ); 00132 00133 // let other functions (ones not listed in the conditions above) be transformed 00134 if ( in_array( $childFunctionName, array( 'elseif', 'else', 'break', 'continue', 'skip' ) ) ) 00135 continue; 00136 } 00137 $newNodes[] = $child; 00138 } 00139 } 00140 00141 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode(); 00142 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}" ); 00143 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "unset( \$if_cond );" ); 00144 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// if ends\n" ); 00145 00146 $newNodes = array_merge( $nodesToPrepend, $newNodes, $nodesToAppend ); 00147 00148 return $newNodes; 00149 } 00150 00151 /*! 00152 * Actually executes the function and its children (in processed mode). 00153 */ 00154 function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace ) 00155 { 00156 if ( count( $functionParameters ) == 0 || !count( $functionParameters['condition'] ) ) 00157 { 00158 eZDebug::writeError( "Not enough arguments passed to 'if' function." ); 00159 return; 00160 } 00161 00162 $ifValue = $tpl->elementValue( $functionParameters['condition'], $rootNamespace, $currentNamespace, $functionPlacement ); 00163 00164 $show = $ifValue; // whether to show the child being currently processing 00165 $showWasTrue = $show; // true if $show has been assigned 'true' value at least once in the current {if}...{/if} block. 00166 $foundElse = false; // true if 'else' has been met once in the current {if}...{/if} block. 00167 00168 if ( !is_array( $functionChildren ) ) 00169 { 00170 return; 00171 } 00172 foreach ( $functionChildren as $key => $child ) 00173 { 00174 $childType = $child[0]; 00175 00176 // parse 'elseif', 'else' functions 00177 if ( $childType == eZTemplate::NODE_FUNCTION ) 00178 { 00179 $childFunctionName =& $child[2]; 00180 $childFunctionArgs =& $child[3]; 00181 $childFunctionPlacement =& $child[4]; 00182 00183 if ( $childFunctionName == 'else' ) 00184 { 00185 if ( $foundElse ) 00186 { 00187 eZDebug::writeError( "Duplicated 'else'" ); 00188 $show = false; 00189 continue; 00190 } 00191 00192 $show = !$showWasTrue; 00193 $foundElse = true; 00194 continue; 00195 } 00196 elseif ( $childFunctionName == 'elseif' ) 00197 { 00198 if ( $foundElse ) 00199 { 00200 eZDebug::writeError( "There should be no more 'elseif' after 'else'" ); 00201 $show = false; 00202 continue; 00203 } 00204 00205 if ( !isset( $childFunctionArgs['condition'] ) || !count( $childFunctionArgs['condition'] ) ) // no arguments passes to 'elseif' (should not happen) 00206 $elseifValue = false; 00207 else 00208 $elseifValue = $tpl->elementValue( $childFunctionArgs['condition'], $rootNamespace, $currentNamespace, $functionPlacement ); 00209 00210 if ( !$showWasTrue && $elseifValue ) 00211 $show = $showWasTrue = true; 00212 else 00213 $show = false; 00214 continue; 00215 } 00216 elseif ( $childFunctionName == 'break' ) 00217 { 00218 if ( !$show ) 00219 continue; 00220 return array( 'breakFunctionFound' => 1 ); 00221 } 00222 elseif ( $childFunctionName == 'continue' ) 00223 { 00224 if ( !$show ) 00225 continue; 00226 return array( 'continueFunctionFound' => 1 ); 00227 } 00228 elseif ( $childFunctionName == 'skip' ) 00229 { 00230 if ( !$show ) 00231 continue; 00232 return array( 'skipFunctionFound' => 1 ); 00233 } 00234 } 00235 00236 if ( $show ) 00237 { 00238 $rslt = $tpl->processNode( $child, $textElements, $rootNamespace, $currentNamespace ); 00239 00240 // handle 'break', 'continue' and 'skip' 00241 if ( is_array( $rslt ) && ( array_key_exists( 'breakFunctionFound', $rslt ) || 00242 array_key_exists( 'continueFunctionFound', $rslt ) || 00243 array_key_exists( 'skipFunctionFound', $rslt ) ) ) 00244 { 00245 return $rslt; 00246 } 00247 } 00248 } 00249 } 00250 00251 /*! 00252 * Returns true, telling the template parser that the function can have children. 00253 */ 00254 function hasChildren() 00255 { 00256 return true; 00257 } 00258 } 00259 00260 ?>