|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZTemplateCacheFunction class 00004 // 00005 // Created on: <28-Feb-2003 15:06:33 bf> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 \class eZTemplateCacheFunction eztemplatecachefunction.php 00033 \ingroup eZTemplateFunctions 00034 \brief Advanced cache handling 00035 00036 */ 00037 00038 //include_once( 'lib/eztemplate/classes/eztemplatecacheblock.php' ); 00039 00040 class eZTemplateCacheFunction 00041 { 00042 const DEFAULT_TTL = 7200; // 2 hours = 60*60*2 00043 00044 /*! 00045 Initializes the object with names. 00046 */ 00047 function eZTemplateCacheFunction( $blockName = 'cache-block' ) 00048 { 00049 $this->BlockName = $blockName; 00050 } 00051 00052 /*! 00053 Returns an array containing the name of the block function, default is "block". 00054 The name is specified in the constructor. 00055 */ 00056 function functionList() 00057 { 00058 return array( $this->BlockName ); 00059 } 00060 00061 function functionTemplateHints() 00062 { 00063 return array( $this->BlockName => array( 'parameters' => true, 00064 'static' => false, 00065 'transform-children' => true, 00066 'tree-transformation' => true, 00067 'transform-parameters' => true ) ); 00068 } 00069 00070 function templateNodeTransformation( $functionName, &$node, 00071 $tpl, $parameters, $privateData ) 00072 { 00073 $ini = eZINI::instance(); 00074 $children = eZTemplateNodeTool::extractFunctionNodeChildren( $node ); 00075 if ( $ini->variable( 'TemplateSettings', 'TemplateCache' ) != 'enabled' ) 00076 { 00077 return $children; 00078 } 00079 00080 $functionPlacement = eZTemplateNodeTool::extractFunctionNodePlacement( $node ); 00081 $placementKeyString = eZTemplateCacheBlock::placementString( $functionPlacement ); 00082 00083 $newNodes = array(); 00084 $ignoreContentExpiry = false; 00085 00086 if ( isset( $parameters['expiry'] ) ) 00087 { 00088 if ( eZTemplateNodeTool::isStaticElement( $parameters['expiry'] ) ) 00089 { 00090 $expiryValue = eZTemplateNodeTool::elementStaticValue( $parameters['expiry'] ); 00091 $ttlCode = $expiryValue > 0 ? eZPHPCreator::variableText( $expiryValue , 0, 0, false ) : 'null'; 00092 } 00093 else 00094 { 00095 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $parameters['expiry'], false, array(), 'localExpiry' ); 00096 $ttlCode = "( \$localExpiry > 0 ? \$localExpiry : null )"; 00097 } 00098 } 00099 else 00100 { 00101 $ttlCode = eZPHPCreator::variableText( self::DEFAULT_TTL, 0, 0, false ); 00102 } 00103 00104 if ( isset( $parameters['ignore_content_expiry'] ) ) 00105 { 00106 $ignoreContentExpiry = eZTemplateNodeTool::elementStaticValue( $parameters['ignore_content_expiry'] ); 00107 } 00108 00109 $keysData = false; 00110 $hasKeys = false; 00111 $subtreeExpiryData = null; 00112 $subtreeValue = null; 00113 if ( isset( $parameters['keys'] ) ) 00114 { 00115 $keysData = $parameters['keys']; 00116 $hasKeys = true; 00117 } 00118 if ( isset( $parameters['subtree_expiry'] ) ) 00119 { 00120 $subtreeExpiryData = $parameters['subtree_expiry']; 00121 if ( !eZTemplateNodeTool::isStaticElement( $subtreeExpiryData ) ) 00122 $hasKeys = true; 00123 else 00124 $subtreeValue = eZTemplateNodeTool::elementStaticValue( $subtreeExpiryData ); 00125 00126 $ignoreContentExpiry = true; 00127 } 00128 $accessName = false; 00129 if ( isset( $GLOBALS['eZCurrentAccess']['name'] ) ) 00130 $accessName = $GLOBALS['eZCurrentAccess']['name']; 00131 if ( $hasKeys ) 00132 { 00133 $placementKeyStringText = eZPHPCreator::variableText( $placementKeyString, 0, 0, false ); 00134 $accessNameText = eZPHPCreator::variableText( $accessName, 0, 0, false ); 00135 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $keysData, false, array(), 'cacheKeys' ); 00136 $newNodes[] = eZTemplateNodeTool::createVariableNode( false, $subtreeExpiryData, false, array(), 'subtreeExpiry' ); 00137 00138 $code = ( "//include_once( 'lib/eztemplate/classes/eztemplatecacheblock.php' );\n" . 00139 "\$cacheKeys = array( \$cacheKeys, $placementKeyStringText, $accessNameText );\n" ); 00140 $cachePathText = "\$cachePath"; 00141 } 00142 else 00143 { 00144 $nodeID = $subtreeValue ? eZTemplateCacheBlock::decodeNodeID( $subtreeValue ) : false; 00145 $cachePath = eZTemplateCacheBlock::cachePath( eZTemplateCacheBlock::keyString( array( $placementKeyString, $accessName ) ), $nodeID ); 00146 $code = ( "//include_once( 'lib/eztemplate/classes/eztemplatecacheblock.php' );\n" ); 00147 $cachePathText = eZPHPCreator::variableText( $cachePath, 0, 0, false ); 00148 } 00149 00150 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code ); 00151 00152 $code = ''; 00153 00154 $codePlacementHash = md5( $placementKeyString ); 00155 if ( $hasKeys ) 00156 { 00157 $code .= "list(\$cacheHandler_{$codePlacementHash}, \$contentData) =\n eZTemplateCacheBlock::retrieve( \$cacheKeys, \$subtreeExpiry, $ttlCode, " . ($ignoreContentExpiry ? "false" : "true") . " );\n"; 00158 } 00159 else 00160 { 00161 $nodeIDText = var_export( $nodeID, true ); 00162 $code .= "list(\$cacheHandler_{$codePlacementHash}, \$contentData) =\n eZTemplateCacheBlock::handle( $cachePathText, $nodeIDText, $ttlCode, " . ($ignoreContentExpiry ? "false" : "true") . " );\n"; 00163 } 00164 $code .= 00165 "if ( !( \$contentData instanceof eZClusterFileFailure ) )\n" . 00166 "{\n"; 00167 00168 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code, array( 'spacing' => 0 ) ); 00169 $newNodes[] = eZTemplateNodeTool::createWriteToOutputVariableNode( 'contentData', array( 'spacing' => 4 ) ); 00170 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( " unset( \$contentData );\n" . 00171 "}\n" . 00172 "else\n" . 00173 "{\n" . 00174 " unset( \$contentData );" ); 00175 00176 $newNodes[] = eZTemplateNodeTool::createOutputVariableIncreaseNode( array( 'spacing' => 4 ) ); 00177 $newNodes[] = eZTemplateNodeTool::createSpacingIncreaseNode( 4 ); 00178 $newNodes = array_merge( $newNodes, $children ); 00179 $newNodes[] = eZTemplateNodeTool::createSpacingDecreaseNode( 4 ); 00180 $newNodes[] = eZTemplateNodeTool::createAssignFromOutputVariableNode( 'cachedText', array( 'spacing' => 4 ) ); 00181 00182 $code = 00183 "\$cacheHandler_{$codePlacementHash}->storeCache( array( 'scope' => 'template-block', 'binarydata' => \$cachedText ) );\n"; 00184 00185 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( $code, array( 'spacing' => 4 ) ); 00186 $newNodes[] = eZTemplateNodeTool::createOutputVariableDecreaseNode( array( 'spacing' => 4 ) ); 00187 $newNodes[] = eZTemplateNodeTool::createWriteToOutputVariableNode( 'cachedText', array( 'spacing' => 4 ) ); 00188 $newNodes[] = eZTemplateNodeTool::createCodePieceNode( " unset( \$cachedText, \$cacheHandler_{$codePlacementHash} );\n}\n" ); 00189 00190 return $newNodes; 00191 } 00192 00193 /*! 00194 Processes the function with all it's children. 00195 */ 00196 function process( $tpl, &$textElements, $functionName, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace ) 00197 { 00198 switch ( $functionName ) 00199 { 00200 case $this->BlockName: 00201 { 00202 // Check for disabled cache. 00203 $ini = eZINI::instance(); 00204 if ( $ini->variable( 'TemplateSettings', 'TemplateCache' ) != 'enabled' ) 00205 { 00206 $text = eZTemplateCacheFunction::processUncached( $tpl, $functionChildren, 00207 $rootNamespace, $currentNamespace ); 00208 $textElements[] = $text; 00209 return; 00210 } 00211 else 00212 { 00213 $text = eZTemplateCacheFunction::processCachedPreprocess( $tpl, $functionChildren, 00214 $functionParameters, $functionPlacement, 00215 $rootNamespace, $currentNamespace ); 00216 $textElements[] = $text; 00217 } 00218 } break; 00219 } 00220 } 00221 00222 function processCachedPreprocess( $tpl, $functionChildren, $functionParameters, $functionPlacement, $rootNamespace, $currentNamespace ) 00223 { 00224 $keys = null; 00225 $subtreeExpiry = null; 00226 $expiry = self::DEFAULT_TTL; 00227 $ignoreContentExpiry = null; 00228 $subtreeExpiry = null; 00229 00230 if ( isset( $functionParameters["keys"] ) ) 00231 { 00232 $keys = $tpl->elementValue( $functionParameters["keys"], $rootNamespace, $currentNamespace, $functionPlacement ); 00233 } 00234 if ( isset( $functionParameters['subtree_expiry'] ) ) 00235 { 00236 $subtreeExpiry = $tpl->elementValue( $functionParameters["subtree_expiry"], $rootNamespace, $currentNamespace, $functionPlacement ); 00237 } 00238 if ( isset( $functionParameters["expiry"] ) ) 00239 { 00240 $expiry = $tpl->elementValue( $functionParameters["expiry"], $rootNamespace, $currentNamespace, $functionPlacement ); 00241 } 00242 if ( isset( $functionParameters["ignore_content_expiry"] ) ) 00243 { 00244 $ignoreContentExpiry = $tpl->elementValue( $functionParameters["ignore_content_expiry"], $rootNamespace, $currentNamespace, $functionPlacement ) === true; 00245 } 00246 if ( isset( $functionParameters['subtree_expiry'] ) ) 00247 { 00248 $ignoreContentExpiry = true; 00249 } 00250 00251 $placementString = eZTemplateCacheBlock::placementString( $functionPlacement ); 00252 00253 return eZTemplateCacheFunction::processCached( $tpl, $functionChildren, $rootNamespace, $currentNamespace, 00254 $placementString, $keys, $subtreeExpiry, $expiry, $ignoreContentExpiry ); 00255 } 00256 00257 function processCached( $tpl, $functionChildren, $rootNamespace, $currentNamespace, 00258 $placementString, $keys, $subtreeExpiry, $expiry, $ignoreContentExpiry ) 00259 { 00260 // Fetch the current siteaccess 00261 $accessName = false; 00262 if ( isset( $GLOBALS['eZCurrentAccess']['name'] ) ) 00263 $accessName = $GLOBALS['eZCurrentAccess']['name']; 00264 if ( $keys === null ) 00265 { 00266 $keyArray = array( $placementString, $accessName ); 00267 } 00268 else 00269 { 00270 $keyArray = array( $keys, $placementString, $accessName ); 00271 } 00272 00273 $nodeID = $subtreeExpiry ? eZTemplateCacheBlock::decodeNodeID( $subtreeExpiry ) : false; 00274 $phpPath = eZTemplateCacheBlock::cachePath( eZTemplateCacheBlock::keyString( $keyArray ), $nodeID ); 00275 00276 $ttl = $expiry > 0 ? $expiry : null; 00277 00278 if ( $subtreeExpiry !== null ) 00279 { 00280 $ignoreContentExpiry = true; 00281 } 00282 else if ( $ignoreContentExpiry === null ) 00283 { 00284 $ignoreContentExpiry = false; 00285 } 00286 00287 $globalExpiryTime = -1; 00288 eZExpiryHandler::registerShutdownFunction(); 00289 if ( $ignoreContentExpiry == false ) 00290 { 00291 $globalExpiryTime = eZExpiryHandler::getTimestamp( 'template-block-cache', -1 ); 00292 } 00293 $globalExpiryTime = max( eZExpiryHandler::getTimestamp( 'global-template-block-cache', -1 ), // This expiry value is the true global expiry for cache-blocks 00294 $globalExpiryTime ); 00295 00296 // Check if we can restore 00297 require_once( 'kernel/classes/ezclusterfilehandler.php' ); 00298 $cacheFile = eZClusterFileHandler::instance( $phpPath ); 00299 $args = array( "tpl" => $tpl, 00300 "functionChildren" => $functionChildren, 00301 "rootNamespace" => $rootNamespace, 00302 "currentNamespace" => $currentNamespace ); 00303 return $cacheFile->processCache( array( 'eZTemplateCacheBlock', 'retrieveContent' ), 00304 array( $this, 'generateProcessedContent' ), 00305 $ttl, 00306 $globalExpiryTime, 00307 $args ); 00308 } 00309 00310 function generateProcessedContent( $fname, $args ) 00311 { 00312 extract( $args ); 00313 $content = eZTemplateCacheFunction::processUncached( $tpl, $functionChildren, $rootNamespace, $currentNamespace ); 00314 return array( 'scope' => 'template-block', 00315 'content' => $content, 00316 'binarydata' => $content ); 00317 } 00318 00319 /*! 00320 \private 00321 \static 00322 Performs processing of the cache-block using the non-compiled way and with caching off. 00323 */ 00324 function processUncached( $tpl, $functionChildren, $rootNamespace, $currentNamespace ) 00325 { 00326 $children = $functionChildren; 00327 00328 $childTextElements = array(); 00329 if ( is_array( $children ) ) 00330 { 00331 foreach ( array_keys( $children ) as $childKey ) 00332 { 00333 $child =& $children[$childKey]; 00334 $tpl->processNode( $child, $childTextElements, $rootNamespace, $currentNamespace ); 00335 } 00336 } 00337 $text = implode( '', $childTextElements ); 00338 return $text; 00339 } 00340 00341 /*! 00342 Returns true. 00343 */ 00344 function hasChildren() 00345 { 00346 return true; 00347 } 00348 00349 // Deprecated functions follow 00350 00351 /*! 00352 \static 00353 \deprecated 00354 Returns base directory where 'subtree_expiry' caches are stored. 00355 */ 00356 static function subtreeCacheBaseSubDir() 00357 { 00358 return eZTemplateCacheBlock::subtreeCacheBaseSubDir(); 00359 } 00360 00361 /*! 00362 \static 00363 \deprecated Does not seem to be used 00364 Returns base directory where expired 'subtree_expiry' caches are stored. 00365 */ 00366 static function expiryTemplateBlockCacheDir() 00367 { 00368 //include_once( 'lib/ezutils/classes/ezsys.php' ); 00369 $expiryCacheDir = eZSys::cacheDirectory() . '/' . 'template-block-expiry'; 00370 return $expiryCacheDir; 00371 } 00372 00373 /*! 00374 \static 00375 \deprecated 00376 Returns base directory where template block caches are stored. 00377 */ 00378 static function templateBlockCacheDir() 00379 { 00380 return eZTemplateCacheBlock::templateBlockCacheDir(); 00381 } 00382 00383 /*! 00384 \static 00385 \deprecated 00386 Returns path of the directory where 'subtree_expiry' caches are stored. 00387 */ 00388 static function subtreeCacheSubDir( $subtreeExpiryParameter, $cacheFilename ) 00389 { 00390 return eZTemplateCacheBlock::subtreeCacheSubDir( $subtreeExpiryParameter, $cacheFilename ); 00391 } 00392 00393 /*! 00394 \static 00395 \deprecated 00396 Builds and returns path from $nodeID, e.g. if $nodeID = 23 then path = subtree/2/3 00397 */ 00398 static function subtreeCacheSubDirForNode( $nodeID ) 00399 { 00400 return eZTemplateCacheBlock::subtreeCacheSubDirForNode( $nodeID ); 00401 } 00402 00403 /// \privatesection 00404 /// Name of the function 00405 public $BlockName; 00406 } 00407 00408 ?>