<?php
namespace Yesf\Config\Adapter;
use SplQueue;
use Yesf\Yesf;
use Yesf\Exception\Exception;
use Yesf\Config\ConfigTrait;
use Yesf\Config\ConfigInterface;
class Arr implements ConfigInterface {
use ConfigTrait;
protected $environment;
protected $conf;
public function __construct(array $conf, $env = null) {
if ($env === null) {
$env = Yesf::app()->getEnvironment();
}
$this->environment = $env;
$this->conf = $conf;
}
public function get($key, $default = null) {
$keys = explode('.', $key);
$conf = empty($this->environment) ? $this->conf : $this->conf[$this->environment];
foreach ($keys as $v) {
if (isset($conf[$v])) {
$conf = $conf[$v];
} else {
return $default;
}
}
return $conf;
}
public function has($key) {
$keys = explode('.', $key);
$conf = empty($this->environment) ? $this->conf : $this->conf[$this->environment];
foreach ($keys as $v) {
if (isset($conf[$v])) {
$conf = $conf[$v];
} else {
return false;
}
}
return true;
}
public static function fromIniFile($file) {
if (!is_file($file)) {
throw new Exception("Config file $file not found");
}
$conf = parse_ini_file($file, true);
$all = [];
$queue = new SplQueue;
$environments = array_keys($conf);
foreach ($environments as $one) {
if (strpos($one, ':') === false) {
$queue->push($one);
}
}
while ($queue->count() > 0) {
$it = $queue->pop();
if (strpos($it, ':') === false) {
$all[$it] = $conf[$it];
$child = $it;
} else {
list($child, $parent) = explode(':', $it, 2);
$child = trim($child);
$parent = trim($parent);
$all[$child] = array_merge($all[$parent], $conf[$it]);
}
foreach ($environments as $one) {
if (!isset($all[$one]) && strpos($one, ':') !== false) {
$one_parse = explode(':', $one, 2);
if ($one_parse[1] === $child) {
$queue->push($one);
}
}
}
}
$result = [];
foreach ($all as $env => $it) {
$result[$env] = [];
foreach ($it as $k => $v) {
if (strpos($k, '.') === false) {
$result[$env][$k] = $v;
continue;
}
$keys = explode('.', $k);
$total = count($keys) - 1;
$parent = &$result[$env];
foreach ($keys as $kk => $vv) {
if ($total === $kk) {
$parent[$vv] = $v;
} else {
if (!isset($parent[$vv])) {
$parent[$vv] = [];
}
$parent = &$parent[$vv];
}
}
}
}
return new self($result);
}
}