eZ Publish  [trunk]
eztemplatefileresource.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZTemplateFileResource class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  */
00010 
00011 /*!
00012  \class eZTemplateFileResource eztemplatefileresource.php
00013  \brief Handles filesystem retrieval of templates.
00014 
00015  Templates are loaded from the disk and returned to the template system.
00016  The name of the resource is "file:".
00017 */
00018 
00019 class eZTemplateFileResource
00020 {
00021     /*!
00022      Initializes with a default resource name "file".
00023      Also sets whether the resource servers static data files, this is needed
00024      for the cache system.
00025     */
00026     function eZTemplateFileResource( $name = "file", $servesStaticData = true )
00027     {
00028         $this->Name = $name;
00029         $this->ServesStaticData = $servesStaticData;
00030         $this->TemplateCache = array();
00031     }
00032 
00033     /*!
00034      Returns the name of the resource.
00035     */
00036     function resourceName()
00037     {
00038         return $this->Name;
00039     }
00040 
00041     /*
00042      \return true if this resource handler servers static data,
00043      this means that the data can be cached by the template system.
00044     */
00045     function servesStaticData()
00046     {
00047         return $this->ServesStaticData;
00048     }
00049 
00050     function templateNodeTransformation( $functionName, &$node,
00051                                          $tpl, &$resourceData, $parameters, $namespaceValue )
00052     {
00053         if ( $this->Name != 'file' )
00054             return false;
00055         $file = $resourceData['template-name'];
00056         if ( !file_exists( $file ) )
00057             return false;
00058         $newNodes = array();
00059         $newNodes[] = eZTemplateNodeTool::createResourceAcquisitionNode( $resourceData['resource'],
00060                                                                          $file, $file,
00061                                                                          eZTemplate::RESOURCE_FETCH, false,
00062                                                                          $node[4],
00063                                                                          array(),
00064                                                                          $namespaceValue );
00065         return $newNodes;
00066     }
00067 
00068     /*!
00069      Generates a unique key string from the input data and returns it.
00070      The key will be used for storing cached data and retrieving cache files.
00071      When implementing file resource handlers this key must be reimplemented if
00072      the current code does not generate correct keys. However most file based
00073      resource handlers can simple reuse this class.
00074 
00075      Default implementation returns an md5 of the \a $keyData.
00076     */
00077     function cacheKey( $keyData, $res, $templatePath, &$extraParameters )
00078     {
00079         $key = md5( $keyData );
00080         return $key;
00081     }
00082 
00083     /*!
00084      \return the cached node tree for the selected template.
00085     */
00086     function hasCachedProcessTree( $keyData, $uri, $res, $templatePath, &$extraParameters, $timestamp )
00087     {
00088         return false;
00089         $key = $this->cacheKey( $keyData, $res, $templatePath, $extraParameters );
00090         if ( eZTemplateTreeCache::canRestoreCache( $key, $timestamp, $templatePath ) )
00091             eZTemplateTreeCache::restoreCache( $key, $templatePath );
00092         return eZTemplateTreeCache::cachedTree( $key, $uri, $res, $templatePath, $extraParameters );
00093     }
00094 
00095     /*!
00096      Sets the cached node tree for the selected template to \a $root.
00097     */
00098     function compileTemplate( $tpl, $keyData, $uri, $res, $templatePath, &$extraParameters, &$resourceData )
00099     {
00100         $key = $this->cacheKey( $keyData, $res, $templatePath, $extraParameters );
00101         return eZTemplateCompiler::compileTemplate( $tpl, $key, $resourceData );
00102     }
00103 
00104     /*!
00105      Sets the cached node tree for the selected template to \a $root.
00106     */
00107     function executeCompiledTemplate( $tpl, &$textElements,
00108                                       $keyData, $uri, $resourceData, $templatePath,
00109                                       &$extraParameters, $timestamp,
00110                                       $rootNamespace, $currentNamespace )
00111     {
00112         $key = $this->cacheKey( $keyData, $resourceData, $templatePath, $extraParameters );
00113         return eZTemplateCompiler::executeCompilation( $tpl, $textElements, $key, $resourceData,
00114                                                        $rootNamespace, $currentNamespace );
00115     }
00116 
00117     /*!
00118      \return \c true if a compiled template exists for the current request.
00119     */
00120     function hasCompiledTemplate( $keyData, $uri, &$resourceData, $templatePath, &$extraParameters, $timestamp )
00121     {
00122         $key = $this->cacheKey( $keyData, $resourceData, $templatePath, $extraParameters );
00123         return eZTemplateCompiler::hasCompiledTemplate( $key, $timestamp, $resourceData );
00124     }
00125 
00126     /*!
00127      \return \c true if a compiled template can be generated for this request.
00128     */
00129     function canCompileTemplate( $tpl, &$resourceData, &$extraParameters )
00130     {
00131         return eZTemplateCompiler::isCompilationEnabled();
00132     }
00133 
00134     /*!
00135      \return the cached node tree for the selected template.
00136     */
00137     function cachedTemplateTree( $keyData, $uri, $res, $templatePath, &$extraParameters, $timestamp )
00138     {
00139         $key = $this->cacheKey( $keyData, $res, $templatePath, $extraParameters );
00140         if ( eZTemplateTreeCache::canRestoreCache( $key, $timestamp, $templatePath ) )
00141             eZTemplateTreeCache::restoreCache( $key, $templatePath );
00142         return eZTemplateTreeCache::cachedTree( $key, $uri, $res, $templatePath, $extraParameters );
00143     }
00144 
00145     /*!
00146      Sets the cached node tree for the selected template to \a $root.
00147     */
00148     function setCachedTemplateTree( $keyData, $uri, $res, $templatePath, &$extraParameters, &$root )
00149     {
00150         $key = $this->cacheKey( $keyData, $res, $templatePath, $extraParameters );
00151         eZTemplateTreeCache::setCachedTree( $key, $uri, $res, $templatePath, $extraParameters, $root );
00152         eZTemplateTreeCache::storeCache( $key, $templatePath );
00153     }
00154 
00155     /*!
00156      Loads the template file if it exists, also sets the modification timestamp.
00157      Returns true if the file exists.
00158     */
00159     function handleResource( $tpl, &$resourceData, $method, &$extraParameters )
00160     {
00161         return $this->handleResourceData( $tpl, $this, $resourceData, $method, $extraParameters );
00162     }
00163 
00164     /*!
00165      \static
00166      Reusable function for handling file based loading.
00167      Call this with the resource handler object in \a $handler.
00168      It will load the template file and handle any charsets conversion if necessary.
00169      It will also handle tree node caching if one is found.
00170     */
00171     function handleResourceData( $tpl, $handler, &$resourceData, $method, &$extraParameters )
00172     {
00173         // &$templateRoot, &$text, &$tstamp, $uri, $resourceName, &$path, &$keyData
00174         $templateRoot =& $resourceData['root-node'];
00175         $text =& $resourceData['text'];
00176         $tstamp =& $resourceData['time-stamp'];
00177         $uri =& $resourceData['uri'];
00178         $resourceName =& $resourceData['resource'];
00179         $path =& $resourceData['template-filename'];
00180         $keyData =& $resourceData['key-data'];
00181         $localeData =& $resourceData['locales'];
00182 
00183         if ( !file_exists( $path ) )
00184             return false;
00185         $tstamp = filemtime( $path );
00186         $result = false;
00187         $canCache = true;
00188         $templateRoot = null;
00189         if ( !$handler->servesStaticData() )
00190             $canCache = false;
00191         if ( !$tpl->isCachingAllowed() )
00192             $canCache = false;
00193         $keyData = 'file:' . $path;
00194         if ( $method == eZTemplate::RESOURCE_FETCH )
00195         {
00196             if ( $canCache )
00197             {
00198                 if ( $handler->hasCompiledTemplate( $keyData, $uri, $resourceData, $path, $extraParameters, $tstamp ) )
00199                 {
00200                     $resourceData['compiled-template'] = true;
00201                     return true;
00202                 }
00203             }
00204             if ( $canCache )
00205                 $templateRoot = $handler->cachedTemplateTree( $keyData, $uri, $resourceName, $path, $extraParameters, $tstamp );
00206 
00207             if ( $templateRoot !== null )
00208                 return true;
00209 
00210             if ( is_readable( $path ) )
00211             {
00212                 $text = file_get_contents( $path );
00213                 $text = preg_replace( "/\n|\r\n|\r/", "\n", $text );
00214                 $tplINI = $tpl->ini();
00215                 $charset = $tplINI->variable( 'CharsetSettings', 'DefaultTemplateCharset' );
00216                 $locales = array();
00217                 $pos = strpos( $text, "\n" );
00218                 if ( $pos !== false )
00219                 {
00220                     $line = substr( $text, 0, $pos );
00221                     if ( preg_match( "/^\{\*\?template(.+)\?\*\}/", $line, $tpl_arr ) )
00222                     {
00223                         $args = explode( " ", trim( $tpl_arr[1] ) );
00224                         foreach ( $args as $arg )
00225                         {
00226                             $vars = explode( '=', trim( $arg ) );
00227                             switch ( $vars[0] ) {
00228                                 case 'charset': {
00229                                     $val = $vars[1];
00230                                     if ( $val[0] == '"' and
00231                                          strlen( $val ) > 0 and
00232                                          $val[strlen($val)-1] == '"' )
00233                                     {
00234                                         $val = substr( $val, 1, strlen($val) - 2 );
00235                                     }
00236                                     $charset = $val;
00237                                 } break;
00238                                 case 'locale': {
00239                                     $val = $vars[1];
00240                                     if ( $val[0] == '"' and
00241                                          strlen( $val ) > 0 and
00242                                          $val[strlen($val)-1] == '"' )
00243                                     {
00244                                         $val = substr( $val, 1, strlen($val) - 2 );
00245                                     }
00246                                     $locales = explode( ',', $val );
00247                                 } break;
00248                             }
00249                         }
00250                     }
00251                 }
00252 
00253                 /* Setting locale to allow standard PHP functions to handle
00254                  * strtoupper/lower() */
00255                 $defaultLocale = trim( $tplINI->variable( 'CharsetSettings', 'DefaultTemplateLocale' ) );
00256                 if ( $defaultLocale != '' )
00257                 {
00258                     $locales = array_merge( $locales, explode( ',', $defaultLocale ) );
00259                 }
00260                 $localeData = $locales;
00261                 if ( $locales && count( $locales ) )
00262                 {
00263                     setlocale( LC_CTYPE, $locales );
00264                 }
00265 
00266                 if ( eZTemplate::isDebugEnabled() )
00267                     eZDebug::writeNotice( "$path, $charset" );
00268                 $codec = eZTextCodec::instance( $charset, false, false );
00269                 if ( $codec )
00270                 {
00271                     eZDebug::accumulatorStart( 'template_resource_conversion', 'template_total', 'String conversion in template resource' );
00272                     $text = $codec->convertString( $text );
00273                     eZDebug::accumulatorStop( 'template_resource_conversion' );
00274                 }
00275                 $result = true;
00276             }
00277         }
00278         else if ( $method == eZTemplate::RESOURCE_QUERY )
00279             $result = true;
00280         return $result;
00281     }
00282 
00283     /// \privatesection
00284     /// The name of the resource
00285     public $Name;
00286     /// True if the data served from this resource is static, ie it can be cached properly
00287     public $ServesStaticData;
00288     /// The cache for templates
00289     public $TemplateCache;
00290 }
00291 
00292 ?>