From fa8fd6e7c3043d0b0c6f99db706c8fa37f1f4276 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Thu, 23 May 2024 08:16:02 +0400 Subject: [PATCH] =?UTF-8?q?supprimer=20schema=20qui=20n'est=20pas=20encore?= =?UTF-8?q?=20pr=C3=AAt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/src/file/app/RunFile.php | 11 +- php/src/schema/OldSchema.php | 22 --- php/src/schema/README.md | 197 ----------------------- php/src/schema/Result.php | 30 ---- php/src/schema/Schema.php | 94 ----------- php/src/schema/SchemaException.php | 22 --- php/src/schema/TODO.md | 82 ---------- php/src/schema/Value.php | 85 ---------- php/src/schema/_assoc/AssocResult.php | 8 - php/src/schema/_assoc/AssocSchema.php | 55 ------- php/src/schema/_assoc/AssocValue.php | 18 --- php/src/schema/_list/ListResult.php | 8 - php/src/schema/_list/ListSchema.php | 53 ------- php/src/schema/_list/ListValue.php | 19 --- php/src/schema/_scalar/ScalarResult.php | 165 -------------------- php/src/schema/_scalar/ScalarSchema.php | 193 ----------------------- php/src/schema/_scalar/ScalarValue.php | 198 ------------------------ php/src/schema/input/FormInput.php | 46 ------ php/src/schema/input/GetInput.php | 35 ----- php/src/schema/input/Input.php | 61 -------- php/src/schema/input/PostInput.php | 35 ----- php/src/schema/types.php | 37 ----- php/src/schema/types/IType.php | 33 ---- php/src/schema/types/Registry.php | 36 ----- php/src/schema/types/_tsimple.php | 14 -- php/src/schema/types/tarray.php | 27 ---- php/src/schema/types/tbool.php | 123 --------------- php/src/schema/types/tcallable.php | 29 ---- php/src/schema/types/tcontent.php | 26 ---- php/src/schema/types/tfloat.php | 50 ------ php/src/schema/types/tint.php | 52 ------- php/src/schema/types/tkey.php | 26 ---- php/src/schema/types/tpkey.php | 32 ---- php/src/schema/types/tstring.php | 48 ------ 34 files changed, 10 insertions(+), 1960 deletions(-) delete mode 100644 php/src/schema/OldSchema.php delete mode 100644 php/src/schema/README.md delete mode 100644 php/src/schema/Result.php delete mode 100644 php/src/schema/Schema.php delete mode 100644 php/src/schema/SchemaException.php delete mode 100644 php/src/schema/TODO.md delete mode 100644 php/src/schema/Value.php delete mode 100644 php/src/schema/_assoc/AssocResult.php delete mode 100644 php/src/schema/_assoc/AssocSchema.php delete mode 100644 php/src/schema/_assoc/AssocValue.php delete mode 100644 php/src/schema/_list/ListResult.php delete mode 100644 php/src/schema/_list/ListSchema.php delete mode 100644 php/src/schema/_list/ListValue.php delete mode 100644 php/src/schema/_scalar/ScalarResult.php delete mode 100644 php/src/schema/_scalar/ScalarSchema.php delete mode 100644 php/src/schema/_scalar/ScalarValue.php delete mode 100644 php/src/schema/input/FormInput.php delete mode 100644 php/src/schema/input/GetInput.php delete mode 100644 php/src/schema/input/Input.php delete mode 100644 php/src/schema/input/PostInput.php delete mode 100644 php/src/schema/types.php delete mode 100644 php/src/schema/types/IType.php delete mode 100644 php/src/schema/types/Registry.php delete mode 100644 php/src/schema/types/_tsimple.php delete mode 100644 php/src/schema/types/tarray.php delete mode 100644 php/src/schema/types/tbool.php delete mode 100644 php/src/schema/types/tcallable.php delete mode 100644 php/src/schema/types/tcontent.php delete mode 100644 php/src/schema/types/tfloat.php delete mode 100644 php/src/schema/types/tint.php delete mode 100644 php/src/schema/types/tkey.php delete mode 100644 php/src/schema/types/tpkey.php delete mode 100644 php/src/schema/types/tstring.php diff --git a/php/src/file/app/RunFile.php b/php/src/file/app/RunFile.php index c931804..501930d 100644 --- a/php/src/file/app/RunFile.php +++ b/php/src/file/app/RunFile.php @@ -42,10 +42,11 @@ class RunFile { "serial" => 0, "date_start" => $dateStart, "date_stop" => null, + "exitcode" => null, "action" => null, "action_date_start" => null, - "action_max_step" => null, "action_current_step" => null, + "action_max_step" => null, "action_date_step" => null, ]; } @@ -119,6 +120,14 @@ class RunFile { ])); } + /** après l'arrêt de l'application, mettre à jour le code de retour */ + function stopped(int $exitcode): void { + [$file, $data] = $this->willWrite(); + $file->serialize(self::merge($data, [ + "exitcode" => $exitcode, + ])); + } + function getLockFile(?string $name=null, ?string $title=null): LockFile { $ext = self::LOCK_EXT; if ($name !== null) $ext = ".$name$ext"; diff --git a/php/src/schema/OldSchema.php b/php/src/schema/OldSchema.php deleted file mode 100644 index d823e4d..0000000 --- a/php/src/schema/OldSchema.php +++ /dev/null @@ -1,22 +0,0 @@ - NATURE, -]; -~~~ - -La nature indique le type de données représenté par le schéma. -* nature scalaire: modélise une donnée scalaire - ~~~php - const SCALAR_SCHEMA = [ - $type, [$default, $title, ...] - "" => "scalar", - ]; - ~~~ - Si le type est "array" ou "?array", on peut préciser le schéma de la donnée - ~~~php - const SCALAR_SCHEMA = [ - "?array", [$default, $title, ...] - "" => "scalar", - "schema" => NAKED_SCHEMA, - ]; - ~~~ -* nature tableau associatif: modélise un tableau associatif (le tableau peut - avoir des clés numériques ou chaines --> seules les clés décrites par le - schéma sont validées) - ~~~php - const ASSOC_SCHEMA = [ - KEY => VALUE_SCHEMA, - ... - "" => "assoc", - ]; - ~~~ - la nature "tableau associatif" est du sucre syntaxique pour une valeur - scalaire de type "?array" dont on précise le schéma - ~~~php - // la valeur ci-dessus est strictement équivalent à - const ASSOC_SCHEMA = [ - "?array", - "" => "scalar", - "schema" => [ - KEY => VALUE_SCHEMA, - ... - ], - ]; - ~~~ - -* nature liste: modélise une liste de valeurs du même type (le tableau peut - avoir des clés numériques ou chaines --> on ne modélise ni le type ni la - valeur des clés) - ~~~php - const LIST_SCHEMA = [ - "?array", [$default, $title, ...] - "" => "list", - "schema" => ITEM_SCHEMA, - ]; - ~~~ - -## Schéma d'une valeur scalaire - -Dans sa forme normalisée, une valeur scalaire est généralement modélisée de -cette manière: -~~~php -const SCALAR_SCHEMA = [ - "type" => "types autorisés de la valeur", - "default" => "valeur par défaut si la valeur n'existe pas", - "title" => "libellé de la valeur, utilisable par exemple dans un formulaire", - "required" => "la valeur est-elle requise? si oui, elle doit exister", - "nullable" => "si la valeur existe, peut-elle être nulle?", - "desc" => "description de la valeur", - "checker_func" => "une fonction qui vérifie une valeur et la classifie", - "parser_func" => "une fonction qui analyse une chaine pour produire la valeur", - "messages" => "messages à afficher en cas d'erreur d'analyse", - "formatter_func" => "une fonction qui formatte la valeur pour affichage", - "format" => "format à utiliser pour l'affichage", - "" => "scalar", - "schema" => "schéma de la valeur si le type est array ou ?array, null sinon", -]; -~~~ - -L'ordre des clés du schéma ci-dessus indique la clé associé à une valeur si elle -est fournie dans un tableau séquentiel. Par exemple, les deux schéma suivants -sont équivalents: -~~~php -const SCALAR_SCHEMA1 = [ - "string", null, "une valeur chaine", -]; -const SCALAR_SCHEMA2 = [ - "type" => "string", - "default" => null, - "title" => "une valeur chaine", - "" => "scalar", -]; -~~~ - -Si la nature du schéma n'est pas spécifiée, on considère que c'est un schéma de -nature scalaire si: -* c'est une chaine, qui représente alors le type, e.g `"string"` -* c'est un tableau avec un unique élément à l'index 0 de type chaine, qui est - aussi le type, e.g `["string"]` -* c'est un tableau avec un élément à l'index 0, ainsi que d'autres éléments, - e.g `["string", null, "required" => true]` - -message indique les messages à afficher en cas d'erreur d'analyse. les clés sont -normalisées et correspondent à différents états de la valeur tels qu'analysés -par `checker_func` -~~~php -const MESSAGE_SCHEMA = [ - "missing" => "message si la valeur n'existe pas dans la source et qu'elle est requise", - "unavailable" => "message si la valeur vaut false dans la source et qu'elle est requise", - "null" => "message si la valeur est nulle et qu'elle n'est pas nullable", - "empty" => "message si la valeur est une chaine vide et que ce n'est pas autorisé", - "invalid" => "message si la valeur est invalide", -]; -~~~ - -## Schéma d'un tableau associatif - -Dans sa forme *non normalisée*, un tableau associatif est généralement modélisé -de cette manière: -~~~php -const ASSOC_SCHEMA = [ - KEY => VALUE_SCHEMA, - ... - "" => "assoc", -]; -~~~ -où chaque occurrence de `KEY => VALUE_SCHEMA` définit le schéma de la valeur -dont la clé est `KEY` - -Si la nature du schéma n'est pas spécifiée, on considère que c'est un schéma de -nature associative si: -* c'est un tableau uniquement associatif avec aucun élément séquentiel, e.g - `["name" => "string", "age" => "int"]` - -VALUE_SCHEMA peut-être n'importe quel schéma valide, qui sera analysé -récursivement, avec cependant l'ajout de quelques clés supplémentaires: -* description de la valeur dans le contexte du tableau - ~~~php - VALUE_SCHEMA = [ - ... - "name" => "identifiant de la valeur", - "pkey" => "chemin de clé de la valeur dans le tableau associatif", - ]; - ~~~ -* s'il s'agit d'une valeur scalaire simple autre que array - ~~~php - VALUE_SCHEMA = [ - ... - "header" => "nom de l'en-tête s'il faut présenter cette donnée dans un tableau", - "composite" => "ce champ fait-il partie d'une valeur composite?", - ]; - ~~~ - -## Schéma d'une liste (tableau séquentiel ou associatif d'éléments du même type) - -Dans sa forme *non normalisée*, une liste est généralement modélisée de cette -manière: -~~~php -const LIST_SCHEMA = [ITEM_SCHEMA]; -~~~ -où ITEM_SCHEMA est le schéma des éléments de la liste - -Pour information, la forme normalisée est plutôt de la forme -~~~php -const LIST_SCHEMA = [ - "?array", - "" => "list", - "schema" => ITEM_SCHEMA, -]; -~~~ -le type "?array" ou "array" indique si la liste est nullable ou non. la valeur -par défaut est "?array" - -Si la nature du schéma n'est pas spécifiée, on considère que c'est un schéma de -nature liste si: -* c'est un tableau avec un unique élément de type tableau à l'index 0, e.g - `[["string", null, "required" => true]]` - --*- 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 diff --git a/php/src/schema/Result.php b/php/src/schema/Result.php deleted file mode 100644 index af6c680..0000000 --- a/php/src/schema/Result.php +++ /dev/null @@ -1,30 +0,0 @@ -reset(); - } - - function isAssoc(?AssocResult &$assoc=null): bool { return false; } - function isList(?ListResult &$list=null): bool { return false; } - function isScalar(?ScalarResult &$scalar=null): bool { return false; } - - /** - * Obtenir la liste des clés valides pour les valeurs accessibles via cet - * objet - */ - abstract function getKeys(): array; - - /** obtenir un objet pour gérer la valeur spécifiée */ - abstract function getResult($key=null): Result; - - abstract function reset(): void; -} diff --git a/php/src/schema/Schema.php b/php/src/schema/Schema.php deleted file mode 100644 index 76c606b..0000000 --- a/php/src/schema/Schema.php +++ /dev/null @@ -1,94 +0,0 @@ -newValue($destv, $dest, $destKey); - } - - /** - * @var array définition du schéma, à redéfinir le cas échéant dans une classe - * dérivée - */ - const SCHEMA = null; - - /** @var array */ - protected $definition; - - /** retourner true si le schéma est de nature tableau associatif */ - function isAssoc(?AssocSchema &$assoc=null): bool { return false; } - /** retourner true si le schéma est de nature liste */ - function isList(?ListSchema &$list=null): bool { return false; } - /** retourner true si le schéma est de nature scalaire */ - function isScalar(?ScalarSchema &$scalar=null): bool { return false; } - - abstract function newValue(?Value &$destv=null, &$dest=null, $destKey=null): Value; - - ############################################################################# - # key & properties - - function offsetExists($offset): bool { - return array_key_exists($offset, $this->definition); - } - function offsetGet($offset) { - if (!array_key_exists($offset, $this->definition)) return null; - else return $this->definition[$offset]; - } - function offsetSet($offset, $value): void { - throw AccessException::read_only(null, $offset); - } - function offsetUnset($offset): void { - throw AccessException::read_only(null, $offset); - } - - const _PROPERTY_PKEYS = []; - function __get($name) { - $pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name); - return cl::pget($this->definition, $pkey); - } -} diff --git a/php/src/schema/SchemaException.php b/php/src/schema/SchemaException.php deleted file mode 100644 index f6e3998..0000000 --- a/php/src/schema/SchemaException.php +++ /dev/null @@ -1,22 +0,0 @@ - "?string", - "b" => "?int", - ])->newValue(); - $dest = ["x_a" => 5, "x_b" => "10"], - $value->reset($dest, null, [ - "key_prefix" => "x_", - ]); - # $dest vaut ["x_a" => "5", "x_b" => 10]; - ~~~ - définir si le préfixe doit être spécifié sur le schéma ou sur la valeur... - actuellement, le code ne permet pas de définir de tels paramètres... - - alternative: c'est lors de la *définition* du schéma que le préfixe est ajouté - e.g - ~~~php - $value = Schema::ns($schema, [ - "a" => "?string", - "b" => "?int", - ], [ - "key_prefix" => "x_", - ])->newValue(); - $dest = ["x_a" => 5, "x_b" => "10"], - $value->reset($dest); - # $dest vaut ["x_a" => "5", "x_b" => 10]; - ~~~ -* dans la définition, `[type]` est remplacé par l'instance de IType lors de sa - résolution? -* implémenter l'instanciation de types avec des paramètres particuliers. *si* - des paramètres sont fournis, le type est instancié avec la signature - `IType($typeDefinition, $schemaDefinition)` e.g - ~~~php - const SCHEMA = ["type", default, "required" => true]; - # le type est instancié comme suit: - $type = new ttype(); - - const SCHEMA = [[["type", ...]], default, "required" => true]; - # le type est instancié comme suit: - # le tableau peut être une liste ou associatif, c'est au type de décider ce - # qu'il en fait - $type = new ttype(["type", ...], SCHEMA); - ~~~ -* ajouter à IType les méthodes getName() pour le nom officiel du type, - getAliases() pour les alias supportés, et getClass() pour la définition de la - classe dans les méthodes et propriétés - getName() et getAliases() sont juste pour information, ils ne sont pas utilisés - lors de la résolution du type effectif. -* si cela a du sens, dans AssocSchema, n'instancier les schémas de chaque clé qu'à la demande. - l'idée est de ne pas perdre du temps à instancier un schéma qui ne serait pas utilisé - - on pourrait avoir d'une manière générale quelque chose comme: - ~~~ - Schema::ensure(&$schema, ?array $def=null, $defKey=null): Schema; - ~~~ - * si $schema est une instance de Schema, la retourner - * si c'est un array, c'est une définition et il faut la remplacer par l'instance de Schema correspondant - * sinon, prendre $def comme définition - $key est la clé si $schema est dans un autre schema -* actuellement, pour un schéma associatif, si on normalise un tableau séquentiel, - chaque valeur correspond à la clé de même rang, eg. pour un schéma - ~~~php - const SCHEMA = ["first" => DEF, "second" => DEF]; - const ARRAY = ["first", "second"]; - ~~~ - la valeur normalisée de `ARRAY` est `["first" => "first", "second" => "second"]` - - cependant, dans certaines circonstances (notamment pour des paramètres), on - devrait pouvoir considérer une valeur indexée comme un flag, i.e la valeur - normalisée de ARRAY serait `["first" => true, "second" => true]` - - 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" - --*- 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 diff --git a/php/src/schema/Value.php b/php/src/schema/Value.php deleted file mode 100644 index 4c512db..0000000 --- a/php/src/schema/Value.php +++ /dev/null @@ -1,85 +0,0 @@ -getKeys() as $key) { - yield $key => $this->getValue($key); - } - } - - /** - * obtenir le résultat de l'appel d'une des fonctions {@link set()} ou - * {@link unset()} - */ - abstract function getResult(): Result; - - /** retourner true si la valeur existe */ - abstract function isPresent(): bool; - - /** retourner le type associé à la valeur */ - abstract function getType(): IType; - - /** retourner true si la valeur est disponible */ - abstract function isAvailable(): bool; - - /** retourner true si la valeur est valide */ - abstract function isValid(): bool; - - /** retourner true si la valeur est dans sa forme normalisée */ - abstract function isNormalized(): bool; - - /** obtenir la valeur */ - abstract function get($default=null); - - /** remplacer la valeur */ - abstract function set($value): self; - - /** supprimer la valeur */ - abstract function unset(): self; - - /** formatter la valeur pour affichage */ - abstract function format($format=null): string; - - ############################################################################# - # key & properties - - function offsetExists($offset): bool { - return in_array($offset, $this->getKeys()); - } - - function offsetGet($offset) { - return $this->getValue($offset); - } - - function offsetSet($offset, $value): void { - $this->getValue($offset)->set($value); - } - - function offsetUnset($offset): void { - $this->getValue($offset)->unset(); - } -} diff --git a/php/src/schema/_assoc/AssocResult.php b/php/src/schema/_assoc/AssocResult.php deleted file mode 100644 index f698968..0000000 --- a/php/src/schema/_assoc/AssocResult.php +++ /dev/null @@ -1,8 +0,0 @@ -definition = $definition; - } - - function isAssoc(?AssocSchema &$assoc=null): bool { - $assoc = $this; - return true; - } - - function newValue(?Value &$destv=null, &$dest=null, $destKey=null): AssocValue { - if ($destv instanceof AssocValue) return $destv->reset($dest, $destKey); - else return ($destv = new AssocValue($this, $dest, $destKey)); - } -} diff --git a/php/src/schema/_assoc/AssocValue.php b/php/src/schema/_assoc/AssocValue.php deleted file mode 100644 index 94eeade..0000000 --- a/php/src/schema/_assoc/AssocValue.php +++ /dev/null @@ -1,18 +0,0 @@ -definition = $definition; - } - - function isList(?ListSchema &$list=null): bool { - $list = $this; - return true; - } - - function newValue(?Value &$destv=null, &$dest=null, $destKey=null): ListValue { - if ($destv instanceof ListValue) return $destv->reset($dest, $destKey); - else return ($destv = new ListValue($this, $dest, $destKey)); - } -} diff --git a/php/src/schema/_list/ListValue.php b/php/src/schema/_list/ListValue.php deleted file mode 100644 index 21208d9..0000000 --- a/php/src/schema/_list/ListValue.php +++ /dev/null @@ -1,19 +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 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, $orig): void { - $message = str_replace("{orig}", strval($orig), $message); - } - - protected function getMessage(string $key, ScalarSchema $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 { - $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 { - $message = $this->getMessage("missing", $schema); - self::replace_key($message, $schema->name); - $this->message = $message; - return ref_analyze::MISSING; - } - } - - function setUnavailable(ScalarSchema $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 { - $message = $this->getMessage("unavailable", $schema); - self::replace_key($message, $schema->name); - $this->message = $message; - return ref_analyze::UNAVAILABLE; - } - } - - function setNull(ScalarSchema $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 { - $message = $this->getMessage("null", $schema); - self::replace_key($message, $schema->name); - $this->message = $message; - return ref_analyze::NULL; - } - } - - function setInvalid($value, ScalarSchema $schema): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = false; - $this->orig = $value; - $message = $this->getMessage("invalid", $schema); - self::replace_key($message, $schema->name); - self::replace_orig($message, $schema->orig); - $this->message = $message; - return ref_analyze::INVALID; - } - - function setValid(): int { - $this->resultAvailable = true; - $this->present = true; - $this->available = true; - $this->null = false; - $this->valid = true; - 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) throw new ValueException($this->message); - } -} diff --git a/php/src/schema/_scalar/ScalarSchema.php b/php/src/schema/_scalar/ScalarSchema.php deleted file mode 100644 index 823b4e5..0000000 --- a/php/src/schema/_scalar/ScalarSchema.php +++ /dev/null @@ -1,193 +0,0 @@ - 1; - } - - static function normalize($definition, $definitionKey=null): array { - 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(self::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] = self::METASCHEMA[$key][1]; - } - } - } - # réordonner les clés numériques - if (cl::have_num_keys($definition)) { - $keys = array_keys($definition); - $index = 0; - foreach ($keys as $key) { - if (!is_int($key)) continue; - $definition[$index] = $definition[$key]; - unset($definition[$key]); - $index++; - } - } - # type - $types = []; - $deftype = $definition["type"]; - $nullable = $definition["nullable"]; - if ($deftype === null) { - $types[] = null; - $nullable = true; - } else { - if (!is_array($deftype)) { - if (!is_string($deftype)) throw SchemaException::invalid_type($deftype); - $deftype = explode("|", $deftype); - } - foreach ($deftype as $type) { - if ($type === null || $type === "null") { - $nullable = true; - continue; - } - if (!is_string($type)) throw SchemaException::invalid_type($type); - if (substr($type, 0, 1) == "?") { - $type = substr($type, 1); - $nullable = true; - } - if ($type === "") throw SchemaException::invalid_type($type); - $type = cl::get(ref_types::ALIASES, $type, $type); - $types = array_merge($types, explode("|", $type)); - } - if (!$types) throw SchemaException::invalid_schema("scalar: type is required"); - $types = array_keys(array_fill_keys($types, true)); - } - $definition["type"] = $types; - $definition["nullable"] = $nullable; - # nature - $nature = $definition[""]; - tarray::ensure_array($nature); - if (!array_key_exists(0, $nature) || $nature[0] !== "scalar") { - throw SchemaException::invalid_schema("expected scalar nature"); - } - $definition[""] = $nature; - # name, pkey, header - $name = $definition["name"]; - $pkey = $definition["pkey"]; - $header = $definition["header"]; - if ($name === null) $name = $definitionKey; - tstring::ensure_nstring($name); - tpkey::ensure_npkey($pkey); - tstring::ensure_nstring($header); - if ($pkey === null) $pkey = $name; - if ($header === null) $header = $name; - $definition["name"] = $name; - $definition["pkey"] = $pkey; - $definition["header"] = $header; - # autres éléments - tstring::ensure_nstring($definition["title"]); - 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"]); - tarray::ensure_narray($definition["messages"]); - tcallable::ensure_ncallable($definition["formatter_func"]); - tbool::ensure_nbool($definition["composite"]); - return $definition; - } - - function __construct($definition=null, $definitionKey=null, bool $normalize=true) { - if ($definition === null) $definition = static::SCHEMA; - if ($normalize) $definition = self::normalize($definition, $definitionKey); - $this->definition = $definition; - } - - function isScalar(?ScalarSchema &$scalar=null): bool { - $scalar = $this; - return true; - } - - function newValue(?Value &$destv=null, &$dest=null, $destKey=null): ScalarValue { - if ($destv instanceof ScalarValue) return $destv->reset($dest, $destKey); - else return ($destv = new ScalarValue($this, $dest, $destKey)); - } - - ############################################################################# - # 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/php/src/schema/_scalar/ScalarValue.php b/php/src/schema/_scalar/ScalarValue.php deleted file mode 100644 index 70577dc..0000000 --- a/php/src/schema/_scalar/ScalarValue.php +++ /dev/null @@ -1,198 +0,0 @@ -schema = $schema; - $this->defaultVerifix = $defaultVerifix; - $this->defaultThrow = $defaultThrow !== null? $defaultThrow: false; - $this->result = new ScalarResult(); - $this->reset($dest, $destKey); - $this->defaultThrow = $defaultThrow !== null? $defaultThrow: true; - } - - function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; } - - /** @var ScalarSchema schéma de cette valeur */ - protected $schema; - - /** @var Input source et destination de la valeur */ - protected $input; - - /** @var string|int|null clé de la valeur dans le tableau destination */ - protected $destKey; - - /** @var bool */ - protected $defaultVerifix; - - /** @var bool */ - protected $defaultThrow; - - /** @var IType type de la valeur après analyse */ - protected $type; - - /** @var ?ScalarResult résultat de l'analyse de la valeur */ - protected $result; - - function reset(&$dest, $destKey=null, ?bool $verifix=null): Value { - if ($dest instanceof Input) $input = $dest; - else $input = new Input($dest); - $this->input = $input; - $this->destKey = $destKey; - $this->type = null; - $this->_analyze(); - if ($verifix == null) $verifix = $this->defaultVerifix; - if ($verifix) $this->verifix(); - return $this; - } - - function getKeys(): array { - return [null]; - } - - function getValue($key=null): ScalarValue { - if ($key === null) return $this; - throw ValueException::invalid_key($key); - } - - /** analyser la valeur et résoudre son type */ - function _analyze(): int { - $schema = $this->schema; - $input = $this->input; - $destKey = $this->destKey; - $result = $this->result; - $result->reset(); - if (!$input->isPresent($destKey)) return $result->setMissing($schema); - $haveType = false; - $types = []; - $type = $firstType = null; - $haveValue = false; - $value = null; - # d'abord chercher un type pour lequel c'est une valeur normalisée - foreach ($schema->type as $name) { - $type = types::get($name); - if ($firstType === null) $firstType = $type; - $types[] = $type; - if ($type->isAvailable($input, $destKey)) { - if (!$haveValue) { - $value = $input->get($destKey); - $haveValue = true; - } - if ($type->isValid($value, $normalized) && $normalized) { - $haveType = true; - $this->type = $type; - break; - } - } - } - if (!$haveType) { - # ensuite chercher un type pour lequel la valeur est valide - foreach ($types as $type) { - if ($type->isAvailable($input, $destKey) && $type->isValid($value)) { - $haveType = true; - $this->type = $type; - break; - } - } - } - # sinon prendre le premier type - if (!$haveType) $type = $this->type = $firstType; - if (!$type->isAvailable($input, $destKey)) return $result->setUnavailable($schema); - $value = $input->get($destKey); - if ($type->isNull($value)) return $result->setNull($schema); - if ($type->isValid($value, $normalized)) { - if ($normalized) return $result->setNormalized(); - else return $result->setValid(); - } - if (is_string($value)) return ref_analyze::STRING; - else return $result->setInvalid($value, $schema); - } - - function verifix(?bool $throw=null): bool { - if ($throw === null) $throw = $this->defaultThrow; - $destKey = $this->destKey; - $verifix = false; - $result =& $this->result; - $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, $destKey); - } elseif ($result->valid && !$result->normalized) { - # normaliser la valeur - $verifix = true; - } - } else { - $verifix = true; - } - if ($verifix) { - $value = $this->input->get($destKey); - $modified = $this->type->verifix($value, $result, $this->schema); - if ($result->valid) $this->input->set($value, $destKey); - } - if (!$result->valid) $result->throw($throw); - return $modified; - } - - function getResult(): ScalarResult { - return $this->result; - } - - function isPresent(): bool { - return $this->result->present; - } - - function getType(): IType { - return $this->type; - } - - function isAvailable(): bool { - return $this->result->available; - } - - function isValid(): bool { - return $this->result->valid; - } - - function isNormalized(): bool { - return $this->result->normalized; - } - - function get($default=null) { - if ($this->result->available) return $this->input->get($this->destKey); - else return $default; - } - - function set($value, ?bool $verifix=null): ScalarValue { - $this->input->set($value, $this->destKey); - $this->_analyze(); - if ($verifix === null) $verifix = $this->defaultVerifix; - if ($verifix) $this->verifix(); - return $this; - } - - function unset(?bool $verifix=null): ScalarValue { - $this->input->unset($this->destKey); - $this->_analyze(); - if ($verifix === null) $verifix = $this->defaultVerifix; - if ($verifix) $this->verifix(); - return $this; - } - - function format($format=null): string { - return $this->type->format($this->input->get($this->destKey), $format); - } -} diff --git a/php/src/schema/input/FormInput.php b/php/src/schema/input/FormInput.php deleted file mode 100644 index 701254d..0000000 --- a/php/src/schema/input/FormInput.php +++ /dev/null @@ -1,46 +0,0 @@ -allowEmpty || $_POST[$key] !== ""; - } elseif (array_key_exists($key, $_GET)) { - return $this->allowEmpty || $_GET[$key] !== ""; - } else { - return false; - } - } - - function get($key=null) { - if ($key === null) return null; - if (array_key_exists($key, $_POST)) { - $value = $_POST[$key]; - if ($value === "" && !$this->allowEmpty) return null; - return $value; - } elseif (array_key_exists($key, $_GET)) { - $value = $_GET[$key]; - if ($value === "" && !$this->allowEmpty) return null; - return $value; - } else { - return null; - } - } -} diff --git a/php/src/schema/input/GetInput.php b/php/src/schema/input/GetInput.php deleted file mode 100644 index d1ed48e..0000000 --- a/php/src/schema/input/GetInput.php +++ /dev/null @@ -1,35 +0,0 @@ -allowEmpty || $_GET[$key] !== ""; - } else { - return false; - } - } - - function get($key=null) { - if ($key === null) return null; - if (array_key_exists($key, $_GET)) { - $value = $_GET[$key]; - if ($value === "" && !$this->allowEmpty) return null; - return $value; - } else { - return null; - } - } -} diff --git a/php/src/schema/input/Input.php b/php/src/schema/input/Input.php deleted file mode 100644 index 87fc08d..0000000 --- a/php/src/schema/input/Input.php +++ /dev/null @@ -1,61 +0,0 @@ -dest =& $dest; - $allowEmpty = cl::get($params, "allow_empty"); - if ($allowEmpty === null) $allowEmpty = static::ALLOW_EMPTY; - $this->allowEmpty = $allowEmpty; - } - - protected $dest; - - /** tester si la valeur existe sans tenir compte de $allowEmpty */ - function isPresent($key=null): bool { - if ($key === null) return true; - $dest = $this->dest; - return $dest !== null && array_key_exists($key, $dest); - } - - /** - * @var bool comment considérer une chaine vide: "" si allowEmpty, null sinon - */ - protected $allowEmpty; - - /** tester si la valeur est disponible en tenant compte de $allowEmpty */ - function isAvailable($key=null): bool { - if ($key === null) return true; - $dest = $this->dest; - if ($dest === null || !array_key_exists($key, $dest)) return false; - return $this->allowEmpty || $dest[$key] !== ""; - } - - function get($key=null) { - $dest = $this->dest; - if ($key === null) return $dest; - if ($dest === null || !array_key_exists($key, $dest)) return null; - $value = $dest[$key]; - if ($value === "" && !$this->allowEmpty) return null; - return $value; - } - - function set($value, $key=null): void { - if ($key === null) $this->dest = $value; - else $this->dest[$key] = $value; - } - - function unset($key=null): void { - if ($key === null) $this->dest = null; - else unset($this->dest[$key]); - } -} diff --git a/php/src/schema/input/PostInput.php b/php/src/schema/input/PostInput.php deleted file mode 100644 index 88a0edd..0000000 --- a/php/src/schema/input/PostInput.php +++ /dev/null @@ -1,35 +0,0 @@ -allowEmpty || $_POST[$key] !== ""; - } else { - return false; - } - } - - function get($key=null) { - if ($key === null) return null; - if (array_key_exists($key, $_POST)) { - $value = $_POST[$key]; - if ($value === "" && !$this->allowEmpty) return null; - return $value; - } else { - return null; - } - } -} diff --git a/php/src/schema/types.php b/php/src/schema/types.php deleted file mode 100644 index a8e30ef..0000000 --- a/php/src/schema/types.php +++ /dev/null @@ -1,37 +0,0 @@ -get($name); - } - - static function string(): tstring { return self::get("string"); } - static function bool(): tbool { return self::get("bool"); } - static function int(): tint { return self::get("int"); } - static function float(): tfloat { return self::get("float"); } - static function array(): tarray { return self::get("array"); } - static function callable(): tcallable { return self::get("callable"); } -} diff --git a/php/src/schema/types/IType.php b/php/src/schema/types/IType.php deleted file mode 100644 index 71017cf..0000000 --- a/php/src/schema/types/IType.php +++ /dev/null @@ -1,33 +0,0 @@ - tstring::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, - "array" => tarray::class, - "callable" => tcallable::class, - # types spéciaux - "key" => tkey::class, - "pkey" => tpkey::class, - "content" => tcontent::class, - ]; - - function __construct() { - $this->types = []; - } - - /** @var IType[] */ - protected $types; - - function get(string $name): IType { - $type = cl::get($this->types, $name); - if ($type === null) { - $class = self::TYPES[$name]; - $type = $this->types[$name] = new $class(); - } - return $type; - } -} diff --git a/php/src/schema/types/_tsimple.php b/php/src/schema/types/_tsimple.php deleted file mode 100644 index ad2895e..0000000 --- a/php/src/schema/types/_tsimple.php +++ /dev/null @@ -1,14 +0,0 @@ -isAvailable($destKey) && $input->get($destKey) !== false; - } - - function isNull($value): bool { - return $value === null || (is_string($value) && trim($value) === ""); - } -} diff --git a/php/src/schema/types/tarray.php b/php/src/schema/types/tarray.php deleted file mode 100644 index f7b335b..0000000 --- a/php/src/schema/types/tarray.php +++ /dev/null @@ -1,27 +0,0 @@ -isAvailable($destKey); - } - - function isValid($value, ?bool &$normalized=null): bool { - $normalized = is_bool($value); - if (is_string($value)) { - $value = trim($value); - $valid = self::is_yes($value) || self::is_no($value); - } else { - $valid = is_scalar($value); - } - return $valid; - } - - /** - * @var ScalarResult $result - * @var ScalarSchema $schema - */ - function verifix(&$value, Result &$result, Schema $schema): bool { - if (is_bool($value)) { - $result->setNormalized(); - return false; - } elseif (is_string($value)) { - $bool = trim($value); - if (self::is_yes($bool)) $value = true; - elseif (self::is_no($bool)) $value = false; - else return $result->setInvalid($value, $schema); - } elseif (is_scalar($value)) { - $value = boolval($value); - } else { - return $result->setInvalid($value, $schema); - } - $result->setValid(); - return true; - } - - const OUINON_FORMAT = ["Oui", "Non", false]; - const OUINONNULL_FORMAT = ["Oui", "Non", ""]; - const ON_FORMAT = ["O", "N", false]; - const ONN_FORMAT = ["O", "N", ""]; - const XN_FORMAT = ["X", "", false]; - const OZ_FORMAT = ["1", "", false]; - const FORMATS = [ - "ouinon" => self::OUINON_FORMAT, - "ouinonnull" => self::OUINONNULL_FORMAT, - "on" => self::ON_FORMAT, - "onn" => self::ONN_FORMAT, - "xn" => self::XN_FORMAT, - "oz" => self::OZ_FORMAT, - ]; - - const DEFAULT_FORMAT = self::OUINON_FORMAT; - - function format($value, $format=null): string { - if ($format === null) $format = static::DEFAULT_FORMAT; - if (is_string($format)) { - $oformat = $format; - $format = cl::get(self::FORMATS, strtolower($oformat)); - if ($format === null) throw ValueException::invalid_kind($oformat, "format"); - } - if ($value === null) { - $null = $format[2]; - if ($null !== false) return $null; - } - return $value? $format[0]: $format[1]; - } -} diff --git a/php/src/schema/types/tcallable.php b/php/src/schema/types/tcallable.php deleted file mode 100644 index fab6e86..0000000 --- a/php/src/schema/types/tcallable.php +++ /dev/null @@ -1,29 +0,0 @@ -setNormalized(); - return false; - } elseif (is_string($value)) { - $float = trim($value); - if (is_numeric($float)) $value = floatval($float); - else return $result->setInvalid($value, $schema); - } elseif (is_scalar($value)) { - $value = floatval($value); - } else { - return $result->setInvalid($value, $schema); - } - $result->setValid(); - return true; - } - - function format($value, $format=null): string { - if ($format !== null) return sprintf($format, $value); - else return strval($value); - } -} diff --git a/php/src/schema/types/tint.php b/php/src/schema/types/tint.php deleted file mode 100644 index ca59754..0000000 --- a/php/src/schema/types/tint.php +++ /dev/null @@ -1,52 +0,0 @@ -setNormalized(); - return false; - } elseif (is_string($value)) { - $int = trim($value); - if (is_numeric($int)) $value = intval($int); - else return $result->setInvalid($value, $schema); - } elseif (is_scalar($value)) { - $value = intval($value); - } else { - return $result->setInvalid($value, $schema); - } - $result->setValid(); - return true; - } - - function format($value, $format=null): string { - if ($format !== null) return sprintf($format, $value); - else return strval($value); - } -} diff --git a/php/src/schema/types/tkey.php b/php/src/schema/types/tkey.php deleted file mode 100644 index 120e729..0000000 --- a/php/src/schema/types/tkey.php +++ /dev/null @@ -1,26 +0,0 @@ -setNormalized(); - return false; - } elseif (is_scalar($value)) { - $value = strval($value); - $result->setValid(); - return true; - } else { - $result->setInvalid($value, $schema); - return false; - } - } - - function format($value, $format=null): string { - return strval($value); - } -}