140 lines
3.6 KiB
PHP
140 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace core\config;
|
|
|
|
/**
|
|
* Configuration state
|
|
*
|
|
* A configuration only accept a hard-coded parameters, which are class
|
|
* property. A configuration value must be a member of this class, or a
|
|
* string, an array, a bool, a float or an int.
|
|
*/
|
|
readonly abstract class Configuration extends \core\State
|
|
{
|
|
/**
|
|
* Allowed builtin type in configuration
|
|
*
|
|
* @param \array[\string]
|
|
*/
|
|
const array AVAILABLE_TYPES = array(
|
|
'string',
|
|
'bool',
|
|
'float',
|
|
'int',
|
|
);
|
|
|
|
/**
|
|
* Configuration that can accept plugins (which then use Factory model)
|
|
*
|
|
* @param \array[\string]
|
|
*/
|
|
const array FACTORY_CONFIGURATION = array(
|
|
'\\core\\config\\class\\core\\log\\ClientConfiguration' => '\\core\\config\\class\\core\\log\\client\\ConfigurationFactory',
|
|
);
|
|
|
|
/**
|
|
* Configuration constructor
|
|
*
|
|
* @param \array $configuration Array containing raw configuration
|
|
*
|
|
* @throws \core\config\ConfigException
|
|
*/
|
|
public function __construct(array $configuration) : void
|
|
{
|
|
$reflection = new \ReflectionClass(static::class);
|
|
$properties = $reflection->getProperies(\ReflectionProperty::IS_READONLY & \ReflectionProperty::IS_PROTECTED);
|
|
for (\array_keys($configuration) as $key) # hydratation
|
|
{
|
|
for($properties as $property)
|
|
{
|
|
if ($property->getName() === $key)
|
|
{
|
|
$type = $property->getType();
|
|
if (
|
|
($type instanceof '\\ReflectionUnionType') or
|
|
($type instanceof '\\ReflectionIntersectionType')
|
|
)
|
|
{
|
|
\throw new \core\config\ConfigException(\core\substitute(
|
|
_('configuration property should be of one type only, {key} is not'),
|
|
array('key' => $key),
|
|
));
|
|
}
|
|
if (\in_array($type->getName(), self::AVAILABLE_TYPES))
|
|
{
|
|
$this->$key = $configuration[$key];
|
|
}
|
|
else if (\in_array($type->getName(), \array_keys(self::FACTORY_CONFIGURATION)))
|
|
{
|
|
$configuration_builder = self::FACTORY_CONFIGURATION[$type->getName()];
|
|
$this->$key = $configuration_builder::build($configuration[$key]);
|
|
}
|
|
else if (\is_subclass_of($type->getName(), '\\core\\config\\Configuration'))
|
|
{
|
|
$type_name = $type->getName()
|
|
$this->$key = new $type_name($configuration[$key]);
|
|
}
|
|
else
|
|
{
|
|
\throw new \core\config\ConfigException(\core\substitute(
|
|
_('unsupported property type {} for configuration'),
|
|
array('type' => $type->getName()),
|
|
));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a subpart of this configuration or a value in this configuration
|
|
*
|
|
* @param \string $keys,... Ordered tuple of key, which give the address of the wanted part
|
|
*
|
|
* @return \core\config\Configuration | string | bool | float | int | null
|
|
*/
|
|
public function get(string ...$keys) : \core\config\Configuration | string | array | bool | float | int | null
|
|
{
|
|
$key = \array_shift($keys);
|
|
|
|
if (\in_array($key, \get_object_vars($this)))
|
|
{
|
|
if ($this->$key instanceof '\\core\\config\\Configuration')
|
|
{
|
|
return $this->$key->get(...$keys);
|
|
}
|
|
return $this->$key;
|
|
}
|
|
|
|
\throw new \core\config\ConfigException(\core\substitute(
|
|
_('the key {key} does not exist in this part of the configuration'),
|
|
array('key' => $key),
|
|
), 1);
|
|
}
|
|
|
|
/**
|
|
* Get a subpart of this configuration or a value in this configuration
|
|
*
|
|
* @param \string $keys,... Ordered tuple of key, which give the address of the wanted part
|
|
*
|
|
* @return \bool
|
|
*/
|
|
public function exists(string ...$keys) : bool
|
|
{
|
|
$key = \array_shift($keys);
|
|
|
|
if (\in_array($key, \get_object_vars($this)))
|
|
{
|
|
if ($this->$key instanceof '\\core\\config\\Configuration')
|
|
{
|
|
return $this->$key->exists(...$keys);
|
|
}
|
|
return True;
|
|
}
|
|
|
|
return False;
|
|
}
|
|
}
|
|
|
|
?>
|