PageRenderTime 72ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/libs/cache/file.php

https://bitbucket.org/enangyusup/vbulletin-cakephp
PHP | 278 lines | 169 code | 16 blank | 93 comment | 30 complexity | b0953f98843b6327b0972658f3cef2eb MD5 | raw file
  1. <?php
  2. /**
  3. * File Storage engine for cache
  4. *
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  9. * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. *
  11. * Licensed under The MIT License
  12. * Redistributions of files must retain the above copyright notice.
  13. *
  14. * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://cakephp.org CakePHP(tm) Project
  16. * @package cake
  17. * @subpackage cake.cake.libs.cache
  18. * @since CakePHP(tm) v 1.2.0.4933
  19. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  20. */
  21. /**
  22. * File Storage engine for cache
  23. *
  24. * @todo use the File and Folder classes (if it's not a too big performance hit)
  25. * @package cake
  26. * @subpackage cake.cake.libs.cache
  27. */
  28. class FileEngine extends CacheEngine {
  29. /**
  30. * Instance of File class
  31. *
  32. * @var File
  33. * @access private
  34. */
  35. var $__File = null;
  36. /**
  37. * Settings
  38. *
  39. * - path = absolute path to cache directory, default => CACHE
  40. * - prefix = string prefix for filename, default => cake_
  41. * - lock = enable file locking on write, default => false
  42. * - serialize = serialize the data, default => true
  43. *
  44. * @var array
  45. * @see CacheEngine::__defaults
  46. * @access public
  47. */
  48. var $settings = array();
  49. /**
  50. * Set to true if FileEngine::init(); and FileEngine::__active(); do not fail.
  51. *
  52. * @var boolean
  53. * @access private
  54. */
  55. var $__active = false;
  56. /**
  57. * True unless FileEngine::__active(); fails
  58. *
  59. * @var boolean
  60. * @access private
  61. */
  62. var $__init = true;
  63. /**
  64. * Initialize the Cache Engine
  65. *
  66. * Called automatically by the cache frontend
  67. * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
  68. *
  69. * @param array $setting array of setting for the engine
  70. * @return boolean True if the engine has been successfully initialized, false if not
  71. * @access public
  72. */
  73. function init($settings = array()) {
  74. parent::init(array_merge(
  75. array(
  76. 'engine' => 'File', 'path' => CACHE, 'prefix'=> 'cake_', 'lock'=> false,
  77. 'serialize'=> true, 'isWindows' => false
  78. ),
  79. $settings
  80. ));
  81. if (!isset($this->__File)) {
  82. if (!class_exists('File')) {
  83. require LIBS . 'file.php';
  84. }
  85. $this->__File =& new File($this->settings['path'] . DS . 'cake');
  86. }
  87. if (DIRECTORY_SEPARATOR === '\\') {
  88. $this->settings['isWindows'] = true;
  89. }
  90. $this->settings['path'] = $this->__File->Folder->cd($this->settings['path']);
  91. if (empty($this->settings['path'])) {
  92. return false;
  93. }
  94. return $this->__active();
  95. }
  96. /**
  97. * Garbage collection. Permanently remove all expired and deleted data
  98. *
  99. * @return boolean True if garbage collection was succesful, false on failure
  100. * @access public
  101. */
  102. function gc() {
  103. return $this->clear(true);
  104. }
  105. /**
  106. * Write data for key into cache
  107. *
  108. * @param string $key Identifier for the data
  109. * @param mixed $data Data to be cached
  110. * @param mixed $duration How long to cache the data, in seconds
  111. * @return boolean True if the data was succesfully cached, false on failure
  112. * @access public
  113. */
  114. function write($key, &$data, $duration) {
  115. if ($data === '' || !$this->__init) {
  116. return false;
  117. }
  118. if ($this->__setKey($key) === false) {
  119. return false;
  120. }
  121. $lineBreak = "\n";
  122. if ($this->settings['isWindows']) {
  123. $lineBreak = "\r\n";
  124. }
  125. if (!empty($this->settings['serialize'])) {
  126. if ($this->settings['isWindows']) {
  127. $data = str_replace('\\', '\\\\\\\\', serialize($data));
  128. } else {
  129. $data = serialize($data);
  130. }
  131. }
  132. if ($this->settings['lock']) {
  133. $this->__File->lock = true;
  134. }
  135. $expires = time() + $duration;
  136. $contents = $expires . $lineBreak . $data . $lineBreak;
  137. $success = $this->__File->write($contents);
  138. $this->__File->close();
  139. return $success;
  140. }
  141. /**
  142. * Read a key from the cache
  143. *
  144. * @param string $key Identifier for the data
  145. * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
  146. * @access public
  147. */
  148. function read($key) {
  149. if ($this->__setKey($key) === false || !$this->__init || !$this->__File->exists()) {
  150. return false;
  151. }
  152. if ($this->settings['lock']) {
  153. $this->__File->lock = true;
  154. }
  155. $time = time();
  156. $cachetime = intval($this->__File->read(11));
  157. if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
  158. $this->__File->close();
  159. return false;
  160. }
  161. $data = $this->__File->read(true);
  162. if ($data !== '' && !empty($this->settings['serialize'])) {
  163. if ($this->settings['isWindows']) {
  164. $data = str_replace('\\\\\\\\', '\\', $data);
  165. }
  166. $data = unserialize((string)$data);
  167. }
  168. $this->__File->close();
  169. return $data;
  170. }
  171. /**
  172. * Delete a key from the cache
  173. *
  174. * @param string $key Identifier for the data
  175. * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
  176. * @access public
  177. */
  178. function delete($key) {
  179. if ($this->__setKey($key) === false || !$this->__init) {
  180. return false;
  181. }
  182. return $this->__File->delete();
  183. }
  184. /**
  185. * Delete all values from the cache
  186. *
  187. * @param boolean $check Optional - only delete expired cache items
  188. * @return boolean True if the cache was succesfully cleared, false otherwise
  189. * @access public
  190. */
  191. function clear($check) {
  192. if (!$this->__init) {
  193. return false;
  194. }
  195. $dir = dir($this->settings['path']);
  196. if ($check) {
  197. $now = time();
  198. $threshold = $now - $this->settings['duration'];
  199. }
  200. while (($entry = $dir->read()) !== false) {
  201. if ($this->__setKey($entry) === false) {
  202. continue;
  203. }
  204. if ($check) {
  205. $mtime = $this->__File->lastChange();
  206. if ($mtime === false || $mtime > $threshold) {
  207. continue;
  208. }
  209. $expires = $this->__File->read(11);
  210. $this->__File->close();
  211. if ($expires > $now) {
  212. continue;
  213. }
  214. }
  215. $this->__File->delete();
  216. }
  217. $dir->close();
  218. return true;
  219. }
  220. /**
  221. * Get absolute file for a given key
  222. *
  223. * @param string $key The key
  224. * @return mixed Absolute cache file for the given key or false if erroneous
  225. * @access private
  226. */
  227. function __setKey($key) {
  228. $this->__File->Folder->cd($this->settings['path']);
  229. if ($key !== $this->__File->name) {
  230. $this->__File->name = $key;
  231. $this->__File->path = null;
  232. }
  233. if (!$this->__File->Folder->inPath($this->__File->pwd(), true)) {
  234. return false;
  235. }
  236. }
  237. /**
  238. * Determine is cache directory is writable
  239. *
  240. * @return boolean
  241. * @access private
  242. */
  243. function __active() {
  244. if (!$this->__active && $this->__init && !is_writable($this->settings['path'])) {
  245. $this->__init = false;
  246. trigger_error(sprintf(__('%s is not writable', true), $this->settings['path']), E_USER_WARNING);
  247. } else {
  248. $this->__active = true;
  249. }
  250. return true;
  251. }
  252. }
  253. ?>