-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathConfig.php
112 lines (101 loc) · 3.13 KB
/
Config.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
declare(strict_types=1);
namespace Roots\WPConfig;
use Roots\WPConfig\Exceptions\ConstantAlreadyDefinedException;
use Roots\WPConfig\Exceptions\UndefinedConfigKeyException;
/**
* Class Config
* @package Roots\Bedrock
*/
class Config
{
/**
* @var array<string, mixed>
*/
protected static $configMap = [];
/**
* @param string $key
* @param mixed $value
* @throws ConstantAlreadyDefinedException
*/
public static function define(string $key, $value): void
{
self::defined($key) or self::$configMap[$key] = $value;
}
/**
* @param string $key
* @return mixed
* @throws UndefinedConfigKeyException
*/
public static function get(string $key)
{
if (!array_key_exists($key, self::$configMap)) {
$class = self::class;
throw new UndefinedConfigKeyException("'$key' has not been defined. Use `$class::define('$key', ...)`.");
}
return self::$configMap[$key];
}
/**
* @param string $key
*/
public static function remove(string $key): void
{
unset(self::$configMap[$key]);
}
/**
* define() all values in $configMap and throw an exception if we are attempting to redefine a constant.
*
* We throw the exception because a silent rejection of a configuration value is unacceptable. This method fails
* fast before undefined behavior propagates due to unexpected configuration sneaking through.
*
* ```
* define('BEDROCK', 'no');
* define('BEDROCK', 'yes');
* echo BEDROCK;
* // output: 'no'
* ```
*
* vs.
*
* ```
* define('BEDROCK', 'no');
* Config::define('BEDROCK', 'yes');
* Config::apply();
* // output: Fatal error: Uncaught Roots\Bedrock\ConstantAlreadyDefinedException ...
* ```
*
* @throws ConstantAlreadyDefinedException
*/
public static function apply(): void
{
// Scan configMap to see if user is trying to redefine any constants.
// We do this because we don't want to 'half apply' the configMap. The user should be able to catch the
// exception, repair their config, and run apply() again
foreach (self::$configMap as $key => $value) {
try {
self::defined($key);
} catch (ConstantAlreadyDefinedException $e) {
if (constant($key) !== $value) {
throw $e;
}
}
}
// If all is well, apply the configMap ignoring entries that have already been applied
foreach (self::$configMap as $key => $value) {
defined($key) or define($key, $value);
}
}
/**
* @param string $key
* @return false
* @throws ConstantAlreadyDefinedException
*/
protected static function defined(string $key): bool
{
if (defined($key)) {
$message = "Aborted trying to redefine constant '$key'. `define('$key', ...)` has already been occurred elsewhere.";
throw new ConstantAlreadyDefinedException($message);
}
return false;
}
}