PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/sapphire/thirdparty/Zend/Cache/Backend/ZendPlatform.php

https://github.com/benbruscella/vpcounselling.com
PHP | 316 lines | 181 code | 18 blank | 117 comment | 46 complexity | e3d94ef69c15e621311b92ca13efc44f MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Cache
  17. * @subpackage Zend_Cache_Backend
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @see Zend_Cache_Backend_Interface
  23. */
  24. require_once 'Zend/Cache/Backend.php';
  25. /**
  26. * @see Zend_Cache_Backend_Interface
  27. */
  28. require_once 'Zend/Cache/Backend/Interface.php';
  29. /**
  30. * Impementation of Zend Cache Backend using the Zend Platform (Output Content Caching)
  31. *
  32. * @package Zend_Cache
  33. * @subpackage Zend_Cache_Backend
  34. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. class Zend_Cache_Backend_ZendPlatform extends Zend_Cache_Backend implements Zend_Cache_Backend_Interface
  38. {
  39. /**
  40. * internal ZP prefix
  41. */
  42. const TAGS_PREFIX = "internal_ZPtag:";
  43. /**
  44. * Constructor
  45. * Validate that the Zend Platform is loaded and licensed
  46. *
  47. * @param array $options Associative array of options
  48. * @throws Zend_Cache_Exception
  49. * @return void
  50. */
  51. public function __construct(array $options = array())
  52. {
  53. if (!function_exists('accelerator_license_info')) {
  54. Zend_Cache::throwException('The Zend Platform extension must be loaded for using this backend !');
  55. }
  56. if (!function_exists('accelerator_get_configuration')) {
  57. $licenseInfo = accelerator_license_info();
  58. Zend_Cache::throwException('The Zend Platform extension is not loaded correctly: '.$licenseInfo['failure_reason']);
  59. }
  60. $accConf = accelerator_get_configuration();
  61. if (@!$accConf['output_cache_licensed']) {
  62. Zend_Cache::throwException('The Zend Platform extension does not have the proper license to use content caching features');
  63. }
  64. if (@!$accConf['output_cache_enabled']) {
  65. Zend_Cache::throwException('The Zend Platform content caching feature must be enabled for using this backend, set the \'zend_accelerator.output_cache_enabled\' directive to On !');
  66. }
  67. if (!is_writable($accConf['output_cache_dir'])) {
  68. Zend_Cache::throwException('The cache copies directory \''. ini_get('zend_accelerator.output_cache_dir') .'\' must be writable !');
  69. }
  70. parent:: __construct($options);
  71. }
  72. /**
  73. * Test if a cache is available for the given id and (if yes) return it (false else)
  74. *
  75. * @param string $id Cache id
  76. * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
  77. * @return string Cached data (or false)
  78. */
  79. public function load($id, $doNotTestCacheValidity = false)
  80. {
  81. // doNotTestCacheValidity implemented by giving zero lifetime to the cache
  82. if ($doNotTestCacheValidity) {
  83. $lifetime = 0;
  84. } else {
  85. $lifetime = $this->_directives['lifetime'];
  86. }
  87. $res = output_cache_get($id, $lifetime);
  88. if($res) {
  89. return $res[0];
  90. } else {
  91. return false;
  92. }
  93. }
  94. /**
  95. * Test if a cache is available or not (for the given id)
  96. *
  97. * @param string $id Cache id
  98. * @return mixed|false false (a cache is not available) or "last modified" timestamp (int) of the available cache record
  99. */
  100. public function test($id)
  101. {
  102. $result = output_cache_get($id, $this->_directives['lifetime']);
  103. if ($result) {
  104. return $result[1];
  105. }
  106. return false;
  107. }
  108. /**
  109. * Save some string datas into a cache record
  110. *
  111. * Note : $data is always "string" (serialization is done by the
  112. * core not by the backend)
  113. *
  114. * @param string $data Data to cache
  115. * @param string $id Cache id
  116. * @param array $tags Array of strings, the cache record will be tagged by each string entry
  117. * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime)
  118. * @return boolean true if no problem
  119. */
  120. public function save($data, $id, $tags = array(), $specificLifetime = false)
  121. {
  122. if (!($specificLifetime === false)) {
  123. $this->_log("Zend_Cache_Backend_ZendPlatform::save() : non false specifc lifetime is unsuported for this backend");
  124. }
  125. $lifetime = $this->_directives['lifetime'];
  126. $result1 = output_cache_put($id, array($data, time()));
  127. $result2 = (count($tags) == 0);
  128. foreach ($tags as $tag) {
  129. $tagid = self::TAGS_PREFIX.$tag;
  130. $old_tags = output_cache_get($tagid, $lifetime);
  131. if ($old_tags === false) {
  132. $old_tags = array();
  133. }
  134. $old_tags[$id] = $id;
  135. output_cache_remove_key($tagid);
  136. $result2 = output_cache_put($tagid, $old_tags);
  137. }
  138. return $result1 && $result2;
  139. }
  140. /**
  141. * Remove a cache record
  142. *
  143. * @param string $id Cache id
  144. * @return boolean True if no problem
  145. */
  146. public function remove($id)
  147. {
  148. return output_cache_remove_key($id);
  149. }
  150. /**
  151. * Clean some cache records
  152. *
  153. * Available modes are :
  154. * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used)
  155. * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used)
  156. * This mode is not supported in this backend
  157. * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags
  158. * ($tags can be an array of strings or a single string)
  159. * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => unsupported
  160. * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
  161. * ($tags can be an array of strings or a single string)
  162. *
  163. * @param string $mode Clean mode
  164. * @param array $tags Array of tags
  165. * @throws Zend_Cache_Exception
  166. * @return boolean True if no problem
  167. */
  168. public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array())
  169. {
  170. switch ($mode) {
  171. case Zend_Cache::CLEANING_MODE_ALL:
  172. case Zend_Cache::CLEANING_MODE_OLD:
  173. $cache_dir = ini_get('zend_accelerator.output_cache_dir');
  174. if (!$cache_dir) {
  175. return false;
  176. }
  177. $cache_dir .= '/.php_cache_api/';
  178. return $this->_clean($cache_dir, $mode);
  179. break;
  180. case Zend_Cache::CLEANING_MODE_MATCHING_TAG:
  181. $idlist = null;
  182. foreach ($tags as $tag) {
  183. $next_idlist = output_cache_get(self::TAGS_PREFIX.$tag, $this->_directives['lifetime']);
  184. if ($idlist) {
  185. $idlist = array_intersect_assoc($idlist, $next_idlist);
  186. } else {
  187. $idlist = $next_idlist;
  188. }
  189. if (count($idlist) == 0) {
  190. // if ID list is already empty - we may skip checking other IDs
  191. $idlist = null;
  192. break;
  193. }
  194. }
  195. if ($idlist) {
  196. foreach ($idlist as $id) {
  197. output_cache_remove_key($id);
  198. }
  199. }
  200. return true;
  201. break;
  202. case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG:
  203. $this->_log("Zend_Cache_Backend_ZendPlatform::clean() : CLEANING_MODE_NOT_MATCHING_TAG is not supported by the Zend Platform backend");
  204. return false;
  205. break;
  206. case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG:
  207. $idlist = null;
  208. foreach ($tags as $tag) {
  209. $next_idlist = output_cache_get(self::TAGS_PREFIX.$tag, $this->_directives['lifetime']);
  210. if ($idlist) {
  211. $idlist = array_merge_recursive($idlist, $next_idlist);
  212. } else {
  213. $idlist = $next_idlist;
  214. }
  215. if (count($idlist) == 0) {
  216. // if ID list is already empty - we may skip checking other IDs
  217. $idlist = null;
  218. break;
  219. }
  220. }
  221. if ($idlist) {
  222. foreach ($idlist as $id) {
  223. output_cache_remove_key($id);
  224. }
  225. }
  226. return true;
  227. break;
  228. default:
  229. Zend_Cache::throwException('Invalid mode for clean() method');
  230. break;
  231. }
  232. }
  233. /**
  234. * Clean a directory and recursivly go over it's subdirectories
  235. *
  236. * Remove all the cached files that need to be cleaned (according to mode and files mtime)
  237. *
  238. * @param string $dir Path of directory ot clean
  239. * @param string $mode The same parameter as in Zend_Cache_Backend_ZendPlatform::clean()
  240. * @return boolean True if ok
  241. */
  242. private function _clean($dir, $mode)
  243. {
  244. $d = @dir($dir);
  245. if (!$d) {
  246. return false;
  247. }
  248. $result = true;
  249. while (false !== ($file = $d->read())) {
  250. if ($file == '.' || $file == '..') {
  251. continue;
  252. }
  253. $file = $d->path . $file;
  254. if (is_dir($file)) {
  255. $result = ($this->_clean($file .'/', $mode)) && ($result);
  256. } else {
  257. if ($mode == Zend_Cache::CLEANING_MODE_ALL) {
  258. $result = ($this->_remove($file)) && ($result);
  259. } else if ($mode == Zend_Cache::CLEANING_MODE_OLD) {
  260. // Files older than lifetime get deleted from cache
  261. if ($this->_directives['lifetime'] !== null) {
  262. if ((time() - @filemtime($file)) > $this->_directives['lifetime']) {
  263. $result = ($this->_remove($file)) && ($result);
  264. }
  265. }
  266. }
  267. }
  268. }
  269. $d->close();
  270. return $result;
  271. }
  272. /**
  273. * Remove a file
  274. *
  275. * If we can't remove the file (because of locks or any problem), we will touch
  276. * the file to invalidate it
  277. *
  278. * @param string $file Complete file path
  279. * @return boolean True if ok
  280. */
  281. private function _remove($file)
  282. {
  283. if (!@unlink($file)) {
  284. # If we can't remove the file (because of locks or any problem), we will touch
  285. # the file to invalidate it
  286. $this->_log("Zend_Cache_Backend_ZendPlatform::_remove() : we can't remove $file => we are going to try to invalidate it");
  287. if ($this->_directives['lifetime'] === null) {
  288. return false;
  289. }
  290. if (!file_exists($file)) {
  291. return false;
  292. }
  293. return @touch($file, time() - 2*abs($this->_directives['lifetime']));
  294. }
  295. return true;
  296. }
  297. }