logbook/class/core/config/Configuration.class.php
2025-04-05 23:00:51 +02:00

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