72 lines
2.2 KiB
PHP
72 lines
2.2 KiB
PHP
|
<?php
|
||
|
namespace nur\config;
|
||
|
|
||
|
use nur\A;
|
||
|
use nur\b\ValueException;
|
||
|
use nur\str;
|
||
|
|
||
|
/**
|
||
|
* Class Ref: une référence à une clé de configuration
|
||
|
*
|
||
|
* La référence peut être relative, e.g '..x.y' qui correspond à 'a.b.x.y' si
|
||
|
* la référence est située au chemin de clé 'a.b.w.t' (le nombre de '.' au
|
||
|
* début indique le nombre d'éléments de chemin à enlever)
|
||
|
*/
|
||
|
class Ref {
|
||
|
/** @var string */
|
||
|
public $pkey;
|
||
|
/** @var array */
|
||
|
public $merge;
|
||
|
/** @var array */
|
||
|
public $appends;
|
||
|
/** @var array */
|
||
|
public $prepends;
|
||
|
|
||
|
function __construct(string $pkey) {
|
||
|
$this->pkey = $pkey;
|
||
|
}
|
||
|
|
||
|
/** calculer le chemin effectif à partir du chemin relative $pkey */
|
||
|
static final function abs_pkey(string $rel_pkey, string $base_pkey): string {
|
||
|
if (substr($rel_pkey, 0, 1) == ".") {
|
||
|
$base = explode(".", $base_pkey);
|
||
|
## c'est un chemin relatif
|
||
|
$parts = $rel_pkey;
|
||
|
# monter
|
||
|
while ($parts != "" && substr($parts, 0, 1) == ".") {
|
||
|
A::del($base, count($base) - 1);
|
||
|
$parts = substr($parts, 1);
|
||
|
}
|
||
|
# puis descendre
|
||
|
$parts = explode(".", $parts);
|
||
|
A::merge($base, $parts);
|
||
|
$pkey = implode(".", $base);
|
||
|
} else {
|
||
|
## c'est un chemin absolu
|
||
|
$pkey = $rel_pkey;
|
||
|
}
|
||
|
if ($pkey == $base_pkey) {
|
||
|
throw new ValueException("rel_pkey($rel_pkey) must be different of $base_pkey");
|
||
|
} elseif (str::starts_with("$base_pkey.", $pkey)) {
|
||
|
throw new ValueException("rel_pkey($rel_pkey) shall not be a child of $base_pkey");
|
||
|
} elseif (str::starts_with("$pkey.", $base_pkey)) {
|
||
|
throw new ValueException("rel_pkey($rel_pkey) shall not be a direct parent of $base_pkey");
|
||
|
}
|
||
|
return $pkey;
|
||
|
}
|
||
|
|
||
|
/** résoudre cette référence, qui est située au chemin $pkey */
|
||
|
function resolve(IConfigManager $cm, string $base_pkey, string $profile) {
|
||
|
$abs_pkey = $this->abs_pkey($this->pkey, $base_pkey);
|
||
|
$value = $cm->getValue($abs_pkey, null, $profile);
|
||
|
if ($this->merge !== null) A::merge($value, $this->merge);
|
||
|
if ($this->appends !== null) A::merge($value, $this->appends);
|
||
|
if ($this->prepends !== null) {
|
||
|
$prepends = $this->prepends;
|
||
|
A::merge($prepends, $value);
|
||
|
$value = $prepends;
|
||
|
}
|
||
|
return $value;
|
||
|
}
|
||
|
}
|