|
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-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Backend.php 20880 2010-02-03 18:18:32Z matthew $ |
|
21 */ |
|
22 |
|
23 |
|
24 /** |
|
25 * @package Zend_Cache |
|
26 * @subpackage Zend_Cache_Backend |
|
27 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
28 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
29 */ |
|
30 class Zend_Cache_Backend |
|
31 { |
|
32 /** |
|
33 * Frontend or Core directives |
|
34 * |
|
35 * =====> (int) lifetime : |
|
36 * - Cache lifetime (in seconds) |
|
37 * - If null, the cache is valid forever |
|
38 * |
|
39 * =====> (int) logging : |
|
40 * - if set to true, a logging is activated throw Zend_Log |
|
41 * |
|
42 * @var array directives |
|
43 */ |
|
44 protected $_directives = array( |
|
45 'lifetime' => 3600, |
|
46 'logging' => false, |
|
47 'logger' => null |
|
48 ); |
|
49 |
|
50 /** |
|
51 * Available options |
|
52 * |
|
53 * @var array available options |
|
54 */ |
|
55 protected $_options = array(); |
|
56 |
|
57 /** |
|
58 * Constructor |
|
59 * |
|
60 * @param array $options Associative array of options |
|
61 * @throws Zend_Cache_Exception |
|
62 * @return void |
|
63 */ |
|
64 public function __construct(array $options = array()) |
|
65 { |
|
66 while (list($name, $value) = each($options)) { |
|
67 $this->setOption($name, $value); |
|
68 } |
|
69 } |
|
70 |
|
71 /** |
|
72 * Set the frontend directives |
|
73 * |
|
74 * @param array $directives Assoc of directives |
|
75 * @throws Zend_Cache_Exception |
|
76 * @return void |
|
77 */ |
|
78 public function setDirectives($directives) |
|
79 { |
|
80 if (!is_array($directives)) Zend_Cache::throwException('Directives parameter must be an array'); |
|
81 while (list($name, $value) = each($directives)) { |
|
82 if (!is_string($name)) { |
|
83 Zend_Cache::throwException("Incorrect option name : $name"); |
|
84 } |
|
85 $name = strtolower($name); |
|
86 if (array_key_exists($name, $this->_directives)) { |
|
87 $this->_directives[$name] = $value; |
|
88 } |
|
89 |
|
90 } |
|
91 |
|
92 $this->_loggerSanity(); |
|
93 } |
|
94 |
|
95 /** |
|
96 * Set an option |
|
97 * |
|
98 * @param string $name |
|
99 * @param mixed $value |
|
100 * @throws Zend_Cache_Exception |
|
101 * @return void |
|
102 */ |
|
103 public function setOption($name, $value) |
|
104 { |
|
105 if (!is_string($name)) { |
|
106 Zend_Cache::throwException("Incorrect option name : $name"); |
|
107 } |
|
108 $name = strtolower($name); |
|
109 if (array_key_exists($name, $this->_options)) { |
|
110 $this->_options[$name] = $value; |
|
111 } |
|
112 } |
|
113 |
|
114 /** |
|
115 * Get the life time |
|
116 * |
|
117 * if $specificLifetime is not false, the given specific life time is used |
|
118 * else, the global lifetime is used |
|
119 * |
|
120 * @param int $specificLifetime |
|
121 * @return int Cache life time |
|
122 */ |
|
123 public function getLifetime($specificLifetime) |
|
124 { |
|
125 if ($specificLifetime === false) { |
|
126 return $this->_directives['lifetime']; |
|
127 } |
|
128 return $specificLifetime; |
|
129 } |
|
130 |
|
131 /** |
|
132 * Return true if the automatic cleaning is available for the backend |
|
133 * |
|
134 * DEPRECATED : use getCapabilities() instead |
|
135 * |
|
136 * @deprecated |
|
137 * @return boolean |
|
138 */ |
|
139 public function isAutomaticCleaningAvailable() |
|
140 { |
|
141 return true; |
|
142 } |
|
143 |
|
144 /** |
|
145 * Determine system TMP directory and detect if we have read access |
|
146 * |
|
147 * inspired from Zend_File_Transfer_Adapter_Abstract |
|
148 * |
|
149 * @return string |
|
150 * @throws Zend_Cache_Exception if unable to determine directory |
|
151 */ |
|
152 public function getTmpDir() |
|
153 { |
|
154 $tmpdir = array(); |
|
155 foreach (array($_ENV, $_SERVER) as $tab) { |
|
156 foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $key) { |
|
157 if (isset($tab[$key])) { |
|
158 if (($key == 'windir') or ($key == 'SystemRoot')) { |
|
159 $dir = realpath($tab[$key] . '\\temp'); |
|
160 } else { |
|
161 $dir = realpath($tab[$key]); |
|
162 } |
|
163 if ($this->_isGoodTmpDir($dir)) { |
|
164 return $dir; |
|
165 } |
|
166 } |
|
167 } |
|
168 } |
|
169 $upload = ini_get('upload_tmp_dir'); |
|
170 if ($upload) { |
|
171 $dir = realpath($upload); |
|
172 if ($this->_isGoodTmpDir($dir)) { |
|
173 return $dir; |
|
174 } |
|
175 } |
|
176 if (function_exists('sys_get_temp_dir')) { |
|
177 $dir = sys_get_temp_dir(); |
|
178 if ($this->_isGoodTmpDir($dir)) { |
|
179 return $dir; |
|
180 } |
|
181 } |
|
182 // Attemp to detect by creating a temporary file |
|
183 $tempFile = tempnam(md5(uniqid(rand(), TRUE)), ''); |
|
184 if ($tempFile) { |
|
185 $dir = realpath(dirname($tempFile)); |
|
186 unlink($tempFile); |
|
187 if ($this->_isGoodTmpDir($dir)) { |
|
188 return $dir; |
|
189 } |
|
190 } |
|
191 if ($this->_isGoodTmpDir('/tmp')) { |
|
192 return '/tmp'; |
|
193 } |
|
194 if ($this->_isGoodTmpDir('\\temp')) { |
|
195 return '\\temp'; |
|
196 } |
|
197 Zend_Cache::throwException('Could not determine temp directory, please specify a cache_dir manually'); |
|
198 } |
|
199 |
|
200 /** |
|
201 * Verify if the given temporary directory is readable and writable |
|
202 * |
|
203 * @param $dir temporary directory |
|
204 * @return boolean true if the directory is ok |
|
205 */ |
|
206 protected function _isGoodTmpDir($dir) |
|
207 { |
|
208 if (is_readable($dir)) { |
|
209 if (is_writable($dir)) { |
|
210 return true; |
|
211 } |
|
212 } |
|
213 return false; |
|
214 } |
|
215 |
|
216 /** |
|
217 * Make sure if we enable logging that the Zend_Log class |
|
218 * is available. |
|
219 * Create a default log object if none is set. |
|
220 * |
|
221 * @throws Zend_Cache_Exception |
|
222 * @return void |
|
223 */ |
|
224 protected function _loggerSanity() |
|
225 { |
|
226 if (!isset($this->_directives['logging']) || !$this->_directives['logging']) { |
|
227 return; |
|
228 } |
|
229 |
|
230 if (isset($this->_directives['logger'])) { |
|
231 if ($this->_directives['logger'] instanceof Zend_Log) { |
|
232 return; |
|
233 } |
|
234 Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); |
|
235 } |
|
236 |
|
237 // Create a default logger to the standard output stream |
|
238 require_once 'Zend/Log.php'; |
|
239 require_once 'Zend/Log/Writer/Stream.php'; |
|
240 $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output')); |
|
241 $this->_directives['logger'] = $logger; |
|
242 } |
|
243 |
|
244 /** |
|
245 * Log a message at the WARN (4) priority. |
|
246 * |
|
247 * @param string $message |
|
248 * @throws Zend_Cache_Exception |
|
249 * @return void |
|
250 */ |
|
251 protected function _log($message, $priority = 4) |
|
252 { |
|
253 if (!$this->_directives['logging']) { |
|
254 return; |
|
255 } |
|
256 |
|
257 if (!isset($this->_directives['logger'])) { |
|
258 Zend_Cache::throwException('Logging is enabled but logger is not set.'); |
|
259 } |
|
260 $logger = $this->_directives['logger']; |
|
261 if (!$logger instanceof Zend_Log) { |
|
262 Zend_Cache::throwException('Logger object is not an instance of Zend_Log class.'); |
|
263 } |
|
264 $logger->log($message, $priority); |
|
265 } |
|
266 } |