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;
 | 
						|
  }
 | 
						|
}
 |