/lib/eztemplate/classes/eztemplatecompiler.php
PHP | 3357 lines | 3130 code | 53 blank | 174 comment | 55 complexity | 719270ac1b739ddefeca5ba57668cdfd MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- <?php
- //
- // Definition of eZTemplateCompiler class
- //
- // Created on: <06-Dec-2002 14:17:10 amos>
- //
- // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
- // SOFTWARE NAME: eZ Publish
- // SOFTWARE RELEASE: 4.1.x
- // COPYRIGHT NOTICE: Copyright (C) 1999-2010 eZ Systems AS
- // SOFTWARE LICENSE: GNU General Public License v2.0
- // NOTICE: >
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of version 2.0 of the GNU General
- // Public License as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of version 2.0 of the GNU General
- // Public License along with this program; if not, write to the Free
- // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- // MA 02110-1301, USA.
- //
- //
- // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
- //
- /*! \file
- */
- /*!
- \class eZTemplateCompiler eztemplatecompiler.php
- \brief Creates compiled PHP code from templates to speed up template usage.
- Various optimizations that can be done are:
- Data:
- - Is constant, generate static data
- - Is variable, generate direct variable extraction
- - Has operators
- - Has attributes
- Attributes:
- - Is constant, generate static data
- Operators:
- - Supports input
- - Supports output
- - Supports parameters
- - Generates static data (true, false)
- - Custom PHP code
- - Modifies template variables, if possible name which ones. Allows
- for caching of variables in the script.
- Functions:
- - Supports parameters
- - Supports children (set? no, section? yes)
- - Generates static data (ldelim,rdelim)
- - Children usage, no result(set-block) | copy(let,default) | dynamic(conditional, repeated etc.)
- - Children tree, requires original tree | allows custom processing
- - Custom PHP code
- - Deflate/transform tree, create new non-nested tree (let, default)
- - Modifies template variables, if possible name which ones. Allows
- for caching of variables in the script.
- */
- class eZTemplateCompiler
- {
- const CODE_DATE = 1074699607;
- /*!
- \static
- Returns the prefix for file names
- */
- static function TemplatePrefix()
- {
- $templatePrefix = '';
- $ini = eZINI::instance();
- if ( $ini->variable( 'TemplateSettings', 'TemplateCompression' ) == 'enabled' )
- {
- $templatePrefix = 'compress.zlib://';
- }
- return $templatePrefix;
- }
- /*!
- \static
- Sets/unsets various compiler settings. To set a setting add a key in the \a $settingsMap
- with the wanted value, to unset it use \c null as the value.
- The following values can be set.
- - compile - boolean, whether to compile templates or not
- - comments - boolean, whether to include comments in templates
- - accumulators - boolean, whether to include debug accumulators in templates
- - timingpoints - boolean, whether to include debug timingpoints in templates
- - fallbackresource - boolean, whether to include the fallback resource code
- - nodeplacement - boolean, whether to include information on placement of all nodes
- - execution - boolean, whether to execute the compiled templates or not
- - generate - boolean, whether to always generate the compiled files, or only when template is changed
- - compilation-directory - string, where to place compiled files, the path will be relative from the
- eZ Publish directory and not the var/cache directory.
- */
- static function setSettings( $settingsMap )
- {
- $existingMap = array();
- if ( isset( $GLOBALS['eZTemplateCompilerSettings'] ) )
- {
- $existingMap = $GLOBALS['eZTemplateCompilerSettings'];
- }
- $GLOBALS['eZTemplateCompilerSettings'] = array_merge( $existingMap, $settingsMap );
- }
- /*!
- \static
- \return true if template compiling is enabled.
- \note To change this setting edit settings/site.ini and locate the group TemplateSettings and the entry TemplateCompile.
- */
- static function isCompilationEnabled()
- {
- if ( isset( $GLOBALS['eZSiteBasics'] ) )
- {
- $siteBasics = $GLOBALS['eZSiteBasics'];
- if ( isset( $siteBasics['no-cache-adviced'] ) and
- $siteBasics['no-cache-adviced'] )
- {
- return false;
- }
- }
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['compile'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['compile'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['compile'];
- }
- $ini = eZINI::instance();
- $compilationEnabled = $ini->variable( 'TemplateSettings', 'TemplateCompile' ) == 'enabled';
- return $compilationEnabled;
- }
- /*!
- \static
- \return true if template compilation should include comments.
- */
- static function isCommentsEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['comments'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['comments'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['comments'];
- }
- $ini = eZINI::instance();
- $commentsEnabled = $ini->variable( 'TemplateSettings', 'CompileComments' ) == 'enabled';
- return $commentsEnabled;
- }
- /*!
- \static
- \return true if template compilation should run in development mode.
- When in development mode the system will perform additional checks, e.g. for
- modification time of compiled file vs original source file.
- This mode is quite useful for development since it requires less
- clear-cache calls but has additional file checks and should be turned off
- for live sites.
- */
- static function isDevelopmentModeEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['development_mode'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['development_mode'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['development_mode'];
- }
- $ini = eZINI::instance();
- $developmentModeEnabled = $ini->variable( 'TemplateSettings', 'DevelopmentMode' ) == 'enabled';
- return $developmentModeEnabled;
- }
- /*!
- \static
- \return true if template compilation should include debug accumulators.
- */
- static function isAccumulatorsEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['accumulators'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['accumulators'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['accumulators'];
- }
- $ini = eZINI::instance();
- $enabled = $ini->variable( 'TemplateSettings', 'CompileAccumulators' ) == 'enabled';
- return $enabled;
- }
- /*!
- \static
- \return true if template compilation should include debug timing points.
- */
- static function isTimingPointsEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['timingpoints'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['timingpoints'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['timingpoints'];
- }
- $ini = eZINI::instance();
- $enabled = $ini->variable( 'TemplateSettings', 'CompileTimingPoints' ) == 'enabled';
- return $enabled;
- }
- /*!
- \static
- \return true if resource fallback code should be included.
- */
- static function isFallbackResourceCodeEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['fallbackresource'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['fallbackresource'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['fallbackresource'];
- }
- $ini = eZINI::instance();
- $enabled = $ini->variable( 'TemplateSettings', 'CompileResourceFallback' ) == 'enabled';
- return $enabled;
- }
- /*!
- \static
- \return true if template compilation should include comments.
- */
- static function isNodePlacementEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['nodeplacement'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['nodeplacement'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['nodeplacement'];
- }
- $ini = eZINI::instance();
- $nodePlacementEnabled = $ini->variable( 'TemplateSettings', 'CompileNodePlacements' ) == 'enabled';
- return $nodePlacementEnabled;
- }
- /*!
- \static
- \return true if the compiled template execution is enabled.
- */
- static function isExecutionEnabled()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['execution'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['execution'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['execution'];
- }
- $ini = eZINI::instance();
- $execution = $ini->variable( 'TemplateSettings', 'CompileExecution' ) == 'enabled';
- return $execution;
- }
- /*!
- \static
- \return true if template compilation should always be run even if a sufficient compilation already exists.
- */
- static function alwaysGenerate()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['generate'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['generate'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['generate'];
- }
- $ini = eZINI::instance();
- $alwaysGenerate = $ini->variable( 'TemplateSettings', 'CompileAlwaysGenerate' ) == 'enabled';
- return $alwaysGenerate;
- }
- /*!
- \static
- \return true if template node tree named \a $treeName should be included the compiled template.
- */
- static function isTreeEnabled( $treeName )
- {
- $ini = eZINI::instance();
- $treeList = $ini->variable( 'TemplateSettings', 'CompileIncludeNodeTree' );
- return in_array( $treeName, $treeList );
- }
- /*!
- \static
- \return the directory for compiled templates.
- */
- static function compilationDirectory()
- {
- if ( isset( $GLOBALS['eZTemplateCompilerSettings']['compilation-directory'] ) and
- $GLOBALS['eZTemplateCompilerSettings']['compilation-directory'] !== null )
- {
- return $GLOBALS['eZTemplateCompilerSettings']['compilation-directory'];
- }
- $compilationDirectory =& $GLOBALS['eZTemplateCompilerDirectory'];
- if ( !isset( $compilationDirectory ) )
- {
- $ini = eZINI::instance();
- $shareTemplates = $ini->hasVariable( 'TemplateSettings', 'ShareCompiledTemplates' ) ?
- $ini->variable( 'TemplateSettings', 'ShareCompiledTemplates' ) == 'enabled' :
- false;
- if ( $shareTemplates &&
- $ini->hasVariable( 'TemplateSettings', 'SharedCompiledTemplatesDir' ) &&
- trim( $ini->variable( 'TemplateSettings', 'SharedCompiledTemplatesDir' ) ) != '' )
- {
- $compilationDirectory = eZDir::path( array( $ini->variable( 'TemplateSettings', 'SharedCompiledTemplatesDir' ) ) );
- }
- else
- {
- $compilationDirectory = eZDir::path( array( eZSys::cacheDirectory(), 'template/compiled' ) );
- }
- }
- return $compilationDirectory;
- }
- /*!
- Creates the name for the compiled template and returns it.
- The name conists of original filename with the md5 of the key and charset appended.
- */
- static function compilationFilename( $key, $resourceData )
- {
- $internalCharset = eZTextCodec::internalCharset();
- $templateFilepath = $resourceData['template-filename'];
- $extraName = '';
- if ( preg_match( "#^.+/(.*)\.tpl$#", $templateFilepath, $matches ) )
- $extraName = $matches[1] . '-';
- else if ( preg_match( "#^(.*)\.tpl$#", $templateFilepath, $matches ) )
- $extraName = $matches[1] . '-';
- $accessText = false;
- if ( isset( $GLOBALS['eZCurrentAccess']['name'] ) )
- $accessText = '-' . $GLOBALS['eZCurrentAccess']['name'];
- $locale = eZLocale::instance();
- $language = $locale->localeFullCode();
- $http = eZHTTPTool::instance();
- $useFullUrlText = $http->UseFullUrl ? 'full' : 'relative';
- $pageLayoutVariable = "";
- if ( isset( $GLOBALS['eZCustomPageLayout'] ) )
- $pageLayoutVariable = $GLOBALS['eZCustomPageLayout'];
- $ini = eZINI::instance();
- $shareTemplates = $ini->hasVariable( 'TemplateSettings', 'ShareCompiledTemplates' ) ?
- $ini->variable( 'TemplateSettings', 'ShareCompiledTemplates' ) == 'enabled' :
- false;
- if ( $shareTemplates )
- $cacheFileKey = $key . '-' . $language;
- else
- $cacheFileKey = $key . '-' . $internalCharset . '-' . $language . '-' . $useFullUrlText . $accessText . "-" . $pageLayoutVariable . '-' . eZSys::indexFile();
- $cacheFileName = $extraName . md5( $cacheFileKey ) . '.php';
- return $cacheFileName;
- }
- /*!
- \static
- \return true if the compiled template with the key \a $key exists.
- A compiled template is found usable when it exists and has a timestamp
- higher or equal to \a $timestamp.
- */
- static function hasCompiledTemplate( $key, $timestamp, &$resourceData )
- {
- if ( !eZTemplateCompiler::isCompilationEnabled() )
- return false;
- if ( eZTemplateCompiler::alwaysGenerate() )
- return false;
- $cacheFileName = eZTemplateCompiler::compilationFilename( $key, $resourceData );
- $php = new eZPHPCreator( eZTemplateCompiler::compilationDirectory(), $cacheFileName, eZTemplateCompiler::TemplatePrefix() );
- $canRestore = $php->canRestore( $timestamp );
- $uri = false;
- if ( $canRestore )
- eZDebugSetting::writeDebug( 'eztemplate-compile', "Cache hit for uri '$uri' with key '$key'", 'eZTemplateCompiler::hasCompiledTemplate' );
- else
- eZDebugSetting::writeDebug( 'eztemplate-compile', "Cache miss for uri '$uri' with key '$key'", 'eZTemplateCompiler::hasCompiledTemplate' );
- return $canRestore;
- }
- /*!
- Tries to execute the compiled template and returns \c true if succsesful.
- Returns \c false if caching is disabled or the compiled template could not be executed.
- */
- static function executeCompilation( $tpl, &$textElements, $key, &$resourceData,
- $rootNamespace, $currentNamespace )
- {
- if ( !eZTemplateCompiler::isCompilationEnabled() )
- return false;
- if ( !eZTemplateCompiler::isExecutionEnabled() )
- return false;
- $cacheFileName = eZTemplateCompiler::compilationFilename( $key, $resourceData );
- $resourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
- $directory = eZTemplateCompiler::compilationDirectory();
- $phpScript = eZDir::path( array( $directory, $cacheFileName ) );
- if ( file_exists( $phpScript ) )
- {
- $text = false;
- $helperStatus = eZTemplateCompiler::executeCompilationHelper( $phpScript, $text,
- $tpl, $key, $resourceData,
- $rootNamespace, $currentNamespace );
- if ( $helperStatus )
- {
- $textElements[] = $text;
- return true;
- }
- else
- eZDebug::writeError( "Failed executing compiled template '$phpScript'", 'eZTemplateCompiler::executeCompilation' );
- }
- else
- eZDebug::writeError( "Unknown compiled template '$phpScript'", 'eZTemplateCompiler::executeCompilation' );
- return false;
- }
- /*!
- Helper function for executeCompilation. Will execute the script \a $phpScript and
- set the result text in \a $text.
- The parameters \a $tpl, \a $resourceData, \a $rootNamespace and \a $currentNamespace
- are passed to the executed template compilation script.
- \return true if a text result was created.
- */
- static function executeCompilationHelper( $phpScript, &$text,
- $tpl, $key, &$resourceData,
- $rootNamespace, $currentNamespace )
- {
- $vars =& $tpl->Variables;
- /* We use $setArray to detect if execution failed, and not $text,
- * because an empty template does not return any $text and this is not
- * an error. */
- $setArray = null;
- $namespaceStack = array();
- $tpl->createLocalVariablesList();
- include( eZTemplateCompiler::TemplatePrefix() . $phpScript );
- $tpl->unsetLocalVariables();
- $tpl->destroyLocalVariablesList();
- if ( $setArray !== null )
- {
- return true;
- }
- return false;
- }
- /*!
- \static
- Generates the cache which will be used for handling optimized processing using the key \a $key.
- \note Each call to this will set the PHP time limit to 30
- \return false if the cache does not exist.
- */
- static function compileTemplate( $tpl, $key, &$resourceData )
- {
- if ( !eZTemplateCompiler::isCompilationEnabled() )
- return false;
- $resourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
- $cacheFileName = eZTemplateCompiler::compilationFilename( $key, $resourceData );
- $resourceData['uniqid'] = md5( $resourceData['template-filename']. uniqid( "ezp". getmypid(), true ) );
- // Time limit #1:
- // We reset the time limit to 30 seconds to ensure that templates
- // have enough time to compile
- // However if time limit is unlimited (0) we leave it be
- // Time limit will also be reset after subtemplates are compiled
- $maxExecutionTime = ini_get( 'max_execution_time' );
- if ( $maxExecutionTime != 0 && $maxExecutionTime < 30 )
- {
- @set_time_limit( 30 );
- }
- $rootNode =& $resourceData['root-node'];
- if ( !$rootNode )
- return false;
- $GLOBALS['eZTemplateCompilerResourceCache'][$resourceData['template-filename']] =& $resourceData;
- $useComments = eZTemplateCompiler::isCommentsEnabled();
- if ( !$resourceData['test-compile'] )
- {
- eZTemplateCompiler::createCommonCompileTemplate();
- }
- /* Check if we need to disable the generation of spacing for the compiled templates */
- $ini = eZINI::instance();
- $spacing = 'disabled';
- if ( $ini->variable( 'TemplateSettings', 'UseFormatting' ) == 'enabled' )
- {
- $spacing = 'enabled';
- }
- $php = new eZPHPCreator( eZTemplateCompiler::compilationDirectory(), $cacheFileName,
- eZTemplateCompiler::TemplatePrefix(), array( 'spacing' => $spacing ) );
- $php->addComment( 'URI: ' . $resourceData['uri'] );
- $php->addComment( 'Filename: ' . $resourceData['template-filename'] );
- $php->addComment( 'Timestamp: ' . $resourceData['time-stamp'] . ' (' . date( 'D M j G:i:s T Y', $resourceData['time-stamp'] ) . ')' );
- $php->addCodePiece("\$oldSetArray_{$resourceData['uniqid']} = isset( \$setArray ) ? \$setArray : array();\n".
- "\$setArray = array();\n");
- // Code to decrement include level of the templates
- $php->addCodePiece( "\$tpl->Level++;\n" );
- $php->addCodePiece( "if ( \$tpl->Level > $tpl->MaxLevel )\n".
- "{\n".
- "\$text = \$tpl->MaxLevelWarning;".
- "\$tpl->Level--;\n".
- "return;\n".
- "}\n" );
- if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
- {
- $php->addComment( 'Locales: ' . join( ', ', $resourceData['locales'] ) );
- $php->addCodePiece(
- '$locales = array( "'. join( '", "', $resourceData['locales'] ) . "\" );\n".
- '$oldLocale_'. $resourceData['uniqid']. ' = setlocale( LC_CTYPE, null );'. "\n".
- '$currentLocale_'. $resourceData['uniqid']. ' = setlocale( LC_CTYPE, $locales );'. "\n"
- );
- }
- // $php->addCodePiece( "print( \"" . $resourceData['template-filename'] . " ($cacheFileName)<br/>\n\" );" );
- if ( $useComments )
- {
- $templateFilename = $resourceData['template-filename'];
- if ( file_exists( $templateFilename ) )
- {
- $fd = fopen( $templateFilename, 'rb' );
- if ( $fd )
- {
- $templateText = fread( $fd, filesize( $templateFilename ) );
- $php->addComment( "Original code:\n" . $templateText );
- fclose( $fd );
- }
- }
- }
- $php->addVariable( 'eZTemplateCompilerCodeDate', eZTemplateCompiler::CODE_DATE );
- $php->addCodePiece( "if ( !defined( 'EZ_TEMPLATE_COMPILER_COMMON_CODE' ) )\n" );
- $php->addInclude( eZTemplateCompiler::compilationDirectory() . '/common.php', eZPHPCreator::INCLUDE_ONCE_STATEMENT, array( 'spacing' => 4 ) );
- $php->addSpace();
- if ( eZTemplateCompiler::isAccumulatorsEnabled() )
- {
- $php->addCodePiece( "eZDebug::accumulatorStart( 'template_compiled_execution', 'template_total', 'Template compiled execution', true );\n" );
- }
- if ( eZTemplateCompiler::isTimingPointsEnabled() )
- {
- $php->addCodePiece( "eZDebug::addTimingPoint( 'Script start $cacheFileName' );\n" );
- }
- // $php->addCodePiece( "if ( !isset( \$vars ) )\n \$vars =& \$tpl->Variables;\n" );
- // $php->addSpace();
- $parameters = array();
- $textName = eZTemplateCompiler::currentTextName( $parameters );
- // $php->addCodePiece( "if ( !isset( \$$textName ) )\n \$$textName = '';\n" );
- // $php->addSpace();
- // $variableStats = array();
- // eZTemplateCompiler::prepareVariableStatistics( $tpl, $resourceData, $variableStats );
- // eZTemplateCompiler::calculateVariableStatistics( $tpl, $rootNode, $resourceData, $variableStats );
- // print_r( $variableStats );
- $transformedTree = array();
- eZTemplateCompiler::processNodeTransformation( $useComments, $php, $tpl, $rootNode, $resourceData, $transformedTree );
- if ( $ini->variable( 'TemplateSettings', 'TemplateOptimization' ) == 'enabled' )
- {
- /* Retrieve class information for the attribute lookup table */
- if ( isset( $resourceData['handler']->Keys ) and isset( $resourceData['handler']->Keys['class'] ) ) {
- $resourceData['class-info'] = eZTemplateOptimizer::fetchClassDeclaration( $resourceData['handler']->Keys['class'] );
- }
- /* Run the optimizations */
- eZTemplateOptimizer::optimize( $useComments, $php, $tpl, $transformedTree, $resourceData );
- }
- $staticTree = array();
- eZTemplateCompiler::processStaticOptimizations( $useComments, $php, $tpl, $transformedTree, $resourceData, $staticTree );
- $combinedTree = array();
- eZTemplateCompiler::processNodeCombining( $useComments, $php, $tpl, $staticTree, $resourceData, $combinedTree );
- $finalTree = $combinedTree;
- if ( !eZTemplateCompiler::isNodePlacementEnabled() )
- eZTemplateCompiler::processRemoveNodePlacement( $finalTree );
- eZTemplateCompiler::generatePHPCode( $useComments, $php, $tpl, $finalTree, $resourceData );
- if ( eZTemplateCompiler::isTreeEnabled( 'final' ) )
- $php->addVariable( 'finalTree', $finalTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
- if ( eZTemplateCompiler::isTreeEnabled( 'combined' ) )
- $php->addVariable( 'combinedTree', $combinedTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
- if ( eZTemplateCompiler::isTreeEnabled( 'static' ) )
- $php->addVariable( 'staticTree', $staticTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
- if ( eZTemplateCompiler::isTreeEnabled( 'transformed' ) )
- $php->addVariable( 'transformedTree', $transformedTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
- if ( eZTemplateCompiler::isTreeEnabled( 'original' ) )
- $php->addVariable( 'originalTree', $rootNode, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
- if ( eZTemplateCompiler::isTimingPointsEnabled() )
- $php->addCodePiece( "eZDebug::addTimingPoint( 'Script end $cacheFileName' );\n" );
- if ( eZTemplateCompiler::isAccumulatorsEnabled() )
- $php->addCodePiece( "eZDebug::accumulatorStop( 'template_compiled_execution', true );\n" );
- if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
- {
- $php->addCodePiece(
- 'setlocale( LC_CTYPE, $oldLocale_'. $resourceData['uniqid']. ' );'. "\n"
- );
- }
- $php->addCodePiece('$setArray = $oldSetArray_'. $resourceData['uniqid']. ";\n");
- // Code to decrement include level of the templates
- $php->addCodePiece("\$tpl->Level--;\n" );
- /*
- // dump names of all defined PHP variables
- $php->addCodePiece( "echo \"defined vars in $resourceData[uri]:<br/><pre>\\n\";\n" );
- $php->addCodePiece( 'foreach ( array_keys( get_defined_vars() ) as $var_name ) echo "- $var_name\n";' );
- // dump tpl vars
- $php->addCodePiece( 'echo "\n-----------------------------------------------------------\nvars: ";' );
- $php->addCodePiece( 'var_dump( $vars );' );
- $php->addCodePiece( 'echo "</pre><hr/>\n";' );
- */
- if ( !$resourceData['test-compile'] )
- {
- $php->store( true );
- }
- return true;
- }
- static function prepareVariableStatistics( $tpl, &$resourceData, &$stats )
- {
- // $path = $resourceData['template-filename'];
- // $info =& $GLOBALS['eZTemplateCompileVariableInfo'][$path];
- if ( isset( $resourceData['variable-info'] ) )
- {
- }
- }
- static function calculateVariableStatistics( $tpl, &$node, &$resourceData, &$stats )
- {
- $nodeType = $node[0];
- if ( $nodeType == eZTemplate::NODE_ROOT )
- {
- $children = $node[1];
- $namespace = '';
- if ( $children )
- {
- eZTemplateCompiler::calculateVariableStatisticsChildren( $tpl, $children, $resourceData, $namespace, $stats );
- }
- }
- else
- $tpl->error( 'calculateVariableStatistics', "Unknown root type $nodeType, should be " . eZTemplate::NODE_ROOT );
- }
- static function calculateVariableStatisticsChildren( $tpl, &$nodeChildren, &$resourceData, $namespace, &$stats )
- {
- foreach ( $nodeChildren as $node )
- {
- if ( !isset( $node[0] ) )
- continue;
- $nodeType = $node[0];
- if ( $nodeType == eZTemplate::NODE_ROOT )
- {
- $children = $node[1];
- if ( $children )
- {
- eZTemplateCompiler::calculateVariableStatisticsChildren( $tpl, $children, $resourceData, $namespace, $stats );
- }
- }
- else if ( $nodeType == eZTemplate::NODE_TEXT )
- {
- $text = $node[2];
- $placement = $node[3];
- }
- else if ( $nodeType == eZTemplate::NODE_VARIABLE )
- {
- $variableData = $node[2];
- $variablePlacement = $node[3];
- $variableParameters = false;
- eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $variableData, $variablePlacement, $resourceData, $namespace, $stats );
- }
- else if ( $nodeType == eZTemplate::NODE_FUNCTION )
- {
- $functionChildren = $node[1];
- $functionName = $node[2];
- $functionParameters = $node[3];
- $functionPlacement = $node[4];
- if ( !isset( $tpl->Functions[$functionName] ) )
- continue;
- if ( is_array( $tpl->Functions[$functionName] ) )
- {
- $tpl->loadAndRegisterOperators( $tpl->Functions[$functionName] );
- }
- $functionObject =& $tpl->Functions[$functionName];
- if ( is_object( $functionObject ) )
- {
- $hasTransformationSupport = false;
- $transformChildren = true;
- if ( method_exists( $functionObject, 'functionTemplateStatistics' ) )
- {
- $functionObject->functionTemplateStatistics( $functionName, $node, $tpl, $resourceData, $namespace, $stats );
- }
- }
- else if ( $resourceData['test-compile'] )
- {
- $tpl->warning( '', "Operator '$operatorName' is not registered.", $functionPlacement );
- }
- }
- }
- }
- static function calculateVariableNodeStatistics( $tpl, $variableData, $variablePlacement, &$resourceData, $namespace, &$stats )
- {
- if ( !is_array( $variableData ) )
- return false;
- foreach ( $variableData as $variableItem )
- {
- $variableItemType = $variableItem[0];
- $variableItemData = $variableItem[1];
- $variableItemPlacement = $variableItem[2];
- if ( $variableItemType == eZTemplate::TYPE_STRING or
- $variableItemType == eZTemplate::TYPE_IDENTIFIER )
- {
- }
- else if ( $variableItemType == eZTemplate::TYPE_NUMERIC )
- {
- }
- else if ( $variableItemType == eZTemplate::TYPE_ARRAY )
- {
- }
- else if ( $variableItemType == eZTemplate::TYPE_BOOLEAN )
- {
- }
- else if ( $variableItemType == eZTemplate::TYPE_VARIABLE )
- {
- $variableNamespace = $variableItemData[0];
- $variableNamespaceScope = $variableItemData[1];
- $variableName = $variableItemData[2];
- if ( $variableNamespaceScope == eZTemplate::NAMESPACE_SCOPE_GLOBAL )
- $newNamespace = $variableNamespace;
- else if ( $variableNamespaceScope == eZTemplate::NAMESPACE_SCOPE_LOCAL )
- $newNamespace = $variableNamespace;
- else if ( $variableNamespaceScope == eZTemplate::NAMESPACE_SCOPE_RELATIVE )
- $newNamespace = $tpl->mergeNamespace( $namespace, $variableNamespace );
- else
- $newNamespace = false;
- eZTemplateCompiler::setVariableStatistics( $stats, $newNamespace, $variableName, array( 'is_accessed' => true ) );
- }
- else if ( $variableItemType == eZTemplate::TYPE_ATTRIBUTE )
- {
- eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $variableItemData, $variableItemPlacement, $resourceData, $namespace, $stats );
- }
- else if ( $variableItemType == eZTemplate::TYPE_OPERATOR )
- {
- $operatorName = $variableItemData[0];
- if ( !isset( $tpl->Operators[$operatorName] ) )
- continue;
- if ( is_array( $tpl->Operators[$operatorName] ) )
- {
- $tpl->loadAndRegisterOperators( $tpl->Operators[$operatorName] );
- }
- $operator =& $tpl->Operators[$operatorName];
- if ( is_object( $operator ) )
- {
- $hasStats = false;
- if ( method_exists( $operator, 'operatorTemplateHints' ) )
- {
- $hints = $operator->operatorTemplateHints();
- if ( isset( $hints[$operatorName] ) )
- {
- $operatorHints = $hints[$operatorName];
- $hasParameters = false;
- if ( isset( $operatorHints['parameters'] ) )
- $hasParameters = $operatorHints['parameters'];
- if ( $hasParameters === true )
- {
- $parameters = $variableItemData;
- $count = count( $parameters ) - 1;
- for ( $i = 0; $i < $count; ++$i )
- {
- $parameter =& $parameters[$i + 1];
- $parameterData = $parameter[1];
- $parameterPlacement = $parameter[2];
- eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $parameter, $parameterPlacement,
- $resourceData, $namespace, $stats );
- }
- }
- else if ( is_integer( $hasParameters ) )
- {
- $parameters = $variableItemData;
- $count = min( count( $parameters ) - 1, $hasParameters );
- for ( $i = 0; $i < $count; ++$i )
- {
- $parameter =& $parameters[$i + 1];
- $parameterData = $parameter[1];
- $parameterPlacement = $parameter[2];
- eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $parameter, $parameterPlacement,
- $resourceData, $namespace, $stats );
- }
- }
- $hasStats = true;
- }
- }
- if ( !$hasStats and method_exists( $operator, 'operatorTemplateStatistics' ) )
- {
- $hasStats = $operator->operatorTemplateStatistics( $operatorName, $variableItem, $variablePlacement, $tpl, $resourceData, $namespace, $stats );
- }
- if ( !$hasStats and method_exists( $operator, 'namedParameterList' ) )
- {
- $namedParameterList = $operator->namedParameterList();
- if ( method_exists( $operator, 'namedParameterPerOperator' ) and
- $operator->namedParameterPerOperator() )
- {
- $namedParameterList = $namedParameterList[$operatorName];
- }
- $operatorParameters = array_slice( $variableItemData, 1 );
- $count = 0;
- foreach ( $namedParameterList as $parameterName => $parameterDefinition )
- {
- $operatorParameter = $operatorParameters[$count];
- eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $operatorParameter, $variablePlacement, $resourceData, $namespace, $stats );
- ++$count;
- }
- $hasStats = true;
- }
- }
- else if ( $resourceData['test-compile'] )
- {
- $tpl->warning( '', "Operator '$operatorName' is not registered." );
- }
- }
- else if ( $variableItemType == eZTemplate::TYPE_VOID )
- {
- $tpl->warning( 'TemplateCompiler::calculateOperatorStatistics', "Void datatype should not be used, ignoring it" );
- }
- else
- {
- $tpl->warning( 'TemplateCompiler::calculateOperatorStatistics', "Unknown data type $variableItemType, ignoring it" );
- }
- }
- return true;
- }
- static function setVariableStatistics( &$stats, $namespace, $variableName, $changes )
- {
- if ( isset( $stats['variables'][$namespace][$variableName] ) )
- {
- $variableStats =& $stats['variables'][$namespace][$variableName];
- }
- else
- {
- $variableStats = array( 'is_accessed' => false,
- 'is_created' => false,
- 'is_modified' => false,
- 'is_removed' => false,
- 'is_local' => false,
- 'is_input' => false,
- 'namespace' => $namespace,
- 'namespace_scope' => false,
- 'type' => false );
- $stats['variables'][$namespace][$variableName] =& $variableStats;
- }
- if ( isset( $changes['invalid_access'] ) and $changes['invalid_access'] !== false )
- $variableStats['invalid_access'] = $changes['invalid_access'];
- if ( isset( $changes['is_accessed'] ) and $changes['is_accessed'] !== false )
- $variableStats['is_accessed'] = $changes['is_accessed'];
- if ( isset( $changes['is_created'] ) and $changes['is_created'] !== false )
- $variableStats['is_created'] = $changes['is_created'];
- if ( isset( $changes['is_modified'] ) and $changes['is_modified'] !== false )
- $variableStats['is_modified'] = $changes['is_modified'];
- if ( isset( $changes['is_removed'] ) and $changes['is_removed'] !== false )
- $variableStats['is_removed'] = $changes['is_removed'];
- if ( isset( $changes['is_local'] ) and $changes['is_local'] !== false )
- $variableStats['is_local'] = $changes['is_local'];
- if ( isset( $changes['is_input'] ) and $changes['is_input'] !== false )
- $variableStats['is_input'] = $changes['is_input'];
- if ( isset( $changes['namespace'] ) )
- $variableStats['namespace'] = $changes['namespace'];
- if ( isset( $changes['namespace_scope'] ) )
- $variableStats['namespace_scope'] = $changes['namespace_scope'];
- if ( isset( $changes['type'] ) )
- $variableStats['type'] = $changes['type'];
- }
- /*!
- Iterates over the template node tree and tries to combine multiple static siblings
- into one element. The original tree is specified in \a $node and the new
- combined tree will be present in \a $newNode.
- \sa processNodeCombiningChildren
- */
- static function processNodeCombining( $useComments, $php, $tpl, &$node, &$resourceData, &$newNode )
- {
- $nodeType = $node[0];
- if ( $nodeType == eZTemplate::NODE_ROOT )
- {
- $children = $node[1];
- $newNode[0] = $nodeType;
- $newNode[1] = false;
- if ( $children )
- {
- eZTemplateCompiler::processNodeCombiningChildren( $useComments, $php, $tpl, $children, $resourceData, $newNode );
- }
- }
- else
- $tpl->error( 'processNodeCombining', "Unknown root type $nodeType, should be " . eZTemplate::NODE_ROOT );
- }
- /*!
- Does node combining on the children \a $nodeChildren.
- \sa processNodeCombining
- */
- static function processNodeCombiningChildren( $useComments, $php, $tpl, &$nodeChildren, &$resourceData, &$parentNode )
- {
- $newNodeChildren = array();
- $lastNode = false;
- foreach ( $nodeChildren as $node )
- {
- $newNode = false;
- if ( !isset( $node[0] ) )
- continue;
- $nodeType = $node[0];
- if ( $nodeType == eZTemplate::NODE_ROOT )
- {
- $children = $node[1];
- $newNode = array( $nodeType,
- false );
- if ( $children )
- {
- eZTemplateCompiler::processNodeCombiningChildren( $useComments, $php, $tpl, $children, $resourceData, $newNode );
- }
- }
- else if ( $nodeType == eZTemplate::NODE_TEXT )
- {
- $text = $node[2];
- $placement = $node[3];
- $newNode = array( $nodeType,
- false,
- $text,
- $placement );
- eZTemplateCompiler::combineStaticNodes( $tpl, $resourceData, $lastNode, $newNode );
- }
- else if ( $nodeType == eZTemplate::NODE_VARIABLE )
- {
- $variableCustom = $node[1];
- $variableData = $node[2];
- $variablePlacement = $node[3];
- $variableParameters = false;
- $dataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
- $variableData, $variablePlacement,
- $resourceData );
- $newNode = $node;
- $newNode[1] = $variableCustom;
- unset( $dataInspection );
- eZTemplateCompiler::combineStaticNodes( $tpl, $resourceData, $lastNode, $newNode );
- }
- else if ( $nodeType == eZTemplate::NODE_FUNCTION )
- {
- $functionChildren = $node[1];
- $functionName = $node[2];
- $functionParameters = $node[3];
- $functionPlacement = $node[4];
- $newNode = array( $nodeType,
- false,
- $functionName,
- $functionParameters,
- $functionPlacement );
- if ( isset( $node[5] ) )
- $newNode[5] = $node[5];
- if ( is_array( $functionChildren ) )
- {
- eZTemplateCompiler::processNodeCombiningChildren( $useComments, $php, $tpl,
- $functionChildren, $resourceData, $newNode );
- }
- }
- else
- $newNode = $node;
- if ( $lastNode != false )
- {
- $newNodeChildren[] = $lastNode;
- $lastNode = false;
- }
- if ( $newNode != false )
- $lastNode = $newNode;
- }
- if ( $lastNode != false )
- {
- $newNodeChildren[] = $lastNode;
- $lastNode = false;
- }
- $parentNode[1] = $newNodeChildren;
- }
- /*!
- Tries to combine the node \a $lastNode and the node \a $newNode
- into one new text node. If possible the new node is created in \a $newNode
- and \a $lastNode will be set to \c false.
- Combining nodes only works for text nodes and variable nodes without
- variable lookup, attributes and operators.
- */
- static function combineStaticNodes( $tpl, &$resourceData, &$lastNode, &$newNode )
- {
- if ( $lastNode == false or
- $newNode == false )
- return false;
- $lastNodeType = $lastNode[0];
- $newNodeType = $newNode[0];
- if ( !in_array( $lastNodeType, array( eZTemplate::NODE_TEXT,
- eZTemplate::NODE_VARIABLE ) ) or
- !in_array( $newNodeType, array( eZTemplate::NODE_TEXT,
- eZTemplate::NODE_VARIABLE ) ) )
- return false;
- if ( $lastNodeType == eZTemplate::NODE_VARIABLE )
- {
- if ( is_array( $lastNode[1] ) )
- return false;
- $lastDataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
- $lastNode[2], $lastNode[3],
- $resourceData );
- if ( !$lastDataInspection['is-constant'] or
- $lastDataInspection['is-variable'] or
- $lastDataInspection['has-attributes'] or
- $lastDataInspection['has-operators'] )
- return false;
- if ( isset( $lastNode[4] ) and
- isset( $lastNode[4]['text-result'] ) and
- !$lastNode[4]['text-result'] )
- return false;
- }
- if ( $newNodeType == eZTemplate::NODE_VARIABLE )
- {
- if ( is_array( $newNode[1] ) )
- return false;
- $newDataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
- $newNode[2], $newNode[3],
- $resourceData );
- if ( !$newDataInspection['is-constant'] or
- $newDataInspection['is-variable'] or
- $newDataInspection['has-attributes'] or
- $newDataInspection['has-operators'] )
- return false;
- if ( isset( $newNode[4] ) and
- isset( $newNode[4]['text-result'] ) and
- !$newNode[4]['text-result'] )
- return false;
- if ( isset( $newNode[1] ) and
- $newNode[1] !== false )
- return false;
- }
- $textElements = array();
- $lastNodeData = eZTemplateCompiler::staticNodeData( $lastNode );
- $newNodeData = eZTemplateCompiler::staticNodeData( $newNode );
- $tpl->appendElementText( $textElements, $lastNodeData, false, false );
- $tpl->appendElementText( $textElements, $newNodeData, false, false );
- $newData = implode( '', $textElements );
- $newPlacement = $lastNode[3];
- if ( !is_array( $newPlacement ) )
- {
- $newPlacement = $newNode[3];
- }
- else
- {
- $newPlacement[1][0] = $newNode[3][1][0]; // Line end
- $newPlacement[1][1] = $newNode[3][1][1]; // Column end
- $newPlacement[1][2] = $newNode[3][1][2]; // Position end
- }
- $lastNode = false;
- $newNode = array( eZTemplate::NODE_TEXT,
- false,
- $newData,
- $newPlacement );
- }
- /*!
- \return the static data for the node \a $node or \c false if
- no data could be fetched.
- Will only return data from text nodes and variables nodes
- without variable lookup, attribute lookup or operators.
- */
- static function staticNodeData( $node )
- {
- $nodeType = $node[0];
- if ( $nodeType == eZTemplate::NODE_TEXT )
- {
- return $node[2];
- }
- else if ( $nodeType == eZTemplate::NODE_VARIABLE )
- {
- $data = $node[2];
- if ( is_array( $data ) and
- count( $data ) > 0 )
- {
- $dataType = $data[0][0];
- if ( $dataType == eZTemplate::TYPE_STRING or
- $dataType == eZTemplate::TYPE_NUMERIC or
- $dataType == eZTemplate::TYPE_IDENTIFIER or
- $dataType == eZTemplate::TYPE_ARRAY or
- $dataType == eZTemplate::TYPE_BOOLEAN )
- {
- return $data[0][1];
- }
- }
- }
- return null;
- }
- /*!
- Iterates over the items in the tree \a $node and tries to extract static data
- from operators which supports it.
- */
- static function processStaticOptimizations( $useComments, $php, $tpl, &$node, &$resourceData, &$newNode )
- {
- $nodeType = $node[0];
- if ( $nodeType == eZTemplate::NODE_ROOT )
- {
- $children = $node[1];
- $newNode[0] = $nodeType;
- $newNode[1] = false;
- if ( $children )
- {
- $newNode[1] = array();
- foreach ( $children as $child )
- {
- $newChild = array();
- eZTemplateCompiler::processStaticOptimizations( $useComments, $php, $tpl, $child, $resourceData, $newChild );
- $newNode[1][] = $newChild;
- }
- }
- }
- else if ( $nodeType == eZTemplate::NODE_TEXT )
- {
- $text = $node[2];
- $placement = $node[3];
- $newNode[0] = $nodeType;
- $newNode[1] = false;
- $newNode[2] = $text;
- $newNode[3] = $placement;
- }
- else if ( $nodeType == eZTemplate::NODE_VARIABLE )
- {
- $variableCustom = $node[1];
- $variableData = $node[2];
- $variablePlacement = $node[3];
- $dataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
- …
Large files files are truncated, but you can click here to view the full file