From 84df1b78b83a64bd3ba06246a54782a251d15187 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 17 Mar 2025 17:23:59 +0400 Subject: [PATCH 01/55] deps de dev --- composer.json | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index e88b3e7..9803ead 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,18 @@ "type": "library", "description": "espace de maturation pour les librairies", "repositories": [ + { + "type": "path", + "url": "../nulib" + }, + { + "type": "path", + "url": "../nulib-spout" + }, + { + "type": "path", + "url": "../nulib-phpss" + }, { "type": "composer", "url": "https://repos.univ-reunion.fr/composer" @@ -18,9 +30,9 @@ "php": "^8.2" }, "require-dev": { - "nulib/php": "^0.4.0p82", - "nulib/spout": "^0.4.0p82", - "nulib/phpss": "^0.4.0p82", + "nulib/php": "^8.2-dev", + "nulib/spout": "^8.2-dev", + "nulib/phpss": "^8.2-dev", "nulib/tests": "^8.2", "ext-posix": "*", "ext-pcntl": "*", From 62987d576e0271b07ba0739b77c3d3e1b4eb89f4 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 17 Mar 2025 17:23:44 +0400 Subject: [PATCH 02/55] Init changelog & version 0.4.1p82 --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 6055589..f74bd64 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,5 @@ +## Release 0.4.1p82 du 17/03/2025-17:23 + ## Release 0.4.1p74 du 17/03/2025-17:19 * `56fda96` changer le type de variables gérées par EnvConfig From 1feffb6c0f0d63ac109f91dfec9d684b1ad20635 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 18 Mar 2025 10:35:28 +0400 Subject: [PATCH 03/55] modifs.mineures sans commentaires --- src/schema/Schema.php | 35 +++++++++- src/schema/TODO.md | 1 - src/schema/WrapperContext.php | 19 ++++-- src/schema/_scalar/ScalarSchema.php | 32 --------- src/schema/_scalar/ScalarWrapper.php | 99 ++++++++++++++-------------- 5 files changed, 96 insertions(+), 90 deletions(-) diff --git a/src/schema/Schema.php b/src/schema/Schema.php index 02365cb..55f1304 100644 --- a/src/schema/Schema.php +++ b/src/schema/Schema.php @@ -17,6 +17,29 @@ use nur\sery\wip\schema\types\tcontent; use nur\sery\wip\schema\types\tpkey; use nur\sery\wip\schema\types\trawstring; +/** + * Class Schema + * + * @property-read array|IType $type + * @property-read mixed $default + * @property-read string|null $title + * @property-read bool $required + * @property-read bool $nullable + * @property-read string|array|null $desc + * @property-read callable|null $analyzerFunc + * @property-read callable|null $extractorFunc + * @property-read callable|null $parserFunc + * @property-read callable|null $normalizerFunc + * @property-read array|null $messages + * @property-read callable|null $formatterFunc + * @property-read mixed $format + * @property-read array $nature + * @property-read array|null $schema + * @property-read string|int|null $name + * @property-read string|array|null $pkey + * @property-read string|null $header + * @property-read bool|null $computed + */ abstract class Schema implements ArrayAccess { /** * créer le cas échéant une nouvelle instance de {@link Schema} à partir d'une @@ -253,6 +276,8 @@ abstract class Schema implements ArrayAccess { /** retourner true si le schéma est de nature scalaire */ function isScalar(?ScalarSchema &$schema=null): bool { return false; } + abstract protected function newWrapper(): Wrapper; + abstract function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): Wrapper; ############################################################################# @@ -272,7 +297,15 @@ abstract class Schema implements ArrayAccess { throw AccessException::read_only(null, $offset); } - const _PROPERTY_PKEYS = []; + const _PROPERTY_PKEYS = [ + "analyzerFunc" => "analyzer_func", + "extractorFunc" => "extractor_func", + "parserFunc" => "parser_func", + "normalizerFunc" => "normalizer_func", + "formatterFunc" => "formatter_func", + "nature" => ["", 0], + ]; + function __get($name) { $pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name); return cl::pget($this->definition, $pkey); diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 5f50801..46e80ce 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,6 +1,5 @@ # nulib\schema -* instance de WrapperContext directement dans le schéma * plus de {key} ni {orig} dans messages * les messages standard ne sont utilisés que s'il n'y a pas de message dans l'exception diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index 5ee0d37..071ed7b 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -5,26 +5,31 @@ use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; class WrapperContext { - function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) { + function __construct(Schema $schema, Wrapper $wrapper, ?Input $input, $valueKey, Result $result) { $this->schema = $schema; $this->wrapper = $wrapper; - $this->input = $input; - $this->result = $result; + if ($input !== null) $this->input = $input; + $this->valueKey = $valueKey; $this->type = null; + $this->result = $result; $this->origValue = null; $this->value = null; - $this->valueKey = $valueKey; } + /** schéma de la valeur */ public Schema $schema; + /** instance de Wrapper associé à ce contexte */ public Wrapper $wrapper; + /** source et destination de la valeur */ public Input $input; - public Result $result; + /** @var string|int|null clé de la valeur dans le tableau destination */ + public $valueKey; + /** type de la valeur après analyse */ public ?IType $type; + /** résultat de l'analyse de la valeur */ + public Result $result; /** @var mixed */ public $origValue; /** @var mixed */ public $value; - /** @var int|string|null */ - public $valueKey; } diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index a4c11bf..44e2ac5 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -8,26 +8,6 @@ use nur\sery\wip\schema\Wrapper; /** * Class ScalarSchema - * - * @property-read array|IType $type - * @property-read mixed $default - * @property-read string|null $title - * @property-read bool $required - * @property-read bool $nullable - * @property-read string|array|null $desc - * @property-read callable|null $analyzerFunc - * @property-read callable|null $extractorFunc - * @property-read callable|null $parserFunc - * @property-read callable|null $normalizerFunc - * @property-read array|null $messages - * @property-read callable|null $formatterFunc - * @property-read mixed $format - * @property-read array $nature - * @property-read array|null $schema - * @property-read string|int|null $name - * @property-read string|array|null $pkey - * @property-read string|null $header - * @property-read bool|null $composite */ class ScalarSchema extends Schema { /** @var array meta-schema d'un schéma de nature scalaire */ @@ -97,16 +77,4 @@ class ScalarSchema extends Schema { if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); return $wrapper->reset($value, $valueKey, $verifix); } - - ############################################################################# - # key & properties - - const _PROPERTY_PKEYS = [ - "analyzerFunc" => "analyzer_func", - "extractorFunc" => "extractor_func", - "parserFunc" => "parser_func", - "normalizerFunc" => "normalizer_func", - "formatterFunc" => "formatter_func", - "nature" => ["", 0], - ]; } diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 0ea9596..5bcb847 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -19,35 +19,21 @@ class ScalarWrapper extends Wrapper { # c'est une initialisation sans conséquences $throw = true; } + $this->context = new WrapperContext($schema, $this, null, null, new ScalarResult()); $this->verifix = $verifix; $this->throw = $throw ?? false; - $this->schema = $schema; - $this->result = new ScalarResult(); $this->reset($value, $valueKey); $this->throw = $throw ?? true; } function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; } + protected WrapperContext $context; + protected bool $verifix; protected bool $throw; - /** schéma de cette valeur */ - protected ScalarSchema $schema; - - /** source et destination de la valeur */ - protected Input $input; - - /** @var string|int|null clé de la valeur dans le tableau destination */ - protected $valueKey; - - /** type de la valeur après analyse */ - protected ?IType $type; - - /** résultat de l'analyse de la valeur */ - protected ScalarResult $result; - protected function newInput(&$value): Input { return new Input($value); } @@ -55,9 +41,9 @@ class ScalarWrapper extends Wrapper { function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper { if ($value instanceof Input) $input = $value; else $input = $this->newInput($value); - $this->input = $input; - $this->valueKey = $valueKey; - $this->type = null; + $this->context->input = $input; + $this->context->valueKey = $valueKey; + $this->context->type = null; $this->analyze(); if ($verifix ?? $this->verifix) $this->verifix(); return $this; @@ -74,7 +60,8 @@ class ScalarWrapper extends Wrapper { } /** analyser la valeur et résoudre son type */ - protected function analyze0(WrapperContext $context): int { + protected function analyze0(): int { + $context = $this->context; /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; @@ -112,7 +99,7 @@ class ScalarWrapper extends Wrapper { $args = $name; $name = $key; } - $type = types::get($schema->nullable, $name, $args, $this->schema->getDefinition()); + $type = types::get($schema->nullable, $name, $args, $schema->getDefinition()); if ($firstType === null) $firstType = $type; $types[] = $type; if ($type->isAvailable($input, $valueKey)) { @@ -166,17 +153,19 @@ class ScalarWrapper extends Wrapper { } protected function analyze(): int { - $schema = $this->schema; - $input = $this->input; - $valueKey = $this->valueKey; - $result = $this->result; + $context = $this->context; + /** @var ScalarSchema $schema */ + $schema = $context->schema; + $input = $context->input; + $valueKey = $context->valueKey; + /** @var ScalarResult $result */ + $result = $context->result; $result->reset(); - $context = new WrapperContext($schema, $this, $input, $valueKey, $result); /** @var func $analyzerFunc */ $analyzerFunc = $schema->analyzerFunc; if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context]); - else $what = $this->analyze0($context); + else $what = $this->analyze0(); if ($what !== ref_analyze::STRING) return $what; $value = $context->value; @@ -212,20 +201,27 @@ class ScalarWrapper extends Wrapper { } function verifix(?bool $throw=null): bool { - $result = $this->result; - $valueKey = $this->valueKey; + $context = $this->context; + /** @var ScalarSchema $schema */ + $schema = $context->schema; + $input = $context->input; + $valueKey = $context->valueKey; + /** @var ScalarResult $result */ + $result = $context->result; + + $verifix = false; $modified = false; if ($result->resultAvailable) { if ($result->null) { # forcer la valeur null, parce que la valeur actuelle est peut-être une # valeur assimilée à null - $this->input->set(null, $valueKey); + $input->set(null, $valueKey); } elseif ($result->valid && !$result->normalized) { $normalizedValue = $result->normalizedValue; if ($normalizedValue !== null) { # la valeur normalisée est disponible - $this->input->set($normalizedValue); + $input->set($normalizedValue); $result->normalizedValue = null; $modified = true; } else { @@ -238,75 +234,80 @@ class ScalarWrapper extends Wrapper { } if ($verifix) { - $value = $this->input->get($valueKey); - $schema = $this->schema; + $value = $input->get($valueKey); /** @var func $normalizerFunc */ $normalizerFunc = $schema->normalizerFunc; if ($normalizerFunc !== null) { - $context = new WrapperContext($schema, $this, $this->input, $valueKey, $result); + $context = new WrapperContext($schema, $this, $input, $valueKey, $result); $orig = $value; $value = $normalizerFunc->invoke([$orig, $context]); $modified = $value !== $orig; } else { - $modified = $this->type->verifix($value, $result, $this->schema); + $modified = $this->type->verifix($value, $result, $schema); } - if ($result->valid) $this->input->set($value, $valueKey); + if ($result->valid) $input->set($value, $valueKey); } if (!$result->valid) $result->throw($throw ?? $this->throw); return $modified; } function getResult(): ScalarResult { - return $this->result; + /** @var ScalarResult $result */ + $result = $this->context->result; + return $result; } function isPresent(): bool { - return $this->result->present; + return $this->context->result->present; } function getType(): IType { - return $this->type; + return $this->context->type; } function isAvailable(): bool { - return $this->result->available; + return $this->context->result->available; } function isValid(): bool { - return $this->result->valid; + return $this->context->result->valid; } function isNormalized(): bool { - return $this->result->normalized; + return $this->context->result->normalized; } function get($default=null) { - if ($this->result->available) return $this->input->get($this->valueKey); + $context = $this->context; + if ($context->result->available) return $context->input->get($context->valueKey); else return $default; } function set($value, ?bool $verifix=null): ScalarWrapper { - $this->input->set($value, $this->valueKey); + $context = $this->context; + $context->input->set($value, $context->valueKey); $this->analyze(); if ($verifix ?? $this->verifix) $this->verifix(); return $this; } function unset(?bool $verifix=null): ScalarWrapper { - $this->input->unset($this->valueKey); + $context = $this->context; + $context->input->unset($context->valueKey); $this->analyze(); if ($verifix ?? $this->verifix) $this->verifix(); return $this; } function format($format=null): string { - $value = $this->input->get($this->valueKey); + $context = $this->context; + $value = $context->input->get($context->valueKey); /** @var func $formatterFunc */ - $formatterFunc = $this->schema->formatterFunc; + $formatterFunc = $context->schema->formatterFunc; if ($formatterFunc !== null) { # la fonction formatter n'a pas forcément accès au format de la définition # le lui fournir ici - $format ??= $this->schema->format; + $format ??= $context->schema->format; return $formatterFunc->invoke([$value, $format]); } else { # on assume que le type a été initialisé avec le format de la définition From bb311708d7b5ef8c45cc22da941c04c5d3372e49 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 18 Mar 2025 10:43:43 +0400 Subject: [PATCH 04/55] modifs.mineures sans commentaires --- src/schema/_scalar/ScalarResult.php | 37 +++++++---------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index cb568d5..1dbd2b6 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -46,19 +46,6 @@ class ScalarResult extends Result { $this->result[$name] = $value; } - protected static function replace_key(string &$message, ?string $key): void { - if ($key) { - $message = str_replace("{key}", $key, $message); - } else { - $message = str_replace("{key}: ", "", $message); - $message = str_replace("cette valeur", "la valeur", $message); - } - } - - protected static function replace_orig(string &$message, $origValue): void { - $message = str_replace("{orig}", strval($origValue), $message); - } - protected function getMessage(string $key, ScalarSchema $schema): string { $message = cl::get($schema->messages, $key); if ($message !== null) return $message; @@ -75,10 +62,8 @@ class ScalarResult extends Result { $this->normalized = true; return ref_analyze::NORMALIZED; } else { - $messageKey = $this->messageKey = "missing"; - $message = $this->getMessage($messageKey, $schema); - self::replace_key($message, $schema->name); - $this->message = $message; + $this->messageKey = $messageKey = "missing"; + $this->message = $this->getMessage($messageKey, $schema); return ref_analyze::MISSING; } } @@ -93,10 +78,8 @@ class ScalarResult extends Result { $this->normalized = true; return ref_analyze::NORMALIZED; } else { - $messageKey = $this->messageKey = "unavailable"; - $message = $this->getMessage($messageKey, $schema); - self::replace_key($message, $schema->name); - $this->message = $message; + $this->messageKey = $messageKey = "unavailable"; + $this->message = $this->getMessage($messageKey, $schema); return ref_analyze::UNAVAILABLE; } } @@ -111,10 +94,8 @@ class ScalarResult extends Result { $this->normalized = true; return ref_analyze::NORMALIZED; } else { - $messageKey = $this->messageKey = "null"; - $message = $this->getMessage($messageKey, $schema); - self::replace_key($message, $schema->name); - $this->message = $message; + $this->messageKey = $messageKey = "null"; + $this->message = $this->getMessage($messageKey, $schema); return ref_analyze::NULL; } } @@ -126,13 +107,11 @@ class ScalarResult extends Result { $this->null = false; $this->valid = false; $this->origValue = $value; - $messageKey = $this->messageKey = "invalid"; + $this->messageKey = $messageKey = "invalid"; $message = $this->getMessage($messageKey, $schema); - self::replace_key($message, $schema->name); - self::replace_orig($message, $schema->orig); if ($t !== null) { $tmessage = ValueException::get_message($t); - if ($tmessage) $message .= ": $tmessage"; + if ($tmessage) $message = $tmessage; } $this->message = $message; return ref_analyze::INVALID; From 91e6c0dcd2d1eec7b176f77e58fc19696ea451ff Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 18 Mar 2025 10:48:50 +0400 Subject: [PATCH 05/55] modifs.mineures sans commentaires --- src/schema/Result.php | 5 ++++- src/schema/_scalar/ScalarResult.php | 13 +++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/schema/Result.php b/src/schema/Result.php index 3ccb261..46f08ee 100644 --- a/src/schema/Result.php +++ b/src/schema/Result.php @@ -5,6 +5,7 @@ use IteratorAggregate; use nur\sery\wip\schema\_assoc\AssocResult; use nur\sery\wip\schema\_list\ListResult; use nur\sery\wip\schema\_scalar\ScalarResult; +use Throwable; /** * Class Result: résultat de l'analyse ou de la normalisation d'une valeur @@ -17,6 +18,8 @@ use nur\sery\wip\schema\_scalar\ScalarResult; * @property bool $normalized si la valeur est valide, est-elle normalisée? * @property string|null $messageKey clé de message si la valeur n'est pas valide * @property string|null $message message si la valeur n'est pas valide + * @property Throwable|null $exception l'exception qui a fait échouer la + * validation le cas échéant * @property string|null $origValue valeur originale avant extraction et analyse * @property mixed|null $normalizedValue la valeur normalisée si elle est * disponible, null sinon. ce champ est utilisé comme optimisation si la valeur @@ -26,7 +29,7 @@ abstract class Result implements IteratorAggregate { const KEYS = [ "resultAvailable", "present", "available", "null", "valid", "normalized", - "messageKey", "message", + "messageKey", "message", "exception", "origValue", "normalizedValue", ]; diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index 1dbd2b6..572d936 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -100,7 +100,7 @@ class ScalarResult extends Result { } } - function setInvalid($value, ScalarSchema $schema, ?Throwable $t=null): int { + function setInvalid($value, ScalarSchema $schema, ?Throwable $exception=null): int { $this->resultAvailable = true; $this->present = true; $this->available = true; @@ -109,11 +109,12 @@ class ScalarResult extends Result { $this->origValue = $value; $this->messageKey = $messageKey = "invalid"; $message = $this->getMessage($messageKey, $schema); - if ($t !== null) { - $tmessage = ValueException::get_message($t); + if ($exception !== null) { + $tmessage = ValueException::get_message($exception); if ($tmessage) $message = $tmessage; } $this->message = $message; + $this->exception = $exception; return ref_analyze::INVALID; } @@ -138,6 +139,10 @@ class ScalarResult extends Result { } function throw(bool $throw): void { - if ($throw) throw new ValueException($this->message); + if ($throw) { + $exception = $this->exception; + if ($exception !== null) throw $exception; + else throw new ValueException($this->message); + } } } From 189c7aba6832fac661a2741cb67c234dbdcbf056 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 18 Mar 2025 13:30:02 +0400 Subject: [PATCH 06/55] modifs.mineures sans commentaires --- src/schema/Schema.php | 7 ++ src/schema/TODO.md | 7 +- src/schema/Wrapper.php | 17 +++ src/schema/WrapperContext.php | 16 ++- src/schema/_assoc/AssocResult.php | 33 +++--- src/schema/_assoc/AssocSchema.php | 25 ++++- src/schema/_assoc/AssocWrapper.php | 113 ++++++++++---------- src/schema/_assoc/AssocWrapperContext.php | 21 ++++ src/schema/_list/ListSchema.php | 17 ++- src/schema/_scalar/ScalarResult.php | 5 +- src/schema/_scalar/ScalarSchema.php | 12 +++ src/schema/_scalar/ScalarWrapper.php | 59 ++++------ tests/wip/schema/_assoc/AssocSchemaTest.php | 5 +- 13 files changed, 206 insertions(+), 131 deletions(-) create mode 100644 src/schema/_assoc/AssocWrapperContext.php diff --git a/src/schema/Schema.php b/src/schema/Schema.php index 55f1304..a7721f4 100644 --- a/src/schema/Schema.php +++ b/src/schema/Schema.php @@ -269,6 +269,13 @@ abstract class Schema implements ArrayAccess { return $this->_definition; } + /** + * retourner la liste des clés valides pour l'accès aux valeurs et résultats + */ + 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 */ diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 46e80ce..73b4aca 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,15 +1,12 @@ # nulib\schema -* plus de {key} ni {orig} dans messages - * les messages standard ne sont utilisés que s'il n'y a pas de message dans - l'exception - * si instance de UserException, prendre le message "non technique" pour - résultat * valeurs composite/computed * analyse / vérification de la valeur complète après calcul du résultat, si tous les résultats sont bons * calcul des valeurs composites/computed par une fonction avant/après l'analyse globale si résultat ok + * 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 * ScalarSchema::from_property() diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index d8cafed..f567702 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -3,6 +3,7 @@ namespace nur\sery\wip\schema; use ArrayAccess; use IteratorAggregate; +use nulib\php\func; use nur\sery\wip\schema\_assoc\AssocWrapper; use nur\sery\wip\schema\_list\ListWrapper; use nur\sery\wip\schema\_scalar\ScalarWrapper; @@ -67,6 +68,22 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { /** supprimer la valeur */ abstract function unset(): self; + protected function _format(WrapperContext $context, $format=null): string { + $value = $context->input->get($context->valueKey); + /** @var func $formatterFunc */ + $formatterFunc = $context->schema->formatterFunc; + if ($formatterFunc !== null) { + # la fonction formatter n'a pas forcément accès au format de la définition + # le lui fournir ici + $format ??= $context->schema->format; + return $formatterFunc->invoke([$value, $format, $context, $this]); + } else { + # on assume que le type a été initialisé avec le format de la définition + # le cas échéant + return $context->type->format($value, $format); + } + } + /** formatter la valeur pour affichage */ abstract function format($format=null): string; diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index 071ed7b..440b8c6 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -5,21 +5,29 @@ use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; class WrapperContext { - function __construct(Schema $schema, Wrapper $wrapper, ?Input $input, $valueKey, Result $result) { + function __construct(Schema $schema, ?Input $input, $valueKey, ?Result $result, ?array $params) { + $this->params = $params; + $this->verifix = $params["verifix"] ?? true; + $this->throw = $params["throw"] ?? null; + $this->schema = $schema; - $this->wrapper = $wrapper; + //$this->wrapper = $wrapper; if ($input !== null) $this->input = $input; $this->valueKey = $valueKey; $this->type = null; - $this->result = $result; + if ($result !== null) $this->result = $result; $this->origValue = null; $this->value = null; } + public ?array $params; + public bool $verifix; + public ?bool $throw; + /** schéma de la valeur */ public Schema $schema; /** instance de Wrapper associé à ce contexte */ - public Wrapper $wrapper; + //public Wrapper $wrapper; /** source et destination de la valeur */ public Input $input; /** @var string|int|null clé de la valeur dans le tableau destination */ diff --git a/src/schema/_assoc/AssocResult.php b/src/schema/_assoc/AssocResult.php index 8ac0c77..76a2a74 100644 --- a/src/schema/_assoc/AssocResult.php +++ b/src/schema/_assoc/AssocResult.php @@ -5,41 +5,38 @@ use nulib\ValueException; use nur\sery\wip\schema\Result; class AssocResult extends Result { - function __construct(Result $arrayResult, array &$keyResults) { - $this->arrayResult = $arrayResult; - $this->keyResults =& $keyResults; - $this->result =& $this->arrayResult; + function __construct(AssocWrapperContext $context) { + $this->context = $context; parent::__construct(); } function isAssoc(?AssocResult &$result=null): bool { $result = $this; return true;} - protected Result $arrayResult; - - /** @var Result[] */ - protected array $keyResults; + protected AssocWrapperContext $context; function getKeys(): array { - return array_keys($this->keyResults); + return $this->context->keys; } protected Result $result; - function select($key): Result { + function select($key): AssocResult { + $context = $this->context; 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); + $this->result = $context->arrayResult; + return $this; } + $wrapper = $context->keyWrappers[$key] ?? null; + if ($wrapper === null) throw ValueException::invalid_key($key); + $this->result = $wrapper->getResult(); return $this; } function reset(): void { - $this->arrayResult->reset(); - foreach ($this->keyResults as $result) { - $result->reset(); + $context = $this->context; + $context->arrayResult->reset(); + foreach ($context->keyWrappers as $wrapper) { + $wrapper->getResult()->reset(); } } diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index cabcc38..017a6fd 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -3,6 +3,8 @@ namespace nur\sery\wip\schema\_assoc; use nulib\cl; use nulib\ref\schema\ref_schema; +use nulib\ValueException; +use nur\sery\wip\schema\_scalar\ScalarWrapper; use nur\sery\wip\schema\Schema; use nur\sery\wip\schema\Wrapper; @@ -50,6 +52,11 @@ class AssocSchema extends Schema { self::_ensure_schema_instances($definition); } $this->definition = $definition; + $keys = []; + foreach ($definition["schema"] as $key => $schema) { + if (!$schema["computed"]) $keys[] = $key; + } + $this->keys = $keys; } function isAssoc(?AssocSchema &$schema=null): bool { @@ -57,12 +64,28 @@ class AssocSchema extends Schema { return true; } + protected array $keys; + + function getKeys(): array { + return $this->keys; + } + + function getSchema($key): Schema { + if ($key === null) return $this; + $schema = $this->definition["schema"][$key] ?? null; + if ($schema === null) throw ValueException::invalid_key($key); + return $schema; + } + protected function newWrapper(): AssocWrapper { return new AssocWrapper($this); } function getWrapper(&$array=null, $arrayKey=null, ?Wrapper &$wrapper=null): AssocWrapper { + # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception + # cf le code similaire dans ScalarWrapper::__construct() + $verifix = $array !== null || $wrapper !== null; if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper(); - return $wrapper->reset($array, $arrayKey); + return $wrapper->reset($array, $arrayKey, $verifix); } } diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index ea2981c..5ce88b1 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -3,59 +3,43 @@ namespace nur\sery\wip\schema\_assoc; use nulib\ValueException; use nur\sery\wip\schema\_scalar\ScalarResult; -use nur\sery\wip\schema\_scalar\ScalarWrapper; use nur\sery\wip\schema\input\Input; -use nur\sery\wip\schema\Result; use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; +use nur\sery\wip\schema\WrapperContext; class AssocWrapper extends Wrapper { function __construct(AssocSchema $schema, &$array=null, $arrayKey=null, ?array $params=null) { - $verifix = $params["verifix"] ?? true; - $throw = $params["throw"] ?? null; + $definitionSchema = $schema->getDefinition()["schema"]; + $keys = $schema->getKeys(); + $keyTypes = []; + $keyWrappers = []; + foreach ($keys as $key) { + $keyTypes[$key] = null; + $keyWrappers[$key] = $schema->getSchema($key)->getWrapper(); + } + $this->context = $context = new AssocWrapperContext($schema, null, null, null, $params); + $context->arrayResult = new ScalarResult(); + $context->keys = $keys; + $context->keyTypes = $keyTypes; + $context->keyWrappers = $keyWrappers; + $context->result = new AssocResult($context); + + $throw = $context->throw; if ($array !== null && $throw === null) { # Si $value est null, ne pas lancer d'exception, parce qu'on considère que # c'est une initialisation sans conséquences $throw = true; } - $this->schema = $schema; - $this->verifix = $verifix; - $this->throw = $throw ?? false; - $this->result = new AssocResult(); + $context->throw = $throw ?? false; $this->reset($array, $arrayKey); - $this->throw = $throw ?? true; + $context->throw = $throw ?? true; } function isAssoc(?AssocWrapper &$wrapper=null): bool { $wrapper = $this; return true; } - protected bool $verifix; - - protected bool $throw; - - /** schéma de ce tableau */ - protected AssocSchema $schema; - - /** source et destination de la valeur */ - protected Input $input; - - /** @var string|int|null clé du tableau dans le tableau destination */ - protected $arrayKey; - - protected IType $arrayType; - - protected ScalarResult $arrayResult; - - /** @var IType[] */ - protected array $keyTypes; - - /** @var Result[] */ - protected array $keyResults; - - protected AssocResult $result; - - protected ?array $keys; - - protected ?array $wrappers; + /** @var AssocWrapperContext */ + protected WrapperContext $context; protected function newInput(&$value): Input { return new Input($value); @@ -64,73 +48,84 @@ class AssocWrapper extends Wrapper { function reset(&$array, $arrayKey=null, ?bool $verifix=null): Wrapper { if ($array instanceof Input) $input = $array; else $input = $this->newInput($array); - $this->input = $input; - $this->arrayKey = $arrayKey; + $context = $this->context; + $context->input = $input; + $context->valueKey = $arrayKey; $this->analyze(); - if ($verifix ?? $this->verifix) $this->verifix(); + if ($verifix ?? $context->verifix) $this->verifix(); return $this; } function getKeys(): array { - return $this->keys; + return $this->context->keys; } - function select($key=null): ScalarWrapper { - $wrapper = $this->wrappers[$key] ?? null; - if ($key !== null) return $wrapper; - throw ValueException::invalid_key($key); + /** @param string|int|null $key */ + function select($key=null): Wrapper { + if ($key === null) return $this; + $wrapper = $this->context->keyWrappers[$key] ?? null; + if ($wrapper === null) throw ValueException::invalid_key($key); + return $wrapper; } - /** @param Result[] $results */ - function verifix(?bool $throw=null, ?array &$results=null): bool { + protected function analyze(): int { + return 0; #XXX } + function verifix(?bool $throw=null): bool { + return false; #XXX + } function getResult(): AssocResult { - return $this->result; + /** @var AssocResult $result */ + $result = $this->context->result; + return $result; } function isPresent(): bool { - return $this->result->present; + return $this->context->result->present; } function getType(): IType { - return $this->arrayType; + return $this->context->type; } function isAvailable(): bool { - return $this->result->available; + return $this->context->result->available; } function isValid(): bool { - return $this->result->valid; + return $this->context->result->valid; } function isNormalized(): bool { - return $this->result->normalized; + return $this->context->result->normalized; } function get($default=null) { - if ($this->result->available) return $this->input->get($this->arrayKey); + $context = $this->context; + if ($context->result->available) return $context->input->get($context->valueKey); else return $default; } function set($value, ?bool $verifix=null): AssocWrapper { - $this->input->set($value, $this->arrayKey); + $context = $this->context; + $context->input->set($value, $context->valueKey); $this->analyze(); - if ($verifix ?? $this->verifix) $this->verifix(); + if ($verifix ?? $context->verifix) $this->verifix(); return $this; } function unset(?bool $verifix=null): AssocWrapper { - $this->input->unset($this->arrayKey); + $context = $this->context; + $context->input->unset($context->valueKey); $this->analyze(); - if ($verifix ?? $this->verifix) $this->verifix(); + if ($verifix ?? $context->verifix) $this->verifix(); return $this; } function format($format = null): string { - // TODO: Implement format() method. + return $this->_format($this->context, $format); } function ensureKeys(): bool { diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php new file mode 100644 index 0000000..ed25436 --- /dev/null +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -0,0 +1,21 @@ +newWrapper(); - return $wrapper->reset($value, $valueKey); + return $wrapper->reset($value, $valueKey, $verifix); } } diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index 572d936..cc28149 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -15,7 +15,7 @@ class ScalarResult extends Result { function isScalar(?ScalarResult &$result=null): bool { $result = $this; return true; } function getKeys(): array { - return [null]; + return ScalarSchema::KEYS; } function select($key): Result { @@ -23,8 +23,7 @@ class ScalarResult extends Result { return $this; } - /** @var array */ - protected $result; + protected array $result; function reset(): void { $this->result = array_merge( diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 44e2ac5..8ff264b 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -2,6 +2,7 @@ namespace nur\sery\wip\schema\_scalar; use nulib\ref\schema\ref_schema; +use nulib\ValueException; use nur\sery\wip\schema\Schema; use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; @@ -66,6 +67,17 @@ class ScalarSchema extends Schema { 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; + } + protected function newWrapper(): ScalarWrapper { return new ScalarWrapper($this); } diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 5bcb847..3ff48fb 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -12,28 +12,23 @@ use nur\sery\wip\schema\Wrapper; class ScalarWrapper extends Wrapper { function __construct(ScalarSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { - $verifix = $params["verifix"] ?? true; - $throw = $params["throw"] ?? null; + $this->context = $context = new WrapperContext($schema, null, null, new ScalarResult(), $params); + + $throw = $context->throw; if ($value !== null && $throw === null) { # Si $value est null, ne pas lancer d'exception, parce qu'on considère que # c'est une initialisation sans conséquences $throw = true; } - $this->context = new WrapperContext($schema, $this, null, null, new ScalarResult()); - $this->verifix = $verifix; - $this->throw = $throw ?? false; + $context->throw = $throw ?? false; $this->reset($value, $valueKey); - $this->throw = $throw ?? true; + $context->throw = $throw ?? true; } function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; } protected WrapperContext $context; - protected bool $verifix; - - protected bool $throw; - protected function newInput(&$value): Input { return new Input($value); } @@ -41,16 +36,17 @@ class ScalarWrapper extends Wrapper { function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper { if ($value instanceof Input) $input = $value; else $input = $this->newInput($value); - $this->context->input = $input; - $this->context->valueKey = $valueKey; - $this->context->type = null; + $context = $this->context; + $context->input = $input; + $context->valueKey = $valueKey; + $context->type = null; $this->analyze(); - if ($verifix ?? $this->verifix) $this->verifix(); + if ($verifix ?? $context->verifix) $this->verifix(); return $this; } function getKeys(): array { - return [null]; + return ScalarSchema::KEYS; } /** @param string|int|null $key */ @@ -164,7 +160,7 @@ class ScalarWrapper extends Wrapper { /** @var func $analyzerFunc */ $analyzerFunc = $schema->analyzerFunc; - if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context]); + if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context, $this]); else $what = $this->analyze0(); if ($what !== ref_analyze::STRING) return $what; @@ -172,7 +168,7 @@ class ScalarWrapper extends Wrapper { try { /** @var func $extractorFunc */ $extractorFunc = $schema->extractorFunc; - if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context]); + if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context, $this]); else $extracted = $context->type->extract($value); $context->value = $extracted; } catch (ValueException $e) { @@ -183,7 +179,7 @@ class ScalarWrapper extends Wrapper { try { /** @var func $parserFunc */ $parserFunc = $schema->parserFunc; - if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context]); + if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context, $this]); else $parsed = $context->type->parse($extracted); $context->value = $parsed; } catch (ValueException $e) { @@ -209,7 +205,6 @@ class ScalarWrapper extends Wrapper { /** @var ScalarResult $result */ $result = $context->result; - $verifix = false; $modified = false; if ($result->resultAvailable) { @@ -238,16 +233,15 @@ class ScalarWrapper extends Wrapper { /** @var func $normalizerFunc */ $normalizerFunc = $schema->normalizerFunc; if ($normalizerFunc !== null) { - $context = new WrapperContext($schema, $this, $input, $valueKey, $result); $orig = $value; - $value = $normalizerFunc->invoke([$orig, $context]); + $value = $normalizerFunc->invoke([$orig, $context, $this]); $modified = $value !== $orig; } else { - $modified = $this->type->verifix($value, $result, $schema); + $modified = $context->type->verifix($value, $result, $schema); } if ($result->valid) $input->set($value, $valueKey); } - if (!$result->valid) $result->throw($throw ?? $this->throw); + if (!$result->valid) $result->throw($throw ?? $context->throw); return $modified; } @@ -287,7 +281,7 @@ class ScalarWrapper extends Wrapper { $context = $this->context; $context->input->set($value, $context->valueKey); $this->analyze(); - if ($verifix ?? $this->verifix) $this->verifix(); + if ($verifix ?? $context->verifix) $this->verifix(); return $this; } @@ -295,24 +289,11 @@ class ScalarWrapper extends Wrapper { $context = $this->context; $context->input->unset($context->valueKey); $this->analyze(); - if ($verifix ?? $this->verifix) $this->verifix(); + if ($verifix ?? $context->verifix) $this->verifix(); return $this; } function format($format=null): string { - $context = $this->context; - $value = $context->input->get($context->valueKey); - /** @var func $formatterFunc */ - $formatterFunc = $context->schema->formatterFunc; - if ($formatterFunc !== null) { - # la fonction formatter n'a pas forcément accès au format de la définition - # le lui fournir ici - $format ??= $context->schema->format; - return $formatterFunc->invoke([$value, $format]); - } else { - # on assume que le type a été initialisé avec le format de la définition - # le cas échéant - return $this->type->format($value, $format); - } + return $this->_format($this->context, $format); } } diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index 4ac9fca..8f78dd4 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -90,6 +90,9 @@ class AssocSchemaTest extends TestCase { "name" => "c", "pkey" => "c", "header" => "c", ], ]), $schema->getDefinition()); - yaml::dump($schema->getDefinition()); + //yaml::dump($schema->getDefinition()); + + $wrapper = $schema->getWrapper(); + $wrapper->getKeys(); } } From d148850c1273ebfcf006dce3e94f387dd4a978ef Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 18 Mar 2025 17:37:55 +0400 Subject: [PATCH 07/55] modifs.mineures sans commentaires --- src/schema/Schema.php | 10 +- src/schema/TODO.md | 5 + src/schema/Wrapper.php | 139 +++++++++++++++--- src/schema/WrapperContext.php | 35 +++-- src/schema/_assoc/AssocSchema.php | 16 +- src/schema/_assoc/AssocWrapper.php | 69 +-------- src/schema/_list/ListSchema.php | 4 +- src/schema/_scalar/ScalarSchema.php | 16 +- src/schema/_scalar/ScalarWrapper.php | 101 ++++--------- tests/wip/schema/_assoc/AssocSchemaTest.php | 4 +- tests/wip/schema/_scalar/ScalarSchemaTest.php | 32 ++-- .../wip/schema/_scalar/ScalarWrapperTest.php | 12 +- 12 files changed, 223 insertions(+), 220 deletions(-) diff --git a/src/schema/Schema.php b/src/schema/Schema.php index a7721f4..4d1a422 100644 --- a/src/schema/Schema.php +++ b/src/schema/Schema.php @@ -80,7 +80,7 @@ abstract class Schema implements ArrayAccess { # schéma d'un scalaire quelconque), on ne l'autorise pas ici throw SchemaException::invalid_schema("definition is required"); } - return self::ns($schema, $definition)->getWrapper($value, $valueKey, $wrapper); + return self::ns($schema, $definition)->getWrapper($value, $valueKey, null, $wrapper); } protected static function have_nature(array $definition, ?string &$nature=null): bool { @@ -98,7 +98,7 @@ abstract class Schema implements ArrayAccess { return false; } - protected static function _normalize(&$definition, $definitionKey=null): void { + protected static function _normalize_definition(&$definition, $definitionKey=null): void { if (!is_array($definition)) $definition = [$definition]; # s'assurer que toutes les clés existent avec leur valeur par défaut $index = 0; @@ -192,11 +192,11 @@ abstract class Schema implements ArrayAccess { switch ($nature[0] ?? null) { case "assoc": foreach ($definition["schema"] as $key => &$keydef) { - self::_normalize($keydef, $key); + self::_normalize_definition($keydef, $key); }; unset($keydef); break; case "list": - self::_normalize($definition["schema"]); + self::_normalize_definition($definition["schema"]); break; } } @@ -285,7 +285,7 @@ abstract class Schema implements ArrayAccess { abstract protected function newWrapper(): Wrapper; - abstract function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): Wrapper; + abstract function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): Wrapper; ############################################################################# # key & properties diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 73b4aca..b41abbe 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,5 +1,10 @@ # nulib\schema +* faire PropertyAccess +* si l'argument de Input() est un objet, utiliser PropertyAccess au lieu de KeyAccess +* possibilité de forcer l'un ou l'autre +* ensureKeys() et orderKeys() se fait au niveau de access + * 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/Wrapper.php b/src/schema/Wrapper.php index f567702..7d6361f 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -6,7 +6,9 @@ use IteratorAggregate; use nulib\php\func; use nur\sery\wip\schema\_assoc\AssocWrapper; use nur\sery\wip\schema\_list\ListWrapper; +use nur\sery\wip\schema\_scalar\ScalarResult; use nur\sery\wip\schema\_scalar\ScalarWrapper; +use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; abstract class Wrapper implements ArrayAccess, IteratorAggregate { @@ -14,8 +16,81 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { function isList(?ListWrapper &$wrapper=null): bool { return false; } function isScalar(?ScalarWrapper &$wrapper=null): bool { return false; } - /** spécifier la valeur destination gérée par cet objet */ - abstract function reset(&$value, $valueKey=null, ?bool $verifix=null): self; + protected WrapperContext $context; + + /** changer les paramètres de gestion des valeurs */ + function resetParams(?array $params): void { + $this->context->resetParams($params); + } + + protected function afterModify(?array $params, bool $reset=true): void { + $context = $this->context; + if ($reset) { + $context->type = null; + $context->result->reset(); + $context->analyzed = false; + $context->normalized = false; + } + if ($params["analyze"] ?? $context->analyze) { + $this->analyze($params); + } + if ($context->analyzed) { + if ($params["normalize"] ?? $context->normalize) { + $this->normalize($params); + } + } + } + + protected function newInput(&$value): Input { + return new Input($value); + } + + /** + * spécifier la valeur destination gérée par cet objet. + * + * @param ?array $params paramètres spécifique à cet appel, qui peuvent être + * différent des paramètres par défaut + */ + abstract function reset(&$value, $valueKey=null, ?array $params=null): self; + + /** analyser la valeur */ + abstract protected function _analyze(?array $params): int; + + function analyze(?array $params=null): bool { + $context = $this->context; + $reanalyze = $params["reanalyze"] ?? false; + if ($context->analyzed && !$reanalyze) return false; + + $this->_analyze($params); + $context->analyzed = true; + return true; + } + + /** normaliser la valeur */ + abstract protected function _normalize(?array $params): bool; + + function normalize(?array $params=null): bool { + $context = $this->context; + + // il faut que la valeur soit analysée avant de la normaliser + $this->analyze($params); + if (!$context->analyzed) return false; + + $renormalize = $params["renormalize"] ?? false; + if ($renormalize || !$context->normalized) { + $modified = $this->_normalize($params); + $context->normalized = true; + } else { + $modified = false; + } + + /** @var ScalarResult $result */ + $result = $context->result; + if (!$result->valid) { + $result->throw($params["throw"] ?? $context->throw); + } + return $modified; + } /** * Obtenir la liste des clés valides pour les valeurs accessibles via cet @@ -39,34 +114,60 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } /** - * obtenir le résultat de l'appel d'une des fonctions {@link set()} ou - * {@link unset()} + * obtenir le résultat de l'analyse de la valeur du wrapper sélectionné + * + * 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()} */ - abstract function getResult(): Result; + function getResult(): Result { + return $this->context->result; + } /** retourner true si la valeur existe */ - abstract function isPresent(): bool; + function isPresent(): bool { + return $this->context->result->present; + } /** retourner le type associé à la valeur */ - abstract function getType(): IType; + function getType(): IType { + return $this->context->type; + } /** retourner true si la valeur est disponible */ - abstract function isAvailable(): bool; + function isAvailable(): bool { + return $this->context->result->available; + } /** retourner true si la valeur est valide */ - abstract function isValid(): bool; + function isValid(): bool { + return $this->context->result->valid; + } /** retourner true si la valeur est dans sa forme normalisée */ - abstract function isNormalized(): bool; + function isNormalized(): bool { + return $this->context->result->normalized; + } - /** obtenir la valeur */ - abstract function get($default=null); - /** remplacer la valeur */ - abstract function set($value): self; + function get($default=null) { + $context = $this->context; + if ($context->result->available) return $context->input->get($context->valueKey); + else return $default; + } - /** supprimer la valeur */ - abstract function unset(): self; + function set($value, ?array $params=null): self { + $context = $this->context; + $context->input->set($value, $context->valueKey); + $this->afterModify($params); + return $this; + } + + function unset(?array $params=null): self { + $context = $this->context; + $context->input->unset($context->valueKey); + $this->afterModify($params); + return $this; + } protected function _format(WrapperContext $context, $format=null): string { $value = $context->input->get($context->valueKey); @@ -85,7 +186,9 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } /** formatter la valeur pour affichage */ - abstract function format($format=null): string; + function format($format=null): string { + return $this->_format($this->context, $format); + } ############################################################################# # key & properties @@ -95,7 +198,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } function offsetGet($offset) { - return $this->select($offset); + return $this->select($offset)->get(); } function offsetSet($offset, $value): void { diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index 440b8c6..6e523e4 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -5,39 +5,44 @@ use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; class WrapperContext { - function __construct(Schema $schema, ?Input $input, $valueKey, ?Result $result, ?array $params) { - $this->params = $params; - $this->verifix = $params["verifix"] ?? true; - $this->throw = $params["throw"] ?? null; - + function __construct(Schema $schema, ?Input $input, $valueKey, ?array $params) { + $this->resetParams($params); $this->schema = $schema; - //$this->wrapper = $wrapper; if ($input !== null) $this->input = $input; $this->valueKey = $valueKey; - $this->type = null; - if ($result !== null) $this->result = $result; $this->origValue = null; $this->value = null; + $this->type = null; + $this->result = null; } public ?array $params; - public bool $verifix; + public bool $analyze, $analyzed; + public bool $normalize, $normalized; public ?bool $throw; + function resetParams(?array $params): void { + $this->params = $params; + $this->analyze = $params["analyze"] ?? true; + $this->normalize = $params["normalize"] ?? true; + $this->throw = $params["throw"] ?? true; + } + /** schéma de la valeur */ public Schema $schema; - /** instance de Wrapper associé à ce contexte */ - //public Wrapper $wrapper; /** source et destination de la valeur */ public Input $input; /** @var string|int|null clé de la valeur dans le tableau destination */ public $valueKey; - /** type de la valeur après analyse */ - public ?IType $type; - /** résultat de l'analyse de la valeur */ - public Result $result; /** @var mixed */ public $origValue; /** @var mixed */ public $value; + + /** @var string|int|null clé sélectionnée */ + public $selectedKey; + /** type de la valeur de la clé sélectionnée après analyse */ + public ?IType $type; + /** résultat de l'analyse de la valeur de la clé sélectionnée */ + public ?Result $result; } diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index 017a6fd..d7bb88e 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -4,7 +4,6 @@ namespace nur\sery\wip\schema\_assoc; use nulib\cl; use nulib\ref\schema\ref_schema; use nulib\ValueException; -use nur\sery\wip\schema\_scalar\ScalarWrapper; use nur\sery\wip\schema\Schema; use nur\sery\wip\schema\Wrapper; @@ -17,7 +16,7 @@ class AssocSchema extends Schema { /** * indiquer si $definition est une définition de schéma de nature tableau - * associatif que {@link normalize()} pourrait normaliser + * associatif que {@link normalize_definition()} pourrait normaliser */ static function isa_definition($definition): bool { if (!is_array($definition)) return false; @@ -29,7 +28,7 @@ class AssocSchema extends Schema { return !cl::have_num_keys($definition); } - static function normalize($definition, $definitionKey=null): array { + static function normalize_definition($definition, $definitionKey=null): array { if (!is_array($definition)) $definition = [$definition]; if (!self::have_nature($definition)) { $definition = [ @@ -38,7 +37,7 @@ class AssocSchema extends Schema { "schema" => $definition, ]; } - self::_normalize($definition, $definitionKey); + self::_normalize_definition($definition, $definitionKey); self::_ensure_nature($definition, "assoc", "array"); return $definition; } @@ -46,7 +45,7 @@ class AssocSchema extends Schema { function __construct($definition=null, $definitionKey=null, bool $normalize=true) { if ($definition === null) $definition = static::SCHEMA; if ($normalize) { - $definition = self::normalize($definition, $definitionKey); + $definition = self::normalize_definition($definition, $definitionKey); $this->_definition = $definition; self::_ensure_type($definition); self::_ensure_schema_instances($definition); @@ -81,11 +80,12 @@ class AssocSchema extends Schema { return new AssocWrapper($this); } - function getWrapper(&$array=null, $arrayKey=null, ?Wrapper &$wrapper=null): AssocWrapper { + function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): AssocWrapper { # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception # cf le code similaire dans ScalarWrapper::__construct() - $verifix = $array !== null || $wrapper !== null; + $verifix = $value !== null || $wrapper !== null; if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper(); - return $wrapper->reset($array, $arrayKey, $verifix); + if ($params !== null) $wrapper->resetParams($params); + return $wrapper->reset($value, $valueKey, $verifix); } } diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 5ce88b1..f7a3a38 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -10,7 +10,6 @@ use nur\sery\wip\schema\WrapperContext; class AssocWrapper extends Wrapper { function __construct(AssocSchema $schema, &$array=null, $arrayKey=null, ?array $params=null) { - $definitionSchema = $schema->getDefinition()["schema"]; $keys = $schema->getKeys(); $keyTypes = []; $keyWrappers = []; @@ -18,7 +17,7 @@ class AssocWrapper extends Wrapper { $keyTypes[$key] = null; $keyWrappers[$key] = $schema->getSchema($key)->getWrapper(); } - $this->context = $context = new AssocWrapperContext($schema, null, null, null, $params); + $this->context = $context = new AssocWrapperContext($schema, null, null, $params); $context->arrayResult = new ScalarResult(); $context->keys = $keys; $context->keyTypes = $keyTypes; @@ -41,18 +40,13 @@ class AssocWrapper extends Wrapper { /** @var AssocWrapperContext */ protected WrapperContext $context; - protected function newInput(&$value): Input { - return new Input($value); - } - - function reset(&$array, $arrayKey=null, ?bool $verifix=null): Wrapper { + function reset(&$array, $arrayKey=null, ?array $params=null): Wrapper { if ($array instanceof Input) $input = $array; else $input = $this->newInput($array); $context = $this->context; $context->input = $input; $context->valueKey = $arrayKey; - $this->analyze(); - if ($verifix ?? $context->verifix) $this->verifix(); + $this->afterModify($params); return $this; } @@ -62,72 +56,17 @@ class AssocWrapper extends Wrapper { /** @param string|int|null $key */ function select($key=null): Wrapper { + #XXX il faut que context contiennent les informations pour la clé sélectionnée if ($key === null) return $this; $wrapper = $this->context->keyWrappers[$key] ?? null; if ($wrapper === null) throw ValueException::invalid_key($key); return $wrapper; } - protected function analyze(): int { - return 0; #XXX - } - - function verifix(?bool $throw=null): bool { - return false; #XXX - } - - function getResult(): AssocResult { - /** @var AssocResult $result */ - $result = $this->context->result; - return $result; - } - - function isPresent(): bool { - return $this->context->result->present; - } - - function getType(): IType { - return $this->context->type; - } - - function isAvailable(): bool { - return $this->context->result->available; - } - - function isValid(): bool { - return $this->context->result->valid; - } - function isNormalized(): bool { return $this->context->result->normalized; } - function get($default=null) { - $context = $this->context; - if ($context->result->available) return $context->input->get($context->valueKey); - else return $default; - } - - function set($value, ?bool $verifix=null): AssocWrapper { - $context = $this->context; - $context->input->set($value, $context->valueKey); - $this->analyze(); - if ($verifix ?? $context->verifix) $this->verifix(); - return $this; - } - - function unset(?bool $verifix=null): AssocWrapper { - $context = $this->context; - $context->input->unset($context->valueKey); - $this->analyze(); - if ($verifix ?? $context->verifix) $this->verifix(); - return $this; - } - - function format($format = null): string { - return $this->_format($this->context, $format); - } - function ensureKeys(): bool { } function orderKeys(): bool { diff --git a/src/schema/_list/ListSchema.php b/src/schema/_list/ListSchema.php index 24dadda..4887e95 100644 --- a/src/schema/_list/ListSchema.php +++ b/src/schema/_list/ListSchema.php @@ -35,7 +35,7 @@ class ListSchema extends Schema { "schema" => $definition[0], ]; } - self::_normalize($definition, $definitionKey); + self::_normalize_definition($definition, $definitionKey); self::_ensure_nature($definition, "list", "array"); return $definition; } @@ -71,7 +71,7 @@ class ListSchema extends Schema { return new ListWrapper($this); } - function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): ListWrapper { + function getWrapper(&$value=null, $valueKey=null, ?array $params = null, ?Wrapper &$wrapper=null): ListWrapper { # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception # cf le code similaire dans ScalarWrapper::__construct() $verifix = $value !== null || $wrapper !== null; diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 8ff264b..1621e5b 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -4,7 +4,6 @@ namespace nur\sery\wip\schema\_scalar; use nulib\ref\schema\ref_schema; use nulib\ValueException; use nur\sery\wip\schema\Schema; -use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; /** @@ -16,7 +15,7 @@ class ScalarSchema extends Schema { /** * indiquer si $definition est une définition de schéma scalaire que - * {@link normalize()} pourrait normaliser + * {@link normalize_definition()} pourrait normaliser */ static function isa_definition($definition): bool { # chaine ou null @@ -45,8 +44,8 @@ class ScalarSchema extends Schema { return $haveIndex0 && $count > 1; } - static function normalize($definition, $definitionKey=null): array { - self::_normalize($definition, $definitionKey); + static function normalize_definition($definition, $definitionKey=null): array { + self::_normalize_definition($definition, $definitionKey); self::_ensure_nature($definition, "scalar"); return $definition; } @@ -54,7 +53,7 @@ class ScalarSchema extends Schema { function __construct($definition=null, $definitionKey=null, bool $normalize=true) { if ($definition === null) $definition = static::SCHEMA; if ($normalize) { - $definition = self::normalize($definition, $definitionKey); + $definition = self::normalize_definition($definition, $definitionKey); $this->_definition = $definition; self::_ensure_type($definition); self::_ensure_schema_instances($definition); @@ -82,11 +81,12 @@ class ScalarSchema extends Schema { return new ScalarWrapper($this); } - function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): ScalarWrapper { + function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): ScalarWrapper { # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception # cf le code similaire dans ScalarWrapper::__construct() - $verifix = $value !== null || $wrapper !== null; + $dontNormalize = $value === null && $wrapper === null; if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); - return $wrapper->reset($value, $valueKey, $verifix); + if ($params !== null) $wrapper->resetParams($params); + return $wrapper->reset($value, $valueKey, $dontNormalize? ["normalize" => false]: null); } } diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 3ff48fb..3a33684 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -4,22 +4,31 @@ namespace nur\sery\wip\schema\_scalar; use nulib\php\func; use nulib\ref\schema\ref_analyze; use nulib\ValueException; -use nur\sery\wip\schema\WrapperContext; use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types; use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; +use nur\sery\wip\schema\WrapperContext; +/** + * Class ScalarWrapper + * + * @method ScalarResult getResult() + * @method self set() + * @method self unset() + */ class ScalarWrapper extends Wrapper { function __construct(ScalarSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { - $this->context = $context = new WrapperContext($schema, null, null, new ScalarResult(), $params); + $this->context = $context = new WrapperContext($schema, null, null, $params); + $context->result = new ScalarResult(); - $throw = $context->throw; - if ($value !== null && $throw === null) { - # Si $value est null, ne pas lancer d'exception, parce qu'on considère que - # c'est une initialisation sans conséquences - $throw = true; - } + # 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; @@ -29,19 +38,13 @@ class ScalarWrapper extends Wrapper { protected WrapperContext $context; - protected function newInput(&$value): Input { - return new Input($value); - } - - function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper { + function reset(&$value, $valueKey=null, ?array $params=null): Wrapper { + $context = $this->context; if ($value instanceof Input) $input = $value; else $input = $this->newInput($value); - $context = $this->context; $context->input = $input; $context->valueKey = $valueKey; - $context->type = null; - $this->analyze(); - if ($verifix ?? $context->verifix) $this->verifix(); + $this->afterModify($params); return $this; } @@ -56,7 +59,7 @@ class ScalarWrapper extends Wrapper { } /** analyser la valeur et résoudre son type */ - protected function analyze0(): int { + protected function _analyze0(): int { $context = $this->context; /** @var ScalarSchema $schema */ $schema = $context->schema; @@ -123,7 +126,7 @@ class ScalarWrapper extends Wrapper { $type = $firstType; } } - $context->type = $this->type = $type; + $context->type = $type; if (!$type->isAvailable($input, $valueKey)) { if ($default !== null) { @@ -148,7 +151,7 @@ class ScalarWrapper extends Wrapper { } } - protected function analyze(): int { + protected function _analyze(?array $params): int { $context = $this->context; /** @var ScalarSchema $schema */ $schema = $context->schema; @@ -156,12 +159,11 @@ class ScalarWrapper extends Wrapper { $valueKey = $context->valueKey; /** @var ScalarResult $result */ $result = $context->result; - $result->reset(); /** @var func $analyzerFunc */ $analyzerFunc = $schema->analyzerFunc; if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context, $this]); - else $what = $this->analyze0(); + else $what = $this->_analyze0(); if ($what !== ref_analyze::STRING) return $what; $value = $context->value; @@ -196,7 +198,7 @@ class ScalarWrapper extends Wrapper { } } - function verifix(?bool $throw=null): bool { + protected function _normalize(?array $params): bool { $context = $this->context; /** @var ScalarSchema $schema */ $schema = $context->schema; @@ -241,59 +243,6 @@ class ScalarWrapper extends Wrapper { } if ($result->valid) $input->set($value, $valueKey); } - if (!$result->valid) $result->throw($throw ?? $context->throw); return $modified; } - - function getResult(): ScalarResult { - /** @var ScalarResult $result */ - $result = $this->context->result; - return $result; - } - - function isPresent(): bool { - return $this->context->result->present; - } - - function getType(): IType { - return $this->context->type; - } - - function isAvailable(): bool { - return $this->context->result->available; - } - - function isValid(): bool { - return $this->context->result->valid; - } - - function isNormalized(): bool { - return $this->context->result->normalized; - } - - function get($default=null) { - $context = $this->context; - if ($context->result->available) return $context->input->get($context->valueKey); - else return $default; - } - - function set($value, ?bool $verifix=null): ScalarWrapper { - $context = $this->context; - $context->input->set($value, $context->valueKey); - $this->analyze(); - if ($verifix ?? $context->verifix) $this->verifix(); - return $this; - } - - function unset(?bool $verifix=null): ScalarWrapper { - $context = $this->context; - $context->input->unset($context->valueKey); - $this->analyze(); - if ($verifix ?? $context->verifix) $this->verifix(); - return $this; - } - - function format($format=null): string { - return $this->_format($this->context, $format); - } } diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index 8f78dd4..384f5d6 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -44,7 +44,7 @@ class AssocSchemaTest extends TestCase { "type" => ["string"], "nullable" => false, "name" => "a", "pkey" => "a", "header" => "a", ], - ]), AssocSchema::normalize(["a" => "string"])); + ]), AssocSchema::normalize_definition(["a" => "string"])); self::assertSame(self::schema([ "type" => ["array"], "nullable" => true, @@ -61,7 +61,7 @@ class AssocSchemaTest extends TestCase { "type" => ["bool"], "nullable" => false, "name" => "c", "pkey" => "c", "header" => "c", ], - ]), AssocSchema::normalize([ + ]), AssocSchema::normalize_definition([ "a" => "string", "b" => "int", "c" => "bool", diff --git a/tests/wip/schema/_scalar/ScalarSchemaTest.php b/tests/wip/schema/_scalar/ScalarSchemaTest.php index c862fa5..a5b6cee 100644 --- a/tests/wip/schema/_scalar/ScalarSchemaTest.php +++ b/tests/wip/schema/_scalar/ScalarSchemaTest.php @@ -32,33 +32,33 @@ class ScalarSchemaTest extends TestCase { } function testNormalize() { - self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize(null)); - self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([])); - self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([null])); + self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize_definition(null)); + self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize_definition([])); + self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize_definition([null])); self::assertException(SchemaException::class, function () { - ScalarSchema::normalize([[]]); + ScalarSchema::normalize_definition([[]]); }); self::assertException(SchemaException::class, function () { - ScalarSchema::normalize([[null]]); + ScalarSchema::normalize_definition([[null]]); }); $string = self::schema(["type" => ["string"], "nullable" => false]); - self::assertSame($string, ScalarSchema::normalize("string")); - self::assertSame($string, ScalarSchema::normalize(["string"])); + self::assertSame($string, ScalarSchema::normalize_definition("string")); + self::assertSame($string, ScalarSchema::normalize_definition(["string"])); $nstring = self::schema(["type" => ["string"]]); - self::assertSame($nstring, ScalarSchema::normalize(["?string"])); - self::assertSame($nstring, ScalarSchema::normalize(["?string|null"])); - self::assertSame($nstring, ScalarSchema::normalize(["string|null"])); - self::assertSame($nstring, ScalarSchema::normalize([["?string", "null"]])); - self::assertSame($nstring, ScalarSchema::normalize([["string", "null"]])); - self::assertSame($nstring, ScalarSchema::normalize([["string", null]])); + self::assertSame($nstring, ScalarSchema::normalize_definition(["?string"])); + self::assertSame($nstring, ScalarSchema::normalize_definition(["?string|null"])); + self::assertSame($nstring, ScalarSchema::normalize_definition(["string|null"])); + self::assertSame($nstring, ScalarSchema::normalize_definition([["?string", "null"]])); + self::assertSame($nstring, ScalarSchema::normalize_definition([["string", "null"]])); + self::assertSame($nstring, ScalarSchema::normalize_definition([["string", null]])); $key = self::schema(["type" => ["string", "int"], "nullable" => false]); - self::assertSame($key, ScalarSchema::normalize("string|int")); + self::assertSame($key, ScalarSchema::normalize_definition("string|int")); $nkey = self::schema(["type" => ["string", "int"], "nullable" => true]); - self::assertSame($nkey, ScalarSchema::normalize("?string|int")); - self::assertSame($nkey, ScalarSchema::normalize("string|?int")); + self::assertSame($nkey, ScalarSchema::normalize_definition("?string|int")); + self::assertSame($nkey, ScalarSchema::normalize_definition("string|?int")); } } diff --git a/tests/wip/schema/_scalar/ScalarWrapperTest.php b/tests/wip/schema/_scalar/ScalarWrapperTest.php index 6e9326b..a78e548 100644 --- a/tests/wip/schema/_scalar/ScalarWrapperTest.php +++ b/tests/wip/schema/_scalar/ScalarWrapperTest.php @@ -15,19 +15,21 @@ class ScalarWrapperTest extends TestCase { self::assertSame($normalized, $wrapper->isNormalized(), "normalized"); } - function checkVerifix(ScalarSchema $schema, $orig, bool $verifix, $value, bool $present, bool $available, bool $valid, bool $normalized, ?array $inputParams=null): void { + function checkVerifix(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); else $input = $orig; - $wrapper->reset($input, null, $verifix); + $wrapper->reset($input); $this->checkValue($wrapper, $value, $present, $available, $valid, $normalized); } - function checkException(ScalarSchema $schema, $orig, bool $verifix, string $exceptionClass, ?array $inputParams=null) { + function checkException(ScalarSchema $schema, $orig, bool $normalize, string $exceptionClass, ?array $inputParams=null) { $wrapper = $schema->getWrapper(); if ($inputParams !== null) $orig = new Input($orig, $inputParams); - self::assertException($exceptionClass, function() use ($wrapper, &$orig, $verifix) { - $wrapper->reset($orig, null, $verifix); + self::assertException($exceptionClass, function() use ($wrapper, &$orig, $normalize) { + $wrapper->resetParams(["normalize" => $normalize]); + $wrapper->reset($orig); }); } From 3608b02749e13a24c88f761b2e5b11baa7552752 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 06:38:19 +0400 Subject: [PATCH 08/55] modifs.mineures sans commentaires --- src/schema/Result.php | 7 - src/schema/Schema.php | 12 +- src/schema/TODO.md | 4 +- src/schema/Wrapper.php | 65 ++++++---- src/schema/WrapperContext.php | 1 + src/schema/_assoc/AssocResult.php | 50 -------- src/schema/_assoc/AssocSchema.php | 14 +- src/schema/_assoc/AssocWrapper.php | 120 ++++++++++++++---- src/schema/_assoc/AssocWrapperContext.php | 11 +- src/schema/_scalar/ScalarSchema.php | 11 +- src/schema/_scalar/ScalarWrapper.php | 12 +- tests/wip/schema/_assoc/AssocSchemaTest.php | 9 +- tests/wip/schema/_scalar/ScalarSchemaTest.php | 6 +- 13 files changed, 186 insertions(+), 136 deletions(-) delete mode 100644 src/schema/_assoc/AssocResult.php diff --git a/src/schema/Result.php b/src/schema/Result.php index 46f08ee..21c2b7f 100644 --- a/src/schema/Result.php +++ b/src/schema/Result.php @@ -2,9 +2,6 @@ namespace nur\sery\wip\schema; use IteratorAggregate; -use nur\sery\wip\schema\_assoc\AssocResult; -use nur\sery\wip\schema\_list\ListResult; -use nur\sery\wip\schema\_scalar\ScalarResult; use Throwable; /** @@ -37,10 +34,6 @@ abstract class Result implements IteratorAggregate { $this->reset(); } - function isAssoc(?AssocResult &$result=null): bool { return false; } - function isList(?ListResult &$result=null): bool { return false; } - function isScalar(?ScalarResult &$result=null): bool { return false; } - /** * Obtenir la liste des clés valides pour les valeurs accessibles via cet * objet diff --git a/src/schema/Schema.php b/src/schema/Schema.php index 4d1a422..aef756d 100644 --- a/src/schema/Schema.php +++ b/src/schema/Schema.php @@ -98,18 +98,18 @@ abstract class Schema implements ArrayAccess { return false; } - protected static function _normalize_definition(&$definition, $definitionKey=null): void { + protected static function _normalize_definition(&$definition, $definitionKey=null, ?array $natureMetaschema=null): void { if (!is_array($definition)) $definition = [$definition]; # s'assurer que toutes les clés existent avec leur valeur par défaut $index = 0; - foreach (array_keys(ref_schema::SCALAR_METASCHEMA) as $key) { + foreach (array_keys(ref_schema::VALUE_METASCHEMA) as $key) { if (!array_key_exists($key, $definition)) { if (array_key_exists($index, $definition)) { $definition[$key] = $definition[$index]; unset($definition[$index]); $index++; } else { - $definition[$key] = ref_schema::SCALAR_METASCHEMA[$key][1]; + $definition[$key] = ref_schema::VALUE_METASCHEMA[$key][1]; } } } @@ -161,6 +161,12 @@ abstract class Schema implements ArrayAccess { # nature $nature = $definition[""]; tarray::ensure_array($nature); + $natureMetaschema ??= ref_schema::NATURE_METASCHEMA; + foreach (array_keys($natureMetaschema) as $key) { + if (!array_key_exists($key, $nature)) { + $nature[$key] = $natureMetaschema[$key][1]; + } + } $definition[""] = $nature; # name, pkey, header $name = $definition["name"]; diff --git a/src/schema/TODO.md b/src/schema/TODO.md index b41abbe..745781f 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -2,8 +2,8 @@ * faire PropertyAccess * si l'argument de Input() est un objet, utiliser PropertyAccess au lieu de KeyAccess -* possibilité de forcer l'un ou l'autre -* ensureKeys() et orderKeys() se fait au niveau de access + * possibilité de forcer l'un ou l'autre (paramètre type=value|array|object) +* ensureKeys() et orderKeys() se fait au niveau de access (ou input?) * valeurs composite/computed * analyse / vérification de la valeur complète après calcul du résultat, si diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 7d6361f..4cf6a9a 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -23,14 +23,17 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $this->context->resetParams($params); } - protected function afterModify(?array $params, bool $reset=true): void { + protected function resetContext($resetSelectedKey): void { $context = $this->context; - if ($reset) { - $context->type = null; - $context->result->reset(); - $context->analyzed = false; - $context->normalized = false; - } + $context->type = null; + $context->result->reset(); + $context->analyzed = false; + $context->normalized = false; + } + + protected function afterModify(?array $params, $resetSelectedKey=false): void { + $context = $this->context; + $this->resetContext($resetSelectedKey); if ($params["analyze"] ?? $context->analyze) { $this->analyze($params); } @@ -51,7 +54,15 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { * @param ?array $params paramètres spécifique à cet appel, qui peuvent être * différent des paramètres par défaut */ - abstract function reset(&$value, $valueKey=null, ?array $params=null): self; + function reset(&$value, $valueKey=null, ?array $params=null): Wrapper { + $context = $this->context; + if ($value instanceof Input) $input = $value; + else $input = $this->newInput($value); + $context->input = $input; + $context->valueKey = $valueKey; + $this->afterModify($params, true); + return $this; + } /** analyser la valeur */ abstract protected function _analyze(?array $params): int; @@ -119,50 +130,50 @@ 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()} */ - function getResult(): Result { + function getResult($key=false): Result { return $this->context->result; } /** retourner true si la valeur existe */ - function isPresent(): bool { - return $this->context->result->present; + function isPresent($key=false): bool { + return $this->getResult()->present; } /** retourner le type associé à la valeur */ - function getType(): IType { + function getType($key=false): IType { return $this->context->type; } /** retourner true si la valeur est disponible */ - function isAvailable(): bool { - return $this->context->result->available; + function isAvailable($key=false): bool { + return $this->getResult()->available; } /** retourner true si la valeur est valide */ - function isValid(): bool { - return $this->context->result->valid; + function isValid($key=false): bool { + return $this->getResult()->valid; } /** retourner true si la valeur est dans sa forme normalisée */ - function isNormalized(): bool { - return $this->context->result->normalized; + function isNormalized($key=false): bool { + return $this->getResult()->normalized; } - function get($default=null) { + function get($default=null, $key=false) { $context = $this->context; - if ($context->result->available) return $context->input->get($context->valueKey); - else return $default; + if (!$context->result->available) return $default; + return $context->input->get($context->valueKey); } - function set($value, ?array $params=null): self { + function set($value, ?array $params=null, $key=false): self { $context = $this->context; $context->input->set($value, $context->valueKey); $this->afterModify($params); return $this; } - function unset(?array $params=null): self { + function unset(?array $params=null, $key=false): self { $context = $this->context; $context->input->unset($context->valueKey); $this->afterModify($params); @@ -186,7 +197,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } /** formatter la valeur pour affichage */ - function format($format=null): string { + function format($format=null, $key=false): string { return $this->_format($this->context, $format); } @@ -198,14 +209,14 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } function offsetGet($offset) { - return $this->select($offset)->get(); + return $this->get(null, $offset); } function offsetSet($offset, $value): void { - $this->select($offset)->set($value); + $this->set($value, null, $offset); } function offsetUnset($offset): void { - $this->select($offset)->unset(); + $this->unset(null, $offset); } } diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index 6e523e4..d144939 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -12,6 +12,7 @@ class WrapperContext { $this->valueKey = $valueKey; $this->origValue = null; $this->value = null; + $this->selectedKey = null; $this->type = null; $this->result = null; } diff --git a/src/schema/_assoc/AssocResult.php b/src/schema/_assoc/AssocResult.php deleted file mode 100644 index 76a2a74..0000000 --- a/src/schema/_assoc/AssocResult.php +++ /dev/null @@ -1,50 +0,0 @@ -context = $context; - parent::__construct(); - } - - function isAssoc(?AssocResult &$result=null): bool { $result = $this; return true;} - - protected AssocWrapperContext $context; - - function getKeys(): array { - return $this->context->keys; - } - - protected Result $result; - - function select($key): AssocResult { - $context = $this->context; - if ($key === null) { - $this->result = $context->arrayResult; - return $this; - } - $wrapper = $context->keyWrappers[$key] ?? null; - if ($wrapper === null) throw ValueException::invalid_key($key); - $this->result = $wrapper->getResult(); - return $this; - } - - function reset(): void { - $context = $this->context; - $context->arrayResult->reset(); - foreach ($context->keyWrappers as $wrapper) { - $wrapper->getResult()->reset(); - } - } - - function __get(string $name) { - return $this->result[$name]; - } - - function __set(string $name, $value): void { - $this->result[$name] = $value; - } -} diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index d7bb88e..e49d794 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -11,8 +11,11 @@ use nur\sery\wip\schema\Wrapper; * Class AssocSchema */ class AssocSchema extends Schema { - /** @var array meta-schema d'un schéma de nature tableau associatif */ - const METASCHEMA = ref_schema::ASSOC_METASCHEMA; + //const METASCHEMA = ref_schema::VALUE_METASCHEMA; + //const NATURE_METASCHEMA = [ + // ...ref_schema::NATURE_METASCHEMA, + // ...ref_schema::ASSOC_NATURE_METASCHEMA, + //]; /** * indiquer si $definition est une définition de schéma de nature tableau @@ -37,7 +40,8 @@ class AssocSchema extends Schema { "schema" => $definition, ]; } - self::_normalize_definition($definition, $definitionKey); + $natureMetaschema = array_merge(ref_schema::NATURE_METASCHEMA, ref_schema::ASSOC_NATURE_METASCHEMA); + self::_normalize_definition($definition, $definitionKey, $natureMetaschema); self::_ensure_nature($definition, "assoc", "array"); return $definition; } @@ -83,9 +87,9 @@ class AssocSchema extends Schema { function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): AssocWrapper { # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception # cf le code similaire dans ScalarWrapper::__construct() - $verifix = $value !== null || $wrapper !== null; + $dontNormalize = $value === null && $wrapper === null; if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper(); if ($params !== null) $wrapper->resetParams($params); - return $wrapper->reset($value, $valueKey, $verifix); + return $wrapper->reset($value, $valueKey, $dontNormalize? ["normalize" => false]: null); } } diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index f7a3a38..029d5b7 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -4,12 +4,13 @@ namespace nur\sery\wip\schema\_assoc; use nulib\ValueException; use nur\sery\wip\schema\_scalar\ScalarResult; use nur\sery\wip\schema\input\Input; +use nur\sery\wip\schema\Result; use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; use nur\sery\wip\schema\WrapperContext; class AssocWrapper extends Wrapper { - function __construct(AssocSchema $schema, &$array=null, $arrayKey=null, ?array $params=null) { + function __construct(AssocSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { $keys = $schema->getKeys(); $keyTypes = []; $keyWrappers = []; @@ -22,16 +23,17 @@ class AssocWrapper extends Wrapper { $context->keys = $keys; $context->keyTypes = $keyTypes; $context->keyWrappers = $keyWrappers; - $context->result = new AssocResult($context); + $context->result = $context->arrayResult; - $throw = $context->throw; - if ($array !== null && $throw === null) { - # Si $value est null, ne pas lancer d'exception, parce qu'on considère que - # c'est une initialisation sans conséquences - $throw = true; - } + # 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($array, $arrayKey); + $this->reset($value, $valueKey); $context->throw = $throw ?? true; } @@ -40,35 +42,103 @@ class AssocWrapper extends Wrapper { /** @var AssocWrapperContext */ protected WrapperContext $context; - function reset(&$array, $arrayKey=null, ?array $params=null): Wrapper { - if ($array instanceof Input) $input = $array; - else $input = $this->newInput($array); + protected function resetContext($resetSelectedKey): void { $context = $this->context; - $context->input = $input; - $context->valueKey = $arrayKey; - $this->afterModify($params); - return $this; + $context->arrayResult->reset(); + foreach ($context->keyWrappers as $wrapper) { + $wrapper->getResult()->reset(); + } + $context->analyzed = false; + $context->normalized = false; + if ($resetSelectedKey) { + $context->selectedKey = null; + $context->type = $context->arrayType; + $context->result = $context->arrayResult; + } } function getKeys(): array { return $this->context->keys; } - /** @param string|int|null $key */ - function select($key=null): Wrapper { - #XXX il faut que context contiennent les informations pour la clé sélectionnée - if ($key === null) return $this; - $wrapper = $this->context->keyWrappers[$key] ?? null; + protected function _getWrapper($key): Wrapper { + $wrapper = $context->keyWrappers[$key] ?? null; if ($wrapper === null) throw ValueException::invalid_key($key); return $wrapper; } - function isNormalized(): bool { - return $this->context->result->normalized; + /** @param string|int|null $key */ + function select($key=null): Wrapper { + $context = $this->context; + if ($key === null) { + $context->selectedKey = null; + $context->type = $context->arrayType; + $context->result = $context->arrayResult; + return $this; + } + $wrapper = $this->_getWrapper($key); + $context->selectedKey = $key; + $context->type = $wrapper->getType(); + $context->result = $wrapper->getResult(); + return $wrapper; } - function ensureKeys(): bool { + protected function _analyze(?array $params): int { + return -1; } - function orderKeys(): bool { + + protected function _normalize(?array $params): bool { + return false; + } + + function getResult($key=false): Result { + if ($key === false) return $this->context->result; + elseif ($key === null) return $this->context->arrayResult; + else return $this->_getWrapper($key)->getResult(); + } + + function getType($key=false): IType { + if ($key === false) return $this->context->type; + elseif ($key === null) return $this->context->arrayType; + else return $this->_getWrapper($key)->getType(); + } + + function get($default=null, $key=false) { + $context = $this->context; + if (!$context->arrayResult->available) return $default; + if ($key === false) $key = $context->selectedKey; + if ($key === null) return $context->input->get($context->valueKey); + else return $this->_getWrapper($key)->get($default); + } + + function set($value, ?array $params=null, $key=false): Wrapper { + $context = $this->context; + if ($key === false) $key = $context->selectedKey; + if ($key === null) { + $context->input->set($value, $context->valueKey); + $this->afterModify($params); + } else { + $this->_getWrapper($key)->set($value); + } + return $this; + } + + function unset(?array $params=null, $key=false): Wrapper { + $context = $this->context; + if ($key === false) $key = $context->selectedKey; + if ($key === null) { + $context->input->unset($context->valueKey); + $this->afterModify($params); + } else { + $this->_getWrapper($key)->unset(); + } + return $this; + } + + function format($format=null, $key=false): string { + $context = $this->context; + if ($key === false) $key = $context->selectedKey; + if ($key === null) return $this->_format($context, $format); + else return $this->_getWrapper($key)->format($format); } } diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index ed25436..44fee29 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -2,13 +2,22 @@ namespace nur\sery\wip\schema\_assoc; use nur\sery\wip\schema\_scalar\ScalarResult; +use nur\sery\wip\schema\input\Input; +use nur\sery\wip\schema\Schema; use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; use nur\sery\wip\schema\WrapperContext; class AssocWrapperContext extends WrapperContext { + function __construct(Schema $schema, ?Input $input, $valueKey, ?array $params) { + parent::__construct($schema, $input, $valueKey, $params); + $this->arrayType = null; + $this->arrayResult = null; + } + + public ?IType $arrayType; /** résultat de l'analyse du tableau */ - public ScalarResult $arrayResult; + public ?ScalarResult $arrayResult; /** liste des clés valides */ public array $keys; diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 1621e5b..d726ebb 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -1,6 +1,7 @@ context; - if ($value instanceof Input) $input = $value; - else $input = $this->newInput($value); - $context->input = $input; - $context->valueKey = $valueKey; - $this->afterModify($params); - return $this; - } - function getKeys(): array { return ScalarSchema::KEYS; } diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index 384f5d6..a082855 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -7,7 +7,14 @@ use nur\sery\wip\schema\_scalar\ScalarSchemaTest; class AssocSchemaTest extends TestCase { const NULL_SCHEMA = [ - "" => ["assoc"], + "" => [ + "assoc", + "compute_func" => null, + "validate_func" => null, + "ensure_array" => false, + "ensure_keys" => true, + "ensure_order" => true, + ], "schema" => null, "type" => [null], "default" => null, diff --git a/tests/wip/schema/_scalar/ScalarSchemaTest.php b/tests/wip/schema/_scalar/ScalarSchemaTest.php index a5b6cee..5742fb8 100644 --- a/tests/wip/schema/_scalar/ScalarSchemaTest.php +++ b/tests/wip/schema/_scalar/ScalarSchemaTest.php @@ -19,7 +19,11 @@ class ScalarSchemaTest extends TestCase { "messages" => null, "formatter_func" => null, "format" => null, - "" => ["scalar"], + "" => [ + "scalar", + "compute_func" => null, + "validate_func" => null, + ], "schema" => null, "name" => null, "pkey" => null, From b9e91bd91745615351ba09a53cb175620cb21391 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 07:18:41 +0400 Subject: [PATCH 09/55] modifs.mineures sans commentaires --- src/schema/_assoc/AssocWrapper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 029d5b7..0ee3800 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -23,7 +23,6 @@ class AssocWrapper extends Wrapper { $context->keys = $keys; $context->keyTypes = $keyTypes; $context->keyWrappers = $keyWrappers; - $context->result = $context->arrayResult; # calculer manuellemet throw ici parce que WrapperContext le met à true par # défaut. on veut pouvoir mettre temporairement throw à false si jamais il From 62fc315b9e472bbd595412db90b299cdc1e22e7c Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 08:37:17 +0400 Subject: [PATCH 10/55] modifs.mineures sans commentaires --- src/schema/Wrapper.php | 8 +++--- src/schema/_assoc/AssocSchema.php | 8 +++--- src/schema/_scalar/ScalarSchema.php | 4 +-- tests/wip/schema/_assoc/AssocSchemaTest.php | 31 +++++++++++++++++++-- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 4cf6a9a..d8e1e4d 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -136,7 +136,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { /** retourner true si la valeur existe */ function isPresent($key=false): bool { - return $this->getResult()->present; + return $this->getResult($key)->present; } /** retourner le type associé à la valeur */ @@ -146,17 +146,17 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { /** retourner true si la valeur est disponible */ function isAvailable($key=false): bool { - return $this->getResult()->available; + return $this->getResult($key)->available; } /** retourner true si la valeur est valide */ function isValid($key=false): bool { - return $this->getResult()->valid; + return $this->getResult($key)->valid; } /** retourner true si la valeur est dans sa forme normalisée */ function isNormalized($key=false): bool { - return $this->getResult()->normalized; + return $this->getResult($key)->normalized; } diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index e49d794..6d3ba16 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -85,11 +85,11 @@ class AssocSchema extends Schema { } function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): AssocWrapper { - # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception - # cf le code similaire dans ScalarWrapper::__construct() - $dontNormalize = $value === null && $wrapper === null; + # si pas de valeur ni de wrapper, pas d'analyse et donc pas d'exception + # cf le code similaire dans AssocWrapper::__construct() + $dontAnalyze = $value === null && $wrapper === null; if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper(); if ($params !== null) $wrapper->resetParams($params); - return $wrapper->reset($value, $valueKey, $dontNormalize? ["normalize" => false]: null); + return $wrapper->reset($value, $valueKey, $dontAnalyze? ["analyze" => false]: null); } } diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index d726ebb..5c14a5c 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -89,9 +89,9 @@ class ScalarSchema extends Schema { function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): ScalarWrapper { # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception # cf le code similaire dans ScalarWrapper::__construct() - $dontNormalize = $value === null && $wrapper === null; + $dontAnalyze = $value === null && $wrapper === null; if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper(); if ($params !== null) $wrapper->resetParams($params); - return $wrapper->reset($value, $valueKey, $dontNormalize? ["normalize" => false]: null); + 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 a082855..38586bd 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -98,8 +98,35 @@ class AssocSchemaTest extends TestCase { ], ]), $schema->getDefinition()); //yaml::dump($schema->getDefinition()); + } - $wrapper = $schema->getWrapper(); - $wrapper->getKeys(); + function testWrapper() { + $schema = new AssocSchema([ + "a" => "string", + "b" => "int", + "c" => "bool", + ]); + + $array = ["c" => false, "a" => " string "]; + $schema->getWrapper($array); + self::assertSame([ + "a" => "string", + "b" => null, + "c" => false, + ], $array); + + $array = ["c" => false, "a" => " string "]; + $schema->getWrapper($array, null, ["ensure_order" => false]); + self::assertSame([ + "c" => false, + "a" => "string", + "b" => null, + ], $array); + + $array = ["a" => " string "]; + $schema->getWrapper($array, null, ["ensure_keys" => false]); + self::assertSame([ + "a" => "string", + ], $array); } } From 9328aac9e9cb75717f726eae81cca1f619e18064 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 10:06:53 +0400 Subject: [PATCH 11/55] modifs.mineures sans commentaires --- src/schema/Wrapper.php | 11 ++-- src/schema/WrapperContext.php | 19 +++--- src/schema/_assoc/AssocSchema.php | 6 -- src/schema/_assoc/AssocWrapper.php | 72 ++++++++--------------- src/schema/_assoc/AssocWrapperContext.php | 18 +----- src/schema/_scalar/ScalarResult.php | 11 ++-- src/schema/_scalar/ScalarSchema.php | 6 -- src/schema/_scalar/ScalarWrapper.php | 41 +++++++------ 8 files changed, 67 insertions(+), 117 deletions(-) diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index d8e1e4d..43cc54b 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -65,31 +65,31 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } /** analyser la valeur */ - abstract protected function _analyze(?array $params): int; + abstract static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int; function analyze(?array $params=null): bool { $context = $this->context; $reanalyze = $params["reanalyze"] ?? false; if ($context->analyzed && !$reanalyze) return false; - $this->_analyze($params); + static::_analyze($params, $context, $this); $context->analyzed = true; return true; } /** normaliser la valeur */ - abstract protected function _normalize(?array $params): bool; + abstract static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool; function normalize(?array $params=null): bool { $context = $this->context; // il faut que la valeur soit analysée avant de la normaliser - $this->analyze($params); + static::analyze($params); if (!$context->analyzed) return false; $renormalize = $params["renormalize"] ?? false; if ($renormalize || !$context->normalized) { - $modified = $this->_normalize($params); + $modified = static::_normalize($params, $context, $this); $context->normalized = true; } else { $modified = false; @@ -159,7 +159,6 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { return $this->getResult($key)->normalized; } - function get($default=null, $key=false) { $context = $this->context; if (!$context->result->available) return $default; diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index d144939..58a7fe8 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -10,16 +10,11 @@ class WrapperContext { $this->schema = $schema; if ($input !== null) $this->input = $input; $this->valueKey = $valueKey; - $this->origValue = null; - $this->value = null; - $this->selectedKey = null; - $this->type = null; - $this->result = null; } public ?array $params; - public bool $analyze, $analyzed; - public bool $normalize, $normalized; + public bool $analyze, $analyzed = false; + public bool $normalize, $normalized = false; public ?bool $throw; function resetParams(?array $params): void { @@ -36,14 +31,14 @@ class WrapperContext { /** @var string|int|null clé de la valeur dans le tableau destination */ public $valueKey; /** @var mixed */ - public $origValue; + public $origValue = null; /** @var mixed */ - public $value; + public $value = null; /** @var string|int|null clé sélectionnée */ - public $selectedKey; + public $selectedKey = null; /** type de la valeur de la clé sélectionnée après analyse */ - public ?IType $type; + public ?IType $type = null; /** résultat de l'analyse de la valeur de la clé sélectionnée */ - public ?Result $result; + public ?Result $result = null; } diff --git a/src/schema/_assoc/AssocSchema.php b/src/schema/_assoc/AssocSchema.php index 6d3ba16..b9fac49 100644 --- a/src/schema/_assoc/AssocSchema.php +++ b/src/schema/_assoc/AssocSchema.php @@ -11,12 +11,6 @@ use nur\sery\wip\schema\Wrapper; * Class AssocSchema */ class AssocSchema extends Schema { - //const METASCHEMA = ref_schema::VALUE_METASCHEMA; - //const NATURE_METASCHEMA = [ - // ...ref_schema::NATURE_METASCHEMA, - // ...ref_schema::ASSOC_NATURE_METASCHEMA, - //]; - /** * indiquer si $definition est une définition de schéma de nature tableau * associatif que {@link normalize_definition()} pourrait normaliser diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 0ee3800..a071c62 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -2,8 +2,7 @@ namespace nur\sery\wip\schema\_assoc; use nulib\ValueException; -use nur\sery\wip\schema\_scalar\ScalarResult; -use nur\sery\wip\schema\input\Input; +use nur\sery\wip\schema\_scalar\ScalarWrapper; use nur\sery\wip\schema\Result; use nur\sery\wip\schema\types\IType; use nur\sery\wip\schema\Wrapper; @@ -12,16 +11,13 @@ use nur\sery\wip\schema\WrapperContext; class AssocWrapper extends Wrapper { function __construct(AssocSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { $keys = $schema->getKeys(); - $keyTypes = []; $keyWrappers = []; foreach ($keys as $key) { - $keyTypes[$key] = null; $keyWrappers[$key] = $schema->getSchema($key)->getWrapper(); } $this->context = $context = new AssocWrapperContext($schema, null, null, $params); - $context->arrayResult = new ScalarResult(); + $context->arrayWrapper = new ScalarWrapper($schema, $dummy, null, null, $context); $context->keys = $keys; - $context->keyTypes = $keyTypes; $context->keyWrappers = $keyWrappers; # calculer manuellemet throw ici parce que WrapperContext le met à true par @@ -43,17 +39,13 @@ class AssocWrapper extends Wrapper { protected function resetContext($resetSelectedKey): void { $context = $this->context; - $context->arrayResult->reset(); + $context->arrayWrapper->getResult()->reset(); foreach ($context->keyWrappers as $wrapper) { $wrapper->getResult()->reset(); } $context->analyzed = false; $context->normalized = false; - if ($resetSelectedKey) { - $context->selectedKey = null; - $context->type = $context->arrayType; - $context->result = $context->arrayResult; - } + if ($resetSelectedKey) $context->selectedKey = null; } function getKeys(): array { @@ -61,6 +53,7 @@ class AssocWrapper extends Wrapper { } protected function _getWrapper($key): Wrapper { + if ($key === null) return $this->context->arrayWrapper; $wrapper = $context->keyWrappers[$key] ?? null; if ($wrapper === null) throw ValueException::invalid_key($key); return $wrapper; @@ -68,76 +61,57 @@ class AssocWrapper extends Wrapper { /** @param string|int|null $key */ function select($key=null): Wrapper { - $context = $this->context; - if ($key === null) { - $context->selectedKey = null; - $context->type = $context->arrayType; - $context->result = $context->arrayResult; - return $this; - } $wrapper = $this->_getWrapper($key); - $context->selectedKey = $key; - $context->type = $wrapper->getType(); - $context->result = $wrapper->getResult(); + $this->context->selectedKey = $key; return $wrapper; } - protected function _analyze(?array $params): int { - return -1; + /** + * @param AssocWrapperContext $context + * @param AssocWrapper $wrapper + */ + static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int { + return ScalarWrapper::_analyze($params, $context, $wrapper); } - protected function _normalize(?array $params): bool { - return false; + static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool { + return ScalarWrapper::_normalize($params, $context, $wrapper); } function getResult($key=false): Result { - if ($key === false) return $this->context->result; - elseif ($key === null) return $this->context->arrayResult; - else return $this->_getWrapper($key)->getResult(); + if ($key === false) $key = $this->context->selectedKey; + return $this->_getWrapper($key)->getResult(); } function getType($key=false): IType { - if ($key === false) return $this->context->type; - elseif ($key === null) return $this->context->arrayType; - else return $this->_getWrapper($key)->getType(); + if ($key === false) $key = $this->context->selectedKey; + return $this->_getWrapper($key)->getType(); } function get($default=null, $key=false) { $context = $this->context; - if (!$context->arrayResult->available) return $default; + if (!$context->arrayWrapper->isAvailable()) return $default; if ($key === false) $key = $context->selectedKey; - if ($key === null) return $context->input->get($context->valueKey); - else return $this->_getWrapper($key)->get($default); + return $this->_getWrapper($key)->get($default); } function set($value, ?array $params=null, $key=false): Wrapper { $context = $this->context; if ($key === false) $key = $context->selectedKey; - if ($key === null) { - $context->input->set($value, $context->valueKey); - $this->afterModify($params); - } else { - $this->_getWrapper($key)->set($value); - } + $this->_getWrapper($key)->set($value); return $this; } function unset(?array $params=null, $key=false): Wrapper { $context = $this->context; if ($key === false) $key = $context->selectedKey; - if ($key === null) { - $context->input->unset($context->valueKey); - $this->afterModify($params); - } else { - $this->_getWrapper($key)->unset(); - } + $this->_getWrapper($key)->unset(); return $this; } function format($format=null, $key=false): string { $context = $this->context; if ($key === false) $key = $context->selectedKey; - if ($key === null) return $this->_format($context, $format); - else return $this->_getWrapper($key)->format($format); + return $this->_getWrapper($key)->format($format); } } diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index 44fee29..a1a4693 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -1,30 +1,16 @@ arrayType = null; - $this->arrayResult = null; - } - - public ?IType $arrayType; - /** résultat de l'analyse du tableau */ - public ?ScalarResult $arrayResult; + public ?ScalarWrapper $arrayWrapper = null; /** liste des clés valides */ public array $keys; - /** @var ?IType[] */ - public array $keyTypes; - /** @var Wrapper[] */ public array $keyWrappers; } diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index cc28149..caf4c31 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -6,6 +6,7 @@ use nulib\ref\schema\ref_analyze; use nulib\ref\schema\ref_schema; use nulib\ValueException; use nur\sery\wip\schema\Result; +use nur\sery\wip\schema\Schema; use Throwable; /** @@ -45,13 +46,13 @@ class ScalarResult extends Result { $this->result[$name] = $value; } - protected function getMessage(string $key, ScalarSchema $schema): string { + 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(ScalarSchema $schema): int { + function setMissing( Schema $schema): int { $this->resultAvailable = true; $this->present = false; $this->available = false; @@ -67,7 +68,7 @@ class ScalarResult extends Result { } } - function setUnavailable(ScalarSchema $schema): int { + function setUnavailable( Schema $schema): int { $this->resultAvailable = true; $this->present = true; $this->available = false; @@ -83,7 +84,7 @@ class ScalarResult extends Result { } } - function setNull(ScalarSchema $schema): int { + function setNull( Schema $schema): int { $this->resultAvailable = true; $this->present = true; $this->available = true; @@ -99,7 +100,7 @@ class ScalarResult extends Result { } } - function setInvalid($value, ScalarSchema $schema, ?Throwable $exception=null): int { + function setInvalid($value, Schema $schema, ?Throwable $exception=null): int { $this->resultAvailable = true; $this->present = true; $this->available = true; diff --git a/src/schema/_scalar/ScalarSchema.php b/src/schema/_scalar/ScalarSchema.php index 5c14a5c..597a34b 100644 --- a/src/schema/_scalar/ScalarSchema.php +++ b/src/schema/_scalar/ScalarSchema.php @@ -11,12 +11,6 @@ use nur\sery\wip\schema\Wrapper; * Class ScalarSchema */ class ScalarSchema extends Schema { - //const METASCHEMA = ref_schema::VALUE_METASCHEMA; - //const NATURE_METASCHEMA = [ - // ...ref_schema::NATURE_METASCHEMA, - // ...ref_schema::SCALAR_NATURE_METASCHEMA, - //]; - /** * indiquer si $definition est une définition de schéma scalaire que * {@link normalize_definition()} pourrait normaliser diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 6f48a41..31f9ba9 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -4,6 +4,9 @@ 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; use nur\sery\wip\schema\Wrapper; @@ -12,15 +15,16 @@ use nur\sery\wip\schema\WrapperContext; /** * Class ScalarWrapper * - * @method ScalarWrapper reset() - * @method ScalarResult getResult() - * @method self set() - * @method self unset() + * @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(ScalarSchema $schema, &$value=null, $valueKey=null, ?array $params=null) { - $this->context = $context = new WrapperContext($schema, null, null, $params); + 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(); + $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 @@ -49,8 +53,7 @@ class ScalarWrapper extends Wrapper { } /** analyser la valeur et résoudre son type */ - protected function _analyze0(): int { - $context = $this->context; + protected static function _analyze0(WrapperContext $context): int { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; @@ -141,8 +144,10 @@ class ScalarWrapper extends Wrapper { } } - protected function _analyze(?array $params): int { - $context = $this->context; + /** + * @param ScalarWrapper $wrapper + */ + static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; @@ -152,15 +157,15 @@ class ScalarWrapper extends Wrapper { /** @var func $analyzerFunc */ $analyzerFunc = $schema->analyzerFunc; - if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context, $this]); - else $what = $this->_analyze0(); + if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context, $wrapper]); + else $what = self::_analyze0($context); if ($what !== ref_analyze::STRING) return $what; $value = $context->value; try { /** @var func $extractorFunc */ $extractorFunc = $schema->extractorFunc; - if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context, $this]); + if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context, $wrapper]); else $extracted = $context->type->extract($value); $context->value = $extracted; } catch (ValueException $e) { @@ -171,7 +176,7 @@ class ScalarWrapper extends Wrapper { try { /** @var func $parserFunc */ $parserFunc = $schema->parserFunc; - if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context, $this]); + if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context, $wrapper]); else $parsed = $context->type->parse($extracted); $context->value = $parsed; } catch (ValueException $e) { @@ -188,8 +193,10 @@ class ScalarWrapper extends Wrapper { } } - protected function _normalize(?array $params): bool { - $context = $this->context; + /** + * @param ScalarWrapper $wrapper + */ + static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; @@ -226,7 +233,7 @@ class ScalarWrapper extends Wrapper { $normalizerFunc = $schema->normalizerFunc; if ($normalizerFunc !== null) { $orig = $value; - $value = $normalizerFunc->invoke([$orig, $context, $this]); + $value = $normalizerFunc->invoke([$orig, $context, $wrapper]); $modified = $value !== $orig; } else { $modified = $context->type->verifix($value, $result, $schema); From ef7e8551aa4da50e25dc6d6c912632f2fde07097 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 13:49:36 +0400 Subject: [PATCH 12/55] modifs.mineures sans commentaires --- src/schema/_assoc/AssocWrapper.php | 19 ++++++++++++++++++- src/schema/_assoc/AssocWrapperContext.php | 13 +++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index a071c62..05fad7d 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -2,6 +2,7 @@ namespace nur\sery\wip\schema\_assoc; use nulib\ValueException; +use nur\sery\wip\schema\_scalar\ScalarResult; use nur\sery\wip\schema\_scalar\ScalarWrapper; use nur\sery\wip\schema\Result; use nur\sery\wip\schema\types\IType; @@ -71,7 +72,23 @@ class AssocWrapper extends Wrapper { * @param AssocWrapper $wrapper */ static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int { - return ScalarWrapper::_analyze($params, $context, $wrapper); + if ($context->ensureArray) { + $array = $context->input->get(); + if ($array === null) $context->input->set([]); + } + $what = ScalarWrapper::_analyze($params, $context, $wrapper); + /** @var ScalarResult $result */ + $result = $context->result; + if (!$result->valid) return $what; + foreach ($context->keyWrappers as $wrapper) { + $wrapper->analyze($params); + if (!$wrapper->isValid()) { + $result->setInvalid(null, $context->schema, $wrapper->getResult()->exception); + break; + #XXX + } + } + return $what; } static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool { diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index a1a4693..07b9f79 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -2,10 +2,23 @@ namespace nur\sery\wip\schema\_assoc; use nur\sery\wip\schema\_scalar\ScalarWrapper; +use nur\sery\wip\schema\input\Input; +use nur\sery\wip\schema\Schema; use nur\sery\wip\schema\Wrapper; use nur\sery\wip\schema\WrapperContext; class AssocWrapperContext extends WrapperContext { + function __construct(Schema $schema, ?Input $input, $valueKey, ?array $params) { + parent::__construct($schema, $input, $valueKey, $params); + $this->ensureArray = $params["ensure_array"] ?? false; + $this->ensureKeys = $params["ensure_keys"] ?? true; + $this->ensureOrder = $params["ensure_order"] ?? true; + } + + public bool $ensureArray; + public bool $ensureKeys; + public bool $ensureOrder; + public ?ScalarWrapper $arrayWrapper = null; /** liste des clés valides */ From 1fc4e7637b9686e8f821bd7e58c2db93eb70ae87 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 16:10:26 +0400 Subject: [PATCH 13/55] modifs.mineures sans commentaires --- src/php/access/AbstractAccess.php | 10 +++ src/php/access/ChainAccess.php | 57 ++++++++++++++ src/php/access/FormAccess.php | 84 +++++++++++++-------- src/php/access/GetAccess.php | 30 ++------ src/php/access/IAccess.php | 3 + src/php/access/IGetter.php | 6 ++ src/php/access/KeyAccess.php | 36 +++++---- src/php/access/PostAccess.php | 30 ++------ src/php/access/ShadowAccess.php | 9 +++ src/php/access/ValueAccess.php | 20 +++-- src/schema/Wrapper.php | 8 +- src/schema/WrapperContext.php | 10 ++- src/schema/_assoc/AssocWrapper.php | 28 +++++-- src/schema/_assoc/AssocWrapperContext.php | 10 ++- src/schema/_scalar/ScalarResult.php | 24 ++++++ src/schema/_scalar/ScalarWrapper.php | 4 +- src/schema/input/ChainInput.php | 5 ++ src/schema/input/IInput.php | 18 +++++ src/schema/input/Input.php | 6 +- tests/wip/schema/_assoc/AssocSchemaTest.php | 13 ++++ 20 files changed, 288 insertions(+), 123 deletions(-) create mode 100644 src/php/access/ChainAccess.php create mode 100644 src/schema/input/ChainInput.php create mode 100644 src/schema/input/IInput.php diff --git a/src/php/access/AbstractAccess.php b/src/php/access/AbstractAccess.php index 21dda22..f162ca5 100644 --- a/src/php/access/AbstractAccess.php +++ b/src/php/access/AbstractAccess.php @@ -8,6 +8,16 @@ use nulib\cl; * de {@link IAccess} */ abstract class AbstractAccess implements IAccess { + function __construct(?array $params=null) { + $this->allowEmpty = $params["allow_empty"] ?? true; + } + + protected bool $allowEmpty; + + function isAllowEmpty(): bool { + return $this->allowEmpty; + } + function inc(): int { $value = (int)$this->get(); $this->set(++$value); diff --git a/src/php/access/ChainAccess.php b/src/php/access/ChainAccess.php new file mode 100644 index 0000000..d08be7f --- /dev/null +++ b/src/php/access/ChainAccess.php @@ -0,0 +1,57 @@ +access = $access; + $this->key = $key; + } + + protected IAccess $access; + + /** @var int|string|array */ + protected $key; + + function isAllowEmpty(): bool { + return $this->access->isAllowEmpty(); + } + + function exists(): bool { + $key = $this->key; + if ($key === null) return false; + if (!$this->access->exists()) return false; + return cl::phas($this->access->get(), $key); + } + + function available(): bool { + $key = $this->key; + if ($key === null) return false; + if (!$this->access->available()) return false; + $array = $this->access->get(); + if (!cl::phas($array, $key)) return false; + return $this->isAllowEmpty() || cl::pget($array, $key) !== ""; + } + + function get($default=null) { + return cl::pget($this->access->get($default), $this->key); + } + + function set($value): void { + $array = $this->access->get(); + cl::pset($array, $this->key, $value); + $this->access->set($array); + } + + function del(): void { + $array = $this->access->get(); + cl::pdel($array, $this->key); + $this->access->set($array); + } + + function addKey($key): IAccess { + return new ChainAccess($this->access, cl::merge($this->key, $key)); + } +} diff --git a/src/php/access/FormAccess.php b/src/php/access/FormAccess.php index 7b3840d..db8d09a 100644 --- a/src/php/access/FormAccess.php +++ b/src/php/access/FormAccess.php @@ -8,66 +8,88 @@ use nulib\cl; */ class FormAccess extends AbstractAccess { function __construct($key, ?array $params=null) { + parent::__construct($params); $this->key = $key; - $this->allowEmpty = $params["allow_empty"] ?? false; } - /** @var int|string */ + /** @var int|string|array */ protected $key; - protected bool $allowEmpty; - - function exists(): bool { + protected function _exists(array $first, ?array $second=null): bool { $key = $this->key; if ($key === null) return false; - return array_key_exists($key, $_POST) || array_key_exists($key, $_GET); + if (cl::phas($first, $key)) return true; + return $second !== null && cl::phas($second, $key); } - public function available(): bool { + function exists(): bool { + return $this->_exists($_POST, $_GET); + } + + protected function _available(array $first, ?array $second=null): bool { $key = $this->key; if ($key === null) return false; - if (array_key_exists($key, $_POST)) { - return $this->allowEmpty || $_POST[$key] !== ""; - } elseif (array_key_exists($key, $_GET)) { - return $this->allowEmpty || $_GET[$key] !== ""; + if (cl::phas($first, $key)) { + return $this->allowEmpty || cl::pget($first, $key) !== ""; + } elseif ($second !== null && cl::phas($second, $key)) { + return $this->allowEmpty || cl::pget($second, $key) !== ""; } else { return false; } } - function get($default=null) { + public function available(): bool { + return $this->_available($_POST, $_GET); + } + + protected function _get($default, array $first, ?array $second=null) { $key = $this->key; if ($key === null) return $default; - if (array_key_exists($key, $_POST)) { - $value = $_POST[$key]; - if ($value === "" && !$this->allowEmpty) return $default; - return $value; - } elseif (array_key_exists($key, $_GET)) { - $value = $_GET[$key]; - if ($value === "" && !$this->allowEmpty) return $default; - return $value; + if (cl::phas($first, $key)) { + $value = cl::pget($first, $key); + if ($value !== "" || $this->allowEmpty) return $value; + } elseif ($second !== null && cl::phas($second, $key)) { + $value = cl::pget($second, $key); + if ($value !== "" || $this->allowEmpty) return $value; + } + return $default; + } + + function get($default=null) { + return $this->_get($default, $_POST, $_GET); + } + + function _set($value, array &$first, ?array &$second=null): void { + $key = $this->key; + if ($key === null) return; + if ($second !== null && !cl::phas($first, $key) && cl::phas($second, $key)) { + cl::pset($second, $key, $value); } else { - return $default; + cl::pset($first, $key, $value); } } function set($value): void { + $this->_set($value, $_POST, $_GET); + } + + function _del(array &$first, ?array &$second=null): void { $key = $this->key; if ($key === null) return; - if (!array_key_exists($key, $_POST) && array_key_exists($key, $_GET)) { - cl::set($_GET, $key, $value); + if ($second !== null && !cl::phas($first, $key) && cl::phas($second, $key)) { + cl::pdel($second, $key); } else { - cl::set($_POST, $key, $value); + cl::pdel($first, $key); } } function del(): void { - $key = $this->key; - if ($key === null) return; - if (!array_key_exists($key, $_POST) && array_key_exists($key, $_GET)) { - cl::del($_GET, $key); - } else { - cl::del($_POST, $key); - } + $this->_del($_POST, $_GET); + } + + function addKey($key): self { + return new static(cl::merge($this->key, $key), [ + "allow_empty" => $this->allowEmpty + ]); } } diff --git a/src/php/access/GetAccess.php b/src/php/access/GetAccess.php index 4b67367..ed42023 100644 --- a/src/php/access/GetAccess.php +++ b/src/php/access/GetAccess.php @@ -8,42 +8,22 @@ use nulib\cl; */ class GetAccess extends FormAccess { function exists(): bool { - $key = $this->key; - if ($key === null) return false; - return array_key_exists($key, $_GET); + return $this->_exists($_GET); } public function available(): bool { - $key = $this->key; - if ($key === null) return false; - if (array_key_exists($key, $_GET)) { - return $this->allowEmpty || $_GET[$key] !== ""; - } else { - return false; - } + return $this->_available($_GET); } function get($default=null) { - $key = $this->key; - if ($key === null) return $default; - if (array_key_exists($key, $_GET)) { - $value = $_GET[$key]; - if ($value === "" && !$this->allowEmpty) return $default; - return $value; - } else { - return $default; - } + return $this->_get($default, $_GET); } function set($value): void { - $key = $this->key; - if ($key === null) return; - cl::set($_GET, $key, $value); + $this->_set($value, $_GET); } function del(): void { - $key = $this->key; - if ($key === null) return; - cl::del($_GET, $key); + $this->_del($_GET); } } diff --git a/src/php/access/IAccess.php b/src/php/access/IAccess.php index 2581c8b..7987c4c 100644 --- a/src/php/access/IAccess.php +++ b/src/php/access/IAccess.php @@ -25,4 +25,7 @@ interface IAccess extends IGetter, ISetter, IDeleter { * tableau si $key===null */ function append($value, $key=null): void; + + /** retourner une instance permettant d'accéder à $value[$key] */ + function addKey($key): IAccess; } diff --git a/src/php/access/IGetter.php b/src/php/access/IGetter.php index d4b1b9c..430d908 100644 --- a/src/php/access/IGetter.php +++ b/src/php/access/IGetter.php @@ -11,6 +11,12 @@ interface IGetter { */ function exists(): bool; + /** + * @return bool true si cet objet autorise les chaines vides. si c'est le cas, + * {@link exists()} et {@link available()} sont fonctionnellement identiques + */ + function isAllowEmpty(): bool; + /** @return bool true si la valeur existe et est utilisable, false sinon */ function available(): bool; diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index 2421c5a..2f7b4c4 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -9,61 +9,67 @@ use nulib\cl; */ class KeyAccess extends AbstractAccess { function __construct(&$array, $key, ?array $params=null) { + parent::__construct($params); $this->array =& $array; $this->key = $key; $this->allowNull = $params["allow_null"] ?? true; $this->allowFalse = $params["allow_false"] ?? false; - $this->allowEmpty = $params["allow_empty"] ?? true; } /** @var array|ArrayAccess */ protected $array; - function reset(&$array): self { - $this->array =& $array; - return $this; - } - - /** @var int|string */ + /** @var int|string|array */ protected $key; protected bool $allowNull; protected bool $allowFalse; - protected bool $allowEmpty; + function reset(&$array): self { + $this->array =& $array; + return $this; + } function exists(): bool { $key = $this->key; if ($key === null) return false; - return cl::has($this->array, $key); + return cl::phas($this->array, $key); } function available(): bool { if (!$this->exists()) return false; - $value = cl::get($this->array, $this->key); + $value = cl::pget($this->array, $this->key); + if ($value === "") return $this->allowEmpty; if ($value === null) return $this->allowNull; if ($value === false) return $this->allowFalse; - if ($value === "") return $this->allowEmpty; return true; } function get($default=null) { if ($this->key === null) return $default; - $value = cl::get($this->array, $this->key, $default); + $value = cl::pget($this->array, $this->key, $default); + if ($value === "" && !$this->allowEmpty) return $default; if ($value === null && !$this->allowNull) return $default; if ($value === false && !$this->allowFalse) return $default; - if ($value === "" && !$this->allowEmpty) return $default; return $value; } function set($value): void { if ($this->key === null) return; - cl::set($this->array, $this->key, $value); + cl::pset($this->array, $this->key, $value); } function del(): void { if ($this->key === null) return; - cl::del($this->array, $this->key); + cl::pdel($this->array, $this->key); + } + + function addKey($key): self { + return new KeyAccess($this->array, cl::merge($this->key, $key), [ + "allow_empty" => $this->allowEmpty, + "allow_null" => $this->allowNull, + "allow_false" => $this->allowFalse, + ]); } } diff --git a/src/php/access/PostAccess.php b/src/php/access/PostAccess.php index 1756964..e9c7f13 100644 --- a/src/php/access/PostAccess.php +++ b/src/php/access/PostAccess.php @@ -8,42 +8,22 @@ use nulib\cl; */ class PostAccess extends FormAccess { function exists(): bool { - $key = $this->key; - if ($key === null) return false; - return array_key_exists($key, $_POST); + return $this->_exists($_POST); } public function available(): bool { - $key = $this->key; - if ($key === null) return false; - if (array_key_exists($key, $_POST)) { - return $this->allowEmpty || $_POST[$key] !== ""; - } else { - return false; - } + return $this->_available($_POST); } function get($default=null) { - $key = $this->key; - if ($key === null) return $default; - if (array_key_exists($key, $_POST)) { - $value = $_POST[$key]; - if ($value === "" && !$this->allowEmpty) return $default; - return $value; - } else { - return $default; - } + return $this->_get($default, $_POST); } function set($value): void { - $key = $this->key; - if ($key === null) return; - cl::set($_POST, $key, $value); + $this->_set($value, $_POST); } function del(): void { - $key = $this->key; - if ($key === null) return; - cl::del($_POST, $key); + $this->_del($_POST); } } diff --git a/src/php/access/ShadowAccess.php b/src/php/access/ShadowAccess.php index 229bad1..e4f1211 100644 --- a/src/php/access/ShadowAccess.php +++ b/src/php/access/ShadowAccess.php @@ -16,6 +16,7 @@ namespace nur\sery\wip\php\access; */ class ShadowAccess extends AbstractAccess { function __construct(IAccess $reader, IAccess $writer) { + parent::__construct(); $this->reader = $reader; $this->writer = $writer; $this->getter = $reader; @@ -27,6 +28,10 @@ class ShadowAccess extends AbstractAccess { protected IGetter $getter; + public function isAllowEmpty(): bool { + return $this->getter->isAllowEmpty(); + } + function exists(): bool { return $this->getter->exists(); } @@ -48,4 +53,8 @@ class ShadowAccess extends AbstractAccess { $this->writer->del(); $this->getter = $this->reader; } + + function addKey($key): IAccess { + return new ChainAccess($this, $key); + } } diff --git a/src/php/access/ValueAccess.php b/src/php/access/ValueAccess.php index 624092f..3b95431 100644 --- a/src/php/access/ValueAccess.php +++ b/src/php/access/ValueAccess.php @@ -6,25 +6,23 @@ namespace nur\sery\wip\php\access; */ class ValueAccess extends AbstractAccess { function __construct(&$value, ?array $params=null) { + parent::__construct($params); $this->value =& $value; $this->allowNull = $params["allow_null"] ?? false; $this->allowFalse = $params["allow_false"] ?? true; - $this->allowEmpty = $params["allow_empty"] ?? true; } /** @var mixed */ protected $value; - function reset(&$value): self { - $this->value =& $value; - return $this; - } - protected bool $allowNull; protected bool $allowFalse; - protected bool $allowEmpty; + function reset(&$value): self { + $this->value =& $value; + return $this; + } function exists(): bool { return $this->allowNull || $this->value !== null; @@ -53,4 +51,12 @@ class ValueAccess extends AbstractAccess { function del(): void { $this->value = null; } + + function addKey($key): KeyAccess { + return new KeyAccess($this->value, $key, [ + "allow_empty" => $this->allowEmpty, + "allow_null" => $this->allowNull, + "allow_false" => $this->allowFalse, + ]); + } } diff --git a/src/schema/Wrapper.php b/src/schema/Wrapper.php index 43cc54b..7c558e8 100644 --- a/src/schema/Wrapper.php +++ b/src/schema/Wrapper.php @@ -65,20 +65,20 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { } /** analyser la valeur */ - abstract static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int; + abstract static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int; function analyze(?array $params=null): bool { $context = $this->context; $reanalyze = $params["reanalyze"] ?? false; if ($context->analyzed && !$reanalyze) return false; - static::_analyze($params, $context, $this); + static::_analyze($context, $this, $params); $context->analyzed = true; return true; } /** normaliser la valeur */ - abstract static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool; + abstract static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool; function normalize(?array $params=null): bool { $context = $this->context; @@ -89,7 +89,7 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate { $renormalize = $params["renormalize"] ?? false; if ($renormalize || !$context->normalized) { - $modified = static::_normalize($params, $context, $this); + $modified = static::_normalize($context, $this, $params); $context->normalized = true; } else { $modified = false; diff --git a/src/schema/WrapperContext.php b/src/schema/WrapperContext.php index 58a7fe8..d22a81f 100644 --- a/src/schema/WrapperContext.php +++ b/src/schema/WrapperContext.php @@ -5,6 +5,10 @@ use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; class WrapperContext { + const DEFAULT_ANALYZE = true; + const DEFAULT_NORMALIZE = true; + const DEFAULT_THROW = true; + function __construct(Schema $schema, ?Input $input, $valueKey, ?array $params) { $this->resetParams($params); $this->schema = $schema; @@ -19,9 +23,9 @@ class WrapperContext { function resetParams(?array $params): void { $this->params = $params; - $this->analyze = $params["analyze"] ?? true; - $this->normalize = $params["normalize"] ?? true; - $this->throw = $params["throw"] ?? true; + $this->analyze = $params["analyze"] ?? self::DEFAULT_ANALYZE; + $this->normalize = $params["normalize"] ?? self::DEFAULT_NORMALIZE; + $this->throw = $params["throw"] ?? self::DEFAULT_THROW; } /** schéma de la valeur */ diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 05fad7d..5b71446 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -1,9 +1,11 @@ selectedKey = null; } + function reset(&$value, $valueKey=null, ?array $params=null): Wrapper { + $context = $this->context; + if ($value instanceof Input) $input = $value; + else $input = $this->newInput($value); + $context->input = $input; + $context->valueKey = $valueKey; + foreach ($context->keyWrappers as $key => $wrapper) { + $wrapper->reset($input->subInput($valueKey), $key); + } + $this->afterModify($params, true); + return $this; + } + function getKeys(): array { return $this->context->keys; } @@ -71,28 +86,27 @@ class AssocWrapper extends Wrapper { * @param AssocWrapperContext $context * @param AssocWrapper $wrapper */ - static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int { + static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int { if ($context->ensureArray) { $array = $context->input->get(); if ($array === null) $context->input->set([]); } - $what = ScalarWrapper::_analyze($params, $context, $wrapper); + $what = ScalarWrapper::_analyze($context, $wrapper, $params); /** @var ScalarResult $result */ $result = $context->result; if (!$result->valid) return $what; foreach ($context->keyWrappers as $wrapper) { $wrapper->analyze($params); if (!$wrapper->isValid()) { - $result->setInvalid(null, $context->schema, $wrapper->getResult()->exception); - break; - #XXX + $what = ref_analyze::INVALID; + $result->addInvalidMessage($wrapper); } } return $what; } - static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool { - return ScalarWrapper::_normalize($params, $context, $wrapper); + static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { + return ScalarWrapper::_normalize($context, $wrapper, $params); } function getResult($key=false): Result { diff --git a/src/schema/_assoc/AssocWrapperContext.php b/src/schema/_assoc/AssocWrapperContext.php index 07b9f79..c504197 100644 --- a/src/schema/_assoc/AssocWrapperContext.php +++ b/src/schema/_assoc/AssocWrapperContext.php @@ -8,11 +8,15 @@ use nur\sery\wip\schema\Wrapper; use nur\sery\wip\schema\WrapperContext; class AssocWrapperContext extends WrapperContext { + const DEFAULT_ENSURE_ARRAY = false; + 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); - $this->ensureArray = $params["ensure_array"] ?? false; - $this->ensureKeys = $params["ensure_keys"] ?? true; - $this->ensureOrder = $params["ensure_order"] ?? true; + $this->ensureArray = $params["ensure_array"] ?? self::DEFAULT_ENSURE_ARRAY; + $this->ensureKeys = $params["ensure_keys"] ?? self::DEFAULT_ENSURE_KEYS; + $this->ensureOrder = $params["ensure_order"] ?? self::DEFAULT_ENSURE_ORDER; } public bool $ensureArray; diff --git a/src/schema/_scalar/ScalarResult.php b/src/schema/_scalar/ScalarResult.php index caf4c31..59453eb 100644 --- a/src/schema/_scalar/ScalarResult.php +++ b/src/schema/_scalar/ScalarResult.php @@ -7,6 +7,7 @@ use nulib\ref\schema\ref_schema; use nulib\ValueException; use nur\sery\wip\schema\Result; use nur\sery\wip\schema\Schema; +use nur\sery\wip\schema\Wrapper; use Throwable; /** @@ -118,6 +119,29 @@ class ScalarResult extends Result { 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; diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index 31f9ba9..f9ba7db 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -147,7 +147,7 @@ class ScalarWrapper extends Wrapper { /** * @param ScalarWrapper $wrapper */ - static function _analyze(?array $params, WrapperContext $context, Wrapper $wrapper): int { + static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; @@ -196,7 +196,7 @@ class ScalarWrapper extends Wrapper { /** * @param ScalarWrapper $wrapper */ - static function _normalize(?array $params, WrapperContext $context, Wrapper $wrapper): bool { + static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; diff --git a/src/schema/input/ChainInput.php b/src/schema/input/ChainInput.php new file mode 100644 index 0000000..6e26061 --- /dev/null +++ b/src/schema/input/ChainInput.php @@ -0,0 +1,5 @@ +access($key)->del(); } + + function addKey($key): IInput { + return new ChainInput($this, $key); + } } diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index 38586bd..0ab3763 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -101,6 +101,19 @@ class AssocSchemaTest extends TestCase { } function testWrapper() { + $schema = new AssocSchema([ + "a" => "?string", + "b" => "?int", + "c" => "?bool", + ]); + $array = ["a" => " string ", "b" => " 42 ", "c" => false]; + $schema->getWrapper($array); + self::assertSame([ + "a" => "string", + "b" => 42, + "c" => false, + ], $array); + $schema = new AssocSchema([ "a" => "string", "b" => "int", From 39af99ffa4890cca1b5783d24ccd28e568f51222 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 16:56:36 +0400 Subject: [PATCH 14/55] modifs.mineures sans commentaires --- .../{ChainAccess.php => ChainKeyAccess.php} | 4 +- src/php/access/PropertyAccess.php | 95 +++++++++++++++++++ src/php/access/ShadowAccess.php | 2 +- 3 files changed, 98 insertions(+), 3 deletions(-) rename src/php/access/{ChainAccess.php => ChainKeyAccess.php} (91%) create mode 100644 src/php/access/PropertyAccess.php diff --git a/src/php/access/ChainAccess.php b/src/php/access/ChainKeyAccess.php similarity index 91% rename from src/php/access/ChainAccess.php rename to src/php/access/ChainKeyAccess.php index d08be7f..f2460f8 100644 --- a/src/php/access/ChainAccess.php +++ b/src/php/access/ChainKeyAccess.php @@ -3,7 +3,7 @@ namespace nur\sery\wip\php\access; use nulib\cl; -class ChainAccess extends AbstractAccess { +class ChainKeyAccess extends AbstractAccess { function __construct(IAccess $access, $key) { parent::__construct(); $this->access = $access; @@ -52,6 +52,6 @@ class ChainAccess extends AbstractAccess { } function addKey($key): IAccess { - return new ChainAccess($this->access, cl::merge($this->key, $key)); + return new ChainKeyAccess($this->access, cl::merge($this->key, $key)); } } diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php new file mode 100644 index 0000000..1550173 --- /dev/null +++ b/src/php/access/PropertyAccess.php @@ -0,0 +1,95 @@ +object =& $object; + $this->class = new ReflectionClass($object); + $this->name = $name; + $this->allowNull = $params["allow_null"] ?? true; + $this->allowFalse = $params["allow_false"] ?? false; + } + + protected object $object; + + protected ReflectionClass $class; + + protected string $name; + + protected bool $allowNull; + + protected bool $allowFalse; + + function reset(object &$object): self { + $this->object =& $object; + return $this; + } + + function exists(): bool { + return $this->class->hasProperty($this->name) + || property_exists($this->object, $this->name); + } + + protected function _property(): ReflectionProperty { + $property = $this->class->getProperty($this->name); + $property->setAccessible(true); + return $property; + } + + protected function _get($default=null) { + try { + return $this->_property()->getValue($this->object); + } catch (ReflectionException $e) { + } + $name = $this->name; + if (property_exists($this->object, $name)) { + return $this->object->$name; + } else { + return $default; + } + } + + function available(): bool { + if (!$this->exists()) return false; + $value = $this->_get(); + if ($value === "") return $this->allowEmpty; + if ($value === null) return $this->allowNull; + if ($value === false) return $this->allowFalse; + return true; + } + + function get($default=null) { + if (!$this->exists()) return $default; + $value = $this->_get(); + if ($value === "" && !$this->allowEmpty) return $default; + if ($value === null && !$this->allowNull) return $default; + if ($value === false && !$this->allowFalse) return $default; + return $value; + } + + protected function _set($value): void { + try { + $this->_property()->setValue($this->object, $value); + } catch (ReflectionException $e) { + $name = $this->name; + $this->object->$name = $value; + } + } + + function set($value): void { + $this->_set($value); + } + + function del(): void { + $this->_set(null); + } + + function addKey($key): IAccess { + return new ChainKeyAccess($this, $key); + } +} diff --git a/src/php/access/ShadowAccess.php b/src/php/access/ShadowAccess.php index e4f1211..ab0e33a 100644 --- a/src/php/access/ShadowAccess.php +++ b/src/php/access/ShadowAccess.php @@ -55,6 +55,6 @@ class ShadowAccess extends AbstractAccess { } function addKey($key): IAccess { - return new ChainAccess($this, $key); + return new ChainKeyAccess($this, $key); } } From c5bfa3940cd599db1882888fd6ef25ed8b75b03c Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 17:03:12 +0400 Subject: [PATCH 15/55] modifs.mineures sans commentaires --- src/php/access/PropertyAccess.php | 39 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index 1550173..fe09704 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -9,18 +9,25 @@ class PropertyAccess extends AbstractAccess { function __construct(object &$object, $name, ?array $params=null) { parent::__construct($params); $this->object =& $object; - $this->class = new ReflectionClass($object); $this->name = $name; + $class = new ReflectionClass($object); + try { + $property = $class->getProperty($this->name); + $property->setAccessible(true); + } catch (ReflectionException $e) { + $property = null; + } + $this->property = $property; $this->allowNull = $params["allow_null"] ?? true; $this->allowFalse = $params["allow_false"] ?? false; } protected object $object; - protected ReflectionClass $class; - protected string $name; + protected ?ReflectionProperty $property; + protected bool $allowNull; protected bool $allowFalse; @@ -31,23 +38,16 @@ class PropertyAccess extends AbstractAccess { } function exists(): bool { - return $this->class->hasProperty($this->name) + return $this->property !== null || property_exists($this->object, $this->name); } - protected function _property(): ReflectionProperty { - $property = $this->class->getProperty($this->name); - $property->setAccessible(true); - return $property; - } - protected function _get($default=null) { - try { - return $this->_property()->getValue($this->object); - } catch (ReflectionException $e) { - } $name = $this->name; - if (property_exists($this->object, $name)) { + $property = $this->property; + if ($property !== null) { + return $property->getValue($this->object); + } elseif (property_exists($this->object, $name)) { return $this->object->$name; } else { return $default; @@ -73,10 +73,11 @@ class PropertyAccess extends AbstractAccess { } protected function _set($value): void { - try { - $this->_property()->setValue($this->object, $value); - } catch (ReflectionException $e) { - $name = $this->name; + $name = $this->name; + $property = $this->property; + if ($property !== null) { + $property->setValue($this->object, $value); + } else { $this->object->$name = $value; } } From baa770d969b9bed7d804e77e8ef79b0cee942222 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 17:05:26 +0400 Subject: [PATCH 16/55] modifs.mineures sans commentaires --- src/php/access/PropertyAccess.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index fe09704..ec823c1 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -6,9 +6,9 @@ use ReflectionException; use ReflectionProperty; class PropertyAccess extends AbstractAccess { - function __construct(object &$object, $name, ?array $params=null) { + function __construct(object $object, $name, ?array $params=null) { parent::__construct($params); - $this->object =& $object; + $this->object = $object; $this->name = $name; $class = new ReflectionClass($object); try { @@ -32,8 +32,8 @@ class PropertyAccess extends AbstractAccess { protected bool $allowFalse; - function reset(object &$object): self { - $this->object =& $object; + function reset(object $object): self { + $this->object = $object; return $this; } From 19f6f9c9e1b47fef1cc3bec739424a3e9bf4d7e7 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 18:31:49 +0400 Subject: [PATCH 17/55] modifs.mineures sans commentaires --- src/php/access/ChainAccess.php | 150 ++++++++++++++++++++++++++++++ src/php/access/ChainKeyAccess.php | 57 ------------ src/php/access/PropertyAccess.php | 2 +- src/php/access/ShadowAccess.php | 2 +- 4 files changed, 152 insertions(+), 59 deletions(-) create mode 100644 src/php/access/ChainAccess.php delete mode 100644 src/php/access/ChainKeyAccess.php diff --git a/src/php/access/ChainAccess.php b/src/php/access/ChainAccess.php new file mode 100644 index 0000000..cd3d1cd --- /dev/null +++ b/src/php/access/ChainAccess.php @@ -0,0 +1,150 @@ +access = $access; + $this->key = $key; + $this->accessType = $params["access_type"] ?? self::ACCESS_AUTO; + } + + protected IAccess $access; + + /** @var int|string|array */ + protected $key; + + protected int $accessType; + + protected function _accessType($access, $key): int { + $accessType = $this->accessType; + if ($accessType === self::ACCESS_AUTO) { + if (is_object($access) && is_string($key)) { + $accessType = self::ACCESS_PROPERTY; + } else { + $accessType = self::ACCESS_KEY; + } + } + return $accessType; + } + + protected function _has(): bool { + $src = $this->access->get(); + $key = $this->key; + $accessType = $this->_accessType($src, $key); + if ($accessType === self::ACCESS_KEY) { + return cl::phas($src, $key); + } elseif ($accessType === self::ACCESS_PROPERTY) { + $class = new ReflectionClass($src); + return $class->hasProperty($key) || property_exists($src, $key); + } else { + throw StateException::unexpected_state(); + } + } + + protected function _get($default=null) { + $src = $this->access->get(); + $key = $this->key; + $accessType = $this->_accessType($src, $key); + if ($accessType === self::ACCESS_KEY) { + return cl::pget($src, $key); + } elseif ($accessType === self::ACCESS_PROPERTY) { + $class = new ReflectionClass($src); + try { + $property = $class->getProperty($key); + $property->setAccessible(true); + } catch (ReflectionException $e) { + $property = null; + } + if ($property !== null) { + return $property->getValue($src); + } elseif (property_exists($src, $key)) { + return $src->$key; + } else { + return $default; + } + } else { + throw StateException::unexpected_state(); + } + } + + protected function _pset(object $dest, $name, $value): void { + $class = new ReflectionClass($dest); + try { + $property = $class->getProperty($name); + $property->setAccessible(true); + } catch (ReflectionException $e) { + $property = null; + } + if ($property !== null) { + $property->setValue($dest, $value); + } else { + $dest->$name = $value; + } + } + + function isAllowEmpty(): bool { + return $this->access->isAllowEmpty(); + } + + function exists(): bool { + if ($this->key === null) return false; + if (!$this->access->exists()) return false; + return $this->_has(); + } + + function available(): bool { + if ($this->key === null) return false; + if (!$this->access->available()) return false; + if (!$this->_has()) return false; + return $this->isAllowEmpty() || $this->_get() !== ""; + } + + function get($default=null) { + return $this->_get($default); + } + + function set($value): void { + $dest = $this->access->get(); + $key = $this->key; + $accessType = $this->_accessType($dest, $key); + if ($accessType === self::ACCESS_KEY) { + cl::pset($dest, $key, $value); + $this->access->set($dest); + } elseif ($accessType === self::ACCESS_PROPERTY) { + $this->_pset($dest, $key, $value); + } else { + throw StateException::unexpected_state(); + } + } + + function del(): void { + $dest = $this->access->get(); + $key = $this->key; + $accessType = $this->_accessType($dest, $key); + if ($accessType === self::ACCESS_KEY) { + cl::pdel($dest, $key); + $this->access->set($dest); + } elseif ($accessType === self::ACCESS_PROPERTY) { + $this->_pset($dest, $key, null); + } else { + throw StateException::unexpected_state(); + } + } + + function addKey($key, ?array $params=null): IAccess { + $accessType = $params["access_type"] ?? self::ACCESS_AUTO; + if ($accessType === self::ACCESS_KEY && $accessType === $this->accessType) { + return new ChainAccess($this->access, cl::merge($this->key, $key)); + } else { + return new ChainAccess($this, $key); + } + } +} diff --git a/src/php/access/ChainKeyAccess.php b/src/php/access/ChainKeyAccess.php deleted file mode 100644 index f2460f8..0000000 --- a/src/php/access/ChainKeyAccess.php +++ /dev/null @@ -1,57 +0,0 @@ -access = $access; - $this->key = $key; - } - - protected IAccess $access; - - /** @var int|string|array */ - protected $key; - - function isAllowEmpty(): bool { - return $this->access->isAllowEmpty(); - } - - function exists(): bool { - $key = $this->key; - if ($key === null) return false; - if (!$this->access->exists()) return false; - return cl::phas($this->access->get(), $key); - } - - function available(): bool { - $key = $this->key; - if ($key === null) return false; - if (!$this->access->available()) return false; - $array = $this->access->get(); - if (!cl::phas($array, $key)) return false; - return $this->isAllowEmpty() || cl::pget($array, $key) !== ""; - } - - function get($default=null) { - return cl::pget($this->access->get($default), $this->key); - } - - function set($value): void { - $array = $this->access->get(); - cl::pset($array, $this->key, $value); - $this->access->set($array); - } - - function del(): void { - $array = $this->access->get(); - cl::pdel($array, $this->key); - $this->access->set($array); - } - - function addKey($key): IAccess { - return new ChainKeyAccess($this->access, cl::merge($this->key, $key)); - } -} diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index ec823c1..832ea88 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -91,6 +91,6 @@ class PropertyAccess extends AbstractAccess { } function addKey($key): IAccess { - return new ChainKeyAccess($this, $key); + return new ChainAccess($this, $key); } } diff --git a/src/php/access/ShadowAccess.php b/src/php/access/ShadowAccess.php index ab0e33a..e4f1211 100644 --- a/src/php/access/ShadowAccess.php +++ b/src/php/access/ShadowAccess.php @@ -55,6 +55,6 @@ class ShadowAccess extends AbstractAccess { } function addKey($key): IAccess { - return new ChainKeyAccess($this, $key); + return new ChainAccess($this, $key); } } From f4e252a6e0a716e1743a7bab861336008937d560 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 19:32:27 +0400 Subject: [PATCH 18/55] modifs.mineures sans commentaires --- src/php/access/AbstractAccess.php | 4 +- src/php/access/FormAccess.php | 2 + src/php/access/KeyAccess.php | 88 ++++++++++++++++-------- src/php/access/ValueAccess.php | 62 ----------------- src/schema/input/Input.php | 44 ++++-------- tests/wip/php/access/KeyAccessTest.php | 64 ++++++++++++++++- tests/wip/php/access/ValueAccessTest.php | 69 ------------------- 7 files changed, 143 insertions(+), 190 deletions(-) delete mode 100644 src/php/access/ValueAccess.php delete mode 100644 tests/wip/php/access/ValueAccessTest.php diff --git a/src/php/access/AbstractAccess.php b/src/php/access/AbstractAccess.php index f162ca5..417d2cb 100644 --- a/src/php/access/AbstractAccess.php +++ b/src/php/access/AbstractAccess.php @@ -8,8 +8,10 @@ use nulib\cl; * de {@link IAccess} */ abstract class AbstractAccess implements IAccess { + const ALLOW_EMPTY = true; + function __construct(?array $params=null) { - $this->allowEmpty = $params["allow_empty"] ?? true; + $this->allowEmpty = $params["allow_empty"] ?? static::ALLOW_EMPTY; } protected bool $allowEmpty; diff --git a/src/php/access/FormAccess.php b/src/php/access/FormAccess.php index db8d09a..92c2a8c 100644 --- a/src/php/access/FormAccess.php +++ b/src/php/access/FormAccess.php @@ -7,6 +7,8 @@ use nulib\cl; * Class FormAccess: accès à une valeur de $_POST puis $_GET, dans cet ordre */ class FormAccess extends AbstractAccess { + const ALLOW_EMPTY = false; + function __construct($key, ?array $params=null) { parent::__construct($params); $this->key = $key; diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index 2f7b4c4..b6e5979 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -3,70 +3,102 @@ namespace nur\sery\wip\php\access; use ArrayAccess; use nulib\cl; +use stdClass; /** - * Class KeyAccess: accès à une valeur d'une clé dans un tableau + * Class KeyAccess: accès + * - soit à une valeur d'un chemin de clé dans un tableau (si $key !== null) + * - soit à une valeur scalaire (si $key === null) */ class KeyAccess extends AbstractAccess { - function __construct(&$array, $key, ?array $params=null) { + const ALLOW_NULL = null; + const ALLOW_FALSE = null; + + function __construct(&$dest, $key=null, ?array $params=null) { parent::__construct($params); - $this->array =& $array; + $this->dest =& $dest; $this->key = $key; - $this->allowNull = $params["allow_null"] ?? true; - $this->allowFalse = $params["allow_false"] ?? false; + $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL; + $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE; } - /** @var array|ArrayAccess */ - protected $array; + /** @var mixed|array|ArrayAccess */ + protected $dest; - /** @var int|string|array */ + /** @var null|int|string|array */ protected $key; - protected bool $allowNull; - - protected bool $allowFalse; - - function reset(&$array): self { - $this->array =& $array; + function reset(&$dest, $key=null): self { + $this->dest =& $dest; + $this->key = $key; return $this; } + function resetKey($key=null): self { + $this->key = $key; + return $this; + } + + protected ?bool $allowNull; + + protected function isAllowNull(): bool { + $allowNull = $this->allowNull; + if ($allowNull !== null) return $allowNull; + return $this->key !== null; + } + + protected ?bool $allowFalse; + + protected function isAllowFalse(): bool { + $allowFalse = $this->allowFalse; + if ($allowFalse !== null) return $allowFalse; + return $this->key === null; + } + function exists(): bool { $key = $this->key; - if ($key === null) return false; - return cl::phas($this->array, $key); + if ($key === null) { + return $this->isAllowNull() || $this->dest !== null; + } else { + return cl::phas($this->dest, $key); + } } function available(): bool { if (!$this->exists()) return false; - $value = cl::pget($this->array, $this->key); + $key = $this->key; + if ($key === null) $value = $this->dest; + else $value = cl::pget($this->dest, $key); if ($value === "") return $this->allowEmpty; - if ($value === null) return $this->allowNull; - if ($value === false) return $this->allowFalse; + if ($value === null) return $this->isAllowNull(); + if ($value === false) return $this->isAllowFalse(); return true; } function get($default=null) { - if ($this->key === null) return $default; - $value = cl::pget($this->array, $this->key, $default); + $key = $this->key; + if ($key === null) $value = $this->dest; + else $value = cl::pget($this->dest, $key, $default); if ($value === "" && !$this->allowEmpty) return $default; - if ($value === null && !$this->allowNull) return $default; - if ($value === false && !$this->allowFalse) return $default; + if ($value === null && !$this->isAllowNull()) return $default; + if ($value === false && !$this->isAllowFalse()) return $default; return $value; } function set($value): void { - if ($this->key === null) return; - cl::pset($this->array, $this->key, $value); + $key = $this->key; + if ($key === null) $this->dest = $value; + else cl::pset($this->dest, $key, $value); } function del(): void { - if ($this->key === null) return; - cl::pdel($this->array, $this->key); + $key = $this->key; + if ($key === null) $this->dest = null; + else cl::pdel($this->dest, $key); } function addKey($key): self { - return new KeyAccess($this->array, cl::merge($this->key, $key), [ + return new KeyAccess($this->dest, cl::merge($this->key, $key), [ "allow_empty" => $this->allowEmpty, "allow_null" => $this->allowNull, "allow_false" => $this->allowFalse, diff --git a/src/php/access/ValueAccess.php b/src/php/access/ValueAccess.php deleted file mode 100644 index 3b95431..0000000 --- a/src/php/access/ValueAccess.php +++ /dev/null @@ -1,62 +0,0 @@ -value =& $value; - $this->allowNull = $params["allow_null"] ?? false; - $this->allowFalse = $params["allow_false"] ?? true; - } - - /** @var mixed */ - protected $value; - - protected bool $allowNull; - - protected bool $allowFalse; - - function reset(&$value): self { - $this->value =& $value; - return $this; - } - - function exists(): bool { - return $this->allowNull || $this->value !== null; - } - - function available(): bool { - if (!$this->exists()) return false; - $value = $this->value; - if ($value === false) return $this->allowFalse; - if ($value === "") return $this->allowEmpty; - return true; - } - - function get($default=null) { - $value = $this->value; - if ($value === null && !$this->allowNull) return $default; - if ($value === false && !$this->allowFalse) return $default; - if ($value === "" && !$this->allowEmpty) return $default; - return $value; - } - - function set($value): void { - $this->value = $value; - } - - function del(): void { - $this->value = null; - } - - function addKey($key): KeyAccess { - return new KeyAccess($this->value, $key, [ - "allow_empty" => $this->allowEmpty, - "allow_null" => $this->allowNull, - "allow_false" => $this->allowFalse, - ]); - } -} diff --git a/src/schema/input/Input.php b/src/schema/input/Input.php index 1ee3c7e..6c63ed9 100644 --- a/src/schema/input/Input.php +++ b/src/schema/input/Input.php @@ -1,9 +1,8 @@ value =& $value; - $this->allowEmpty = $params["allow_empty"] ?? static::ALLOW_EMPTY; - } - - /** @var mixed */ - protected $value; - - /** - * @var bool comment considérer une chaine vide: "" si allowEmpty, null sinon - */ - protected $allowEmpty; - - protected ?ValueAccess $valueAccess = null; - protected ?array $keyAccess = null; - - protected function access($key): IAccess { - if ($key === null) { - return $this->valueAccess ??= new ValueAccess($this->value, [ + function __construct(&$dest=null, ?array $params=null) { + if (is_object($dest)) { + $this->access = new PropertyAccess($dest, null, [ + "allow_empty" => $params["allow_empty"] ?? static::ALLOW_EMPTY, "allow_null" => true, - "allow_empty" => $this->allowEmpty, ]); } else { - return $this->keyAccess[$key] ??= new KeyAccess($this->value, $key, [ - "allow_empty" => $this->allowEmpty, + $this->access = new KeyAccess($dest, null, [ + "allow_empty" => $params["allow_empty"] ?? static::ALLOW_EMPTY, + "allow_null" => true, ]); } } + protected KeyAccess $access; + /** tester si la valeur existe sans tenir compte de $allowEmpty */ function isPresent($key=null): bool { - return $this->access($key)->exists(); + return $this->access->resetKey($key)->exists(); } /** tester si la valeur est disponible en tenant compte de $allowEmpty */ function isAvailable($key=null): bool { - return $this->access($key)->available(); + return $this->access->resetKey($key)->available(); } function get($key=null) { - return $this->access($key)->get(); + return $this->access->resetKey($key)->get(); } function set($value, $key=null): void { - $this->access($key)->set($value); + $this->access->resetKey($key)->set($value); } function unset($key=null): void { - $this->access($key)->del(); + $this->access->resetKey($key)->del(); } function addKey($key): IInput { diff --git a/tests/wip/php/access/KeyAccessTest.php b/tests/wip/php/access/KeyAccessTest.php index 2b1c8ff..d71eb8e 100644 --- a/tests/wip/php/access/KeyAccessTest.php +++ b/tests/wip/php/access/KeyAccessTest.php @@ -5,7 +5,69 @@ use nulib\tests\TestCase; use stdClass; class KeyAccessTest extends TestCase { - function testAccess() { + function testValueAccess() { + $default = new stdClass(); + + # + $i = null; + $a = new KeyAccess($i); + self::assertFalse($a->exists()); + self::assertFalse($a->available()); + self::assertSame($default, $a->get($default)); + + $i = false; + $a = new KeyAccess($i); + self::assertTrue($a->exists()); + self::assertTrue($a->available()); + self::assertSame(false, $a->get($default)); + + $i = ""; + $a = new KeyAccess($i); + self::assertTrue($a->exists()); + self::assertTrue($a->available()); + self::assertSame("", $a->get($default)); + + # + $i = null; + $a = new KeyAccess($i, null, ["allow_null" => false]); + self::assertFalse($a->exists()); + self::assertFalse($a->available()); + self::assertSame($default, $a->get($default)); + + $i = null; + $a = new KeyAccess($i, null, ["allow_null" => true]); + self::assertTrue($a->exists()); + self::assertTrue($a->available()); + self::assertSame(null, $a->get($default)); + + # + $i = false; + $a = new KeyAccess($i, null, ["allow_false" => false]); + self::assertTrue($a->exists()); + self::assertFalse($a->available()); + self::assertSame($default, $a->get($default)); + + $i = false; + $a = new KeyAccess($i, null, ["allow_false" => true]); + self::assertTrue($a->exists()); + self::assertTrue($a->available()); + self::assertSame(false, $a->get($default)); + + # + $i = ""; + $a = new KeyAccess($i, null, ["allow_empty" => false]); + self::assertTrue($a->exists()); + self::assertFalse($a->available()); + self::assertSame($default, $a->get($default)); + + $i = ""; + $a = new KeyAccess($i, null, ["allow_empty" => true]); + self::assertTrue($a->exists()); + self::assertTrue($a->available()); + self::assertSame("", $a->get($default)); + } + + function testArrayAccess() { $default = new stdClass(); $array = ["null" => null, "false" => false, "empty" => ""]; diff --git a/tests/wip/php/access/ValueAccessTest.php b/tests/wip/php/access/ValueAccessTest.php deleted file mode 100644 index 3bd9333..0000000 --- a/tests/wip/php/access/ValueAccessTest.php +++ /dev/null @@ -1,69 +0,0 @@ -exists()); - self::assertFalse($a->available()); - self::assertSame($default, $a->get($default)); - - $i = false; - $a = new ValueAccess($i); - self::assertTrue($a->exists()); - self::assertTrue($a->available()); - self::assertSame(false, $a->get($default)); - - $i = ""; - $a = new ValueAccess($i); - self::assertTrue($a->exists()); - self::assertTrue($a->available()); - self::assertSame("", $a->get($default)); - - # - $i = null; - $a = new ValueAccess($i, ["allow_null" => false]); - self::assertFalse($a->exists()); - self::assertFalse($a->available()); - self::assertSame($default, $a->get($default)); - - $i = null; - $a = new ValueAccess($i, ["allow_null" => true]); - self::assertTrue($a->exists()); - self::assertTrue($a->available()); - self::assertSame(null, $a->get($default)); - - # - $i = false; - $a = new ValueAccess($i, ["allow_false" => false]); - self::assertTrue($a->exists()); - self::assertFalse($a->available()); - self::assertSame($default, $a->get($default)); - - $i = false; - $a = new ValueAccess($i, ["allow_false" => true]); - self::assertTrue($a->exists()); - self::assertTrue($a->available()); - self::assertSame(false, $a->get($default)); - - # - $i = ""; - $a = new ValueAccess($i, ["allow_empty" => false]); - self::assertTrue($a->exists()); - self::assertFalse($a->available()); - self::assertSame($default, $a->get($default)); - - $i = ""; - $a = new ValueAccess($i, ["allow_empty" => true]); - self::assertTrue($a->exists()); - self::assertTrue($a->available()); - self::assertSame("", $a->get($default)); - } -} From 6e8245dbcb58caec8f4c786c3959c1ceb3d7e405 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 19 Mar 2025 20:34:46 +0400 Subject: [PATCH 19/55] modifs.mineures sans commentaires --- src/php/access/KeyAccess.php | 3 +- src/php/access/PropertyAccess.php | 49 +++++++++++++++++++++++-------- src/schema/input/Input.php | 3 +- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index b6e5979..b65b86d 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -3,7 +3,6 @@ namespace nur\sery\wip\php\access; use ArrayAccess; use nulib\cl; -use stdClass; /** * Class KeyAccess: accès @@ -13,7 +12,7 @@ use stdClass; class KeyAccess extends AbstractAccess { const ALLOW_NULL = null; const ALLOW_FALSE = null; - + function __construct(&$dest, $key=null, ?array $params=null) { parent::__construct($params); $this->dest =& $dest; diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index 832ea88..d27493f 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -6,7 +6,10 @@ use ReflectionException; use ReflectionProperty; class PropertyAccess extends AbstractAccess { - function __construct(object $object, $name, ?array $params=null) { + const ALLOW_NULL = true; + const ALLOW_FALSE = false; + + function __construct(object $object, ?string $name=null, ?array $params=null) { parent::__construct($params); $this->object = $object; $this->name = $name; @@ -18,34 +21,44 @@ class PropertyAccess extends AbstractAccess { $property = null; } $this->property = $property; - $this->allowNull = $params["allow_null"] ?? true; - $this->allowFalse = $params["allow_false"] ?? false; + $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL; + $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE; } protected object $object; - protected string $name; + protected ?string $name; protected ?ReflectionProperty $property; + function reset(object $object, ?string $name=null): self { + $this->object = $object; + $this->name = $name; + return $this; + } + + function resetKey($name=null): self { + $this->name = $name; + return $this; + } + protected bool $allowNull; protected bool $allowFalse; - function reset(object $object): self { - $this->object = $object; - return $this; - } - function exists(): bool { - return $this->property !== null - || property_exists($this->object, $this->name); + $name = $this->name; + return $name === null + || $this->property !== null + || property_exists($this->object, $name); } protected function _get($default=null) { $name = $this->name; $property = $this->property; - if ($property !== null) { + if ($name === null) { + return $this->object; + } elseif ($property !== null) { return $property->getValue($this->object); } elseif (property_exists($this->object, $name)) { return $this->object->$name; @@ -75,7 +88,17 @@ class PropertyAccess extends AbstractAccess { protected function _set($value): void { $name = $this->name; $property = $this->property; - if ($property !== null) { + if ($name === null) { + $this->object = $value; + $class = new ReflectionClass($value); + try { + $property = $class->getProperty($this->name); + $property->setAccessible(true); + } catch (ReflectionException $e) { + $property = null; + } + $this->property = $property; + } elseif ($property !== null) { $property->setValue($this->object, $value); } else { $this->object->$name = $value; diff --git a/src/schema/input/Input.php b/src/schema/input/Input.php index 6c63ed9..e951a62 100644 --- a/src/schema/input/Input.php +++ b/src/schema/input/Input.php @@ -1,6 +1,7 @@ Date: Thu, 20 Mar 2025 08:01:50 +0400 Subject: [PATCH 20/55] modifs.mineures sans commentaires --- src/php/access/ChainAccess.php | 35 ++++++--- src/php/access/FormAccess.php | 22 ++++-- src/php/access/KeyAccess.php | 23 ++++-- src/php/access/PropertyAccess.php | 85 +++++++++++++-------- src/schema/TODO.md | 3 - src/schema/_assoc/AssocWrapper.php | 28 ++++--- src/schema/_scalar/ScalarWrapper.php | 12 +-- src/schema/input/ChainInput.php | 5 -- src/schema/input/FormInput.php | 16 ++-- src/schema/input/GetInput.php | 6 +- src/schema/input/IInput.php | 18 ----- src/schema/input/Input.php | 36 ++++++--- src/schema/input/PostInput.php | 6 +- src/schema/types/IType.php | 4 +- src/schema/types/tarray.php | 2 +- src/schema/types/tbool.php | 2 +- src/schema/types/tcallable.php | 2 +- src/schema/types/tcontent.php | 2 +- src/schema/types/tfloat.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 +- tests/wip/schema/_assoc/AssocSchemaTest.php | 27 ++++++- 26 files changed, 214 insertions(+), 134 deletions(-) delete mode 100644 src/schema/input/ChainInput.php delete mode 100644 src/schema/input/IInput.php diff --git a/src/php/access/ChainAccess.php b/src/php/access/ChainAccess.php index cd3d1cd..299c01d 100644 --- a/src/php/access/ChainAccess.php +++ b/src/php/access/ChainAccess.php @@ -9,6 +9,10 @@ use ReflectionException; class ChainAccess extends AbstractAccess { const ACCESS_AUTO = 0, ACCESS_KEY = 1, ACCESS_PROPERTY = 2; + private static function unexpected_access_type(): StateException { + return StateException::unexpected_state("access_type"); + } + function __construct(IAccess $access, $key, ?array $params=null) { parent::__construct(); $this->access = $access; @@ -18,7 +22,7 @@ class ChainAccess extends AbstractAccess { protected IAccess $access; - /** @var int|string|array */ + /** @var null|int|string|array */ protected $key; protected int $accessType; @@ -45,7 +49,7 @@ class ChainAccess extends AbstractAccess { $class = new ReflectionClass($src); return $class->hasProperty($key) || property_exists($src, $key); } else { - throw StateException::unexpected_state(); + throw self::unexpected_access_type(); } } @@ -71,7 +75,7 @@ class ChainAccess extends AbstractAccess { return $default; } } else { - throw StateException::unexpected_state(); + throw self::unexpected_access_type(); } } @@ -95,23 +99,30 @@ class ChainAccess extends AbstractAccess { } function exists(): bool { - if ($this->key === null) return false; if (!$this->access->exists()) return false; + if ($this->key === null) return true; return $this->_has(); } function available(): bool { - if ($this->key === null) return false; if (!$this->access->available()) return false; + if ($this->key === null) return true; if (!$this->_has()) return false; return $this->isAllowEmpty() || $this->_get() !== ""; } function get($default=null) { + if ($this->key === null) { + return $this->access->get($default); + } return $this->_get($default); } function set($value): void { + if ($this->key === null) { + $this->access->set($value); + return; + } $dest = $this->access->get(); $key = $this->key; $accessType = $this->_accessType($dest, $key); @@ -121,11 +132,15 @@ class ChainAccess extends AbstractAccess { } elseif ($accessType === self::ACCESS_PROPERTY) { $this->_pset($dest, $key, $value); } else { - throw StateException::unexpected_state(); + throw self::unexpected_access_type(); } } function del(): void { + if ($this->key === null) { + $this->access->del(); + return; + } $dest = $this->access->get(); $key = $this->key; $accessType = $this->_accessType($dest, $key); @@ -135,14 +150,16 @@ class ChainAccess extends AbstractAccess { } elseif ($accessType === self::ACCESS_PROPERTY) { $this->_pset($dest, $key, null); } else { - throw StateException::unexpected_state(); + throw self::unexpected_access_type(); } } function addKey($key, ?array $params=null): IAccess { - $accessType = $params["access_type"] ?? self::ACCESS_AUTO; + if ($key === null) return $this; + $accessType = $params["access_type"] ?? $this->accessType; if ($accessType === self::ACCESS_KEY && $accessType === $this->accessType) { - return new ChainAccess($this->access, cl::merge($this->key, $key)); + if ($this->key !== null) $key = cl::merge($this->key, $key); + return new ChainAccess($this->access, $key); } else { return new ChainAccess($this, $key); } diff --git a/src/php/access/FormAccess.php b/src/php/access/FormAccess.php index 92c2a8c..2368e75 100644 --- a/src/php/access/FormAccess.php +++ b/src/php/access/FormAccess.php @@ -14,12 +14,12 @@ class FormAccess extends AbstractAccess { $this->key = $key; } - /** @var int|string|array */ + /** @var null|int|string|array */ protected $key; protected function _exists(array $first, ?array $second=null): bool { $key = $this->key; - if ($key === null) return false; + if ($key === null) return true; if (cl::phas($first, $key)) return true; return $second !== null && cl::phas($second, $key); } @@ -30,7 +30,7 @@ class FormAccess extends AbstractAccess { protected function _available(array $first, ?array $second=null): bool { $key = $this->key; - if ($key === null) return false; + if ($key === null) return true; if (cl::phas($first, $key)) { return $this->allowEmpty || cl::pget($first, $key) !== ""; } elseif ($second !== null && cl::phas($second, $key)) { @@ -46,7 +46,7 @@ class FormAccess extends AbstractAccess { protected function _get($default, array $first, ?array $second=null) { $key = $this->key; - if ($key === null) return $default; + if ($key === null) return cl::merge($first, $second); if (cl::phas($first, $key)) { $value = cl::pget($first, $key); if ($value !== "" || $this->allowEmpty) return $value; @@ -63,7 +63,10 @@ class FormAccess extends AbstractAccess { function _set($value, array &$first, ?array &$second=null): void { $key = $this->key; - if ($key === null) return; + if ($key === null) { + # interdire la modification de la destination + return; + } if ($second !== null && !cl::phas($first, $key) && cl::phas($second, $key)) { cl::pset($second, $key, $value); } else { @@ -77,7 +80,10 @@ class FormAccess extends AbstractAccess { function _del(array &$first, ?array &$second=null): void { $key = $this->key; - if ($key === null) return; + if ($key === null) { + # interdire la modification de la destination + return; + } if ($second !== null && !cl::phas($first, $key) && cl::phas($second, $key)) { cl::pdel($second, $key); } else { @@ -90,7 +96,9 @@ class FormAccess extends AbstractAccess { } function addKey($key): self { - return new static(cl::merge($this->key, $key), [ + if ($key === null) return $this; + if ($this->key !== null) $key = cl::merge($this->key, $key); + return new static($key, [ "allow_empty" => $this->allowEmpty ]); } diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index b65b86d..38bfee5 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -12,15 +12,19 @@ use nulib\cl; class KeyAccess extends AbstractAccess { const ALLOW_NULL = null; const ALLOW_FALSE = null; + const PROTECT_DEST = false; function __construct(&$dest, $key=null, ?array $params=null) { parent::__construct($params); + $this->protectDest = $params["protect_dest"] ?? static::PROTECT_DEST; $this->dest =& $dest; $this->key = $key; $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL; $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE; } + protected bool $protectDest; + /** @var mixed|array|ArrayAccess */ protected $dest; @@ -86,21 +90,30 @@ class KeyAccess extends AbstractAccess { function set($value): void { $key = $this->key; - if ($key === null) $this->dest = $value; - else cl::pset($this->dest, $key, $value); + if ($key === null) { + if (!$this->protectDest) $this->dest = $value; + } else { + cl::pset($this->dest, $key, $value); + } } function del(): void { $key = $this->key; - if ($key === null) $this->dest = null; - else cl::pdel($this->dest, $key); + if ($key === null) { + if (!$this->protectDest) $this->dest = null; + } else { + cl::pdel($this->dest, $key); + } } function addKey($key): self { - return new KeyAccess($this->dest, cl::merge($this->key, $key), [ + if ($key === null) return $this; + if ($this->key !== null) $key = cl::merge($this->key, $key); + return new KeyAccess($this->dest, $key, [ "allow_empty" => $this->allowEmpty, "allow_null" => $this->allowNull, "allow_false" => $this->allowFalse, + "protect_dest" => $this->protectDest, ]); } } diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index d27493f..eadf80d 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -1,44 +1,65 @@ object = $object; - $this->name = $name; - $class = new ReflectionClass($object); - try { - $property = $class->getProperty($this->name); - $property->setAccessible(true); - } catch (ReflectionException $e) { - $property = null; - } - $this->property = $property; + $this->protectDest = $params["protect_dest"] ?? static::PROTECT_DEST; + $this->mapNames = $params["map_names"] ?? static::MAP_NAMES; + $this->_setName($name); + $this->_setDest($dest); $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL; $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE; } - protected object $object; + protected bool $protectDest; + + protected ?object $dest; + protected bool $mapNames; protected ?string $name; protected ?ReflectionProperty $property; - function reset(object $object, ?string $name=null): self { - $this->object = $object; + private function _setName(?string $name): void { + if ($this->mapNames) $name = str::us2camel($name); $this->name = $name; + } + + private function _setDest(?object $dest): void { + $this->dest = $dest; + $property = null; + $name = $this->name; + if ($dest !== null && $name !== null) { + $class = new ReflectionClass($dest); + try { + $property = $class->getProperty($name); + $property->setAccessible(true); + } catch (ReflectionException $e) { + } + } + $this->property = $property; + } + + function reset(?object $dest, ?string $name=null): self { + $this->_setName($name); + $this->_setDest($dest); return $this; } function resetKey($name=null): self { - $this->name = $name; + $this->_setName($name); return $this; } @@ -48,20 +69,23 @@ class PropertyAccess extends AbstractAccess { function exists(): bool { $name = $this->name; + if ($this->dest === null) return false; return $name === null || $this->property !== null - || property_exists($this->object, $name); + || property_exists($this->dest, $name); } protected function _get($default=null) { $name = $this->name; $property = $this->property; - if ($name === null) { - return $this->object; + if ($this->dest === null) { + return $default; + } elseif ($name === null) { + return $this->dest; } elseif ($property !== null) { - return $property->getValue($this->object); - } elseif (property_exists($this->object, $name)) { - return $this->object->$name; + return $property->getValue($this->dest); + } elseif (property_exists($this->dest, $name)) { + return $this->dest->$name; } else { return $default; } @@ -88,20 +112,14 @@ class PropertyAccess extends AbstractAccess { protected function _set($value): void { $name = $this->name; $property = $this->property; - if ($name === null) { - $this->object = $value; - $class = new ReflectionClass($value); - try { - $property = $class->getProperty($this->name); - $property->setAccessible(true); - } catch (ReflectionException $e) { - $property = null; - } - $this->property = $property; + if ($this->dest === null) { + throw StateException::unexpected_state("dest is null"); + } elseif ($name === null) { + if (!$this->protectDest) $this->_setDest($value); } elseif ($property !== null) { - $property->setValue($this->object, $value); + $property->setValue($this->dest, $value); } else { - $this->object->$name = $value; + $this->dest->$name = $value; } } @@ -114,6 +132,7 @@ class PropertyAccess extends AbstractAccess { } function addKey($key): IAccess { + if ($key === null) return $this; return new ChainAccess($this, $key); } } diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 745781f..5dce1ef 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,8 +1,5 @@ # nulib\schema -* faire PropertyAccess -* si l'argument de Input() est un objet, utiliser PropertyAccess au lieu de KeyAccess - * possibilité de forcer l'un ou l'autre (paramètre type=value|array|object) * ensureKeys() et orderKeys() se fait au niveau de access (ou input?) * valeurs composite/computed diff --git a/src/schema/_assoc/AssocWrapper.php b/src/schema/_assoc/AssocWrapper.php index 5b71446..1add86c 100644 --- a/src/schema/_assoc/AssocWrapper.php +++ b/src/schema/_assoc/AssocWrapper.php @@ -57,8 +57,9 @@ class AssocWrapper extends Wrapper { else $input = $this->newInput($value); $context->input = $input; $context->valueKey = $valueKey; - foreach ($context->keyWrappers as $key => $wrapper) { - $wrapper->reset($input->subInput($valueKey), $key); + foreach ($context->keyWrappers as $key => $keyWrapper) { + $keyInput = $input->addKey($valueKey); + $keyWrapper->reset($keyInput, $key, ["analyze" => false]); } $this->afterModify($params, true); return $this; @@ -88,25 +89,34 @@ class AssocWrapper extends Wrapper { */ static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int { if ($context->ensureArray) { - $array = $context->input->get(); - if ($array === null) $context->input->set([]); + $valueKey = $context->valueKey; + $array = $context->input->get($valueKey); + if ($array === null) $context->input->set([], $valueKey); } $what = ScalarWrapper::_analyze($context, $wrapper, $params); /** @var ScalarResult $result */ $result = $context->result; if (!$result->valid) return $what; - foreach ($context->keyWrappers as $wrapper) { - $wrapper->analyze($params); - if (!$wrapper->isValid()) { + foreach ($context->keyWrappers as $keyWrapper) { + $keyWrapper->analyze($params); + if (!$keyWrapper->isValid()) { $what = ref_analyze::INVALID; - $result->addInvalidMessage($wrapper); + $result->addInvalidMessage($keyWrapper); } } return $what; } + /** + * @param AssocWrapperContext $context + * @param AssocWrapper $wrapper + */ static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { - return ScalarWrapper::_normalize($context, $wrapper, $params); + $modified = ScalarWrapper::_normalize($context, $wrapper, $params); + foreach ($context->keyWrappers as $keyWrapper) { + if ($keyWrapper->normalize($params)) $modified = true; + } + return $modified; } function getResult($key=false): Result { diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index f9ba7db..588e8b3 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -204,7 +204,7 @@ class ScalarWrapper extends Wrapper { /** @var ScalarResult $result */ $result = $context->result; - $verifix = false; + $normalize = false; $modified = false; if ($result->resultAvailable) { if ($result->null) { @@ -215,19 +215,19 @@ class ScalarWrapper extends Wrapper { $normalizedValue = $result->normalizedValue; if ($normalizedValue !== null) { # la valeur normalisée est disponible - $input->set($normalizedValue); + $input->set($normalizedValue, $valueKey); $result->normalizedValue = null; $modified = true; } else { # normaliser la valeur - $verifix = true; + $normalize = true; } } } else { - $verifix = true; + $normalize = true; } - if ($verifix) { + if ($normalize) { $value = $input->get($valueKey); /** @var func $normalizerFunc */ $normalizerFunc = $schema->normalizerFunc; @@ -236,7 +236,7 @@ class ScalarWrapper extends Wrapper { $value = $normalizerFunc->invoke([$orig, $context, $wrapper]); $modified = $value !== $orig; } else { - $modified = $context->type->verifix($value, $result, $schema); + $modified = $context->type->normalize($value, $result, $schema); } if ($result->valid) $input->set($value, $valueKey); } diff --git a/src/schema/input/ChainInput.php b/src/schema/input/ChainInput.php deleted file mode 100644 index 6e26061..0000000 --- a/src/schema/input/ChainInput.php +++ /dev/null @@ -1,5 +0,0 @@ - $this->allowEmpty, - ]); + function __construct(&$dest=null, ?array $params=null) { + parent::__construct($dest, $params); + $this->access = new ShadowAccess($this->formAccess($this->access), $this->access); } - protected function access($key): IAccess { - return $this->keyAccess[$key] ??= new ShadowAccess($this->formAccess($key), new KeyAccess($this->value, $key, [ - "allow_empty" => $this->allowEmpty, - ])); + protected function formAccess(IAccess $access): IAccess { + return new FormAccess(null, [ + "allow_empty" => $access->isAllowEmpty(), + ]); } } diff --git a/src/schema/input/GetInput.php b/src/schema/input/GetInput.php index 766c8e5..558e1ab 100644 --- a/src/schema/input/GetInput.php +++ b/src/schema/input/GetInput.php @@ -11,9 +11,9 @@ use nur\sery\wip\php\access\IAccess; * une référence */ class GetInput extends FormInput { - protected function formAccess($key): IAccess { - return new GetAccess($key, [ - "allow_empty" => $this->allowEmpty, + protected function formAccess(IAccess $access): IAccess { + return new GetAccess(null, [ + "allow_empty" => $access->isAllowEmpty(), ]); } } diff --git a/src/schema/input/IInput.php b/src/schema/input/IInput.php deleted file mode 100644 index a25bf55..0000000 --- a/src/schema/input/IInput.php +++ /dev/null @@ -1,18 +0,0 @@ -access = new PropertyAccess($dest, null, [ - "allow_empty" => $params["allow_empty"] ?? static::ALLOW_EMPTY, + "allow_empty" => $allowEmpty, + "allow_null" => true, + ]); + } elseif ($accessType == self::ACCESS_KEY) { + $this->access = new KeyAccess($dest, null, [ + "allow_empty" => $allowEmpty, "allow_null" => true, ]); } else { - $this->access = new KeyAccess($dest, null, [ - "allow_empty" => $params["allow_empty"] ?? static::ALLOW_EMPTY, - "allow_null" => true, - ]); + throw self::unexpected_access_type(); } } @@ -51,7 +66,10 @@ class Input implements IInput { $this->access->resetKey($key)->del(); } - function addKey($key): IInput { - return new ChainInput($this, $key); + function addKey($key): Input { + if ($key === null) return $this; + $input = clone $this; + $input->access = $this->access->addKey($key); + return $input; } } diff --git a/src/schema/input/PostInput.php b/src/schema/input/PostInput.php index bf720ab..9b5fef6 100644 --- a/src/schema/input/PostInput.php +++ b/src/schema/input/PostInput.php @@ -11,9 +11,9 @@ use nur\sery\wip\php\access\PostAccess; * une référence */ class PostInput extends FormInput { - protected function formAccess($key): IAccess { - return new PostAccess($key, [ - "allow_empty" => $this->allowEmpty, + protected function formAccess(IAccess $access): IAccess { + return new PostAccess(null, [ + "allow_empty" => $access->isAllowEmpty(), ]); } } diff --git a/src/schema/types/IType.php b/src/schema/types/IType.php index 36f5fd4..9dbd48a 100644 --- a/src/schema/types/IType.php +++ b/src/schema/types/IType.php @@ -23,7 +23,7 @@ interface IType { /** * @return string la classe des objets gérés par ce format: le type attendu - * par {@link format()} et le type retourné par {@link verifix()} + * par {@link format()} et le type retourné par {@link normalize()} * * Les valeurs "mixed", "bool", "float", "int", "string" et "array" peuvent * aussi être retournées, bien qu'elles ne soient pas à proprement parler des @@ -106,7 +106,7 @@ interface IType { * si la valeur était déjà normalisée, ou si une erreur s'est produite, * retourner false. */ - function verifix(&$value, Result $result, Schema $schema): bool; + function normalize(&$value, Result $result, Schema $schema): bool; /** * formatter la valeur pour affichage. si $value n'est pas null, elle est diff --git a/src/schema/types/tarray.php b/src/schema/types/tarray.php index aba2aab..b62160d 100644 --- a/src/schema/types/tarray.php +++ b/src/schema/types/tarray.php @@ -49,7 +49,7 @@ class tarray extends _tstring { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_array($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/tbool.php b/src/schema/types/tbool.php index 50fa206..5e0795d 100644 --- a/src/schema/types/tbool.php +++ b/src/schema/types/tbool.php @@ -99,7 +99,7 @@ class tbool extends _tformatable { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_bool($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/tcallable.php b/src/schema/types/tcallable.php index f9e95d6..af6be72 100644 --- a/src/schema/types/tcallable.php +++ b/src/schema/types/tcallable.php @@ -43,7 +43,7 @@ class tcallable extends _tsimple { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if ($value instanceof func) { $result->setNormalized(); return false; diff --git a/src/schema/types/tcontent.php b/src/schema/types/tcontent.php index 1dfe455..2bb2912 100644 --- a/src/schema/types/tcontent.php +++ b/src/schema/types/tcontent.php @@ -36,7 +36,7 @@ abstract class tcontent extends _tunion { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_string($value) || is_array($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/tfloat.php b/src/schema/types/tfloat.php index db67257..f1befd1 100644 --- a/src/schema/types/tfloat.php +++ b/src/schema/types/tfloat.php @@ -43,7 +43,7 @@ class tfloat extends _tformatable { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_float($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/tgeneric.php b/src/schema/types/tgeneric.php index 16f86a8..492c57e 100644 --- a/src/schema/types/tgeneric.php +++ b/src/schema/types/tgeneric.php @@ -41,7 +41,7 @@ class tgeneric extends _tsimple { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { $result->setNormalized(); return false; } diff --git a/src/schema/types/tint.php b/src/schema/types/tint.php index 5673ab5..d7e95df 100644 --- a/src/schema/types/tint.php +++ b/src/schema/types/tint.php @@ -45,7 +45,7 @@ class tint extends _tformatable { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_int($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/tkey.php b/src/schema/types/tkey.php index 0e00cb3..6f5072e 100644 --- a/src/schema/types/tkey.php +++ b/src/schema/types/tkey.php @@ -36,7 +36,7 @@ class tkey extends _tunion { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_string($value) || is_int($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/tmixed.php b/src/schema/types/tmixed.php index fa525eb..652e51d 100644 --- a/src/schema/types/tmixed.php +++ b/src/schema/types/tmixed.php @@ -35,7 +35,7 @@ class tmixed extends _tsimple { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { $result->setNormalized(); return false; } diff --git a/src/schema/types/tpkey.php b/src/schema/types/tpkey.php index 14f2e01..e099051 100644 --- a/src/schema/types/tpkey.php +++ b/src/schema/types/tpkey.php @@ -41,7 +41,7 @@ class tpkey extends _tunion { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_string($value) || is_int($value) || is_array($value)) { $result->setNormalized(); return false; diff --git a/src/schema/types/trawstring.php b/src/schema/types/trawstring.php index 4278008..1f09dab 100644 --- a/src/schema/types/trawstring.php +++ b/src/schema/types/trawstring.php @@ -44,7 +44,7 @@ class trawstring extends _tstring { * @var ScalarResult $result * @var ScalarSchema $schema */ - function verifix(&$value, Result $result, Schema $schema): bool { + function normalize(&$value, Result $result, Schema $schema): bool { if (is_string($value)) { $result->setNormalized(); return false; diff --git a/tests/wip/schema/_assoc/AssocSchemaTest.php b/tests/wip/schema/_assoc/AssocSchemaTest.php index 0ab3763..987e845 100644 --- a/tests/wip/schema/_assoc/AssocSchemaTest.php +++ b/tests/wip/schema/_assoc/AssocSchemaTest.php @@ -120,20 +120,36 @@ class AssocSchemaTest extends TestCase { "c" => "bool", ]); + $array = ["a" => " string "]; + $schema->getWrapper($array); + self::assertSame([ + "a" => "string", + "b" => false, + "c" => null, + ], $array); + $array = ["c" => false, "a" => " string "]; $schema->getWrapper($array); self::assertSame([ "a" => "string", - "b" => null, + "b" => false, "c" => false, ], $array); + $array = ["a" => " string "]; + $schema->getWrapper($array, null, ["ensure_order" => false]); + self::assertSame([ + "a" => "string", + "b" => false, + "c" => null, + ], $array); + $array = ["c" => false, "a" => " string "]; $schema->getWrapper($array, null, ["ensure_order" => false]); self::assertSame([ "c" => false, "a" => "string", - "b" => null, + "b" => false, ], $array); $array = ["a" => " string "]; @@ -141,5 +157,12 @@ class AssocSchemaTest extends TestCase { self::assertSame([ "a" => "string", ], $array); + + $array = ["c" => false, "a" => " string "]; + $schema->getWrapper($array, null, ["ensure_keys" => false]); + self::assertSame([ + "a" => "string", + "c" => false, + ], $array); } } From fd9b3b29bc1f3f6de7f669bff9b19549dd71d38f Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 20 Mar 2025 08:41:31 +0400 Subject: [PATCH 21/55] modifs.mineures sans commentaires --- src/schema/TODO.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 5dce1ef..10c9c00 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,6 +1,10 @@ # 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] * valeurs composite/computed * analyse / vérification de la valeur complète après calcul du résultat, si From e9f4826a94bbbc81e28a9eb528079659ff3f68a0 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 20 Mar 2025 09:36:01 +0400 Subject: [PATCH 22/55] modifs.mineures sans commentaires --- src/schema/TODO.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 10c9c00..cab4345 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -4,7 +4,7 @@ * 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] +* l'ordre est `ensureAssoc [--> ensureKeys] [--> orderKeys]` * valeurs composite/computed * analyse / vérification de la valeur complète après calcul du résultat, si @@ -17,6 +17,10 @@ * possibilité de spécifier le format de la date à analyser * ScalarSchema::from_property() +* l'argument $format de AssocWrapper::format() est un tableau associatif + `[$key => $format]` + cela permet de spécifier des format spécifiques pour certains champs + * dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe commun aux champs dans le tableau destination, e.g ~~~php From 741a807420d5bcbaa2305b0b789fb4e75a317812 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 20 Mar 2025 09:38:01 +0400 Subject: [PATCH 23/55] modifs.mineures sans commentaires --- src/schema/TODO.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index cab4345..6ab55f0 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -19,7 +19,9 @@ * l'argument $format de AssocWrapper::format() est un tableau associatif `[$key => $format]` - cela permet de spécifier des format spécifiques pour certains champs + cela permet de spécifier des format spécifiques pour certains champs. + * cela signifie que la valeur de retour n'est pas string :-( + retourner string|array * dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe commun aux champs dans le tableau destination, e.g From c2ec23be30b8ef6c2624420be46772f7142ad80b Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 20 Mar 2025 09:57:07 +0400 Subject: [PATCH 24/55] modifs.mineures sans commentaires --- src/schema/types/IType.php | 13 ++++++++----- src/schema/types/tarray.php | 15 +++------------ src/schema/types/tbool.php | 13 ++----------- src/schema/types/tcallable.php | 15 +++------------ src/schema/types/tcontent.php | 11 ++++------- src/schema/types/tfloat.php | 13 ++----------- src/schema/types/tgeneric.php | 6 +++--- src/schema/types/tint.php | 13 ++----------- src/schema/types/tkey.php | 11 ++++------- src/schema/types/tmixed.php | 2 +- src/schema/types/tpkey.php | 11 ++++------- src/schema/types/trawstring.php | 9 +++------ 12 files changed, 39 insertions(+), 93 deletions(-) diff --git a/src/schema/types/IType.php b/src/schema/types/IType.php index 9dbd48a..0fbe948 100644 --- a/src/schema/types/IType.php +++ b/src/schema/types/IType.php @@ -98,13 +98,16 @@ interface IType { function parse(string $value); /** - * analyser, corriger éventuellement et normaliser la valeur - * - * NB: si $value est un string. elle doit avoir déjà été traitée au préalable + * normaliser la valeur. elle *doit* déjà être valide. + * Si $value est un string. elle *doit* avoir déjà été traitée au préalable * par extract() et parse() * - * si la valeur était déjà normalisée, ou si une erreur s'est produite, - * retourner false. + * - si $result indique que la valeur est déjà normalisée, cette méthode ne + * fait rien + * - si la valeur était déjà normalisée, mettre à jour $result pour indiquer + * que la valeur est normalisée et retourner false + * - sinon, retourner true pour indiquer qu'il a fallut normaliser la valeur. + * $result n'est pas modifié */ function normalize(&$value, Result $result, Schema $schema): bool; diff --git a/src/schema/types/tarray.php b/src/schema/types/tarray.php index b62160d..a6b2bf9 100644 --- a/src/schema/types/tarray.php +++ b/src/schema/types/tarray.php @@ -37,7 +37,7 @@ class tarray extends _tstring { function isValid($value, ?bool &$normalized=null): bool { $normalized = is_array($value); - return is_scalar($value) || is_array($value); + return $normalized || is_scalar($value); } function parse(string $value) { @@ -50,22 +50,13 @@ class tarray extends _tstring { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_array($value)) { + if ($result->normalized) { + } elseif (is_array($value)) { $result->setNormalized(); - return false; - } elseif (is_string($value)) { - try { - $value = $this->parse($value); - $result->setValid(); - return true; - } catch (ValueException $e) { - } } elseif (is_scalar($value)) { $value = cl::with($value); - $result->setValid(); return true; } - $result->setInvalid($value, $schema); return false; } diff --git a/src/schema/types/tbool.php b/src/schema/types/tbool.php index 5e0795d..dffa9c4 100644 --- a/src/schema/types/tbool.php +++ b/src/schema/types/tbool.php @@ -100,22 +100,13 @@ class tbool extends _tformatable { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_bool($value)) { + if ($result->normalized) { + } elseif (is_bool($value)) { $result->setNormalized(); - return false; - } elseif (is_string($value)) { - try { - $value = $this->parse($value); - $result->setValid(); - return true; - } catch (ValueException $e) { - } } elseif (is_scalar($value)) { $value = boolval($value); - $result->setValid(); return true; } - $result->setInvalid($value, $schema); return false; } diff --git a/src/schema/types/tcallable.php b/src/schema/types/tcallable.php index af6be72..76e2656 100644 --- a/src/schema/types/tcallable.php +++ b/src/schema/types/tcallable.php @@ -27,7 +27,7 @@ class tcallable extends _tsimple { } function isValid($value, ?bool &$normalized=null): bool { - $normalized = is_callable($value); + $normalized = $value instanceof func; return func::check($value); } @@ -44,22 +44,13 @@ class tcallable extends _tsimple { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if ($value instanceof func) { + if ($result->normalized) { + } elseif ($value instanceof func) { $result->setNormalized(); - return false; } elseif (is_callable($value)) { $value = func::with($value); - $result->setNormalized(); return true; - } elseif (is_string($value)) { - try { - $value = $this->parse($value); - $result->setValid(); - return true; - } catch (ValueException $e) { - } } - $result->setInvalid($value, $schema); return false; } diff --git a/src/schema/types/tcontent.php b/src/schema/types/tcontent.php index 2bb2912..0a600f4 100644 --- a/src/schema/types/tcontent.php +++ b/src/schema/types/tcontent.php @@ -25,7 +25,7 @@ abstract class tcontent extends _tunion { function isValid($value, ?bool &$normalized=null): bool { $normalized = is_string($value) || is_array($value); - return is_scalar($value) || is_array($value); + return $normalized || is_scalar($value); } function parse(string $value) { @@ -37,17 +37,14 @@ abstract class tcontent extends _tunion { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_string($value) || is_array($value)) { + if ($result->normalized) { + } elseif (is_string($value) || is_array($value)) { $result->setNormalized(); - return false; } elseif (is_scalar($value)) { $value = strval($value); - $result->setValid(); return true; - } else { - $result->setInvalid($value, $schema); - return false; } + return false; } function format($value, $format=null): string { diff --git a/src/schema/types/tfloat.php b/src/schema/types/tfloat.php index f1befd1..85767b6 100644 --- a/src/schema/types/tfloat.php +++ b/src/schema/types/tfloat.php @@ -44,22 +44,13 @@ class tfloat extends _tformatable { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_float($value)) { + if ($result->normalized) { + } elseif (is_float($value)) { $result->setNormalized(); - return false; - } elseif (is_string($value)) { - try { - $value = $this->parse($value); - $result->setValid(); - return true; - } catch (ValueException $e) { - } } elseif (is_scalar($value)) { $value = floatval($value); - $result->setValid(); return true; } - $result->setInvalid($value, $schema); return false; } } diff --git a/src/schema/types/tgeneric.php b/src/schema/types/tgeneric.php index 492c57e..fe069b8 100644 --- a/src/schema/types/tgeneric.php +++ b/src/schema/types/tgeneric.php @@ -29,8 +29,8 @@ class tgeneric extends _tsimple { } function isValid($value, ?bool &$normalized=null): bool { - $normalized = true; - return $value instanceof $this->class; + $normalized = $value instanceof $this->class; + return $normalized; } function parse(string $value) { @@ -42,7 +42,7 @@ class tgeneric extends _tsimple { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - $result->setNormalized(); + if (!$result->normalized) $result->setNormalized(); return false; } diff --git a/src/schema/types/tint.php b/src/schema/types/tint.php index d7e95df..eddab99 100644 --- a/src/schema/types/tint.php +++ b/src/schema/types/tint.php @@ -46,22 +46,13 @@ class tint extends _tformatable { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_int($value)) { + if ($result->normalized) { + } elseif (is_int($value)) { $result->setNormalized(); - return false; - } elseif (is_string($value)) { - try { - $value = $this->parse($value); - $result->setValid(); - return true; - } catch (ValueException $e) { - } } elseif (is_scalar($value)) { $value = intval($value); - $result->setValid(); return true; } - $result->setInvalid($value, $schema); return false; } } diff --git a/src/schema/types/tkey.php b/src/schema/types/tkey.php index 6f5072e..f1cca27 100644 --- a/src/schema/types/tkey.php +++ b/src/schema/types/tkey.php @@ -25,7 +25,7 @@ class tkey extends _tunion { function isValid($value, ?bool &$normalized=null): bool { $normalized = is_string($value) || is_int($value); - return is_scalar($value); + return $normalized || is_scalar($value); } function parse(string $value) { @@ -37,17 +37,14 @@ class tkey extends _tunion { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_string($value) || is_int($value)) { + if ($result->normalized) { + } elseif (is_string($value) || is_int($value)) { $result->setNormalized(); - return false; } elseif (is_scalar($value)) { $value = strval($value); - $result->setValid(); return true; - } else { - $result->setInvalid($value, $schema); - return false; } + return false; } function format($value, $format=null): string { diff --git a/src/schema/types/tmixed.php b/src/schema/types/tmixed.php index 652e51d..f549204 100644 --- a/src/schema/types/tmixed.php +++ b/src/schema/types/tmixed.php @@ -36,7 +36,7 @@ class tmixed extends _tsimple { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - $result->setNormalized(); + if (!$result->normalized) $result->setNormalized(); return false; } diff --git a/src/schema/types/tpkey.php b/src/schema/types/tpkey.php index e099051..7b2234b 100644 --- a/src/schema/types/tpkey.php +++ b/src/schema/types/tpkey.php @@ -30,7 +30,7 @@ class tpkey extends _tunion { function isValid($value, ?bool &$normalized=null): bool { $normalized = is_string($value) || is_int($value) || is_array($value); - return is_scalar($value) || is_array($value); + return $normalized || is_scalar($value); } function parse(string $value) { @@ -42,17 +42,14 @@ class tpkey extends _tunion { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_string($value) || is_int($value) || is_array($value)) { + if ($result->normalized) { + } elseif (is_string($value) || is_int($value) || is_array($value)) { $result->setNormalized(); - return false; } elseif (is_scalar($value)) { $value = strval($value); - $result->setValid(); return true; - } else { - $result->setInvalid($value, $schema); - return false; } + return false; } function format($value, $format=null): string { diff --git a/src/schema/types/trawstring.php b/src/schema/types/trawstring.php index 1f09dab..674d430 100644 --- a/src/schema/types/trawstring.php +++ b/src/schema/types/trawstring.php @@ -45,17 +45,14 @@ class trawstring extends _tstring { * @var ScalarSchema $schema */ function normalize(&$value, Result $result, Schema $schema): bool { - if (is_string($value)) { + if ($result->normalized) { + } elseif (is_string($value)) { $result->setNormalized(); - return false; } elseif (is_scalar($value)) { $value = strval($value); - $result->setValid(); return true; - } else { - $result->setInvalid($value, $schema); - return false; } + return false; } function format($value, $format=null): string { From e2bec38540bacb483657dccd19d1a489747ae347 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Fri, 21 Mar 2025 07:45:22 +0400 Subject: [PATCH 25/55] modifs.mineures sans commentaires --- src/schema/TODO.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 6ab55f0..8da8c24 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -6,6 +6,10 @@ * 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 + * valeurs composite/computed * analyse / vérification de la valeur complète après calcul du résultat, si tous les résultats sont bons @@ -66,6 +70,8 @@ la définition de ces "circonstances" est encore à faire: soit un paramètre lors de la définition du schéma, soit un truc magique du genre "toutes les - valeurs séquentielles sont des clés du schéma" + valeurs séquentielles sont des clés du schéma", soit un mode automatique + activé par un paramètre où une valeur "val" devient "val"=>true si la clé + "val" existe dans le schéma -*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary \ No newline at end of file From 7257654753ad05ecee0e7ea82cadae74e5c983c5 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sat, 22 Mar 2025 16:42:42 +0400 Subject: [PATCH 26/55] modifs.mineures sans commentaires --- src/php/access/KeyAccess.php | 31 ++++++++++++ tests/wip/php/access/KeyAccessTest.php | 65 ++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index 38bfee5..79948b2 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -3,6 +3,7 @@ namespace nur\sery\wip\php\access; use ArrayAccess; use nulib\cl; +use nulib\ref\schema\ref_schema; /** * Class KeyAccess: accès @@ -116,4 +117,34 @@ class KeyAccess extends AbstractAccess { "protect_dest" => $this->protectDest, ]); } + + function ensureAssoc(array $keys): void { + $index = 0; + $dest =& $this->dest; + foreach ($keys as $key) { + if ($dest !== null && array_key_exists($key, $dest)) continue; + while (in_array($index, $keys, true)) { + $index++; + } + if ($dest !== null && array_key_exists($index, $dest)) { + $dest[$key] = $dest[$index]; + unset($dest[$index]); + $index++; + } + } + } + + function ensureKeys(array $defaults): void { + $dest =& $this->dest; + $keys = array_keys($defaults); + foreach ($keys as $key) { + if ($dest === null || !array_key_exists($key, $dest)) { + $dest[$key] = $defaults[$key]; + } + } + } + + function ensureOrder(array $keys): void { + $dest =& $this->dest; + } } diff --git a/tests/wip/php/access/KeyAccessTest.php b/tests/wip/php/access/KeyAccessTest.php index d71eb8e..5247d98 100644 --- a/tests/wip/php/access/KeyAccessTest.php +++ b/tests/wip/php/access/KeyAccessTest.php @@ -125,4 +125,69 @@ class KeyAccessTest extends TestCase { self::assertTrue($a->available()); self::assertSame("", $a->get($default)); } + + private function _ensureAssoc(?array $orig, ?array $expected, array $keys) { + $v = $orig; $a = new KeyAccess($v); + $a->ensureAssoc($keys); + self::assertSame($expected, $v); + } + function testEnsureAssoc() { + $keys = ["a", "b", "c"]; + + $this->_ensureAssoc(null, null, $keys); + $this->_ensureAssoc([], [], $keys); + $this->_ensureAssoc([1], ["a" => 1], $keys); + $this->_ensureAssoc([1, 2, 3], ["a" => 1, "b" => 2, "c" => 3], $keys); + $this->_ensureAssoc([1, 2, 3, 4], [3 => 4, "a" => 1, "b" => 2, "c" => 3], $keys); + $this->_ensureAssoc(["c" => 3, 1], ["c" => 3, "a" => 1], $keys); + $this->_ensureAssoc(["c" => 3, "b" => 2, 1], ["c" => 3, "b" => 2, "a" => 1], $keys); + $this->_ensureAssoc(["c" => 3, "b" => 2, "a" => 1], ["c" => 3, "b" => 2, "a" => 1], $keys); + $this->_ensureAssoc(["a" => 1, 2], ["a" => 1, "b" => 2], $keys); + $this->_ensureAssoc([2, "a" => 1], ["a" => 1, "b" => 2], $keys); + + $keys = [0, "a", "b"]; + $this->_ensureAssoc([1], [1], $keys); + $this->_ensureAssoc([1, 2], [1, "a" => 2], $keys); + } + + private function _ensureKeys(?array $orig, ?array $expected, array $defaults) { + $v = $orig; $a = new KeyAccess($v); + $a->ensureKeys($defaults); + self::assertSame($expected, $v); + } + function testEnsureKeys() { + $defaults = ["a" => false, "b" => false, "c" => false]; + + $this->_ensureKeys(null, ["a" => false, "b" => false, "c" => false], $defaults); + $this->_ensureKeys([], ["a" => false, "b" => false, "c" => false], $defaults); + $this->_ensureKeys(["a" => 1], ["a" => 1, "b" => false, "c" => false], $defaults); + $this->_ensureKeys(["a" => 1, "b" => 2, "c" => 3], ["a" => 1, "b" => 2, "c" => 3], $defaults); + $this->_ensureKeys(["x"], ["x", "a" => false, "b" => false, "c" => false], $defaults); + $this->_ensureKeys(["x", "a" => 1], ["x", "a" => 1, "b" => false, "c" => false], $defaults); + $this->_ensureKeys(["a" => 1, "x"], ["a" => 1, "x", "b" => false, "c" => false], $defaults); + $this->_ensureKeys(["a" => 1, "b" => 2, "c" => 3, "x"], ["a" => 1, "b" => 2, "c" => 3, "x"], $defaults); + } + + private function _ensureAssocKeysOrder(?array $orig, ?array $expected, array $defaults) { + $v = $orig; $a = new KeyAccess($v); + $keys = array_keys($defaults); + $a->ensureAssoc($keys); + $a->ensureKeys($defaults); + $a->ensureOrder($keys); + self::assertSame($expected, $v); + } + function testEnsureAssocKeysOrder() { + $defaults = ["a" => false, "b" => false, "c" => false]; + + $this->_ensureAssocKeysOrder(null, ["a" => false, "b" => false, "c" => false], $defaults); + $this->_ensureAssocKeysOrder([], ["a" => false, "b" => false, "c" => false], $defaults); + $this->_ensureAssocKeysOrder([1], ["a" => 1, "b" => false, "c" => false], $defaults); + $this->_ensureAssocKeysOrder([1, 2, 3], ["a" => 1, "b" => 2, "c" => 3], $defaults); + $this->_ensureAssocKeysOrder([1, 2, 3, 4], [3 => 4, "a" => 1, "b" => 2, "c" => 3], $defaults); + $this->_ensureAssocKeysOrder(["c" => 3, 1], ["c" => 3, "a" => 1, "b" => false], $defaults); + $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, 1], ["c" => 3, "b" => 2, "a" => 1], $defaults); + $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, "a" => 1], ["c" => 3, "b" => 2, "a" => 1], $defaults); + $this->_ensureAssocKeysOrder(["a" => 1, 2], ["a" => 1, "b" => 2, "c" => false], $defaults); + $this->_ensureAssocKeysOrder([2, "a" => 1], ["a" => 1, "b" => 2, "c" => false], $defaults); + } } From 26817d28266716717cdbc98b681cc2e3d34fff96 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sun, 23 Mar 2025 08:06:40 +0400 Subject: [PATCH 27/55] modifs.mineures sans commentaires --- .pman.yml => .composer.pman.yml | 0 src/php/access/KeyAccess.php | 54 +++++++++++++++++++---- src/php/access/PropertyAccess.php | 59 +++++++++++++++++++++++--- tests/wip/php/access/KeyAccessTest.php | 46 ++++++++++++++------ 4 files changed, 132 insertions(+), 27 deletions(-) rename .pman.yml => .composer.pman.yml (100%) diff --git a/.pman.yml b/.composer.pman.yml similarity index 100% rename from .pman.yml rename to .composer.pman.yml diff --git a/src/php/access/KeyAccess.php b/src/php/access/KeyAccess.php index 79948b2..356d297 100644 --- a/src/php/access/KeyAccess.php +++ b/src/php/access/KeyAccess.php @@ -118,33 +118,71 @@ class KeyAccess extends AbstractAccess { ]); } - function ensureAssoc(array $keys): void { - $index = 0; + function ensureAssoc(array $keys, ?array $params=null): void { $dest =& $this->dest; + $prefix = $params["key_prefix"] ?? null; + $suffix = $params["key_suffix"] ?? null; + $index = 0; foreach ($keys as $key) { - if ($dest !== null && array_key_exists($key, $dest)) continue; + if ($prefix !== null || $suffix !== null) { + $destKey = "$prefix$key$suffix"; + } else { + # préserver les clés numériques + $destKey = $key; + } + if ($dest !== null && array_key_exists($destKey, $dest)) continue; while (in_array($index, $keys, true)) { $index++; } if ($dest !== null && array_key_exists($index, $dest)) { - $dest[$key] = $dest[$index]; + $dest[$destKey] = $dest[$index]; unset($dest[$index]); $index++; } } } - function ensureKeys(array $defaults): void { + function ensureKeys(array $defaults, ?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) { - if ($dest === null || !array_key_exists($key, $dest)) { - $dest[$key] = $defaults[$key]; + $destKey = "$prefix$key$suffix"; + if ($dest === null || !array_key_exists($destKey, $dest)) { + $dest[$destKey] = $defaults[$key]; } } } - function ensureOrder(array $keys): void { + function ensureOrder(array $keys, ?array $params=null): void { $dest =& $this->dest; + if ($dest === null) return; + + $prefix = $params["key_prefix"] ?? null; + $suffix = $params["key_suffix"] ?? null; + if ($prefix !== null || $suffix !== null) { + foreach ($keys as &$key) { + $key = "$prefix$key$suffix"; + }; unset($key); + } + + $destKeys = array_keys($dest); + $keyCount = count($keys); + if (array_slice($destKeys, 0, $keyCount) === $keys) { + # si le tableau a déjà les bonnes clés dans le bon ordre, rien à faire + return; + } + + $ordered = []; + foreach ($keys as $key) { + if (array_key_exists($key, $dest)) { + $ordered[$key] = $dest[$key]; + unset($dest[$key]); + } + } + $preserveKeys = $params["preserve_keys"] ?? false; + if ($preserveKeys) $dest = cl::merge2($ordered, $dest); + else $dest = array_merge($ordered, $dest); } } diff --git a/src/php/access/PropertyAccess.php b/src/php/access/PropertyAccess.php index eadf80d..522c9db 100644 --- a/src/php/access/PropertyAccess.php +++ b/src/php/access/PropertyAccess.php @@ -5,7 +5,9 @@ use nulib\StateException; use nulib\str; use ReflectionClass; use ReflectionException; +use ReflectionNamedType; use ReflectionProperty; +use stdClass; class PropertyAccess extends AbstractAccess { const PROTECT_DEST = true; @@ -32,24 +34,32 @@ class PropertyAccess extends AbstractAccess { protected ?ReflectionProperty $property; + private function _getName(string $key): string { + return $this->mapNames? str::us2camel($key): $key; + } private function _setName(?string $name): void { - if ($this->mapNames) $name = str::us2camel($name); + if ($name !== null) $name = $this->_getName($name); $this->name = $name; } - private function _setDest(?object $dest): void { - $this->dest = $dest; + private function _getProperty(?string $name, ?ReflectionClass $class, ?object $object=null): ?ReflectionProperty { $property = null; - $name = $this->name; - if ($dest !== null && $name !== null) { - $class = new ReflectionClass($dest); + if ($class === null && $object !== null) { + $class = new ReflectionClass($object); + } + if ($class !== null && $name !== null) { try { $property = $class->getProperty($name); $property->setAccessible(true); } catch (ReflectionException $e) { } } - $this->property = $property; + return $property; + } + + private function _setDest(?object $dest): void { + $this->dest = $dest; + $this->property = $this->_getProperty($this->name, null, $dest); } function reset(?object $dest, ?string $name=null): self { @@ -135,4 +145,39 @@ class PropertyAccess extends AbstractAccess { if ($key === null) return $this; return new ChainAccess($this, $key); } + + function ensureAssoc(array $keys, ?array $params=null): void { + # NOP + } + + function ensureKeys(array $defaults, ?array $params=null): void { + $dest = $this->dest; + if ($dest === null) { + # comme ne connait pas la classe de l'objet destination, on n'essaie pas + # de le créer + return; + } + $class = new ReflectionClass($dest); + $keys = array_keys($defaults); + $prefix = $params["key_prefix"] ?? null; + $suffix = $params["key_suffix"] ?? null; + foreach ($keys as $key) { + $name = $this->_getName("$prefix$key$suffix"); + $property = $this->_getProperty($name, $class); + if ($property !== null) { + $type = $property->getType(); + if ($type !== null && !$property->isInitialized($dest) && $type->allowsNull()) { + # initialiser avec null au lieu de $defaults[$key] pour respecter le + # type de la propriété + $property->setValue($dest, null); + } + } elseif (!property_exists($dest, $name)) { + $dest->$name = $defaults[$key]; + } + } + } + + function ensureOrder(array $keys, ?array $params=null): void { + # NOP + } } diff --git a/tests/wip/php/access/KeyAccessTest.php b/tests/wip/php/access/KeyAccessTest.php index 5247d98..8911ccd 100644 --- a/tests/wip/php/access/KeyAccessTest.php +++ b/tests/wip/php/access/KeyAccessTest.php @@ -126,9 +126,9 @@ class KeyAccessTest extends TestCase { self::assertSame("", $a->get($default)); } - private function _ensureAssoc(?array $orig, ?array $expected, array $keys) { + private function _ensureAssoc(?array $orig, ?array $expected, array $keys, ?array $params=null) { $v = $orig; $a = new KeyAccess($v); - $a->ensureAssoc($keys); + $a->ensureAssoc($keys, $params); self::assertSame($expected, $v); } function testEnsureAssoc() { @@ -150,9 +150,9 @@ class KeyAccessTest extends TestCase { $this->_ensureAssoc([1, 2], [1, "a" => 2], $keys); } - private function _ensureKeys(?array $orig, ?array $expected, array $defaults) { + private function _ensureKeys(?array $orig, ?array $expected, array $defaults, ?array $params=null) { $v = $orig; $a = new KeyAccess($v); - $a->ensureKeys($defaults); + $a->ensureKeys($defaults, $params); self::assertSame($expected, $v); } function testEnsureKeys() { @@ -168,12 +168,27 @@ class KeyAccessTest extends TestCase { $this->_ensureKeys(["a" => 1, "b" => 2, "c" => 3, "x"], ["a" => 1, "b" => 2, "c" => 3, "x"], $defaults); } - private function _ensureAssocKeysOrder(?array $orig, ?array $expected, array $defaults) { + private function _ensureOrder(?array $orig, ?array $expected, array $keys, ?array $params=null) { + $v = $orig; $a = new KeyAccess($v); + $a->ensureOrder($keys, $params); + self::assertSame($expected, $v); + } + function testEnsureOrder() { + $keys = ["a", "b", "c"]; + + $this->_ensureOrder(null, null, $keys); + $this->_ensureOrder([], [], $keys); + $this->_ensureOrder([1], [1], $keys); + $this->_ensureOrder(["b" => 2, "a" => 1], ["a" => 1, "b" => 2], $keys); + $this->_ensureOrder(["c" => 3, "a" => 1], ["a" => 1, "c" => 3], $keys); + } + + private function _ensureAssocKeysOrder(?array $orig, ?array $expected, array $defaults, ?array $params=null) { $v = $orig; $a = new KeyAccess($v); $keys = array_keys($defaults); - $a->ensureAssoc($keys); - $a->ensureKeys($defaults); - $a->ensureOrder($keys); + $a->ensureAssoc($keys, $params); + $a->ensureKeys($defaults, $params); + $a->ensureOrder($keys, $params); self::assertSame($expected, $v); } function testEnsureAssocKeysOrder() { @@ -183,11 +198,18 @@ class KeyAccessTest extends TestCase { $this->_ensureAssocKeysOrder([], ["a" => false, "b" => false, "c" => false], $defaults); $this->_ensureAssocKeysOrder([1], ["a" => 1, "b" => false, "c" => false], $defaults); $this->_ensureAssocKeysOrder([1, 2, 3], ["a" => 1, "b" => 2, "c" => 3], $defaults); - $this->_ensureAssocKeysOrder([1, 2, 3, 4], [3 => 4, "a" => 1, "b" => 2, "c" => 3], $defaults); - $this->_ensureAssocKeysOrder(["c" => 3, 1], ["c" => 3, "a" => 1, "b" => false], $defaults); - $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, 1], ["c" => 3, "b" => 2, "a" => 1], $defaults); - $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, "a" => 1], ["c" => 3, "b" => 2, "a" => 1], $defaults); + $this->_ensureAssocKeysOrder([1, 2, 3, 4], ["a" => 1, "b" => 2, "c" => 3, 4], $defaults); + $this->_ensureAssocKeysOrder([1, 2, 3, 4], ["a" => 1, "b" => 2, "c" => 3, 3 => 4], $defaults, [ + "preserve_keys" => true, + ]); + $this->_ensureAssocKeysOrder(["c" => 3, 1], ["a" => 1, "b" => false, "c" => 3], $defaults); + $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, 1], ["a" => 1, "b" => 2, "c" => 3], $defaults); + $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, "a" => 1], ["a" => 1, "b" => 2, "c" => 3], $defaults); $this->_ensureAssocKeysOrder(["a" => 1, 2], ["a" => 1, "b" => 2, "c" => false], $defaults); $this->_ensureAssocKeysOrder([2, "a" => 1], ["a" => 1, "b" => 2, "c" => false], $defaults); + + $this->_ensureAssocKeysOrder([1], ["x_a" => 1, "x_b" => false, "x_c" => false], $defaults, [ + "key_prefix" => "x_", + ]); } } From fd1ebaf6114f005418de0a46c2d6631678647278 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sun, 23 Mar 2025 08:19:20 +0400 Subject: [PATCH 28/55] modifs.mineures sans commentaires --- src/php/access/AbstractAccess.php | 9 +++++++++ src/php/access/ChainAccess.php | 15 +++++++++++++++ src/php/access/IAccess.php | 21 +++++++++++++++++++++ src/php/access/PropertyAccess.php | 8 -------- src/php/access/ShadowAccess.php | 12 ++++++++++++ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/php/access/AbstractAccess.php b/src/php/access/AbstractAccess.php index 417d2cb..cffb954 100644 --- a/src/php/access/AbstractAccess.php +++ b/src/php/access/AbstractAccess.php @@ -45,4 +45,13 @@ abstract class AbstractAccess implements IAccess { cl::set($array, $key, $value); $this->set($array); } + + function ensureAssoc(array $keys, ?array $params=null): void { + } + + function ensureKeys(array $defaults, ?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 299c01d..00529ce 100644 --- a/src/php/access/ChainAccess.php +++ b/src/php/access/ChainAccess.php @@ -164,4 +164,19 @@ class ChainAccess extends AbstractAccess { return new ChainAccess($this, $key); } } + + function ensureAssoc(array $keys, ?array $params=null): void { + #XXX fonction de $accessType? + #$this->access->ensureAssoc($keys, $params); + } + + function ensureKeys(array $defaults, ?array $params=null): void { + #XXX fonction de $accessType? + #$this->access->ensureKeys($defaults, $params); + } + + function ensureOrder(array $keys, ?array $params=null): void { + #XXX fonction de $accessType? + #$this->access->ensureOrder($keys, $params); + } } diff --git a/src/php/access/IAccess.php b/src/php/access/IAccess.php index 7987c4c..a6f9b84 100644 --- a/src/php/access/IAccess.php +++ b/src/php/access/IAccess.php @@ -1,6 +1,8 @@ dest; if ($dest === null) { @@ -176,8 +172,4 @@ class PropertyAccess extends AbstractAccess { } } } - - function ensureOrder(array $keys, ?array $params=null): void { - # NOP - } } diff --git a/src/php/access/ShadowAccess.php b/src/php/access/ShadowAccess.php index e4f1211..bdd12d6 100644 --- a/src/php/access/ShadowAccess.php +++ b/src/php/access/ShadowAccess.php @@ -57,4 +57,16 @@ class ShadowAccess extends AbstractAccess { function addKey($key): IAccess { return new ChainAccess($this, $key); } + + function ensureAssoc(array $keys, ?array $params=null): void { + $this->writer->ensureAssoc($keys, $params); + } + + function ensureKeys(array $defaults, ?array $params=null): void { + $this->writer->ensureKeys($defaults, $params); + } + + function ensureOrder(array $keys, ?array $params=null): void { + $this->writer->ensureOrder($keys, $params); + } } From 9109e0fe391111fbe28e6647b58c37c0600d88f5 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 24 Mar 2025 13:46:51 +0400 Subject: [PATCH 29/55] 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 30/55] 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 31/55] 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 32/55] 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 33/55] 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 34/55] 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 35/55] =?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 36/55] 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 37/55] 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 38/55] 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 39/55] 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 40/55] 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 41/55] 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 42/55] 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 43/55] 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 44/55] 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 45/55] 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 46/55] =?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 47/55] 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; From 36d486a6492b10e8d76fb18bb3831adbf5c6fe1d Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 23 Apr 2025 12:02:10 +0400 Subject: [PATCH 48/55] =?UTF-8?q?r=C3=A9tablir=20composer.lock=20=C3=A0=20?= =?UTF-8?q?la=20version=20dev74=20pour=20limiter=20les=20conflits=20de=20f?= =?UTF-8?q?usion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.lock | 1029 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 680 insertions(+), 349 deletions(-) diff --git a/composer.lock b/composer.lock index b9de821..df6be65 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e271d0728ec974a8964542dc16fc1b11", + "content-hash": "0b1e015d12aecf1cdfbdc6a702d83d25", "packages": [], "packages-dev": [ { @@ -87,37 +87,164 @@ "time": "2024-11-12T16:29:46+00:00" }, { - "name": "maennchen/zipstream-php", - "version": "3.1.2", + "name": "doctrine/instantiator", + "version": "1.5.0", "source": { "type": "git", - "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f", - "reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { - "ext-mbstring": "*", - "ext-zlib": "*", - "php-64bit": "^8.2" + "php": "^7.1 || ^8.0" }, "require-dev": { - "brianium/paratest": "^7.7", - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.16", - "guzzlehttp/guzzle": "^7.5", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.5", - "phpunit/phpunit": "^11.0", - "vimeo/psalm": "^6.0" + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" }, "suggest": { - "guzzlehttp/psr7": "^2.4", - "psr/http-message": "^2.0" + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0" + }, + "time": "2024-11-01T03:51:45+00:00" + }, + { + "name": "maennchen/zipstream-php", + "version": "2.2.6", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "shasum": "" + }, + "require": { + "myclabs/php-enum": "^1.5", + "php": "^7.4 || ^8.0", + "psr/http-message": "^1.0", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.9", + "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.4", + "phpunit/phpunit": "^8.5.8 || ^9.4.2", + "vimeo/psalm": "^4.1" }, "type": "library", "autoload": { @@ -154,15 +281,19 @@ ], "support": { "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2" + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.6" }, "funding": [ { "url": "https://github.com/maennchen", "type": "github" + }, + { + "url": "https://opencollective.com/zipstream", + "type": "open_collective" } ], - "time": "2025-01-27T12:07:53+00:00" + "time": "2022-11-25T18:57:19+00:00" }, { "name": "markbaker/complex", @@ -331,6 +462,69 @@ ], "time": "2025-02-12T12:17:51+00:00" }, + { + "name": "myclabs/php-enum", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "e7be26966b7398204a234f8673fdad5ac6277802" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/e7be26966b7398204a234f8673fdad5ac6277802", + "reference": "e7be26966b7398204a234f8673fdad5ac6277802", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2 || ^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "https://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.5" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2025-01-14T11:49:03+00:00" + }, { "name": "nikic/php-parser", "version": "v5.4.0", @@ -391,16 +585,16 @@ }, { "name": "nulib/php", - "version": "0.4.0p82", - "source": { - "type": "git", - "url": "https://git.univ-reunion.fr/sda-php/nulib.git", - "reference": "fd120298a91bddcaa3da2decd34b8f99853fb070" + "version": "dev-dev74", + "dist": { + "type": "path", + "url": "../nulib", + "reference": "2a50167241fe6b6d84d793aad748eb74c631eae9" }, "require": { "ext-json": "*", - "php": "^8.2", - "symfony/yaml": "^7.1" + "php": "^7.4", + "symfony/yaml": "^5.0" }, "require-dev": { "ext-curl": "*", @@ -409,7 +603,7 @@ "ext-pgsql": "*", "ext-posix": "*", "ext-sqlite3": "*", - "nulib/tests": "^8.2" + "nulib/tests": "^7.4" }, "type": "library", "extra": { @@ -435,23 +629,25 @@ } ], "description": "fonctions et classes essentielles", - "time": "2025-03-14T11:24:39+00:00" + "transport-options": { + "relative": true + } }, { "name": "nulib/phpss", - "version": "0.4.0p82", - "source": { - "type": "git", - "url": "https://git.univ-reunion.fr/sda-php/nulib-phpss.git", - "reference": "44b6507d02d62451fcf260b9af19ced7083dc674" + "version": "dev-dev74", + "dist": { + "type": "path", + "url": "../nulib-phpss", + "reference": "e902acb4461a9358de8cce0a534bfe0e63e8b100" }, "require": { - "nulib/php": "^0.4.0p82", - "php": "^8.2", - "phpoffice/phpspreadsheet": "^3.3.0" + "nulib/php": "^7.4-dev", + "php": "^7.4", + "phpoffice/phpspreadsheet": "^1.0" }, "require-dev": { - "nulib/tests": "^8.2" + "nulib/tests": "^7.4" }, "type": "library", "extra": { @@ -477,38 +673,36 @@ } ], "description": "wrapper pour phpoffice/phpspreadsheet", - "time": "2025-03-14T11:30:18+00:00" + "transport-options": { + "relative": true + } }, { "name": "nulib/spout", - "version": "0.4.0p82", - "source": { - "type": "git", - "url": "https://git.univ-reunion.fr/sda-php/nulib-spout.git", - "reference": "2b2af6be95070c1262740ab0242c96c1d86af568" + "version": "dev-dev74", + "dist": { + "type": "path", + "url": "../nulib-spout", + "reference": "8d7512e2bff3dc333bb58130ac5500017db700ca" }, "require": { "ext-dom": "*", - "ext-fileinfo": "*", "ext-filter": "*", "ext-libxml": "*", "ext-xmlreader": "*", "ext-zip": "*", - "nulib/php": "^0.4.0p82", - "php": "^8.2" + "nulib/php": "^7.4-dev", + "php": "^7.4" }, "replace": { - "openspout/openspout": "v4.27.0" + "openspout/openspout": "v3.7.4" }, "require-dev": { "ext-zlib": "*", - "friendsofphp/php-cs-fixer": "^3.64.0", - "infection/infection": "^0.29.6", - "nulib/tests": "^8.2", - "phpbench/phpbench": "^1.3.1", - "phpstan/phpstan": "^1.12.4", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1" + "friendsofphp/php-cs-fixer": "^3.4", + "nulib/tests": "^7.4", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1.0" }, "type": "library", "extra": { @@ -520,7 +714,7 @@ "autoload": { "psr-4": { "nulib\\": "src", - "OpenSpout\\": "openspout4/src" + "OpenSpout\\": "openspout3/src" } }, "autoload-dev": { @@ -535,19 +729,21 @@ } ], "description": "wrapper pour openspout/openspout", - "time": "2025-03-14T11:41:00+00:00" + "transport-options": { + "relative": true + } }, { "name": "nulib/tests", - "version": "8.2", + "version": "7.4", "source": { "type": "git", "url": "https://git.univ-reunion.fr/sda-php/nulib-tests.git", - "reference": "d6bc680156ef837aabc666da802c5cc7eac8deec" + "reference": "8f641d9a7cf6aba1453cb42ebd15951aa7002e1b" }, "require": { - "php": "^8.1", - "phpunit/phpunit": "^10" + "php": "^7.3 || 8.0.*", + "phpunit/phpunit": "^9" }, "type": "library", "extra": { @@ -573,7 +769,7 @@ } ], "description": "fonctions et classes pour les tests", - "time": "2025-02-28T17:08:35+00:00" + "time": "2025-02-28T17:12:35+00:00" }, { "name": "phar-io/manifest", @@ -695,20 +891,20 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "3.9.1", + "version": "1.29.10", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "56f334ace62fc8301c98d425272cbf0a00eb848d" + "reference": "c80041b1628c4f18030407134fe88303661d4e4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/56f334ace62fc8301c98d425272cbf0a00eb848d", - "reference": "56f334ace62fc8301c98d425272cbf0a00eb848d", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/c80041b1628c4f18030407134fe88303661d4e4e", + "reference": "c80041b1628c4f18030407134fe88303661d4e4e", "shasum": "" }, "require": { - "composer/pcre": "^1 || ^2 || ^3", + "composer/pcre": "^1||^2||^3", "ext-ctype": "*", "ext-dom": "*", "ext-fileinfo": "*", @@ -722,24 +918,25 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.15", "maennchen/zipstream-php": "^2.1 || ^3.0", "markbaker/complex": "^3.0", "markbaker/matrix": "^3.0", - "php": "^8.1", + "php": "^7.4 || ^8.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-main", - "dompdf/dompdf": "^2.0 || ^3.0", + "dompdf/dompdf": "^1.0 || ^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^3.2", "mitoteam/jpgraph": "^10.3", "mpdf/mpdf": "^8.1.1", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^10.5", + "phpunit/phpunit": "^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, @@ -794,22 +991,22 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/3.9.1" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.10" }, - "time": "2025-02-08T03:04:52+00:00" + "time": "2025-02-08T02:56:14+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "version": "9.2.32", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", "shasum": "" }, "require": { @@ -817,18 +1014,18 @@ "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^9.6" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -837,7 +1034,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "9.2.x-dev" } }, "autoload": { @@ -866,7 +1063,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" }, "funding": [ { @@ -874,32 +1071,32 @@ "type": "github" } ], - "time": "2024-08-22T04:31:57+00:00" + "time": "2024-08-22T04:23:01+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -926,8 +1123,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -935,28 +1131,28 @@ "type": "github" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcntl": "*" @@ -964,7 +1160,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -990,7 +1186,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" }, "funding": [ { @@ -998,32 +1194,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2020-09-28T05:58:55+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1049,8 +1245,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" }, "funding": [ { @@ -1058,32 +1253,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2020-10-26T05:33:50+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1109,7 +1304,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" }, "funding": [ { @@ -1117,23 +1312,24 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.45", + "version": "9.6.22", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" + "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f80235cb4d3caa59ae09be3adf1ded27521d1a9c", + "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c", "shasum": "" }, "require": { + "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -1143,26 +1339,27 @@ "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.32", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.6", + "sebastian/global-state": "^5.0.7", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", + "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -1170,7 +1367,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -1202,7 +1399,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.22" }, "funding": [ { @@ -1218,7 +1415,7 @@ "type": "tidelift" } ], - "time": "2025-02-06T16:08:12+00:00" + "time": "2024-12-05T13:48:26+00:00" }, { "name": "psr/http-client", @@ -1329,16 +1526,16 @@ }, { "name": "psr/http-message", - "version": "2.0", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { @@ -1347,7 +1544,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -1362,7 +1559,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -1376,31 +1573,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2023-04-04T09:54:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/simple-cache", - "version": "3.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", "shasum": "" }, "require": { - "php": ">=8.0.0" + "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -1415,7 +1612,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common interfaces for simple caching", @@ -1427,34 +1624,34 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + "source": "https://github.com/php-fig/simple-cache/tree/master" }, - "time": "2021-10-29T13:26:27+00:00" + "time": "2017-10-23T01:57:42+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-master": "1.0-dev" } }, "autoload": { @@ -1477,8 +1674,7 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" }, "funding": [ { @@ -1486,32 +1682,32 @@ "type": "github" } ], - "time": "2024-03-02T07:12:49+00:00" + "time": "2024-03-02T06:27:43+00:00" }, { "name": "sebastian/code-unit", - "version": "2.0.0", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-master": "1.0-dev" } }, "autoload": { @@ -1534,7 +1730,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" }, "funding": [ { @@ -1542,32 +1738,32 @@ "type": "github" } ], - "time": "2023-02-03T06:58:43+00:00" + "time": "2020-10-26T13:08:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1589,7 +1785,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" }, "funding": [ { @@ -1597,36 +1793,34 @@ "type": "github" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.3", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1665,8 +1859,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -1674,33 +1867,33 @@ "type": "github" } ], - "time": "2024-10-18T14:56:07+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1723,8 +1916,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -1732,33 +1924,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1790,8 +1982,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" }, "funding": [ { @@ -1799,27 +1990,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2024-03-02T06:30:58+00:00" }, { "name": "sebastian/environment", - "version": "6.1.0", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" @@ -1827,7 +2018,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -1846,7 +2037,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", + "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -1854,8 +2045,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -1863,34 +2053,34 @@ "type": "github" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1932,8 +2122,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" }, "funding": [ { @@ -1941,35 +2130,38 @@ "type": "github" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2024-03-02T06:33:00+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "5.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1988,14 +2180,13 @@ } ], "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" }, "funding": [ { @@ -2003,33 +2194,33 @@ "type": "github" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2024-03-02T06:35:11+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-master": "1.0-dev" } }, "autoload": { @@ -2052,8 +2243,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -2061,34 +2251,34 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -2110,7 +2300,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, "funding": [ { @@ -2118,32 +2308,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -2165,7 +2355,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, "funding": [ { @@ -2173,32 +2363,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -2228,7 +2418,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -2236,32 +2426,86 @@ "type": "github" } ], - "time": "2023-02-03T07:05:40+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { - "name": "sebastian/type", - "version": "4.0.0", + "name": "sebastian/resource-operations", + "version": "3.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-14T16:00:52+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" } }, "autoload": { @@ -2284,7 +2528,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -2292,29 +2536,29 @@ "type": "github" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2337,7 +2581,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, "funding": [ { @@ -2345,24 +2589,24 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" + "time": "2020-09-28T06:39:44+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.1" }, "type": "library", "extra": { @@ -2371,7 +2615,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "2.5-dev" } }, "autoload": { @@ -2396,7 +2640,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" }, "funding": [ { @@ -2412,7 +2656,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2494,29 +2738,112 @@ "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/yaml", - "version": "v7.2.3", + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", - "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/yaml", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "a454d47278cc16a5db371fe73ae66a78a633371e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a454d47278cc16a5db371fe73ae66a78a633371e", + "reference": "a454d47278cc16a5db371fe73ae66a78a633371e", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<6.4" + "symfony/console": "<5.3" }, "require-dev": { - "symfony/console": "^6.4|^7.0" + "symfony/console": "^5.3|^6.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, "bin": [ "Resources/bin/yaml-lint" @@ -2547,7 +2874,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.2.3" + "source": "https://github.com/symfony/yaml/tree/v5.4.45" }, "funding": [ { @@ -2563,7 +2890,7 @@ "type": "tidelift" } ], - "time": "2025-01-07T12:55:42+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "theseer/tokenizer", @@ -2618,11 +2945,15 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "nulib/php": 20, + "nulib/spout": 20, + "nulib/phpss": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.2" + "php": "^7.4" }, "platform-dev": { "ext-posix": "*", From 555d15b9e4c812c6d2cd7f89e8a505f2fc30a70e Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:30:45 +0400 Subject: [PATCH 49/55] maj projet --- .composer.pman.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.composer.pman.yml b/.composer.pman.yml index 8e5132d..35e8f60 100644 --- a/.composer.pman.yml +++ b/.composer.pman.yml @@ -11,6 +11,6 @@ composer: dist: link: false require-dev: - nulib/php: ^0.4.0p74 - nulib/spout: ^0.4.0p74 - nulib/phpss: ^0.4.0p74 + nulib/php: ^0.5.0p74 + nulib/spout: ^0.5.0p74 + nulib/phpss: ^0.5.0p74 From 9c659866ef772e98878cbc2301574f8917dfef35 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:30:56 +0400 Subject: [PATCH 50/55] Init changelog & version 0.5.0p74 --- CHANGES.md | 9 +++++++++ VERSION.txt | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f74bd64..9a2877c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,12 @@ +## Release 0.5.0p74 du 30/04/2025-05:30 + +* `2d73f4d` documenter showmorePlugin +* `3b13ef1` possiblité de forcer la suppression +* `3933fd1` corrections sur les controles +* `4d238cc` maj doc +* `f005692` déplacer nur/sery/wip et nur/sery dans nulib +* `c4e02d5` afficher la version de l'application + ## Release 0.4.1p82 du 17/03/2025-17:23 ## Release 0.4.1p74 du 17/03/2025-17:19 diff --git a/VERSION.txt b/VERSION.txt index 267577d..8f0916f 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.4.1 +0.5.0 From 177e504ca8fdebaf5532da1a517e4587787ca7c2 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:32:08 +0400 Subject: [PATCH 51/55] deps de dist --- composer.json | 18 +++----------- composer.lock | 66 ++++++++++++++++++++++----------------------------- 2 files changed, 31 insertions(+), 53 deletions(-) diff --git a/composer.json b/composer.json index 1ba08c0..acaf711 100644 --- a/composer.json +++ b/composer.json @@ -3,18 +3,6 @@ "type": "library", "description": "espace de maturation pour les librairies", "repositories": [ - { - "type": "path", - "url": "../nulib" - }, - { - "type": "path", - "url": "../nulib-spout" - }, - { - "type": "path", - "url": "../nulib-phpss" - }, { "type": "composer", "url": "https://repos.univ-reunion.fr/composer" @@ -30,9 +18,9 @@ "php": "^7.4" }, "require-dev": { - "nulib/php": "^7.4-dev", - "nulib/spout": "^7.4-dev", - "nulib/phpss": "^7.4-dev", + "nulib/php": "^0.5.0p74", + "nulib/spout": "^0.5.0p74", + "nulib/phpss": "^0.5.0p74", "nulib/tests": "^7.4", "ext-posix": "*", "ext-pcntl": "*", diff --git a/composer.lock b/composer.lock index df6be65..cb9584f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0b1e015d12aecf1cdfbdc6a702d83d25", + "content-hash": "b4bd340f94d33a320d66b249b1c21edb", "packages": [], "packages-dev": [ { @@ -404,16 +404,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414" + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", "shasum": "" }, "require": { @@ -452,7 +452,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" }, "funding": [ { @@ -460,7 +460,7 @@ "type": "tidelift" } ], - "time": "2025-02-12T12:17:51+00:00" + "time": "2025-04-29T12:36:36+00:00" }, { "name": "myclabs/php-enum", @@ -585,11 +585,11 @@ }, { "name": "nulib/php", - "version": "dev-dev74", - "dist": { - "type": "path", - "url": "../nulib", - "reference": "2a50167241fe6b6d84d793aad748eb74c631eae9" + "version": "0.5.0p74", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/nulib.git", + "reference": "4037bf20424eb48708e5fdf9fc8e10f2ef71d134" }, "require": { "ext-json": "*", @@ -629,20 +629,18 @@ } ], "description": "fonctions et classes essentielles", - "transport-options": { - "relative": true - } + "time": "2025-04-30T00:32:10+00:00" }, { "name": "nulib/phpss", - "version": "dev-dev74", - "dist": { - "type": "path", - "url": "../nulib-phpss", - "reference": "e902acb4461a9358de8cce0a534bfe0e63e8b100" + "version": "0.5.0p74", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/nulib-phpss.git", + "reference": "26b4bfddf5646f9313d419e568cd930efb9353eb" }, "require": { - "nulib/php": "^7.4-dev", + "nulib/php": "^0.5.0p74", "php": "^7.4", "phpoffice/phpspreadsheet": "^1.0" }, @@ -673,17 +671,15 @@ } ], "description": "wrapper pour phpoffice/phpspreadsheet", - "transport-options": { - "relative": true - } + "time": "2025-04-30T00:46:31+00:00" }, { "name": "nulib/spout", - "version": "dev-dev74", - "dist": { - "type": "path", - "url": "../nulib-spout", - "reference": "8d7512e2bff3dc333bb58130ac5500017db700ca" + "version": "0.5.0p74", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/nulib-spout.git", + "reference": "e650e27abe571553424524633deada32747d33a6" }, "require": { "ext-dom": "*", @@ -691,7 +687,7 @@ "ext-libxml": "*", "ext-xmlreader": "*", "ext-zip": "*", - "nulib/php": "^7.4-dev", + "nulib/php": "^0.5.0p74", "php": "^7.4" }, "replace": { @@ -729,9 +725,7 @@ } ], "description": "wrapper pour openspout/openspout", - "transport-options": { - "relative": true - } + "time": "2025-04-30T00:40:11+00:00" }, { "name": "nulib/tests", @@ -2945,11 +2939,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "nulib/php": 20, - "nulib/spout": 20, - "nulib/phpss": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 309375c297016d20cf796b9f1c39162b38a54988 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:32:13 +0400 Subject: [PATCH 52/55] deps de dev --- composer.json | 18 ++++++++++++++--- composer.lock | 54 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/composer.json b/composer.json index acaf711..1ba08c0 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,18 @@ "type": "library", "description": "espace de maturation pour les librairies", "repositories": [ + { + "type": "path", + "url": "../nulib" + }, + { + "type": "path", + "url": "../nulib-spout" + }, + { + "type": "path", + "url": "../nulib-phpss" + }, { "type": "composer", "url": "https://repos.univ-reunion.fr/composer" @@ -18,9 +30,9 @@ "php": "^7.4" }, "require-dev": { - "nulib/php": "^0.5.0p74", - "nulib/spout": "^0.5.0p74", - "nulib/phpss": "^0.5.0p74", + "nulib/php": "^7.4-dev", + "nulib/spout": "^7.4-dev", + "nulib/phpss": "^7.4-dev", "nulib/tests": "^7.4", "ext-posix": "*", "ext-pcntl": "*", diff --git a/composer.lock b/composer.lock index cb9584f..5ab7b92 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b4bd340f94d33a320d66b249b1c21edb", + "content-hash": "0b1e015d12aecf1cdfbdc6a702d83d25", "packages": [], "packages-dev": [ { @@ -585,11 +585,11 @@ }, { "name": "nulib/php", - "version": "0.5.0p74", - "source": { - "type": "git", - "url": "https://git.univ-reunion.fr/sda-php/nulib.git", - "reference": "4037bf20424eb48708e5fdf9fc8e10f2ef71d134" + "version": "dev-dev74", + "dist": { + "type": "path", + "url": "../nulib", + "reference": "a371a68ee2d388d6970eec8ccf83b51cbc8e4e37" }, "require": { "ext-json": "*", @@ -629,18 +629,20 @@ } ], "description": "fonctions et classes essentielles", - "time": "2025-04-30T00:32:10+00:00" + "transport-options": { + "relative": true + } }, { "name": "nulib/phpss", - "version": "0.5.0p74", - "source": { - "type": "git", - "url": "https://git.univ-reunion.fr/sda-php/nulib-phpss.git", - "reference": "26b4bfddf5646f9313d419e568cd930efb9353eb" + "version": "dev-dev74", + "dist": { + "type": "path", + "url": "../nulib-phpss", + "reference": "e68672917d2c51d5cf559835a71d49b66facd081" }, "require": { - "nulib/php": "^0.5.0p74", + "nulib/php": "^7.4-dev", "php": "^7.4", "phpoffice/phpspreadsheet": "^1.0" }, @@ -671,15 +673,17 @@ } ], "description": "wrapper pour phpoffice/phpspreadsheet", - "time": "2025-04-30T00:46:31+00:00" + "transport-options": { + "relative": true + } }, { "name": "nulib/spout", - "version": "0.5.0p74", - "source": { - "type": "git", - "url": "https://git.univ-reunion.fr/sda-php/nulib-spout.git", - "reference": "e650e27abe571553424524633deada32747d33a6" + "version": "dev-dev74", + "dist": { + "type": "path", + "url": "../nulib-spout", + "reference": "853f747bad42718f58aa0c1760f4d2536a165d3d" }, "require": { "ext-dom": "*", @@ -687,7 +691,7 @@ "ext-libxml": "*", "ext-xmlreader": "*", "ext-zip": "*", - "nulib/php": "^0.5.0p74", + "nulib/php": "^7.4-dev", "php": "^7.4" }, "replace": { @@ -725,7 +729,9 @@ } ], "description": "wrapper pour openspout/openspout", - "time": "2025-04-30T00:40:11+00:00" + "transport-options": { + "relative": true + } }, { "name": "nulib/tests", @@ -2939,7 +2945,11 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "nulib/php": 20, + "nulib/spout": 20, + "nulib/phpss": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From a7f6bc939b9bfbdce377f4763af62c1357867ca4 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:35:09 +0400 Subject: [PATCH 53/55] maj projet --- .composer.pman.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.composer.pman.yml b/.composer.pman.yml index 2fe16e2..afdbb47 100644 --- a/.composer.pman.yml +++ b/.composer.pman.yml @@ -11,6 +11,6 @@ composer: dist: link: false require-dev: - nulib/php: ^0.4.0p82 - nulib/spout: ^0.4.0p82 - nulib/phpss: ^0.4.0p82 + nulib/php: ^0.5.0p82 + nulib/spout: ^0.5.0p82 + nulib/phpss: ^0.5.0p82 From c979a30526bfd5f5bca5ce71271d213c84910c4b Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:35:22 +0400 Subject: [PATCH 54/55] Init changelog & version 0.5.0p82 --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 9a2877c..83072ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,5 @@ +## Release 0.5.0p82 du 30/04/2025-05:35 + ## Release 0.5.0p74 du 30/04/2025-05:30 * `2d73f4d` documenter showmorePlugin From 1ecee7a7282b90c5efbc6386b6ae8c25cb5516c4 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Wed, 30 Apr 2025 05:35:31 +0400 Subject: [PATCH 55/55] deps de dist --- composer.json | 18 +- composer.lock | 1017 +++++++++++++++++-------------------------------- 2 files changed, 346 insertions(+), 689 deletions(-) diff --git a/composer.json b/composer.json index b86627d..514ceb3 100644 --- a/composer.json +++ b/composer.json @@ -3,18 +3,6 @@ "type": "library", "description": "espace de maturation pour les librairies", "repositories": [ - { - "type": "path", - "url": "../nulib" - }, - { - "type": "path", - "url": "../nulib-spout" - }, - { - "type": "path", - "url": "../nulib-phpss" - }, { "type": "composer", "url": "https://repos.univ-reunion.fr/composer" @@ -30,9 +18,9 @@ "php": "^8.2" }, "require-dev": { - "nulib/php": "^8.2-dev", - "nulib/spout": "^8.2-dev", - "nulib/phpss": "^8.2-dev", + "nulib/php": "^0.5.0p82", + "nulib/spout": "^0.5.0p82", + "nulib/phpss": "^0.5.0p82", "nulib/tests": "^8.2", "ext-posix": "*", "ext-pcntl": "*", diff --git a/composer.lock b/composer.lock index 5ab7b92..adbbf00 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0b1e015d12aecf1cdfbdc6a702d83d25", + "content-hash": "20d80ba2a043b1e083f352300c19da0f", "packages": [], "packages-dev": [ { @@ -86,165 +86,38 @@ ], "time": "2024-11-12T16:29:46+00:00" }, - { - "name": "doctrine/instantiator", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^11", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.5.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-12-30T00:15:36+00:00" - }, - { - "name": "ezyang/htmlpurifier", - "version": "v4.18.0", - "source": { - "type": "git", - "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "cb56001e54359df7ae76dc522d08845dc741621b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b", - "reference": "cb56001e54359df7ae76dc522d08845dc741621b", - "shasum": "" - }, - "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" - }, - "require-dev": { - "cerdic/css-tidy": "^1.7 || ^2.0", - "simpletest/simpletest": "dev-master" - }, - "suggest": { - "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", - "ext-bcmath": "Used for unit conversion and imagecrash protection", - "ext-iconv": "Converts text to and from non-UTF-8 encodings", - "ext-tidy": "Used for pretty-printing HTML" - }, - "type": "library", - "autoload": { - "files": [ - "library/HTMLPurifier.composer.php" - ], - "psr-0": { - "HTMLPurifier": "library/" - }, - "exclude-from-classmap": [ - "/library/HTMLPurifier/Language/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Edward Z. Yang", - "email": "admin@htmlpurifier.org", - "homepage": "http://ezyang.com" - } - ], - "description": "Standards compliant HTML filter written in PHP", - "homepage": "http://htmlpurifier.org/", - "keywords": [ - "html" - ], - "support": { - "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0" - }, - "time": "2024-11-01T03:51:45+00:00" - }, { "name": "maennchen/zipstream-php", - "version": "2.2.6", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f" + "reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", - "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f", + "reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f", "shasum": "" }, "require": { - "myclabs/php-enum": "^1.5", - "php": "^7.4 || ^8.0", - "psr/http-message": "^1.0", - "symfony/polyfill-mbstring": "^1.0" + "ext-mbstring": "*", + "ext-zlib": "*", + "php-64bit": "^8.2" }, "require-dev": { + "brianium/paratest": "^7.7", "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.9", - "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", + "friendsofphp/php-cs-fixer": "^3.16", + "guzzlehttp/guzzle": "^7.5", "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.4", - "phpunit/phpunit": "^8.5.8 || ^9.4.2", - "vimeo/psalm": "^4.1" + "php-coveralls/php-coveralls": "^2.5", + "phpunit/phpunit": "^11.0", + "vimeo/psalm": "^6.0" + }, + "suggest": { + "guzzlehttp/psr7": "^2.4", + "psr/http-message": "^2.0" }, "type": "library", "autoload": { @@ -281,19 +154,15 @@ ], "support": { "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.6" + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2" }, "funding": [ { "url": "https://github.com/maennchen", "type": "github" - }, - { - "url": "https://opencollective.com/zipstream", - "type": "open_collective" } ], - "time": "2022-11-25T18:57:19+00:00" + "time": "2025-01-27T12:07:53+00:00" }, { "name": "markbaker/complex", @@ -462,69 +331,6 @@ ], "time": "2025-04-29T12:36:36+00:00" }, - { - "name": "myclabs/php-enum", - "version": "1.8.5", - "source": { - "type": "git", - "url": "https://github.com/myclabs/php-enum.git", - "reference": "e7be26966b7398204a234f8673fdad5ac6277802" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/e7be26966b7398204a234f8673fdad5ac6277802", - "reference": "e7be26966b7398204a234f8673fdad5ac6277802", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^4.6.2 || ^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "MyCLabs\\Enum\\": "src/" - }, - "classmap": [ - "stubs/Stringable.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP Enum contributors", - "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" - } - ], - "description": "PHP Enum implementation", - "homepage": "https://github.com/myclabs/php-enum", - "keywords": [ - "enum" - ], - "support": { - "issues": "https://github.com/myclabs/php-enum/issues", - "source": "https://github.com/myclabs/php-enum/tree/1.8.5" - }, - "funding": [ - { - "url": "https://github.com/mnapoli", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", - "type": "tidelift" - } - ], - "time": "2025-01-14T11:49:03+00:00" - }, { "name": "nikic/php-parser", "version": "v5.4.0", @@ -585,16 +391,16 @@ }, { "name": "nulib/php", - "version": "dev-dev74", - "dist": { - "type": "path", - "url": "../nulib", - "reference": "a371a68ee2d388d6970eec8ccf83b51cbc8e4e37" + "version": "0.5.0p82", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/nulib.git", + "reference": "9f8b6545e68079728bb7349487b99024bd7d5090" }, "require": { "ext-json": "*", - "php": "^7.4", - "symfony/yaml": "^5.0" + "php": "^8.2", + "symfony/yaml": "^7.1" }, "require-dev": { "ext-curl": "*", @@ -603,7 +409,7 @@ "ext-pgsql": "*", "ext-posix": "*", "ext-sqlite3": "*", - "nulib/tests": "^7.4" + "nulib/tests": "^8.2" }, "type": "library", "extra": { @@ -629,25 +435,23 @@ } ], "description": "fonctions et classes essentielles", - "transport-options": { - "relative": true - } + "time": "2025-04-30T00:33:36+00:00" }, { "name": "nulib/phpss", - "version": "dev-dev74", - "dist": { - "type": "path", - "url": "../nulib-phpss", - "reference": "e68672917d2c51d5cf559835a71d49b66facd081" + "version": "0.5.0p82", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/nulib-phpss.git", + "reference": "620e1b8eab68afc8bae94b5a936b7929c03bc734" }, "require": { - "nulib/php": "^7.4-dev", - "php": "^7.4", - "phpoffice/phpspreadsheet": "^1.0" + "nulib/php": "^0.5.0p82", + "php": "^8.2", + "phpoffice/phpspreadsheet": "^3.3.0" }, "require-dev": { - "nulib/tests": "^7.4" + "nulib/tests": "^8.2" }, "type": "library", "extra": { @@ -673,36 +477,38 @@ } ], "description": "wrapper pour phpoffice/phpspreadsheet", - "transport-options": { - "relative": true - } + "time": "2025-04-30T00:48:34+00:00" }, { "name": "nulib/spout", - "version": "dev-dev74", - "dist": { - "type": "path", - "url": "../nulib-spout", - "reference": "853f747bad42718f58aa0c1760f4d2536a165d3d" + "version": "0.5.0p82", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/nulib-spout.git", + "reference": "32fbed599e2e3cfc616df70fe51ba8ec4cb3aefd" }, "require": { "ext-dom": "*", + "ext-fileinfo": "*", "ext-filter": "*", "ext-libxml": "*", "ext-xmlreader": "*", "ext-zip": "*", - "nulib/php": "^7.4-dev", - "php": "^7.4" + "nulib/php": "^0.5.0p82", + "php": "^8.2" }, "replace": { - "openspout/openspout": "v3.7.4" + "openspout/openspout": "v4.27.0" }, "require-dev": { "ext-zlib": "*", - "friendsofphp/php-cs-fixer": "^3.4", - "nulib/tests": "^7.4", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1.0" + "friendsofphp/php-cs-fixer": "^3.64.0", + "infection/infection": "^0.29.6", + "nulib/tests": "^8.2", + "phpbench/phpbench": "^1.3.1", + "phpstan/phpstan": "^1.12.4", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.1" }, "type": "library", "extra": { @@ -714,7 +520,7 @@ "autoload": { "psr-4": { "nulib\\": "src", - "OpenSpout\\": "openspout3/src" + "OpenSpout\\": "openspout4/src" } }, "autoload-dev": { @@ -729,21 +535,19 @@ } ], "description": "wrapper pour openspout/openspout", - "transport-options": { - "relative": true - } + "time": "2025-04-30T00:43:21+00:00" }, { "name": "nulib/tests", - "version": "7.4", + "version": "8.2", "source": { "type": "git", "url": "https://git.univ-reunion.fr/sda-php/nulib-tests.git", - "reference": "8f641d9a7cf6aba1453cb42ebd15951aa7002e1b" + "reference": "d6bc680156ef837aabc666da802c5cc7eac8deec" }, "require": { - "php": "^7.3 || 8.0.*", - "phpunit/phpunit": "^9" + "php": "^8.1", + "phpunit/phpunit": "^10" }, "type": "library", "extra": { @@ -769,7 +573,7 @@ } ], "description": "fonctions et classes pour les tests", - "time": "2025-02-28T17:12:35+00:00" + "time": "2025-02-28T17:08:35+00:00" }, { "name": "phar-io/manifest", @@ -891,20 +695,20 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "1.29.10", + "version": "3.9.1", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "c80041b1628c4f18030407134fe88303661d4e4e" + "reference": "56f334ace62fc8301c98d425272cbf0a00eb848d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/c80041b1628c4f18030407134fe88303661d4e4e", - "reference": "c80041b1628c4f18030407134fe88303661d4e4e", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/56f334ace62fc8301c98d425272cbf0a00eb848d", + "reference": "56f334ace62fc8301c98d425272cbf0a00eb848d", "shasum": "" }, "require": { - "composer/pcre": "^1||^2||^3", + "composer/pcre": "^1 || ^2 || ^3", "ext-ctype": "*", "ext-dom": "*", "ext-fileinfo": "*", @@ -918,25 +722,24 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.15", "maennchen/zipstream-php": "^2.1 || ^3.0", "markbaker/complex": "^3.0", "markbaker/matrix": "^3.0", - "php": "^7.4 || ^8.0", + "php": "^8.1", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-main", - "dompdf/dompdf": "^1.0 || ^2.0 || ^3.0", + "dompdf/dompdf": "^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^3.2", "mitoteam/jpgraph": "^10.3", "mpdf/mpdf": "^8.1.1", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5 || ^9.0", + "phpunit/phpunit": "^10.5", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, @@ -991,22 +794,22 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.10" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/3.9.1" }, - "time": "2025-02-08T02:56:14+00:00" + "time": "2025-02-08T03:04:52+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.32", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { @@ -1014,18 +817,18 @@ "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-text-template": "^2.0.4", - "sebastian/code-unit-reverse-lookup": "^2.0.3", - "sebastian/complexity": "^2.0.3", - "sebastian/environment": "^5.1.5", - "sebastian/lines-of-code": "^1.0.4", - "sebastian/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "^10.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -1034,7 +837,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "9.2.x-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -1063,7 +866,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -1071,32 +874,32 @@ "type": "github" } ], - "time": "2024-08-22T04:23:01+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1123,7 +926,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -1131,28 +935,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -1160,7 +964,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1186,7 +990,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -1194,32 +998,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1245,7 +1049,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -1253,32 +1058,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1304,7 +1109,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -1312,24 +1117,23 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "9.6.22", + "version": "10.5.45", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c" + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f80235cb4d3caa59ae09be3adf1ded27521d1a9c", - "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -1339,27 +1143,26 @@ "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.32", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.4", - "phpunit/php-timer": "^5.0.3", - "sebastian/cli-parser": "^1.0.2", - "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.6", - "sebastian/environment": "^5.1.5", - "sebastian/exporter": "^4.0.6", - "sebastian/global-state": "^5.0.7", - "sebastian/object-enumerator": "^4.0.4", - "sebastian/resource-operations": "^3.0.4", - "sebastian/type": "^3.2.1", - "sebastian/version": "^3.0.2" + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.3", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.2", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.0", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -1367,7 +1170,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -1399,7 +1202,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.22" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" }, "funding": [ { @@ -1415,7 +1218,7 @@ "type": "tidelift" } ], - "time": "2024-12-05T13:48:26+00:00" + "time": "2025-02-06T16:08:12+00:00" }, { "name": "psr/http-client", @@ -1526,16 +1329,16 @@ }, { "name": "psr/http-message", - "version": "1.1", + "version": "2.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { @@ -1544,7 +1347,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1559,7 +1362,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -1573,31 +1376,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/1.1" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2023-04-04T09:50:52+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { "name": "psr/simple-cache", - "version": "1.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1612,7 +1415,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for simple caching", @@ -1624,34 +1427,34 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/master" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, - "time": "2017-10-23T01:57:42+00:00" + "time": "2021-10-29T13:26:27+00:00" }, { "name": "sebastian/cli-parser", - "version": "1.0.2", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1674,7 +1477,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" }, "funding": [ { @@ -1682,32 +1486,32 @@ "type": "github" } ], - "time": "2024-03-02T06:27:43+00:00" + "time": "2024-03-02T07:12:49+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1730,7 +1534,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, "funding": [ { @@ -1738,32 +1542,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1785,7 +1589,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -1793,34 +1597,36 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1859,7 +1665,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -1867,33 +1674,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.3", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -1916,7 +1723,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -1924,33 +1732,33 @@ "type": "github" } ], - "time": "2023-12-22T06:19:30+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", - "version": "4.0.6", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1982,7 +1790,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -1990,27 +1799,27 @@ "type": "github" } ], - "time": "2024-03-02T06:30:58+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.5", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -2018,7 +1827,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -2037,7 +1846,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -2045,7 +1854,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -2053,34 +1863,34 @@ "type": "github" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.6", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -2122,7 +1932,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -2130,38 +1941,35 @@ "type": "github" } ], - "time": "2024-03-02T06:33:00+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.7", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2180,13 +1988,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, "funding": [ { @@ -2194,33 +2003,33 @@ "type": "github" } ], - "time": "2024-03-02T06:35:11+00:00" + "time": "2024-03-02T07:19:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.4", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -2243,7 +2052,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -2251,34 +2061,34 @@ "type": "github" } ], - "time": "2023-12-22T06:20:34+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2300,7 +2110,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -2308,32 +2118,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -2355,7 +2165,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -2363,32 +2173,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.5", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2418,7 +2228,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -2426,86 +2236,32 @@ "type": "github" } ], - "time": "2023-02-03T06:07:39+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-14T16:00:52+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "3.2.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2528,7 +2284,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -2536,29 +2292,29 @@ "type": "github" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2581,7 +2337,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -2589,24 +2345,24 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.4", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", - "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { @@ -2615,7 +2371,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" } }, "autoload": { @@ -2640,7 +2396,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -2656,7 +2412,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2737,113 +2493,30 @@ ], "time": "2024-09-09T11:45:10+00:00" }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, { "name": "symfony/yaml", - "version": "v5.4.45", + "version": "v7.2.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "a454d47278cc16a5db371fe73ae66a78a633371e" + "reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a454d47278cc16a5db371fe73ae66a78a633371e", - "reference": "a454d47278cc16a5db371fe73ae66a78a633371e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912", + "reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.3" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^5.3|^6.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "symfony/console": "^6.4|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -2874,7 +2547,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.45" + "source": "https://github.com/symfony/yaml/tree/v7.2.5" }, "funding": [ { @@ -2890,7 +2563,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2025-03-03T07:12:39+00:00" }, { "name": "theseer/tokenizer", @@ -2945,15 +2618,11 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "nulib/php": 20, - "nulib/spout": 20, - "nulib/phpss": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.4" + "php": "^8.2" }, "platform-dev": { "ext-posix": "*",