modifs.mineures sans commentaires
This commit is contained in:
parent
62987d576e
commit
1feffb6c0f
@ -17,6 +17,29 @@ use nur\sery\wip\schema\types\tcontent;
|
|||||||
use nur\sery\wip\schema\types\tpkey;
|
use nur\sery\wip\schema\types\tpkey;
|
||||||
use nur\sery\wip\schema\types\trawstring;
|
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 {
|
abstract class Schema implements ArrayAccess {
|
||||||
/**
|
/**
|
||||||
* créer le cas échéant une nouvelle instance de {@link Schema} à partir d'une
|
* 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 */
|
/** retourner true si le schéma est de nature scalaire */
|
||||||
function isScalar(?ScalarSchema &$schema=null): bool { return false; }
|
function isScalar(?ScalarSchema &$schema=null): bool { return false; }
|
||||||
|
|
||||||
|
abstract protected function newWrapper(): Wrapper;
|
||||||
|
|
||||||
abstract function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): 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);
|
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) {
|
function __get($name) {
|
||||||
$pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name);
|
$pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name);
|
||||||
return cl::pget($this->definition, $pkey);
|
return cl::pget($this->definition, $pkey);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# nulib\schema
|
# nulib\schema
|
||||||
|
|
||||||
* instance de WrapperContext directement dans le schéma
|
|
||||||
* plus de {key} ni {orig} dans messages
|
* plus de {key} ni {orig} dans messages
|
||||||
* les messages standard ne sont utilisés que s'il n'y a pas de message dans
|
* les messages standard ne sont utilisés que s'il n'y a pas de message dans
|
||||||
l'exception
|
l'exception
|
||||||
|
@ -5,26 +5,31 @@ use nur\sery\wip\schema\input\Input;
|
|||||||
use nur\sery\wip\schema\types\IType;
|
use nur\sery\wip\schema\types\IType;
|
||||||
|
|
||||||
class WrapperContext {
|
class WrapperContext {
|
||||||
function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) {
|
function __construct(Schema $schema, Wrapper $wrapper, ?Input $input, $valueKey, Result $result) {
|
||||||
$this->schema = $schema;
|
$this->schema = $schema;
|
||||||
$this->wrapper = $wrapper;
|
$this->wrapper = $wrapper;
|
||||||
$this->input = $input;
|
if ($input !== null) $this->input = $input;
|
||||||
$this->result = $result;
|
$this->valueKey = $valueKey;
|
||||||
$this->type = null;
|
$this->type = null;
|
||||||
|
$this->result = $result;
|
||||||
$this->origValue = null;
|
$this->origValue = null;
|
||||||
$this->value = null;
|
$this->value = null;
|
||||||
$this->valueKey = $valueKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** schéma de la valeur */
|
||||||
public Schema $schema;
|
public Schema $schema;
|
||||||
|
/** instance de Wrapper associé à ce contexte */
|
||||||
public Wrapper $wrapper;
|
public Wrapper $wrapper;
|
||||||
|
/** source et destination de la valeur */
|
||||||
public Input $input;
|
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;
|
public ?IType $type;
|
||||||
|
/** résultat de l'analyse de la valeur */
|
||||||
|
public Result $result;
|
||||||
/** @var mixed */
|
/** @var mixed */
|
||||||
public $origValue;
|
public $origValue;
|
||||||
/** @var mixed */
|
/** @var mixed */
|
||||||
public $value;
|
public $value;
|
||||||
/** @var int|string|null */
|
|
||||||
public $valueKey;
|
|
||||||
}
|
}
|
||||||
|
@ -8,26 +8,6 @@ use nur\sery\wip\schema\Wrapper;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ScalarSchema
|
* 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 {
|
class ScalarSchema extends Schema {
|
||||||
/** @var array meta-schema d'un schéma de nature scalaire */
|
/** @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();
|
if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper();
|
||||||
return $wrapper->reset($value, $valueKey, $verifix);
|
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],
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
@ -19,35 +19,21 @@ class ScalarWrapper extends Wrapper {
|
|||||||
# c'est une initialisation sans conséquences
|
# c'est une initialisation sans conséquences
|
||||||
$throw = true;
|
$throw = true;
|
||||||
}
|
}
|
||||||
|
$this->context = new WrapperContext($schema, $this, null, null, new ScalarResult());
|
||||||
$this->verifix = $verifix;
|
$this->verifix = $verifix;
|
||||||
$this->throw = $throw ?? false;
|
$this->throw = $throw ?? false;
|
||||||
$this->schema = $schema;
|
|
||||||
$this->result = new ScalarResult();
|
|
||||||
$this->reset($value, $valueKey);
|
$this->reset($value, $valueKey);
|
||||||
$this->throw = $throw ?? true;
|
$this->throw = $throw ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
|
function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
|
||||||
|
|
||||||
|
protected WrapperContext $context;
|
||||||
|
|
||||||
protected bool $verifix;
|
protected bool $verifix;
|
||||||
|
|
||||||
protected bool $throw;
|
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 {
|
protected function newInput(&$value): Input {
|
||||||
return new Input($value);
|
return new Input($value);
|
||||||
}
|
}
|
||||||
@ -55,9 +41,9 @@ class ScalarWrapper extends Wrapper {
|
|||||||
function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper {
|
function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper {
|
||||||
if ($value instanceof Input) $input = $value;
|
if ($value instanceof Input) $input = $value;
|
||||||
else $input = $this->newInput($value);
|
else $input = $this->newInput($value);
|
||||||
$this->input = $input;
|
$this->context->input = $input;
|
||||||
$this->valueKey = $valueKey;
|
$this->context->valueKey = $valueKey;
|
||||||
$this->type = null;
|
$this->context->type = null;
|
||||||
$this->analyze();
|
$this->analyze();
|
||||||
if ($verifix ?? $this->verifix) $this->verifix();
|
if ($verifix ?? $this->verifix) $this->verifix();
|
||||||
return $this;
|
return $this;
|
||||||
@ -74,7 +60,8 @@ class ScalarWrapper extends Wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** analyser la valeur et résoudre son type */
|
/** analyser la valeur et résoudre son type */
|
||||||
protected function analyze0(WrapperContext $context): int {
|
protected function analyze0(): int {
|
||||||
|
$context = $this->context;
|
||||||
/** @var ScalarSchema $schema */
|
/** @var ScalarSchema $schema */
|
||||||
$schema = $context->schema;
|
$schema = $context->schema;
|
||||||
$input = $context->input;
|
$input = $context->input;
|
||||||
@ -112,7 +99,7 @@ class ScalarWrapper extends Wrapper {
|
|||||||
$args = $name;
|
$args = $name;
|
||||||
$name = $key;
|
$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;
|
if ($firstType === null) $firstType = $type;
|
||||||
$types[] = $type;
|
$types[] = $type;
|
||||||
if ($type->isAvailable($input, $valueKey)) {
|
if ($type->isAvailable($input, $valueKey)) {
|
||||||
@ -166,17 +153,19 @@ class ScalarWrapper extends Wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function analyze(): int {
|
protected function analyze(): int {
|
||||||
$schema = $this->schema;
|
$context = $this->context;
|
||||||
$input = $this->input;
|
/** @var ScalarSchema $schema */
|
||||||
$valueKey = $this->valueKey;
|
$schema = $context->schema;
|
||||||
$result = $this->result;
|
$input = $context->input;
|
||||||
|
$valueKey = $context->valueKey;
|
||||||
|
/** @var ScalarResult $result */
|
||||||
|
$result = $context->result;
|
||||||
$result->reset();
|
$result->reset();
|
||||||
$context = new WrapperContext($schema, $this, $input, $valueKey, $result);
|
|
||||||
|
|
||||||
/** @var func $analyzerFunc */
|
/** @var func $analyzerFunc */
|
||||||
$analyzerFunc = $schema->analyzerFunc;
|
$analyzerFunc = $schema->analyzerFunc;
|
||||||
if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context]);
|
if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context]);
|
||||||
else $what = $this->analyze0($context);
|
else $what = $this->analyze0();
|
||||||
if ($what !== ref_analyze::STRING) return $what;
|
if ($what !== ref_analyze::STRING) return $what;
|
||||||
|
|
||||||
$value = $context->value;
|
$value = $context->value;
|
||||||
@ -212,20 +201,27 @@ class ScalarWrapper extends Wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function verifix(?bool $throw=null): bool {
|
function verifix(?bool $throw=null): bool {
|
||||||
$result = $this->result;
|
$context = $this->context;
|
||||||
$valueKey = $this->valueKey;
|
/** @var ScalarSchema $schema */
|
||||||
|
$schema = $context->schema;
|
||||||
|
$input = $context->input;
|
||||||
|
$valueKey = $context->valueKey;
|
||||||
|
/** @var ScalarResult $result */
|
||||||
|
$result = $context->result;
|
||||||
|
|
||||||
|
|
||||||
$verifix = false;
|
$verifix = false;
|
||||||
$modified = false;
|
$modified = false;
|
||||||
if ($result->resultAvailable) {
|
if ($result->resultAvailable) {
|
||||||
if ($result->null) {
|
if ($result->null) {
|
||||||
# forcer la valeur null, parce que la valeur actuelle est peut-être une
|
# forcer la valeur null, parce que la valeur actuelle est peut-être une
|
||||||
# valeur assimilée à null
|
# valeur assimilée à null
|
||||||
$this->input->set(null, $valueKey);
|
$input->set(null, $valueKey);
|
||||||
} elseif ($result->valid && !$result->normalized) {
|
} elseif ($result->valid && !$result->normalized) {
|
||||||
$normalizedValue = $result->normalizedValue;
|
$normalizedValue = $result->normalizedValue;
|
||||||
if ($normalizedValue !== null) {
|
if ($normalizedValue !== null) {
|
||||||
# la valeur normalisée est disponible
|
# la valeur normalisée est disponible
|
||||||
$this->input->set($normalizedValue);
|
$input->set($normalizedValue);
|
||||||
$result->normalizedValue = null;
|
$result->normalizedValue = null;
|
||||||
$modified = true;
|
$modified = true;
|
||||||
} else {
|
} else {
|
||||||
@ -238,75 +234,80 @@ class ScalarWrapper extends Wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($verifix) {
|
if ($verifix) {
|
||||||
$value = $this->input->get($valueKey);
|
$value = $input->get($valueKey);
|
||||||
$schema = $this->schema;
|
|
||||||
/** @var func $normalizerFunc */
|
/** @var func $normalizerFunc */
|
||||||
$normalizerFunc = $schema->normalizerFunc;
|
$normalizerFunc = $schema->normalizerFunc;
|
||||||
if ($normalizerFunc !== null) {
|
if ($normalizerFunc !== null) {
|
||||||
$context = new WrapperContext($schema, $this, $this->input, $valueKey, $result);
|
$context = new WrapperContext($schema, $this, $input, $valueKey, $result);
|
||||||
$orig = $value;
|
$orig = $value;
|
||||||
$value = $normalizerFunc->invoke([$orig, $context]);
|
$value = $normalizerFunc->invoke([$orig, $context]);
|
||||||
$modified = $value !== $orig;
|
$modified = $value !== $orig;
|
||||||
} else {
|
} 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);
|
if (!$result->valid) $result->throw($throw ?? $this->throw);
|
||||||
return $modified;
|
return $modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getResult(): ScalarResult {
|
function getResult(): ScalarResult {
|
||||||
return $this->result;
|
/** @var ScalarResult $result */
|
||||||
|
$result = $this->context->result;
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPresent(): bool {
|
function isPresent(): bool {
|
||||||
return $this->result->present;
|
return $this->context->result->present;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getType(): IType {
|
function getType(): IType {
|
||||||
return $this->type;
|
return $this->context->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAvailable(): bool {
|
function isAvailable(): bool {
|
||||||
return $this->result->available;
|
return $this->context->result->available;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValid(): bool {
|
function isValid(): bool {
|
||||||
return $this->result->valid;
|
return $this->context->result->valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNormalized(): bool {
|
function isNormalized(): bool {
|
||||||
return $this->result->normalized;
|
return $this->context->result->normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get($default=null) {
|
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;
|
else return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set($value, ?bool $verifix=null): ScalarWrapper {
|
function set($value, ?bool $verifix=null): ScalarWrapper {
|
||||||
$this->input->set($value, $this->valueKey);
|
$context = $this->context;
|
||||||
|
$context->input->set($value, $context->valueKey);
|
||||||
$this->analyze();
|
$this->analyze();
|
||||||
if ($verifix ?? $this->verifix) $this->verifix();
|
if ($verifix ?? $this->verifix) $this->verifix();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unset(?bool $verifix=null): ScalarWrapper {
|
function unset(?bool $verifix=null): ScalarWrapper {
|
||||||
$this->input->unset($this->valueKey);
|
$context = $this->context;
|
||||||
|
$context->input->unset($context->valueKey);
|
||||||
$this->analyze();
|
$this->analyze();
|
||||||
if ($verifix ?? $this->verifix) $this->verifix();
|
if ($verifix ?? $this->verifix) $this->verifix();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
function format($format=null): string {
|
function format($format=null): string {
|
||||||
$value = $this->input->get($this->valueKey);
|
$context = $this->context;
|
||||||
|
$value = $context->input->get($context->valueKey);
|
||||||
/** @var func $formatterFunc */
|
/** @var func $formatterFunc */
|
||||||
$formatterFunc = $this->schema->formatterFunc;
|
$formatterFunc = $context->schema->formatterFunc;
|
||||||
if ($formatterFunc !== null) {
|
if ($formatterFunc !== null) {
|
||||||
# la fonction formatter n'a pas forcément accès au format de la définition
|
# la fonction formatter n'a pas forcément accès au format de la définition
|
||||||
# le lui fournir ici
|
# le lui fournir ici
|
||||||
$format ??= $this->schema->format;
|
$format ??= $context->schema->format;
|
||||||
return $formatterFunc->invoke([$value, $format]);
|
return $formatterFunc->invoke([$value, $format]);
|
||||||
} else {
|
} else {
|
||||||
# on assume que le type a été initialisé avec le format de la définition
|
# on assume que le type a été initialisé avec le format de la définition
|
||||||
|
Loading…
Reference in New Issue
Block a user