nur-sery/nur_src/config/Ref.php

72 lines
2.2 KiB
PHP
Raw Normal View History

2023-12-03 22:10:18 +04:00
<?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;
}
}