218 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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),
 | |
|     ];
 | |
|    }
 | |
| }
 |