nur-sery/nur_src/b/params/parametrable_utils.php

218 lines
8.1 KiB
PHP
Raw Normal View History

2023-12-03 22:10:18 +04:00
<?php
namespace nur\b\params;
use nur\A;
use nur\b\ValueException;
use nur\data\types\Metadata;
use nur\md;
use nur\php\Autogen;
use nur\prop;
use nur\str;
class parametrable_utils {
private static function get_pp_property(string $key): string {
return str::us2camel("pp_$key");
}
private static function get_pp_setter(string $key, ?Metadata $md=null) {
if ($md !== null) return "pp_".$md->getType($key)->getSetterName($key);
else return "pp_".prop::get_setter_name($key);
}
private static function get_getter(string $key, ?Metadata $md=null) {
if ($md !== null) return $md->getType($key)->getGetterName($key);
else return prop::get_getter_name($key);
}
private static function get_setter(string $key, ?Metadata $md=null) {
if ($md !== null) return $md->getType($key)->getSetterName($key);
else return prop::get_setter_name($key);
}
static function set_param(object $parametrable, string $key, $value, ?Metadata $md=null): void {
if ($md !== null) {
$property = self::get_pp_property($key);
$setter = self::get_pp_setter($key, $md);
prop::set($parametrable, $property, $value, $setter);
} else {
$property = self::get_pp_property($key);
$setter = self::get_pp_setter($key);
prop::set($parametrable, $property, $value, $setter);
}
}
static function set_defaults(?array $parametrables, IParametrable $defaultParametrable, $schema): void {
if ($schema === null) return;
if ($schema instanceof Metadata) {
$sfields = $schema->getSfields();
foreach ($sfields as $key => $sfield) {
$default = $sfield["default"];
if ($default !== null) {
$parametrable = A::get($parametrables, $key, $defaultParametrable);
self::set_param($parametrable, $key, $default, $schema);
}
}
} else {
md::normalize_schema($schema);
foreach ($schema as $key => $sfield) {
$default = $sfield["default"];
if ($default !== null) {
$parametrable = A::get($parametrables, $key, $defaultParametrable);
self::set_param($parametrable, $key, $default);
}
}
}
}
static function set_params(?array $parametables, IParametrable $defaultParametrable, ?array $params, $schema): array {
if ($params === null || $schema === null) return [];
$modifiedKeys = [];
if ($schema instanceof Metadata) {
foreach ($schema->getKeys() as $key) {
if ($schema->has($params, $key)) {
$parametrable = A::get($parametables, $key, $defaultParametrable);
$value = $schema->get($params, $key);
self::set_param($parametrable, $key, $value, $schema);
$modifiedKeys[] = $key;
}
}
} else {
$indexes = md::normalize_schema($schema);
foreach (array_keys($schema) as $key) {
if (md::_has($params, $key, $schema, $indexes)) {
$parametrable = A::get($parametables, $key, $defaultParametrable);
$value = md::_get($params, $key, $schema, null, true, $indexes);
self::set_param($parametrable, $key, $value);
$modifiedKeys[] = $key;
}
}
}
return $modifiedKeys;
}
/** générer une liste de nom de méthodes pour les clés du schéma */
static function _auto_getters($schema, ?string $class=null): array {
$md = Metadata::with($schema);
$class_methods = get_class_methods($class);
$auto_setters = [];
foreach ($md->getKeys() as $key) {
$ppSetter = self::get_pp_setter($key, $md);
if ($class_methods !== null && in_array($ppSetter, $class_methods)) {
# ne pas générer de getter s'il existe un ppSetter
continue;
}
$method = self::get_getter($key, $md);
$auto_setters[$method] = $key;
}
return $auto_setters;
}
/** générer une liste de nom de méthodes pour les clés du schéma */
static function _auto_setters($schema): array {
$md = Metadata::with($schema);
$auto_setters = [];
foreach ($md->getKeys() as $key) {
$method = self::get_setter($key, $md);
$auto_setters[$method] = $key;
}
return $auto_setters;
}
/** générer une liste de signatures de méthodes getters pour les clés du schéma */
static function _autogen_methods_getters($schema, ?string $class=null): array {
$md = Metadata::with($schema);
$class_methods = get_class_methods($class);
$auto_getters = self::_auto_getters($md, $class);
$methods = [];
foreach ($auto_getters as $method => $key) {
if ($class_methods !== null && in_array($method, $class_methods)) continue;
$property = self::get_pp_property($key);
if (!property_exists($class, $property)) continue;
[$phpType, $returnType] = Autogen::fix_type($md->getType($key)->getPhpType());
$method .= "()";
if ($phpType !== null) $method = "$returnType $method";
$methods[] = $method;
}
return $methods;
}
/** générer une liste de signatures de méthodes setters pour les clés du schéma */
static function _autogen_methods_setters($schema, ?string $class=null): array {
$md = Metadata::with($schema);
$class_methods = get_class_methods($class);
$auto_setters = self::_auto_setters($md);
$methods = [];
foreach ($auto_setters as $method => $key) {
if ($class_methods !== null && in_array($method, $class_methods)) continue;
[$phpType, $returnType] = Autogen::fix_type($md->getType($key)->getPhpType());
if ($phpType !== null) $method .= "($phpType \$value)";
else $method .= "(\$value)";
if ($phpType !== null) $method = "$returnType $method";
$methods[] = $method;
}
return $methods;
}
/** vérifier si le nom de la méthode spécifiée est une méthode automatique */
static function should_call(string $name, ?array $auto_getters, ?array $auto_setters, $schema): bool {
$md = Metadata::with($schema);
if ($auto_setters === null) $auto_setters = self::_auto_setters($schema);
$key = A::get($auto_setters, $name);
if ($key !== null && $md->isKey($key)) return true;
if ($auto_getters === null) $auto_getters = self::_auto_getters($schema);
$key = A::get($auto_getters, $name);
if ($key !== null && $md->isKey($key)) return true;
return false;
}
/** appeler la méthode automatique spécifiée pour mettre à jour un paramètre */
static function call(IParametrable $parametrable, string $name, array $args, ?array $auto_getters, ?array $auto_setters, $schema) {
if ($auto_setters === null) $auto_setters = self::_auto_setters($schema);
$key = A::get($auto_setters, $name);
if ($key !== null) {
$schema = Metadata::with($schema);
$value = $schema->getType($key)->with(A::first($args));
$property = self::get_pp_property($key);
$setter = self::get_pp_setter($key, $schema);
$oldValue = prop::get($parametrable, $property);
prop::set($parametrable, $property, $value, $setter);
return $oldValue;
}
if ($auto_getters === null) $auto_getters = self::_auto_getters($schema);
$key = A::get($auto_getters, $name);
if ($key !== null) {
$property = self::get_pp_property($key);
return prop::get($parametrable, $property);
}
throw ValueException::invalid_value($name);
}
static function _autogen_literals($schema, ?string $class=null, bool $dynamicSchema=false): array {
$literals = [
[self::class, '\\nur\\b\\params\\parametrable_utils::class'],
];
if ($class !== null) $literals[] = [$class, "self::class"];
if (!$dynamicSchema) {
$literals[] = [$schema, "self::PARAMETRABLE_PARAMS_SCHEMA"];
}
return $literals;
}
static function _autogen_methods($schema, ?string $class=null): array {
return [
[self::class, "_autogen_methods_getters", $schema, $class],
[self::class, "_autogen_methods_setters", $schema, $class],
];
}
static function _AUTOGEN_CONSTS($schema, ?string $class=null, bool $dynamicSchema=false): array {
return [
"_AUTOGEN_LITERALS" => self::_autogen_literals($schema, $class, $dynamicSchema),
"_AUTOGEN_METHODS" => self::_autogen_methods($schema, $class),
"_AUTO_GETTERS" => self::_auto_getters($schema, $class),
"_AUTO_SETTERS" => self::_auto_setters($schema),
];
}
}