/lib/eztemplate/classes/eztemplatesetfunction.php

https://github.com/GunioRobot/ezpublish · PHP · 378 lines · 306 code · 31 blank · 41 comment · 74 complexity · a11a85714338d9c58f0516f6d07013be MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the eZTemplateSetFunction class.
  4. *
  5. * @copyright Copyright (C) 1999-2011 eZ Systems AS. All rights reserved.
  6. * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
  7. * @version //autogentag//
  8. * @package lib
  9. */
  10. /*!
  11. \class eZTemplateSetFunction eztemplatesetfunction.php
  12. \ingroup eZTemplateFunctions
  13. \brief Sets template variables code using function 'set'
  14. Allows for setting template variables from templates using
  15. a template function. This is mainly used for optimizations.
  16. The let function will define new variables and initialize them with
  17. a value while set only sets values to existing variables.
  18. The let function is also scoped with children which means that the
  19. variables are unset when the children are processed.
  20. \code
  21. // Example template code
  22. {let object=$item1 some_text='abc' integer=1}
  23. {set object=$item2 some_text='def'}
  24. {/let}
  25. {set name=NewNamespace place='/etc/test.tpl'}
  26. \endcode
  27. */
  28. class eZTemplateSetFunction
  29. {
  30. const SCOPE_RELATIVE = 1;
  31. const SCOPE_ROOT = 2;
  32. const SCOPE_GLOBAL = 3;
  33. /*!
  34. Initializes the function with the function names $setName and $letName.
  35. */
  36. function eZTemplateSetFunction( $setName = 'set', $letName = 'let', $defaultName = 'default' )
  37. {
  38. $this->SetName = $setName;
  39. $this->LetName = $letName;
  40. $this->DefaultName = $defaultName;
  41. }
  42. /*!
  43. Returns an array of the function names, required for eZTemplate::registerFunctions.
  44. */
  45. function functionList()
  46. {
  47. return array( $this->SetName, $this->LetName, $this->DefaultName );
  48. }
  49. function functionTemplateHints()
  50. {
  51. return array( $this->LetName => array( 'parameters' => true,
  52. 'static' => false,
  53. 'tree-transformation' => true,
  54. 'transform-children' => true,
  55. 'transform-parameters' => true ),
  56. $this->SetName => array( 'parameters' => true,
  57. 'static' => false,
  58. 'tree-transformation' => true,
  59. 'transform-children' => true,
  60. 'transform-parameters' => true ),
  61. $this->DefaultName => array( 'parameters' => true,
  62. 'static' => false,
  63. 'tree-transformation' => true,
  64. 'transform-children' => true,
  65. 'transform-parameters' => true ) );
  66. }
  67. function templateNodeTransformation( $functionName, &$node,
  68. $tpl, $parameters, $privateData )
  69. {
  70. switch( $functionName )
  71. {
  72. case $this->SetName:
  73. case $this->DefaultName:
  74. case $this->LetName:
  75. {
  76. $scope = eZTemplate::NAMESPACE_SCOPE_RELATIVE;
  77. if ( isset( $parameters['-scope'] ) )
  78. {
  79. if ( !eZTemplateNodeTool::isConstantElement( $parameters['-scope'] ) )
  80. return false;
  81. $scopeText = eZTemplateNodeTool::elementConstantValue( $parameters['-scope'] );
  82. if ( $scopeText == 'relative' )
  83. $scope = eZTemplate::NAMESPACE_SCOPE_RELATIVE;
  84. else if ( $scopeText == 'root' )
  85. $scope = eZTemplate::NAMESPACE_SCOPE_LOCAL;
  86. else if ( $scopeText == 'global' )
  87. $scope = eZTemplate::NAMESPACE_SCOPE_GLOBAL;
  88. }
  89. $parameters = eZTemplateNodeTool::extractFunctionNodeParameters( $node );
  90. $namespaceValue = false;
  91. if ( isset( $parameters['-name'] ) )
  92. {
  93. if ( !eZTemplateNodeTool::isConstantElement( $parameters['-name'] ) )
  94. {
  95. return false;
  96. }
  97. $namespaceValue = eZTemplateNodeTool::elementConstantValue( $parameters['-name'] );
  98. }
  99. $variableList = array();
  100. $setVarNodes = array();
  101. foreach ( array_keys( $parameters ) as $parameterName )
  102. {
  103. if ( $parameterName == '-name' or $parameterName == '-scope' )
  104. {
  105. continue;
  106. }
  107. $parameterData =& $parameters[$parameterName];
  108. $setVarNodes[] = eZTemplateNodeTool::createVariableNode(
  109. false, $parameterData, eZTemplateNodeTool::extractFunctionNodePlacement( $node ),
  110. array(), array( $namespaceValue, $scope, $parameterName ),
  111. ( $functionName == $this->SetName ), ( $functionName != $this->DefaultName ),
  112. false, ( $functionName == $this->DefaultName ) );
  113. if ( $functionName == $this->LetName or $functionName == $this->DefaultName )
  114. {
  115. $variableList[] = $parameterName;
  116. }
  117. }
  118. if ( ( $functionName == $this->LetName or $functionName == $this->DefaultName ) and
  119. $namespaceValue )
  120. {
  121. $setVarNodes[] = eZTemplateNodeTool::createNamespaceChangeNode( $namespaceValue );
  122. }
  123. if ( $functionName == $this->LetName or $functionName == $this->DefaultName )
  124. {
  125. $childNodes = eZTemplateNodeTool::extractFunctionNodeChildren( $node );
  126. if ( !is_array( $childNodes ) )
  127. {
  128. $childNodes = array();
  129. }
  130. }
  131. else
  132. {
  133. $childNodes = array();
  134. }
  135. $unsetVarNodes = array();
  136. if ( ( $functionName == $this->LetName or $functionName == $this->DefaultName ) and
  137. $namespaceValue )
  138. {
  139. $unsetVarNodes[] = eZTemplateNodeTool::createNamespaceRestoreNode();
  140. }
  141. if ( $functionName == $this->LetName or $functionName == $this->DefaultName )
  142. {
  143. foreach( $variableList as $parameterName )
  144. {
  145. $unsetVarNodes[] = eZTemplateNodeTool::createVariableUnsetNode( array( $namespaceValue,
  146. eZTemplate::NAMESPACE_SCOPE_RELATIVE,
  147. $parameterName ),
  148. array( 'remember_set' => $functionName == $this->DefaultName ) );
  149. }
  150. }
  151. return array_merge( $setVarNodes, $childNodes, $unsetVarNodes );
  152. } break;
  153. }
  154. }
  155. function templateHookProcess( $functionName, $functionHookName, $functionHook,
  156. $tpl, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
  157. {
  158. }
  159. function defineVariables( $tpl, $functionParameters, $functionPlacement, $name, $rootNamespace, &$currentNamespace )
  160. {
  161. $oldCurrentNamespace = $currentNamespace;
  162. $definedVariables = array();
  163. foreach ( array_keys( $functionParameters ) as $key )
  164. {
  165. $item =& $functionParameters[$key];
  166. switch ( $key )
  167. {
  168. case '-name':
  169. break;
  170. default:
  171. {
  172. if ( !$tpl->hasVariable( $key, $name ) )
  173. {
  174. $itemValue = $tpl->elementValue( $item, $rootNamespace, $currentNamespace, $functionPlacement );
  175. $tpl->setVariable( $key, $itemValue, $name );
  176. $definedVariables[] = $key;
  177. }
  178. else
  179. {
  180. $varname = $key;
  181. if ( $name != '' )
  182. $varname = "$name:$varname";
  183. $tpl->warning( $this->SetName, "Variable '$varname' already exists, cannot define" );
  184. }
  185. } break;
  186. }
  187. }
  188. $currentNamespace = $name;
  189. return array( $definedVariables,
  190. $oldCurrentNamespace );
  191. }
  192. function createDefaultVariables( $tpl, $functionParameters, $functionPlacement, $name, $rootNamespace, &$currentNamespace )
  193. {
  194. $oldCurrentNamespace = $currentNamespace;
  195. $definedVariables = array();
  196. foreach ( array_keys( $functionParameters ) as $key )
  197. {
  198. $item =& $functionParameters[$key];
  199. switch ( $key )
  200. {
  201. case '-name':
  202. break;
  203. default:
  204. {
  205. if ( !$tpl->hasVariable( $key, $name ) )
  206. {
  207. $itemValue = $tpl->elementValue( $item, $rootNamespace, $currentNamespace, $functionPlacement );
  208. $tpl->setVariable( $key, $itemValue, $name );
  209. $definedVariables[] = $key;
  210. }
  211. } break;
  212. }
  213. }
  214. $currentNamespace = $name;
  215. return array( $definedVariables,
  216. $oldCurrentNamespace );
  217. }
  218. function cleanupVariables( $tpl, $rootNamespace, &$currentNamespace, $setData )
  219. {
  220. $definedVariables = $setData[0];
  221. foreach ( $definedVariables as $variable )
  222. {
  223. $tpl->unsetVariable( $variable, $currentNamespace );
  224. }
  225. $currentNamespace = $setData[1];
  226. }
  227. /*!
  228. Loads the file specified in the parameter 'uri' with namespace 'name'.
  229. */
  230. function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace )
  231. {
  232. if ( $functionName != $this->SetName and
  233. $functionName != $this->LetName and
  234. $functionName != $this->DefaultName )
  235. return null;
  236. $children = $functionChildren;
  237. $parameters = $functionParameters;
  238. $scope = eZTemplateSetFunction::SCOPE_RELATIVE;
  239. if ( isset( $parameters['-scope'] ) )
  240. {
  241. $scopeText = $tpl->elementValue( $parameters['-scope'], $rootNamespace, $currentNamespace, $functionPlacement );
  242. if ( $scopeText == 'relative' )
  243. $scope = eZTemplateSetFunction::SCOPE_RELATIVE;
  244. else if ( $scopeText == 'root' )
  245. $scope = eZTemplateSetFunction::SCOPE_ROOT;
  246. else if ( $scopeText == 'global' )
  247. $scope = eZTemplateSetFunction::SCOPE_GLOBAL;
  248. else
  249. $tpl->warning( $functionName, "Scope value '$scopeText' is not valid, use either 'relative', 'root' or 'global'" );
  250. }
  251. $name = null;
  252. if ( isset( $parameters['-name'] ) )
  253. $name = $tpl->elementValue( $parameters['-name'], $rootNamespace, $currentNamespace, $functionPlacement );
  254. if ( $name === null )
  255. {
  256. if ( $scope == eZTemplateSetFunction::SCOPE_RELATIVE )
  257. $name = $currentNamespace;
  258. else if ( $scope == eZTemplateSetFunction::SCOPE_ROOT )
  259. $name = $rootNamespace;
  260. else
  261. $name = '';
  262. }
  263. else
  264. {
  265. if ( $scope == eZTemplateSetFunction::SCOPE_RELATIVE and
  266. $currentNamespace != '' )
  267. $name = "$currentNamespace:$name";
  268. else if ( $scope == eZTemplateSetFunction::SCOPE_ROOT and
  269. $rootNamespace != '' )
  270. $name = "$rootNamespace:$name";
  271. }
  272. $definedVariables = array();
  273. if ( $functionName == $this->SetName )
  274. {
  275. foreach ( array_keys( $functionParameters ) as $key )
  276. {
  277. $item =& $functionParameters[$key];
  278. switch ( $key )
  279. {
  280. case '-name':
  281. case '-scope':
  282. break;
  283. default:
  284. {
  285. if ( $tpl->hasVariable( $key, $name ) )
  286. {
  287. unset( $itemValue );
  288. $itemValue = $tpl->elementValue( $item, $rootNamespace, $currentNamespace, $functionPlacement );
  289. $tpl->setVariable( $key, $itemValue, $name );
  290. }
  291. else
  292. {
  293. $varname = $key;
  294. if ( $name != '' )
  295. $varname = "$name:$varname";
  296. $tpl->warning( $functionName, "Variable '$varname' doesn't exist, cannot set" );
  297. }
  298. } break;
  299. }
  300. }
  301. }
  302. else if ( $functionName == $this->DefaultName )
  303. {
  304. $definedVariables = eZTemplateSetFunction::createDefaultVariables( $tpl, $functionParameters, $functionPlacement, $name, $rootNamespace, $currentNamespace );
  305. }
  306. else
  307. {
  308. $definedVariables = eZTemplateSetFunction::defineVariables( $tpl, $functionParameters, $functionPlacement, $name, $rootNamespace, $currentNamespace );
  309. }
  310. if ( $functionName == $this->LetName or
  311. $functionName == $this->DefaultName )
  312. {
  313. if ( is_array( $functionChildren ) )
  314. {
  315. foreach ( array_keys( $functionChildren ) as $childKey )
  316. {
  317. $child =& $functionChildren[$childKey];
  318. $tpl->processNode( $child, $textElements, $rootNamespace, $name );
  319. }
  320. }
  321. eZTemplateSetFunction::cleanupVariables( $tpl, $rootNamespace, $currentNamespace, $definedVariables );
  322. }
  323. }
  324. /*!
  325. Returns false, telling the template parser that this is a single tag.
  326. */
  327. function hasChildren()
  328. {
  329. return array( $this->SetName => false,
  330. $this->LetName => true,
  331. $this->DefaultName => true );
  332. }
  333. /// The name of the set function
  334. public $SetName;
  335. public $LetName;
  336. public $DefaultName;
  337. }
  338. ?>