PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/eztemplate/classes/eztemplateiffunction.php

http://github.com/ezsystems/ezpublish
PHP | 260 lines | 173 code | 29 blank | 58 comment | 34 complexity | d1d6874b540867f57d37c4ace600b850 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * File containing the eZTemplateIfFunction class.
  4. *
  5. * @copyright Copyright (C) eZ Systems AS. All rights reserved.
  6. * @license For full copyright and license information view LICENSE file distributed with this source code.
  7. * @version //autogentag//
  8. * @package lib
  9. */
  10. /*!
  11. \class eZTemplateIfFunction eztemplateiffunction.php
  12. \ingroup eZTemplateFunctions
  13. \brief Conditional execution in templates
  14. This class allows to execute on of two or more code pieces depending
  15. on a condition.
  16. Syntax:
  17. \code
  18. {if <condition>}
  19. [{elseif <condition>}]
  20. [{else}]
  21. {/if}
  22. \endcode
  23. Example:
  24. \code
  25. {if eq( $var, true() )}
  26. Hello world
  27. {else}
  28. No world here, move along.
  29. {/if}
  30. \endcode
  31. */
  32. class eZTemplateIfFunction
  33. {
  34. const FUNCTION_NAME = 'if';
  35. /*!
  36. * Returns an array of the function names, required for eZTemplate::registerFunctions.
  37. */
  38. function functionList()
  39. {
  40. //eZDebug::writeDebug( "if::functionList()" );
  41. $functionList = array( eZTemplateIfFunction::FUNCTION_NAME );
  42. return $functionList;
  43. }
  44. /*!
  45. * Returns the attribute list which is 'delimiter', 'elseif' and 'else'.
  46. * key: parameter name
  47. * value: can have children
  48. */
  49. function attributeList()
  50. {
  51. return array( 'elseif' => false,
  52. 'else' => false );
  53. }
  54. /*!
  55. * Returns the array with hits for the template compiler.
  56. */
  57. function functionTemplateHints()
  58. {
  59. return array( eZTemplateIfFunction::FUNCTION_NAME => array( 'parameters' => true,
  60. 'static' => false,
  61. 'transform-parameters' => true,
  62. 'tree-transformation' => true ) );
  63. }
  64. /*!
  65. * Compiles the function and its children into PHP code.
  66. */
  67. function templateNodeTransformation( $functionName, &$node,
  68. $tpl, $parameters, $privateData )
  69. {
  70. $tpl->ElseifCounter++;
  71. $newNodes = array();
  72. $nodesToPrepend = array();
  73. $nodesToAppend = array();
  74. $nodePlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node );
  75. $uniqid = md5( $nodePlacement[2] ) . "_" . $tpl->ElseifCounter;
  76. $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node );
  77. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// if begins" );
  78. $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['condition'], $nodePlacement, array( 'treat-value-as-non-object' => true ), 'if_cond' );
  79. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "if ( \$if_cond )\n{" );
  80. $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode();
  81. if ( is_array( $children ) )
  82. {
  83. foreach ( array_keys( $children ) as $childKey )
  84. {
  85. $child =& $children[$childKey];
  86. if ( $child[0] == eZTemplate::NODE_FUNCTION )
  87. {
  88. $childFunctionName =& $child[2];
  89. $childChildren = eZTemplateNodeTool::extractFunctionNodeChildren( $child );
  90. $childFunctionArgs =& $child[3];
  91. if ( $childFunctionName == 'elseif' )
  92. {
  93. $compiledElseifCondition = eZTemplateCompiler::processElementTransformationList( $tpl, $child, $childFunctionArgs['condition'], $privateData );
  94. $nodesToPrepend[] = eZTemplateNodeTool::createVariableNode( false, $compiledElseifCondition,
  95. $nodePlacement,
  96. array( 'text-result' => true ),
  97. "elseif_cond_$uniqid" );
  98. $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode();
  99. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\nelseif ( \$elseif_cond_$uniqid )\n{" );
  100. $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode();
  101. $nodesToAppend[] = eZTemplateNodeTool::createVariableUnsetNode( "elseif_cond_$uniqid" );
  102. // increment unique elseif counter
  103. $uniqid = md5( $nodePlacement[2] ) . "_" . ++$tpl->ElseifCounter;
  104. }
  105. elseif ( $childFunctionName == 'else' )
  106. {
  107. $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode();
  108. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}\nelse\n{" );
  109. $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode();
  110. }
  111. elseif ( $childFunctionName == 'break' )
  112. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "break;\n" );
  113. elseif ( $childFunctionName == 'continue' )
  114. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "continue;\n" );
  115. elseif ( $childFunctionName == 'skip' )
  116. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "\$skipDelimiter = true;\ncontinue;\n" );
  117. // let other functions (ones not listed in the conditions above) be transformed
  118. if ( in_array( $childFunctionName, array( 'elseif', 'else', 'break', 'continue', 'skip' ) ) )
  119. continue;
  120. }
  121. $newNodes[] = $child;
  122. }
  123. }
  124. $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode();
  125. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "}" );
  126. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "unset( \$if_cond );" );
  127. $newNodes[] = eZTemplateNodeTool::createCodePieceNode( "// if ends\n" );
  128. $newNodes = array_merge( $nodesToPrepend, $newNodes, $nodesToAppend );
  129. return $newNodes;
  130. }
  131. /*!
  132. * Actually executes the function and its children (in processed mode).
  133. */
  134. function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
  135. {
  136. if ( count( $functionParameters ) == 0 || !count( $functionParameters['condition'] ) )
  137. {
  138. eZDebug::writeError( "Not enough arguments passed to 'if' function." );
  139. return;
  140. }
  141. $ifValue = $tpl->elementValue( $functionParameters['condition'], $rootNamespace, $currentNamespace, $functionPlacement );
  142. $show = $ifValue; // whether to show the child being currently processing
  143. $showWasTrue = $show; // true if $show has been assigned 'true' value at least once in the current {if}...{/if} block.
  144. $foundElse = false; // true if 'else' has been met once in the current {if}...{/if} block.
  145. if ( !is_array( $functionChildren ) )
  146. {
  147. return;
  148. }
  149. foreach ( $functionChildren as $key => $child )
  150. {
  151. $childType = $child[0];
  152. // parse 'elseif', 'else' functions
  153. if ( $childType == eZTemplate::NODE_FUNCTION )
  154. {
  155. $childFunctionName =& $child[2];
  156. $childFunctionArgs =& $child[3];
  157. $childFunctionPlacement =& $child[4];
  158. if ( $childFunctionName == 'else' )
  159. {
  160. if ( $foundElse )
  161. {
  162. eZDebug::writeError( "Duplicated 'else'" );
  163. $show = false;
  164. continue;
  165. }
  166. $show = !$showWasTrue;
  167. $foundElse = true;
  168. continue;
  169. }
  170. elseif ( $childFunctionName == 'elseif' )
  171. {
  172. if ( $foundElse )
  173. {
  174. eZDebug::writeError( "There should be no more 'elseif' after 'else'" );
  175. $show = false;
  176. continue;
  177. }
  178. if ( !isset( $childFunctionArgs['condition'] ) || !count( $childFunctionArgs['condition'] ) ) // no arguments passes to 'elseif' (should not happen)
  179. $elseifValue = false;
  180. else
  181. $elseifValue = $tpl->elementValue( $childFunctionArgs['condition'], $rootNamespace, $currentNamespace, $functionPlacement );
  182. if ( !$showWasTrue && $elseifValue )
  183. $show = $showWasTrue = true;
  184. else
  185. $show = false;
  186. continue;
  187. }
  188. elseif ( $childFunctionName == 'break' )
  189. {
  190. if ( !$show )
  191. continue;
  192. return array( 'breakFunctionFound' => 1 );
  193. }
  194. elseif ( $childFunctionName == 'continue' )
  195. {
  196. if ( !$show )
  197. continue;
  198. return array( 'continueFunctionFound' => 1 );
  199. }
  200. elseif ( $childFunctionName == 'skip' )
  201. {
  202. if ( !$show )
  203. continue;
  204. return array( 'skipFunctionFound' => 1 );
  205. }
  206. }
  207. if ( $show )
  208. {
  209. $rslt = $tpl->processNode( $child, $textElements, $rootNamespace, $currentNamespace );
  210. // handle 'break', 'continue' and 'skip'
  211. if ( is_array( $rslt ) && ( array_key_exists( 'breakFunctionFound', $rslt ) ||
  212. array_key_exists( 'continueFunctionFound', $rslt ) ||
  213. array_key_exists( 'skipFunctionFound', $rslt ) ) )
  214. {
  215. return $rslt;
  216. }
  217. }
  218. }
  219. }
  220. /*!
  221. * Returns true, telling the template parser that the function can have children.
  222. */
  223. function hasChildren()
  224. {
  225. return true;
  226. }
  227. }
  228. ?>