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 | |||
3 | namespace Spatie\Valuestore; |
||
4 | |||
5 | use Countable; |
||
6 | use ArrayAccess; |
||
7 | |||
8 | class Valuestore implements ArrayAccess, Countable |
||
9 | { |
||
10 | /** @var string */ |
||
11 | protected $fileName; |
||
12 | |||
13 | /** |
||
14 | * @param string $fileName |
||
15 | * @param array|null $values |
||
16 | * |
||
17 | * @return $this |
||
18 | */ |
||
19 | public static function make(string $fileName, array $values = null) |
||
20 | { |
||
21 | $valuestore = (new static())->setFileName($fileName); |
||
22 | |||
23 | if (! is_null($values)) { |
||
24 | $valuestore->put($values); |
||
25 | } |
||
26 | |||
27 | return $valuestore; |
||
28 | } |
||
29 | |||
30 | protected function __construct() |
||
31 | { |
||
32 | } |
||
33 | |||
34 | /** |
||
35 | * Set the filename where all values will be stored. |
||
36 | * |
||
37 | * @param string $fileName |
||
38 | * |
||
39 | * @return $this |
||
40 | */ |
||
41 | protected function setFileName(string $fileName) |
||
42 | { |
||
43 | $this->fileName = $fileName; |
||
44 | |||
45 | return $this; |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * Put a value in the store. |
||
50 | * |
||
51 | * @param string|array $name |
||
52 | * @param string|int|null $value |
||
53 | * |
||
54 | * @return $this |
||
55 | */ |
||
56 | public function put($name, $value = null) |
||
57 | { |
||
58 | if ($name == []) { |
||
59 | return $this; |
||
60 | } |
||
61 | |||
62 | $newValues = $name; |
||
63 | |||
64 | if (! is_array($name)) { |
||
65 | $newValues = [$name => $value]; |
||
66 | } |
||
67 | |||
68 | $newContent = array_merge($this->all(), $newValues); |
||
69 | |||
70 | $this->setContent($newContent); |
||
71 | |||
72 | return $this; |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * Push a new value into an array. |
||
77 | * |
||
78 | * @param string $name |
||
79 | * @param $pushValue |
||
80 | * |
||
81 | * @return $this |
||
82 | */ |
||
83 | View Code Duplication | public function push(string $name, $pushValue) |
|
0 ignored issues
–
show
|
|||
84 | { |
||
85 | if (! is_array($pushValue)) { |
||
86 | $pushValue = [$pushValue]; |
||
87 | } |
||
88 | |||
89 | if (! $this->has($name)) { |
||
90 | $this->put($name, $pushValue); |
||
0 ignored issues
–
show
$pushValue is of type array , but the function expects a string|integer|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
91 | |||
92 | return $this; |
||
93 | } |
||
94 | |||
95 | $oldValue = $this->get($name); |
||
96 | |||
97 | if (! is_array($oldValue)) { |
||
98 | $oldValue = [$oldValue]; |
||
99 | } |
||
100 | |||
101 | $newValue = array_merge($oldValue, $pushValue); |
||
102 | |||
103 | $this->put($name, $newValue); |
||
0 ignored issues
–
show
$newValue is of type array , but the function expects a string|integer|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
104 | |||
105 | return $this; |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Prepend a new value in an array. |
||
110 | * |
||
111 | * @param string $name |
||
112 | * @param $prependValue |
||
113 | * |
||
114 | * @return $this |
||
115 | */ |
||
116 | View Code Duplication | public function prepend(string $name, $prependValue) |
|
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. ![]() |
|||
117 | { |
||
118 | if (! is_array($prependValue)) { |
||
119 | $prependValue = [$prependValue]; |
||
120 | } |
||
121 | |||
122 | if (! $this->has($name)) { |
||
123 | $this->put($name, $prependValue); |
||
0 ignored issues
–
show
$prependValue is of type array , but the function expects a string|integer|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
124 | |||
125 | return $this; |
||
126 | } |
||
127 | |||
128 | $oldValue = $this->get($name); |
||
129 | |||
130 | if (! is_array($oldValue)) { |
||
131 | $oldValue = [$oldValue]; |
||
132 | } |
||
133 | |||
134 | $newValue = array_merge($prependValue, $oldValue); |
||
135 | |||
136 | $this->put($name, $newValue); |
||
0 ignored issues
–
show
$newValue is of type array , but the function expects a string|integer|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
137 | |||
138 | return $this; |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Get a value from the store. |
||
143 | * |
||
144 | * @param string $name |
||
145 | * @param $default |
||
146 | * |
||
147 | * @return null|string|array |
||
148 | */ |
||
149 | public function get(string $name, $default = null) |
||
150 | { |
||
151 | $all = $this->all(); |
||
152 | |||
153 | if (! array_key_exists($name, $all)) { |
||
154 | return $default; |
||
155 | } |
||
156 | |||
157 | return $all[$name]; |
||
158 | } |
||
159 | |||
160 | /* |
||
161 | * Determine if the store has a value for the given name. |
||
162 | */ |
||
163 | public function has(string $name) : bool |
||
164 | { |
||
165 | return array_key_exists($name, $this->all()); |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * Get all values from the store. |
||
170 | * |
||
171 | * @return array |
||
172 | */ |
||
173 | public function all() : array |
||
174 | { |
||
175 | if (! file_exists($this->fileName)) { |
||
176 | return []; |
||
177 | } |
||
178 | |||
179 | return json_decode(file_get_contents($this->fileName), true) ?? []; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * Get all keys starting with a given string from the store. |
||
184 | * |
||
185 | * @param string $startingWith |
||
186 | * |
||
187 | * @return array |
||
188 | */ |
||
189 | public function allStartingWith(string $startingWith = '') : array |
||
190 | { |
||
191 | $values = $this->all(); |
||
192 | |||
193 | if ($startingWith === '') { |
||
194 | return $values; |
||
195 | } |
||
196 | |||
197 | return $this->filterKeysStartingWith($values, $startingWith); |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Forget a value from the store. |
||
202 | * |
||
203 | * @param string $key |
||
204 | * |
||
205 | * @return $this |
||
206 | */ |
||
207 | public function forget(string $key) |
||
208 | { |
||
209 | $newContent = $this->all(); |
||
210 | |||
211 | unset($newContent[$key]); |
||
212 | |||
213 | $this->setContent($newContent); |
||
214 | |||
215 | return $this; |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * Flush all values from the store. |
||
220 | * |
||
221 | * @return $this |
||
222 | */ |
||
223 | public function flush() |
||
224 | { |
||
225 | return $this->setContent([]); |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * Flush all values which keys start with a given string. |
||
230 | * |
||
231 | * @param string $startingWith |
||
232 | * |
||
233 | * @return $this |
||
234 | */ |
||
235 | public function flushStartingWith(string $startingWith = '') |
||
236 | { |
||
237 | $newContent = []; |
||
238 | |||
239 | if ($startingWith !== '') { |
||
240 | $newContent = $this->filterKeysNotStartingWith($this->all(), $startingWith); |
||
241 | } |
||
242 | |||
243 | return $this->setContent($newContent); |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * Get and forget a value from the store. |
||
248 | * |
||
249 | * @param string $name |
||
250 | * |
||
251 | * @return null|string |
||
252 | */ |
||
253 | public function pull(string $name) |
||
254 | { |
||
255 | $value = $this->get($name); |
||
256 | |||
257 | $this->forget($name); |
||
258 | |||
259 | return $value; |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * Increment a value from the store. |
||
264 | * |
||
265 | * @param string $name |
||
266 | * @param int $by |
||
267 | * |
||
268 | * @return int|null|string |
||
269 | */ |
||
270 | public function increment(string $name, int $by = 1) |
||
271 | { |
||
272 | $currentValue = $this->get($name) ?? 0; |
||
273 | |||
274 | $newValue = $currentValue + $by; |
||
275 | |||
276 | $this->put($name, $newValue); |
||
277 | |||
278 | return $newValue; |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Decrement a value from the store. |
||
283 | * |
||
284 | * @param string $name |
||
285 | * @param int $by |
||
286 | * |
||
287 | * @return int|null|string |
||
288 | */ |
||
289 | public function decrement(string $name, int $by = 1) |
||
290 | { |
||
291 | return $this->increment($name, $by * -1); |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Whether a offset exists. |
||
296 | * |
||
297 | * @link http://php.net/manual/en/arrayaccess.offsetexists.php |
||
298 | * |
||
299 | * @param mixed $offset |
||
300 | * |
||
301 | * @return bool |
||
302 | */ |
||
303 | public function offsetExists($offset) |
||
304 | { |
||
305 | return $this->has($offset); |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Offset to retrieve. |
||
310 | * |
||
311 | * @link http://php.net/manual/en/arrayaccess.offsetget.php |
||
312 | * |
||
313 | * @param mixed $offset |
||
314 | * |
||
315 | * @return mixed |
||
316 | */ |
||
317 | public function offsetGet($offset) |
||
318 | { |
||
319 | return $this->get($offset); |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * Offset to set. |
||
324 | * |
||
325 | * @link http://php.net/manual/en/arrayaccess.offsetset.php |
||
326 | * |
||
327 | * @param mixed $offset |
||
328 | * @param mixed $value |
||
329 | */ |
||
330 | public function offsetSet($offset, $value) |
||
331 | { |
||
332 | $this->put($offset, $value); |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * Offset to unset. |
||
337 | * |
||
338 | * @link http://php.net/manual/en/arrayaccess.offsetunset.php |
||
339 | * |
||
340 | * @param mixed $offset |
||
341 | */ |
||
342 | public function offsetUnset($offset) |
||
343 | { |
||
344 | $this->forget($offset); |
||
345 | } |
||
346 | |||
347 | /** |
||
348 | * Count elements. |
||
349 | * |
||
350 | * @link http://php.net/manual/en/countable.count.php |
||
351 | * |
||
352 | * @return int |
||
353 | */ |
||
354 | public function count() |
||
355 | { |
||
356 | return count($this->all()); |
||
357 | } |
||
358 | |||
359 | protected function filterKeysStartingWith(array $values, string $startsWith) : array |
||
360 | { |
||
361 | return array_filter($values, function ($key) use ($startsWith) { |
||
362 | return $this->startsWith($key, $startsWith); |
||
363 | }, ARRAY_FILTER_USE_KEY); |
||
364 | } |
||
365 | |||
366 | protected function filterKeysNotStartingWith(array $values, string $startsWith) : array |
||
367 | { |
||
368 | return array_filter($values, function ($key) use ($startsWith) { |
||
369 | return ! $this->startsWith($key, $startsWith); |
||
370 | }, ARRAY_FILTER_USE_KEY); |
||
371 | } |
||
372 | |||
373 | protected function startsWith(string $haystack, string $needle) : bool |
||
374 | { |
||
375 | return substr($haystack, 0, strlen($needle)) === $needle; |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * @param array $values |
||
380 | * |
||
381 | * @return $this |
||
382 | */ |
||
383 | protected function setContent(array $values) |
||
384 | { |
||
385 | file_put_contents($this->fileName, json_encode($values)); |
||
386 | |||
387 | if (! count($values)) { |
||
388 | unlink($this->fileName); |
||
389 | } |
||
390 | |||
391 | return $this; |
||
392 | } |
||
393 | } |
||
394 |
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.