128 lines
4.1 KiB
PHP
128 lines
4.1 KiB
PHP
<?php
|
|
namespace nur\b\coll;
|
|
|
|
use nur\A;
|
|
use nur\b\IllegalAccessException;
|
|
use ReflectionMethod;
|
|
|
|
/**
|
|
* Trait TAutomethods: support des méthodes automatiques
|
|
*/
|
|
trait TAutomethods {
|
|
/**
|
|
* return @array un tableau {$method => $key} qui associe des noms de getters
|
|
* aux clés correspondantes. cette valeur est utilisée pour implémenter les
|
|
* getters automatiques
|
|
*/
|
|
protected static function _AUTO_GETTERS(): ?array {
|
|
return static::_AUTO_GETTERS;
|
|
}
|
|
|
|
/**
|
|
* return @array un tableau {$method => $key} qui associe des noms de setters
|
|
* aux clés correspondantes. cette valeur est utilisée pour implémenter les
|
|
* setters automatiques
|
|
*/
|
|
protected static function _AUTO_SETTERS(): ?array {
|
|
return static::_AUTO_SETTERS;
|
|
}
|
|
|
|
/**
|
|
* return @array un tableau {$method => $key} qui associe des noms de deleters
|
|
* aux clés correspondantes. cette valeur est utilisée pour implémenter les
|
|
* deleters automatiques
|
|
*/
|
|
protected static function _AUTO_DELETERS(): ?array {
|
|
return static::_AUTO_DELETERS;
|
|
}
|
|
|
|
/**
|
|
* return @array un tableau {$method => $key} qui associe des noms de getters
|
|
* aux clés composites correspondantes. cette valeur est utilisée pour
|
|
* implémenter les getters automatiques
|
|
*/
|
|
protected static function _AUTO_CI_GETTERS(): ?array {
|
|
return static::_AUTO_CI_GETTERS;
|
|
}
|
|
|
|
/**
|
|
* return @array un tableau {$method => $key} qui associe des noms de setters
|
|
* aux clés composites correspondantes. cette valeur est utilisée pour
|
|
* implémenter les setters automatiques
|
|
*/
|
|
protected static function _AUTO_CI_SETTERS(): ?array {
|
|
return static::_AUTO_CI_SETTERS;
|
|
}
|
|
|
|
static function _TAutomethods__have_method(string $method): bool {
|
|
$autoLists = [
|
|
static::_AUTO_GETTERS,
|
|
static::_AUTO_SETTERS,
|
|
static::_AUTO_DELETERS,
|
|
static::_AUTO_CI_GETTERS,
|
|
static::_AUTO_CI_SETTERS,
|
|
];
|
|
foreach ($autoLists as $method2properties) {
|
|
if ($method2properties !== null && array_key_exists($method, $method2properties)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function _haveMethod(string $method): bool {
|
|
if (method_exists($this, $method)) return true;
|
|
return self::_TAutomethods__have_method($method);
|
|
}
|
|
|
|
private static function call_args(object $object, string $method, array $args) {
|
|
$rf = new ReflectionMethod($object, $method);
|
|
if (!$rf->isVariadic()) {
|
|
$maxArgs = $rf->getNumberOfParameters();
|
|
$args = array_slice($args, 0, $maxArgs);
|
|
while (count($args) < $maxArgs) {
|
|
$args[] = null;
|
|
}
|
|
}
|
|
if (count($args) === 0) return $rf->invoke($object);
|
|
else return $rf->invokeArgs($object, $args);
|
|
}
|
|
|
|
function __call(string $name, array $args) {
|
|
$getter_keys = static::_AUTO_GETTERS();
|
|
if ($getter_keys !== null && array_key_exists($name, $getter_keys)) {
|
|
$key = $getter_keys[$name];
|
|
$default = A::get($args, 0);
|
|
return self::call_args($this, "get", [$key, $default]);
|
|
}
|
|
$setter_keys = static::_AUTO_SETTERS();
|
|
if ($setter_keys !==null && array_key_exists($name, $setter_keys)) {
|
|
$key = $setter_keys[$name];
|
|
$value = A::get($args, 0);
|
|
if (is_string($value)) {
|
|
$type = $this->md()->getType($key, false);
|
|
if ($type !== null) $value = $type->with($value);
|
|
}
|
|
return self::call_args($this, "set", [$key, $value]);
|
|
}
|
|
$deleter_keys = static::_AUTO_DELETERS();
|
|
if ($deleter_keys !== null && array_key_exists($name, $deleter_keys)) {
|
|
$key = $deleter_keys[$name];
|
|
return self::call_args($this, "del", [$key]);
|
|
}
|
|
$ci_getter_keys = static::_AUTO_CI_GETTERS();
|
|
if ($ci_getter_keys !== null && array_key_exists($name, $ci_getter_keys)) {
|
|
$key = $ci_getter_keys[$name];
|
|
return $this->md()->get($this->data, $key, null, false);
|
|
}
|
|
$ci_setter_keys = static::_AUTO_CI_SETTERS();
|
|
if ($ci_setter_keys !==null && array_key_exists($name, $ci_setter_keys)) {
|
|
$key = $ci_setter_keys[$name];
|
|
$value = A::get($args, 0);
|
|
$this->md()->set($this->data, $key, $value);
|
|
return null;
|
|
}
|
|
throw IllegalAccessException::not_implemented($name);
|
|
}
|
|
}
|