PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/kernel/classes/ezcontentcache.php

https://github.com/Socrattes2099/ezpublish
PHP | 323 lines | 234 code | 44 blank | 45 comment | 26 complexity | d846340ab2f40e160c503f519952ac13 MD5 | raw file
  1. <?php
  2. //
  3. // Definition of eZContentCache class
  4. //
  5. // Created on: <12-Dec-2002 16:53:41 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. /*! \file
  31. */
  32. /*!
  33. \class eZContentCache ezcontentcache.php
  34. \brief The class eZContentCache does
  35. */
  36. class eZContentCache
  37. {
  38. // The timestamp for the cache format, will expire
  39. // cache which differs from this.
  40. const CODE_DATE = 1064816011;
  41. static function cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList, $layout, $cacheTTL = false,
  42. $parameters = array() )
  43. {
  44. $md5Input = array( $nodeID, $viewMode, $language );
  45. $md5Input[] = $offset;
  46. $md5Input = array_merge( $md5Input, $layout );
  47. sort( $roleList );
  48. $md5Input = array_merge( $md5Input, $roleList );
  49. sort( $discountList );
  50. $md5Input = array_merge( $md5Input, $discountList );
  51. if ( $cacheTTL == true )
  52. $md5Input = array_merge( $md5Input, "cache_ttl" );
  53. if ( isset( $parameters['view_parameters'] ) )
  54. {
  55. $viewParameters = $parameters['view_parameters'];
  56. ksort( $viewParameters );
  57. foreach ( $viewParameters as $viewParameterName => $viewParameter )
  58. {
  59. if ( !$viewParameter )
  60. continue;
  61. $md5Input = array_merge( $md5Input, 'vp:' . $viewParameterName . '=' . $viewParameter );
  62. }
  63. }
  64. $md5Text = md5( implode( '-', $md5Input ) );
  65. $cacheFile = $nodeID . '-' . $md5Text . '.cache';
  66. $extraPath = eZDir::filenamePath( "$nodeID" );
  67. $ini = eZINI::instance();
  68. $currentSiteAccess = $GLOBALS['eZCurrentAccess']['name'];
  69. $cacheDir = eZDir::path( array( eZSys::cacheDirectory(), $ini->variable( 'ContentSettings', 'CacheDir' ), $currentSiteAccess, $extraPath ) );
  70. $cachePath = eZDir::path( array( $cacheDir, $cacheFile ) );
  71. return array( 'dir' => $cacheDir,
  72. 'file' => $cacheFile,
  73. 'path' => $cachePath );
  74. }
  75. static function exists( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList, $layout,
  76. $parameters = array() )
  77. {
  78. $cachePathInfo = eZContentCache::cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList,
  79. $layout, false, $parameters );
  80. $cacheFile = eZClusterFileHandler::instance( $cachePathInfo['path'] );
  81. if ( $cacheFile->exists() )
  82. {
  83. $timestamp = $cacheFile->mtime();
  84. if ( eZContentObject::isCacheExpired( $timestamp ) )
  85. {
  86. eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache expired #1' );
  87. return false;
  88. }
  89. eZDebugSetting::writeDebug( 'kernel-content-view-cache', "checking viewmode '$viewMode' #1" );
  90. if ( eZContentObject::isComplexViewModeCacheExpired( $viewMode, $timestamp ) )
  91. {
  92. eZDebugSetting::writeDebug( 'kernel-content-view-cache', "viewmode '$viewMode' cache expired #1" );
  93. return false;
  94. }
  95. return true;
  96. }
  97. eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache used #1' );
  98. return false;
  99. }
  100. static function restore( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList, $layout,
  101. $parameters = array() )
  102. {
  103. $result = array();
  104. $cachePathInfo = eZContentCache::cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList,
  105. $layout, false, $parameters );
  106. $cacheDir = $cachePathInfo['dir'];
  107. $cacheFile = $cachePathInfo['file'];
  108. $cachePath = $cachePathInfo['path'];
  109. $timestamp = false;
  110. $cacheFile = eZClusterFileHandler::instance( $cachePath );
  111. if ( $cacheFile->exists() )
  112. {
  113. $timestamp = $cacheFile->mtime();
  114. if ( eZContentObject::isCacheExpired( $timestamp ) )
  115. {
  116. eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache expired #2' );
  117. return false;
  118. }
  119. eZDebugSetting::writeDebug( 'kernel-content-view-cache', "checking viewmode '$viewMode' #1" );
  120. if ( eZContentObject::isComplexViewModeCacheExpired( $viewMode, $timestamp ) )
  121. {
  122. eZDebugSetting::writeDebug( 'kernel-content-view-cache', "viewmode '$viewMode' cache expired #2" );
  123. return false;
  124. }
  125. }
  126. if ( $viewMode == 'pdf' )
  127. {
  128. return $cachePath;
  129. }
  130. eZDebugSetting::writeDebug( 'kernel-content-view-cache', 'cache used #2' );
  131. $fileName = $cacheDir . "/" . $cacheFile;
  132. $cacheFile = eZClusterFileHandler::instance( $fileName );
  133. $contents = $cacheFile->fetchContents();
  134. $cachedArray = unserialize( $contents );
  135. $cacheTTL = $cachedArray['cache_ttl'];
  136. // Check if cache has expired
  137. if ( $cacheTTL > 0 )
  138. {
  139. $expiryTime = $timestamp + $cacheTTL;
  140. if ( time() > $expiryTime )
  141. {
  142. return false;
  143. }
  144. }
  145. // Check for template language timestamp
  146. $cacheCodeDate = $cachedArray['cache_code_date'];
  147. if ( $cacheCodeDate != self::CODE_DATE )
  148. return false;
  149. $viewMode = $cachedArray['content_info']['viewmode'];
  150. $res = eZTemplateDesignResource::instance();
  151. $res->setKeys( array( array( 'node', $nodeID ),
  152. array( 'view_offset', $offset ),
  153. array( 'viewmode', $viewMode ),
  154. array( 'section', $cachedArray['section_id'] )
  155. ) );
  156. $result['content_info'] = $cachedArray['content_info'];
  157. $result['content'] = $cachedArray['content'];
  158. $result['view_parameters'] = $cachedArray['content_info']['view_parameters'];
  159. foreach ( array( 'path', 'node_id', 'section_id', 'navigation_part' ) as $item )
  160. {
  161. if ( isset( $cachedArray[$item] ) )
  162. {
  163. $result[$item] = $cachedArray[$item];
  164. }
  165. }
  166. return $result;
  167. }
  168. static function store( $siteDesign, $objectID, $classID, $classIdentifier,
  169. $nodeID, $parentNodeID, $nodeDepth, $urlAlias, $viewMode, $sectionID,
  170. $language, $offset, $roleList, $discountList, $layout, $navigationPartIdentifier,
  171. $result, $cacheTTL = -1,
  172. $parameters = array() )
  173. {
  174. $cachePathInfo = eZContentCache::cachePathInfo( $siteDesign, $nodeID, $viewMode, $language, $offset, $roleList, $discountList,
  175. $layout, false, $parameters );
  176. $cacheDir = $cachePathInfo['dir'];
  177. $cacheFile = $cachePathInfo['file'];
  178. $serializeArray = array();
  179. if ( isset( $parameters['view_parameters']['offset'] ) )
  180. {
  181. $offset = $parameters['view_parameters']['offset'];
  182. }
  183. $viewParameters = false;
  184. if ( isset( $parameters['view_parameters'] ) )
  185. {
  186. $viewParameters = $parameters['view_parameters'];
  187. }
  188. $contentInfo = array( 'site_design' => $siteDesign,
  189. 'node_id' => $nodeID,
  190. 'parent_node_id' => $parentNodeID,
  191. 'node_depth' => $nodeDepth,
  192. 'url_alias' => $urlAlias,
  193. 'object_id' => $objectID,
  194. 'class_id' => $classID,
  195. 'class_identifier' => $classIdentifier,
  196. 'navigation_part' => $navigationPartIdentifier,
  197. 'viewmode' => $viewMode,
  198. 'language' => $language,
  199. 'offset' => $offset,
  200. 'view_parameters' => $viewParameters,
  201. 'role_list' => $roleList,
  202. 'discount_list' => $discountList,
  203. 'section_id' => $result['section_id'] );
  204. $serializeArray['content_info'] = $contentInfo;
  205. foreach ( array( 'path', 'node_id', 'section_id', 'navigation_part' ) as $item )
  206. {
  207. if ( isset( $result[$item] ) )
  208. {
  209. $serializeArray[$item] = $result[$item];
  210. }
  211. }
  212. $serializeArray['cache_ttl'] = $cacheTTL;
  213. $serializeArray['cache_code_date'] = self::CODE_DATE;
  214. $serializeArray['content'] = $result['content'];
  215. $serializeString = serialize( $serializeArray );
  216. if ( !file_exists( $cacheDir ) )
  217. {
  218. eZDir::mkdir( $cacheDir, false, true );
  219. }
  220. $path = $cacheDir . '/' . $cacheFile;
  221. $uniqid = md5( uniqid( 'ezpcache'. getmypid(), true ) );
  222. $file = eZClusterFileHandler::instance( "$cacheDir/$uniqid" );
  223. $file->storeContents( $serializeString, 'viewcache', 'pdf' );
  224. $file->move( $path );
  225. return true;
  226. }
  227. static function calculateCleanupValue( $nodeCount )
  228. {
  229. return $nodeCount;
  230. }
  231. static function inCleanupThresholdRange( $value )
  232. {
  233. $ini = eZINI::instance();
  234. $threshold = $ini->variable( 'ContentSettings', 'CacheThreshold' );
  235. return ( $value < $threshold );
  236. }
  237. static function cleanup( $nodeList, $userId = false )
  238. {
  239. // The view-cache has a different storage structure than before:
  240. // var/cache/content/<siteaccess>/<extra-path>/<nodeID>-<hash>.cache
  241. // Also it uses the cluster file handler to delete files using a wildcard (glob style).
  242. $ini = eZINI::instance();
  243. $extraCacheName = '';
  244. $cacheBaseDir = eZDir::path( array( eZSys::cacheDirectory(), $ini->variable( 'ContentSettings', 'CacheDir' ) ) );
  245. $fileHandler = eZClusterFileHandler::instance();
  246. if ( $userId !== false && is_numeric( $userId ) )
  247. {
  248. $extraCacheName = $userId . '-';
  249. }
  250. // Figure out the siteaccess which are related, first using the new
  251. // INI setting RelatedSiteAccessList then the old existing one
  252. // AvailableSiteAccessList
  253. if ( $ini->hasVariable( 'SiteAccessSettings', 'RelatedSiteAccessList' ) &&
  254. $relatedSiteAccessList = $ini->variable( 'SiteAccessSettings', 'RelatedSiteAccessList' ) )
  255. {
  256. if ( !is_array( $relatedSiteAccessList ) )
  257. {
  258. $relatedSiteAccessList = array( $relatedSiteAccessList );
  259. }
  260. $relatedSiteAccessList[] = $GLOBALS['eZCurrentAccess']['name'];
  261. $siteAccesses = array_unique( $relatedSiteAccessList );
  262. }
  263. else
  264. {
  265. $siteAccesses = $ini->variable( 'SiteAccessSettings', 'AvailableSiteAccessList' );
  266. }
  267. if ( !$siteAccesses )
  268. {
  269. return;
  270. }
  271. foreach ( $nodeList as $nodeID )
  272. {
  273. $extraPath = eZDir::filenamePath( $nodeID );
  274. $fileHandler->fileDeleteByDirList( $siteAccesses, $cacheBaseDir, "$extraPath$nodeID-$extraCacheName" );
  275. }
  276. }
  277. }
  278. ?>