eZ Publish  [4.0]
ezcontentcache.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZContentCache class
00004 //
00005 // Created on: <12-Dec-2002 16:53:41 amos>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*! \file ezcontentcache.php
00032 */
00033 
00034 /*!
00035   \class eZContentCache ezcontentcache.php
00036   \brief The class eZContentCache does
00037 
00038 */
00039 
00040 //include_once( 'lib/ezutils/classes/ezsys.php' );
00041 //include_once( "lib/ezfile/classes/ezdir.php" );
00042 
00043 class eZContentCache
00044 {
00045     // The timestamp for the cache format, will expire
00046     // cache which differs from this.
00047     const CODE_DATE = 1064816011;
00048 
00049     static function cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList, $layout, $cacheTTL = false,
00050                             $parameters = array() )
00051     {
00052         $md5Input = array( $nodeID, $viewMode, $language );
00053         $md5Input[] = $offset;
00054         $md5Input = array_merge( $md5Input, $layout );
00055         sort( $roleList );
00056         $md5Input = array_merge( $md5Input, $roleList );
00057         sort( $discountList );
00058         $md5Input = array_merge( $md5Input, $discountList );
00059         if ( $cacheTTL == true )
00060             $md5Input = array_merge( $md5Input, "cache_ttl" );
00061         if ( isset( $parameters['view_parameters'] ) )
00062         {
00063             $viewParameters = $parameters['view_parameters'];
00064             ksort( $viewParameters );
00065             foreach ( $viewParameters as $viewParameterName => $viewParameter )
00066             {
00067                 if ( !$viewParameter )
00068                     continue;
00069                 $md5Input = array_merge( $md5Input, 'vp:' . $viewParameterName . '=' . $viewParameter );
00070             }
00071         }
00072         $md5Text = md5( implode( '-', $md5Input ) );
00073         $cacheFile = $nodeID . '-' . $md5Text . '.cache';
00074         $extraPath = eZDir::filenamePath( "$nodeID" );
00075         $ini = eZINI::instance();
00076         $currentSiteAccess = $GLOBALS['eZCurrentAccess']['name'];
00077         $cacheDir = eZDir::path( array( eZSys::cacheDirectory(), $ini->variable( 'ContentSettings', 'CacheDir' ), $currentSiteAccess, $extraPath ) );
00078         $cachePath = eZDir::path( array( $cacheDir, $cacheFile ) );
00079         return array( 'dir' => $cacheDir,
00080                       'file' => $cacheFile,
00081                       'path' => $cachePath );
00082     }
00083 
00084     static function exists( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList, $layout,
00085                      $parameters = array() )
00086     {
00087         $cachePathInfo = eZContentCache::cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList,
00088                                                         $layout, false, $parameters );
00089         require_once( 'kernel/classes/ezclusterfilehandler.php' );
00090         $cacheFile = eZClusterFileHandler::instance( $cachePathInfo['path'] );
00091 
00092         if ( $cacheFile->exists() )
00093         {
00094             $timestamp = $cacheFile->mtime();
00095             //include_once( 'kernel/classes/ezcontentobject.php' );
00096             if ( eZContentObject::isCacheExpired( $timestamp ) )
00097             {
00098                 eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache expired #1' );
00099                 return false;
00100             }
00101             eZDebugSetting::writeDebug( 'kernel-content-view-cache', "checking viewmode '$viewMode' #1" );
00102             if ( eZContentObject::isComplexViewModeCacheExpired( $viewMode, $timestamp ) )
00103             {
00104                 eZDebugSetting::writeDebug( 'kernel-content-view-cache', "viewmode '$viewMode' cache expired #1" );
00105                 return false;
00106             }
00107 
00108             return true;
00109         }
00110 
00111         eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache used #1' );
00112         return false;
00113     }
00114 
00115     static function restore( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList, $layout,
00116                       $parameters = array() )
00117     {
00118         $result = array();
00119         $cachePathInfo = eZContentCache::cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList,
00120                                                         $layout, false, $parameters );
00121         $cacheDir = $cachePathInfo['dir'];
00122         $cacheFile = $cachePathInfo['file'];
00123         $cachePath = $cachePathInfo['path'];
00124         $timestamp = false;
00125 
00126         require_once( 'kernel/classes/ezclusterfilehandler.php' );
00127         $cacheFile = eZClusterFileHandler::instance( $cachePath );
00128 
00129         if ( $cacheFile->exists() )
00130         {
00131             $timestamp = $cacheFile->mtime();
00132             //include_once( 'kernel/classes/ezcontentobject.php' );
00133             if ( eZContentObject::isCacheExpired( $timestamp ) )
00134             {
00135                 eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache expired #2' );
00136                 return false;
00137             }
00138             eZDebugSetting::writeDebug( 'kernel-content-view-cache', "checking viewmode '$viewMode' #1" );
00139             if ( eZContentObject::isComplexViewModeCacheExpired( $viewMode, $timestamp ) )
00140             {
00141                 eZDebugSetting::writeDebug( 'kernel-content-view-cache', "viewmode '$viewMode' cache expired #2" );
00142                 return false;
00143             }
00144 
00145         }
00146 
00147         if ( $viewMode == 'pdf' )
00148         {
00149             return $cachePath;
00150         }
00151 
00152         eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache used #2' );
00153 
00154         $fileName = $cacheDir . "/" . $cacheFile;
00155 
00156         $cacheFile = eZClusterFileHandler::instance( $fileName );
00157         $contents = $cacheFile->fetchContents();
00158 
00159         $cachedArray = unserialize( $contents );
00160 
00161         $cacheTTL = $cachedArray['cache_ttl'];
00162 
00163         // Check if cache has expired
00164         if ( $cacheTTL > 0 )
00165         {
00166             $expiryTime = $timestamp + $cacheTTL;
00167             if ( time() > $expiryTime )
00168             {
00169                 return false;
00170             }
00171         }
00172 
00173         // Check for template language timestamp
00174         $cacheCodeDate = $cachedArray['cache_code_date'];
00175         if ( $cacheCodeDate != self::CODE_DATE )
00176             return false;
00177 
00178         $viewMode = $cachedArray['content_info']['viewmode'];
00179 
00180         $res = eZTemplateDesignResource::instance();
00181         $res->setKeys( array( array( 'node', $nodeID ),
00182                               array( 'view_offset', $offset ),
00183                               array( 'viewmode', $viewMode )
00184                               ) );
00185         $result['content_info'] = $cachedArray['content_info'];
00186         $result['content'] = $cachedArray['content'];
00187 
00188         $result['view_parameters'] = $cachedArray['content_info']['view_parameters'];
00189 
00190         foreach ( array( 'path', 'node_id', 'section_id', 'navigation_part' ) as $item )
00191         {
00192             if ( isset( $cachedArray[$item] ) )
00193             {
00194                 $result[$item] = $cachedArray[$item];
00195             }
00196         }
00197 
00198         // set section id
00199         //include_once( 'kernel/classes/ezsection.php' );
00200         eZSection::setGlobalID( $cachedArray['section_id'] );
00201         return $result;
00202     }
00203 
00204     static function store( $siteDesign, $objectID, $classID, $classIdentifier,
00205                     $nodeID, $parentNodeID, $nodeDepth, $urlAlias, $viewMode, $sectionID,
00206                     $language, $offset, $roleList, $discountList, $layout, $navigationPartIdentifier,
00207                     $result, $cacheTTL = -1,
00208                     $parameters = array() )
00209     {
00210         $cachePathInfo = eZContentCache::cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList,
00211                                                         $layout, false, $parameters );
00212         $cacheDir = $cachePathInfo['dir'];
00213         $cacheFile = $cachePathInfo['file'];
00214 
00215         $serializeArray = array();
00216 
00217         if ( isset( $parameters['view_parameters']['offset'] ) )
00218         {
00219             $offset = $parameters['view_parameters']['offset'];
00220         }
00221         $viewParameters = false;
00222         if ( isset( $parameters['view_parameters'] ) )
00223         {
00224             $viewParameters = $parameters['view_parameters'];
00225         }
00226         $contentInfo = array( 'site_design' => $siteDesign,
00227                               'node_id' => $nodeID,
00228                               'parent_node_id' => $parentNodeID,
00229                               'node_depth' => $nodeDepth,
00230                               'url_alias' => $urlAlias,
00231                               'object_id' => $objectID,
00232                               'class_id' => $classID,
00233                               'class_identifier' => $classIdentifier,
00234                               'navigation_part' => $navigationPartIdentifier,
00235                               'viewmode' => $viewMode,
00236                               'language' => $language,
00237                               'offset' => $offset,
00238                               'view_parameters' => $viewParameters,
00239                               'role_list' => $roleList,
00240                               'discount_list' => $discountList,
00241                               'section_id' => $result['section_id'] );
00242 
00243         $serializeArray['content_info'] = $contentInfo;
00244 
00245         foreach ( array( 'path', 'node_id', 'section_id', 'navigation_part' ) as $item )
00246         {
00247             if ( isset( $result[$item] ) )
00248             {
00249                 $serializeArray[$item] = $result[$item];
00250             }
00251         }
00252 
00253         $serializeArray['cache_ttl'] = $cacheTTL;
00254 
00255         $serializeArray['cache_code_date'] = self::CODE_DATE;
00256         $serializeArray['content'] = $result['content'];
00257 
00258         $serializeString = serialize( $serializeArray );
00259 
00260         if ( !file_exists( $cacheDir ) )
00261         {
00262             //include_once( 'lib/ezfile/classes/ezdir.php' );
00263             eZDir::mkdir( $cacheDir, false, true );
00264         }
00265 
00266         $path = $cacheDir . '/' . $cacheFile;
00267         $uniqid = md5( uniqid( 'ezpcache'. getmypid(), true ) );
00268 
00269         require_once( 'kernel/classes/ezclusterfilehandler.php' );
00270         $file = eZClusterFileHandler::instance( "$cacheDir/$uniqid" );
00271         $file->storeContents( $serializeString, 'viewcache', 'pdf' );
00272         $file->move( $path );
00273 
00274         return true;
00275     }
00276 
00277     static function calculateCleanupValue( $nodeCount )
00278     {
00279         return $nodeCount;
00280     }
00281 
00282     static function inCleanupThresholdRange( $value )
00283     {
00284         $ini = eZINI::instance();
00285         $threshold = $ini->variable( 'ContentSettings', 'CacheThreshold' );
00286         return ( $value < $threshold );
00287     }
00288 
00289     static function cleanup( $nodeList )
00290     {
00291         // The view-cache has a different storage structure than before:
00292         // var/cache/content/<siteaccess>/<extra-path>/<nodeID>-<hash>.cache
00293         // Also it uses the cluster file handler to delete files using a wildcard (glob style).
00294         $ini = eZINI::instance();
00295         $cacheBaseDir = eZDir::path( array( eZSys::cacheDirectory(), $ini->variable( 'ContentSettings', 'CacheDir' ) ) );
00296 
00297         require_once( 'kernel/classes/ezclusterfilehandler.php' );
00298         $fileHandler = eZClusterFileHandler::instance();
00299 
00300         // Figure out the siteaccess which are related, first using the new
00301         // INI setting RelatedSiteAccessList then the old existing one
00302         // AvailableSiteAccessList
00303         if ( $ini->hasVariable( 'SiteAccessSettings', 'RelatedSiteAccessList' ) &&
00304              $relatedSiteAccessList = $ini->variable( 'SiteAccessSettings', 'RelatedSiteAccessList' ) )
00305         {
00306             if ( !is_array( $relatedSiteAccessList ) )
00307             {
00308                 $relatedSiteAccessList = array( $relatedSiteAccessList );
00309             }
00310             $relatedSiteAccessList[] = $GLOBALS['eZCurrentAccess']['name'];
00311             $siteAccesses = array_unique( $relatedSiteAccessList );
00312         }
00313         else
00314         {
00315             $siteAccesses = $ini->variable( 'SiteAccessSettings', 'AvailableSiteAccessList' );
00316         }
00317         if ( !$siteAccesses )
00318         {
00319             return;
00320         }
00321 
00322         foreach ( $nodeList as $nodeID )
00323         {
00324             $extraPath = eZDir::filenamePath( $nodeID );
00325             $fileHandler->fileDeleteByDirList( $siteAccesses, $cacheBaseDir, "$extraPath$nodeID-" );
00326         }
00327     }
00328 }
00329 
00330 ?>