App: fix handling app's options when substituting variable reference in option value

This commit is contained in:
Benjamin Renard 2023-03-03 10:36:08 +01:00
parent 97f91156de
commit 455ec45c3b
Signed by: bn8
GPG key ID: 3E2E1CE1907115BC
2 changed files with 20 additions and 8 deletions

View file

@ -139,7 +139,8 @@ class App {
Config::loaded()?Config::get($key, $default, $cast, $split):$default,
$cast,
$split,
self :: $options
self :: $options,
array(self :: class, 'get')
);
}

View file

@ -138,9 +138,11 @@ Class Config {
* @param bool $split If true, $cast=='array' and $value is a string, split
* the value by comma (optional, default: false)
* @param array|null $config Optional configuration to use instead of current loaded configuration
* @param callable|null $get Optional callable to get another value that will be used to replace
* variables references found in retreived value.
* @return mixed The configuration variable value
**/
public static function get($key, $default=null, $cast=null, $split=false, &$config=null) {
public static function get($key, $default=null, $cast=null, $split=false, &$config=null, $get=null) {
if (array_key_exists($key, self :: $extra_variables)) {
$value = self :: $extra_variables[$key];
}
@ -153,37 +155,46 @@ Class Config {
}
else {
$exploded_key = explode('.', $key);
if (!is_array($exploded_key)) return self :: replace_variables($default);
if (!is_array($exploded_key)) return self :: replace_variables($default, $get?$get:$config);
$value = is_array($config)?$config:self :: $config;
foreach ($exploded_key as $k) {
if (!is_array($value) || !isset($value[$k]))
return self :: replace_variables($default);
return self :: replace_variables($default, $get?$get:$config);
$value = $value[$k];
}
}
return self :: replace_variables(cast($value, $cast, $split));
return self :: replace_variables(cast($value, $cast, $split), $get?$get:$config);
}
/**
* Replace variable in specified value
* @param mixed $value
* @param array|callable|null $config Optional configuration to use to retreive variable reference
* value instead of current loaded configuration. Could be an
* array of configuration data or a callable that could be used
* as Config::get() to retreive the desired variable reference.
* @return mixed
*/
public static function replace_variables($value) {
public static function replace_variables($value, $config=null) {
if (is_array($value)) {
foreach(array_keys($value) as $key) {
if (is_string($value[$key]) || is_array($value[$key]))
$value[$key] = self :: replace_variables($value[$key]);
$value[$key] = self :: replace_variables($value[$key], $config);
}
}
else if (is_string($value)) {
$config = is_null($config)?self :: $config:$config;
$iteration = 0;
while (preg_match('/\$\{([^\}]+)\}/', $value, $m)) {
if ($iteration > 20) {
Log::fatal('Config::replace_variables(%s): max iteration reached');
return $value;
}
$value = str_replace($m[0], self :: get($m[1], '', 'string'), $value);
if (is_callable($config))
$replace_by = call_user_func($config, $m[1], '', 'string', false);
else
$replace_by = self :: get($m[1], '', 'string', false, $config);
$value = str_replace($m[0], $replace_by, $value);
$iteration++;
}
}