Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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