Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
45 / 45 |
|
100.00% |
9 / 9 |
CRAP | |
100.00% |
1 / 1 |
Config | |
100.00% |
45 / 45 |
|
100.00% |
9 / 9 |
24 | |
100.00% |
1 / 1 |
__construct | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
load | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
get | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
5 | |||
getCommaSeparatedValues | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getArray | |
100.00% |
18 / 18 |
|
100.00% |
1 / 1 |
7 | |||
isCached | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFullPath | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getArrayItemValue | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
cacheAndReturn | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
replaceEnvValue | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 |
1 | <?php |
2 | |
3 | namespace Dynart\Micro; |
4 | |
5 | /** |
6 | * Config handler |
7 | * |
8 | * Loads INI files, caches the retrieved values |
9 | * |
10 | * @package Dynart\Micro |
11 | */ |
12 | class Config { |
13 | |
14 | private $config = []; |
15 | private $cached = []; |
16 | |
17 | public function __construct() {} |
18 | |
19 | /** |
20 | * Loads an INI file and merges with current config |
21 | * |
22 | * It does NOT process sections! The "true", "false", "no", "yes", "on", "off" values |
23 | * will be replaced with true and false values. |
24 | * |
25 | * @param string $path The path of the INI file |
26 | */ |
27 | public function load(string $path) { |
28 | $this->config = array_merge($this->config, parse_ini_file($path, false, INI_SCANNER_TYPED)); |
29 | } |
30 | |
31 | public function get($name, $default = null, $useCache = true) { |
32 | if ($useCache && array_key_exists($name, $this->cached)) { |
33 | return $this->cached[$name]; |
34 | } |
35 | if (getenv($name) !== false) { |
36 | return $this->cacheAndReturn($name, getenv($name), $useCache); |
37 | } |
38 | $value = array_key_exists($name, $this->config) ? $this->config[$name] : $default; |
39 | return $this->cacheAndReturn($name, $this->replaceEnvValue($value), $useCache); |
40 | } |
41 | |
42 | /** |
43 | * Returns with an array from a comma separated string config value |
44 | * |
45 | * For example: "1, 2, 3" will result in ['1', '2', '3'] |
46 | * |
47 | * @param string $name The config name |
48 | * @param bool $useCache Use the cache for retrieving the value? |
49 | * @return array The result in array |
50 | */ |
51 | public function getCommaSeparatedValues(string $name, bool $useCache = true): array { |
52 | $values = explode(',', $this->get($name)); |
53 | $result = array_map([$this, 'getArrayItemValue'], $values); |
54 | return $this->cacheAndReturn($name, $result, $useCache); |
55 | } |
56 | |
57 | /** |
58 | * Returns with an array from the config |
59 | * |
60 | * For example: with the following config: |
61 | * |
62 | * <pre> |
63 | * persons.0.name = "name1" |
64 | * persons.0.age = "32" |
65 | * persons.1.name = "name2" |
66 | * persons.1.age = "42" |
67 | * </pre> |
68 | * |
69 | * the result will be for `$config->getArray('persons')`: |
70 | * |
71 | * <pre> |
72 | * [ |
73 | * "0" => [ |
74 | * "name" => "name1", |
75 | * "age" => "32" |
76 | * ], |
77 | * "1" => [ |
78 | * "name" => "name2", |
79 | * "age" => "42" |
80 | * ] |
81 | * ] |
82 | * </pre> |
83 | * |
84 | * @param $prefix |
85 | * @param array $default |
86 | * @param bool $useCache |
87 | * @return array |
88 | */ |
89 | public function getArray(string $prefix, array $default = [], bool $useCache = true): array { |
90 | global $_ENV; |
91 | if ($useCache && array_key_exists($prefix, $this->cached)) { |
92 | return $this->cached[$prefix]; |
93 | } |
94 | $result = $default; |
95 | $len = strlen($prefix); |
96 | $keys = array_merge(array_keys($this->config), array_keys($_ENV)); |
97 | foreach ($keys as $key) { |
98 | if (substr($key, 0, $len) != $prefix) { |
99 | continue; |
100 | } |
101 | $configKey = substr($key, $len + 1, strlen($key)); |
102 | $parts = explode('.', $configKey); |
103 | $current = &$result; |
104 | foreach ($parts as $part) { |
105 | if (!array_key_exists($part, $current)) { |
106 | $current[$part] = []; |
107 | } |
108 | $current = &$current[$part]; |
109 | } |
110 | $current = $this->get($key, null, false); |
111 | } |
112 | return $this->cacheAndReturn($prefix, $result, $useCache); |
113 | } |
114 | |
115 | /** |
116 | * Returns true if the config value is cached |
117 | * @param string $name Name of the config |
118 | * @return bool Is the config value cached? |
119 | */ |
120 | public function isCached(string $name): bool { |
121 | return array_key_exists($name, $this->cached); |
122 | } |
123 | |
124 | /** |
125 | * Replaces the ~ symbol with the `app.root_path` config value |
126 | * @param string $path |
127 | * @return string |
128 | */ |
129 | public function getFullPath(string $path): string { |
130 | return str_replace('~', $this->get(App::CONFIG_ROOT_PATH), $path); |
131 | } |
132 | |
133 | /** |
134 | * Trims and replaces variables to environment variable values in a string |
135 | * @param string $value The value for trim and replace |
136 | * @return string The trimmed and replaced value |
137 | */ |
138 | protected function getArrayItemValue(string $value) { |
139 | $result = trim($value); |
140 | $this->replaceEnvValue($result); |
141 | return $result; |
142 | } |
143 | |
144 | /** |
145 | * Caches a value if the `$useCache` is true and returns with it |
146 | * @param string|null $name The config name |
147 | * @param string|array|null $value The value |
148 | * @param bool $useCache Use the cache? |
149 | * @return mixed |
150 | */ |
151 | protected function cacheAndReturn($name, $value, $useCache = true) { |
152 | if ($useCache) { |
153 | $this->cached[$name] = $value; |
154 | } |
155 | return $value; |
156 | } |
157 | |
158 | /** |
159 | * Replaces the {{name}} formatted variables in a string with environment variable values |
160 | * @param string|null $value The value |
161 | * @return mixed|null The replaced string |
162 | */ |
163 | protected function replaceEnvValue($value) { |
164 | if (!$value) { |
165 | return $value; |
166 | } |
167 | $matches = []; |
168 | if (!preg_match_all('/{{\s*(\w+)\s*}}/', $value, $matches)) { |
169 | return $value; |
170 | } |
171 | $vars = array_unique($matches[1]); |
172 | foreach ($vars as $var) { |
173 | $value = str_replace('{{' . $var . '}}', getenv($var), $value); |
174 | } |
175 | return $value; |
176 | } |
177 | |
178 | } |