1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace BlueCache\Storage; |
4
|
|
|
|
5
|
|
|
use Psr\Cache\CacheItemInterface; |
6
|
|
|
use BlueCache\CacheException; |
7
|
|
|
|
8
|
|
|
class File implements StorageInterface |
9
|
|
|
{ |
10
|
|
|
const CACHE_EXTENSION = '.cache'; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* @var array |
14
|
|
|
*/ |
15
|
|
|
protected $params = [ |
16
|
|
|
'cache_path' => './var/cache', |
17
|
|
|
]; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var array |
21
|
|
|
*/ |
22
|
|
|
protected $currentCache = []; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @param array $params |
26
|
|
|
*/ |
27
|
33 |
|
public function __construct(array $params = []) |
28
|
|
|
{ |
29
|
33 |
|
$this->params = array_merge($this->params, $params); |
30
|
33 |
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @param CacheItemInterface $item |
34
|
|
|
* @return bool |
35
|
|
|
* @throws \BlueCache\CacheException |
36
|
|
|
*/ |
37
|
24 |
|
public function store(CacheItemInterface $item) |
38
|
|
|
{ |
39
|
24 |
|
$data = serialize($item); |
40
|
24 |
|
$key = $item->getKey(); |
41
|
|
|
|
42
|
24 |
|
$cacheFile = $this->getFilePath($key); |
43
|
24 |
|
$dir = $this->params['cache_path']; |
44
|
|
|
|
45
|
24 |
|
if (!file_exists($dir) && !is_dir($dir)) { |
46
|
1 |
|
throw new CacheException('Unable to create cache directory: ' . $this->params['cache_path']); |
47
|
|
|
} |
48
|
|
|
|
49
|
23 |
|
if (!@file_put_contents($cacheFile, $data)) { |
50
|
1 |
|
throw new CacheException('Unable to save log file: ' . $cacheFile); |
51
|
|
|
} |
52
|
|
|
|
53
|
23 |
|
return true; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @param array|string $names |
58
|
|
|
* @return array|null|CacheItemInterface |
59
|
|
|
*/ |
60
|
8 |
|
public function restore($names) |
61
|
|
|
{ |
62
|
8 |
|
if (\is_array($names)) { |
63
|
3 |
|
return $this->processNames($names); |
64
|
|
|
} |
65
|
|
|
|
66
|
5 |
|
return $this->getItem($names); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param array $names |
71
|
|
|
* @return array |
72
|
|
|
*/ |
73
|
3 |
|
protected function processNames(array $names) |
74
|
|
|
{ |
75
|
3 |
|
$list = []; |
76
|
|
|
|
77
|
3 |
|
foreach ($names as $name) { |
78
|
3 |
|
$list[$name] = $this->getItem($name); |
79
|
3 |
|
} |
80
|
|
|
|
81
|
3 |
|
return $list; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* @param array|string|null $names |
86
|
|
|
* @return bool |
87
|
|
|
* @throws \BlueCache\CacheException |
88
|
|
|
*/ |
89
|
7 |
|
public function clear($names = null) |
90
|
|
|
{ |
91
|
7 |
|
switch (true) { |
92
|
7 |
|
case \is_null($names): |
93
|
3 |
|
$cacheDir = $this->params['cache_path'] . DIRECTORY_SEPARATOR; |
94
|
3 |
|
$this->currentCache = []; |
95
|
|
|
|
96
|
3 |
|
return $this->clearMany(glob($cacheDir . '*.cache'), false); |
97
|
|
|
|
98
|
5 |
|
case \is_array($names): |
99
|
2 |
|
return $this->clearMany($names); |
100
|
|
|
|
101
|
5 |
|
case \is_string($names): |
102
|
4 |
|
return $this->delete($names); |
103
|
|
|
|
104
|
1 |
|
default: |
105
|
1 |
|
throw new CacheException('Invalid type: ' . $names); |
106
|
|
|
break; |
107
|
1 |
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @param string $key |
112
|
|
|
* @return bool |
113
|
|
|
*/ |
114
|
21 |
|
public function exists($key) |
115
|
|
|
{ |
116
|
|
|
/** @var CacheItemInterface|null $item */ |
117
|
21 |
|
$item = $this->getCacheItem($key); |
118
|
|
|
|
119
|
21 |
|
if (\is_null($item)) { |
120
|
17 |
|
return false; |
121
|
|
|
} |
122
|
|
|
|
123
|
19 |
|
return $item->isHit(); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @param string $key |
128
|
|
|
* @return CacheItemInterface|null |
129
|
|
|
*/ |
130
|
8 |
|
protected function getItem($key) |
131
|
|
|
{ |
132
|
8 |
|
if ($this->exists($key)) { |
133
|
7 |
|
return $this->currentCache[$key]; |
134
|
|
|
} |
135
|
|
|
|
136
|
1 |
|
return null; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @param string $key |
141
|
|
|
* @return CacheItemInterface|null |
142
|
|
|
*/ |
143
|
21 |
|
protected function getCacheItem($key) |
144
|
|
|
{ |
145
|
21 |
|
if (!isset($this->currentCache[$key])) { |
146
|
21 |
|
if (file_exists($this->getFilePath($key))) { |
147
|
20 |
|
return $this->getUnserializedCacheItem($key); |
148
|
|
|
} |
149
|
|
|
|
150
|
16 |
|
return null; |
151
|
|
|
} |
152
|
|
|
|
153
|
6 |
|
return $this->currentCache[$key]; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @param string $key |
158
|
|
|
* @return null|CacheItemInterface |
159
|
|
|
*/ |
160
|
20 |
|
protected function getUnserializedCacheItem($key) |
161
|
|
|
{ |
162
|
|
|
/** @var CacheItemInterface $item */ |
163
|
20 |
|
$item = unserialize($this->getCacheContent($key)); |
164
|
|
|
|
165
|
20 |
|
if (!$item->isHit()) { |
166
|
1 |
|
$this->delete($key); |
167
|
1 |
|
return null; |
168
|
|
|
} |
169
|
|
|
|
170
|
19 |
|
$this->currentCache[$key] = $item; |
171
|
19 |
|
return $item; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* @param string $key |
176
|
|
|
* @return bool|string |
177
|
|
|
*/ |
178
|
20 |
|
protected function getCacheContent($key) |
179
|
|
|
{ |
180
|
20 |
|
return file_get_contents($this->getFilePath($key)); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* @param array $list |
185
|
|
|
* @param bool $isKey |
186
|
|
|
* @return bool |
187
|
|
|
*/ |
188
|
4 |
View Code Duplication |
protected function clearMany(array $list, $isKey = true) |
|
|
|
|
189
|
|
|
{ |
190
|
4 |
|
$flag = true; |
191
|
|
|
|
192
|
4 |
|
foreach ($list as $name) { |
193
|
4 |
|
$deleted = $this->delete($name, $isKey); |
194
|
|
|
|
195
|
4 |
|
if (!$deleted) { |
196
|
|
|
$flag = false; |
197
|
|
|
} |
198
|
4 |
|
} |
199
|
|
|
|
200
|
4 |
|
return $flag; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* @param string $key |
205
|
|
|
* @param bool $isKey |
206
|
|
|
* @return bool |
207
|
|
|
*/ |
208
|
7 |
|
protected function delete($key, $isKey = true) |
209
|
|
|
{ |
210
|
7 |
|
if ($isKey) { |
211
|
5 |
|
unset($this->currentCache[$key]); |
212
|
5 |
|
$key = $this->getFilePath($key); |
213
|
5 |
|
} |
214
|
|
|
|
215
|
7 |
|
return unlink($key); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* @param string $key |
220
|
|
|
* @return string |
221
|
|
|
*/ |
222
|
25 |
|
protected function getFilePath($key) |
223
|
|
|
{ |
224
|
25 |
|
return $this->params['cache_path'] . DIRECTORY_SEPARATOR . $key . self::CACHE_EXTENSION; |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.