1: | <?php
|
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | |
18: |
|
19: | defined('XOOPS_ROOT_PATH') || exit('Restricted access');
|
20: |
|
21: | |
22: | |
23: | |
24: | |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | |
32: | |
33: | |
34: | |
35: | |
36: | |
37: | |
38: | |
39: | |
40: | |
41: | |
42: | |
43: | |
44: |
|
45: |
|
46: | |
47: | |
48: | |
49: | |
50: | |
51: | |
52: |
|
53: | class XoopsCacheFile extends XoopsCacheEngine
|
54: | {
|
55: | |
56: | |
57: | |
58: | |
59: | |
60: |
|
61: | private $file;
|
62: |
|
63: | |
64: | |
65: | |
66: | |
67: | |
68: | |
69: | |
70: | |
71: | |
72: | |
73: |
|
74: | public $settings = array();
|
75: |
|
76: | |
77: | |
78: | |
79: | |
80: | |
81: |
|
82: | private $active = false;
|
83: |
|
84: | |
85: | |
86: | |
87: | |
88: | |
89: |
|
90: | private $init = true;
|
91: |
|
92: | |
93: | |
94: | |
95: | |
96: | |
97: | |
98: | |
99: | |
100: | |
101: |
|
102: | public function init($settings = array())
|
103: | {
|
104: | parent::init($settings);
|
105: | $defaults = array(
|
106: | 'path' => XOOPS_VAR_PATH . '/caches/xoops_cache',
|
107: | 'extension' => '.php',
|
108: | 'prefix' => 'xoops_',
|
109: | 'lock' => false,
|
110: | 'serialize' => false,
|
111: | 'duration' => 31556926);
|
112: | $this->settings = array_merge($defaults, $this->settings);
|
113: | if (!isset($this->file)) {
|
114: | XoopsLoad::load('XoopsFile');
|
115: | $this->file = XoopsFile::getHandler('file', $this->settings['path'] . '/index.php', true);
|
116: | }
|
117: | $this->settings['path'] = $this->file->folder->cd($this->settings['path']);
|
118: | if (empty($this->settings['path'])) {
|
119: | return false;
|
120: | }
|
121: |
|
122: | return $this->active();
|
123: | }
|
124: |
|
125: | |
126: | |
127: | |
128: | |
129: | |
130: |
|
131: | public function gc()
|
132: | {
|
133: | return $this->clear(true);
|
134: | }
|
135: |
|
136: | |
137: | |
138: | |
139: | |
140: | |
141: | |
142: | |
143: | |
144: |
|
145: | public function write($key, $data = null, $duration = null)
|
146: | {
|
147: | if (!isset($data) || !$this->init) {
|
148: | return false;
|
149: | }
|
150: |
|
151: | if ($this->setKey($key) === false) {
|
152: | return false;
|
153: | }
|
154: |
|
155: | if ($duration == null) {
|
156: | $duration = $this->settings['duration'];
|
157: | }
|
158: | $windows = false;
|
159: | $lineBreak = "\n";
|
160: |
|
161: | if (substr(PHP_OS, 0, 3) === 'WIN') {
|
162: | $lineBreak = "\r\n";
|
163: | $windows = true;
|
164: | }
|
165: | $expires = time() + $duration;
|
166: | if (!empty($this->settings['serialize'])) {
|
167: | if ($windows) {
|
168: | $data = str_replace('\\', '\\\\\\\\', serialize($data));
|
169: | } else {
|
170: | $data = serialize($data);
|
171: | }
|
172: | $contents = $expires . $lineBreak . $data . $lineBreak;
|
173: | } else {
|
174: | $contents = $expires . $lineBreak . 'return ' . var_export($data, true) . ';' . $lineBreak;
|
175: | }
|
176: |
|
177: | if ($this->settings['lock']) {
|
178: | $this->file->lock = true;
|
179: | }
|
180: | $success = $this->file->write($contents);
|
181: | $this->file->close();
|
182: |
|
183: | return $success;
|
184: | }
|
185: |
|
186: | |
187: | |
188: | |
189: | |
190: | |
191: | |
192: |
|
193: | public function read($key)
|
194: | {
|
195: | if ($this->setKey($key) === false || !$this->init) {
|
196: | return false;
|
197: | }
|
198: | if ($this->settings['lock']) {
|
199: | $this->file->lock = true;
|
200: | }
|
201: | $cachetime = $this->file->read(11);
|
202: |
|
203: | if ($cachetime !== false && (int)$cachetime < time()) {
|
204: | $this->file->close();
|
205: | $this->file->delete();
|
206: |
|
207: | return false;
|
208: | }
|
209: |
|
210: | $data = $this->file->read(true);
|
211: | if (!empty($data) && !empty($this->settings['serialize'])) {
|
212: | $data = stripslashes($data);
|
213: |
|
214: | $data = preg_replace_callback('!s:(\d+):"(.*?)";!s', function ($m) { return 's:' . strlen($m[2]) . ':"' . $m[2] . '";'; }, $data);
|
215: | $data = unserialize($data, array('allowed_classes' => false));
|
216: | if (is_array($data)) {
|
217: | XoopsLoad::load('XoopsUtility');
|
218: | $data = XoopsUtility::recursive('stripslashes', $data);
|
219: | }
|
220: | } elseif ($data && empty($this->settings['serialize'])) {
|
221: | $data = eval($data);
|
222: | }
|
223: | $this->file->close();
|
224: |
|
225: | return $data;
|
226: | }
|
227: |
|
228: | |
229: | |
230: | |
231: | |
232: | |
233: | |
234: |
|
235: | public function delete($key)
|
236: | {
|
237: | if ($this->setKey($key) === false || !$this->init) {
|
238: | return false;
|
239: | }
|
240: |
|
241: | return $this->file->delete();
|
242: | }
|
243: |
|
244: | |
245: | |
246: | |
247: | |
248: | |
249: | |
250: |
|
251: | public function clear($check = true)
|
252: | {
|
253: | if (!$this->init) {
|
254: | return false;
|
255: | }
|
256: | $dir = dir($this->settings['path']);
|
257: | if ($check) {
|
258: | $now = time();
|
259: | $threshold = $now - $this->settings['duration'];
|
260: | }
|
261: | while (($entry = $dir->read()) !== false) {
|
262: | if ($this->setKey(str_replace($this->settings['prefix'], '', $entry)) === false) {
|
263: | continue;
|
264: | }
|
265: | if ($check) {
|
266: | $mtime = $this->file->lastChange();
|
267: |
|
268: | if ($mtime === false || $mtime > $threshold) {
|
269: | continue;
|
270: | }
|
271: |
|
272: | $expires = $this->file->read(11);
|
273: | $this->file->close();
|
274: |
|
275: | if ($expires > $now) {
|
276: | continue;
|
277: | }
|
278: | }
|
279: | $this->file->delete();
|
280: | }
|
281: | $dir->close();
|
282: |
|
283: | return true;
|
284: | }
|
285: |
|
286: | |
287: | |
288: | |
289: | |
290: | |
291: | |
292: |
|
293: | private function setKey($key)
|
294: | {
|
295: | $this->file->folder->cd($this->settings['path']);
|
296: | $this->file->name = $this->settings['prefix'] . $key . $this->settings['extension'];
|
297: | $this->file->handle = null;
|
298: | $this->file->info = null;
|
299: | if (!$this->file->folder->inPath($this->file->pwd(), true)) {
|
300: | return false;
|
301: | }
|
302: | return null;
|
303: | }
|
304: |
|
305: | |
306: | |
307: | |
308: | |
309: | |
310: |
|
311: | private function active()
|
312: | {
|
313: | if (!$this->active && $this->init && !is_writable($this->settings['path'])) {
|
314: | $this->init = false;
|
315: | trigger_error(sprintf('%s is not writable', $this->settings['path']), E_USER_WARNING);
|
316: | } else {
|
317: | $this->active = true;
|
318: | }
|
319: |
|
320: | return true;
|
321: | }
|
322: | }
|
323: | |