1: <?php
2: 3: 4: 5: 6: 7: 8: 9:
10:
11: namespace Kotchasan\Cache;
12:
13: use Kotchasan\Cache\CacheItem as Item;
14: use Kotchasan\File;
15: use Psr\Cache\CacheItemInterface;
16:
17: 18: 19: 20: 21: 22: 23:
24: class FileCache extends Cache
25: {
26: 27: 28: 29: 30:
31: protected $cache_dir = null;
32: 33: 34: 35: 36:
37: protected $cache_expire = 0;
38:
39: 40: 41: 42: 43:
44: public function __construct()
45: {
46: $this->cache_expire = self::$cfg->get('cache_expire', 0);
47: if (!empty($this->cache_expire)) {
48:
49: $this->cache_dir = ROOT_PATH.'datas/cache/';
50: if (!File::makeDirectory($this->cache_dir)) {
51: throw new \Exception('Folder '.str_replace(ROOT_PATH, '', $this->cache_dir).' cannot be created.');
52: }
53:
54: $d = is_file($this->cache_dir.'index.php') ? (int) file_get_contents($this->cache_dir.'index.php') : 0;
55: if ($d != (int) date('d')) {
56: $this->clear();
57: $f = @fopen($this->cache_dir.'index.php', 'wb');
58: if ($f === false) {
59: throw new \Exception('File '.str_replace(ROOT_PATH, '', $this->cache_dir).'index.php cannot be written.');
60: } else {
61: fwrite($f, date('d-m-Y H:i:s'));
62: fclose($f);
63: }
64: }
65: }
66: }
67:
68: 69: 70: 71: 72: 73:
74: public function clear()
75: {
76: $error = array();
77: if ($this->cache_dir && !empty($this->cache_expire)) {
78: $this->clearCache($this->cache_dir, $error);
79: }
80:
81: return empty($error) ? true : false;
82: }
83:
84: 85: 86: 87: 88: 89: 90: 91:
92: public function deleteItems(array $keys)
93: {
94: if ($this->cache_dir) {
95: foreach ($keys as $key) {
96: @unlink($this->fetchStreamUri($key));
97: }
98: }
99:
100: return true;
101: }
102:
103: 104: 105: 106: 107: 108: 109:
110: public function getItems(array $keys = array())
111: {
112: $resuts = array();
113: foreach ($keys as $key) {
114: $file = $this->fetchStreamUri($key);
115: if ($this->isExpired($file)) {
116: $item = new Item($key);
117: $resuts[$key] = $item->set(unserialize(preg_replace('/^<\?php\sexit\?>/', '', file_get_contents($file), 1)));
118: }
119: }
120:
121: return $resuts;
122: }
123:
124: 125: 126: 127: 128: 129: 130: 131:
132: public function hasItem($key)
133: {
134: return $this->isExpired($this->fetchStreamUri($key));
135: }
136:
137: 138: 139: 140: 141: 142: 143: 144: 145: 146:
147: public function save(CacheItemInterface $item)
148: {
149: if ($this->cache_dir && !empty($this->cache_expire)) {
150: $f = @fopen($this->fetchStreamUri($item->getKey()), 'wb');
151: if (!$f) {
152: throw new \Exception('resource cache file cannot be created.');
153: } else {
154: fwrite($f, '<?php exit?>'.serialize($item->get()));
155: fclose($f);
156:
157: return true;
158: }
159: }
160:
161: return false;
162: }
163:
164: 165: 166: 167: 168: 169:
170: private function clearCache($dir, &$error)
171: {
172: $f = @opendir($dir);
173: if ($f) {
174: while (false !== ($text = readdir($f))) {
175: if ($text != '.' && $text != '..' && $text != 'index.php') {
176: if (is_dir($dir.$text)) {
177: $this->clearCache($dir.$text.'/', $error);
178: } elseif (is_file($dir.$text)) {
179: if (@unlink($dir.$text) === false) {
180: $error[] = $dir.$text;
181: }
182: }
183: }
184: }
185: closedir($f);
186: }
187: }
188:
189: 190: 191: 192: 193: 194: 195:
196: private function fetchStreamUri($key)
197: {
198: return $this->cache_dir.md5($key).'.php';
199: }
200:
201: 202: 203: 204: 205: 206: 207: 208:
209: private function isExpired($file)
210: {
211: if ($this->cache_dir && !empty($this->cache_expire)) {
212: return file_exists($file) && time() - filemtime($file) < $this->cache_expire;
213: }
214:
215: return false;
216: }
217: }
218: