PageRenderTime 192ms CodeModel.GetById 109ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/eztemplate/classes/eztemplatecompiler.php

https://github.com/aurelienRT1/ezpublish
PHP | 3357 lines | 3130 code | 53 blank | 174 comment | 55 complexity | 719270ac1b739ddefeca5ba57668cdfd MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2//
   3// Definition of eZTemplateCompiler class
   4//
   5// Created on: <06-Dec-2002 14:17:10 amos>
   6//
   7// ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
   8// SOFTWARE NAME: eZ Publish
   9// SOFTWARE RELEASE: 4.1.x
  10// COPYRIGHT NOTICE: Copyright (C) 1999-2010 eZ Systems AS
  11// SOFTWARE LICENSE: GNU General Public License v2.0
  12// NOTICE: >
  13//   This program is free software; you can redistribute it and/or
  14//   modify it under the terms of version 2.0  of the GNU General
  15//   Public License as published by the Free Software Foundation.
  16//
  17//   This program is distributed in the hope that it will be useful,
  18//   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20//   GNU General Public License for more details.
  21//
  22//   You should have received a copy of version 2.0 of the GNU General
  23//   Public License along with this program; if not, write to the Free
  24//   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25//   MA 02110-1301, USA.
  26//
  27//
  28// ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
  29//
  30
  31/*! \file
  32*/
  33
  34/*!
  35  \class eZTemplateCompiler eztemplatecompiler.php
  36  \brief Creates compiled PHP code from templates to speed up template usage.
  37
  38   Various optimizations that can be done are:
  39
  40    Data:
  41    - Is constant, generate static data
  42    - Is variable, generate direct variable extraction
  43    - Has operators
  44    - Has attributes
  45
  46    Attributes:
  47    - Is constant, generate static data
  48
  49    Operators:
  50    - Supports input
  51    - Supports output
  52    - Supports parameters
  53    - Generates static data (true, false)
  54    - Custom PHP code
  55    - Modifies template variables, if possible name which ones. Allows
  56      for caching of variables in the script.
  57
  58    Functions:
  59    - Supports parameters
  60    - Supports children (set? no, section? yes)
  61    - Generates static data (ldelim,rdelim)
  62    - Children usage, no result(set-block) | copy(let,default) | dynamic(conditional, repeated etc.)
  63    - Children tree, requires original tree | allows custom processing
  64    - Custom PHP code
  65    - Deflate/transform tree, create new non-nested tree (let, default)
  66    - Modifies template variables, if possible name which ones. Allows
  67      for caching of variables in the script.
  68*/
  69
  70class eZTemplateCompiler
  71{
  72    const CODE_DATE = 1074699607;
  73
  74    /*!
  75     \static
  76     Returns the prefix for file names
  77    */
  78    static function TemplatePrefix()
  79    {
  80        $templatePrefix = '';
  81        $ini = eZINI::instance();
  82        if ( $ini->variable( 'TemplateSettings', 'TemplateCompression' ) == 'enabled' )
  83        {
  84            $templatePrefix = 'compress.zlib://';
  85        }
  86        return $templatePrefix;
  87    }
  88    /*!
  89     \static
  90     Sets/unsets various compiler settings. To set a setting add a key in the \a $settingsMap
  91     with the wanted value, to unset it use \c null as the value.
  92
  93     The following values can be set.
  94     - compile - boolean, whether to compile templates or not
  95     - comments - boolean, whether to include comments in templates
  96     - accumulators - boolean, whether to include debug accumulators in templates
  97     - timingpoints - boolean, whether to include debug timingpoints in templates
  98     - fallbackresource - boolean, whether to include the fallback resource code
  99     - nodeplacement - boolean, whether to include information on placement of all nodes
 100     - execution - boolean, whether to execute the compiled templates or not
 101     - generate - boolean, whether to always generate the compiled files, or only when template is changed
 102     - compilation-directory - string, where to place compiled files, the path will be relative from the
 103                               eZ Publish directory and not the var/cache directory.
 104    */
 105    static function setSettings( $settingsMap )
 106    {
 107        $existingMap = array();
 108        if ( isset( $GLOBALS['eZTemplateCompilerSettings'] ) )
 109        {
 110            $existingMap = $GLOBALS['eZTemplateCompilerSettings'];
 111        }
 112        $GLOBALS['eZTemplateCompilerSettings'] = array_merge( $existingMap, $settingsMap );
 113    }
 114
 115    /*!
 116     \static
 117     \return true if template compiling is enabled.
 118     \note To change this setting edit settings/site.ini and locate the group TemplateSettings and the entry TemplateCompile.
 119    */
 120    static function isCompilationEnabled()
 121    {
 122        if ( isset( $GLOBALS['eZSiteBasics'] ) )
 123        {
 124            $siteBasics = $GLOBALS['eZSiteBasics'];
 125            if ( isset( $siteBasics['no-cache-adviced'] ) and
 126                 $siteBasics['no-cache-adviced'] )
 127            {
 128                return false;
 129            }
 130        }
 131
 132        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['compile'] ) and
 133             $GLOBALS['eZTemplateCompilerSettings']['compile'] !== null )
 134        {
 135            return $GLOBALS['eZTemplateCompilerSettings']['compile'];
 136        }
 137
 138        $ini = eZINI::instance();
 139        $compilationEnabled = $ini->variable( 'TemplateSettings', 'TemplateCompile' ) == 'enabled';
 140        return $compilationEnabled;
 141    }
 142
 143    /*!
 144     \static
 145     \return true if template compilation should include comments.
 146    */
 147    static function isCommentsEnabled()
 148    {
 149        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['comments'] ) and
 150             $GLOBALS['eZTemplateCompilerSettings']['comments'] !== null )
 151        {
 152            return $GLOBALS['eZTemplateCompilerSettings']['comments'];
 153        }
 154
 155        $ini = eZINI::instance();
 156        $commentsEnabled = $ini->variable( 'TemplateSettings', 'CompileComments' ) == 'enabled';
 157        return $commentsEnabled;
 158    }
 159
 160    /*!
 161     \static
 162     \return true if template compilation should run in development mode.
 163
 164     When in development mode the system will perform additional checks, e.g. for
 165     modification time of compiled file vs original source file.
 166     This mode is quite useful for development since it requires less
 167     clear-cache calls but has additional file checks and should be turned off
 168     for live sites.
 169    */
 170    static function isDevelopmentModeEnabled()
 171    {
 172        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['development_mode'] ) and
 173             $GLOBALS['eZTemplateCompilerSettings']['development_mode'] !== null )
 174        {
 175            return $GLOBALS['eZTemplateCompilerSettings']['development_mode'];
 176        }
 177
 178        $ini = eZINI::instance();
 179        $developmentModeEnabled = $ini->variable( 'TemplateSettings', 'DevelopmentMode' ) == 'enabled';
 180        return $developmentModeEnabled;
 181    }
 182
 183    /*!
 184     \static
 185     \return true if template compilation should include debug accumulators.
 186    */
 187    static function isAccumulatorsEnabled()
 188    {
 189        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['accumulators'] ) and
 190             $GLOBALS['eZTemplateCompilerSettings']['accumulators'] !== null )
 191        {
 192            return $GLOBALS['eZTemplateCompilerSettings']['accumulators'];
 193        }
 194
 195        $ini = eZINI::instance();
 196        $enabled = $ini->variable( 'TemplateSettings', 'CompileAccumulators' ) == 'enabled';
 197        return $enabled;
 198    }
 199
 200    /*!
 201     \static
 202     \return true if template compilation should include debug timing points.
 203    */
 204    static function isTimingPointsEnabled()
 205    {
 206        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['timingpoints'] ) and
 207             $GLOBALS['eZTemplateCompilerSettings']['timingpoints'] !== null )
 208        {
 209            return $GLOBALS['eZTemplateCompilerSettings']['timingpoints'];
 210        }
 211
 212        $ini = eZINI::instance();
 213        $enabled = $ini->variable( 'TemplateSettings', 'CompileTimingPoints' ) == 'enabled';
 214        return $enabled;
 215    }
 216
 217    /*!
 218     \static
 219     \return true if resource fallback code should be included.
 220    */
 221    static function isFallbackResourceCodeEnabled()
 222    {
 223        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['fallbackresource'] ) and
 224             $GLOBALS['eZTemplateCompilerSettings']['fallbackresource'] !== null )
 225        {
 226            return $GLOBALS['eZTemplateCompilerSettings']['fallbackresource'];
 227        }
 228
 229        $ini = eZINI::instance();
 230        $enabled = $ini->variable( 'TemplateSettings', 'CompileResourceFallback' ) == 'enabled';
 231        return $enabled;
 232    }
 233
 234    /*!
 235     \static
 236     \return true if template compilation should include comments.
 237    */
 238    static function isNodePlacementEnabled()
 239    {
 240        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['nodeplacement'] ) and
 241             $GLOBALS['eZTemplateCompilerSettings']['nodeplacement'] !== null )
 242        {
 243            return $GLOBALS['eZTemplateCompilerSettings']['nodeplacement'];
 244        }
 245
 246        $ini = eZINI::instance();
 247        $nodePlacementEnabled = $ini->variable( 'TemplateSettings', 'CompileNodePlacements' ) == 'enabled';
 248        return $nodePlacementEnabled;
 249    }
 250
 251    /*!
 252     \static
 253     \return true if the compiled template execution is enabled.
 254    */
 255    static function isExecutionEnabled()
 256    {
 257        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['execution'] ) and
 258             $GLOBALS['eZTemplateCompilerSettings']['execution'] !== null )
 259        {
 260            return $GLOBALS['eZTemplateCompilerSettings']['execution'];
 261        }
 262
 263        $ini = eZINI::instance();
 264        $execution = $ini->variable( 'TemplateSettings', 'CompileExecution' ) == 'enabled';
 265        return $execution;
 266    }
 267
 268    /*!
 269     \static
 270     \return true if template compilation should always be run even if a sufficient compilation already exists.
 271    */
 272    static function alwaysGenerate()
 273    {
 274        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['generate'] ) and
 275             $GLOBALS['eZTemplateCompilerSettings']['generate'] !== null )
 276        {
 277            return $GLOBALS['eZTemplateCompilerSettings']['generate'];
 278        }
 279
 280        $ini = eZINI::instance();
 281        $alwaysGenerate = $ini->variable( 'TemplateSettings', 'CompileAlwaysGenerate' ) == 'enabled';
 282        return $alwaysGenerate;
 283    }
 284
 285    /*!
 286     \static
 287     \return true if template node tree named \a $treeName should be included the compiled template.
 288    */
 289    static function isTreeEnabled( $treeName )
 290    {
 291        $ini = eZINI::instance();
 292        $treeList = $ini->variable( 'TemplateSettings', 'CompileIncludeNodeTree' );
 293        return in_array( $treeName, $treeList );
 294    }
 295
 296    /*!
 297     \static
 298     \return the directory for compiled templates.
 299    */
 300    static function compilationDirectory()
 301    {
 302        if ( isset( $GLOBALS['eZTemplateCompilerSettings']['compilation-directory'] ) and
 303             $GLOBALS['eZTemplateCompilerSettings']['compilation-directory'] !== null )
 304        {
 305            return $GLOBALS['eZTemplateCompilerSettings']['compilation-directory'];
 306        }
 307
 308        $compilationDirectory =& $GLOBALS['eZTemplateCompilerDirectory'];
 309        if ( !isset( $compilationDirectory ) )
 310        {
 311            $ini = eZINI::instance();
 312            $shareTemplates = $ini->hasVariable( 'TemplateSettings', 'ShareCompiledTemplates' ) ?
 313                                $ini->variable( 'TemplateSettings', 'ShareCompiledTemplates' ) == 'enabled' :
 314                                false;
 315            if ( $shareTemplates &&
 316                 $ini->hasVariable( 'TemplateSettings', 'SharedCompiledTemplatesDir' ) &&
 317                 trim( $ini->variable( 'TemplateSettings', 'SharedCompiledTemplatesDir' ) ) != '' )
 318            {
 319                $compilationDirectory = eZDir::path( array( $ini->variable( 'TemplateSettings', 'SharedCompiledTemplatesDir' ) ) );
 320            }
 321            else
 322            {
 323                $compilationDirectory = eZDir::path( array( eZSys::cacheDirectory(), 'template/compiled' ) );
 324            }
 325        }
 326        return $compilationDirectory;
 327    }
 328
 329    /*!
 330     Creates the name for the compiled template and returns it.
 331     The name conists of original filename with the md5 of the key and charset appended.
 332    */
 333    static function compilationFilename( $key, $resourceData )
 334    {
 335        $internalCharset = eZTextCodec::internalCharset();
 336        $templateFilepath = $resourceData['template-filename'];
 337        $extraName = '';
 338        if ( preg_match( "#^.+/(.*)\.tpl$#", $templateFilepath, $matches ) )
 339            $extraName = $matches[1] . '-';
 340        else if ( preg_match( "#^(.*)\.tpl$#", $templateFilepath, $matches ) )
 341            $extraName = $matches[1] . '-';
 342        $accessText = false;
 343        if ( isset( $GLOBALS['eZCurrentAccess']['name'] ) )
 344            $accessText = '-' . $GLOBALS['eZCurrentAccess']['name'];
 345        $locale = eZLocale::instance();
 346        $language = $locale->localeFullCode();
 347        $http = eZHTTPTool::instance();
 348        $useFullUrlText = $http->UseFullUrl ? 'full' : 'relative';
 349
 350        $pageLayoutVariable = "";
 351        if ( isset( $GLOBALS['eZCustomPageLayout'] ) )
 352            $pageLayoutVariable = $GLOBALS['eZCustomPageLayout'];
 353
 354        $ini = eZINI::instance();
 355
 356        $shareTemplates = $ini->hasVariable( 'TemplateSettings', 'ShareCompiledTemplates' ) ?
 357                            $ini->variable( 'TemplateSettings', 'ShareCompiledTemplates' ) == 'enabled' :
 358                            false;
 359
 360        if ( $shareTemplates )
 361            $cacheFileKey = $key . '-' . $language;
 362        else
 363            $cacheFileKey = $key . '-' . $internalCharset . '-' . $language . '-' . $useFullUrlText . $accessText . "-" . $pageLayoutVariable . '-' . eZSys::indexFile();
 364
 365        $cacheFileName = $extraName . md5( $cacheFileKey ) . '.php';
 366        return $cacheFileName;
 367    }
 368
 369    /*!
 370     \static
 371     \return true if the compiled template with the key \a $key exists.
 372             A compiled template is found usable when it exists and has a timestamp
 373             higher or equal to \a $timestamp.
 374    */
 375    static function hasCompiledTemplate( $key, $timestamp, &$resourceData )
 376    {
 377        if ( !eZTemplateCompiler::isCompilationEnabled() )
 378            return false;
 379        if ( eZTemplateCompiler::alwaysGenerate() )
 380            return false;
 381
 382        $cacheFileName = eZTemplateCompiler::compilationFilename( $key, $resourceData );
 383
 384        $php = new eZPHPCreator( eZTemplateCompiler::compilationDirectory(), $cacheFileName, eZTemplateCompiler::TemplatePrefix() );
 385        $canRestore = $php->canRestore( $timestamp );
 386        $uri = false;
 387        if ( $canRestore )
 388            eZDebugSetting::writeDebug( 'eztemplate-compile', "Cache hit for uri '$uri' with key '$key'", 'eZTemplateCompiler::hasCompiledTemplate' );
 389        else
 390            eZDebugSetting::writeDebug( 'eztemplate-compile', "Cache miss for uri '$uri' with key '$key'", 'eZTemplateCompiler::hasCompiledTemplate' );
 391        return $canRestore;
 392    }
 393
 394    /*!
 395     Tries to execute the compiled template and returns \c true if succsesful.
 396     Returns \c false if caching is disabled or the compiled template could not be executed.
 397    */
 398    static function executeCompilation( $tpl, &$textElements, $key, &$resourceData,
 399                                 $rootNamespace, $currentNamespace )
 400     {
 401        if ( !eZTemplateCompiler::isCompilationEnabled() )
 402            return false;
 403        if ( !eZTemplateCompiler::isExecutionEnabled() )
 404            return false;
 405        $cacheFileName = eZTemplateCompiler::compilationFilename( $key, $resourceData );
 406        $resourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
 407
 408        $directory = eZTemplateCompiler::compilationDirectory();
 409        $phpScript = eZDir::path( array( $directory, $cacheFileName ) );
 410        if ( file_exists( $phpScript ) )
 411        {
 412            $text = false;
 413            $helperStatus = eZTemplateCompiler::executeCompilationHelper( $phpScript, $text,
 414                                                                          $tpl, $key, $resourceData,
 415                                                                          $rootNamespace, $currentNamespace );
 416            if ( $helperStatus )
 417            {
 418                $textElements[] = $text;
 419                return true;
 420            }
 421            else
 422                eZDebug::writeError( "Failed executing compiled template '$phpScript'", 'eZTemplateCompiler::executeCompilation' );
 423        }
 424        else
 425            eZDebug::writeError( "Unknown compiled template '$phpScript'", 'eZTemplateCompiler::executeCompilation' );
 426        return false;
 427    }
 428
 429    /*!
 430     Helper function for executeCompilation. Will execute the script \a $phpScript and
 431     set the result text in \a $text.
 432     The parameters \a $tpl, \a $resourceData, \a $rootNamespace and \a $currentNamespace
 433     are passed to the executed template compilation script.
 434     \return true if a text result was created.
 435    */
 436    static function executeCompilationHelper( $phpScript, &$text,
 437                                       $tpl, $key, &$resourceData,
 438                                       $rootNamespace, $currentNamespace )
 439    {
 440        $vars =& $tpl->Variables;
 441
 442        /* We use $setArray to detect if execution failed, and not $text,
 443         * because an empty template does not return any $text and this is not
 444         * an error. */
 445        $setArray = null;
 446        $namespaceStack = array();
 447
 448        $tpl->createLocalVariablesList();
 449        include( eZTemplateCompiler::TemplatePrefix() . $phpScript );
 450        $tpl->unsetLocalVariables();
 451        $tpl->destroyLocalVariablesList();
 452
 453        if ( $setArray !== null )
 454        {
 455            return true;
 456        }
 457        return false;
 458    }
 459
 460    /*!
 461     \static
 462     Generates the cache which will be used for handling optimized processing using the key \a $key.
 463     \note Each call to this will set the PHP time limit to 30
 464     \return false if the cache does not exist.
 465    */
 466    static function compileTemplate( $tpl, $key, &$resourceData )
 467    {
 468        if ( !eZTemplateCompiler::isCompilationEnabled() )
 469            return false;
 470
 471        $resourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
 472
 473        $cacheFileName = eZTemplateCompiler::compilationFilename( $key, $resourceData );
 474        $resourceData['uniqid'] = md5( $resourceData['template-filename']. uniqid( "ezp". getmypid(), true ) );
 475
 476        // Time limit #1:
 477        // We reset the time limit to 30 seconds to ensure that templates
 478        // have enough time to compile
 479        // However if time limit is unlimited (0) we leave it be
 480        // Time limit will also be reset after subtemplates are compiled
 481        $maxExecutionTime = ini_get( 'max_execution_time' );
 482        if ( $maxExecutionTime != 0 && $maxExecutionTime < 30 )
 483        {
 484            @set_time_limit( 30 );
 485        }
 486
 487        $rootNode =& $resourceData['root-node'];
 488        if ( !$rootNode )
 489            return false;
 490
 491        $GLOBALS['eZTemplateCompilerResourceCache'][$resourceData['template-filename']] =& $resourceData;
 492
 493        $useComments = eZTemplateCompiler::isCommentsEnabled();
 494
 495        if ( !$resourceData['test-compile'] )
 496        {
 497            eZTemplateCompiler::createCommonCompileTemplate();
 498        }
 499
 500        /* Check if we need to disable the generation of spacing for the compiled templates */
 501        $ini = eZINI::instance();
 502        $spacing = 'disabled';
 503        if ( $ini->variable( 'TemplateSettings', 'UseFormatting' ) == 'enabled' )
 504        {
 505            $spacing = 'enabled';
 506        }
 507
 508        $php = new eZPHPCreator( eZTemplateCompiler::compilationDirectory(), $cacheFileName,
 509                                 eZTemplateCompiler::TemplatePrefix(), array( 'spacing' => $spacing ) );
 510        $php->addComment( 'URI:       ' . $resourceData['uri'] );
 511        $php->addComment( 'Filename:  ' . $resourceData['template-filename'] );
 512        $php->addComment( 'Timestamp: ' . $resourceData['time-stamp'] . ' (' . date( 'D M j G:i:s T Y', $resourceData['time-stamp'] ) . ')' );
 513
 514        $php->addCodePiece("\$oldSetArray_{$resourceData['uniqid']} = isset( \$setArray ) ? \$setArray : array();\n".
 515                           "\$setArray = array();\n");
 516// Code to decrement include level of the templates
 517        $php->addCodePiece( "\$tpl->Level++;\n" );
 518        $php->addCodePiece( "if ( \$tpl->Level > $tpl->MaxLevel )\n".
 519                            "{\n".
 520                            "\$text = \$tpl->MaxLevelWarning;".
 521                            "\$tpl->Level--;\n".
 522                            "return;\n".
 523                            "}\n" );
 524        if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
 525        {
 526            $php->addComment( 'Locales:   ' . join( ', ', $resourceData['locales'] ) );
 527
 528            $php->addCodePiece(
 529                '$locales = array( "'. join( '", "', $resourceData['locales'] ) . "\" );\n".
 530                '$oldLocale_'. $resourceData['uniqid']. ' = setlocale( LC_CTYPE, null );'. "\n".
 531                '$currentLocale_'. $resourceData['uniqid']. ' = setlocale( LC_CTYPE, $locales );'. "\n"
 532            );
 533        }
 534//         $php->addCodePiece( "print( \"" . $resourceData['template-filename'] . " ($cacheFileName)<br/>\n\" );" );
 535        if ( $useComments )
 536        {
 537            $templateFilename = $resourceData['template-filename'];
 538            if ( file_exists( $templateFilename ) )
 539            {
 540                $fd = fopen( $templateFilename, 'rb' );
 541                if ( $fd )
 542                {
 543                    $templateText = fread( $fd, filesize( $templateFilename ) );
 544                    $php->addComment( "Original code:\n" . $templateText );
 545                    fclose( $fd );
 546                }
 547            }
 548        }
 549        $php->addVariable( 'eZTemplateCompilerCodeDate', eZTemplateCompiler::CODE_DATE );
 550        $php->addCodePiece( "if ( !defined( 'EZ_TEMPLATE_COMPILER_COMMON_CODE' ) )\n" );
 551        $php->addInclude( eZTemplateCompiler::compilationDirectory() . '/common.php', eZPHPCreator::INCLUDE_ONCE_STATEMENT, array( 'spacing' => 4 ) );
 552        $php->addSpace();
 553
 554        if ( eZTemplateCompiler::isAccumulatorsEnabled() )
 555        {
 556            $php->addCodePiece( "eZDebug::accumulatorStart( 'template_compiled_execution', 'template_total', 'Template compiled execution', true );\n" );
 557        }
 558        if ( eZTemplateCompiler::isTimingPointsEnabled() )
 559        {
 560            $php->addCodePiece( "eZDebug::addTimingPoint( 'Script start $cacheFileName' );\n" );
 561        }
 562
 563//         $php->addCodePiece( "if ( !isset( \$vars ) )\n    \$vars =& \$tpl->Variables;\n" );
 564//         $php->addSpace();
 565
 566        $parameters = array();
 567        $textName = eZTemplateCompiler::currentTextName( $parameters );
 568
 569//         $php->addCodePiece( "if ( !isset( \$$textName ) )\n    \$$textName = '';\n" );
 570//         $php->addSpace();
 571
 572//         $variableStats = array();
 573//         eZTemplateCompiler::prepareVariableStatistics( $tpl, $resourceData, $variableStats );
 574//         eZTemplateCompiler::calculateVariableStatistics( $tpl, $rootNode, $resourceData, $variableStats );
 575//         print_r( $variableStats );
 576
 577        $transformedTree = array();
 578        eZTemplateCompiler::processNodeTransformation( $useComments, $php, $tpl, $rootNode, $resourceData, $transformedTree );
 579
 580        if ( $ini->variable( 'TemplateSettings', 'TemplateOptimization' ) == 'enabled' )
 581        {
 582            /* Retrieve class information for the attribute lookup table */
 583            if ( isset( $resourceData['handler']->Keys ) and isset( $resourceData['handler']->Keys['class'] ) ) {
 584                $resourceData['class-info'] = eZTemplateOptimizer::fetchClassDeclaration( $resourceData['handler']->Keys['class'] );
 585            }
 586            /* Run the optimizations */
 587            eZTemplateOptimizer::optimize( $useComments, $php, $tpl, $transformedTree, $resourceData );
 588        }
 589
 590        $staticTree = array();
 591        eZTemplateCompiler::processStaticOptimizations( $useComments, $php, $tpl, $transformedTree, $resourceData, $staticTree );
 592
 593        $combinedTree = array();
 594        eZTemplateCompiler::processNodeCombining( $useComments, $php, $tpl, $staticTree, $resourceData, $combinedTree );
 595
 596        $finalTree = $combinedTree;
 597        if ( !eZTemplateCompiler::isNodePlacementEnabled() )
 598            eZTemplateCompiler::processRemoveNodePlacement( $finalTree );
 599
 600        eZTemplateCompiler::generatePHPCode( $useComments, $php, $tpl, $finalTree, $resourceData );
 601
 602        if ( eZTemplateCompiler::isTreeEnabled( 'final' ) )
 603            $php->addVariable( 'finalTree', $finalTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
 604        if ( eZTemplateCompiler::isTreeEnabled( 'combined' ) )
 605            $php->addVariable( 'combinedTree', $combinedTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
 606        if ( eZTemplateCompiler::isTreeEnabled( 'static' ) )
 607            $php->addVariable( 'staticTree', $staticTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
 608        if ( eZTemplateCompiler::isTreeEnabled( 'transformed' ) )
 609            $php->addVariable( 'transformedTree', $transformedTree, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
 610        if ( eZTemplateCompiler::isTreeEnabled( 'original' ) )
 611            $php->addVariable( 'originalTree', $rootNode, eZPHPCreator::VARIABLE_ASSIGNMENT, array( 'full-tree' => true ) );
 612
 613        if ( eZTemplateCompiler::isTimingPointsEnabled() )
 614            $php->addCodePiece( "eZDebug::addTimingPoint( 'Script end $cacheFileName' );\n" );
 615        if ( eZTemplateCompiler::isAccumulatorsEnabled() )
 616            $php->addCodePiece( "eZDebug::accumulatorStop( 'template_compiled_execution', true );\n" );
 617
 618        if ( $resourceData['locales'] && count( $resourceData['locales'] ) )
 619        {
 620            $php->addCodePiece(
 621                'setlocale( LC_CTYPE, $oldLocale_'. $resourceData['uniqid']. ' );'. "\n"
 622            );
 623        }
 624        $php->addCodePiece('$setArray = $oldSetArray_'. $resourceData['uniqid']. ";\n");
 625
 626// Code to decrement include level of the templates
 627        $php->addCodePiece("\$tpl->Level--;\n" );
 628
 629        /*
 630        // dump names of all defined PHP variables
 631        $php->addCodePiece( "echo \"defined vars in $resourceData[uri]:<br/><pre>\\n\";\n" );
 632        $php->addCodePiece( 'foreach ( array_keys( get_defined_vars() ) as $var_name  ) echo "- $var_name\n";' );
 633        // dump tpl vars
 634        $php->addCodePiece( 'echo "\n-----------------------------------------------------------\nvars: ";' );
 635        $php->addCodePiece( 'var_dump( $vars );' );
 636        $php->addCodePiece( 'echo "</pre><hr/>\n";' );
 637        */
 638
 639        if ( !$resourceData['test-compile'] )
 640        {
 641            $php->store( true );
 642        }
 643
 644        return true;
 645    }
 646
 647    static function prepareVariableStatistics( $tpl, &$resourceData, &$stats )
 648    {
 649//         $path = $resourceData['template-filename'];
 650//         $info =& $GLOBALS['eZTemplateCompileVariableInfo'][$path];
 651        if ( isset( $resourceData['variable-info'] ) )
 652        {
 653        }
 654    }
 655
 656    static function calculateVariableStatistics( $tpl, &$node, &$resourceData, &$stats )
 657    {
 658        $nodeType = $node[0];
 659        if ( $nodeType == eZTemplate::NODE_ROOT )
 660        {
 661            $children = $node[1];
 662            $namespace = '';
 663            if ( $children )
 664            {
 665                eZTemplateCompiler::calculateVariableStatisticsChildren( $tpl, $children, $resourceData, $namespace, $stats );
 666            }
 667        }
 668        else
 669            $tpl->error( 'calculateVariableStatistics', "Unknown root type $nodeType, should be " . eZTemplate::NODE_ROOT );
 670    }
 671
 672    static function calculateVariableStatisticsChildren( $tpl, &$nodeChildren, &$resourceData, $namespace, &$stats )
 673    {
 674        foreach ( $nodeChildren as $node )
 675        {
 676            if ( !isset( $node[0] ) )
 677                continue;
 678            $nodeType = $node[0];
 679            if ( $nodeType == eZTemplate::NODE_ROOT )
 680            {
 681                $children = $node[1];
 682                if ( $children )
 683                {
 684                    eZTemplateCompiler::calculateVariableStatisticsChildren( $tpl, $children, $resourceData, $namespace, $stats );
 685                }
 686            }
 687            else if ( $nodeType == eZTemplate::NODE_TEXT )
 688            {
 689                $text = $node[2];
 690                $placement = $node[3];
 691            }
 692            else if ( $nodeType == eZTemplate::NODE_VARIABLE )
 693            {
 694                $variableData = $node[2];
 695                $variablePlacement = $node[3];
 696                $variableParameters = false;
 697                eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $variableData, $variablePlacement, $resourceData, $namespace, $stats );
 698            }
 699            else if ( $nodeType == eZTemplate::NODE_FUNCTION )
 700            {
 701                $functionChildren = $node[1];
 702                $functionName = $node[2];
 703                $functionParameters = $node[3];
 704                $functionPlacement = $node[4];
 705
 706                if ( !isset( $tpl->Functions[$functionName] ) )
 707                    continue;
 708
 709                if ( is_array( $tpl->Functions[$functionName] ) )
 710                {
 711                    $tpl->loadAndRegisterOperators( $tpl->Functions[$functionName] );
 712                }
 713                $functionObject =& $tpl->Functions[$functionName];
 714                if ( is_object( $functionObject ) )
 715                {
 716                    $hasTransformationSupport = false;
 717                    $transformChildren = true;
 718                    if ( method_exists( $functionObject, 'functionTemplateStatistics' ) )
 719                    {
 720                        $functionObject->functionTemplateStatistics( $functionName, $node, $tpl, $resourceData, $namespace, $stats );
 721                    }
 722                }
 723                else if ( $resourceData['test-compile'] )
 724                {
 725                    $tpl->warning( '', "Operator '$operatorName' is not registered.", $functionPlacement );
 726                }
 727            }
 728        }
 729    }
 730
 731    static function calculateVariableNodeStatistics( $tpl, $variableData, $variablePlacement, &$resourceData, $namespace, &$stats )
 732    {
 733        if ( !is_array( $variableData ) )
 734            return false;
 735        foreach ( $variableData as $variableItem )
 736        {
 737            $variableItemType = $variableItem[0];
 738            $variableItemData = $variableItem[1];
 739            $variableItemPlacement = $variableItem[2];
 740            if ( $variableItemType == eZTemplate::TYPE_STRING or
 741                 $variableItemType == eZTemplate::TYPE_IDENTIFIER )
 742            {
 743            }
 744            else if ( $variableItemType == eZTemplate::TYPE_NUMERIC )
 745            {
 746            }
 747            else if ( $variableItemType == eZTemplate::TYPE_ARRAY )
 748            {
 749            }
 750            else if ( $variableItemType == eZTemplate::TYPE_BOOLEAN )
 751            {
 752            }
 753            else if ( $variableItemType == eZTemplate::TYPE_VARIABLE )
 754            {
 755                $variableNamespace = $variableItemData[0];
 756                $variableNamespaceScope = $variableItemData[1];
 757                $variableName = $variableItemData[2];
 758                if ( $variableNamespaceScope == eZTemplate::NAMESPACE_SCOPE_GLOBAL )
 759                    $newNamespace = $variableNamespace;
 760                else if ( $variableNamespaceScope == eZTemplate::NAMESPACE_SCOPE_LOCAL )
 761                    $newNamespace = $variableNamespace;
 762                else if ( $variableNamespaceScope == eZTemplate::NAMESPACE_SCOPE_RELATIVE )
 763                    $newNamespace = $tpl->mergeNamespace( $namespace, $variableNamespace );
 764                else
 765                    $newNamespace = false;
 766                eZTemplateCompiler::setVariableStatistics( $stats, $newNamespace, $variableName, array( 'is_accessed' => true ) );
 767            }
 768            else if ( $variableItemType == eZTemplate::TYPE_ATTRIBUTE )
 769            {
 770                eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $variableItemData, $variableItemPlacement, $resourceData, $namespace, $stats );
 771            }
 772            else if ( $variableItemType == eZTemplate::TYPE_OPERATOR )
 773            {
 774                $operatorName = $variableItemData[0];
 775
 776                if ( !isset( $tpl->Operators[$operatorName] ) )
 777                    continue;
 778
 779                if ( is_array( $tpl->Operators[$operatorName] ) )
 780                {
 781                    $tpl->loadAndRegisterOperators( $tpl->Operators[$operatorName] );
 782                }
 783                $operator =& $tpl->Operators[$operatorName];
 784
 785                if ( is_object( $operator ) )
 786                {
 787                    $hasStats = false;
 788                    if ( method_exists( $operator, 'operatorTemplateHints' ) )
 789                    {
 790                        $hints = $operator->operatorTemplateHints();
 791                        if ( isset( $hints[$operatorName] ) )
 792                        {
 793                            $operatorHints = $hints[$operatorName];
 794                            $hasParameters = false;
 795                            if ( isset( $operatorHints['parameters'] ) )
 796                                $hasParameters = $operatorHints['parameters'];
 797                            if ( $hasParameters === true )
 798                            {
 799                                $parameters = $variableItemData;
 800                                $count = count( $parameters ) - 1;
 801                                for ( $i = 0; $i < $count; ++$i )
 802                                {
 803                                    $parameter =& $parameters[$i + 1];
 804                                    $parameterData = $parameter[1];
 805                                    $parameterPlacement = $parameter[2];
 806                                    eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $parameter, $parameterPlacement,
 807                                                                                         $resourceData, $namespace, $stats );
 808                                }
 809                            }
 810                            else if ( is_integer( $hasParameters ) )
 811                            {
 812                                $parameters = $variableItemData;
 813                                $count = min( count( $parameters ) - 1, $hasParameters );
 814                                for ( $i = 0; $i < $count; ++$i )
 815                                {
 816                                    $parameter =& $parameters[$i + 1];
 817                                    $parameterData = $parameter[1];
 818                                    $parameterPlacement = $parameter[2];
 819                                    eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $parameter, $parameterPlacement,
 820                                                                                         $resourceData, $namespace, $stats );
 821                                }
 822                            }
 823                            $hasStats = true;
 824                        }
 825                    }
 826                    if ( !$hasStats and method_exists( $operator, 'operatorTemplateStatistics' ) )
 827                    {
 828                        $hasStats = $operator->operatorTemplateStatistics( $operatorName, $variableItem, $variablePlacement, $tpl, $resourceData, $namespace, $stats );
 829                    }
 830                    if ( !$hasStats and method_exists( $operator, 'namedParameterList' ) )
 831                    {
 832                        $namedParameterList = $operator->namedParameterList();
 833                        if ( method_exists( $operator, 'namedParameterPerOperator' ) and
 834                             $operator->namedParameterPerOperator() )
 835                        {
 836                            $namedParameterList = $namedParameterList[$operatorName];
 837                        }
 838                        $operatorParameters = array_slice( $variableItemData, 1 );
 839                        $count = 0;
 840                        foreach ( $namedParameterList as $parameterName => $parameterDefinition )
 841                        {
 842                            $operatorParameter = $operatorParameters[$count];
 843                            eZTemplateCompiler::calculateVariableNodeStatistics( $tpl, $operatorParameter, $variablePlacement, $resourceData, $namespace, $stats );
 844                            ++$count;
 845                        }
 846                        $hasStats = true;
 847                    }
 848                }
 849                else if ( $resourceData['test-compile'] )
 850                {
 851                    $tpl->warning( '', "Operator '$operatorName' is not registered." );
 852                }
 853            }
 854            else if ( $variableItemType == eZTemplate::TYPE_VOID )
 855            {
 856                $tpl->warning( 'TemplateCompiler::calculateOperatorStatistics', "Void datatype should not be used, ignoring it" );
 857            }
 858            else
 859            {
 860                $tpl->warning( 'TemplateCompiler::calculateOperatorStatistics', "Unknown data type $variableItemType, ignoring it" );
 861            }
 862        }
 863        return true;
 864    }
 865
 866    static function setVariableStatistics( &$stats, $namespace, $variableName, $changes )
 867    {
 868        if ( isset( $stats['variables'][$namespace][$variableName] ) )
 869        {
 870            $variableStats =& $stats['variables'][$namespace][$variableName];
 871        }
 872        else
 873        {
 874            $variableStats = array( 'is_accessed' => false,
 875                                    'is_created' => false,
 876                                    'is_modified' => false,
 877                                    'is_removed' => false,
 878                                    'is_local' => false,
 879                                    'is_input' => false,
 880                                    'namespace' => $namespace,
 881                                    'namespace_scope' => false,
 882                                    'type' => false );
 883            $stats['variables'][$namespace][$variableName] =& $variableStats;
 884        }
 885        if ( isset( $changes['invalid_access'] ) and $changes['invalid_access'] !== false )
 886            $variableStats['invalid_access'] = $changes['invalid_access'];
 887        if ( isset( $changes['is_accessed'] ) and $changes['is_accessed'] !== false )
 888            $variableStats['is_accessed'] = $changes['is_accessed'];
 889        if ( isset( $changes['is_created'] ) and $changes['is_created'] !== false )
 890            $variableStats['is_created'] = $changes['is_created'];
 891        if ( isset( $changes['is_modified'] ) and $changes['is_modified'] !== false )
 892            $variableStats['is_modified'] = $changes['is_modified'];
 893        if ( isset( $changes['is_removed'] ) and $changes['is_removed'] !== false )
 894            $variableStats['is_removed'] = $changes['is_removed'];
 895        if ( isset( $changes['is_local'] ) and $changes['is_local'] !== false )
 896            $variableStats['is_local'] = $changes['is_local'];
 897        if ( isset( $changes['is_input'] ) and $changes['is_input'] !== false )
 898            $variableStats['is_input'] = $changes['is_input'];
 899        if ( isset( $changes['namespace'] ) )
 900            $variableStats['namespace'] = $changes['namespace'];
 901        if ( isset( $changes['namespace_scope'] ) )
 902            $variableStats['namespace_scope'] = $changes['namespace_scope'];
 903        if ( isset( $changes['type'] ) )
 904            $variableStats['type'] = $changes['type'];
 905    }
 906
 907    /*!
 908     Iterates over the template node tree and tries to combine multiple static siblings
 909     into one element. The original tree is specified in \a $node and the new
 910     combined tree will be present in \a $newNode.
 911     \sa processNodeCombiningChildren
 912    */
 913    static function processNodeCombining( $useComments, $php, $tpl, &$node, &$resourceData, &$newNode )
 914    {
 915        $nodeType = $node[0];
 916        if ( $nodeType == eZTemplate::NODE_ROOT )
 917        {
 918            $children = $node[1];
 919            $newNode[0] = $nodeType;
 920            $newNode[1] = false;
 921            if ( $children )
 922            {
 923                eZTemplateCompiler::processNodeCombiningChildren( $useComments, $php, $tpl, $children, $resourceData, $newNode );
 924            }
 925        }
 926        else
 927            $tpl->error( 'processNodeCombining', "Unknown root type $nodeType, should be " . eZTemplate::NODE_ROOT );
 928    }
 929
 930    /*!
 931     Does node combining on the children \a $nodeChildren.
 932     \sa processNodeCombining
 933    */
 934    static function processNodeCombiningChildren( $useComments, $php, $tpl, &$nodeChildren, &$resourceData, &$parentNode )
 935    {
 936        $newNodeChildren = array();
 937        $lastNode = false;
 938        foreach ( $nodeChildren as $node )
 939        {
 940            $newNode = false;
 941            if ( !isset( $node[0] ) )
 942                continue;
 943            $nodeType = $node[0];
 944            if ( $nodeType == eZTemplate::NODE_ROOT )
 945            {
 946                $children = $node[1];
 947                $newNode = array( $nodeType,
 948                                  false );
 949                if ( $children )
 950                {
 951                    eZTemplateCompiler::processNodeCombiningChildren( $useComments, $php, $tpl, $children, $resourceData, $newNode );
 952                }
 953            }
 954            else if ( $nodeType == eZTemplate::NODE_TEXT )
 955            {
 956                $text = $node[2];
 957                $placement = $node[3];
 958
 959                $newNode = array( $nodeType,
 960                                  false,
 961                                  $text,
 962                                  $placement );
 963                eZTemplateCompiler::combineStaticNodes( $tpl, $resourceData, $lastNode, $newNode );
 964            }
 965            else if ( $nodeType == eZTemplate::NODE_VARIABLE )
 966            {
 967                $variableCustom = $node[1];
 968                $variableData = $node[2];
 969                $variablePlacement = $node[3];
 970                $variableParameters = false;
 971                $dataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
 972                                                                           $variableData, $variablePlacement,
 973                                                                           $resourceData );
 974                $newNode = $node;
 975                $newNode[1] = $variableCustom;
 976                unset( $dataInspection );
 977                eZTemplateCompiler::combineStaticNodes( $tpl, $resourceData, $lastNode, $newNode );
 978            }
 979            else if ( $nodeType == eZTemplate::NODE_FUNCTION )
 980            {
 981                $functionChildren = $node[1];
 982                $functionName = $node[2];
 983                $functionParameters = $node[3];
 984                $functionPlacement = $node[4];
 985
 986                $newNode = array( $nodeType,
 987                                  false,
 988                                  $functionName,
 989                                  $functionParameters,
 990                                  $functionPlacement );
 991                if ( isset( $node[5] ) )
 992                    $newNode[5] = $node[5];
 993
 994                if ( is_array( $functionChildren ) )
 995                {
 996                    eZTemplateCompiler::processNodeCombiningChildren( $useComments, $php, $tpl,
 997                                                                          $functionChildren, $resourceData, $newNode );
 998                }
 999
1000            }
1001            else
1002                $newNode = $node;
1003            if ( $lastNode != false )
1004            {
1005                $newNodeChildren[] = $lastNode;
1006                $lastNode = false;
1007            }
1008            if ( $newNode != false )
1009                $lastNode = $newNode;
1010        }
1011        if ( $lastNode != false )
1012        {
1013            $newNodeChildren[] = $lastNode;
1014            $lastNode = false;
1015        }
1016        $parentNode[1] = $newNodeChildren;
1017    }
1018
1019    /*!
1020     Tries to combine the node \a $lastNode and the node \a $newNode
1021     into one new text node. If possible the new node is created in \a $newNode
1022     and \a $lastNode will be set to \c false.
1023     Combining nodes only works for text nodes and variable nodes without
1024     variable lookup, attributes and operators.
1025    */
1026    static function combineStaticNodes( $tpl, &$resourceData, &$lastNode, &$newNode )
1027    {
1028        if ( $lastNode == false or
1029             $newNode == false )
1030            return false;
1031        $lastNodeType = $lastNode[0];
1032        $newNodeType = $newNode[0];
1033        if ( !in_array( $lastNodeType, array( eZTemplate::NODE_TEXT,
1034                                              eZTemplate::NODE_VARIABLE ) ) or
1035             !in_array( $newNodeType, array( eZTemplate::NODE_TEXT,
1036                                             eZTemplate::NODE_VARIABLE ) ) )
1037            return false;
1038        if ( $lastNodeType == eZTemplate::NODE_VARIABLE )
1039        {
1040            if ( is_array( $lastNode[1] ) )
1041                return false;
1042            $lastDataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
1043                                                                           $lastNode[2], $lastNode[3],
1044                                                                           $resourceData );
1045            if ( !$lastDataInspection['is-constant'] or
1046                 $lastDataInspection['is-variable'] or
1047                 $lastDataInspection['has-attributes'] or
1048                 $lastDataInspection['has-operators'] )
1049                return false;
1050            if ( isset( $lastNode[4] ) and
1051                 isset( $lastNode[4]['text-result'] ) and
1052                 !$lastNode[4]['text-result'] )
1053                return false;
1054        }
1055        if ( $newNodeType == eZTemplate::NODE_VARIABLE )
1056        {
1057            if ( is_array( $newNode[1] ) )
1058                return false;
1059            $newDataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
1060                                                                          $newNode[2], $newNode[3],
1061                                                                          $resourceData );
1062            if ( !$newDataInspection['is-constant'] or
1063                 $newDataInspection['is-variable'] or
1064                 $newDataInspection['has-attributes'] or
1065                 $newDataInspection['has-operators'] )
1066                return false;
1067            if ( isset( $newNode[4] ) and
1068                 isset( $newNode[4]['text-result'] ) and
1069                 !$newNode[4]['text-result'] )
1070                return false;
1071            if ( isset( $newNode[1] ) and
1072                 $newNode[1] !== false )
1073                return false;
1074        }
1075        $textElements = array();
1076        $lastNodeData = eZTemplateCompiler::staticNodeData( $lastNode );
1077        $newNodeData = eZTemplateCompiler::staticNodeData( $newNode );
1078        $tpl->appendElementText( $textElements, $lastNodeData, false, false );
1079        $tpl->appendElementText( $textElements, $newNodeData, false, false );
1080        $newData = implode( '', $textElements );
1081        $newPlacement = $lastNode[3];
1082        if ( !is_array( $newPlacement ) )
1083        {
1084            $newPlacement = $newNode[3];
1085        }
1086        else
1087        {
1088            $newPlacement[1][0] = $newNode[3][1][0]; // Line end
1089            $newPlacement[1][1] = $newNode[3][1][1]; // Column end
1090            $newPlacement[1][2] = $newNode[3][1][2]; // Position end
1091        }
1092        $lastNode = false;
1093        $newNode = array( eZTemplate::NODE_TEXT,
1094                          false,
1095                          $newData,
1096                          $newPlacement );
1097    }
1098
1099    /*!
1100     \return the static data for the node \a $node or \c false if
1101             no data could be fetched.
1102             Will only return data from text nodes and variables nodes
1103             without variable lookup, attribute lookup or operators.
1104    */
1105    static function staticNodeData( $node )
1106    {
1107        $nodeType = $node[0];
1108        if ( $nodeType == eZTemplate::NODE_TEXT )
1109        {
1110            return $node[2];
1111        }
1112        else if ( $nodeType == eZTemplate::NODE_VARIABLE )
1113        {
1114            $data = $node[2];
1115            if ( is_array( $data ) and
1116                 count( $data ) > 0 )
1117            {
1118                $dataType = $data[0][0];
1119                if ( $dataType == eZTemplate::TYPE_STRING or
1120                     $dataType == eZTemplate::TYPE_NUMERIC or
1121                     $dataType == eZTemplate::TYPE_IDENTIFIER or
1122                     $dataType == eZTemplate::TYPE_ARRAY or
1123                     $dataType == eZTemplate::TYPE_BOOLEAN )
1124                {
1125                    return $data[0][1];
1126                }
1127            }
1128        }
1129        return null;
1130    }
1131
1132    /*!
1133     Iterates over the items in the tree \a $node and tries to extract static data
1134     from operators which supports it.
1135    */
1136    static function processStaticOptimizations( $useComments, $php, $tpl, &$node, &$resourceData, &$newNode )
1137    {
1138        $nodeType = $node[0];
1139        if ( $nodeType == eZTemplate::NODE_ROOT )
1140        {
1141            $children = $node[1];
1142            $newNode[0] = $nodeType;
1143            $newNode[1] = false;
1144            if ( $children )
1145            {
1146                $newNode[1] = array();
1147                foreach ( $children as $child )
1148                {
1149                    $newChild = array();
1150                    eZTemplateCompiler::processStaticOptimizations( $useComments, $php, $tpl, $child, $resourceData, $newChild );
1151                    $newNode[1][] = $newChild;
1152                }
1153            }
1154        }
1155        else if ( $nodeType == eZTemplate::NODE_TEXT )
1156        {
1157            $text = $node[2];
1158            $placement = $node[3];
1159
1160            $newNode[0] = $nodeType;
1161            $newNode[1] = false;
1162            $newNode[2] = $text;
1163            $newNode[3] = $placement;
1164        }
1165        else if ( $nodeType == eZTemplate::NODE_VARIABLE )
1166        {
1167            $variableCustom = $node[1];
1168            $variableData = $node[2];
1169            $variablePlacement = $node[3];
1170            $dataInspection = eZTemplateCompiler::inspectVariableData( $tpl,
1171                                

Large files files are truncated, but you can click here to view the full file