nur-sery/nur_src/b/coll/TAutomethods.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);
}
}