From 9109e0fe391111fbe28e6647b58c37c0600d88f5 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 24 Mar 2025 13:46:51 +0400 Subject: [PATCH 01/19] modifs.mineures sans commentaires --- src/schema/TODO.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 8da8c24..42ef73c 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,5 +1,14 @@ # nulib\schema +* pour AssocResult, les clés suivantes sont supportées: + * false pour la clé courante + * null pour un résultat aggrégé + * "" pour le résultat du tableau + * $key pour le résultat de la clé correspondante +* si possible, ne pas utiliser les méthodes isScalar(), isAssoc(), etc. + --> vérifier s'il suffit d'utiliser instanceof ScalarXxx, AssocXxx, etc. pour + les actions courantes + * ensureKeys() et orderKeys() se fait au niveau de access (ou input?) * access/input ne pouvant pas connaître les valeurs appropriées, c'est le schéma qui les génère. ensureKeys($values) From ff02ffdf4fa1e5ab9a5135da619bea15e300812b Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 27 Mar 2025 15:58:47 +0400 Subject: [PATCH 02/19] modifs.mineures sans commentaires --- src/schema/TODO.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 42ef73c..7c9cbb6 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,5 +1,11 @@ # nulib\schema +* ensureKeys() et orderKeys() se fait au niveau de access (ou input?) + * access/input ne pouvant pas connaître les valeurs appropriées, c'est le + schéma qui les génère. ensureKeys($values) + * méthode ensureAssoc() transforme les clés séquentielles en clés associatives +* l'ordre est `ensureAssoc [--> ensureKeys] [--> orderKeys]` + * pour AssocResult, les clés suivantes sont supportées: * false pour la clé courante * null pour un résultat aggrégé @@ -9,12 +15,6 @@ --> vérifier s'il suffit d'utiliser instanceof ScalarXxx, AssocXxx, etc. pour les actions courantes -* ensureKeys() et orderKeys() se fait au niveau de access (ou input?) - * access/input ne pouvant pas connaître les valeurs appropriées, c'est le - schéma qui les génère. ensureKeys($values) - * méthode ensureAssoc() transforme les clés séquentielles en clés associatives -* l'ordre est `ensureAssoc [--> ensureKeys] [--> orderKeys]` - * rajouter l'attribut "size" pour spécifier la taille maximale des valeurs * cela pourrait servir pour générer automatiquement des tables SQL * ou pour modéliser un schéma FSV From c274adb6e66d96b1cd607930e92ff469b36f1424 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 28 Mar 2025 15:38:57 +0400 Subject: [PATCH 03/19] modifs.mineures sans commentaires --- src/php/access/ArrayAccess.php | 8 + src/php/access/PropertyAccess.php | 2 - src/php/access/ValueAccess.php | 8 + src/schema/Schema.php | 31 ++- src/schema/TODO.md | 1 + src/schema/Wrapper.php | 8 +- src/schema/_assoc/AssocSchema.php | 13 +- src/schema/_assoc/AssocWrapper.php | 59 ++++-- src/schema/_assoc/AssocWrapperContext.php | 15 +- src/schema/_list/ListSchema.php | 7 +- src/schema/_list/ListWrapper.php | 2 - src/schema/_scalar/ScalarSchema.php | 15 +- src/schema/_scalar/ScalarWrapper.php | 21 +- src/schema/input/Input.php | 25 ++- src/schema/types.php | 4 +- src/schema/types/IType.php | 3 + src/schema/types/Registry.php | 5 +- src/schema/types/tarray.php | 4 + src/schema/types/tbool.php | 4 + src/schema/types/tcontent.php | 4 + src/schema/types/tfloat.php | 4 + src/schema/types/{tcallable.php => tfunc.php} | 18 +- src/schema/types/tgeneric.php | 4 + src/schema/types/tint.php | 4 + src/schema/types/tkey.php | 4 + src/schema/types/tmixed.php | 4 + src/schema/types/tpkey.php | 4 + src/schema/types/trawstring.php | 4 + tests/wip/schema/_assoc/AssocSchemaTest.php | 196 +++++++++++++++++- tests/wip/schema/types/boolTest.php | 4 +- tests/wip/schema/types/floatTest.php | 12 +- tests/wip/schema/types/intTest.php | 12 +- tests/wip/schema/types/strTest.php | 12 +- tests/wip/schema/types/unionTest.php | 4 +- 34 files changed, 394 insertions(+), 131 deletions(-) create mode 100644 src/php/access/ArrayAccess.php create mode 100644 src/php/access/ValueAccess.php rename src/schema/types/{tcallable.php => tfunc.php} (76%) diff --git a/src/php/access/ArrayAccess.php b/src/php/access/ArrayAccess.php new file mode 100644 index 0000000..96ff505 --- /dev/null +++ b/src/php/access/ArrayAccess.php @@ -0,0 +1,8 @@ +getWrapper($value, $valueKey, null, $wrapper); + return self::ns($definition, null, $schema)->getWrapper($value, $valueKey, null, $wrapper); } protected static function have_nature(array $definition, ?string &$nature=null): bool { @@ -187,12 +187,12 @@ abstract class Schema implements ArrayAccess { tbool::ensure_bool($definition["required"]); tbool::ensure_bool($definition["nullable"]); tcontent::ensure_ncontent($definition["desc"]); - tcallable::ensure_ncallable($definition["analyzer_func"]); - tcallable::ensure_ncallable($definition["extractor_func"]); - tcallable::ensure_ncallable($definition["parser_func"]); - tcallable::ensure_ncallable($definition["normalizer_func"]); + tfunc::ensure_nfunc($definition["analyzer_func"]); + tfunc::ensure_nfunc($definition["extractor_func"]); + tfunc::ensure_nfunc($definition["parser_func"]); + tfunc::ensure_nfunc($definition["normalizer_func"]); tarray::ensure_narray($definition["messages"]); - tcallable::ensure_ncallable($definition["formatter_func"]); + tfunc::ensure_nfunc($definition["formatter_func"]); tbool::ensure_nbool($definition["computed"]); switch ($nature[0] ?? null) { @@ -252,11 +252,11 @@ abstract class Schema implements ArrayAccess { case "assoc": foreach ($definition["schema"] as &$keydef) { self::_ensure_schema_instances($keydef); - Schema::ns($keydef, null, null, false); + Schema::ns(null, null, $keydef, false); }; unset($keydef); break; case "list": - Schema::ns($definition["schema"], null, null, false); + Schema::ns(null, null, $definition["schema"], false); break; } } @@ -280,14 +280,7 @@ abstract class Schema implements ArrayAccess { */ abstract function getKeys(): array; - abstract function getSchema($key): Schema; - - /** retourner true si le schéma est de nature tableau associatif */ - function isAssoc(?AssocSchema &$schema=null): bool { return false; } - /** retourner true si le schéma est de nature liste */ - function isList(?ListSchema &$schema=null): bool { return false; } - /** retourner true si le schéma est de nature scalaire */ - function isScalar(?ScalarSchema &$schema=null): bool { return false; } + abstract function getSchema($key=false): Schema; abstract protected function newWrapper(): Wrapper; diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 7c9cbb6..65c4212 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -5,6 +5,7 @@ schéma qui les génère. ensureKeys($values) * méthode ensureAssoc() transforme les clés séquentielles en clés associatives * l'ordre est `ensureAssoc [--> ensureKeys] [--> orderKeys]` +* si false, supprimer la clé du tableau sauf si ensureKeys * pour AssocResult, les clés suivantes sont supportées: * false pour la clé courante diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 7c558e8..3dfc06b 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -12,10 +12,6 @@ use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; abstract class Wrapper implements ArrayAccess, IteratorAggregate { - function isAssoc(?AssocWrapper &$wrapper=null): bool { return false; } - function isList(?ListWrapper &$wrapper=null): bool { return false; } - function isScalar(?ScalarWrapper &$wrapper=null): bool { return false; } - protected WrapperContext $context; /** changer les paramètres de gestion des valeurs */ @@ -25,7 +21,9 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { protected function resetContext($resetSelectedKey): void { $context = $this->context; - $context->type = null; + $type = $context->schema->type; + if (is_array($type)) $type = $type[0]; + $context->type = $type; $context->result->reset(); $context->analyzed = false; $context->normalized = false; diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index b9fac49..4b6b753 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -47,6 +47,10 @@ class AssocSchema extends Schema { $this->_definition = $definition; self::_ensure_type($definition); self::_ensure_schema_instances($definition); + } else { + # ici, $definition contient un schema déjà instancié, mais c'est le mieux + # qu'on puisse faire + $this->_definition = $definition; } $this->definition = $definition; $keys = []; @@ -56,19 +60,14 @@ class AssocSchema extends Schema { $this->keys = $keys; } - function isAssoc(?AssocSchema &$schema=null): bool { - $schema = $this; - return true; - } - protected array $keys; function getKeys(): array { return $this->keys; } - function getSchema($key): Schema { - if ($key === null) return $this; + function getSchema($key=false): Schema { + if ($key === null || $key === false) return $this; $schema = $this->definition["schema"][$key] ?? null; if ($schema === null) throw ValueException::invalid_key($key); return $schema; diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 1add86c..71210d1 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -1,6 +1,7 @@ getKeys(); + $keyParams = cl::merge($params, [ + "throw" => false, + ]); $keyWrappers = []; foreach ($keys as $key) { - $keyWrappers[$key] = $schema->getSchema($key)->getWrapper(); + $value = null; + $keyWrappers[$key] = $schema->getSchema($key)->getWrapper($value, null, $keyParams); } $this->context = $context = new AssocWrapperContext($schema, null, null, $params); - $context->arrayWrapper = new ScalarWrapper($schema, $dummy, null, null, $context); + $arrayParams = cl::merge($params, [ + "throw" => false, + ]); + $context->arrayWrapper = new ScalarWrapper($schema, $dummy, null, $arrayParams, $context); $context->keys = $keys; $context->keyWrappers = $keyWrappers; - # calculer manuellemet throw ici parce que WrapperContext le met à true par - # défaut. on veut pouvoir mettre temporairement throw à false si jamais il - # n'est pas spécifié par l'utilisateur - $throw = $params["throw"] ?? null; - # Si $value est null, ne pas lancer d'exception, parce qu'on considère que - # c'est une initialisation sans conséquences - if ($throw === null && $value !== null) $throw = true; - $context->throw = $throw ?? false; - $this->reset($value, $valueKey); - $context->throw = $throw ?? true; + if ($value !== null) { + # n'initialiser que si $value n'est pas null + $this->reset($value, $valueKey); + } } - function isAssoc(?AssocWrapper &$wrapper=null): bool { $wrapper = $this; return true; } - /** @var AssocWrapperContext */ protected WrapperContext $context; @@ -70,7 +70,8 @@ class AssocWrapper extends Wrapper { } protected function _getWrapper($key): Wrapper { - if ($key === null) return $this->context->arrayWrapper; + $context = $this->context; + if ($key === null) return $context->arrayWrapper; $wrapper = $context->keyWrappers[$key] ?? null; if ($wrapper === null) throw ValueException::invalid_key($key); return $wrapper; @@ -93,17 +94,26 @@ class AssocWrapper extends Wrapper { $array = $context->input->get($valueKey); if ($array === null) $context->input->set([], $valueKey); } + + if ($context->ensureAssoc) { + $context->input->ensureAssoc($context->schema->getKeys()); + } + $what = ScalarWrapper::_analyze($context, $wrapper, $params); /** @var ScalarResult $result */ $result = $context->result; if (!$result->valid) return $what; + foreach ($context->keyWrappers as $keyWrapper) { $keyWrapper->analyze($params); if (!$keyWrapper->isValid()) { + #XXX distinguer MISSING, UNAVAILABLE, NULL et !VALID $what = ref_analyze::INVALID; $result->addInvalidMessage($keyWrapper); } } + + #XXX supprimer les clés "missing" ou "unavailable" return $what; } @@ -112,6 +122,25 @@ class AssocWrapper extends Wrapper { * @param AssocWrapper $wrapper */ static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { + $ensureKeys = $context->ensureKeys; + $ensureOrder = $context->ensureOrder; + if ($ensureKeys || $ensureOrder) { + $schema = $context->schema; + $keys = $schema->getKeys(); + if ($ensureKeys) { + $defaults = []; + foreach ($keys as $key) { + $default = $schema->getSchema($key)->default; + if ($default === null) { + $default = $wrapper->getType($key)->getNullValue(); + } + $defaults[$key] = $default; + } + } + if ($ensureKeys) $context->input->ensureKeys($defaults, $params); + if ($ensureOrder) $context->input->ensureOrder($keys, $params); + } + $modified = ScalarWrapper::_normalize($context, $wrapper, $params); foreach ($context->keyWrappers as $keyWrapper) { if ($keyWrapper->normalize($params)) $modified = true; diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index c504197..8512635 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -9,20 +9,23 @@ use nur\sery\wip\schema\WrapperContext; class AssocWrapperContext extends WrapperContext { const DEFAULT_ENSURE_ARRAY = false; + const DEFAULT_ENSURE_ASSOC = true; const DEFAULT_ENSURE_KEYS = true; const DEFAULT_ENSURE_ORDER = true; - function __construct(Schema $schema, ?Input $input, $valueKey, ?array $params) { - parent::__construct($schema, $input, $valueKey, $params); + public bool $ensureArray; + public bool $ensureAssoc; + public bool $ensureKeys; + public bool $ensureOrder; + + public function resetParams(?array $params): void { + parent::resetParams($params); $this->ensureArray = $params["ensure_array"] ?? self::DEFAULT_ENSURE_ARRAY; + $this->ensureAssoc = $params["ensure_assoc"] ?? self::DEFAULT_ENSURE_ASSOC; $this->ensureKeys = $params["ensure_keys"] ?? self::DEFAULT_ENSURE_KEYS; $this->ensureOrder = $params["ensure_order"] ?? self::DEFAULT_ENSURE_ORDER; } - public bool $ensureArray; - public bool $ensureKeys; - public bool $ensureOrder; - public ?ScalarWrapper $arrayWrapper = null; /** liste des clés valides */ diff --git a/src/schema/_list/ListSchema.php b/src/schema/_list/ListSchema.php index 4887e95..cdc1024 100644 --- a/src/schema/_list/ListSchema.php +++ b/src/schema/_list/ListSchema.php @@ -51,18 +51,13 @@ class ListSchema extends Schema { $this->definition = $definition; } - function isList(?ListSchema &$schema=null): bool { - $schema = $this; - return true; - } - const KEYS = [null]; function getKeys(): array { return self::KEYS; } - public function getSchema($key): Schema { + public function getSchema($key=false): Schema { if ($key !== null) throw ValueException::invalid_key($key); return $this; } diff --git a/src/schema/_list/ListWrapper.php b/src/schema/_list/ListWrapper.php index cae167b..169dd98 100644 --- a/src/schema/_list/ListWrapper.php +++ b/src/schema/_list/ListWrapper.php @@ -5,8 +5,6 @@ use nur\sery\wip\schema\Result; use nur\sery\wip\schema\Wrapper; abstract/*XXX*/ class ListWrapper extends Wrapper { - function isList(?ListWrapper &$wrapper=null): bool { $wrapper = $this; return true; } - function ensureKeys(): bool { } diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 597a34b..a9c2ad5 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -56,24 +56,23 @@ class ScalarSchema extends Schema { $this->_definition = $definition; self::_ensure_type($definition); self::_ensure_schema_instances($definition); + } else { + # ici, $definition contient un schema déjà instancié, mais c'est le mieux + # qu'on puisse faire + $this->_definition = $definition; } $this->definition = $definition; } - function isScalar(?ScalarSchema &$schema=null): bool { - $schema = $this; - return true; - } - const KEYS = [null]; function getKeys(): array { return self::KEYS; } - function getSchema($key): Schema { - if ($key !== null) throw ValueException::invalid_key($key); - return $this; + function getSchema($key=false): Schema { + if ($key === null || $key === false) return $this; + throw ValueException::invalid_key($key); } protected function newWrapper(): ScalarWrapper { diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 588e8b3..c5b24c8 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -4,8 +4,6 @@ namespace nur\sery\wip\schema\_scalar; use nulib\php\func; use nulib\ref\schema\ref_analyze; use nulib\ValueException; -use nur\sery\wip\schema\_assoc\AssocWrapper; -use nur\sery\wip\schema\_assoc\AssocWrapperContext; use nur\sery\wip\schema\Schema; use nur\sery\wip\schema\types; use nur\sery\wip\schema\types\IType; @@ -26,20 +24,15 @@ class ScalarWrapper extends Wrapper { $context->result = new ScalarResult(); $this->context = $context; - # calculer manuellemet throw ici parce que WrapperContext le met à true par - # défaut. on veut pouvoir mettre temporairement throw à false si jamais il - # n'est pas spécifié par l'utilisateur - $throw = $params["throw"] ?? null; - # Si $value est null, ne pas lancer d'exception, parce qu'on considère que - # c'est une initialisation sans conséquences - if ($throw === null && $value !== null) $throw = true; - $context->throw = $throw ?? false; - $this->reset($value, $valueKey); - $context->throw = $throw ?? true; + if ($value !== null) { + # n'initialiser que si $value n'est pas null + $this->reset($value, $valueKey); + } else { + # il faut au moins que le type soit disponible + $this->resetContext(false); + } } - function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; } - protected WrapperContext $context; function getKeys(): array { diff --git a/src/schema/input/Input.php b/src/schema/input/Input.php index 799eb4a..4973195 100644 --- a/src/schema/input/Input.php +++ b/src/schema/input/Input.php @@ -1,6 +1,7 @@ access = new PropertyAccess($dest, null, [ "allow_empty" => $allowEmpty, "allow_null" => true, ]); - } elseif ($accessType == self::ACCESS_KEY) { + } elseif ($accessType == ref_input::ACCESS_KEY) { $this->access = new KeyAccess($dest, null, [ "allow_empty" => $allowEmpty, "allow_null" => true, @@ -72,4 +71,16 @@ class Input { $input->access = $this->access->addKey($key); return $input; } + + function ensureAssoc(array $keys, ?array $params=null): void { + $this->access->ensureAssoc($keys, $params); + } + + function ensureKeys(array $defaults, ?array $params=null): void { + $this->access->ensureKeys($defaults, $params); + } + + function ensureOrder(array $keys, ?array $params=null): void { + $this->access->ensureOrder($keys, $params); + } } diff --git a/src/schema/types.php b/src/schema/types.php index c1b618b..117e779 100644 --- a/src/schema/types.php +++ b/src/schema/types.php @@ -6,7 +6,7 @@ use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\types\Registry; use nur\sery\wip\schema\types\tarray; use nur\sery\wip\schema\types\tbool; -use nur\sery\wip\schema\types\tcallable; +use nur\sery\wip\schema\types\tfunc; use nur\sery\wip\schema\types\tcontent; use nur\sery\wip\schema\types\tfloat; use nur\sery\wip\schema\types\tint; @@ -47,7 +47,7 @@ class types { static function int(bool $nullable=true): tint { return self::get($nullable, "int"); } static function float(bool $nullable=true): tfloat { return self::get($nullable, "float"); } static function array(bool $nullable=true): tarray { return self::get($nullable, "array"); } - static function callable(bool $nullable=true): tcallable { return self::get($nullable, "callable"); } + static function callable(bool $nullable=true): tfunc { return self::get($nullable, "callable"); } static function raw(bool $nullable=true): traw { return self::get($nullable, "raw"); } static function mixed(bool $nullable=true): tmixed { return self::get($nullable, "mixed"); } static function key(bool $nullable=true): tkey { return self::get($nullable, "key"); } diff --git a/src/schema/types/IType.php b/src/schema/types/IType.php index 0fbe948..574d5e4 100644 --- a/src/schema/types/IType.php +++ b/src/schema/types/IType.php @@ -47,6 +47,9 @@ interface IType { */ function getPhpType(bool $allowNullable=true): ?string; + /** obtenir la valeur "nulle" pour les objets de ce type */ + function getNullValue(); + /** * indiquer si c'est le type d'une valeur qui ne peut prendre que 2 états: une * "vraie" et une "fausse" diff --git a/src/schema/types/Registry.php b/src/schema/types/Registry.php index fdaabde..f8373cf 100644 --- a/src/schema/types/Registry.php +++ b/src/schema/types/Registry.php @@ -12,10 +12,9 @@ class Registry { "text" => ttext::class, "bool" => tbool::class, "boolean" => tbool::class, "int" => tint::class, "integer" => tint::class, - "float" => tfloat::class, "flt" => tfloat::class, - "double" => tfloat::class, "dbl" => tfloat::class, + "float" => tfloat::class, "flt" => tfloat::class, "double" => tfloat::class, "dbl" => tfloat::class, "array" => tarray::class, - "callable" => tcallable::class, + "func" => tfunc::class, "function" => tfunc::class, "callable" => tfunc::class, # types spéciaux "raw" => traw::class, "mixed" => tmixed::class, diff --git a/src/schema/types/tarray.php b/src/schema/types/tarray.php index a6b2bf9..0f55ea3 100644 --- a/src/schema/types/tarray.php +++ b/src/schema/types/tarray.php @@ -35,6 +35,10 @@ class tarray extends _tstring { return "array"; } + function getNullValue() { + return $this->nullable? null: []; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = is_array($value); return $normalized || is_scalar($value); diff --git a/src/schema/types/tbool.php b/src/schema/types/tbool.php index dffa9c4..a8e9e3d 100644 --- a/src/schema/types/tbool.php +++ b/src/schema/types/tbool.php @@ -76,6 +76,10 @@ class tbool extends _tformatable { return [false, true, null]; } + function getNullValue() { + return $this->nullable? null: false; + } + function isAvailable(Input $input, $valueKey): bool { return $input->isAvailable($valueKey); } diff --git a/src/schema/types/tcontent.php b/src/schema/types/tcontent.php index 0a600f4..b885a56 100644 --- a/src/schema/types/tcontent.php +++ b/src/schema/types/tcontent.php @@ -23,6 +23,10 @@ abstract class tcontent extends _tunion { return "string|array"; } + function getNullValue() { + return $this->nullable? null: []; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = is_string($value) || is_array($value); return $normalized || is_scalar($value); diff --git a/src/schema/types/tfloat.php b/src/schema/types/tfloat.php index 85767b6..70118c5 100644 --- a/src/schema/types/tfloat.php +++ b/src/schema/types/tfloat.php @@ -24,6 +24,10 @@ class tfloat extends _tformatable { return "float"; } + function getNullValue() { + return $this->nullable? null: 0.0; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = is_float($value); return is_scalar($value); diff --git a/src/schema/types/tcallable.php b/src/schema/types/tfunc.php similarity index 76% rename from src/schema/types/tcallable.php rename to src/schema/types/tfunc.php index 76e2656..e13a39f 100644 --- a/src/schema/types/tcallable.php +++ b/src/schema/types/tfunc.php @@ -9,23 +9,27 @@ use nur\sery\wip\schema\_scalar\ScalarSchema; use nur\sery\wip\schema\Result; use nur\sery\wip\schema\Schema; -class tcallable extends _tsimple { - const NAME = "callable"; +class tfunc extends _tsimple { + const NAME = "func"; - const ALIASES = ["func", "function"]; + const ALIASES = ["function", "callable"]; - static function ensure_callable(&$callable): void { - $callable = func::ensure($callable); + static function ensure_func(&$func): void { + $func = func::ensure($func); } - static function ensure_ncallable(&$callable): void { - if ($callable !== null) self::ensure_callable($callable); + static function ensure_nfunc(&$func): void { + if ($func !== null) self::ensure_func($func); } function getClass(): string { return func::class; } + function getNullValue() { + return null; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = $value instanceof func; return func::check($value); diff --git a/src/schema/types/tgeneric.php b/src/schema/types/tgeneric.php index fe069b8..09a115d 100644 --- a/src/schema/types/tgeneric.php +++ b/src/schema/types/tgeneric.php @@ -20,6 +20,10 @@ class tgeneric extends _tsimple { return $this->class; } + function getNullValue() { + return null; + } + function isAvailable(Input $input, $valueKey): bool { return $input->isAvailable($valueKey); } diff --git a/src/schema/types/tint.php b/src/schema/types/tint.php index eddab99..a1a98e0 100644 --- a/src/schema/types/tint.php +++ b/src/schema/types/tint.php @@ -26,6 +26,10 @@ class tint extends _tformatable { return "int"; } + function getNullValue() { + return $this->nullable? null: 0; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = is_int($value); return is_scalar($value); diff --git a/src/schema/types/tkey.php b/src/schema/types/tkey.php index f1cca27..f3f0f5d 100644 --- a/src/schema/types/tkey.php +++ b/src/schema/types/tkey.php @@ -23,6 +23,10 @@ class tkey extends _tunion { return "string|int"; } + function getNullValue() { + return $this->nullable? null: ""; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = is_string($value) || is_int($value); return $normalized || is_scalar($value); diff --git a/src/schema/types/tmixed.php b/src/schema/types/tmixed.php index f549204..5fa3e85 100644 --- a/src/schema/types/tmixed.php +++ b/src/schema/types/tmixed.php @@ -14,6 +14,10 @@ class tmixed extends _tsimple { return "mixed"; } + function getNullValue() { + return null; + } + function isAvailable(Input $input, $valueKey): bool { return $input->isAvailable($valueKey); } diff --git a/src/schema/types/tpkey.php b/src/schema/types/tpkey.php index 7b2234b..20c9c77 100644 --- a/src/schema/types/tpkey.php +++ b/src/schema/types/tpkey.php @@ -28,6 +28,10 @@ class tpkey extends _tunion { return "string|int|array"; } + function getNullValue() { + return $this->nullable? null: []; + } + function isValid($value, ?bool &$normalized=null): bool { $normalized = is_string($value) || is_int($value) || is_array($value); return $normalized || is_scalar($value); diff --git a/src/schema/types/trawstring.php b/src/schema/types/trawstring.php index 674d430..938242d 100644 --- a/src/schema/types/trawstring.php +++ b/src/schema/types/trawstring.php @@ -24,6 +24,10 @@ class trawstring extends _tstring { return "string"; } + function getNullValue() { + return $this->nullable? null: ""; + } + function isNull($value): bool { return $value === null; } diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index 987e845..cdd1567 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -3,7 +3,9 @@ namespace nur\sery\wip\schema\_assoc; use nulib\ext\yaml; use nulib\tests\TestCase; +use nulib\ValueException; use nur\sery\wip\schema\_scalar\ScalarSchemaTest; +use nur\sery\wip\schema\Schema; class AssocSchemaTest extends TestCase { const NULL_SCHEMA = [ @@ -114,6 +116,7 @@ class AssocSchemaTest extends TestCase { "c" => false, ], $array); + ########################################################################### $schema = new AssocSchema([ "a" => "string", "b" => "int", @@ -124,15 +127,15 @@ class AssocSchemaTest extends TestCase { $schema->getWrapper($array); self::assertSame([ "a" => "string", - "b" => false, - "c" => null, + "b" => 0, + "c" => false, ], $array); $array = ["c" => false, "a" => " string "]; $schema->getWrapper($array); self::assertSame([ "a" => "string", - "b" => false, + "b" => 0, "c" => false, ], $array); @@ -140,8 +143,8 @@ class AssocSchemaTest extends TestCase { $schema->getWrapper($array, null, ["ensure_order" => false]); self::assertSame([ "a" => "string", - "b" => false, - "c" => null, + "b" => 0, + "c" => false, ], $array); $array = ["c" => false, "a" => " string "]; @@ -149,7 +152,7 @@ class AssocSchemaTest extends TestCase { self::assertSame([ "c" => false, "a" => "string", - "b" => false, + "b" => 0, ], $array); $array = ["a" => " string "]; @@ -165,4 +168,185 @@ class AssocSchemaTest extends TestCase { "c" => false, ], $array); } + + const STRING_SCHEMA = [ + "s" => "string", + "f" => "string", + "m" => "string", + ]; + + const NSTRING_SCHEMA = [ + "s" => "?string", + "f" => "?string", + "m" => "?string", + ]; + + const RSTRING_SCHEMA = [ + "s" => ["string", "required" => true], + "f" => ["string", "required" => true], + "m" => ["string", "required" => true], + ]; + + const RNSTRING_SCHEMA = [ + "s" => ["?string", "required" => true], + "f" => ["?string", "required" => true], + "m" => ["?string", "required" => true], + ]; + + const STRINGS = ["s" => "string", "f" => false]; + const NSTRINGS = ["s" => null, "f" => null]; + + function testString() { + /** @var AssocSchema $schema */ + $schema = Schema::ns(self::STRING_SCHEMA); + + $array = self::STRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::STRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("f"); + self::assertTrue($result->present); + self::assertFalse($result->available); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + + self::assertNotException(function() use ($schema) { + $array = self::STRINGS; + $schema->getWrapper($array); + }); + + $array = self::NSTRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::NSTRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertFalse($result->valid); + self::assertSame("null", $result->messageKey); + $result = $wrapper->getResult("f"); + self::assertFalse($result->valid); + self::assertSame("null", $result->messageKey); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + + self::assertException(ValueException::class, function() use ($schema) { + $array = self::NSTRINGS; + $schema->getWrapper($array); + }); + } + + function testNstring() { + /** @var AssocSchema $schema */ + $schema = Schema::ns(self::NSTRING_SCHEMA); + + $array = self::STRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::STRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("f"); + self::assertTrue($result->present); + self::assertFalse($result->available); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + + self::assertNotException(function() use ($schema) { + $array = self::STRINGS; + $schema->getWrapper($array); + }); + + $array = self::NSTRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::NSTRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("f"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + + self::assertNotException(function() use ($schema) { + $array = self::NSTRINGS; + $schema->getWrapper($array); + }); + } + + function testRstring() { + /** @var AssocSchema $schema */ + $schema = Schema::ns(self::RSTRING_SCHEMA); + + $array = self::STRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::STRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("f"); + self::assertTrue($result->present); + self::assertFalse($result->available); + self::assertSame("unavailable", $result->messageKey); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + self::assertSame("missing", $result->messageKey); + + self::assertException(ValueException::class, function() use ($schema) { + $array = self::STRINGS; + $schema->getWrapper($array); + }); + + $array = self::NSTRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::NSTRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertFalse($result->valid); + self::assertSame("null", $result->messageKey); + $result = $wrapper->getResult("f"); + self::assertFalse($result->valid); + self::assertSame("null", $result->messageKey); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + self::assertSame("missing", $result->messageKey); + + self::assertException(ValueException::class, function() use ($schema) { + $array = self::NSTRINGS; + $schema->getWrapper($array); + }); + } + + function testRnstring() { + /** @var AssocSchema $schema */ + $schema = Schema::ns(self::RNSTRING_SCHEMA); + + $array = self::STRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::STRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("f"); + self::assertTrue($result->present); + self::assertFalse($result->available); + self::assertSame("unavailable", $result->messageKey); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + self::assertSame("missing", $result->messageKey); + + self::assertException(ValueException::class, function() use ($schema) { + $array = self::STRINGS; + $schema->getWrapper($array); + }); + + $array = self::NSTRINGS; + $wrapper = $schema->getWrapper($array, null, ["throw" => false]); + self::assertSame(self::NSTRINGS, $array); + $result = $wrapper->getResult("s"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("f"); + self::assertTrue($result->normalized); + $result = $wrapper->getResult("m"); + self::assertFalse($result->present); + self::assertSame("missing", $result->messageKey); + + self::assertException(ValueException::class, function() use ($schema) { + $array = self::NSTRINGS; + $schema->getWrapper($array); + }); + } } diff --git a/tests/wip/schema/types/boolTest.php b/tests/wip/schema/types/boolTest.php index f4db6ce..8fa9308 100644 --- a/tests/wip/schema/types/boolTest.php +++ b/tests/wip/schema/types/boolTest.php @@ -59,7 +59,7 @@ class boolTest extends TestCase { function testBool() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "bool", $wrapper); + Schema::nw($value, null, "bool", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -75,7 +75,7 @@ class boolTest extends TestCase { function testNbool() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "?bool", $wrapper); + Schema::nw($value, null, "?bool", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); diff --git a/tests/wip/schema/types/floatTest.php b/tests/wip/schema/types/floatTest.php index a4679a4..f6340a2 100644 --- a/tests/wip/schema/types/floatTest.php +++ b/tests/wip/schema/types/floatTest.php @@ -33,7 +33,7 @@ class floatTest extends TestCase { function testFloat() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "float", $wrapper); + Schema::nw($value, null, "float", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -53,10 +53,10 @@ class floatTest extends TestCase { function testRequiredFloat() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, [ + Schema::nw($value, null, [ "float", null, "required" => true, - ], $wrapper); + ], $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -75,7 +75,7 @@ class floatTest extends TestCase { function testNfloat() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "?float", $wrapper); + Schema::nw($value, null, "?float", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -106,10 +106,10 @@ class floatTest extends TestCase { function testRequiredNfloat() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, [ + Schema::nw($value, null, [ "?float", null, "required" => true, - ], $wrapper); + ], $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); diff --git a/tests/wip/schema/types/intTest.php b/tests/wip/schema/types/intTest.php index c9cccbf..51cd7f9 100644 --- a/tests/wip/schema/types/intTest.php +++ b/tests/wip/schema/types/intTest.php @@ -33,7 +33,7 @@ class intTest extends TestCase { function testInt() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "int", $wrapper); + Schema::nw($value, null, "int", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -53,10 +53,10 @@ class intTest extends TestCase { function testRequiredInt() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, [ + Schema::nw($value, null, [ "int", null, "required" => true, - ], $wrapper); + ], $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -75,7 +75,7 @@ class intTest extends TestCase { function testNint() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "?int", $wrapper); + Schema::nw($value, null, "?int", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -106,10 +106,10 @@ class intTest extends TestCase { function testRequiredNint() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, [ + Schema::nw($value, null, [ "?int", null, "required" => true, - ], $wrapper); + ], $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); diff --git a/tests/wip/schema/types/strTest.php b/tests/wip/schema/types/strTest.php index 184d99c..fd8f142 100644 --- a/tests/wip/schema/types/strTest.php +++ b/tests/wip/schema/types/strTest.php @@ -41,7 +41,7 @@ class strTest extends TestCase { function testStr() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "string", $wrapper); + Schema::nw($value, null, "string", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -59,10 +59,10 @@ class strTest extends TestCase { function testRequiredStr() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, [ + Schema::nw($value, null, [ "string", null, "required" => true, - ], $wrapper); + ], $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -79,7 +79,7 @@ class strTest extends TestCase { function testNstr() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, "?string", $wrapper); + Schema::nw($value, null, "?string", $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); @@ -100,10 +100,10 @@ class strTest extends TestCase { function testRequiredNstr() { /** @var ScalarWrapper $wrapper */ - Schema::nw($value, null, $schema, [ + Schema::nw($value, null, [ "?string", null, "required" => true, - ], $wrapper); + ], $schema, $wrapper); $wrapperSetter = function($value) use($wrapper) { return function() use($wrapper, $value) { $wrapper->set($value); diff --git a/tests/wip/schema/types/unionTest.php b/tests/wip/schema/types/unionTest.php index 312d3d4..7557420 100644 --- a/tests/wip/schema/types/unionTest.php +++ b/tests/wip/schema/types/unionTest.php @@ -11,7 +11,7 @@ class unionTest extends TestCase { # string puis int /** @var ScalarWrapper $siw */ - Schema::nw($si, null, $sis, "string|int", $siw); + Schema::nw($si, null, "string|int", $sis, $siw); $siw->set("12"); self::assertSame("12", $si); @@ -20,7 +20,7 @@ class unionTest extends TestCase { # int puis string /** @var ScalarWrapper $isw */ - Schema::nw($is, null, $iss, "int|string", $isw); + Schema::nw($is, null, "int|string", $iss, $isw); $isw->set("12"); self::assertSame("12", $is); From 2a92a9a07e725ba3383b930e82c8b1f84b7683d4 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 28 Mar 2025 16:17:12 +0400 Subject: [PATCH 04/19] modifs.mineures sans commentaires --- src/schema/TODO.md | 2 ++ src/schema/_assoc/AssocSchema.php | 8 ++++++++ src/schema/_assoc/AssocWrapper.php | 10 +++++----- src/schema/_scalar/ScalarSchema.php | 8 ++++++++ tests/wip/schema/_assoc/AssocSchemaTest.php | 7 ++++--- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 65c4212..8cdcee8 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -20,6 +20,8 @@ * cela pourrait servir pour générer automatiquement des tables SQL * ou pour modéliser un schéma FSV +* support allowed_values + * valeurs composite/computed * analyse / vérification de la valeur complète après calcul du résultat, si tous les résultats sont bons diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index 4b6b753..6c0156b 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -82,7 +82,15 @@ class AssocSchema extends Schema { # cf le code similaire dans AssocWrapper::__construct() $dontAnalyze = $value === null && $wrapper === null; if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper(); + + # le schéma peut contenir des paramètres par défaut + $nature = $this->definition[""]; + foreach (array_keys(ref_schema::ASSOC_PARAMS_SCHEMA) as $key) { + $value = $nature[$key] ?? null; + if ($value !== null) $params[$key] = $value; + } if ($params !== null) $wrapper->resetParams($params); + return $wrapper->reset($value, $valueKey, $dontAnalyze? ["analyze" => false]: null); } } diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 71210d1..1c8f179 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -89,13 +89,13 @@ class AssocWrapper extends Wrapper { * @param AssocWrapper $wrapper */ static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int { - if ($context->ensureArray) { + if ($params["ensure_array"] ?? $context->ensureArray) { $valueKey = $context->valueKey; $array = $context->input->get($valueKey); if ($array === null) $context->input->set([], $valueKey); } - if ($context->ensureAssoc) { + if ($params["ensure_assoc"] ?? $context->ensureAssoc) { $context->input->ensureAssoc($context->schema->getKeys()); } @@ -113,7 +113,7 @@ class AssocWrapper extends Wrapper { } } - #XXX supprimer les clés "missing" ou "unavailable" + #XXX supprimer les clés "missing" ou "unavailable" sauf si $ensureKeys return $what; } @@ -122,8 +122,8 @@ class AssocWrapper extends Wrapper { * @param AssocWrapper $wrapper */ static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { - $ensureKeys = $context->ensureKeys; - $ensureOrder = $context->ensureOrder; + $ensureKeys = $params["ensure_keys"] ?? $context->ensureKeys; + $ensureOrder = $params["ensure_order"] ?? $context->ensureOrder; if ($ensureKeys || $ensureOrder) { $schema = $context->schema; $keys = $schema->getKeys(); diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index a9c2ad5..1a5dd8e 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -84,7 +84,15 @@ class ScalarSchema extends Schema { # cf le code similaire dans ScalarWrapper::__construct() $dontAnalyze = $value === null && $wrapper === null; if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); + + # le schéma peut contenir des paramètres par défaut + $nature = $this->definition[""]; + foreach (array_keys(ref_schema::SCALAR_PARAMS_SCHEMA) as $key) { + $value = $nature[$key] ?? null; + if ($value !== null) $params[$key] = $value; + } if ($params !== null) $wrapper->resetParams($params); + return $wrapper->reset($value, $valueKey, $dontAnalyze? ["analyze" => false]: null); } } diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index cdd1567..cf5e9d4 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -13,9 +13,10 @@ class AssocSchemaTest extends TestCase { "assoc", "compute_func" => null, "validate_func" => null, - "ensure_array" => false, - "ensure_keys" => true, - "ensure_order" => true, + "ensure_array" => null, + "ensure_assoc" => null, + "ensure_keys" => null, + "ensure_order" => null, ], "schema" => null, "type" => [null], From c4e02d5bcfd8fccd813c40d5629284d4a61713e6 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 2 Apr 2025 18:06:51 +0400 Subject: [PATCH 05/19] afficher la version de l'application --- nur_src/v/nb.php | 1 + nur_src/v/vp/NavigablePage.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/nur_src/v/nb.php b/nur_src/v/nb.php index d0d714a..76c2520 100644 --- a/nur_src/v/nb.php +++ b/nur_src/v/nb.php @@ -32,6 +32,7 @@ class nb { } static final function menu($text, ?array $links=null, ?array $options=null): array { + $links = array_filter($links, function($link) { return $link !== null; }); $item = ["item" => "menu", "links" => $links, "value" => $text]; if ($options !== null) $item = array_merge($item, $options); return $item; diff --git a/nur_src/v/vp/NavigablePage.php b/nur_src/v/vp/NavigablePage.php index 64fc944..23212c3 100644 --- a/nur_src/v/vp/NavigablePage.php +++ b/nur_src/v/vp/NavigablePage.php @@ -1,6 +1,7 @@ getProjdir(); + $versionfile = "$projdir/VERSION.txt"; + if (file_exists($versionfile)) { + $name = $app->getName(); + $version = file_get_contents($versionfile); + return nb::text([ + "style" => "margin: 0 15px", + "$name v$version" + ]); + } + return null; + } + protected function getAuthzNbtext(IAuthzUser $user): array { $username = $user->getUsername(); $role = $user->getRole(); @@ -95,6 +111,7 @@ class NavigablePage extends AInitAuthzPage implements INavigablePage { $user = authz::get(); navbar::nav(["align" => "right"], [ nb::menu(icon::user($user->getShortName()), [ + $this->getAppVersionNbtext(), $this->getAuthzNbtext($user), $this->getLogoutNblink(), ]), From d844bd03ad4ee97f26a277748a34f137a1b3efbe Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 2 Apr 2025 22:21:16 +0400 Subject: [PATCH 06/19] modifs.mineures sans commentaires --- src/schema/TODO.md | 10 +- src/schema/Wrapper.php | 2 + src/schema/WrapperContext.php | 10 +- src/schema/_assoc/AssocSchema.php | 8 +- src/schema/_assoc/AssocWrapper.php | 4 +- src/schema/_assoc/AssocWrapperContext.php | 15 +- src/schema/_list/ListResult.php | 2 - src/schema/_scalar/ScalarResult.php | 2 - src/schema/_scalar/ScalarSchema.php | 8 +- tests/wip/schema/_assoc/AssocSchemaTest.php | 16 +- .../wip/schema/_scalar/ScalarWrapperTest.php | 222 +++++++++--------- 11 files changed, 141 insertions(+), 158 deletions(-) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 8cdcee8..bdc7e45 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,9 +1,5 @@ # nulib\schema -* ensureKeys() et orderKeys() se fait au niveau de access (ou input?) - * access/input ne pouvant pas connaître les valeurs appropriées, c'est le - schéma qui les génère. ensureKeys($values) - * méthode ensureAssoc() transforme les clés séquentielles en clés associatives * l'ordre est `ensureAssoc [--> ensureKeys] [--> orderKeys]` * si false, supprimer la clé du tableau sauf si ensureKeys @@ -12,9 +8,6 @@ * null pour un résultat aggrégé * "" pour le résultat du tableau * $key pour le résultat de la clé correspondante -* si possible, ne pas utiliser les méthodes isScalar(), isAssoc(), etc. - --> vérifier s'il suffit d'utiliser instanceof ScalarXxx, AssocXxx, etc. pour - les actions courantes * rajouter l'attribut "size" pour spécifier la taille maximale des valeurs * cela pourrait servir pour générer automatiquement des tables SQL @@ -30,7 +23,8 @@ * fonction getter_func, setter_func, deleter_func pour les propriétés de type computed * tdate et tdatetime. qu'en est-il des autres classes (delay, etc.) - * possibilité de spécifier le format de la date à analyser + * parse_format pour spécifier le format d'analyse au lieu de l'auto-détecter + * ScalarSchema::from_property() * l'argument $format de AssocWrapper::format() est un tableau associatif diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 3dfc06b..7ab80dd 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -23,10 +23,12 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $context = $this->context; $type = $context->schema->type; if (is_array($type)) $type = $type[0]; + if (is_string($type)) $type = types::get($context->schema->nullable, $type); $context->type = $type; $context->result->reset(); $context->analyzed = false; $context->normalized = false; + if ($resetSelectedKey) $context->selectedKey = null; } protected function afterModify(?array $params, $resetSelectedKey=false): void { diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index d22a81f..8199b52 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -1,13 +1,11 @@ resetParams($params); @@ -23,9 +21,9 @@ class WrapperContext { function resetParams(?array $params): void { $this->params = $params; - $this->analyze = $params["analyze"] ?? self::DEFAULT_ANALYZE; - $this->normalize = $params["normalize"] ?? self::DEFAULT_NORMALIZE; - $this->throw = $params["throw"] ?? self::DEFAULT_THROW; + $this->analyze = $params["analyze"] ?? ref_schema::PARAMS_SCHEMA["analyze"][1]; + $this->normalize = $params["normalize"] ?? ref_schema::PARAMS_SCHEMA["normalize"][1]; + $this->throw = $params["throw"] ?? ref_schema::PARAMS_SCHEMA["throw"][1]; } /** schéma de la valeur */ diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index 6c0156b..2183922 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -83,11 +83,11 @@ class AssocSchema extends Schema { $dontAnalyze = $value === null && $wrapper === null; if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper(); - # le schéma peut contenir des paramètres par défaut + # la nature du schéma peut contenir des paramètres par défaut $nature = $this->definition[""]; - foreach (array_keys(ref_schema::ASSOC_PARAMS_SCHEMA) as $key) { - $value = $nature[$key] ?? null; - if ($value !== null) $params[$key] = $value; + foreach (array_keys(ref_schema::ASSOC_PARAMS_SCHEMA) as $paramKey) { + $paramValue = $nature[$paramKey] ?? null; + if ($paramValue !== null) $params[$paramKey] = $paramValue; } if ($params !== null) $wrapper->resetParams($params); diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 1c8f179..9e10bd7 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -41,14 +41,12 @@ class AssocWrapper extends Wrapper { protected WrapperContext $context; protected function resetContext($resetSelectedKey): void { + parent::resetContext($resetSelectedKey); $context = $this->context; $context->arrayWrapper->getResult()->reset(); foreach ($context->keyWrappers as $wrapper) { $wrapper->getResult()->reset(); } - $context->analyzed = false; - $context->normalized = false; - if ($resetSelectedKey) $context->selectedKey = null; } function reset(&$value, $valueKey=null, ?array $params=null): Wrapper { diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index 8512635..7536c5d 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -1,17 +1,12 @@ ensureArray = $params["ensure_array"] ?? self::DEFAULT_ENSURE_ARRAY; - $this->ensureAssoc = $params["ensure_assoc"] ?? self::DEFAULT_ENSURE_ASSOC; - $this->ensureKeys = $params["ensure_keys"] ?? self::DEFAULT_ENSURE_KEYS; - $this->ensureOrder = $params["ensure_order"] ?? self::DEFAULT_ENSURE_ORDER; + $this->ensureArray = $params["ensure_array"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_array"][1]; + $this->ensureAssoc = $params["ensure_assoc"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_assoc"][1]; + $this->ensureKeys = $params["ensure_keys"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_keys"][1]; + $this->ensureOrder = $params["ensure_order"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_order"][1]; } public ?ScalarWrapper $arrayWrapper = null; diff --git a/src/schema/_list/ListResult.php b/src/schema/_list/ListResult.php index b40aadb..d05e464 100644 --- a/src/schema/_list/ListResult.php +++ b/src/schema/_list/ListResult.php @@ -12,8 +12,6 @@ class ListResult extends Result { parent::__construct(); } - function isList(?ListResult &$result=null): bool { $result = $this; return true;} - protected Result $arrayResult; /** @var Result[] */ diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index 59453eb..82714cd 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -14,8 +14,6 @@ use Throwable; * Class ScalarResult: résultat de l'analyse ou de la normalisation d'une valeur */ class ScalarResult extends Result { - function isScalar(?ScalarResult &$result=null): bool { $result = $this; return true; } - function getKeys(): array { return ScalarSchema::KEYS; } diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 1a5dd8e..ec261bc 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -85,11 +85,11 @@ class ScalarSchema extends Schema { $dontAnalyze = $value === null && $wrapper === null; if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); - # le schéma peut contenir des paramètres par défaut + # la nature du schéma peut contenir des paramètres par défaut $nature = $this->definition[""]; - foreach (array_keys(ref_schema::SCALAR_PARAMS_SCHEMA) as $key) { - $value = $nature[$key] ?? null; - if ($value !== null) $params[$key] = $value; + foreach (array_keys(ref_schema::SCALAR_PARAMS_SCHEMA) as $paramKey) { + $paramValue = $nature[$paramKey] ?? null; + if ($paramValue !== null) $params[$paramKey] = $paramValue; } if ($params !== null) $wrapper->resetParams($params); diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index cf5e9d4..d8552a7 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -203,7 +203,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::STRINGS, $array); + self::assertSame(["s" => "string", "f" => false, "m" => ""], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -219,7 +219,7 @@ class AssocSchemaTest extends TestCase { $array = self::NSTRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::NSTRINGS, $array); + self::assertSame(["s" => null, "f" => null, "m" => ""], $array); $result = $wrapper->getResult("s"); self::assertFalse($result->valid); self::assertSame("null", $result->messageKey); @@ -241,7 +241,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::STRINGS, $array); + self::assertSame(["s" => "string", "f" => false, "m" => null], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -257,7 +257,7 @@ class AssocSchemaTest extends TestCase { $array = self::NSTRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::NSTRINGS, $array); + self::assertSame(["s" => null, "f" => null, "m" => null], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -277,7 +277,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::STRINGS, $array); + self::assertSame(["s" => "string", "f" => false, "m" => ""], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -295,7 +295,7 @@ class AssocSchemaTest extends TestCase { $array = self::NSTRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::NSTRINGS, $array); + self::assertSame(["s" => null, "f" => null, "m" => ""], $array); $result = $wrapper->getResult("s"); self::assertFalse($result->valid); self::assertSame("null", $result->messageKey); @@ -318,7 +318,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::STRINGS, $array); + self::assertSame(["s" => "string", "f" => false, "m" => null], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -336,7 +336,7 @@ class AssocSchemaTest extends TestCase { $array = self::NSTRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(self::NSTRINGS, $array); + self::assertSame(["s" => null, "f" => null, "m" => null], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); diff --git a/tests/wip/schema/_scalar/ScalarWrapperTest.php b/tests/wip/schema/_scalar/ScalarWrapperTest.php index a78e548..cc03952 100644 --- a/tests/wip/schema/_scalar/ScalarWrapperTest.php +++ b/tests/wip/schema/_scalar/ScalarWrapperTest.php @@ -15,7 +15,7 @@ class ScalarWrapperTest extends TestCase { self::assertSame($normalized, $wrapper->isNormalized(), "normalized"); } - function checkVerifix(ScalarSchema $schema, $orig, bool $normalize, $value, bool $present, bool $available, bool $valid, bool $normalized, ?array $inputParams=null): void { + function checkNormalize(ScalarSchema $schema, $orig, bool $normalize, $value, bool $present, bool $available, bool $valid, bool $normalized, ?array $inputParams=null): void { $wrapper = $schema->getWrapper(); $wrapper->resetParams(["normalize" => $normalize]); if ($inputParams !== null) $input = new Input($orig, $inputParams); @@ -36,261 +36,261 @@ class ScalarWrapperTest extends TestCase { function testRaw() { $schema = new ScalarSchema(); - $this->checkVerifix($schema, false, false, false, true, true, true, true); - $this->checkVerifix($schema, false, true, false, true, true, true, true); + $this->checkNormalize($schema, false, false, false, true, true, true, true); + $this->checkNormalize($schema, false, true, false, true, true, true, true); - $this->checkVerifix($schema, null, false, null, true, true, true, true); - $this->checkVerifix($schema, null, true, null, true, true, true, true); + $this->checkNormalize($schema, null, false, null, true, true, true, true); + $this->checkNormalize($schema, null, true, null, true, true, true, true); $obj = new stdClass(); - $this->checkVerifix($schema, $obj, false, $obj, true, true, true, true); - $this->checkVerifix($schema, $obj, true, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true); $schema = new ScalarSchema("raw"); - $this->checkVerifix($schema, false, false, false, true, true, true, true); - $this->checkVerifix($schema, false, true, false, true, true, true, true); + $this->checkNormalize($schema, false, false, false, true, true, true, true); + $this->checkNormalize($schema, false, true, false, true, true, true, true); - $this->checkVerifix($schema, null, false, null, true, true, true, true); - $this->checkVerifix($schema, null, true, null, true, true, true, true); + $this->checkNormalize($schema, null, false, null, true, true, true, true); + $this->checkNormalize($schema, null, true, null, true, true, true, true); $obj = new stdClass(); - $this->checkVerifix($schema, $obj, false, $obj, true, true, true, true); - $this->checkVerifix($schema, $obj, true, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true); } function testMixed() { $schema = new ScalarSchema("mixed"); - $this->checkVerifix($schema, false, false, false, true, true, true, true); - $this->checkVerifix($schema, false, true, false, true, true, true, true); + $this->checkNormalize($schema, false, false, false, true, true, true, true); + $this->checkNormalize($schema, false, true, false, true, true, true, true); - $this->checkVerifix($schema, null, false, null, true, true, false, false); + $this->checkNormalize($schema, null, false, null, true, true, false, false); $this->checkException($schema, null, true, ValueException::class); $obj = new stdClass(); - $this->checkVerifix($schema, $obj, false, $obj, true, true, true, true); - $this->checkVerifix($schema, $obj, true, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true); $schema = new ScalarSchema("?mixed"); - $this->checkVerifix($schema, false, false, false, true, true, true, true); - $this->checkVerifix($schema, false, true, false, true, true, true, true); + $this->checkNormalize($schema, false, false, false, true, true, true, true); + $this->checkNormalize($schema, false, true, false, true, true, true, true); - $this->checkVerifix($schema, null, false, null, true, true, true, true); - $this->checkVerifix($schema, null, true, null, true, true, true, true); + $this->checkNormalize($schema, null, false, null, true, true, true, true); + $this->checkNormalize($schema, null, true, null, true, true, true, true); $obj = new stdClass(); - $this->checkVerifix($schema, $obj, false, $obj, true, true, true, true); - $this->checkVerifix($schema, $obj, true, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true); + $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true); } function testRawstring() { $schema = new ScalarSchema("rawstring"); - $this->checkVerifix($schema, false, false, null, true, false, true, true); - $this->checkVerifix($schema, false, true, null, true, false, true, true); + $this->checkNormalize($schema, false, false, null, true, false, true, true); + $this->checkNormalize($schema, false, true, null, true, false, true, true); - $this->checkVerifix($schema, null, false, null, true, true, false, false); + $this->checkNormalize($schema, null, false, null, true, true, false, false); $this->checkException($schema, null, true, ValueException::class); - $this->checkVerifix($schema, "", false, "", true, true, true, true); - $this->checkVerifix($schema, "", true, "", true, true, true, true); + $this->checkNormalize($schema, "", false, "", true, true, true, true); + $this->checkNormalize($schema, "", true, "", true, true, true, true); - $this->checkVerifix($schema, " ", false, " ", true, true, true, true); - $this->checkVerifix($schema, " ", true, " ", true, true, true, true); + $this->checkNormalize($schema, " ", false, " ", true, true, true, true); + $this->checkNormalize($schema, " ", true, " ", true, true, true, true); - $this->checkVerifix($schema, "text", false, "text", true, true, true, true); - $this->checkVerifix($schema, "text", true, "text", true, true, true, true); + $this->checkNormalize($schema, "text", false, "text", true, true, true, true); + $this->checkNormalize($schema, "text", true, "text", true, true, true, true); - $this->checkVerifix($schema, " text ", false, " text ", true, true, true, true); - $this->checkVerifix($schema, " text ", true, " text ", true, true, true, true); + $this->checkNormalize($schema, " text ", false, " text ", true, true, true, true); + $this->checkNormalize($schema, " text ", true, " text ", true, true, true, true); - $this->checkVerifix($schema, true, false, true, true, true, true, false); - $this->checkVerifix($schema, true, true, "1", true, true, true, false); + $this->checkNormalize($schema, true, false, true, true, true, true, false); + $this->checkNormalize($schema, true, true, "1", true, true, true, false); - $this->checkVerifix($schema, 42, false, 42, true, true, true, false); - $this->checkVerifix($schema, 42, true, "42", true, true, true, false); + $this->checkNormalize($schema, 42, false, 42, true, true, true, false); + $this->checkNormalize($schema, 42, true, "42", true, true, true, false); - $this->checkVerifix($schema, [], false, [], true, true, false, false); + $this->checkNormalize($schema, [], false, [], true, true, false, false); $this->checkException($schema, [], true, ValueException::class); ## Tester valeur par défaut $schema = new ScalarSchema(["rawstring", null]); - $this->checkVerifix($schema, false, false, null, true, false, true, true); - $this->checkVerifix($schema, false, true, null, true, false, true, true); + $this->checkNormalize($schema, false, false, null, true, false, true, true); + $this->checkNormalize($schema, false, true, null, true, false, true, true); - $this->checkVerifix($schema, null, false, null, true, true, false, false); + $this->checkNormalize($schema, null, false, null, true, true, false, false); $this->checkException($schema, null, true, ValueException::class); $schema = new ScalarSchema(["rawstring", "default"]); - $this->checkVerifix($schema, false, false, "default", true, true, true, true); - $this->checkVerifix($schema, false, true, "default", true, true, true, true); + $this->checkNormalize($schema, false, false, "default", true, true, true, true); + $this->checkNormalize($schema, false, true, "default", true, true, true, true); - $this->checkVerifix($schema, null, false, null, true, true, false, false); + $this->checkNormalize($schema, null, false, null, true, true, false, false); $this->checkException($schema, null, true, ValueException::class); ## Tester nullable $schema = new ScalarSchema("?rawstring"); - $this->checkVerifix($schema, null, false, null, true, true, true, true); - $this->checkVerifix($schema, null, true, null, true, true, true, true); + $this->checkNormalize($schema, null, false, null, true, true, true, true); + $this->checkNormalize($schema, null, true, null, true, true, true, true); ## Tester required $schema = new ScalarSchema(["rawstring", "required" => true]); - $this->checkVerifix($schema, false, false, null, true, false, false, false); + $this->checkNormalize($schema, false, false, null, true, false, false, false); $this->checkException($schema, false, true, ValueException::class); ## Tester allow_empty === false $inputParams = ["allow_empty" => false]; $schema = new ScalarSchema("rawstring"); - $this->checkVerifix($schema, null, false, null, true, true, false, false, $inputParams); + $this->checkNormalize($schema, null, false, null, true, true, false, false, $inputParams); $this->checkException($schema, null, true, ValueException::class, $inputParams); - $this->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams); - $this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams); $schema = new ScalarSchema("?rawstring"); - $this->checkVerifix($schema, null, false, null, true, true, true, true, $inputParams); - $this->checkVerifix($schema, null, true, null, true, true, true, true, $inputParams); + $this->checkNormalize($schema, null, false, null, true, true, true, true, $inputParams); + $this->checkNormalize($schema, null, true, null, true, true, true, true, $inputParams); - $this->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams); - $this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams); } function testString() { $schema = new ScalarSchema("string"); - $this->checkVerifix($schema, false, false, null, true, false, true, true); - $this->checkVerifix($schema, false, true, null, true, false, true, true); + $this->checkNormalize($schema, false, false, null, true, false, true, true); + $this->checkNormalize($schema, false, true, null, true, false, true, true); - $this->checkVerifix($schema, null, false, null, true, true, false, false); + $this->checkNormalize($schema, null, false, null, true, true, false, false); $this->checkException($schema, null, true, ValueException::class); - $this->checkVerifix($schema, "", false, "", true, true, true, true); - $this->checkVerifix($schema, "", true, "", true, true, true, true); + $this->checkNormalize($schema, "", false, "", true, true, true, true); + $this->checkNormalize($schema, "", true, "", true, true, true, true); - $this->checkVerifix($schema, " ", false, "", true, true, true, false); - $this->checkVerifix($schema, " ", true, "", true, true, true, false); + $this->checkNormalize($schema, " ", false, "", true, true, true, false); + $this->checkNormalize($schema, " ", true, "", true, true, true, false); - $this->checkVerifix($schema, "text", false, "text", true, true, true, true); - $this->checkVerifix($schema, "text", true, "text", true, true, true, true); + $this->checkNormalize($schema, "text", false, "text", true, true, true, true); + $this->checkNormalize($schema, "text", true, "text", true, true, true, true); - $this->checkVerifix($schema, " text ", false, "text", true, true, true, false); - $this->checkVerifix($schema, " text ", true, "text", true, true, true, false); + $this->checkNormalize($schema, " text ", false, "text", true, true, true, false); + $this->checkNormalize($schema, " text ", true, "text", true, true, true, false); - $this->checkVerifix($schema, true, false, true, true, true, true, false); - $this->checkVerifix($schema, true, true, "1", true, true, true, false); + $this->checkNormalize($schema, true, false, true, true, true, true, false); + $this->checkNormalize($schema, true, true, "1", true, true, true, false); - $this->checkVerifix($schema, 42, false, 42, true, true, true, false); - $this->checkVerifix($schema, 42, true, "42", true, true, true, false); + $this->checkNormalize($schema, 42, false, 42, true, true, true, false); + $this->checkNormalize($schema, 42, true, "42", true, true, true, false); - $this->checkVerifix($schema, [], false, [], true, true, false, false); + $this->checkNormalize($schema, [], false, [], true, true, false, false); $this->checkException($schema, [], true, ValueException::class); ## Tester nullable $schema = new ScalarSchema("?string"); - $this->checkVerifix($schema, null, false, null, true, true, true, true); - $this->checkVerifix($schema, null, true, null, true, true, true, true); + $this->checkNormalize($schema, null, false, null, true, true, true, true); + $this->checkNormalize($schema, null, true, null, true, true, true, true); ## Tester required $schema = new ScalarSchema(["string", "required" => true]); - $this->checkVerifix($schema, false, false, null, true, false, false, false); + $this->checkNormalize($schema, false, false, null, true, false, false, false); $this->checkException($schema, false, true, ValueException::class); ## Tester allow_empty === false $inputParams = ["allow_empty" => false]; $schema = new ScalarSchema("string"); - $this->checkVerifix($schema, null, false, null, true, true, false, false, $inputParams); + $this->checkNormalize($schema, null, false, null, true, true, false, false, $inputParams); $this->checkException($schema, null, true, ValueException::class, $inputParams); - $this->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams); - $this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams); $schema = new ScalarSchema("?string"); - $this->checkVerifix($schema, null, false, null, true, true, true, true, $inputParams); - $this->checkVerifix($schema, null, true, null, true, true, true, true, $inputParams); + $this->checkNormalize($schema, null, false, null, true, true, true, true, $inputParams); + $this->checkNormalize($schema, null, true, null, true, true, true, true, $inputParams); - $this->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams); - $this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams); } function testInt() { $schema = new ScalarSchema("int"); - $this->checkVerifix($schema, false, false, null, true, false, true, true); - $this->checkVerifix($schema, false, true, null, true, false, true, true); + $this->checkNormalize($schema, false, false, null, true, false, true, true); + $this->checkNormalize($schema, false, true, null, true, false, true, true); - $this->checkVerifix($schema, null, false, null, true, true, false, false); + $this->checkNormalize($schema, null, false, null, true, true, false, false); $this->checkException($schema, null, true, ValueException::class); - $this->checkVerifix($schema, 42, false, 42, true, true, true, true); - $this->checkVerifix($schema, 42, true, 42, true, true, true, true); + $this->checkNormalize($schema, 42, false, 42, true, true, true, true); + $this->checkNormalize($schema, 42, true, 42, true, true, true, true); - $this->checkVerifix($schema, "42", false, "42", true, true, true, false); - $this->checkVerifix($schema, "42", true, 42, true, true, true, false); + $this->checkNormalize($schema, "42", false, "42", true, true, true, false); + $this->checkNormalize($schema, "42", true, 42, true, true, true, false); - $this->checkVerifix($schema, "42.5", false, "42.5", true, true, true, false); - $this->checkVerifix($schema, "42.5", true, 42, true, true, true, false); + $this->checkNormalize($schema, "42.5", false, "42.5", true, true, true, false); + $this->checkNormalize($schema, "42.5", true, 42, true, true, true, false); - $this->checkVerifix($schema, "42,5", false, "42,5", true, true, true, false); - $this->checkVerifix($schema, "42,5", true, 42, true, true, true, false); + $this->checkNormalize($schema, "42,5", false, "42,5", true, true, true, false); + $this->checkNormalize($schema, "42,5", true, 42, true, true, true, false); - $this->checkVerifix($schema, " 42 ", false, "42", true, true, true, false); - $this->checkVerifix($schema, " 42 ", true, 42, true, true, true, false); + $this->checkNormalize($schema, " 42 ", false, "42", true, true, true, false); + $this->checkNormalize($schema, " 42 ", true, 42, true, true, true, false); - $this->checkVerifix($schema, "", false, "", true, true, false, false); + $this->checkNormalize($schema, "", false, "", true, true, false, false); $this->checkException($schema, "", true, ValueException::class); - $this->checkVerifix($schema, " ", false, " ", true, true, false, false); + $this->checkNormalize($schema, " ", false, " ", true, true, false, false); $this->checkException($schema, " ", true, ValueException::class); - $this->checkVerifix($schema, "text", false, "text", true, true, false, false); + $this->checkNormalize($schema, "text", false, "text", true, true, false, false); $this->checkException($schema, "text", true, ValueException::class); - $this->checkVerifix($schema, true, false, true, true, true, true, false); - $this->checkVerifix($schema, true, true, 1, true, true, true, false); + $this->checkNormalize($schema, true, false, true, true, true, true, false); + $this->checkNormalize($schema, true, true, 1, true, true, true, false); - $this->checkVerifix($schema, [], false, [], true, true, false, false); + $this->checkNormalize($schema, [], false, [], true, true, false, false); $this->checkException($schema, [], true, ValueException::class); ## Tester nullable $schema = new ScalarSchema("?int"); - $this->checkVerifix($schema, null, false, null, true, true, true, true); - $this->checkVerifix($schema, null, true, null, true, true, true, true); + $this->checkNormalize($schema, null, false, null, true, true, true, true); + $this->checkNormalize($schema, null, true, null, true, true, true, true); ## Tester required $schema = new ScalarSchema(["int", "required" => true]); - $this->checkVerifix($schema, false, false, null, true, false, false, false); + $this->checkNormalize($schema, false, false, null, true, false, false, false); $this->checkException($schema, false, true, ValueException::class); ## Tester allow_empty === false $inputParams = ["allow_empty" => false]; $schema = new ScalarSchema("int"); - $this->checkVerifix($schema, null, false, null, true, true, false, false, $inputParams); + $this->checkNormalize($schema, null, false, null, true, true, false, false, $inputParams); $this->checkException($schema, null, true, ValueException::class, $inputParams); - $this->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams); - $this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams); $schema = new ScalarSchema("?int"); - $this->checkVerifix($schema, null, false, null, true, true, true, true, $inputParams); - $this->checkVerifix($schema, null, true, null, true, true, true, true, $inputParams); + $this->checkNormalize($schema, null, false, null, true, true, true, true, $inputParams); + $this->checkNormalize($schema, null, true, null, true, true, true, true, $inputParams); - $this->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams); - $this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams); + $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams); } } From f005692cd8ce34099600d820461858c0dada2457 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 4 Apr 2025 06:35:07 +0400 Subject: [PATCH 07/19] =?UTF-8?q?d=C3=A9placer=20nur/sery/wip=20et=20nur/s?= =?UTF-8?q?ery=20dans=20nulib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/nur-ture.iml | 6 ++-- composer.json | 6 ++-- composer.lock | 2 +- nur_bin/steam-train.php | 2 +- nur_src/cli/Application.php | 2 +- nur_src/ref/ref_type.php | 2 +- nur_tbin/base/test-args4.php | 2 +- {src_app => src}/app.php | 4 +-- {src_app => src}/app/cli/Application.php | 4 +-- {src_app => src}/app/cli/TODO.md | 0 src/php/access/AbstractAccess.php | 2 +- src/php/access/ArrayAccess.php | 2 +- src/php/access/ChainAccess.php | 2 +- src/php/access/FormAccess.php | 2 +- src/php/access/GetAccess.php | 2 +- src/php/access/IAccess.php | 2 +- src/php/access/IDeleter.php | 2 +- src/php/access/IGetter.php | 2 +- src/php/access/ISetter.php | 2 +- src/php/access/KeyAccess.php | 2 +- src/php/access/PostAccess.php | 2 +- src/php/access/PropertyAccess.php | 2 +- src/php/access/ShadowAccess.php | 2 +- src/php/access/ValueAccess.php | 2 +- src/php/coll/Cursor.php | 4 +-- src/php/iter.php | 2 +- src/schema/OldSchema.php | 2 +- src/schema/Result.php | 2 +- src/schema/Schema.php | 22 ++++++------- src/schema/SchemaException.php | 2 +- src/schema/Wrapper.php | 14 ++++---- src/schema/WrapperContext.php | 6 ++-- src/schema/_assoc/AssocSchema.php | 6 ++-- src/schema/_assoc/AssocWrapper.php | 16 +++++----- src/schema/_assoc/AssocWrapperContext.php | 8 ++--- src/schema/_list/ListResult.php | 4 +-- src/schema/_list/ListSchema.php | 6 ++-- src/schema/_list/ListWrapper.php | 6 ++-- src/schema/_scalar/ScalarResult.php | 8 ++--- src/schema/_scalar/ScalarSchema.php | 6 ++-- src/schema/_scalar/ScalarWrapper.php | 12 +++---- src/schema/input/FormInput.php | 8 ++--- src/schema/input/GetInput.php | 6 ++-- src/schema/input/Input.php | 8 ++--- src/schema/input/PostInput.php | 6 ++-- src/schema/types.php | 32 +++++++++---------- src/schema/types/IType.php | 8 ++--- src/schema/types/Registry.php | 2 +- src/schema/types/_tformatable.php | 2 +- src/schema/types/_tsimple.php | 4 +-- src/schema/types/_tstring.php | 2 +- src/schema/types/_tunion.php | 2 +- src/schema/types/tarray.php | 10 +++--- src/schema/types/tbool.php | 12 +++---- src/schema/types/tcontent.php | 10 +++--- src/schema/types/tfloat.php | 10 +++--- src/schema/types/tfunc.php | 10 +++--- src/schema/types/tgeneric.php | 12 +++---- src/schema/types/tint.php | 10 +++--- src/schema/types/tkey.php | 10 +++--- src/schema/types/tmixed.php | 12 +++---- src/schema/types/tpkey.php | 10 +++--- src/schema/types/traw.php | 4 +-- src/schema/types/trawstring.php | 10 +++--- src/schema/types/tstring.php | 2 +- src/schema/types/ttext.php | 2 +- {src_glue => src}/tools/Csv2xlsxApp.php | 0 {src_glue => src}/tools/DumpserApp.php | 0 src/web/content/Tag.php | 2 +- src/web/content/v.php | 2 +- src_glue/app.php | 5 --- src_glue/app/cli/Application.php | 5 --- tests/{wip => }/php/access/KeyAccessTest.php | 2 +- tests/{wip => }/php/coll/CursorTest.php | 2 +- tests/{wip => }/php/content/cTest.php | 6 ++-- tests/{wip => }/php/content/impl/AContent.php | 2 +- .../{wip => }/php/content/impl/APrintable.php | 2 +- tests/{wip => }/php/content/impl/ATag.php | 2 +- tests/{wip => }/php/content/impl/html.php | 2 +- .../schema/_assoc/AssocSchemaTest.php | 6 ++-- .../schema/_scalar/ScalarSchemaTest.php | 4 +-- .../schema/_scalar/ScalarWrapperTest.php | 4 +-- tests/{wip => }/schema/types/boolTest.php | 6 ++-- tests/{wip => }/schema/types/floatTest.php | 6 ++-- tests/{wip => }/schema/types/intTest.php | 6 ++-- tests/{wip => }/schema/types/strTest.php | 6 ++-- tests/{wip => }/schema/types/unionTest.php | 6 ++-- 87 files changed, 225 insertions(+), 239 deletions(-) rename {src_app => src}/app.php (99%) rename {src_app => src}/app/cli/Application.php (99%) rename {src_app => src}/app/cli/TODO.md (100%) rename {src_glue => src}/tools/Csv2xlsxApp.php (100%) rename {src_glue => src}/tools/DumpserApp.php (100%) delete mode 100644 src_glue/app.php delete mode 100644 src_glue/app/cli/Application.php rename tests/{wip => }/php/access/KeyAccessTest.php (99%) rename tests/{wip => }/php/coll/CursorTest.php (99%) rename tests/{wip => }/php/content/cTest.php (92%) rename tests/{wip => }/php/content/impl/AContent.php (79%) rename tests/{wip => }/php/content/impl/APrintable.php (77%) rename tests/{wip => }/php/content/impl/ATag.php (90%) rename tests/{wip => }/php/content/impl/html.php (91%) rename tests/{wip => }/schema/_assoc/AssocSchemaTest.php (98%) rename tests/{wip => }/schema/_scalar/ScalarSchemaTest.php (96%) rename tests/{wip => }/schema/_scalar/ScalarWrapperTest.php (99%) rename tests/{wip => }/schema/types/boolTest.php (96%) rename tests/{wip => }/schema/types/floatTest.php (97%) rename tests/{wip => }/schema/types/intTest.php (97%) rename tests/{wip => }/schema/types/strTest.php (96%) rename tests/{wip => }/schema/types/unionTest.php (83%) diff --git a/.idea/nur-ture.iml b/.idea/nur-ture.iml index ae13f26..e8b45d5 100644 --- a/.idea/nur-ture.iml +++ b/.idea/nur-ture.iml @@ -4,10 +4,8 @@ - - - - + + diff --git a/composer.json b/composer.json index dcc65a0..796d0c3 100644 --- a/composer.json +++ b/composer.json @@ -64,9 +64,7 @@ }, "autoload": { "psr-4": { - "nulib\\": "src_glue", - "nur\\sery\\wip\\": "src", - "nur\\sery\\": "src_app", + "nulib\\": "src", "nur\\": "nur_src" }, "files": [ @@ -75,7 +73,7 @@ }, "autoload-dev": { "psr-4": { - "nur\\sery\\": "tests", + "nulib\\": "tests", "nur\\": "nur_tests" } }, diff --git a/composer.lock b/composer.lock index aaa6402..27a5e88 100644 --- a/composer.lock +++ b/composer.lock @@ -589,7 +589,7 @@ "dist": { "type": "path", "url": "../nulib", - "reference": "2cdc05981013dc403afe26c08f3cfef36f737642" + "reference": "1536e091fb0020858204f59462a7a80b5f9775d9" }, "require": { "ext-json": "*", diff --git a/nur_bin/steam-train.php b/nur_bin/steam-train.php index dbde68a..7d032dc 100755 --- a/nur_bin/steam-train.php +++ b/nur_bin/steam-train.php @@ -2,6 +2,6 @@ Date: Thu, 10 Apr 2025 00:27:05 +0400 Subject: [PATCH 08/19] modifs.mineures sans commentaires --- tests/appTest.php | 132 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 tests/appTest.php diff --git a/tests/appTest.php b/tests/appTest.php new file mode 100644 index 0000000..8d86b6f --- /dev/null +++ b/tests/appTest.php @@ -0,0 +1,132 @@ + $projdir, + "vendor" => [ + "bindir" => "$projdir/vendor/bin", + "autoload" => "$projdir/vendor/autoload.php", + ], + "appcode" => "nur-sery", + "cwd" => $cwd, + "datadir" => "$projdir/devel", + "etcdir" => "$projdir/devel/etc", + "vardir" => "$projdir/devel/var", + "logdir" => "$projdir/devel/log", + "profile" => "devel", + "appgroup" => null, + "name" => "my-application1", + "title" => null, + ], $app1->getParams()); + + $app2 = myapp::with(MyApplication2::class, $app1); + self::assertSame([ + "projdir" => $projdir, + "vendor" => [ + "bindir" => "$projdir/vendor/bin", + "autoload" => "$projdir/vendor/autoload.php", + ], + "appcode" => "nur-sery", + "cwd" => $cwd, + "datadir" => "$projdir/devel", + "etcdir" => "$projdir/devel/etc", + "vardir" => "$projdir/devel/var", + "logdir" => "$projdir/devel/log", + "profile" => "devel", + "appgroup" => null, + "name" => "my-application2", + "title" => null, + ], $app2->getParams()); + } + + function testInit() { + $projdir = config::get_projdir(); + $cwd = getcwd(); + + myapp::reset(); + myapp::init(MyApplication1::class); + self::assertSame([ + "projdir" => $projdir, + "vendor" => [ + "bindir" => "$projdir/vendor/bin", + "autoload" => "$projdir/vendor/autoload.php", + ], + "appcode" => "nur-sery", + "cwd" => $cwd, + "datadir" => "$projdir/devel", + "etcdir" => "$projdir/devel/etc", + "vardir" => "$projdir/devel/var", + "logdir" => "$projdir/devel/log", + "profile" => "devel", + "appgroup" => null, + "name" => "my-application1", + "title" => null, + ], myapp::get()->getParams()); + + myapp::init(MyApplication2::class); + self::assertSame([ + "projdir" => $projdir, + "vendor" => [ + "bindir" => "$projdir/vendor/bin", + "autoload" => "$projdir/vendor/autoload.php", + ], + "appcode" => "nur-sery", + "cwd" => $cwd, + "datadir" => "$projdir/devel", + "etcdir" => "$projdir/devel/etc", + "vardir" => "$projdir/devel/var", + "logdir" => "$projdir/devel/log", + "profile" => "devel", + "appgroup" => null, + "name" => "my-application2", + "title" => null, + ], myapp::get()->getParams()); + } + } +} + +namespace nulib\impl { + + use nulib\app\cli\Application; + use nulib\os\path; + use nulib\app; + + class config { + const PROJDIR = __DIR__.'/..'; + + static function get_projdir(): string { + return path::abspath(self::PROJDIR); + } + } + + class myapp extends app { + static function reset(): void { + self::$app = null; + } + } + + class MyApplication1 extends Application { + const PROJDIR = config::PROJDIR; + + function main() { + } + } + class MyApplication2 extends Application { + const PROJDIR = null; + + function main() { + } + } +} From a045296629e6079c91590ce530b0478c16b878e9 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 15 Apr 2025 12:28:07 +0400 Subject: [PATCH 09/19] modifs.mineures sans commentaires --- composer.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/composer.lock b/composer.lock index 27a5e88..df6be65 100644 --- a/composer.lock +++ b/composer.lock @@ -589,7 +589,7 @@ "dist": { "type": "path", "url": "../nulib", - "reference": "1536e091fb0020858204f59462a7a80b5f9775d9" + "reference": "2a50167241fe6b6d84d793aad748eb74c631eae9" }, "require": { "ext-json": "*", @@ -599,6 +599,8 @@ "require-dev": { "ext-curl": "*", "ext-pcntl": "*", + "ext-pdo": "*", + "ext-pgsql": "*", "ext-posix": "*", "ext-sqlite3": "*", "nulib/tests": "^7.4" @@ -637,7 +639,7 @@ "dist": { "type": "path", "url": "../nulib-phpss", - "reference": "9e4f41e38deef10993d859202988567db9d4fada" + "reference": "e902acb4461a9358de8cce0a534bfe0e63e8b100" }, "require": { "nulib/php": "^7.4-dev", @@ -681,7 +683,7 @@ "dist": { "type": "path", "url": "../nulib-spout", - "reference": "65c74a1db6dda718aa20970ede3dfa4b4d32c791" + "reference": "8d7512e2bff3dc333bb58130ac5500017db700ca" }, "require": { "ext-dom": "*", From c71cc032fbc8ea2400470b257dd96bd8a145d15e Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 17 Apr 2025 13:38:38 +0400 Subject: [PATCH 10/19] modifs.mineures sans commentaires --- src/php/access/AbstractAccess.php | 5 +- src/php/access/ChainAccess.php | 2 +- src/php/access/IAccess.php | 12 ++- src/php/access/KeyAccess.php | 17 +++- src/php/access/PropertyAccess.php | 2 +- src/php/access/ShadowAccess.php | 4 +- src/schema/Wrapper.php | 5 + src/schema/_assoc/AssocWrapper.php | 47 +++++---- src/schema/_scalar/ScalarResult.php | 69 +++++++++++++ src/schema/_scalar/ScalarWrapper.php | 10 ++ src/schema/input/Input.php | 8 +- src/schema/types/IType.php | 34 +++---- src/schema/types/_tsimple.php | 15 +-- src/schema/types/tbool.php | 27 +++-- src/schema/types/tgeneric.php | 4 - src/schema/types/tmixed.php | 5 + tests/php/access/KeyAccessTest.php | 4 +- tests/schema/_assoc/AssocSchemaTest.php | 129 +++++++++++++----------- 18 files changed, 262 insertions(+), 137 deletions(-) diff --git a/src/php/access/AbstractAccess.php b/src/php/access/AbstractAccess.php index fb51207..d90ad7f 100644 --- a/src/php/access/AbstractAccess.php +++ b/src/php/access/AbstractAccess.php @@ -49,7 +49,10 @@ abstract class AbstractAccess implements IAccess { function ensureAssoc(array $keys, ?array $params=null): void { } - function ensureKeys(array $defaults, ?array $params=null): void { + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { + } + + function deleteMissings(array $missings, ?array $params=null): void { } function ensureOrder(array $keys, ?array $params=null): void { diff --git a/src/php/access/ChainAccess.php b/src/php/access/ChainAccess.php index 3ed339e..6395d99 100644 --- a/src/php/access/ChainAccess.php +++ b/src/php/access/ChainAccess.php @@ -170,7 +170,7 @@ class ChainAccess extends AbstractAccess { #$this->access->ensureAssoc($keys, $params); } - function ensureKeys(array $defaults, ?array $params=null): void { + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { #XXX fonction de $accessType? #$this->access->ensureKeys($defaults, $params); } diff --git a/src/php/access/IAccess.php b/src/php/access/IAccess.php index b81692b..71d8631 100644 --- a/src/php/access/IAccess.php +++ b/src/php/access/IAccess.php @@ -39,10 +39,16 @@ interface IAccess extends IGetter, ISetter, IDeleter { /** * s'assurer que toutes les clés mentionnées dans le tableau $defaults - * existent. si elles n'existent pas, leur donner la valeur du tableau - * $defaults + * existent. si elles n'existent pas, ou si elles ont la valeur correspondante + * du tableau $missings, leur donner la valeur du tableau $defaults */ - function ensureKeys(array $defaults, ?array $params=null): void; + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void; + + /** + * supprimer toutes les clés dont la valeur est celle mentionnée dans le + * tableau $missings + */ + function deleteMissings(array $missings, ?array $params=null): void; /** * s'assure que les clés de la destination sont dans l'ordre mentionné dans le diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index 47a8291..fbc9781 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -142,15 +142,30 @@ class KeyAccess extends AbstractAccess { } } - function ensureKeys(array $defaults, ?array $params=null): void { + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { $dest =& $this->dest; $keys = array_keys($defaults); $prefix = $params["key_prefix"] ?? null; $suffix = $params["key_suffix"] ?? null; foreach ($keys as $key) { $destKey = "$prefix$key$suffix"; + $haveMissing = $missings !== null && array_key_exists($key, $missings); if ($dest === null || !array_key_exists($destKey, $dest)) { $dest[$destKey] = $defaults[$key]; + } elseif ($haveMissing && $dest[$destKey] === $missings[$key]) { + $dest[$destKey] = $defaults[$key]; + } + } + } + + function deleteMissings(array $missings, ?array $params=null): void { + $dest =& $this->dest; + $prefix = $params["key_prefix"] ?? null; + $suffix = $params["key_suffix"] ?? null; + foreach ($missings as $key => $missing) { + $destKey = "$prefix$key$suffix"; + if (array_key_exists($destKey, $dest) && $dest[$destKey] === $missing) { + unset($dest[$destKey]); } } } diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index c91529b..b0bc011 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -144,7 +144,7 @@ class PropertyAccess extends AbstractAccess { return new ChainAccess($this, $key); } - function ensureKeys(array $defaults, ?array $params=null): void { + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { $dest = $this->dest; if ($dest === null) { # comme ne connait pas la classe de l'objet destination, on n'essaie pas diff --git a/src/php/access/ShadowAccess.php b/src/php/access/ShadowAccess.php index 639b311..accb960 100644 --- a/src/php/access/ShadowAccess.php +++ b/src/php/access/ShadowAccess.php @@ -62,8 +62,8 @@ class ShadowAccess extends AbstractAccess { $this->writer->ensureAssoc($keys, $params); } - function ensureKeys(array $defaults, ?array $params=null): void { - $this->writer->ensureKeys($defaults, $params); + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { + $this->writer->ensureKeys($defaults, $missings, $params); } function ensureOrder(array $keys, ?array $params=null): void { diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 425e0f6..12049c0 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -149,6 +149,11 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { return $this->getResult($key)->available; } + /** retourner true si la valeur est nulle */ + function isNull($key=false): bool { + return $this->getResult($key)->null; + } + /** retourner true si la valeur est valide */ function isValid($key=false): bool { return $this->getResult($key)->valid; diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 9d33c7f..2b77804 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -102,16 +102,39 @@ class AssocWrapper extends Wrapper { $result = $context->result; if (!$result->valid) return $what; + $schema = $context->schema; + $keys = $schema->getKeys(); + $defaults = []; + $missings = null; + foreach ($keys as $key) { + $type = $wrapper->getType($key); + $default = $schema->getSchema($key)->default; + if ($default === null) $default = $type->getNullValue(); + $defaults[$key] = $default; + $missing = $type->getMissingValue($valid); + if ($valid) $missings[$key] = $missing; + } + foreach ($context->keyWrappers as $keyWrapper) { $keyWrapper->analyze($params); - if (!$keyWrapper->isValid()) { - #XXX distinguer MISSING, UNAVAILABLE, NULL et !VALID - $what = ref_analyze::INVALID; + if ($keyWrapper->isValid()) continue; + $what = ref_analyze::INVALID; + if (!$keyWrapper->isPresent()) { + $result->addMissingMessage($keyWrapper); + } elseif (!$keyWrapper->isAvailable()) { + $result->addUnavailableMessage($keyWrapper); + } elseif ($keyWrapper->isNull()) { + $result->addNullMessage($keyWrapper); + } else { $result->addInvalidMessage($keyWrapper); } } + if ($params["ensure_keys"] ?? $context->ensureKeys) { + $context->input->ensureKeys($defaults, $missings, $params); + } else { + $context->input->deleteMissings($missings, $params); + } - #XXX supprimer les clés "missing" ou "unavailable" sauf si $ensureKeys return $what; } @@ -120,23 +143,11 @@ class AssocWrapper extends Wrapper { * @param AssocWrapper $wrapper */ static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { - $ensureKeys = $params["ensure_keys"] ?? $context->ensureKeys; $ensureOrder = $params["ensure_order"] ?? $context->ensureOrder; - if ($ensureKeys || $ensureOrder) { + if ($ensureOrder) { $schema = $context->schema; $keys = $schema->getKeys(); - if ($ensureKeys) { - $defaults = []; - foreach ($keys as $key) { - $default = $schema->getSchema($key)->default; - if ($default === null) { - $default = $wrapper->getType($key)->getNullValue(); - } - $defaults[$key] = $default; - } - } - if ($ensureKeys) $context->input->ensureKeys($defaults, $params); - if ($ensureOrder) $context->input->ensureOrder($keys, $params); + $context->input->ensureOrder($keys, $params); } $modified = ScalarWrapper::_normalize($context, $wrapper, $params); diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index c442bdb..b538444 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -67,6 +67,29 @@ class ScalarResult extends Result { } } + function addMissingMessage(Wrapper $wrapper): void { + $this->resultAvailable = true; + $this->present = false; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->messageKey = "missing"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } + function setUnavailable( Schema $schema): int { $this->resultAvailable = true; $this->present = true; @@ -83,6 +106,29 @@ class ScalarResult extends Result { } } + function addUnavailableMessage(Wrapper $wrapper): void { + $this->resultAvailable = true; + $this->present = true; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->messageKey = "unavailable"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } + function setNull( Schema $schema): int { $this->resultAvailable = true; $this->present = true; @@ -99,6 +145,29 @@ class ScalarResult extends Result { } } + function addNullMessage(Wrapper $wrapper): void { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = true; + $this->valid = false; + $this->messageKey = "null"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } + function setInvalid($value, Schema $schema, ?Throwable $exception=null): int { $this->resultAvailable = true; $this->present = true; diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 1f43f4b..72f1e40 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -124,6 +124,16 @@ class ScalarWrapper extends Wrapper { } $value = $input->get($valueKey); + $missing = $type->getMissingValue($haveMissing); + if ($haveMissing && $value === $missing) { + if ($default !== null) { + $input->set($default, $valueKey); + return $result->setNormalized(); + } else { + return $result->setMissing($schema); + } + } + $context->origValue = $context->value = $value; if ($type->isNull($value)) { return $result->setNull($schema); diff --git a/src/schema/input/Input.php b/src/schema/input/Input.php index 59eefaa..4935bd6 100644 --- a/src/schema/input/Input.php +++ b/src/schema/input/Input.php @@ -76,8 +76,12 @@ class Input { $this->access->ensureAssoc($keys, $params); } - function ensureKeys(array $defaults, ?array $params=null): void { - $this->access->ensureKeys($defaults, $params); + function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { + $this->access->ensureKeys($defaults, $missings, $params); + } + + function deleteMissings(array $missings, ?array $params=null): void { + $this->access->deleteMissings($missings, $params); } function ensureOrder(array $keys, ?array $params=null): void { diff --git a/src/schema/types/IType.php b/src/schema/types/IType.php index e94fb80..c5fd8e3 100644 --- a/src/schema/types/IType.php +++ b/src/schema/types/IType.php @@ -47,30 +47,26 @@ interface IType { */ function getPhpType(bool $allowNullable=true): ?string; + /** + * obtenir la valeur "inexistante" pour les objets de ce type + * + * si $valid reçoit la valeur false, il faut ignorer la valeur de retour: + * cela veut dire qu'il n'y a pas de valeur "inexistant" pour les valeurs de + * ce type + */ + function getMissingValue(?bool &$valid=null); + /** obtenir la valeur "nulle" pour les objets de ce type */ function getNullValue(); /** - * indiquer si c'est le type d'une valeur qui ne peut prendre que 2 états: une - * "vraie" et une "fausse" + * si c'est le type d'une valeur qui ne prendre qu'une liste prédéterminée + * d'états spécifiques, retourner le nombre d'états possibles, et mettre à + * jour $states avec les valeurs possibles + * + * sinon, retourner 0 et ne pas mettre $states à jour */ - function is2States(): bool; - - /** - * Si {@link is2States()} est vrai, retourner les deux valeurs [faux, vrai] - */ - function get2States(): array; - - /** - * indiquer si c'est le type d'une valeur qui ne peut prendre que 3 états: une - * "vraie", une "fausse", et une "indéterminée" - */ - function is3States(): bool; - - /** - * Si {@link is3States()} est vrai, retourner les 3 valeurs [faux, vrai, undef] - */ - function get3States(): array; + function getNbStates(?array &$states=null): int; /** la donnée $input($valueKey) est-elle disponible? */ function isAvailable(Input $input, $valueKey): bool; diff --git a/src/schema/types/_tsimple.php b/src/schema/types/_tsimple.php index 94ab013..fd8174a 100644 --- a/src/schema/types/_tsimple.php +++ b/src/schema/types/_tsimple.php @@ -43,20 +43,13 @@ abstract class _tsimple implements IType { return $phpType; } - function is2States(): bool { + function getMissingValue(?bool &$valid=null) { + $valid = true; return false; } - function get2States(): array { - throw StateException::not_implemented(); - } - - function is3States(): bool { - return false; - } - - function get3States(): array { - throw StateException::not_implemented(); + function getNbStates(?array &$states=null): int { + return 0; } function isAvailable(Input $input, $valueKey): bool { diff --git a/src/schema/types/tbool.php b/src/schema/types/tbool.php index 1d62eef..a9b7854 100644 --- a/src/schema/types/tbool.php +++ b/src/schema/types/tbool.php @@ -60,26 +60,25 @@ class tbool extends _tformatable { return "bool"; } - function is2States(): bool { - return !$this->nullable; - } - - function get2States(): array { - return [false, true]; - } - - function is3States(): bool { - return $this->nullable; - } - - function get3States(): array { - return [false, true, null]; + function getMissingValue(?bool &$valid=null) { + $valid = !$this->nullable; + return null; } function getNullValue() { return $this->nullable? null: false; } + public function getNbStates(?array &$states=null): int { + if ($this->nullable) { + $states = [false, true, null]; + return 3; + } else { + $states = [false, true]; + return 2; + } + } + function isAvailable(Input $input, $valueKey): bool { return $input->isAvailable($valueKey); } diff --git a/src/schema/types/tgeneric.php b/src/schema/types/tgeneric.php index 9d948a6..498a16b 100644 --- a/src/schema/types/tgeneric.php +++ b/src/schema/types/tgeneric.php @@ -24,10 +24,6 @@ class tgeneric extends _tsimple { return null; } - function isAvailable(Input $input, $valueKey): bool { - return $input->isAvailable($valueKey); - } - public function isNull($value): bool { return $value === null; } diff --git a/src/schema/types/tmixed.php b/src/schema/types/tmixed.php index 045cebf..3d64620 100644 --- a/src/schema/types/tmixed.php +++ b/src/schema/types/tmixed.php @@ -14,6 +14,11 @@ class tmixed extends _tsimple { return "mixed"; } + function getMissingValue(?bool &$valid=null) { + $valid = false; + return null; + } + function getNullValue() { return null; } diff --git a/tests/php/access/KeyAccessTest.php b/tests/php/access/KeyAccessTest.php index b654050..6c17fef 100644 --- a/tests/php/access/KeyAccessTest.php +++ b/tests/php/access/KeyAccessTest.php @@ -152,7 +152,7 @@ class KeyAccessTest extends TestCase { private function _ensureKeys(?array $orig, ?array $expected, array $defaults, ?array $params=null) { $v = $orig; $a = new KeyAccess($v); - $a->ensureKeys($defaults, $params); + $a->ensureKeys($defaults, $missings, $params); self::assertSame($expected, $v); } function testEnsureKeys() { @@ -187,7 +187,7 @@ class KeyAccessTest extends TestCase { $v = $orig; $a = new KeyAccess($v); $keys = array_keys($defaults); $a->ensureAssoc($keys, $params); - $a->ensureKeys($defaults, $params); + $a->ensureKeys($defaults, $missings, $params); $a->ensureOrder($keys, $params); self::assertSame($expected, $v); } diff --git a/tests/schema/_assoc/AssocSchemaTest.php b/tests/schema/_assoc/AssocSchemaTest.php index c8e6c0d..d3314e1 100644 --- a/tests/schema/_assoc/AssocSchemaTest.php +++ b/tests/schema/_assoc/AssocSchemaTest.php @@ -50,54 +50,54 @@ class AssocSchemaTest extends TestCase { self::assertSame(self::schema([ "type" => ["array"], "nullable" => true, ], [ - "a" => [ + "s" => [ "type" => ["string"], "nullable" => false, - "name" => "a", "pkey" => "a", "header" => "a", + "name" => "s", "pkey" => "s", "header" => "s", ], - ]), AssocSchema::normalize_definition(["a" => "string"])); + ]), AssocSchema::normalize_definition(["s" => "string"])); self::assertSame(self::schema([ "type" => ["array"], "nullable" => true, ], [ - "a" => [ + "s" => [ "type" => ["string"], "nullable" => false, - "name" => "a", "pkey" => "a", "header" => "a", + "name" => "s", "pkey" => "s", "header" => "s", + ], + "i" => [ + "type" => ["int"], "nullable" => false, + "name" => "i", "pkey" => "i", "header" => "i", ], "b" => [ - "type" => ["int"], "nullable" => false, + "type" => ["bool"], "nullable" => false, "name" => "b", "pkey" => "b", "header" => "b", ], - "c" => [ - "type" => ["bool"], "nullable" => false, - "name" => "c", "pkey" => "c", "header" => "c", - ], ]), AssocSchema::normalize_definition([ - "a" => "string", - "b" => "int", - "c" => "bool", + "s" => "string", + "i" => "int", + "b" => "bool", ])); } function testConstructor() { $schema = new AssocSchema([ - "a" => "string", - "b" => "int", - "c" => "bool", + "s" => "string", + "i" => "int", + "b" => "bool", ]); self::assertSame(self::schema([ "type" => ["array"], "nullable" => true, ], [ - "a" => [ + "s" => [ "type" => ["string"], "nullable" => false, - "name" => "a", "pkey" => "a", "header" => "a", + "name" => "s", "pkey" => "s", "header" => "s", + ], + "i" => [ + "type" => ["int"], "nullable" => false, + "name" => "i", "pkey" => "i", "header" => "i", ], "b" => [ - "type" => ["int"], "nullable" => false, - "name" => "b", "pkey" => "b", "header" => "b", - ], - "c" => [ "type" => ["bool"], "nullable" => false, - "name" => "c", "pkey" => "c", "header" => "c", + "name" => "b", "pkey" => "b", "header" => "b", ], ]), $schema->getDefinition()); //yaml::dump($schema->getDefinition()); @@ -105,69 +105,82 @@ class AssocSchemaTest extends TestCase { function testWrapper() { $schema = new AssocSchema([ - "a" => "?string", - "b" => "?int", - "c" => "?bool", + "s" => "?string", + "i" => "?int", + "b" => "?bool", ]); - $array = ["a" => " string ", "b" => " 42 ", "c" => false]; + $array = ["s" => " string ", "i" => " 42 ", "b" => false]; $schema->getWrapper($array); self::assertSame([ - "a" => "string", - "b" => 42, - "c" => false, + "s" => "string", + "i" => 42, + "b" => false, ], $array); ########################################################################### $schema = new AssocSchema([ - "a" => "string", - "b" => "int", - "c" => "bool", + "s" => "string", + "i" => "int", + "b" => "bool", ]); - $array = ["a" => " string "]; + $array = ["s" => " string "]; $schema->getWrapper($array); self::assertSame([ - "a" => "string", - "b" => 0, - "c" => false, + "s" => "string", + "i" => 0, + "b" => false, ], $array); - $array = ["c" => false, "a" => " string "]; + $array = ["b" => false, "s" => " string "]; $schema->getWrapper($array); self::assertSame([ - "a" => "string", - "b" => 0, - "c" => false, + "s" => "string", + "i" => 0, + "b" => false, ], $array); - $array = ["a" => " string "]; + $array = ["s" => " string "]; $schema->getWrapper($array, null, ["ensure_order" => false]); self::assertSame([ - "a" => "string", - "b" => 0, - "c" => false, + "s" => "string", + "i" => 0, + "b" => false, ], $array); - $array = ["c" => false, "a" => " string "]; + $array = ["b" => false, "s" => " string "]; $schema->getWrapper($array, null, ["ensure_order" => false]); self::assertSame([ - "c" => false, - "a" => "string", - "b" => 0, + "b" => false, + "s" => "string", + "i" => 0, ], $array); - $array = ["a" => " string "]; + $array = ["s" => " string "]; $schema->getWrapper($array, null, ["ensure_keys" => false]); self::assertSame([ - "a" => "string", + "s" => "string", ], $array); - $array = ["c" => false, "a" => " string "]; + $array = ["b" => false, "s" => " string "]; $schema->getWrapper($array, null, ["ensure_keys" => false]); self::assertSame([ - "a" => "string", - "c" => false, + "s" => "string", + "b" => false, ], $array); + + // false équivaut à absent + $array = ["s" => false, "i" => false, "b" => null]; + $schema->getWrapper($array, null, ["ensure_keys" => true]); + self::assertSame([ + "s" => "", + "i" => 0, + "b" => false, + ], $array); + + $array = ["s" => false, "i" => false, "b" => null]; + $schema->getWrapper($array, null, ["ensure_keys" => false]); + self::assertSame([], $array); } const STRING_SCHEMA = [ @@ -203,7 +216,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(["s" => "string", "f" => false, "m" => ""], $array); + self::assertSame(["s" => "string", "f" => "", "m" => ""], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -241,7 +254,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(["s" => "string", "f" => false, "m" => null], $array); + self::assertSame(["s" => "string", "f" => null, "m" => null], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -277,7 +290,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(["s" => "string", "f" => false, "m" => ""], $array); + self::assertSame(["s" => "string", "f" => "", "m" => ""], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); @@ -318,7 +331,7 @@ class AssocSchemaTest extends TestCase { $array = self::STRINGS; $wrapper = $schema->getWrapper($array, null, ["throw" => false]); - self::assertSame(["s" => "string", "f" => false, "m" => null], $array); + self::assertSame(["s" => "string", "f" => null, "m" => null], $array); $result = $wrapper->getResult("s"); self::assertTrue($result->normalized); $result = $wrapper->getResult("f"); From 4353f482a422119d0510559114ff439bc85dfac9 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 17 Apr 2025 17:28:23 +0400 Subject: [PATCH 11/19] modifs.mineures sans commentaires --- bin/json2yml.php | 7 +++++ bin/yml2json.php | 7 +++++ composer.json | 2 ++ src/schema/TODO.md | 3 --- src/schema/_assoc/AssocWrapper.php | 42 ++++++++++++++---------------- src/tools/Json2yamlApp.php | 23 ++++++++++++++++ src/tools/Yaml2jsonApp.php | 23 ++++++++++++++++ 7 files changed, 82 insertions(+), 25 deletions(-) create mode 100755 bin/json2yml.php create mode 100755 bin/yml2json.php create mode 100644 src/tools/Json2yamlApp.php create mode 100644 src/tools/Yaml2jsonApp.php diff --git a/bin/json2yml.php b/bin/json2yml.php new file mode 100755 index 0000000..d417e90 --- /dev/null +++ b/bin/json2yml.php @@ -0,0 +1,7 @@ +#!/usr/bin/php + ensureKeys] [--> orderKeys]` -* si false, supprimer la clé du tableau sauf si ensureKeys - * pour AssocResult, les clés suivantes sont supportées: * false pour la clé courante * null pour un résultat aggrégé diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 2b77804..0b8ff08 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -102,19 +102,6 @@ class AssocWrapper extends Wrapper { $result = $context->result; if (!$result->valid) return $what; - $schema = $context->schema; - $keys = $schema->getKeys(); - $defaults = []; - $missings = null; - foreach ($keys as $key) { - $type = $wrapper->getType($key); - $default = $schema->getSchema($key)->default; - if ($default === null) $default = $type->getNullValue(); - $defaults[$key] = $default; - $missing = $type->getMissingValue($valid); - if ($valid) $missings[$key] = $missing; - } - foreach ($context->keyWrappers as $keyWrapper) { $keyWrapper->analyze($params); if ($keyWrapper->isValid()) continue; @@ -129,11 +116,6 @@ class AssocWrapper extends Wrapper { $result->addInvalidMessage($keyWrapper); } } - if ($params["ensure_keys"] ?? $context->ensureKeys) { - $context->input->ensureKeys($defaults, $missings, $params); - } else { - $context->input->deleteMissings($missings, $params); - } return $what; } @@ -143,10 +125,26 @@ class AssocWrapper extends Wrapper { * @param AssocWrapper $wrapper */ static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { - $ensureOrder = $params["ensure_order"] ?? $context->ensureOrder; - if ($ensureOrder) { - $schema = $context->schema; - $keys = $schema->getKeys(); + $schema = $context->schema; + $keys = $schema->getKeys(); + + $defaults = []; + $missings = null; + foreach ($keys as $key) { + $type = $wrapper->getType($key); + $default = $schema->getSchema($key)->default; + if ($default === null) $default = $type->getNullValue(); + $defaults[$key] = $default; + $missing = $type->getMissingValue($valid); + if ($valid) $missings[$key] = $missing; + } + if ($params["ensure_keys"] ?? $context->ensureKeys) { + $context->input->ensureKeys($defaults, $missings, $params); + } else { + $context->input->deleteMissings($missings, $params); + } + + if ($params["ensure_order"] ?? $context->ensureOrder) { $context->input->ensureOrder($keys, $params); } diff --git a/src/tools/Json2yamlApp.php b/src/tools/Json2yamlApp.php new file mode 100644 index 0000000..ba729c1 --- /dev/null +++ b/src/tools/Json2yamlApp.php @@ -0,0 +1,23 @@ +args[0] ?? null; + if ($input === null || $input === "-") { + $output = null; + } else { + $output = path::ensure_ext($input, ".yml", ".json"); + } + + $data = json::load($input); + yaml::dump($data, $output); + } +} \ No newline at end of file diff --git a/src/tools/Yaml2jsonApp.php b/src/tools/Yaml2jsonApp.php new file mode 100644 index 0000000..9eba6ea --- /dev/null +++ b/src/tools/Yaml2jsonApp.php @@ -0,0 +1,23 @@ +args[0] ?? null; + if ($input === null || $input === "-") { + $output = null; + } else { + $output = path::ensure_ext($input, ".json", [".yml", ".yaml"]); + } + + $data = yaml::load($input); + json::dump($data, $output); + } +} \ No newline at end of file From e592e8b9c4f5b709f95e565669122a654039e89e Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 18 Apr 2025 13:52:52 +0400 Subject: [PATCH 12/19] modifs.mineures sans commentaires --- src/schema/Wrapper.php | 28 ++++++++-------- src/schema/WrapperContext.php | 2 -- src/schema/_assoc/AssocWrapper.php | 40 +++++++++++++++-------- src/schema/_assoc/AssocWrapperContext.php | 6 ++++ src/schema/_scalar/ScalarWrapper.php | 6 ++-- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 12049c0..4f621c5 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -19,7 +19,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $this->context->resetParams($params); } - protected function resetContext($resetSelectedKey): void { + protected function resetContext(bool $resetSelectedKey): void { $context = $this->context; $type = $context->schema->type; if (is_array($type)) $type = $type[0]; @@ -28,19 +28,16 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $context->result->reset(); $context->analyzed = false; $context->normalized = false; - if ($resetSelectedKey) $context->selectedKey = null; } - protected function afterModify(?array $params, $resetSelectedKey=false): void { + protected function afterModify(?array $params, bool $resetSelectedKey=false): void { $context = $this->context; $this->resetContext($resetSelectedKey); if ($params["analyze"] ?? $context->analyze) { $this->analyze($params); } - if ($context->analyzed) { - if ($params["normalize"] ?? $context->normalize) { - $this->normalize($params); - } + if ($context->analyzed && ($params["normalize"] ?? $context->normalize)) { + $this->normalize($params); } } @@ -80,6 +77,15 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { /** normaliser la valeur */ abstract static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool; + protected function checkResult(): void { + $context = $this->context; + /** @var ScalarResult $result */ + $result = $context->result; + if (!$result->valid) { + $result->throw($params["throw"] ?? $context->throw); + } + } + function normalize(?array $params=null): bool { $context = $this->context; @@ -95,11 +101,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $modified = false; } - /** @var ScalarResult $result */ - $result = $context->result; - if (!$result->valid) { - $result->throw($params["throw"] ?? $context->throw); - } + $this->checkResult(); return $modified; } @@ -115,7 +117,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { * @param string|int|null $key * @return Wrapper $this */ - abstract function select($key): Wrapper; + abstract function select($key=null): Wrapper; function getIterator() { foreach ($this->getKeys() as $key) { diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index d005ea9..a47bfd7 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -37,8 +37,6 @@ class WrapperContext { /** @var mixed */ public $value = null; - /** @var string|int|null clé sélectionnée */ - public $selectedKey = null; /** type de la valeur de la clé sélectionnée après analyse */ public ?IType $type = null; /** résultat de l'analyse de la valeur de la clé sélectionnée */ diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 0b8ff08..18b7737 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -14,23 +14,25 @@ use nulib\schema\WrapperContext; class AssocWrapper extends Wrapper { function __construct(AssocSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { - $keys = $schema->getKeys(); - $keyParams = cl::merge($params, [ + $this->context = $context = new AssocWrapperContext($schema, null, null, $params); + $paramsNoThrow = cl::merge($params, [ "throw" => false, ]); + + $keys = $schema->getKeys(); $keyWrappers = []; foreach ($keys as $key) { - $value = null; - $keyWrappers[$key] = $schema->getSchema($key)->getWrapper($value, null, $keyParams); + $keyDummy = null; + $keyWrappers[$key] = $schema->getSchema($key)->getWrapper($keyDummy, null, $paramsNoThrow); } - $this->context = $context = new AssocWrapperContext($schema, null, null, $params); - $arrayParams = cl::merge($params, [ - "throw" => false, - ]); - $context->arrayWrapper = new ScalarWrapper($schema, $dummy, null, $arrayParams, $context); $context->keys = $keys; $context->keyWrappers = $keyWrappers; + $arrayDummy = null; + $context->arrayWrapper = new ScalarWrapper($schema, $arrayDummy, null, $paramsNoThrow, $context); + + $context->assocResult = new ScalarResult();#XX AssocResult + if ($value !== null) { # n'initialiser que si $value n'est pas null $this->reset($value, $valueKey); @@ -40,13 +42,14 @@ class AssocWrapper extends Wrapper { /** @var AssocWrapperContext */ protected WrapperContext $context; - protected function resetContext($resetSelectedKey): void { + protected function resetContext(bool $resetSelectedKey): void { parent::resetContext($resetSelectedKey); $context = $this->context; $context->arrayWrapper->getResult()->reset(); foreach ($context->keyWrappers as $wrapper) { $wrapper->getResult()->reset(); } + if ($resetSelectedKey) $context->selectedKey = null; } function reset(&$value, $valueKey=null, ?array $params=null): Wrapper { @@ -69,7 +72,7 @@ class AssocWrapper extends Wrapper { protected function _getWrapper($key): Wrapper { $context = $this->context; - if ($key === null) return $context->arrayWrapper; + if ($key === null || $key === "") return $context->arrayWrapper; $wrapper = $context->keyWrappers[$key] ?? null; if ($wrapper === null) throw ValueException::invalid_key($key); return $wrapper; @@ -99,9 +102,10 @@ class AssocWrapper extends Wrapper { $what = ScalarWrapper::_analyze($context, $wrapper, $params); /** @var ScalarResult $result */ - $result = $context->result; - if (!$result->valid) return $what; + if (!$context->result->valid) return $what; + $result = $context->assocResult; + $result->setValid(); foreach ($context->keyWrappers as $keyWrapper) { $keyWrapper->analyze($params); if ($keyWrapper->isValid()) continue; @@ -155,7 +159,17 @@ class AssocWrapper extends Wrapper { return $modified; } + protected function checkResult(): void { + $context = $this->context; + /** @var ScalarResult $result */ + $result = $context->assocResult; + if (!$result->valid) { + $result->throw($params["throw"] ?? $context->throw); + } + } + function getResult($key=false): Result { + if ($key === null) return $this->context->assocResult; if ($key === false) $key = $this->context->selectedKey; return $this->_getWrapper($key)->getResult(); } diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index 01c417e..a75321b 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -2,6 +2,7 @@ namespace nulib\schema\_assoc; use nulib\ref\schema\ref_schema; +use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarWrapper; use nulib\schema\Wrapper; use nulib\schema\WrapperContext; @@ -28,4 +29,9 @@ class AssocWrapperContext extends WrapperContext { /** @var Wrapper[] */ public array $keyWrappers; + + public ScalarResult $assocResult; + + /** @var string|int|null clé sélectionnée */ + public $selectedKey = null; } diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 72f1e40..0aceea6 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -40,9 +40,9 @@ class ScalarWrapper extends Wrapper { } /** @param string|int|null $key */ - function select($key): ScalarWrapper { - if ($key !== null) throw ValueException::invalid_key($key); - return $this; + function select($key=null): ScalarWrapper { + if ($key === null || $key === "") return $this; + throw ValueException::invalid_key($key); } /** analyser la valeur et résoudre son type */ From 4d238cc44eb5f51d1cefb4a43a1bffeb6ad5fd8c Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 18 Apr 2025 21:34:39 +0400 Subject: [PATCH 13/19] maj doc --- src/schema/_assoc/AssocWrapperContext.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index a75321b..f015f75 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -4,6 +4,7 @@ namespace nulib\schema\_assoc; use nulib\ref\schema\ref_schema; use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarWrapper; +use nulib\schema\Result; use nulib\schema\Wrapper; use nulib\schema\WrapperContext; @@ -30,6 +31,10 @@ class AssocWrapperContext extends WrapperContext { /** @var Wrapper[] */ public array $keyWrappers; + /** + * @var ScalarResult résultat consolidé de l'analyse du tableau et de ses + * composants + */ public ScalarResult $assocResult; /** @var string|int|null clé sélectionnée */ From 80fab7e636e226fb4324170d0a719cddeef31a4b Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sat, 19 Apr 2025 06:58:35 +0400 Subject: [PATCH 14/19] modifs.mineures sans commentaires --- src/schema/ConsolidatedResult.php | 98 +++++++++ src/schema/Result.php | 159 +++++++++++--- src/schema/TODO.md | 6 - src/schema/Wrapper.php | 39 ++-- src/schema/_assoc/AssocWrapper.php | 20 +- src/schema/_assoc/AssocWrapperContext.php | 12 +- src/schema/_list/ListResult.php | 51 ----- src/schema/_scalar/ScalarResult.php | 239 ---------------------- src/schema/_scalar/ScalarSchema.php | 4 +- src/schema/_scalar/ScalarWrapper.php | 9 +- src/schema/types/tarray.php | 2 - src/schema/types/tbool.php | 2 - src/schema/types/tcontent.php | 2 - src/schema/types/tfloat.php | 2 - src/schema/types/tfunc.php | 2 - src/schema/types/tgeneric.php | 2 - src/schema/types/tint.php | 2 - src/schema/types/tkey.php | 2 - src/schema/types/tmixed.php | 2 - src/schema/types/tpkey.php | 2 - src/schema/types/trawstring.php | 2 - 21 files changed, 268 insertions(+), 391 deletions(-) create mode 100644 src/schema/ConsolidatedResult.php delete mode 100644 src/schema/_list/ListResult.php delete mode 100644 src/schema/_scalar/ScalarResult.php diff --git a/src/schema/ConsolidatedResult.php b/src/schema/ConsolidatedResult.php new file mode 100644 index 0000000..c760a47 --- /dev/null +++ b/src/schema/ConsolidatedResult.php @@ -0,0 +1,98 @@ +resultAvailable = true; + $this->present = false; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->messageKey = "missing"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } + + function addUnavailableMessage(Wrapper $wrapper): void { + $this->resultAvailable = true; + $this->present = true; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->messageKey = "unavailable"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } + + function addNullMessage(Wrapper $wrapper): void { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = true; + $this->valid = false; + $this->messageKey = "null"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } + + function addInvalidMessage(Wrapper $wrapper): void { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = false; + $this->valid = false; + $this->messageKey = "invalid"; + $result = $wrapper->getResult(); + $resultException = $result->exception; + $resultMessage = $result->message; + if ($resultException !== null) { + $tmessage = ValueException::get_message($resultException); + if ($tmessage) { + if ($resultMessage !== null) $resultMessage .= ": "; + $resultMessage .= $tmessage; + } + } + $message = $this->message; + if ($message) $message .= "\n"; + $message .= $resultMessage; + $this->message = $message; + } +} diff --git a/src/schema/Result.php b/src/schema/Result.php index 2490f5a..835732c 100644 --- a/src/schema/Result.php +++ b/src/schema/Result.php @@ -1,7 +1,10 @@ reset(); } - /** - * Obtenir la liste des clés valides pour les valeurs accessibles via cet - * objet - */ - abstract function getKeys(): array; - - /** - * sélectionner le résultat associé à la clé spécifiée - * - * @param string|int|null $key - * @return Result $this - */ - abstract function select($key): Result; - - function getIterator() { - foreach ($this->getKeys() as $key) { - yield $key => $this->select($key); - } - $this->select(null); - } + public bool $resultAvailable; + public bool $present; + public bool $available; + public bool $null; + public bool $valid; + public bool $normalized; + public ?string $messageKey; + public ?string $message; + public ?Throwable $exception; + public ?string $origValue; + public $normalizedValue; /** réinitialiser tous les objets résultats accessibles via cet objet */ - abstract function reset(): void; + function reset(): void { + $this->resultAvailable = false; + $this->present = false; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->normalized = false; + $this->messageKey = null; + $this->message = null; + $this->exception = null; + $this->origValue = null; + $this->normalizedValue = null; + } + + protected function getMessage(string $key, Schema $schema): string { + $message = cl::get($schema->messages, $key); + if ($message !== null) return $message; + return cl::get(ref_schema::MESSAGES, $key); + } + + function setMissing( Schema $schema): int { + $this->resultAvailable = true; + $this->present = false; + $this->available = false; + if (!$schema->required) { + $this->null = false; + $this->valid = true; + $this->normalized = true; + return ref_analyze::NORMALIZED; + } else { + $this->messageKey = $messageKey = "missing"; + $this->message = $this->getMessage($messageKey, $schema); + return ref_analyze::MISSING; + } + } + + function setUnavailable( Schema $schema): int { + $this->resultAvailable = true; + $this->present = true; + $this->available = false; + if (!$schema->required) { + $this->null = false; + $this->valid = true; + $this->normalized = true; + return ref_analyze::NORMALIZED; + } else { + $this->messageKey = $messageKey = "unavailable"; + $this->message = $this->getMessage($messageKey, $schema); + return ref_analyze::UNAVAILABLE; + } + } + + function setNull( Schema $schema): int { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = true; + if ($schema->nullable) { + $this->valid = true; + $this->normalized = true; + return ref_analyze::NORMALIZED; + } else { + $this->messageKey = $messageKey = "null"; + $this->message = $this->getMessage($messageKey, $schema); + return ref_analyze::NULL; + } + } + + function setInvalid($value, Schema $schema, ?Throwable $exception=null): int { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = false; + $this->valid = false; + $this->origValue = $value; + $this->messageKey = $messageKey = "invalid"; + $message = $this->getMessage($messageKey, $schema); + if ($exception !== null) { + $tmessage = ValueException::get_message($exception); + if ($tmessage) $message = $tmessage; + } + $this->message = $message; + $this->exception = $exception; + return ref_analyze::INVALID; + } + + function setValid($normalizedValue=null): int { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = false; + $this->valid = true; + $this->normalizedValue = $normalizedValue; + return ref_analyze::VALID; + } + + function setNormalized(): int { + $this->resultAvailable = true; + $this->present = true; + $this->available = true; + $this->null = false; + $this->valid = true; + $this->normalized = true; + return ref_analyze::NORMALIZED; + } + + function throw(bool $throw): void { + if ($throw) { + $exception = $this->exception; + if ($exception !== null) throw $exception; + else throw new ValueException($this->message); + } + } } diff --git a/src/schema/TODO.md b/src/schema/TODO.md index ee5c140..ab891c4 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,11 +1,5 @@ # nulib\schema -* pour AssocResult, les clés suivantes sont supportées: - * false pour la clé courante - * null pour un résultat aggrégé - * "" pour le résultat du tableau - * $key pour le résultat de la clé correspondante - * rajouter l'attribut "size" pour spécifier la taille maximale des valeurs * cela pourrait servir pour générer automatiquement des tables SQL * ou pour modéliser un schéma FSV diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 4f621c5..7ea7d1e 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -4,12 +4,9 @@ namespace nulib\schema; use ArrayAccess; use IteratorAggregate; use nulib\php\func; -use nulib\schema\_assoc\AssocWrapper; -use nulib\schema\_list\ListWrapper; -use nulib\schema\_scalar\ScalarResult; -use nulib\schema\_scalar\ScalarWrapper; use nulib\schema\input\Input; use nulib\schema\types\IType; +use nulib\ValueException; abstract class Wrapper implements ArrayAccess, IteratorAggregate { protected WrapperContext $context; @@ -77,13 +74,8 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { /** normaliser la valeur */ abstract static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool; - protected function checkResult(): void { - $context = $this->context; - /** @var ScalarResult $result */ - $result = $context->result; - if (!$result->valid) { - $result->throw($params["throw"] ?? $context->throw); - } + protected function getConsolidatedResult(): Result { + return $this->context->result; } function normalize(?array $params=null): bool { @@ -101,7 +93,11 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $modified = false; } - $this->checkResult(); + $result = $this->getConsolidatedResult(); + if (!$result->valid) { + $result->throw($params["throw"] ?? $context->throw); + } + return $modified; } @@ -114,6 +110,12 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { /** * sélectionner le wrapper associé à la clé spécifiée * + * $key peut valoir: + * - false pour la clé courante (ne pas changer la sélection) + * - null ou "" le wrapper de la valeur principale + * - ou toute autre valeur présente dans {@link getKeys()} pour les valeurs + * accessible via cet objet + * * @param string|int|null $key * @return Wrapper $this */ @@ -123,7 +125,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { foreach ($this->getKeys() as $key) { yield $key => $this->select($key); } - $this->select(null); + $this->select(); } /** @@ -131,9 +133,18 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { * * cette fonction doit être appelée après {@link set()} ou {@link unset()} et * après que le wrapper aie été sélectionné avec {@link select()} + * + * $key peut valoir: + * - false pour la clé sélectionnée avec {@link select()} + * - null pour le résultat consolidé + * - "" pour le résultat de l'analyse de la valeur principale + * - ou toute autre valeur présente dans {@link getKeys()} pour le résultat + * de l'analyse des valeurs correspondantes */ function getResult($key=false): Result { - return $this->context->result; + if ($key === false || $key === "") return $this->context->result; + if ($key === null) return $this->getConsolidatedResult(); + throw ValueException::invalid_key($key); } /** retourner true si la valeur existe */ diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 18b7737..d4d3034 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -3,14 +3,14 @@ namespace nulib\schema\_assoc; use nulib\cl; use nulib\ref\schema\ref_analyze; -use nulib\ValueException; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarWrapper; +use nulib\schema\ConsolidatedResult; use nulib\schema\input\Input; use nulib\schema\Result; use nulib\schema\types\IType; use nulib\schema\Wrapper; use nulib\schema\WrapperContext; +use nulib\ValueException; class AssocWrapper extends Wrapper { function __construct(AssocSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { @@ -31,7 +31,7 @@ class AssocWrapper extends Wrapper { $arrayDummy = null; $context->arrayWrapper = new ScalarWrapper($schema, $arrayDummy, null, $paramsNoThrow, $context); - $context->assocResult = new ScalarResult();#XX AssocResult + $context->consolidatedResult = new ConsolidatedResult(); if ($value !== null) { # n'initialiser que si $value n'est pas null @@ -101,10 +101,9 @@ class AssocWrapper extends Wrapper { } $what = ScalarWrapper::_analyze($context, $wrapper, $params); - /** @var ScalarResult $result */ if (!$context->result->valid) return $what; - $result = $context->assocResult; + $result = $context->consolidatedResult; $result->setValid(); foreach ($context->keyWrappers as $keyWrapper) { $keyWrapper->analyze($params); @@ -159,17 +158,12 @@ class AssocWrapper extends Wrapper { return $modified; } - protected function checkResult(): void { - $context = $this->context; - /** @var ScalarResult $result */ - $result = $context->assocResult; - if (!$result->valid) { - $result->throw($params["throw"] ?? $context->throw); - } + protected function getConsolidatedResult(): Result { + return $this->context->consolidatedResult; } function getResult($key=false): Result { - if ($key === null) return $this->context->assocResult; + if ($key === null) return $this->getConsolidatedResult(); if ($key === false) $key = $this->context->selectedKey; return $this->_getWrapper($key)->getResult(); } diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index f015f75..38c7182 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -2,9 +2,8 @@ namespace nulib\schema\_assoc; use nulib\ref\schema\ref_schema; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarWrapper; -use nulib\schema\Result; +use nulib\schema\ConsolidatedResult; use nulib\schema\Wrapper; use nulib\schema\WrapperContext; @@ -31,12 +30,9 @@ class AssocWrapperContext extends WrapperContext { /** @var Wrapper[] */ public array $keyWrappers; - /** - * @var ScalarResult résultat consolidé de l'analyse du tableau et de ses - * composants - */ - public ScalarResult $assocResult; - /** @var string|int|null clé sélectionnée */ public $selectedKey = null; + + /** résultat consolidé de l'analyse du tableau et de ses composants */ + public ConsolidatedResult $consolidatedResult; } diff --git a/src/schema/_list/ListResult.php b/src/schema/_list/ListResult.php deleted file mode 100644 index 91158a1..0000000 --- a/src/schema/_list/ListResult.php +++ /dev/null @@ -1,51 +0,0 @@ -arrayResult = $arrayResult; - $this->keyResults =& $keyResults; - $this->result =& $this->arrayResult; - parent::__construct(); - } - - protected Result $arrayResult; - - /** @var Result[] */ - protected array $keyResults; - - function getKeys(): array { - return array_keys($this->keyResults); - } - - protected Result $result; - - function select($key): Result { - if ($key === null) { - $this->result =& $this->arrayResult; - } elseif (array_key_exists($key, $this->keyResults)) { - $this->result =& $this->keyResults[$key]; - } else { - throw ValueException::invalid_key($key); - } - return $this; - } - - function reset(): void { - $this->arrayResult->reset(); - foreach ($this->keyResults as $result) { - $result->reset(); - } - } - - function __get(string $name) { - return $this->result[$name]; - } - - function __set(string $name, $value): void { - $this->result[$name] = $value; - } -} diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php deleted file mode 100644 index b538444..0000000 --- a/src/schema/_scalar/ScalarResult.php +++ /dev/null @@ -1,239 +0,0 @@ -result = array_merge( - array_fill_keys(static::KEYS, null), [ - "resultAvailable" => false, - "present" => false, - "available" => false, - "null" => false, - "valid" => false, - "normalized" => false, - ]); - } - - function __get(string $name) { - return $this->result[$name]; - } - - function __set(string $name, $value): void { - $this->result[$name] = $value; - } - - protected function getMessage(string $key, Schema $schema): string { - $message = cl::get($schema->messages, $key); - if ($message !== null) return $message; - return cl::get(ref_schema::MESSAGES, $key); - } - - function setMissing( Schema $schema): int { - $this->resultAvailable = true; - $this->present = false; - $this->available = false; - if (!$schema->required) { - $this->null = false; - $this->valid = true; - $this->normalized = true; - return ref_analyze::NORMALIZED; - } else { - $this->messageKey = $messageKey = "missing"; - $this->message = $this->getMessage($messageKey, $schema); - return ref_analyze::MISSING; - } - } - - function addMissingMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = false; - $this->available = false; - $this->null = false; - $this->valid = false; - $this->messageKey = "missing"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } - } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; - } - - function setUnavailable( Schema $schema): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = false; - if (!$schema->required) { - $this->null = false; - $this->valid = true; - $this->normalized = true; - return ref_analyze::NORMALIZED; - } else { - $this->messageKey = $messageKey = "unavailable"; - $this->message = $this->getMessage($messageKey, $schema); - return ref_analyze::UNAVAILABLE; - } - } - - function addUnavailableMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = true; - $this->available = false; - $this->null = false; - $this->valid = false; - $this->messageKey = "unavailable"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } - } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; - } - - function setNull( Schema $schema): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = true; - if ($schema->nullable) { - $this->valid = true; - $this->normalized = true; - return ref_analyze::NORMALIZED; - } else { - $this->messageKey = $messageKey = "null"; - $this->message = $this->getMessage($messageKey, $schema); - return ref_analyze::NULL; - } - } - - function addNullMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = true; - $this->valid = false; - $this->messageKey = "null"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } - } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; - } - - function setInvalid($value, Schema $schema, ?Throwable $exception=null): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = false; - $this->origValue = $value; - $this->messageKey = $messageKey = "invalid"; - $message = $this->getMessage($messageKey, $schema); - if ($exception !== null) { - $tmessage = ValueException::get_message($exception); - if ($tmessage) $message = $tmessage; - } - $this->message = $message; - $this->exception = $exception; - return ref_analyze::INVALID; - } - - function addInvalidMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = false; - $this->messageKey = "invalid"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } - } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; - } - - function setValid($normalizedValue=null): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = true; - $this->normalizedValue = $normalizedValue; - return ref_analyze::VALID; - } - - function setNormalized(): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = true; - $this->normalized = true; - return ref_analyze::NORMALIZED; - } - - function throw(bool $throw): void { - if ($throw) { - $exception = $this->exception; - if ($exception !== null) throw $exception; - else throw new ValueException($this->message); - } - } -} diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 29deca5..ca7a68f 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -64,14 +64,14 @@ class ScalarSchema extends Schema { $this->definition = $definition; } - const KEYS = [null]; + const KEYS = []; function getKeys(): array { return self::KEYS; } function getSchema($key=false): Schema { - if ($key === null || $key === false) return $this; + if ($key === false || $key === null || $key === "") return $this; throw ValueException::invalid_key($key); } diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 0aceea6..00f7896 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -3,25 +3,25 @@ namespace nulib\schema\_scalar; use nulib\php\func; use nulib\ref\schema\ref_analyze; -use nulib\ValueException; +use nulib\schema\Result; use nulib\schema\Schema; use nulib\schema\types; use nulib\schema\types\IType; use nulib\schema\Wrapper; use nulib\schema\WrapperContext; +use nulib\ValueException; /** * Class ScalarWrapper * * @method ScalarWrapper reset(&$value, $valueKey=null, ?array $params=null) - * @method ScalarResult getResult($key=false) * @method self set($value, ?array $params=null, $key=false) * @method self unset(?array $params=null, $key=false) */ class ScalarWrapper extends Wrapper { function __construct(Schema $schema, &$value=null, $valueKey=null, ?array $params=null, ?WrapperContext $context=null) { if ($context === null) $context = new WrapperContext($schema, null, null, $params); - $context->result = new ScalarResult(); + $context->result = new Result(); $this->context = $context; if ($value !== null) { @@ -51,7 +51,6 @@ class ScalarWrapper extends Wrapper { $schema = $context->schema; $input = $context->input; $valueKey = $context->valueKey; - /** @var ScalarResult $result */ $result = $context->result; $default = $schema->default; @@ -155,7 +154,6 @@ class ScalarWrapper extends Wrapper { $schema = $context->schema; $input = $context->input; $valueKey = $context->valueKey; - /** @var ScalarResult $result */ $result = $context->result; /** @var func $analyzerFunc */ @@ -204,7 +202,6 @@ class ScalarWrapper extends Wrapper { $schema = $context->schema; $input = $context->input; $valueKey = $context->valueKey; - /** @var ScalarResult $result */ $result = $context->result; $normalize = false; diff --git a/src/schema/types/tarray.php b/src/schema/types/tarray.php index b77de54..9c96c5f 100644 --- a/src/schema/types/tarray.php +++ b/src/schema/types/tarray.php @@ -3,7 +3,6 @@ namespace nulib\schema\types; use nulib\cl; use nulib\ValueException; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\Result; use nulib\schema\Schema; @@ -50,7 +49,6 @@ class tarray extends _tstring { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tbool.php b/src/schema/types/tbool.php index a9b7854..61d6472 100644 --- a/src/schema/types/tbool.php +++ b/src/schema/types/tbool.php @@ -4,7 +4,6 @@ namespace nulib\schema\types; use nulib\cl; use nulib\ValueException; use nur\prop; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\input\Input; use nulib\schema\Result; @@ -99,7 +98,6 @@ class tbool extends _tformatable { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tcontent.php b/src/schema/types/tcontent.php index 6316012..b775cdf 100644 --- a/src/schema/types/tcontent.php +++ b/src/schema/types/tcontent.php @@ -2,7 +2,6 @@ namespace nulib\schema\types; use nulib\php\content\c; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\Result; use nulib\schema\Schema; @@ -37,7 +36,6 @@ abstract class tcontent extends _tunion { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tfloat.php b/src/schema/types/tfloat.php index 6202db5..f1b49be 100644 --- a/src/schema/types/tfloat.php +++ b/src/schema/types/tfloat.php @@ -2,7 +2,6 @@ namespace nulib\schema\types; use nulib\ValueException; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\Result; use nulib\schema\Schema; @@ -44,7 +43,6 @@ class tfloat extends _tformatable { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tfunc.php b/src/schema/types/tfunc.php index 0ca3622..3fe47a4 100644 --- a/src/schema/types/tfunc.php +++ b/src/schema/types/tfunc.php @@ -4,7 +4,6 @@ namespace nulib\schema\types; use Exception; use nulib\php\func; use nulib\ValueException; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\Result; use nulib\schema\Schema; @@ -44,7 +43,6 @@ class tfunc extends _tsimple { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tgeneric.php b/src/schema/types/tgeneric.php index 498a16b..e8dfe4e 100644 --- a/src/schema/types/tgeneric.php +++ b/src/schema/types/tgeneric.php @@ -2,7 +2,6 @@ namespace nulib\schema\types; use nulib\ValueException; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\input\Input; use nulib\schema\Result; @@ -38,7 +37,6 @@ class tgeneric extends _tsimple { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tint.php b/src/schema/types/tint.php index cfc1a18..606ba4a 100644 --- a/src/schema/types/tint.php +++ b/src/schema/types/tint.php @@ -2,7 +2,6 @@ namespace nulib\schema\types; use nulib\ValueException; -use nulib\schema\_scalar\ScalarResult; use nulib\schema\_scalar\ScalarSchema; use nulib\schema\Result; use nulib\schema\Schema; @@ -46,7 +45,6 @@ class tint extends _tformatable { } /** - * @var ScalarResult $result * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { diff --git a/src/schema/types/tkey.php b/src/schema/types/tkey.php index cf72006..0650f54 100644 --- a/src/schema/types/tkey.php +++ b/src/schema/types/tkey.php @@ -1,7 +1,6 @@ Date: Sat, 19 Apr 2025 07:48:20 +0400 Subject: [PATCH 15/19] modifs.mineures sans commentaires --- src/app.php | 7 +- src/app/cli/Application.php | 2 +- src/php/access/GetAccess.php | 2 - src/php/access/IAccess.php | 2 - src/php/access/KeyAccess.php | 1 - src/php/access/PostAccess.php | 2 - src/php/iter.php | 1 - src/schema/ConsolidatedResult.php | 123 ++++++++-------------- src/schema/Result.php | 10 +- src/schema/Schema.php | 2 +- src/schema/_assoc/AssocSchema.php | 2 +- src/schema/_assoc/AssocWrapper.php | 13 ++- src/schema/_list/ListSchema.php | 2 +- src/schema/_scalar/ScalarSchema.php | 3 +- src/schema/input/Input.php | 4 +- src/schema/types.php | 4 +- src/schema/types/IType.php | 2 +- src/schema/types/_tsimple.php | 3 +- src/schema/types/tarray.php | 1 - src/schema/types/tbool.php | 6 +- src/schema/types/tfloat.php | 2 +- src/schema/types/tfunc.php | 2 +- src/schema/types/tgeneric.php | 3 +- src/schema/types/tint.php | 2 +- src/schema/types/trawstring.php | 2 +- tests/schema/_assoc/AssocSchemaTest.php | 38 ++++++- tests/schema/_scalar/ScalarSchemaTest.php | 2 + 27 files changed, 114 insertions(+), 129 deletions(-) diff --git a/src/app.php b/src/app.php index 185df43..97802b9 100644 --- a/src/app.php +++ b/src/app.php @@ -1,18 +1,13 @@ resultAvailable = true; - $this->present = false; - $this->available = false; - $this->null = false; - $this->valid = false; - $this->messageKey = "missing"; + protected int $highestResult; + + function reset(): void { + parent::reset(); + $this->highestResult = -1; + } + + protected function _addMessage(Wrapper $wrapper, $prefix=null): void { $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } - } $message = $this->message; if ($message) $message .= "\n"; - $message .= $resultMessage; + if ($prefix !== null) $message .= "$prefix: "; + $message .= $result->message; $this->message = $message; } - function addUnavailableMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = true; - $this->available = false; - $this->null = false; - $this->valid = false; - $this->messageKey = "unavailable"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } + function addMissingMessage(Wrapper $wrapper, $prefix=null): void { + if ($this->highestResult < ref_analyze::MISSING) { + $this->present = false; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->messageKey = "missing"; } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; + $this->_addMessage($wrapper, $prefix); } - function addNullMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = true; - $this->valid = false; - $this->messageKey = "null"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } + function addUnavailableMessage(Wrapper $wrapper, $prefix=null): void { + if ($this->highestResult < ref_analyze::UNAVAILABLE) { + $this->present = true; + $this->available = false; + $this->null = false; + $this->valid = false; + $this->messageKey = "unavailable"; } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; + $this->_addMessage($wrapper, $prefix); } - function addInvalidMessage(Wrapper $wrapper): void { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = false; - $this->messageKey = "invalid"; - $result = $wrapper->getResult(); - $resultException = $result->exception; - $resultMessage = $result->message; - if ($resultException !== null) { - $tmessage = ValueException::get_message($resultException); - if ($tmessage) { - if ($resultMessage !== null) $resultMessage .= ": "; - $resultMessage .= $tmessage; - } + function addNullMessage(Wrapper $wrapper, $prefix=null): void { + if ($this->highestResult < ref_analyze::NULL) { + $this->present = true; + $this->available = true; + $this->null = true; + $this->valid = false; + $this->messageKey = "null"; } - $message = $this->message; - if ($message) $message .= "\n"; - $message .= $resultMessage; - $this->message = $message; + $this->_addMessage($wrapper, $prefix); + } + + function addInvalidMessage(Wrapper $wrapper, $prefix=null): void { + if ($this->highestResult < ref_analyze::INVALID) { + $this->present = true; + $this->available = true; + $this->null = false; + $this->valid = false; + $this->messageKey = "invalid"; + } + $this->_addMessage($wrapper, $prefix); } } diff --git a/src/schema/Result.php b/src/schema/Result.php index 835732c..45d3402 100644 --- a/src/schema/Result.php +++ b/src/schema/Result.php @@ -39,7 +39,7 @@ class Result { public ?string $messageKey; public ?string $message; public ?Throwable $exception; - public ?string $origValue; + public $origValue; public $normalizedValue; /** réinitialiser tous les objets résultats accessibles via cet objet */ @@ -119,11 +119,9 @@ class Result { $this->valid = false; $this->origValue = $value; $this->messageKey = $messageKey = "invalid"; - $message = $this->getMessage($messageKey, $schema); - if ($exception !== null) { - $tmessage = ValueException::get_message($exception); - if ($tmessage) $message = $tmessage; - } + $message = null; + if ($exception !== null) $message = ValueException::get_message($exception); + if (!$message) $message = $this->getMessage($messageKey, $schema); $this->message = $message; $this->exception = $exception; return ref_analyze::INVALID; diff --git a/src/schema/Schema.php b/src/schema/Schema.php index 4e81520..fbb441b 100644 --- a/src/schema/Schema.php +++ b/src/schema/Schema.php @@ -12,8 +12,8 @@ use nulib\schema\_scalar\ScalarSchema; use nulib\schema\types\IType; use nulib\schema\types\tarray; use nulib\schema\types\tbool; -use nulib\schema\types\tfunc; use nulib\schema\types\tcontent; +use nulib\schema\types\tfunc; use nulib\schema\types\tpkey; use nulib\schema\types\trawstring; diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index 2ebbc49..8f05843 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -3,9 +3,9 @@ namespace nulib\schema\_assoc; use nulib\cl; use nulib\ref\schema\ref_schema; -use nulib\ValueException; use nulib\schema\Schema; use nulib\schema\Wrapper; +use nulib\ValueException; /** * Class AssocSchema diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index d4d3034..014507b 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -105,18 +105,21 @@ class AssocWrapper extends Wrapper { $result = $context->consolidatedResult; $result->setValid(); - foreach ($context->keyWrappers as $keyWrapper) { + foreach ($context->keyWrappers as $key => $keyWrapper) { $keyWrapper->analyze($params); if ($keyWrapper->isValid()) continue; $what = ref_analyze::INVALID; + #XXX utiliser si possible la description ou une autre valeur "user-friendly" + # possibilité de sélectionner la valeur à utiliser dans $params? + $prefix = $key; if (!$keyWrapper->isPresent()) { - $result->addMissingMessage($keyWrapper); + $result->addMissingMessage($keyWrapper, $prefix); } elseif (!$keyWrapper->isAvailable()) { - $result->addUnavailableMessage($keyWrapper); + $result->addUnavailableMessage($keyWrapper, $prefix); } elseif ($keyWrapper->isNull()) { - $result->addNullMessage($keyWrapper); + $result->addNullMessage($keyWrapper, $prefix); } else { - $result->addInvalidMessage($keyWrapper); + $result->addInvalidMessage($keyWrapper, $prefix); } } diff --git a/src/schema/_list/ListSchema.php b/src/schema/_list/ListSchema.php index c3d2b9a..02a137b 100644 --- a/src/schema/_list/ListSchema.php +++ b/src/schema/_list/ListSchema.php @@ -2,9 +2,9 @@ namespace nulib\schema\_list; use nulib\ref\schema\ref_schema; -use nulib\ValueException; use nulib\schema\Schema; use nulib\schema\Wrapper; +use nulib\ValueException; class ListSchema extends Schema { /** @var array meta-schema d'un schéma de nature liste */ diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index ca7a68f..c1e5125 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -1,11 +1,10 @@ nullable; + $valid = false; return null; } diff --git a/src/schema/types/tfloat.php b/src/schema/types/tfloat.php index f1b49be..51fae89 100644 --- a/src/schema/types/tfloat.php +++ b/src/schema/types/tfloat.php @@ -1,10 +1,10 @@ null, "formatter_func" => null, "format" => null, + "size" => null, + "precision" => null, "name" => null, "pkey" => null, "header" => null, @@ -169,8 +172,8 @@ class AssocSchemaTest extends TestCase { "b" => false, ], $array); - // false équivaut à absent - $array = ["s" => false, "i" => false, "b" => null]; + // false équivaut à absent, sauf pour "b" qui est de type bool + $array = ["s" => false, "i" => false, "b" => false]; $schema->getWrapper($array, null, ["ensure_keys" => true]); self::assertSame([ "s" => "", @@ -178,9 +181,11 @@ class AssocSchemaTest extends TestCase { "b" => false, ], $array); - $array = ["s" => false, "i" => false, "b" => null]; + $array = ["s" => false, "i" => false, "b" => false]; $schema->getWrapper($array, null, ["ensure_keys" => false]); - self::assertSame([], $array); + self::assertSame([ + "b" => false, + ], $array); } const STRING_SCHEMA = [ @@ -363,4 +368,29 @@ class AssocSchemaTest extends TestCase { $schema->getWrapper($array); }); } + + function testMessage() { + $schema = new AssocSchema([ + "rs" => ["string", "required" => true], + "i" => ["int"], + ]); + + $value = []; + $result = $schema->getWrapper($value, null, ["throw" => false])->getResult(null); + $expectedMessage = <<message); + + $value = [ + "rs" => null, + "i" => "abc", + ]; + $result = $schema->getWrapper($value, null, ["throw" => false])->getResult(null); + $expectedMessage = <<message); + } } diff --git a/tests/schema/_scalar/ScalarSchemaTest.php b/tests/schema/_scalar/ScalarSchemaTest.php index 916fba5..70714dc 100644 --- a/tests/schema/_scalar/ScalarSchemaTest.php +++ b/tests/schema/_scalar/ScalarSchemaTest.php @@ -19,6 +19,8 @@ class ScalarSchemaTest extends TestCase { "messages" => null, "formatter_func" => null, "format" => null, + "size" => null, + "precision" => null, "" => [ "scalar", "compute_func" => null, From 84bad2be0c680551d7c8d00a0062a12277e0db55 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sat, 19 Apr 2025 07:49:15 +0400 Subject: [PATCH 16/19] modifs.mineures sans commentaires --- src/schema/_assoc/AssocWrapper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 014507b..dddb067 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -109,8 +109,9 @@ class AssocWrapper extends Wrapper { $keyWrapper->analyze($params); if ($keyWrapper->isValid()) continue; $what = ref_analyze::INVALID; - #XXX utiliser si possible la description ou une autre valeur "user-friendly" - # possibilité de sélectionner la valeur à utiliser dans $params? + #XXX pour $prefix, utiliser si possible la description ou une autre valeur + # "user-friendly". possibilité de sélectionner la valeur à utiliser avec + # $params? $prefix = $key; if (!$keyWrapper->isPresent()) { $result->addMissingMessage($keyWrapper, $prefix); From 3933fd1e72b439f3f43e4b207d272aa43f038051 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 22 Apr 2025 18:54:21 +0400 Subject: [PATCH 17/19] corrections sur les controles --- nur_src/v/bs3/fo/Form.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nur_src/v/bs3/fo/Form.php b/nur_src/v/bs3/fo/Form.php index c70b2f6..7dbbc14 100644 --- a/nur_src/v/bs3/fo/Form.php +++ b/nur_src/v/bs3/fo/Form.php @@ -599,16 +599,16 @@ class Form extends ComponentPrintable implements IParametrable, ArrayAccess, Cou /** @var ?array */ protected $hiddenControls; - function addHiddenControl($control, ?string $name=null): self { - A::set($this->hiddenControls, $name, $control); + function addHiddenControl($control, ?string $id=null): self { + A::set($this->hiddenControls, $id, $control); return $this; } /** @var ?array */ protected $controls; - function addControl($control, ?string $name=null): self { - A::set($this->controls, $name, $control); + function addControl($control, ?string $id=null): self { + A::set($this->controls, $id, $control); return $this; } @@ -660,7 +660,8 @@ class Form extends ComponentPrintable implements IParametrable, ArrayAccess, Cou $param["value"] = $value; #XXX en attendant le formattage ci-dessus, forcer la format texte pour que # la comparaison puisse se faire - $param["checked"] = strval($currentValue) === strval($value); + #XXX si $name est un tableau e.g values[] le test ci-dessous ne fonctionne pas + $param["checked"] ??= strval($currentValue) === strval($value); break; case self::NV: if ($value === null) $value = $this->get($key, $default); @@ -672,7 +673,7 @@ class Form extends ComponentPrintable implements IParametrable, ArrayAccess, Cou if ($params === null) $params = $param; else A::update_n($params, $param); - return [new $controlClass($this, $params), $name]; + return [new $controlClass($this, $params), $key]; } private function _prepareControls(): ?array { From 3b13ef126cf36c9f3b15496303667feb4287039f Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 22 Apr 2025 18:54:38 +0400 Subject: [PATCH 18/19] =?UTF-8?q?possiblit=C3=A9=20de=20forcer=20la=20supp?= =?UTF-8?q?ression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nur_src/b/io/FileCachedValue.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nur_src/b/io/FileCachedValue.php b/nur_src/b/io/FileCachedValue.php index c988b36..66aff97 100644 --- a/nur_src/b/io/FileCachedValue.php +++ b/nur_src/b/io/FileCachedValue.php @@ -287,10 +287,10 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun } /** supprimer le fichier s'il a expiré */ - function deleteExpired(): bool { + function deleteExpired(bool $force=false): bool { try { - if ($this->shouldUpdate()) { - unlink($this->ppFile); + if ($force || $this->shouldUpdate()) { + @unlink($this->ppFile); return true; } } finally { From 2d73f4d234cc4ecfe2dd38e4eb701c692d0063d6 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 22 Apr 2025 18:54:45 +0400 Subject: [PATCH 19/19] documenter showmorePlugin --- nur_src/v/plugins/showmorePlugin.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/nur_src/v/plugins/showmorePlugin.php b/nur_src/v/plugins/showmorePlugin.php index b5dbb88..483a011 100644 --- a/nur_src/v/plugins/showmorePlugin.php +++ b/nur_src/v/plugins/showmorePlugin.php @@ -5,6 +5,23 @@ use nur\v\BasePlugin; use nur\v\v; use nur\v\vo; +/** + * Class showmorePlugin: un outil pour masquer par défaut un panneau de détails + * et donner la possibilité à l'utilisateur de l'afficher + * + * s'utilise de cette façon: + *
+ * $sm = new showmorePlugin();
+ * // le tout doit être dans le container startc-endc
+ * $sm->printStartc();
+ * // l'invite contient un lien pour afficher le panneau caché
+ * $sm->printInvite();
+ * // le panneau caché est dans le container startp-endp
+ * $sm->printStartp();
+ * $sm->printEndp();
+ * $sm->printEndc();
+ * 
+ */ class showmorePlugin extends BasePlugin { const HAVE_JQUERY = true;