This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace Mouf\Utils\Cache; |
||
3 | use Mouf\Utils\Log\LogInterface; |
||
4 | use Psr\Log\LoggerInterface; |
||
5 | |||
6 | /** |
||
7 | * This package contains a cache mechanism that relies on temporary files. |
||
8 | * |
||
9 | * IMPORTANT: unless you have a good reason to do otherwise, you should use the PhpFileCache instead of this class. |
||
10 | * |
||
11 | * TODO: make a global garbage collector that passes sometimes (like sessions in PHP) |
||
12 | * |
||
13 | */ |
||
14 | class FileCache implements CacheInterface { |
||
15 | |||
16 | /** |
||
17 | * The default time to live of elements stored in the session (in seconds). |
||
18 | * Please note that if the session is flushed, all the elements of the cache will disapear anyway. |
||
19 | * If empty, the time to live will be the time of the session. |
||
20 | * |
||
21 | * @Property |
||
22 | * @var int |
||
23 | */ |
||
24 | public $defaultTimeToLive; |
||
25 | |||
26 | /** |
||
27 | * A prefix to be added to all the keys of the cache. Very useful to avoid conflicting name between different instances. |
||
28 | * |
||
29 | * @var string |
||
30 | */ |
||
31 | public $prefix = ""; |
||
32 | |||
33 | /** |
||
34 | * The logger used to trace the cache activity. |
||
35 | * Supports both PSR3 compatible logger and old Mouf logger for compatibility reasons. |
||
36 | * |
||
37 | * @var LoggerInterface|LogInterface |
||
38 | */ |
||
39 | public $log; |
||
40 | |||
41 | /** |
||
42 | * The directory the files are stored in. |
||
43 | * If none is specified, they are stored in the "filecache" directory. |
||
44 | * The directory must end with a trailing "/". |
||
45 | * |
||
46 | * @Property |
||
47 | * @var string |
||
48 | */ |
||
49 | public $cacheDirectory; |
||
50 | |||
51 | /** |
||
52 | * Whether the directory is relative to the system temp directory or not. |
||
53 | * |
||
54 | * @Property |
||
55 | * @var boolean |
||
56 | */ |
||
57 | public $relativeToSystemTempDirectory = true; |
||
58 | |||
59 | /** |
||
60 | * Returns the cached value for the key passed in parameter. |
||
61 | * |
||
62 | * @param string $key |
||
63 | * @return mixed |
||
64 | */ |
||
65 | public function get($key) { |
||
66 | $filename = $this->getFileName($key); |
||
67 | |||
68 | if (is_readable($filename)) { |
||
69 | $fp = fopen($filename, "r"); |
||
70 | if ($fp === false) {//File may have been deleted between is_readable and fopen |
||
71 | return null; |
||
72 | } |
||
73 | flock($fp, LOCK_SH); |
||
74 | $timeout = fgets($fp); |
||
75 | |||
76 | if ($timeout > time() || $timeout==0) { |
||
77 | $contents = ""; |
||
78 | while (!feof($fp)) { |
||
79 | $contents .= fread($fp, 65536); |
||
80 | } |
||
81 | flock($fp, LOCK_UN); |
||
82 | fclose($fp); |
||
83 | $value = unserialize($contents); |
||
84 | //$this->log->trace("Retrieving key '$key' from file cache: value returned:".var_export($value, true)); |
||
85 | if ($this->log) { |
||
86 | if ($this->log instanceof LoggerInterface) { |
||
87 | $this->log->info("Retrieving key '{key}' from file cache.", array('key'=>$key)); |
||
88 | } else { |
||
89 | $this->log->trace("Retrieving key '$key' from file cache."); |
||
90 | } |
||
91 | } |
||
92 | return $value; |
||
93 | View Code Duplication | } else { |
|
0 ignored issues
–
show
|
|||
94 | flock($fp, LOCK_UN); |
||
95 | fclose($fp); |
||
96 | unlink($filename); |
||
97 | if ($this->log) { |
||
98 | if ($this->log instanceof LoggerInterface) { |
||
99 | $this->log->info("Retrieving key '{key}' from file cache: key outdated, cache miss.", array('key'=>$key)); |
||
100 | } else { |
||
101 | $this->log->trace("Retrieving key '$key' from file cache: key outdated, cache miss."); |
||
102 | } |
||
103 | } |
||
104 | return null; |
||
105 | } |
||
106 | } else { |
||
107 | if ($this->log) { |
||
108 | if ($this->log instanceof LoggerInterface) { |
||
109 | $this->log->info("Retrieving key '{key}' from file cache: cache miss.", array('key'=>$key)); |
||
110 | } else { |
||
111 | $this->log->trace("Retrieving key '$key' from file cache: cache miss."); |
||
112 | } |
||
113 | } |
||
114 | return null; |
||
115 | } |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Sets the value in the cache. |
||
120 | * |
||
121 | * @param string $key The key of the value to store |
||
122 | * @param mixed $value The value to store |
||
123 | * @param float $timeToLive The time to live of the cache, in seconds. |
||
124 | */ |
||
125 | public function set($key, $value, $timeToLive = null) { |
||
126 | $filename = $this->getFileName($key); |
||
127 | //$this->log->trace("Storing value in cache: key '$key', value '".var_export($value, true)."'"); |
||
128 | if ($this->log) { |
||
129 | if ($this->log instanceof LoggerInterface) { |
||
130 | $this->log->info("Storing value in cache: key '{key}'", array('key'=>$key)); |
||
131 | } else { |
||
132 | $this->log->trace("Storing value in cache: key '$key'"); |
||
133 | } |
||
134 | } |
||
135 | |||
136 | $oldUmask = umask(0); |
||
137 | |||
138 | View Code Duplication | if (!is_writable($filename)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
139 | if (!file_exists($this->getDirectory())) { |
||
140 | mkdir($this->getDirectory(), 0777, true); |
||
141 | } |
||
142 | } |
||
143 | |||
144 | View Code Duplication | if ($timeToLive == null) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
145 | if (empty($this->defaultTimeToLive)) { |
||
146 | $timeOut = 0; |
||
147 | } else { |
||
148 | $timeOut = time() + $this->defaultTimeToLive; |
||
149 | } |
||
150 | } else { |
||
151 | $timeOut = time() + $timeToLive; |
||
152 | } |
||
153 | |||
154 | $fp = fopen($filename, "w"); |
||
155 | flock($fp, LOCK_EX); |
||
156 | fwrite($fp, $timeOut."\n"); |
||
157 | fwrite($fp, serialize($value)); |
||
158 | fflush($fp); |
||
159 | flock($fp, LOCK_UN); |
||
160 | fclose($fp); |
||
161 | // Cache is shared with group, not with the rest of the world. |
||
162 | chmod($filename, 0660); |
||
163 | |||
164 | umask($oldUmask); |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Removes the object whose key is $key from the cache. |
||
169 | * |
||
170 | * @param string $key The key of the object |
||
171 | */ |
||
172 | View Code Duplication | public function purge($key) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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. ![]() |
|||
173 | if ($this->log) { |
||
174 | if ($this->log instanceof LoggerInterface) { |
||
175 | $this->log->info("Purging key '{key}' from file cache.", array('key'=>$key)); |
||
176 | } else { |
||
177 | $this->log->trace("Purging key '$key' from file cache."); |
||
178 | } |
||
179 | } |
||
180 | $filename = $this->getFileName($key); |
||
181 | if (file_exists($filename)) { |
||
182 | unlink($filename); |
||
183 | } |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * Removes all the objects from the cache. |
||
188 | * |
||
189 | */ |
||
190 | public function purgeAll() { |
||
191 | if ($this->log) { |
||
192 | if ($this->log instanceof LoggerInterface) { |
||
193 | $this->log->info("Purging the whole file cache."); |
||
194 | } else { |
||
195 | $this->log->trace("Purging the whole file cache."); |
||
196 | } |
||
197 | } |
||
198 | $files = glob($this->getDirectory()."*"); |
||
199 | if (false !== $files){// some file systems wont distinguish between empty match and an error |
||
200 | $prefixFile = str_replace(array("_", "/", "\\", ":"), array("___", "_s_", "_b_", "_d_"), $this->prefix); |
||
201 | foreach ($files as $filename) { |
||
202 | if (empty($prefixFile) || strpos(basename($filename), $prefixFile) === 0) { |
||
203 | unlink($filename); |
||
204 | } |
||
205 | } |
||
206 | } |
||
207 | } |
||
208 | |||
209 | protected function getDirectory() { |
||
210 | |||
211 | $dir = ""; |
||
212 | if ($this->relativeToSystemTempDirectory) { |
||
213 | $dir .= sys_get_temp_dir()."/"; |
||
214 | } |
||
215 | if (!empty($this->cacheDirectory)) { |
||
216 | $dir .= $this->cacheDirectory; |
||
217 | } else { |
||
218 | $dir .= "filecache/"; |
||
219 | } |
||
220 | return $dir; |
||
221 | } |
||
222 | |||
223 | protected function getFileName($key) { |
||
224 | // Remove any "/" and ":" from the name, and replace those with "_" ... |
||
225 | $key = str_replace(array("_", "/", "\\", ":"), array("___", "_s_", "_b_", "_d_"), $this->prefix.$key); |
||
226 | |||
227 | // Windows full path need to be less than 260 characters. We need to limit the size of the filename |
||
228 | $fullPath = $this->getDirectory().$key.".cache"; |
||
229 | |||
230 | // Approximative value due to NTFS short file names (e.g. PROGRA~1) that get longer when evaluated by Windows |
||
231 | if (strlen($fullPath)<160) { |
||
232 | return $fullPath; |
||
233 | } |
||
234 | |||
235 | $prefix = str_replace(array("_", "/", "\\", ":"), array("___", "_s_", "_b_", "_d_"), $this->prefix); |
||
236 | |||
237 | // If we go above 160 characters, let's transform the key into a md5 |
||
238 | |||
239 | return $this->getDirectory().$prefix.md5($key).'.cache'; |
||
240 | } |
||
241 | } |
||
242 |
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.