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\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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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],
|
||||
];
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user