eZ Publish  [4.0]
eztemplateoptimizer.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZTemplateOptimizer class
00004 //
00005 // Created on: <16-Aug-2004 15:02:51 dr>
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 /*! \file eztemplateoptimizer.php
00032 */
00033 
00034 /*!
00035   \class eZTemplateOptimizer eztemplateoptimizer.php
00036   \brief Analyses a compiled template tree and tries to optimize certain parts of it.
00037 
00038 */
00039 
00040 require_once( 'lib/ezutils/classes/ezdebug.php' );
00041 //include_once( 'lib/eztemplate/classes/eztemplate.php' );
00042 
00043 class eZTemplateOptimizer
00044 {
00045     /*!
00046      Optimizes a resource acquisition node and the variable data before it
00047     */
00048     static function optimizeResourceAcquisition( $useComments, &$php, $tpl, &$var, &$node, &$resourceData )
00049     {
00050         $data = $var[2];
00051         /* Check if the variable node has the correct format */
00052         if ( ( $var[1] == 'attributeAccess' ) and
00053              ( count( $data ) == 5 ) and
00054              ( $data[0][0] == eZTemplate::TYPE_VARIABLE ) and
00055              ( $data[0][1][2] == 'node' ) and
00056              ( $data[1][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00057              ( $data[1][1][0][1] == 'object' ) and
00058              ( $data[2][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00059              ( $data[2][1][0][1] == 'data_map' ) and
00060              ( $data[3][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00061              ( $data[4][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00062              ( $data[4][1][0][1] == 'view_template' ) and
00063              ( $node[9] == 'attributeAccess' ) and
00064              ( isset( $resourceData['class-info'] ) ) )
00065         {
00066             $attribute = $data[3][1][0][1];
00067             if ( isset( $resourceData['class-info'][$attribute] ) and
00068                  isset( $node[2][$resourceData['class-info'][$attribute]] ) )
00069             {
00070                 $file = $node[2][$resourceData['class-info'][$attribute]];
00071                 $node[0] = eZTemplate::NODE_OPTIMIZED_RESOURCE_ACQUISITION;
00072                 $node[10] = $resourceData['class-info'][$attribute];
00073                 $node[2] = array( $node[10] => $file );
00074 
00075                 return true;
00076             }
00077             else /* If we can't find it in the lookup table then it's simply
00078                   * not there, so we can just kill the array. */
00079             {
00080                 $node[2] = array( 'dummy' => 'foo' );
00081                 return false;
00082             }
00083             /* Added as an extra fall back, this point should never be reached,
00084              * but if it does then we make sure not to mess up the original
00085              * array in the calling function. */
00086             return false;
00087         }
00088         else
00089         {
00090             return false;
00091         }
00092     }
00093 
00094     /*!
00095      Analyses function nodes and tries to optimize them
00096     */
00097     static function optimizeFunction( $useComments, &$php, $tpl, &$node, &$resourceData )
00098     {
00099         $ret = 0;
00100         /* Just run the optimizer over all parameters */
00101         if ( isset( $node[3] ) and is_array( $node[3] ) )
00102         {
00103             foreach ( $node[3] as $key => $parameter )
00104             {
00105                 $ret = eZTemplateOptimizer::optimizeVariable( $useComments, $php, $tpl, $node[3][$key], $resourceData );
00106             }
00107         }
00108         return $ret;
00109     }
00110 
00111     /*!
00112      Analyses variables and tries to optimize them
00113     */
00114     static function optimizeVariable( $useComments, &$php, $tpl, &$data, &$resourceData )
00115     {
00116         $ret = 0;
00117         /* node.object.data_map optimization */
00118         if ( ( count( $data ) >= 3 ) and
00119              ( $data[0][0] == eZTemplate::TYPE_VARIABLE ) and
00120              ( $data[0][1][2] == 'node' ) and
00121              ( $data[1][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00122              ( $data[1][1][0][1] == 'object' ) and
00123              ( $data[2][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00124              ( $data[2][1][0][1] == 'data_map' ) )
00125         {
00126             /* Modify the next two nodes in the array too as we know for sure
00127              * what type it is. This fixes the dependency on
00128              * compiledFetchAttribute */
00129             if ( ( count( $data ) >= 5 ) and
00130                  ( $data[3][0] == eZTemplate::TYPE_ATTRIBUTE ) and
00131                  ( $data[4][0] == eZTemplate::TYPE_ATTRIBUTE ) )
00132             {
00133                 $data[3][0] = eZTemplate::TYPE_OPTIMIZED_ARRAY_LOOKUP;
00134                 if ( $data[4][1][0][1] == "content")
00135                 {
00136                     $data[4][0] = eZTemplate::TYPE_OPTIMIZED_CONTENT_CALL;
00137                 }
00138                 else
00139                 {
00140                     $data[4][0] = eZTemplate::TYPE_OPTIMIZED_ATTRIBUTE_LOOKUP;
00141                 }
00142             }
00143 
00144             /* Create a new node representing the optimization */
00145             array_unshift( $data, array( eZTemplate::TYPE_OPTIMIZED_NODE, null, 2 ) );
00146             $ret = 1;
00147         }
00148 
00149         /* node.object.data_map optimization through function */
00150         if ( isset( $data[0] ) and
00151              $data[0][0] == eZTemplate::NODE_INTERNAL_CODE_PIECE )
00152         {
00153             $functionRet = eZTemplateOptimizer::optimizeFunction( $useComments, $php, $tpl, $data[0], $resourceData );
00154             // Merge settings
00155             $ret = $ret | $functionRet;
00156         }
00157         return $ret;
00158     }
00159 
00160     /*!
00161      Runs the optimizer
00162     */
00163     static function optimize( $useComments, &$php, $tpl, &$tree, &$resourceData )
00164     {
00165         /* If for some reason we don't have elements, simply return */
00166         if (! is_array( $tree[1] ) )
00167             return;
00168 
00169         $addNodeInit = false;
00170 
00171         /* Loop through the children of the root */
00172         foreach ( $tree[1] as $key => $kiddie )
00173         {
00174             /* Analyse per node type */
00175             switch ( $kiddie[0] )
00176             {
00177                 case eZTemplate::NODE_INTERNAL_OUTPUT_SPACING_INCREASE:
00178                 case eZTemplate::NODE_INTERNAL_SPACING_DECREASE:
00179                     /* Removing unnecessary whitespace changes */
00180                     unset( $tree[1][$key] );
00181                     break;
00182                 case 3: /* Variable */
00183                     if ( isset( $tree[1][$key + 1] ) and
00184                          ( $tree[1][$key + 1][0] == eZTemplate::NODE_INTERNAL_RESOURCE_ACQUISITION ) and
00185                          isset( $resourceData['class-info'] ) )
00186                     {
00187                         $ret = eZTemplateOptimizer::optimizeResourceAcquisition(
00188                             $useComments, $php, $tpl,
00189                             $tree[1][$key], $tree[1][$key + 1], $resourceData );
00190                         /* We only unset the tree node when the optimization
00191                          * function returns false, as that means that the
00192                          * optimization could not be made. */
00193                         if ($ret)
00194                         {
00195                             unset( $tree[1][$key] );
00196                         }
00197                     }
00198                     else
00199                     {
00200                         $ret = eZTemplateOptimizer::optimizeVariable( $useComments, $php, $tpl, $tree[1][$key][2], $resourceData );
00201                         if ( $ret & 1 )
00202                             $addNodeInit = true;
00203                     }
00204                     break;
00205             }
00206         }
00207         if ( $addNodeInit )
00208         {
00209             $initializer = array( eZTemplate::NODE_OPTIMIZED_INIT, null, false );
00210             array_unshift( $tree[1], $initializer );
00211         }
00212     }
00213 
00214     static function fetchClassDeclaration( $classID )
00215     {
00216         include_once "kernel/classes/ezcontentclass.php";
00217         $contentClass = eZContentClass::fetch( $classID );
00218         $attributeArray = array();
00219         $attributes = is_object( $contentClass ) ? $contentClass->fetchAttributes() : array();
00220         foreach ( $attributes as $attribute )
00221         {
00222             $attributeArray[ $attribute->Identifier ] = $attribute->DataTypeString;
00223         }
00224         return $attributeArray;
00225     }
00226 }
00227 ?>