hanyuu/src/Config/ArrayConfig.php

79 lines
2.3 KiB
PHP

<?php
namespace Hanyuu\Config;
use InvalidArgumentException;
class ArrayConfig implements IConfig {
private const SCOPE_CHAR = ':';
private const SCANNER_MODE = INI_SCANNER_TYPED;
private const TEST_VALUE = 'X-Config-Test';
private array $cache = [];
private array $exists = [];
public function __construct(
private array $config
) {}
public function scopeTo(string $prefix): IConfig {
return new ScopedConfig($this, $prefix);
}
private function getRaw(string $name): mixed {
$parts = array_reverse(explode(self::SCOPE_CHAR, $name));
$value = $this->config;
while(count($parts) > 1) {
$part = array_pop($parts);
if(!array_key_exists($part, $value))
break;
$value = $value[$part];
}
if($parts[0] === '')
return $value;
return $value[$parts[0]] ?? null;
}
public function getValue(string $name, string $type = IConfig::T_ANY, $default = null): mixed {
if(array_key_exists($name, $this->cache))
$value = $this->cache[$name];
else {
$this->cache[$name] = $value = $this->getRaw($name);
$this->exists[$name] = $value !== null;
}
if($type !== IConfig::T_ANY && CfgTools::type($value) !== $type)
$value = null;
return $value ?? $default ?? CfgTools::default($type);
}
public function hasValue(string $name): bool {
if(array_key_exists($name, $this->exists))
return $this->exists[$name];
$exists = array_key_exists($name, $this->cache)
|| $this->getRaw($name) !== null;
return $this->exists[$name] = $exists;
}
public static function open(string $path): self {
$parsed = parse_ini_file($path, true, self::SCANNER_MODE);
if($parsed === false)
throw new InvalidArgumentException('Unable to parse configuration file in $path.');
return new static($parsed);
}
public static function from(string $string): self {
$parsed = parse_ini_string($string, true, self::SCANNER_MODE);
if($parsed === false)
throw new InvalidArgumentException('Unable to parse configuration string in $string.');
return new static($parsed);
}
}