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 | /* |
||
4 | * This file is part of the puli/manager package. |
||
5 | * |
||
6 | * (c) Bernhard Schussek <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Puli\Manager\Api\Config; |
||
13 | |||
14 | use Puli\Manager\Api\InvalidConfigException; |
||
15 | |||
16 | /** |
||
17 | * Stores configuration values. |
||
18 | * |
||
19 | * Use the methods {@link get()}, {@link set()} and {@link merge()} to retrieve |
||
20 | * and store values: |
||
21 | * |
||
22 | * ```php |
||
23 | * $config = new Config(); |
||
24 | * $config->set(Config::PULI_DIR, '.puli'); |
||
25 | * |
||
26 | * echo $config->get(Config::PULI_DIR); |
||
27 | * // => .puli |
||
28 | * ``` |
||
29 | * |
||
30 | * You can customize the value returned by {@link get()} if a key is not set |
||
31 | * by passing that value in the second parameter: |
||
32 | * |
||
33 | * ```php |
||
34 | * $config = new Config(); |
||
35 | * |
||
36 | * echo $config->get(Config::PULI_DIR, '.puli'); |
||
37 | * ``` |
||
38 | * |
||
39 | * A configuration may also inherit default values from another configuration: |
||
40 | * |
||
41 | * ```php |
||
42 | * $defaultConfig = new Config(); |
||
43 | * $defaultConfig->set(Config::PULI_DIR, '.puli'); |
||
44 | * |
||
45 | * $config = new Config($defaultConfig); |
||
46 | * |
||
47 | * $config->get(Config::PULI_DIR); |
||
48 | * // => .puli |
||
49 | * ``` |
||
50 | * |
||
51 | * You can disable the fallback to the default value by passing `false` to |
||
52 | * {@link get()}: |
||
53 | * |
||
54 | * ```php |
||
55 | * $defaultConfig = new Config(); |
||
56 | * $defaultConfig->set(Config::PULI_DIR, '.puli'); |
||
57 | * |
||
58 | * $config = new Config($defaultConfig); |
||
59 | * |
||
60 | * $config->get(Config::PULI_DIR, null, false); |
||
61 | * // => null |
||
62 | * ``` |
||
63 | * |
||
64 | * Configuration values support placeholders for other values in the format |
||
65 | * `{$<key>}`. These placeholders will be replaced by the actual values of the |
||
66 | * referenced keys when the values are accessed: |
||
67 | * |
||
68 | * ```php |
||
69 | * $config = new Config(); |
||
70 | * $config->set(Config::PULI_DIR, '.puli'); |
||
71 | * $config->set(Config::FACTORY_FILE, '{$puli-dir}/PuliFactory.php'); |
||
72 | * |
||
73 | * echo $config->get(Config::FACTORY_FILE); |
||
74 | * // => .puli/PuliRegistry.php |
||
75 | * ``` |
||
76 | * |
||
77 | * @since 1.0 |
||
78 | * |
||
79 | * @author Bernhard Schussek <[email protected]> |
||
80 | */ |
||
81 | class Config |
||
82 | { |
||
83 | const PULI_DIR = 'puli-dir'; |
||
84 | |||
85 | const BOOTSTRAP_FILE = 'bootstrap-file'; |
||
86 | |||
87 | const FACTORY = 'factory'; |
||
88 | |||
89 | const FACTORY_AUTO_GENERATE = 'factory.auto-generate'; |
||
90 | |||
91 | const FACTORY_IN = 'factory.in'; |
||
92 | |||
93 | const FACTORY_IN_CLASS = 'factory.in.class'; |
||
94 | |||
95 | const FACTORY_IN_FILE = 'factory.in.file'; |
||
96 | |||
97 | const FACTORY_OUT = 'factory.out'; |
||
98 | |||
99 | const FACTORY_OUT_CLASS = 'factory.out.class'; |
||
100 | |||
101 | const FACTORY_OUT_FILE = 'factory.out.file'; |
||
102 | |||
103 | const REPOSITORY = 'repository'; |
||
104 | |||
105 | const REPOSITORY_TYPE = 'repository.type'; |
||
106 | |||
107 | const REPOSITORY_PATH = 'repository.path'; |
||
108 | |||
109 | const REPOSITORY_SYMLINK = 'repository.symlink'; |
||
110 | |||
111 | const REPOSITORY_OPTIMIZE = 'repository.optimize'; |
||
112 | |||
113 | const REPOSITORY_STORE = 'repository.store'; |
||
114 | |||
115 | const REPOSITORY_STORE_TYPE = 'repository.store.type'; |
||
116 | |||
117 | const REPOSITORY_STORE_PATH = 'repository.store.path'; |
||
118 | |||
119 | const REPOSITORY_STORE_HOST = 'repository.store.host'; |
||
120 | |||
121 | const REPOSITORY_STORE_PORT = 'repository.store.port'; |
||
122 | |||
123 | const REPOSITORY_STORE_BUCKET = 'repository.store.bucket'; |
||
124 | |||
125 | const REPOSITORY_STORE_CACHE = 'repository.store.cache'; |
||
126 | |||
127 | const CHANGE_STREAM = 'change-stream'; |
||
128 | |||
129 | const CHANGE_STREAM_TYPE = 'change-stream.type'; |
||
130 | |||
131 | const CHANGE_STREAM_PATH = 'change-stream.path'; |
||
132 | |||
133 | const CHANGE_STREAM_STORE = 'change-stream.store'; |
||
134 | |||
135 | const CHANGE_STREAM_STORE_TYPE = 'change-stream.store.type'; |
||
136 | |||
137 | const CHANGE_STREAM_STORE_PATH = 'change-stream.store.path'; |
||
138 | |||
139 | const CHANGE_STREAM_STORE_HOST = 'change-stream.store.host'; |
||
140 | |||
141 | const CHANGE_STREAM_STORE_PORT = 'change-stream.store.port'; |
||
142 | |||
143 | const CHANGE_STREAM_STORE_BUCKET = 'change-stream.store.bucket'; |
||
144 | |||
145 | const CHANGE_STREAM_STORE_CACHE = 'change-stream.store.cache'; |
||
146 | |||
147 | const DISCOVERY = 'discovery'; |
||
148 | |||
149 | const DISCOVERY_TYPE = 'discovery.type'; |
||
150 | |||
151 | const DISCOVERY_PATH = 'discovery.path'; |
||
152 | |||
153 | const DISCOVERY_STORE = 'discovery.store'; |
||
154 | |||
155 | const DISCOVERY_STORE_TYPE = 'discovery.store.type'; |
||
156 | |||
157 | const DISCOVERY_STORE_PATH = 'discovery.store.path'; |
||
158 | |||
159 | const DISCOVERY_STORE_HOST = 'discovery.store.host'; |
||
160 | |||
161 | const DISCOVERY_STORE_PORT = 'discovery.store.port'; |
||
162 | |||
163 | const DISCOVERY_STORE_BUCKET = 'discovery.store.bucket'; |
||
164 | |||
165 | const DISCOVERY_STORE_CACHE = 'discovery.store.cache'; |
||
166 | |||
167 | /** |
||
168 | * The accepted config keys. |
||
169 | * |
||
170 | * @var bool[] |
||
171 | */ |
||
172 | private static $keys = array( |
||
173 | self::PULI_DIR => true, |
||
174 | self::BOOTSTRAP_FILE => true, |
||
175 | self::FACTORY_AUTO_GENERATE => true, |
||
176 | self::FACTORY_IN_CLASS => true, |
||
177 | self::FACTORY_IN_FILE => true, |
||
178 | self::FACTORY_OUT_CLASS => true, |
||
179 | self::FACTORY_OUT_FILE => true, |
||
180 | self::REPOSITORY_TYPE => true, |
||
181 | self::REPOSITORY_PATH => true, |
||
182 | self::REPOSITORY_SYMLINK => true, |
||
183 | self::REPOSITORY_OPTIMIZE => true, |
||
184 | self::REPOSITORY_STORE_TYPE => true, |
||
185 | self::REPOSITORY_STORE_PATH => true, |
||
186 | self::REPOSITORY_STORE_HOST => true, |
||
187 | self::REPOSITORY_STORE_PORT => true, |
||
188 | self::REPOSITORY_STORE_BUCKET => true, |
||
189 | self::REPOSITORY_STORE_CACHE => true, |
||
190 | self::CHANGE_STREAM_TYPE => true, |
||
191 | self::CHANGE_STREAM_PATH => true, |
||
192 | self::CHANGE_STREAM_STORE_TYPE => true, |
||
193 | self::CHANGE_STREAM_STORE_PATH => true, |
||
194 | self::CHANGE_STREAM_STORE_HOST => true, |
||
195 | self::CHANGE_STREAM_STORE_PORT => true, |
||
196 | self::CHANGE_STREAM_STORE_BUCKET => true, |
||
197 | self::CHANGE_STREAM_STORE_CACHE => true, |
||
198 | self::DISCOVERY_TYPE => true, |
||
199 | self::DISCOVERY_PATH => true, |
||
200 | self::DISCOVERY_STORE_TYPE => true, |
||
201 | self::DISCOVERY_STORE_PATH => true, |
||
202 | self::DISCOVERY_STORE_HOST => true, |
||
203 | self::DISCOVERY_STORE_PORT => true, |
||
204 | self::DISCOVERY_STORE_BUCKET => true, |
||
205 | self::DISCOVERY_STORE_CACHE => true, |
||
206 | ); |
||
207 | |||
208 | private static $compositeKeys = array( |
||
209 | self::FACTORY => true, |
||
210 | self::FACTORY_IN => true, |
||
211 | self::FACTORY_OUT => true, |
||
212 | self::REPOSITORY => true, |
||
213 | self::REPOSITORY_STORE => true, |
||
214 | self::CHANGE_STREAM => true, |
||
215 | self::CHANGE_STREAM_STORE => true, |
||
216 | self::DISCOVERY => true, |
||
217 | self::DISCOVERY_STORE => true, |
||
218 | ); |
||
219 | |||
220 | /** |
||
221 | * The configuration values. |
||
222 | * |
||
223 | * @var array |
||
224 | */ |
||
225 | private $values = array(); |
||
226 | |||
227 | /** |
||
228 | * The configuration to fall back to. |
||
229 | * |
||
230 | * @var Config |
||
231 | */ |
||
232 | private $baseConfig; |
||
233 | |||
234 | /** |
||
235 | * Returns all valid configuration keys. |
||
236 | * |
||
237 | * @return string[] The config keys. |
||
0 ignored issues
–
show
|
|||
238 | */ |
||
239 | 20 | public static function getKeys() |
|
240 | { |
||
241 | 20 | return array_keys(self::$keys); |
|
242 | } |
||
243 | |||
244 | /** |
||
245 | * Creates a new configuration. |
||
246 | * |
||
247 | * @param Config|null $baseConfig The configuration to fall back to if a value is |
||
248 | * not set in here. |
||
249 | * @param array $values The values to initially set in the configuration. |
||
250 | */ |
||
251 | 713 | public function __construct(Config $baseConfig = null, array $values = array()) |
|
252 | { |
||
253 | 713 | $this->baseConfig = $baseConfig; |
|
254 | |||
255 | 713 | $this->merge($values); |
|
256 | 713 | } |
|
257 | |||
258 | /** |
||
259 | * Returns the base configuration. |
||
260 | * |
||
261 | * @return Config The base configuration or `null` if none is set. |
||
262 | */ |
||
263 | public function getBaseConfig() |
||
264 | { |
||
265 | return $this->baseConfig; |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * Returns the value of a configuration key. |
||
270 | * |
||
271 | * If fallback is enabled, the value of the base configuration is returned |
||
272 | * if the key was not set. |
||
273 | * |
||
274 | * You can also pass a default value in the second parameter. This default |
||
275 | * value is returned if the configuration key was neither found in this nor |
||
276 | * in its fallback configuration. |
||
277 | * |
||
278 | * @param string $key The configuration key. |
||
279 | * @param mixed $default The value to return if the key was not set. |
||
280 | * @param bool $fallback Whether to return the value of the base |
||
281 | * configuration if the key was not set. |
||
282 | * |
||
283 | * @return mixed The value of the configuration key. |
||
0 ignored issues
–
show
|
|||
284 | * |
||
285 | * @throws NoSuchConfigKeyException If the configuration key is invalid. |
||
286 | */ |
||
287 | 134 | public function get($key, $default = null, $fallback = true) |
|
288 | { |
||
289 | 134 | return $this->replacePlaceholders($this->getRaw($key, $default, $fallback), $fallback); |
|
290 | } |
||
291 | |||
292 | /** |
||
293 | * Returns the raw value of a configuration key. |
||
294 | * |
||
295 | * Unlike {@link get()}, this method does not resolve placeholders: |
||
296 | * |
||
297 | * ```php |
||
298 | * $config = new Config(); |
||
299 | * $config->set(Config::PULI_DIR, '.puli'); |
||
300 | * $config->set(Config::INSTALL_FILE, '{$puli-dir}/install-file.json'); |
||
301 | * |
||
302 | * echo $config->get(Config::PULI_DIR); |
||
303 | * // => .puli/install-file.json |
||
304 | * |
||
305 | * echo $config->getRaw(Config::PULI_DIR); |
||
306 | * // => {$puli-dir}/install-file.json |
||
307 | * ``` |
||
308 | * |
||
309 | * @param string $key The configuration key. |
||
310 | * @param mixed $default The value to return if the key was not set. |
||
311 | * @param bool $fallback Whether to return the value of the base |
||
312 | * configuration if the key was not set. |
||
313 | * |
||
314 | * @return mixed The value of the configuration key. |
||
315 | * |
||
316 | * @throws NoSuchConfigKeyException If the configuration key is invalid. |
||
317 | */ |
||
318 | 160 | public function getRaw($key, $default = null, $fallback = true) |
|
319 | { |
||
320 | 160 | if (isset(self::$compositeKeys[$key])) { |
|
321 | 47 | return array_replace_recursive( |
|
322 | 47 | is_array($default) ? $default : array(), |
|
323 | 47 | $fallback && $this->baseConfig ? $this->baseConfig->getRaw($key) : array(), |
|
324 | 47 | $this->filterByKeyPrefix($key.'.') |
|
325 | ); |
||
326 | } |
||
327 | |||
328 | 146 | if (!isset(self::$keys[$key])) { |
|
329 | 2 | throw NoSuchConfigKeyException::forKey($key); |
|
330 | } |
||
331 | |||
332 | 144 | if (!array_key_exists($key, $this->values) && $fallback && $this->baseConfig) { |
|
333 | 72 | return $this->baseConfig->getRaw($key, $default); |
|
334 | } |
||
335 | |||
336 | 144 | return isset($this->values[$key]) ? $this->values[$key] : $default; |
|
337 | } |
||
338 | |||
339 | /** |
||
340 | * Returns whether a configuration key is set. |
||
341 | * |
||
342 | * @param string $key The configuration key to search. |
||
343 | * @param bool $fallback Whether to check the base configuration if the |
||
344 | * key is not found. |
||
345 | * |
||
346 | * @return bool Returns `true` if the configuration key is set. |
||
347 | * |
||
348 | * @throws NoSuchConfigKeyException If the configuration key is invalid. |
||
349 | */ |
||
350 | 22 | public function contains($key, $fallback = true) |
|
351 | { |
||
352 | 22 | if (!isset(self::$compositeKeys[$key]) && !isset(self::$keys[$key])) { |
|
353 | 1 | throw NoSuchConfigKeyException::forKey($key); |
|
354 | } |
||
355 | |||
356 | 21 | if (array_key_exists($key, $this->values)) { |
|
357 | 13 | return true; |
|
358 | } |
||
359 | |||
360 | 16 | if (isset(self::$compositeKeys[$key]) && $this->containsKeyPrefix($key.'.')) { |
|
361 | 2 | return true; |
|
362 | } |
||
363 | |||
364 | 16 | if ($fallback && $this->baseConfig) { |
|
365 | 12 | return $this->baseConfig->contains($key); |
|
366 | } |
||
367 | |||
368 | 16 | return false; |
|
369 | } |
||
370 | |||
371 | /** |
||
372 | * Sets the value of a configuration key. |
||
373 | * |
||
374 | * @param string $key The configuration key. |
||
375 | * @param mixed $value The value to set. |
||
376 | * |
||
377 | * @throws NoSuchConfigKeyException If the configuration key is invalid. |
||
378 | * @throws InvalidConfigException If the value is invalid. |
||
379 | */ |
||
380 | 446 | public function set($key, $value) |
|
381 | { |
||
382 | 446 | if (isset(self::$compositeKeys[$key])) { |
|
383 | 7 | $this->assertArray($key, $value); |
|
384 | 7 | $this->removeByKeyPrefix($key.'.'); |
|
385 | |||
386 | 7 | foreach ($value as $k => $v) { |
|
387 | 7 | $this->set($key.'.'.$k, $v); |
|
388 | } |
||
389 | |||
390 | 7 | return; |
|
391 | } |
||
392 | |||
393 | 446 | if (!isset(self::$keys[$key])) { |
|
394 | 1 | throw NoSuchConfigKeyException::forKey($key); |
|
395 | } |
||
396 | |||
397 | 445 | $this->validate($key, $value); |
|
398 | |||
399 | 420 | $this->values[$key] = $value; |
|
400 | 420 | } |
|
401 | |||
402 | /** |
||
403 | * Sets a list of configuration values. |
||
404 | * |
||
405 | * @param array $values The values to set. |
||
406 | * |
||
407 | * @throws NoSuchConfigKeyException If a configuration key is invalid. |
||
408 | * @throws InvalidConfigException If a value is invalid. |
||
409 | */ |
||
410 | 713 | public function merge(array $values) |
|
411 | { |
||
412 | 713 | foreach ($values as $key => $value) { |
|
413 | 297 | $this->set($key, $value); |
|
414 | } |
||
415 | 713 | } |
|
416 | |||
417 | /** |
||
418 | * Replaces the configuration with a list of configuration values. |
||
419 | * |
||
420 | * @param array $values The values to set. |
||
421 | * |
||
422 | * @throws NoSuchConfigKeyException If a configuration key is invalid. |
||
423 | * @throws InvalidConfigException If a value is invalid. |
||
424 | */ |
||
425 | 4 | public function replace(array $values) |
|
426 | { |
||
427 | 4 | $this->clear(); |
|
428 | 4 | $this->merge($values); |
|
429 | 4 | } |
|
430 | |||
431 | /** |
||
432 | * Removes a configuration key. |
||
433 | * |
||
434 | * If the configuration has a base configuration, the default value will |
||
435 | * be returned by {@link get()} after removing the key. |
||
436 | * |
||
437 | * @param string $key The configuration key to remove. |
||
438 | * |
||
439 | * @throws NoSuchConfigKeyException If the configuration key is invalid. |
||
440 | */ |
||
441 | 13 | public function remove($key) |
|
442 | { |
||
443 | 13 | if (isset(self::$compositeKeys[$key])) { |
|
444 | 1 | $this->removeByKeyPrefix($key.'.'); |
|
445 | |||
446 | 1 | return; |
|
447 | } |
||
448 | |||
449 | 12 | if (!isset(self::$keys[$key])) { |
|
450 | 1 | throw NoSuchConfigKeyException::forKey($key); |
|
451 | } |
||
452 | |||
453 | 11 | unset($this->values[$key]); |
|
454 | 11 | } |
|
455 | |||
456 | /** |
||
457 | * Removes all configuration keys. |
||
458 | * |
||
459 | * If the configuration has a base configuration, the default values will |
||
460 | * be returned by {@link get()} after removing the keys. |
||
461 | */ |
||
462 | 5 | public function clear() |
|
463 | { |
||
464 | 5 | $this->values = array(); |
|
465 | 5 | } |
|
466 | |||
467 | /** |
||
468 | * Returns all configuration values as flat array. |
||
469 | * |
||
470 | * @param bool $includeFallback Whether to include values set in the base |
||
471 | * configuration passed to {@link __construct()}. |
||
472 | * |
||
473 | * @return array The configuration values. |
||
0 ignored issues
–
show
Should the return type not be
array|object|integer|double|null|boolean|string ? Also, consider making the array more specific, something like array<String> , or String[] .
This check compares the return type specified in the If the return type contains the type array, this check recommends the use of
a more specific type like ![]() |
|||
474 | */ |
||
475 | 5 | public function toFlatArray($includeFallback = true) |
|
476 | { |
||
477 | 5 | return $this->replacePlaceholders($this->toFlatRawArray($includeFallback), $includeFallback); |
|
478 | } |
||
479 | |||
480 | /** |
||
481 | * Returns all raw configuration values as flat array. |
||
482 | * |
||
483 | * Unlike {@link toFlatArray()}, this method does not resolve placeholders: |
||
484 | * |
||
485 | * ```php |
||
486 | * $config = new Config(); |
||
487 | * $config->set(Config::PULI_DIR, '.puli'); |
||
488 | * $config->set(Config::REGISTRY_FILE, '{$puli-dir}/ServiceRegistry.php'); |
||
489 | * |
||
490 | * print_r($config->toFlatArray()); |
||
491 | * // Array( |
||
492 | * // 'puli-dir' => '.puli', |
||
493 | * // 'registry-file' => '.puli/ServiceRegistry.php', |
||
494 | * // ) |
||
495 | * |
||
496 | * print_r($config->toFlatRawArray()); |
||
497 | * // Array( |
||
498 | * // 'puli-dir' => '.puli', |
||
499 | * // 'registry-file' => '{$puli-dir}/ServiceRegistry.php', |
||
500 | * // ) |
||
501 | * ``` |
||
502 | * |
||
503 | * @param bool $includeFallback Whether to include values set in the base |
||
504 | * configuration passed to {@link __construct()}. |
||
505 | * |
||
506 | * @return array The raw configuration values. |
||
507 | */ |
||
508 | 34 | public function toFlatRawArray($includeFallback = true) |
|
509 | { |
||
510 | 34 | return $includeFallback && $this->baseConfig |
|
511 | 9 | ? array_replace($this->baseConfig->toFlatRawArray(), $this->values) |
|
512 | 34 | : $this->values; |
|
513 | } |
||
514 | |||
515 | /** |
||
516 | * Returns all configuration values as nested array. |
||
517 | * |
||
518 | * @param bool $includeFallback Whether to include values set in the base |
||
519 | * configuration passed to {@link __construct()}. |
||
520 | * |
||
521 | * @return array The configuration values. |
||
0 ignored issues
–
show
Should the return type not be
array|object|integer|double|null|boolean|string ? Also, consider making the array more specific, something like array<String> , or String[] .
This check compares the return type specified in the If the return type contains the type array, this check recommends the use of
a more specific type like ![]() |
|||
522 | */ |
||
523 | 3 | public function toArray($includeFallback = true) |
|
524 | { |
||
525 | 3 | return $this->replacePlaceholders($this->toRawArray($includeFallback), $includeFallback); |
|
526 | } |
||
527 | |||
528 | /** |
||
529 | * Returns all raw configuration values as nested array. |
||
530 | * |
||
531 | * Unlike {@link toArray()}, this method does not resolve placeholders: |
||
532 | * |
||
533 | * ```php |
||
534 | * $config = new Config(); |
||
535 | * $config->set(Config::PULI_DIR, '.puli'); |
||
536 | * $config->set(Config::REPO_STORAGE_DIR, '{$puli-dir}/repository'); |
||
537 | * |
||
538 | * print_r($config->toArray()); |
||
539 | * // Array( |
||
540 | * // 'puli-dir' => '.puli', |
||
541 | * // 'repository. => array( |
||
542 | * // 'storage-dir' => '.puli/repository', |
||
543 | * // ), |
||
544 | * // ) |
||
545 | * |
||
546 | * print_r($config->toRawArray()); |
||
547 | * // Array( |
||
548 | * // 'puli-dir' => '.puli', |
||
549 | * // 'repository. => array( |
||
550 | * // 'storage-dir' => '{$puli-dir}/repository', |
||
551 | * // ), |
||
552 | * // ) |
||
553 | * ``` |
||
554 | * |
||
555 | * @param bool $includeFallback Whether to include values set in the base |
||
556 | * configuration passed to {@link __construct()}. |
||
557 | * |
||
558 | * @return array The raw configuration values. |
||
559 | */ |
||
560 | 14 | public function toRawArray($includeFallback = true) |
|
561 | { |
||
562 | 14 | $values = array(); |
|
563 | |||
564 | 14 | foreach ($this->values as $key => $value) { |
|
565 | 8 | $this->addKeyValue($key, $value, $values); |
|
566 | } |
||
567 | |||
568 | 14 | return $includeFallback && $this->baseConfig |
|
569 | 2 | ? array_replace_recursive($this->baseConfig->toRawArray(), $values) |
|
570 | 14 | : $values; |
|
571 | } |
||
572 | |||
573 | /** |
||
574 | * Returns whether the configuration is empty. |
||
575 | * |
||
576 | * @param bool $includeFallback Whether to include values set in the base |
||
577 | * configuration passed to {@link __construct()}. |
||
578 | * |
||
579 | * @return bool Returns `true` if no key is set and `false` otherwise. |
||
580 | */ |
||
581 | 5 | public function isEmpty($includeFallback = true) |
|
582 | { |
||
583 | 5 | if (!empty($this->values)) { |
|
584 | 5 | return false; |
|
585 | } |
||
586 | |||
587 | 5 | return $includeFallback && $this->baseConfig |
|
588 | 2 | ? $this->baseConfig->isEmpty(true) |
|
589 | 5 | : true; |
|
590 | } |
||
591 | |||
592 | /** |
||
593 | * @param string $key |
||
594 | * @param mixed $value |
||
595 | */ |
||
596 | 445 | private function validate($key, $value) |
|
597 | { |
||
598 | switch ($key) { |
||
599 | 445 | case self::FACTORY_AUTO_GENERATE: |
|
600 | 442 | case self::REPOSITORY_SYMLINK: |
|
601 | 440 | case self::REPOSITORY_OPTIMIZE: |
|
602 | 438 | case self::REPOSITORY_STORE_CACHE: |
|
603 | 436 | case self::CHANGE_STREAM_STORE_CACHE: |
|
604 | 434 | case self::DISCOVERY_STORE_CACHE: |
|
605 | 310 | $this->assertNotNull($key, $value); |
|
606 | 310 | $this->assertBoolean($key, $value); |
|
607 | 304 | break; |
|
608 | |||
609 | 432 | case self::REPOSITORY_STORE_PORT: |
|
610 | 432 | case self::CHANGE_STREAM_STORE_PORT: |
|
611 | 432 | case self::DISCOVERY_STORE_PORT: |
|
612 | $this->assertNotNull($key, $value); |
||
613 | $this->assertInteger($key, $value); |
||
614 | break; |
||
615 | |||
616 | 432 | case self::BOOTSTRAP_FILE: |
|
617 | 428 | case self::FACTORY_IN_FILE: |
|
618 | 424 | case self::REPOSITORY_STORE_TYPE: |
|
619 | 423 | case self::CHANGE_STREAM_STORE_TYPE: |
|
620 | 422 | case self::DISCOVERY_STORE_TYPE: |
|
621 | 349 | if (null !== $value) { |
|
622 | 343 | $this->assertString($key, $value); |
|
623 | 341 | $this->assertNonEmpty($key, $value); |
|
624 | } |
||
625 | 345 | break; |
|
626 | |||
627 | default: |
||
628 | 417 | $this->assertNotNull($key, $value); |
|
629 | 412 | $this->assertNonEmpty($key, $value); |
|
630 | 407 | $this->assertString($key, $value); |
|
631 | |||
632 | 402 | break; |
|
633 | } |
||
634 | 420 | } |
|
635 | |||
636 | /** |
||
637 | * @param string $key |
||
638 | * @param mixed $value |
||
639 | * |
||
640 | * @throws InvalidConfigException If the config value isn't an array. |
||
641 | */ |
||
642 | 7 | View Code Duplication | private function assertArray($key, $value) |
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. ![]() |
|||
643 | { |
||
644 | 7 | if (!is_array($value)) { |
|
645 | throw new InvalidConfigException(sprintf( |
||
646 | 'The config key "%s" must be an array. Got: %s', |
||
647 | $key, |
||
648 | is_object($value) ? get_class($value) : gettype($value) |
||
649 | )); |
||
650 | } |
||
651 | 7 | } |
|
652 | |||
653 | /** |
||
654 | * @param string $key |
||
655 | * @param mixed $value |
||
656 | * |
||
657 | * @throws InvalidConfigException If the config value is null. |
||
658 | */ |
||
659 | 430 | private function assertNotNull($key, $value) |
|
660 | { |
||
661 | 430 | if (null === $value) { |
|
662 | 5 | throw new InvalidConfigException(sprintf( |
|
663 | 'The config key "%s" must not be null. Use remove() to unset '. |
||
664 | 5 | 'keys.', |
|
665 | $key |
||
666 | )); |
||
667 | } |
||
668 | 425 | } |
|
669 | |||
670 | /** |
||
671 | * @param string $key |
||
672 | * @param mixed $value |
||
673 | * |
||
674 | * @throws InvalidConfigException If the config value isn't a string. |
||
675 | */ |
||
676 | 416 | View Code Duplication | private function assertString($key, $value) |
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. ![]() |
|||
677 | { |
||
678 | 416 | if (!is_string($value) && null !== $value) { |
|
679 | 7 | throw new InvalidConfigException(sprintf( |
|
680 | 7 | 'The config key "%s" must be a string. Got: %s', |
|
681 | $key, |
||
682 | 7 | is_object($value) ? get_class($value) : gettype($value) |
|
683 | )); |
||
684 | } |
||
685 | 409 | } |
|
686 | |||
687 | /** |
||
688 | * @param string $key |
||
689 | * @param mixed $value |
||
690 | * |
||
691 | * @throws InvalidConfigException If the config value isn't an integer. |
||
692 | */ |
||
693 | View Code Duplication | private function assertInteger($key, $value) |
|
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. ![]() |
|||
694 | { |
||
695 | if (!is_int($value) && null !== $value) { |
||
696 | throw new InvalidConfigException(sprintf( |
||
697 | 'The config key "%s" must be an integer. Got: %s', |
||
698 | $key, |
||
699 | is_object($value) ? get_class($value) : gettype($value) |
||
700 | )); |
||
701 | } |
||
702 | } |
||
703 | |||
704 | /** |
||
705 | * @param string $key |
||
706 | * @param mixed $value |
||
707 | * |
||
708 | * @throws InvalidConfigException If the config value isn't a boolean. |
||
709 | */ |
||
710 | 310 | View Code Duplication | private function assertBoolean($key, $value) |
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. ![]() |
|||
711 | { |
||
712 | 310 | if (!is_bool($value) && null !== $value) { |
|
713 | 6 | throw new InvalidConfigException(sprintf( |
|
714 | 6 | 'The config key "%s" must be a bool. Got: %s', |
|
715 | $key, |
||
716 | 6 | is_object($value) ? get_class($value) : gettype($value) |
|
717 | )); |
||
718 | } |
||
719 | 304 | } |
|
720 | |||
721 | /** |
||
722 | * @param string $key |
||
723 | * @param mixed $value |
||
724 | * |
||
725 | * @throws InvalidConfigException If the config value is an empty string. |
||
726 | */ |
||
727 | 419 | private function assertNonEmpty($key, $value) |
|
728 | { |
||
729 | 419 | if ('' === $value) { |
|
730 | 7 | throw new InvalidConfigException(sprintf( |
|
731 | 7 | 'The value of the config key "%s" must not be empty.', |
|
732 | $key |
||
733 | )); |
||
734 | } |
||
735 | 412 | } |
|
736 | |||
737 | /** |
||
738 | * @param mixed $raw |
||
739 | * @param bool $fallback |
||
740 | * |
||
741 | * @return mixed |
||
0 ignored issues
–
show
|
|||
742 | */ |
||
743 | 133 | private function replacePlaceholders($raw, $fallback = true) |
|
744 | { |
||
745 | 133 | if (is_array($raw)) { |
|
746 | 47 | foreach ($raw as $key => $value) { |
|
747 | 45 | $raw[$key] = $this->replacePlaceholders($value, $fallback); |
|
748 | } |
||
749 | |||
750 | 47 | return $raw; |
|
751 | } |
||
752 | |||
753 | 132 | if (!is_string($raw)) { |
|
754 | 86 | return $raw; |
|
755 | } |
||
756 | |||
757 | 91 | $config = $this; |
|
758 | |||
759 | 91 | return preg_replace_callback('~\{\$(.+)\}~', function ($matches) use ($config, $fallback) { |
|
760 | 48 | return $config->get($matches[1], null, $fallback); |
|
761 | 91 | }, $raw); |
|
762 | } |
||
763 | |||
764 | /** |
||
765 | * @param string $keyPrefix |
||
766 | * |
||
767 | * @return array |
||
768 | */ |
||
769 | 47 | private function filterByKeyPrefix($keyPrefix) |
|
770 | { |
||
771 | 47 | $values = array(); |
|
772 | 47 | $offset = strlen($keyPrefix); |
|
773 | |||
774 | 47 | foreach ($this->values as $k => $v) { |
|
775 | 45 | if (0 !== strpos($k, $keyPrefix)) { |
|
776 | 32 | continue; |
|
777 | } |
||
778 | |||
779 | 44 | $this->addKeyValue(substr($k, $offset), $v, $values); |
|
780 | } |
||
781 | |||
782 | 47 | return $values; |
|
783 | } |
||
784 | |||
785 | /** |
||
786 | * @param string $keyPrefix |
||
787 | * |
||
788 | * @return bool |
||
789 | */ |
||
790 | 3 | private function containsKeyPrefix($keyPrefix) |
|
791 | { |
||
792 | 3 | foreach ($this->values as $k => $v) { |
|
793 | 2 | if (0 === strpos($k, $keyPrefix)) { |
|
794 | 2 | return true; |
|
795 | } |
||
796 | } |
||
797 | |||
798 | 3 | return false; |
|
799 | } |
||
800 | |||
801 | /** |
||
802 | * @param string $keyPrefix |
||
803 | */ |
||
804 | 8 | private function removeByKeyPrefix($keyPrefix) |
|
805 | { |
||
806 | 8 | foreach ($this->values as $k => $v) { |
|
807 | 5 | if (0 !== strpos($k, $keyPrefix)) { |
|
808 | 4 | continue; |
|
809 | } |
||
810 | |||
811 | 2 | unset($this->values[$k]); |
|
812 | } |
||
813 | 8 | } |
|
814 | |||
815 | /** |
||
816 | * @param string $key |
||
817 | * @param mixed $value |
||
818 | * @param array $values |
||
819 | */ |
||
820 | 52 | private function addKeyValue($key, $value, array &$values) |
|
821 | { |
||
822 | 52 | $target = &$values; |
|
823 | 52 | $keyParts = explode('.', $key); |
|
824 | |||
825 | 52 | for ($i = 0, $l = count($keyParts) - 1; $i < $l; ++$i) { |
|
826 | 40 | if (!isset($target[$keyParts[$i]])) { |
|
827 | 40 | $target[$keyParts[$i]] = array(); |
|
828 | } |
||
829 | |||
830 | 40 | $target = &$target[$keyParts[$i]]; |
|
831 | } |
||
832 | |||
833 | 52 | $target[$keyParts[$l]] = $value; |
|
834 | 52 | } |
|
835 | } |
||
836 |
This check compares the return type specified in the
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.