/lib/eztemplate/classes/eztemplateoptimizer.php

https://github.com/itag/ezpublish · PHP · 200 lines · 144 code · 11 blank · 45 comment · 37 complexity · 2083d1f47d6b880e3beca8a65e9acf43 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the eZTemplateOptimizer 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 eZTemplateOptimizer eztemplateoptimizer.php
  12. \brief Analyses a compiled template tree and tries to optimize certain parts of it.
  13. */
  14. class eZTemplateOptimizer
  15. {
  16. /*!
  17. Optimizes a resource acquisition node and the variable data before it
  18. */
  19. static function optimizeResourceAcquisition( $useComments, &$php, $tpl, &$var, &$node, &$resourceData )
  20. {
  21. $data = $var[2];
  22. /* Check if the variable node has the correct format */
  23. if ( ( $var[1] == 'attributeAccess' ) and
  24. ( count( $data ) == 5 ) and
  25. ( $data[0][0] == eZTemplate::TYPE_VARIABLE ) and
  26. ( $data[0][1][2] == 'node' ) and
  27. ( $data[1][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  28. ( $data[1][1][0][1] == 'object' ) and
  29. ( $data[2][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  30. ( $data[2][1][0][1] == 'data_map' ) and
  31. ( $data[3][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  32. ( $data[4][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  33. ( $data[4][1][0][1] == 'view_template' ) and
  34. ( $node[9] == 'attributeAccess' ) and
  35. ( isset( $resourceData['class-info'] ) ) )
  36. {
  37. $attribute = $data[3][1][0][1];
  38. if ( isset( $resourceData['class-info'][$attribute] ) and
  39. isset( $node[2][$resourceData['class-info'][$attribute]] ) )
  40. {
  41. $file = $node[2][$resourceData['class-info'][$attribute]];
  42. $node[0] = eZTemplate::NODE_OPTIMIZED_RESOURCE_ACQUISITION;
  43. $node[10] = $resourceData['class-info'][$attribute];
  44. $node[2] = array( $node[10] => $file );
  45. return true;
  46. }
  47. else /* If we can't find it in the lookup table then it's simply
  48. * not there, so we can just kill the array. */
  49. {
  50. $node[2] = array( 'dummy' => 'foo' );
  51. return false;
  52. }
  53. /* Added as an extra fall back, this point should never be reached,
  54. * but if it does then we make sure not to mess up the original
  55. * array in the calling function. */
  56. return false;
  57. }
  58. else
  59. {
  60. return false;
  61. }
  62. }
  63. /*!
  64. Analyses function nodes and tries to optimize them
  65. */
  66. static function optimizeFunction( $useComments, &$php, $tpl, &$node, &$resourceData )
  67. {
  68. $ret = 0;
  69. /* Just run the optimizer over all parameters */
  70. if ( isset( $node[3] ) and is_array( $node[3] ) )
  71. {
  72. foreach ( $node[3] as $key => $parameter )
  73. {
  74. $ret = eZTemplateOptimizer::optimizeVariable( $useComments, $php, $tpl, $node[3][$key], $resourceData );
  75. }
  76. }
  77. return $ret;
  78. }
  79. /*!
  80. Analyses variables and tries to optimize them
  81. */
  82. static function optimizeVariable( $useComments, &$php, $tpl, &$data, &$resourceData )
  83. {
  84. $ret = 0;
  85. /* node.object.data_map optimization */
  86. if ( ( count( $data ) >= 3 ) and
  87. ( $data[0][0] == eZTemplate::TYPE_VARIABLE ) and
  88. ( $data[0][1][2] == 'node' ) and
  89. ( $data[1][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  90. ( $data[1][1][0][1] == 'object' ) and
  91. ( $data[2][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  92. ( $data[2][1][0][1] == 'data_map' ) )
  93. {
  94. /* Modify the next two nodes in the array too as we know for sure
  95. * what type it is. This fixes the dependency on
  96. * compiledFetchAttribute */
  97. if ( ( count( $data ) >= 5 ) and
  98. ( $data[3][0] == eZTemplate::TYPE_ATTRIBUTE ) and
  99. ( $data[4][0] == eZTemplate::TYPE_ATTRIBUTE ) )
  100. {
  101. $data[3][0] = eZTemplate::TYPE_OPTIMIZED_ARRAY_LOOKUP;
  102. if ( $data[4][1][0][1] == "content")
  103. {
  104. $data[4][0] = eZTemplate::TYPE_OPTIMIZED_CONTENT_CALL;
  105. }
  106. else
  107. {
  108. $data[4][0] = eZTemplate::TYPE_OPTIMIZED_ATTRIBUTE_LOOKUP;
  109. }
  110. }
  111. /* Create a new node representing the optimization */
  112. array_unshift( $data, array( eZTemplate::TYPE_OPTIMIZED_NODE, null, 2 ) );
  113. $ret = 1;
  114. }
  115. /* node.object.data_map optimization through function */
  116. if ( isset( $data[0] ) and
  117. $data[0][0] == eZTemplate::NODE_INTERNAL_CODE_PIECE )
  118. {
  119. $functionRet = eZTemplateOptimizer::optimizeFunction( $useComments, $php, $tpl, $data[0], $resourceData );
  120. // Merge settings
  121. $ret = $ret | $functionRet;
  122. }
  123. return $ret;
  124. }
  125. /*!
  126. Runs the optimizer
  127. */
  128. static function optimize( $useComments, &$php, $tpl, &$tree, &$resourceData )
  129. {
  130. /* If for some reason we don't have elements, simply return */
  131. if (! is_array( $tree[1] ) )
  132. return;
  133. $addNodeInit = false;
  134. /* Loop through the children of the root */
  135. foreach ( $tree[1] as $key => $kiddie )
  136. {
  137. /* Analyse per node type */
  138. switch ( $kiddie[0] )
  139. {
  140. case eZTemplate::NODE_INTERNAL_OUTPUT_SPACING_INCREASE:
  141. case eZTemplate::NODE_INTERNAL_SPACING_DECREASE:
  142. /* Removing unnecessary whitespace changes */
  143. unset( $tree[1][$key] );
  144. break;
  145. case 3: /* Variable */
  146. if ( isset( $tree[1][$key + 1] ) and
  147. ( $tree[1][$key + 1][0] == eZTemplate::NODE_INTERNAL_RESOURCE_ACQUISITION ) and
  148. isset( $resourceData['class-info'] ) )
  149. {
  150. $ret = eZTemplateOptimizer::optimizeResourceAcquisition(
  151. $useComments, $php, $tpl,
  152. $tree[1][$key], $tree[1][$key + 1], $resourceData );
  153. /* We only unset the tree node when the optimization
  154. * function returns false, as that means that the
  155. * optimization could not be made. */
  156. if ($ret)
  157. {
  158. unset( $tree[1][$key] );
  159. }
  160. }
  161. else
  162. {
  163. $ret = eZTemplateOptimizer::optimizeVariable( $useComments, $php, $tpl, $tree[1][$key][2], $resourceData );
  164. if ( $ret & 1 )
  165. $addNodeInit = true;
  166. }
  167. break;
  168. }
  169. }
  170. if ( $addNodeInit )
  171. {
  172. $initializer = array( eZTemplate::NODE_OPTIMIZED_INIT, null, false );
  173. array_unshift( $tree[1], $initializer );
  174. }
  175. }
  176. static function fetchClassDeclaration( $classID )
  177. {
  178. $contentClass = eZContentClass::fetch( $classID );
  179. $attributeArray = array();
  180. $attributes = is_object( $contentClass ) ? $contentClass->fetchAttributes() : array();
  181. foreach ( $attributes as $attribute )
  182. {
  183. $attributeArray[ $attribute->Identifier ] = $attribute->DataTypeString;
  184. }
  185. return $attributeArray;
  186. }
  187. }
  188. ?>