diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..1f00665 --- /dev/null +++ b/TODO.md @@ -0,0 +1,8 @@ +# TODO + +## schema + +* [ ] properties dans ScalarSchema, avec aliases pour notamment "nature" => "" +* [ ] remplacer IValue et TValue par une classe abstraite Value + +-*- 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/doc/schema.md b/doc/schema.md index 5f3907c..b4f2c3d 100644 --- a/doc/schema.md +++ b/doc/schema.md @@ -183,10 +183,10 @@ const VALUE_SCHEMA = [ "title" => "libellé de la valeur", "required" => false, "nullable" => true, - "desc" => description de la valeur, + "desc" => "description de la valeur", "name" => "identifiant de la valeur", # spécifique à VALUE_SCHEMA - "key" => ""chemin de clé de la valeur dans le tableau associatif", + "key" => "chemin de clé de la valeur dans le tableau associatif", ], ]; ~~~ @@ -199,7 +199,7 @@ const VALUE_SCHEMA = [ "title" => "libellé de la valeur", "required" => false, "nullable" => true, - "desc" => description de la valeur, + "desc" => "description de la valeur", "name" => "identifiant de la valeur", # spécifique à VALUE_SCHEMA "key" => "chemin de clé de la valeur dans le tableau associatif", diff --git a/src/schema/AssocSchema.php b/src/schema/AssocSchema.php index 0c8704b..f34afd5 100644 --- a/src/schema/AssocSchema.php +++ b/src/schema/AssocSchema.php @@ -38,7 +38,8 @@ class AssocSchema extends Schema { $this->definition = $definition; } - function isAssoc(): bool { + function isAssoc(?AssocSchema &$assoc=null): bool { + $assoc = $this; return true; } } diff --git a/src/schema/ListSchema.php b/src/schema/ListSchema.php index 879af16..f4a6bf7 100644 --- a/src/schema/ListSchema.php +++ b/src/schema/ListSchema.php @@ -38,7 +38,8 @@ class ListSchema extends Schema { $this->definition = $definition; } - function isList(): bool { + function isList(?ListSchema &$list=null): bool { + $list = $this; return true; } } diff --git a/src/schema/OldSchema.php b/src/schema/OldSchema.php index 65e9dc9..8472085 100644 --- a/src/schema/OldSchema.php +++ b/src/schema/OldSchema.php @@ -5,21 +5,9 @@ use nur\sery\schema\input\Input; use nur\sery\schema\values\AssocValue; use nur\sery\schema\values\IValue; use nur\sery\schema\values\ScalarValue; -use nur\sery\schema\values\SeqValue; +use nur\sery\schema\values\ListValue; use nulib\StateException; -#XXX -# analyze() et [analyzer_func] --> indique ce qu'est la valeur qu'on vérifixe -# retourne MISSING (la valeur n'existe pas) -# NULL (la valeur existe mais est nulle) -# STRING (la valeur est une chaine qu'il faut parser) -# INVALID (la valeur n'est pas du bon type et il n'est pas possible de la convertir) -# VALID (la valeur est dans le bon type) -# extract() et [extractor_func] --> si analyze() retourne STRING, extraire la -# chaine à parser -# parse() et [parser_func] --> parser la chaine et retourner la valeur -# format() et [formatter_func] --> formatter la valeur et retourner une chaine - class OldSchema { /** * @var bool true si toutes les clés du schéma doivent exister, avec leur @@ -49,11 +37,11 @@ class OldSchema { } /** retourner true la valeur est un tableau séquentiel */ - function getSeq(&$value, $key=null, ?SeqValue &$seq=null): bool { + function getList(&$value, $key=null, ?ListValue &$list=null): bool { if (!$this->isSeq()) return false; if ($value instanceof Input) $input = $value; else $input = new Input($value); - $seq = new SeqValue($input, $this->schema, $key); + $list = new ListValue($input, $this->schema, $key); return true; } @@ -67,9 +55,9 @@ class OldSchema { } function getValue(&$value, $key=null): IValue { - if ($this->getScalar($input, $key, $scalar)) return $scalar; - elseif ($this->getSeq($input, $key, $seq)) return $seq; - elseif ($this->getAssoc($input, $key, $assoc)) return $assoc; + if ($this->getScalar($value, $key, $scalar)) return $scalar; + elseif ($this->getList($value, $key, $seq)) return $seq; + elseif ($this->getAssoc($value, $key, $assoc)) return $assoc; else throw StateException::unexpected_state(); } } diff --git a/src/schema/ScalarSchema.php b/src/schema/ScalarSchema.php index 21dc011..c74c0f9 100644 --- a/src/schema/ScalarSchema.php +++ b/src/schema/ScalarSchema.php @@ -2,8 +2,11 @@ namespace nur\sery\schema; use nulib\cl; +use nur\sery\schema\input\Input; use nur\sery\schema\ref\ref_schema; use nur\sery\schema\ref\ref_types; +use nur\sery\schema\values\IValue; +use nur\sery\schema\values\ScalarValue; /** * Class ScalarSchema @@ -31,13 +34,7 @@ class ScalarSchema extends Schema { "type", "default", "title", "required", "nullable", "desc", "analyzer_func", "extractor_func", "parser_func", "normalizer_func", "messages", "formatter_func", "format", - "", "name", - ]; - const METASCHEMA_INDEXES = [ - "type" => 0, "default" => 1, "title" => 2, "required" => 3, "nullable" => 4, "desc" => 5, - "analyzer_func" => 6, "extractor_func" => 7, "parser_func" => 8, "normalizer_func" => 9, "messages" => 10, - "formatter_func" => 11, "format" => 12, - "" => 13, "name" => 14, + "", "name", "key", "header", "composite", ]; /** @@ -135,6 +132,18 @@ class ScalarSchema extends Schema { throw SchemaException::invalid_schema("expected scalar nature"); } $definition[""] = $nature; + # name, key, header + $name = $definition["name"]; + $key = $definition["key"]; + $header = $definition["header"]; + self::ensure_nstring($name); + self::ensure_npkey($key); + self::ensure_nstring($header); + if ($key === null) $key = $name; + if ($header === null) $header = $name; + $definition["name"] = $name; + $definition["key"] = $key; + $definition["header"] = $header; # autres éléments self::ensure_nstring($definition["title"]); self::ensure_bool($definition["required"]); @@ -146,7 +155,7 @@ class ScalarSchema extends Schema { self::ensure_ncallable($definition["normalizer_func"]); self::ensure_narray($definition["messages"]); self::ensure_ncallable($definition["formatter_func"]); - self::ensure_nkey($definition["name"]); + self::ensure_nbool($definition["composite"]); return $definition; } @@ -156,7 +165,14 @@ class ScalarSchema extends Schema { $this->definition = $definition; } - function isScalar(): bool { + function isScalar(?ScalarSchema &$scalar=null): bool { + $scalar = $this; return true; } + + function getValue(&$value, $key=null): IValue { + if ($value instanceof Input) $input = $value; + else $input = new Input($value); + return new ScalarValue($input, $this, $key); + } } diff --git a/src/schema/Schema.php b/src/schema/Schema.php index 587c52f..1697dff 100644 --- a/src/schema/Schema.php +++ b/src/schema/Schema.php @@ -2,6 +2,7 @@ namespace nur\sery\schema; use nulib\cl; +use nur\sery\schema\values\IValue; abstract class Schema { /** @@ -22,40 +23,52 @@ abstract class Schema { return $md; } - protected static function ensure_nstring(&$string): void { - if ($string !== null && !is_string($string)) $string = strval($string); - } protected static function ensure_string(&$string): void { if (!is_string($string)) $string = strval($string); } - protected static function ensure_nbool(&$bool): void { - if ($bool !== null && !is_bool($bool)) $bool = boolval($bool); + protected static function ensure_nstring(&$string): void { + if ($string !== null) self::ensure_string($string); } protected static function ensure_bool(&$bool): void { if (!is_bool($bool)) $bool = boolval($bool); } - protected static function ensure_ncallable(&$callable): void { - if ($callable !== null && !is_callable($callable)) { - throw SchemaException::invalid_callable($callable); - } + protected static function ensure_nbool(&$bool): void { + if ($bool !== null) self::ensure_bool($bool); } - protected static function ensure_narray(&$array): void { - if ($array !== null && !is_array($array)) $array = cl::with($array); + protected static function ensure_callable(&$callable): void { + if (!is_callable($callable)) throw SchemaException::invalid_callable($callable); + } + protected static function ensure_ncallable(&$callable): void { + if ($callable !== null) self::ensure_callable($callable); } protected static function ensure_array(&$array): void { if (!is_array($array)) $array = cl::with($array); } - protected static function ensure_nkey(&$key): void { - if ($key !== null && !is_string($key) && !is_int($key)) $key = strval($key); + protected static function ensure_narray(&$array): void { + if ($array !== null) self::ensure_array($array); } protected static function ensure_key(&$key): void { if (!is_string($key) && !is_int($key)) $key = strval($key); } - protected static function ensure_ncontent(&$key): void { - if ($key !== null && !is_string($key) && !is_array($key)) $key = strval($key); + protected static function ensure_nkey(&$key): void { + if ($key !== null) self::ensure_key($key); } - protected static function ensure_content(&$key): void { - if (!is_string($key) && !is_array($key)) $key = strval($key); + protected static function ensure_pkey(&$pkey): void { + if (!is_string($pkey) && !is_int($pkey) && !is_array($pkey)) $pkey = strval($pkey); + if (is_array($pkey)) { + foreach ($pkey as &$key) { + self::ensure_key($key); + }; unset($key); + } + } + protected static function ensure_npkey(&$pkey): void { + if ($pkey !== null) self::ensure_pkey($pkey); + } + protected static function ensure_content(&$content): void { + if (!is_string($content) && !is_array($content)) $content = strval($content); + } + protected static function ensure_ncontent(&$content): void { + if ($content !== null) self::ensure_content($content); } /** @@ -68,9 +81,11 @@ abstract class Schema { protected $definition; /** retourner true si le schéma est de nature tableau associatif */ - function isAssoc(): bool { return false; } + function isAssoc(?AssocSchema &$assoc=null): bool { return false; } /** retourner true si le schéma est de nature liste */ - function isList(): bool { return false; } + function isList(?ListSchema &$list=null): bool { return false; } /** retourner true si le schéma est de nature scalaire */ - function isScalar(): bool { return false; } + function isScalar(?ScalarSchema &$scalar=null): bool { return false; } + + abstract function getValue(&$value, $key=null): IValue; } diff --git a/src/schema/ref/ref_analyze.php b/src/schema/ref/ref_analyze.php new file mode 100644 index 0000000..a640ba1 --- /dev/null +++ b/src/schema/ref/ref_analyze.php @@ -0,0 +1,22 @@ + ["array", "scalar", "nature du schéma", "" => ["assoc", "schema" => self::NATURE_METASCHEMA], ], - "name" => ["?key", null, "identifiant de la valeur"], + "name" => ["?string", null, "identifiant de la valeur"], + "key" => ["?pkey", null, "chemin de clé de la valeur dans un tableau associatif"], + "header" => ["?string", null, "nom de l'en-tête s'il faut présenter cette donnée dans un tableau"], + "composite" => ["?bool", null, "ce champ fait-il partie d'une valeur composite?"], ]; const MESSAGES = [ diff --git a/src/schema/ref/ref_types.php b/src/schema/ref/ref_types.php index a3733b5..f7e5198 100644 --- a/src/schema/ref/ref_types.php +++ b/src/schema/ref/ref_types.php @@ -4,6 +4,7 @@ namespace nur\sery\schema\ref; class ref_types { const ALIASES = [ "key" => "string|int", + "pkey" => "string|int|array", "content" => "string|array", ]; } diff --git a/src/schema/values/AssocValue.php b/src/schema/values/AssocValue.php index e6a55ea..1ed2ad2 100644 --- a/src/schema/values/AssocValue.php +++ b/src/schema/values/AssocValue.php @@ -5,7 +5,7 @@ class AssocValue implements IValue { use TValue; function isScalar(?ScalarValue &$scalar=null): bool { return false; } - function isSeq(?SeqValue &$seq=null): bool { return false; } + function isList(?ListValue &$list=null): bool { return false; } function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; } function ensureKeys(): bool { diff --git a/src/schema/values/IValue.php b/src/schema/values/IValue.php index e5a66f6..478f412 100644 --- a/src/schema/values/IValue.php +++ b/src/schema/values/IValue.php @@ -7,8 +7,8 @@ interface IValue { /** retourner true si cette valeur est scalaire */ function isScalar(?ScalarValue &$scalar=null): bool; - /** retourner true cette valeur est un tableau séquentiel */ - function isSeq(?SeqValue &$seq=null): bool; + /** retourner true cette valeur est une liste */ + function isList(?ListValue &$list=null): bool; /** retourner true cette valeur est un tableau associatif */ function isAssoc(?AssocValue &$assoc=null): bool; diff --git a/src/schema/values/SeqValue.php b/src/schema/values/ListValue.php similarity index 76% rename from src/schema/values/SeqValue.php rename to src/schema/values/ListValue.php index c72ca81..e96bc94 100644 --- a/src/schema/values/SeqValue.php +++ b/src/schema/values/ListValue.php @@ -1,11 +1,11 @@ result = $result; } + /** @var array */ protected $result; function __get($name) { diff --git a/src/schema/values/ScalarValue.php b/src/schema/values/ScalarValue.php index 02fe4aa..2ca3dba 100644 --- a/src/schema/values/ScalarValue.php +++ b/src/schema/values/ScalarValue.php @@ -1,21 +1,26 @@ schema = $schema; $this->reset($value, $key, $verifix); + #XXX résoudre les type dans reset()? } function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; } - function isSeq(?SeqValue &$seq=null): bool { return false; } + function isList(?ListValue &$list=null): bool { return false; } function isAssoc(?AssocValue &$assoc=null): bool { return false; } function get($default=null) { @@ -36,7 +41,7 @@ class ScalarValue implements IValue { protected $type; function type(): IType { - if ($this->type === null) $this->type = $this->md()->getType($this->key); + if ($this->type === null) $this->type = $this->schema->getType($this->key); return $this->type; } diff --git a/src/schema/values/TValue.php b/src/schema/values/TValue.php index 37d15de..d2a52d6 100644 --- a/src/schema/values/TValue.php +++ b/src/schema/values/TValue.php @@ -4,16 +4,6 @@ namespace nur\sery\schema\values; use nur\sery\schema\OldSchema; trait TValue { - /** @var array schéma normalisé de cette valeur */ - protected array $schema; - - /** @var OldSchema */ - protected OldSchema $md; - - function md(): OldSchema { - return OldSchema::new($this->md, $this->schema, true); - } - /** @var mixed valeur ou référence d'un tableau contenant la valeur */ protected $value; diff --git a/tests/schema/ScalarSchemaTest.php b/tests/schema/ScalarSchemaTest.php index 40cdd2a..f8e15e3 100644 --- a/tests/schema/ScalarSchemaTest.php +++ b/tests/schema/ScalarSchemaTest.php @@ -20,6 +20,9 @@ class ScalarSchemaTest extends TestCase { "format" => null, "" => ["scalar"], "name" => null, + "key" => null, + "header" => null, + "composite" => null, ]; static function schema(array $schema): array {