1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
* This file is part of phpFastCache. |
5
|
|
|
* |
6
|
|
|
* @license MIT License (MIT) |
7
|
|
|
* |
8
|
|
|
* For full copyright and license information, please see the docs/CREDITS.txt file. |
9
|
|
|
* |
10
|
|
|
* @author Khoa Bui (khoaofgod) <[email protected]> http://www.phpfastcache.com |
11
|
|
|
* @author Georges.L (Geolim4) <[email protected]> |
12
|
|
|
* |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace phpFastCache\Drivers\Files; |
16
|
|
|
|
17
|
|
|
use phpFastCache\Cache\ExtendedCacheItemInterface; |
18
|
|
|
use phpFastCache\Core\DriverAbstract; |
19
|
|
|
use phpFastCache\Core\PathSeekerTrait; |
20
|
|
|
use phpFastCache\Core\StandardPsr6StructureTrait; |
21
|
|
|
use phpFastCache\Entities\driverStatistic; |
22
|
|
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException; |
23
|
|
|
use phpFastCache\Exceptions\phpFastCacheDriverException; |
24
|
|
|
use phpFastCache\Util\Directory; |
25
|
|
|
use Psr\Cache\CacheItemInterface; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Class Driver |
29
|
|
|
* @package phpFastCache\Drivers |
30
|
|
|
*/ |
31
|
|
|
class Driver extends DriverAbstract |
32
|
|
|
{ |
33
|
|
|
use PathSeekerTrait, StandardPsr6StructureTrait; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Driver constructor. |
37
|
|
|
* @param array $config |
38
|
|
|
* @throws phpFastCacheDriverException |
39
|
|
|
*/ |
40
|
|
|
public function __construct(array $config = []) |
41
|
|
|
{ |
42
|
|
|
$this->setup($config); |
43
|
|
|
|
44
|
|
|
if (!$this->driverCheck()) { |
45
|
|
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName())); |
46
|
|
|
} |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @return bool |
51
|
|
|
*/ |
52
|
|
|
public function driverCheck() |
53
|
|
|
{ |
54
|
|
|
return is_writable($this->getPath()); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @param \Psr\Cache\CacheItemInterface $item |
59
|
|
|
* @return mixed |
60
|
|
|
* @throws \InvalidArgumentException |
61
|
|
|
*/ |
62
|
|
|
public function driverWrite(CacheItemInterface $item) |
63
|
|
|
{ |
64
|
|
|
/** |
65
|
|
|
* Check for Cross-Driver type confusion |
66
|
|
|
*/ |
67
|
|
|
if ($item instanceof Item) { |
68
|
|
|
$file_path = $this->getFilePath($item->getKey()); |
69
|
|
|
$data = $this->encode($this->driverPreWrap($item)); |
70
|
|
|
|
71
|
|
|
$toWrite = true; |
72
|
|
|
/* |
73
|
|
|
* Skip if Existing Caching in Options |
74
|
|
|
*/ |
75
|
|
|
if (isset($option[ 'skipExisting' ]) && $option[ 'skipExisting' ] == true && file_exists($file_path)) { |
|
|
|
|
76
|
|
|
$content = $this->readfile($file_path); |
77
|
|
|
$old = $this->decode($content); |
78
|
|
|
$toWrite = false; |
79
|
|
|
if ($old->isExpired()) { |
80
|
|
|
$toWrite = true; |
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
// Force write |
85
|
|
|
try { |
86
|
|
|
if ($toWrite == true) { |
|
|
|
|
87
|
|
|
$f = fopen($file_path, 'w+'); |
88
|
|
|
fwrite($f, $data); |
89
|
|
|
fclose($f); |
90
|
|
|
|
91
|
|
|
return true; |
92
|
|
|
} |
93
|
|
|
} catch (\Exception $e) { |
94
|
|
|
return false; |
95
|
|
|
} |
96
|
|
|
} else { |
97
|
|
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected'); |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @param string $key |
103
|
|
|
* @return mixed |
104
|
|
|
* @throws \InvalidArgumentException |
105
|
|
|
*/ |
106
|
|
|
public function driverRead($key) |
107
|
|
|
{ |
108
|
|
|
/** |
109
|
|
|
* Check for Cross-Driver type confusion |
110
|
|
|
*/ |
111
|
|
|
$file_path = $this->getFilePath($key); |
112
|
|
|
if (!file_exists($file_path)) { |
113
|
|
|
return null; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$content = $this->readfile($file_path); |
117
|
|
|
$object = $this->decode($content); |
118
|
|
|
|
119
|
|
|
if ($this->driverUnwrapTime($object)->getTimestamp() < time()) { |
120
|
|
|
@unlink($file_path); |
|
|
|
|
121
|
|
|
|
122
|
|
|
return null; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
return $object; |
126
|
|
|
|
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @param \Psr\Cache\CacheItemInterface $item |
131
|
|
|
* @return bool |
132
|
|
|
* @throws \InvalidArgumentException |
133
|
|
|
*/ |
134
|
|
|
public function driverDelete(CacheItemInterface $item) |
135
|
|
|
{ |
136
|
|
|
/** |
137
|
|
|
* Check for Cross-Driver type confusion |
138
|
|
|
*/ |
139
|
|
|
if ($item instanceof Item) { |
140
|
|
|
$file_path = $this->getFilePath($item->getKey(), true); |
141
|
|
|
if (file_exists($file_path) && @unlink($file_path)) { |
|
|
|
|
142
|
|
|
return true; |
143
|
|
|
} else { |
144
|
|
|
return false; |
145
|
|
|
} |
146
|
|
|
} else { |
147
|
|
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected'); |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @return bool |
153
|
|
|
*/ |
154
|
|
|
public function driverClear() |
155
|
|
|
{ |
156
|
|
|
$return = null; |
157
|
|
|
$path = $this->getFilePath(false); |
158
|
|
|
$dir = @opendir($path); |
|
|
|
|
159
|
|
|
if (!$dir) { |
160
|
|
|
throw new phpFastCacheDriverException("Can't read PATH:" . $path); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
while ($file = readdir($dir)) { |
164
|
|
|
if ($file != '.' && $file != '..' && is_dir($path . '/' . $file)) { |
165
|
|
|
// read sub dir |
166
|
|
|
$subdir = @opendir($path . '/' . $file); |
|
|
|
|
167
|
|
|
if (!$subdir) { |
168
|
|
|
throw new phpFastCacheDriverException("Can't read path:" . $path . '/' . $file); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
while ($subdirFile = readdir($subdir)) { |
172
|
|
|
if ($subdirFile != '.' && $subdirFile != '..') { |
173
|
|
|
$file_path = $path . '/' . $file . '/' . $subdirFile; |
174
|
|
|
$result = @unlink($file_path); |
|
|
|
|
175
|
|
|
if ($return !== false) { |
176
|
|
|
$return = $result; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
return (bool) $return; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* @return bool |
188
|
|
|
*/ |
189
|
|
|
public function driverConnect() |
190
|
|
|
{ |
191
|
|
|
return true; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* @param \Psr\Cache\CacheItemInterface $item |
196
|
|
|
* @return bool |
197
|
|
|
* @throws \InvalidArgumentException |
198
|
|
|
*/ |
199
|
|
|
public function driverIsHit(CacheItemInterface $item) |
200
|
|
|
{ |
201
|
|
|
$file_path = $this->getFilePath($item->getKey(), true); |
202
|
|
|
if (!file_exists($file_path)) { |
203
|
|
|
return false; |
204
|
|
|
} else { |
205
|
|
|
// check expired or not |
206
|
|
|
$value = $this->driverRead($item->getKey()); |
207
|
|
|
|
208
|
|
|
return !($value == null); |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* @param string $optionName |
214
|
|
|
* @param mixed $optionValue |
215
|
|
|
* @return bool |
216
|
|
|
* @throws \InvalidArgumentException |
217
|
|
|
*/ |
218
|
|
|
public static function isValidOption($optionName, $optionValue) |
219
|
|
|
{ |
220
|
|
|
parent::isValidOption($optionName, $optionValue); |
221
|
|
|
switch($optionName) |
222
|
|
|
{ |
223
|
|
|
case 'path': |
224
|
|
|
return is_string($optionValue); |
225
|
|
|
break; |
|
|
|
|
226
|
|
|
|
227
|
|
|
case 'default_chmod': |
228
|
|
|
return is_numeric($optionValue); |
229
|
|
|
break; |
|
|
|
|
230
|
|
|
|
231
|
|
|
case 'securityKey': |
232
|
|
|
return is_string($optionValue); |
233
|
|
|
break; |
|
|
|
|
234
|
|
|
case 'htaccess': |
235
|
|
|
return is_bool($optionValue); |
236
|
|
|
break; |
|
|
|
|
237
|
|
|
default: |
238
|
|
|
return false; |
239
|
|
|
break; |
|
|
|
|
240
|
|
|
} |
241
|
|
|
} |
242
|
|
|
/** |
243
|
|
|
* @return array |
244
|
|
|
*/ |
245
|
|
|
public static function getValidOptions() |
246
|
|
|
{ |
247
|
|
|
return ['path', 'default_chmod', 'securityKey', 'htaccess']; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @return array |
252
|
|
|
*/ |
253
|
|
|
public static function getRequiredOptions() |
254
|
|
|
{ |
255
|
|
|
return ['path']; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/******************** |
259
|
|
|
* |
260
|
|
|
* PSR-6 Extended Methods |
261
|
|
|
* |
262
|
|
|
*******************/ |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* @return driverStatistic |
266
|
|
|
* @throws \phpFastCache\Exceptions\phpFastCacheCoreException |
267
|
|
|
* @throws \phpFastCache\Exceptions\phpFastCacheDriverException |
268
|
|
|
*/ |
269
|
|
|
public function getStats() |
270
|
|
|
{ |
271
|
|
|
$stat = new driverStatistic(); |
272
|
|
|
$path = $this->getFilePath(false); |
273
|
|
|
|
274
|
|
|
if (!is_dir($path)) { |
275
|
|
|
throw new phpFastCacheDriverException("Can't read PATH:" . $path, 94); |
276
|
|
|
}else{ |
277
|
|
|
$size = Directory::dirSize($path); |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
$stat->setData('') |
281
|
|
|
->setSize($size) |
282
|
|
|
->setInfo('Number of files used to build the cache: ' . Directory::getFileCount($path)); |
283
|
|
|
|
284
|
|
|
return $stat; |
285
|
|
|
} |
286
|
|
|
} |
This check looks for calls to
isset(...)
orempty()
on variables that are yet undefined. These calls will always produce the same result and can be removed.This is most likely caused by the renaming of a variable or the removal of a function/method parameter.