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