<pman>Intégration de la branche rel74-0.4.1
This commit is contained in:
		
						commit
						ee0234f6ba
					
				| @ -1,3 +1,9 @@ | |||||||
|  | ## Release 0.4.1p74 du 17/03/2025-17:19 | ||||||
|  | 
 | ||||||
|  | * `56fda96` changer le type de variables gérées par EnvConfig | ||||||
|  | 
 | ||||||
|  | ## Release 0.4.0p82 du 14/03/2025-15:46 | ||||||
|  | 
 | ||||||
| ## Release 0.4.0p74 du 14/03/2025-15:44 | ## Release 0.4.0p74 du 14/03/2025-15:44 | ||||||
| 
 | 
 | ||||||
| * `4b84f11` début assocSchema | * `4b84f11` début assocSchema | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 0.4.0 | 0.4.1 | ||||||
|  | |||||||
| @ -15,10 +15,9 @@ use Throwable; | |||||||
|  *   profil par défaut est dépendant de l'implémentation de IConfigManager |  *   profil par défaut est dépendant de l'implémentation de IConfigManager | ||||||
|  *   utilisée. Dans l'implémentation actuelle, 'ALL' est le profil par défaut. |  *   utilisée. Dans l'implémentation actuelle, 'ALL' est le profil par défaut. | ||||||
|  * - PKEY est le chemin de clé dans lequel les caractères '.' sont remplacés |  * - PKEY est le chemin de clé dans lequel les caractères '.' sont remplacés | ||||||
|  *   par '__' et '-' par '_' (celà signifie qu'il n'est pas possible de définir |  *   par '__' | ||||||
|  *   un chemin de clé qui contient le caractère '_') |  | ||||||
|  * |  * | ||||||
|  * par exemple, la valeur dbs.my-auth.type du profil par défaut est pris dans |  * par exemple, la valeur dbs.my_auth.type du profil par défaut est pris dans | ||||||
|  * la variable 'CONFIG_ALL_dbs__my_auth__type'. pour le profil prod c'est la |  * la variable 'CONFIG_ALL_dbs__my_auth__type'. pour le profil prod c'est la | ||||||
|  * variable 'CONFIG_prod_dbs__my_auth__type' |  * variable 'CONFIG_prod_dbs__my_auth__type' | ||||||
|  * |  * | ||||||
| @ -51,7 +50,9 @@ class EnvConfig extends DynConfig { | |||||||
|     $profile = substr($name, 0, $i); |     $profile = substr($name, 0, $i); | ||||||
|     $name = substr($name, $i + 1); |     $name = substr($name, $i + 1); | ||||||
|     $pkey = str_replace("__", ".", $name); |     $pkey = str_replace("__", ".", $name); | ||||||
|     $pkey = str_replace("_", "-", $pkey); |     #XXX désactiver parce que les configurations sont plus généralement avec
 | ||||||
|  |     # le caractères '_', par le caractères '-'
 | ||||||
|  |     //$pkey = str_replace("_", "-", $pkey);
 | ||||||
|     return [$pkey, $profile]; |     return [$pkey, $profile]; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -164,7 +164,7 @@ abstract class Schema implements ArrayAccess { | |||||||
|     tcallable::ensure_ncallable($definition["normalizer_func"]); |     tcallable::ensure_ncallable($definition["normalizer_func"]); | ||||||
|     tarray::ensure_narray($definition["messages"]); |     tarray::ensure_narray($definition["messages"]); | ||||||
|     tcallable::ensure_ncallable($definition["formatter_func"]); |     tcallable::ensure_ncallable($definition["formatter_func"]); | ||||||
|     tbool::ensure_nbool($definition["composite"]); |     tbool::ensure_nbool($definition["computed"]); | ||||||
| 
 | 
 | ||||||
|     switch ($nature[0] ?? null) { |     switch ($nature[0] ?? null) { | ||||||
|     case "assoc": |     case "assoc": | ||||||
|  | |||||||
| @ -1,23 +1,19 @@ | |||||||
| # nulib\schema | # nulib\schema | ||||||
| 
 | 
 | ||||||
|  | * instance de WrapperContext directement dans le schéma  | ||||||
|  | * plus de {key} ni {orig} dans messages | ||||||
|  |   * les messages standard ne sont utilisés que s'il n'y a pas de message dans | ||||||
|  |     l'exception | ||||||
|  |   * si instance de UserException, prendre le message "non technique" pour | ||||||
|  |     résultat | ||||||
|  | * valeurs composite/computed | ||||||
|  |   * analyse / vérification de la valeur complète après calcul du résultat, si | ||||||
|  |     tous les résultats sont bons | ||||||
|  |   * calcul des valeurs composites/computed par une fonction avant/après l'analyse | ||||||
|  |     globale si résultat ok | ||||||
| * tdate et tdatetime. qu'en est-il des autres classes (delay, etc.) | * tdate et tdatetime. qu'en est-il des autres classes (delay, etc.) | ||||||
|   * possibilité de spécifier le format de la date à analyser  |   * possibilité de spécifier le format de la date à analyser  | ||||||
| * ScalarSchema::from_property() | * ScalarSchema::from_property() | ||||||
| * possibilité de spécifier un type via sa classe, e.g |  | ||||||
|   ~~~php |  | ||||||
|   Schema::ns($schema, [ |  | ||||||
|     MyType::class, null, "une valeur de type MyType" |  | ||||||
|   ]); |  | ||||||
|   ~~~ |  | ||||||
|   MyType doit implémenter IType |  | ||||||
| * type générique construit à partir d'un nom de classe, e.g |  | ||||||
|   ~~~php |  | ||||||
|   Schema::ns($schema, [ |  | ||||||
|     MyClass::class, null, "une valeur de type MyClass" |  | ||||||
|   ]); |  | ||||||
|   ~~~ |  | ||||||
|   MyClass ne doit pas implémenter IType, et le type correspondant est créé avec |  | ||||||
|   `new tgeneric(MyClass::class)` |  | ||||||
| 
 | 
 | ||||||
| * dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe | * dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe | ||||||
|   commun aux champs dans le tableau destination, e.g |   commun aux champs dans le tableau destination, e.g | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ namespace nur\sery\wip\schema; | |||||||
| use nur\sery\wip\schema\input\Input; | use nur\sery\wip\schema\input\Input; | ||||||
| use nur\sery\wip\schema\types\IType; | use nur\sery\wip\schema\types\IType; | ||||||
| 
 | 
 | ||||||
| class AnalyzerContext { | class WrapperContext { | ||||||
|   function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) { |   function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) { | ||||||
|     $this->schema = $schema; |     $this->schema = $schema; | ||||||
|     $this->wrapper = $wrapper; |     $this->wrapper = $wrapper; | ||||||
| @ -1,7 +1,6 @@ | |||||||
| <?php | <?php | ||||||
| namespace nur\sery\wip\schema\_scalar; | namespace nur\sery\wip\schema\_scalar; | ||||||
| 
 | 
 | ||||||
| use Exception; |  | ||||||
| use nulib\cl; | use nulib\cl; | ||||||
| use nulib\ref\schema\ref_analyze; | use nulib\ref\schema\ref_analyze; | ||||||
| use nulib\ref\schema\ref_schema; | use nulib\ref\schema\ref_schema; | ||||||
|  | |||||||
| @ -91,8 +91,11 @@ class ScalarSchema extends Schema { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): ScalarWrapper { |   function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): ScalarWrapper { | ||||||
|  |     # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception
 | ||||||
|  |     # cf le code similaire dans ScalarWrapper::__construct()
 | ||||||
|  |     $verifix = $value !== null || $wrapper !== null; | ||||||
|     if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); |     if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); | ||||||
|     return $wrapper->reset($value, $valueKey); |     return $wrapper->reset($value, $valueKey, $verifix); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   #############################################################################
 |   #############################################################################
 | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ namespace nur\sery\wip\schema\_scalar; | |||||||
| use nulib\php\func; | use nulib\php\func; | ||||||
| use nulib\ref\schema\ref_analyze; | use nulib\ref\schema\ref_analyze; | ||||||
| use nulib\ValueException; | use nulib\ValueException; | ||||||
| use nur\sery\wip\schema\AnalyzerContext; | use nur\sery\wip\schema\WrapperContext; | ||||||
| use nur\sery\wip\schema\input\Input; | use nur\sery\wip\schema\input\Input; | ||||||
| use nur\sery\wip\schema\types; | use nur\sery\wip\schema\types; | ||||||
| use nur\sery\wip\schema\types\IType; | use nur\sery\wip\schema\types\IType; | ||||||
| @ -74,7 +74,7 @@ class ScalarWrapper extends Wrapper { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** analyser la valeur et résoudre son type */ |   /** analyser la valeur et résoudre son type */ | ||||||
|   protected function analyze0(AnalyzerContext $context): int { |   protected function analyze0(WrapperContext $context): int { | ||||||
|     /** @var ScalarSchema $schema */ |     /** @var ScalarSchema $schema */ | ||||||
|     $schema = $context->schema; |     $schema = $context->schema; | ||||||
|     $input = $context->input; |     $input = $context->input; | ||||||
| @ -171,7 +171,7 @@ class ScalarWrapper extends Wrapper { | |||||||
|     $valueKey = $this->valueKey; |     $valueKey = $this->valueKey; | ||||||
|     $result = $this->result; |     $result = $this->result; | ||||||
|     $result->reset(); |     $result->reset(); | ||||||
|     $context = new AnalyzerContext($schema, $this, $input, $valueKey, $result); |     $context = new WrapperContext($schema, $this, $input, $valueKey, $result); | ||||||
| 
 | 
 | ||||||
|     /** @var func $analyzerFunc */ |     /** @var func $analyzerFunc */ | ||||||
|     $analyzerFunc = $schema->analyzerFunc; |     $analyzerFunc = $schema->analyzerFunc; | ||||||
| @ -243,7 +243,7 @@ class ScalarWrapper extends Wrapper { | |||||||
|       /** @var func $normalizerFunc */ |       /** @var func $normalizerFunc */ | ||||||
|       $normalizerFunc = $schema->normalizerFunc; |       $normalizerFunc = $schema->normalizerFunc; | ||||||
|       if ($normalizerFunc !== null) { |       if ($normalizerFunc !== null) { | ||||||
|         $context = new AnalyzerContext($schema, $this, $this->input, $valueKey, $result); |         $context = new WrapperContext($schema, $this, $this->input, $valueKey, $result); | ||||||
|         $orig = $value; |         $orig = $value; | ||||||
|         $value = $normalizerFunc->invoke([$orig, $context]); |         $value = $normalizerFunc->invoke([$orig, $context]); | ||||||
|         $modified = $value !== $orig; |         $modified = $value !== $orig; | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| <?php | <?php | ||||||
| namespace nur\sery\wip\schema; | namespace nur\sery\wip\schema; | ||||||
| 
 | 
 | ||||||
|  | use nulib\ValueException; | ||||||
| use nur\sery\wip\schema\types\IType; | use nur\sery\wip\schema\types\IType; | ||||||
| use nur\sery\wip\schema\types\Registry; | use nur\sery\wip\schema\types\Registry; | ||||||
| use nur\sery\wip\schema\types\tarray; | use nur\sery\wip\schema\types\tarray; | ||||||
| @ -31,7 +32,11 @@ class types { | |||||||
|     return self::$registry; |     return self::$registry; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static function get(bool $nullable, ?string $name, ?array $args=null, ?array $definition=null): IType { |   static function get(bool $nullable, $name, ?array $args=null, ?array $definition=null): IType { | ||||||
|  |     if ($name instanceof IType) return $name; | ||||||
|  |     if ($name !== null && !is_string($name)) { | ||||||
|  |       throw ValueException::invalid_type($name, "string"); | ||||||
|  |     } | ||||||
|     return self::registry()->get($nullable, $name, $args, $definition); |     return self::registry()->get($nullable, $name, $args, $definition); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -10,6 +10,8 @@ use nur\sery\wip\schema\Schema; | |||||||
|  * Interface IType: un type de données |  * Interface IType: un type de données | ||||||
|  */ |  */ | ||||||
| interface IType { | interface IType { | ||||||
|  |   static function get_params_from_definition(?array $definition): ?array; | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * obtenir, pour information, le nom officiel de ce type, utilisable dans une |    * obtenir, pour information, le nom officiel de ce type, utilisable dans une | ||||||
|    * définition de schéma |    * définition de schéma | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ namespace nur\sery\wip\schema\types; | |||||||
| 
 | 
 | ||||||
| use nulib\cl; | use nulib\cl; | ||||||
| use nulib\php\func; | use nulib\php\func; | ||||||
|  | use nulib\ValueException; | ||||||
| 
 | 
 | ||||||
| class Registry { | class Registry { | ||||||
|   const TYPES = [ |   const TYPES = [ | ||||||
| @ -16,7 +17,7 @@ class Registry { | |||||||
|     "array" => tarray::class, |     "array" => tarray::class, | ||||||
|     "callable" => tcallable::class, |     "callable" => tcallable::class, | ||||||
|     # types spéciaux
 |     # types spéciaux
 | ||||||
|     "raw" => tmixed::class, |     "raw" => traw::class, | ||||||
|     "mixed" => tmixed::class, |     "mixed" => tmixed::class, | ||||||
|     "key" => tkey::class, |     "key" => tkey::class, | ||||||
|     "pkey" => tpkey::class, |     "pkey" => tpkey::class, | ||||||
| @ -31,8 +32,6 @@ class Registry { | |||||||
|   protected $types; |   protected $types; | ||||||
| 
 | 
 | ||||||
|   function get(bool $nullable, ?string $name, ?array $args=null, ?array $definition=null): IType { |   function get(bool $nullable, ?string $name, ?array $args=null, ?array $definition=null): IType { | ||||||
|     $name ??= "raw"; |  | ||||||
|     $class = self::TYPES[$name]; |  | ||||||
|     if (cl::is_list($args)) { |     if (cl::is_list($args)) { | ||||||
|       $key = array_key_last($args); |       $key = array_key_last($args); | ||||||
|       $params = $args[$key]; |       $params = $args[$key]; | ||||||
| @ -41,6 +40,16 @@ class Registry { | |||||||
|       $params = $args; |       $params = $args; | ||||||
|       $args = null; |       $args = null; | ||||||
|     } |     } | ||||||
|  |     $name ??= "raw"; | ||||||
|  |     $class = cl::get(self::TYPES, $name); | ||||||
|  |     if ($class === null) { | ||||||
|  |       $class = $name; | ||||||
|  |       if (!class_exists($class)) { | ||||||
|  |         throw ValueException::invalid_type($class, IType::class); | ||||||
|  |       } elseif (!is_subclass_of($class, IType::class)) { | ||||||
|  |         return new tgeneric($class, $nullable, $params); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|     $params = cl::merge($class::get_params_from_definition($definition), $params); |     $params = cl::merge($class::get_params_from_definition($definition), $params); | ||||||
|     if ($args || $params !== null) { |     if ($args || $params !== null) { | ||||||
|       $args ??= []; |       $args ??= []; | ||||||
|  | |||||||
							
								
								
									
										52
									
								
								src/schema/types/tgeneric.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/schema/types/tgeneric.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | <?php | ||||||
|  | namespace nur\sery\wip\schema\types; | ||||||
|  | 
 | ||||||
|  | use nulib\ValueException; | ||||||
|  | use nur\sery\wip\schema\_scalar\ScalarResult; | ||||||
|  | use nur\sery\wip\schema\_scalar\ScalarSchema; | ||||||
|  | use nur\sery\wip\schema\input\Input; | ||||||
|  | use nur\sery\wip\schema\Result; | ||||||
|  | use nur\sery\wip\schema\Schema; | ||||||
|  | 
 | ||||||
|  | class tgeneric extends _tsimple { | ||||||
|  |   function __construct(string $class, bool $nullable, ?array $params=null) { | ||||||
|  |     $this->class = $class; | ||||||
|  |     parent::__construct($nullable, $params); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   protected string $class; | ||||||
|  | 
 | ||||||
|  |   function getClass(): string { | ||||||
|  |     return $this->class; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function isAvailable(Input $input, $valueKey): bool { | ||||||
|  |     return $input->isAvailable($valueKey); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   public function isNull($value): bool { | ||||||
|  |     return $value === null; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function isValid($value, ?bool &$normalized=null): bool { | ||||||
|  |     $normalized = true; | ||||||
|  |     return $value instanceof $this->class; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function parse(string $value) { | ||||||
|  |     throw ValueException::invalid_type($value, $this->class); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * @var ScalarResult $result | ||||||
|  |    * @var ScalarSchema $schema | ||||||
|  |    */ | ||||||
|  |   function verifix(&$value, Result $result, Schema $schema): bool { | ||||||
|  |     $result->setNormalized(); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function format($value, $format=null): string { | ||||||
|  |     return strval($value); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -41,6 +41,6 @@ class tmixed extends _tsimple { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function format($value, $format=null): string { |   function format($value, $format=null): string { | ||||||
|     return var_export($value, true); |     return strval($value); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ class AssocSchemaTest extends TestCase { | |||||||
|     "name" => null, |     "name" => null, | ||||||
|     "pkey" => null, |     "pkey" => null, | ||||||
|     "header" => null, |     "header" => null, | ||||||
|     "composite" => null, |     "computed" => null, | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   static function schema(array $definition, array $keyDefinitions): array { |   static function schema(array $definition, array $keyDefinitions): array { | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ class ScalarSchemaTest extends TestCase { | |||||||
|     "name" => null, |     "name" => null, | ||||||
|     "pkey" => null, |     "pkey" => null, | ||||||
|     "header" => null, |     "header" => null, | ||||||
|     "composite" => null, |     "computed" => null, | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   static function schema(array $schema): array { |   static function schema(array $schema): array { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user