modifs.mineures sans commentaires
This commit is contained in:
parent
f8eec57055
commit
a705dd61c4
@ -1,14 +1,19 @@
|
||||
# nulib\schema
|
||||
|
||||
* dans la définition, `[type]` est remplacé par l'instance de IType lors de sa
|
||||
résolution? --> NON, sauf si c'est un type union
|
||||
* newInput dans Schema
|
||||
* ScalarSchema::from_property()
|
||||
|
||||
* dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe
|
||||
commun aux champs dans le tableau destination, e.g
|
||||
~~~php
|
||||
$value = Schema::ns($schema, [
|
||||
$wrapper = Schema::ns($schema, [
|
||||
"a" => "?string",
|
||||
"b" => "?int",
|
||||
])->newValue();
|
||||
])->newWrapper();
|
||||
$dest = ["x_a" => 5, "x_b" => "10"],
|
||||
$value->reset($dest, null, [
|
||||
$wrapper->reset($dest, null, [
|
||||
"key_prefix" => "x_",
|
||||
]);
|
||||
# $dest vaut ["x_a" => "5", "x_b" => 10];
|
||||
@ -19,18 +24,16 @@
|
||||
alternative: c'est lors de la *définition* du schéma que le préfixe est ajouté
|
||||
e.g
|
||||
~~~php
|
||||
$value = Schema::ns($schema, [
|
||||
$wrapper = Schema::ns($schema, [
|
||||
"a" => "?string",
|
||||
"b" => "?int",
|
||||
], [
|
||||
"key_prefix" => "x_",
|
||||
])->newValue();
|
||||
])->newWrapper();
|
||||
$dest = ["x_a" => 5, "x_b" => "10"],
|
||||
$value->reset($dest);
|
||||
$wrapper->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
|
||||
|
@ -1,11 +1,13 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\_scalar;
|
||||
|
||||
use Exception;
|
||||
use nulib\cl;
|
||||
use nulib\ref\schema\ref_analyze;
|
||||
use nulib\ref\schema\ref_schema;
|
||||
use nulib\ValueException;
|
||||
use nur\sery\wip\schema\Result;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class ScalarResult: résultat de l'analyse ou de la normalisation d'une valeur
|
||||
@ -16,12 +18,20 @@ use nur\sery\wip\schema\Result;
|
||||
* @property bool $null si la valeur est disponible, est-elle nulle?
|
||||
* @property bool $valid si la valeur est disponible, est-elle valide?
|
||||
* @property bool $normalized si la valeur est valide, est-elle normalisée?
|
||||
* @property string|null $orig valeur originale avant extraction et analyse
|
||||
* @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 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
|
||||
* normalisée a déjà été calculée
|
||||
*/
|
||||
class ScalarResult extends Result {
|
||||
const KEYS = ["resultAvailable", "present", "available", "null", "valid", "normalized", "orig", "messageKey", "message"];
|
||||
const KEYS = [
|
||||
"resultAvailable",
|
||||
"present", "available", "null", "valid", "normalized",
|
||||
"messageKey", "message",
|
||||
"origValue", "normalizedValue",
|
||||
];
|
||||
|
||||
function isScalar(?ScalarResult &$scalar=null): bool { $scalar = $this; return true; }
|
||||
|
||||
@ -66,8 +76,8 @@ class ScalarResult extends Result {
|
||||
}
|
||||
}
|
||||
|
||||
protected static function replace_orig(string &$message, $orig): void {
|
||||
$message = str_replace("{orig}", strval($orig), $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 {
|
||||
@ -130,27 +140,32 @@ class ScalarResult extends Result {
|
||||
}
|
||||
}
|
||||
|
||||
function setInvalid($value, ScalarSchema $schema): int {
|
||||
function setInvalid($value, ScalarSchema $schema, ?Throwable $t=null): int {
|
||||
$this->resultAvailable = true;
|
||||
$this->present = true;
|
||||
$this->available = true;
|
||||
$this->null = false;
|
||||
$this->valid = false;
|
||||
$this->orig = $value;
|
||||
$this->origValue = $value;
|
||||
$messageKey = $this->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";
|
||||
}
|
||||
$this->message = $message;
|
||||
return ref_analyze::INVALID;
|
||||
}
|
||||
|
||||
function setValid(): int {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -9,22 +9,23 @@ 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 PHPUnit\Event\Code\Throwable;
|
||||
|
||||
class ScalarWrapper extends Wrapper {
|
||||
function __construct(ScalarSchema $schema, &$dest=null, $destKey=null, ?array $params=null) {
|
||||
$defaultVerifix = $params["verifix"] ?? true;
|
||||
$defaultThrow = $params["throw"] ?? null;
|
||||
if ($dest !== null && $defaultThrow === null) {
|
||||
$verifix = $params["verifix"] ?? true;
|
||||
$throw = $params["throw"] ?? null;
|
||||
if ($dest !== null && $throw === null) {
|
||||
# Si $dest est null, ne pas lancer d'exception, parce qu'on considère que
|
||||
# c'est une initialisation sans conséquences
|
||||
$defaultThrow = true;
|
||||
$throw = true;
|
||||
}
|
||||
$this->schema = $schema;
|
||||
$this->verifix = $defaultVerifix;
|
||||
$this->throw = $defaultThrow ?? false;
|
||||
$this->verifix = $verifix;
|
||||
$this->throw = $throw ?? false;
|
||||
$this->result = new ScalarResult();
|
||||
$this->reset($dest, $destKey);
|
||||
$this->throw = $defaultThrow ?? true;
|
||||
$this->throw = $throw ?? true;
|
||||
}
|
||||
|
||||
function isScalar(?ScalarWrapper &$scalar=null): bool { $scalar = $this; return true; }
|
||||
@ -137,19 +138,6 @@ class ScalarWrapper extends Wrapper {
|
||||
}
|
||||
}
|
||||
|
||||
function _extract(AnalyzerContext $context): bool {
|
||||
return $context->type->extract($context->dest);
|
||||
}
|
||||
|
||||
function _parse(AnalyzerContext $context): bool {
|
||||
try {
|
||||
$context->dest = $context->type->parse($context->dest);
|
||||
return true;
|
||||
} catch (ValueException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function analyzeExtractParse(): int {
|
||||
$schema = $this->schema;
|
||||
$input = $this->input;
|
||||
@ -164,42 +152,41 @@ class ScalarWrapper extends Wrapper {
|
||||
else $what = $this->_analyze($context);
|
||||
if ($what !== ref_analyze::STRING) return $what;
|
||||
|
||||
/** @var func $extractorFunc */
|
||||
$extractorFunc = $schema->extractorFunc;
|
||||
if ($extractorFunc !== null) $valid = $extractorFunc->invoke([$context]);
|
||||
else $valid = $this->_extract($context);
|
||||
if (!$valid) return $result->setInvalid($context->orig, $schema);
|
||||
if ($context->type->isNull($context->dest)) return $result->setNull($schema);
|
||||
$extracted = $context->dest;
|
||||
|
||||
/** @var func $parserFunc */
|
||||
$parserFunc = $schema->parserFunc;
|
||||
if ($parserFunc !== null) $valid = $parserFunc->invoke([$context]);
|
||||
else $valid = $this->_parse($context);
|
||||
if ($valid) {
|
||||
$normalized = $context->dest === $context->orig;
|
||||
if ($normalized) {
|
||||
$input->set($context->dest, $destKey);
|
||||
return $result->setNormalized();
|
||||
} else {
|
||||
$input->set($extracted, $destKey);
|
||||
return $result->setValid();
|
||||
}
|
||||
$dest = $context->dest;
|
||||
try {
|
||||
/** @var func $extractorFunc */
|
||||
$extractorFunc = $schema->extractorFunc;
|
||||
if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$dest, $context]);
|
||||
else $extracted = $context->type->extract($dest);
|
||||
$context->dest = $extracted;
|
||||
} catch (ValueException $e) {
|
||||
return $result->setInvalid($context->orig, $schema, $e);
|
||||
}
|
||||
if ($context->type->isNull($extracted)) return $result->setNull($schema);
|
||||
|
||||
try {
|
||||
/** @var func $parserFunc */
|
||||
$parserFunc = $schema->parserFunc;
|
||||
if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context]);
|
||||
else $parsed = $context->type->parse($extracted);
|
||||
$context->dest = $parsed;
|
||||
} catch (ValueException $e) {
|
||||
return $result->setInvalid($context->orig, $schema, $e);
|
||||
}
|
||||
|
||||
$normalized = $parsed === $context->orig;
|
||||
if ($normalized) {
|
||||
$input->set($parsed, $destKey);
|
||||
return $result->setNormalized();
|
||||
} else {
|
||||
$input->set($extracted, $destKey);
|
||||
return $result->setValid($parsed);
|
||||
}
|
||||
return $result->setInvalid($context->orig, $schema);
|
||||
}
|
||||
|
||||
function verifix(?bool $throw=null): bool {
|
||||
$schema = $this->schema;
|
||||
$input = $this->input;
|
||||
$destKey = $this->destKey;
|
||||
$result = $this->result;
|
||||
$context = new AnalyzerContext($schema, $this, $input, $destKey, $result);
|
||||
/** @var func $normalizerFunc */
|
||||
$normalizerFunc = $schema->normalizerFunc;
|
||||
if ($normalizerFunc !== null) return $normalizerFunc->invoke([$context]);
|
||||
|
||||
if ($throw === null) $throw = $this->throw;
|
||||
$destKey = $this->destKey;
|
||||
$verifix = false;
|
||||
$modified = false;
|
||||
if ($result->resultAvailable) {
|
||||
@ -208,18 +195,37 @@ class ScalarWrapper extends Wrapper {
|
||||
# valeur assimilée à null
|
||||
$this->input->set(null, $destKey);
|
||||
} elseif ($result->valid && !$result->normalized) {
|
||||
# normaliser la valeur
|
||||
$verifix = true;
|
||||
$normalizedValue = $result->normalizedValue;
|
||||
if ($normalizedValue !== null) {
|
||||
# la valeur normalisée est disponible
|
||||
$this->input->set($normalizedValue);
|
||||
$result->normalizedValue = null;
|
||||
$modified = true;
|
||||
} else {
|
||||
# normaliser la valeur
|
||||
$verifix = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$verifix = true;
|
||||
}
|
||||
|
||||
if ($verifix) {
|
||||
$value = $this->input->get($destKey);
|
||||
$modified = $this->type->verifix($value, $result, $this->schema);
|
||||
$schema = $this->schema;
|
||||
/** @var func $normalizerFunc */
|
||||
$normalizerFunc = $schema->normalizerFunc;
|
||||
if ($normalizerFunc !== null) {
|
||||
$context = new AnalyzerContext($schema, $this, $this->input, $destKey, $result);
|
||||
$orig = $value;
|
||||
$value = $normalizerFunc->invoke([$orig, $context]);
|
||||
$modified = $value !== $orig;
|
||||
} else {
|
||||
$modified = $this->type->verifix($value, $result, $this->schema);
|
||||
}
|
||||
if ($result->valid) $this->input->set($value, $destKey);
|
||||
}
|
||||
if (!$result->valid) $result->throw($throw);
|
||||
if (!$result->valid) $result->throw($throw ?? $this->throw);
|
||||
return $modified;
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,12 @@ interface IType {
|
||||
*/
|
||||
function isValid($value, ?bool &$normalized=null): bool;
|
||||
|
||||
/** extraire de la chaine la valeur à analyser */
|
||||
function extract(string &$value): bool;
|
||||
/**
|
||||
* extraire de la chaine la valeur à analyser
|
||||
*
|
||||
* @throws ValueException en cas d'erreur d'analyse
|
||||
*/
|
||||
function extract(string $value): string;
|
||||
|
||||
/**
|
||||
* analyser la chaine et retourner la valeur "convertie"
|
||||
|
@ -22,7 +22,7 @@ abstract class _tsimple implements IType {
|
||||
return $value === null || $value === "";
|
||||
}
|
||||
|
||||
function extract(string &$value): bool {
|
||||
return true;
|
||||
function extract(string $value): string {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ abstract class _tstring extends _tsimple {
|
||||
return $params;
|
||||
}
|
||||
|
||||
function extract(string &$value): bool {
|
||||
function extract(string $value): string {
|
||||
if ($this->params["trim"] ?? static::TRIM) $value = trim($value);
|
||||
if ($this->params["norm_nl"] ?? static::NORM_NL) $value = str::norm_nl($value);
|
||||
return true;
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
@ -60,9 +60,8 @@ class tbool extends _tformatable {
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
function extract(string &$value): bool {
|
||||
$value = trim($value);
|
||||
return true;
|
||||
function extract(string $value): string {
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
function parse(string $value) {
|
||||
|
@ -21,9 +21,8 @@ class tfloat extends _tformatable {
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
function extract(string &$value): bool {
|
||||
$value = trim($value);
|
||||
return true;
|
||||
function extract(string $value): string {
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
function parse(string $value) {
|
||||
|
@ -23,9 +23,8 @@ class tint extends _tformatable {
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
function extract(string &$value): bool {
|
||||
$value = trim($value);
|
||||
return true;
|
||||
function extract(string $value): string {
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
function parse(string $value) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\_scalar;
|
||||
|
||||
use Exception;
|
||||
use nulib\tests\TestCase;
|
||||
use nulib\ValueException;
|
||||
use nur\sery\wip\schema\input\Input;
|
||||
@ -34,6 +33,9 @@ class ScalarValueTest extends TestCase {
|
||||
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->checkVerifix($schema, null, false, null, true, true, false, false);
|
||||
$this->checkException($schema, null, true, ValueException::class);
|
||||
|
||||
@ -49,9 +51,6 @@ class ScalarValueTest extends TestCase {
|
||||
$this->checkVerifix($schema, " text ", false, " text ", true, true, true, true);
|
||||
$this->checkVerifix($schema, " text ", true, " text ", true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, false, false, null, true, false, true, true);
|
||||
$this->checkVerifix($schema, false, true, null, true, false, true, true);
|
||||
|
||||
$this->checkVerifix($schema, true, false, true, true, true, true, false);
|
||||
$this->checkVerifix($schema, true, true, "1", true, true, true, false);
|
||||
|
||||
@ -95,6 +94,9 @@ class ScalarValueTest extends TestCase {
|
||||
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->checkVerifix($schema, null, false, null, true, true, false, false);
|
||||
$this->checkException($schema, null, true, ValueException::class);
|
||||
|
||||
@ -102,16 +104,13 @@ class ScalarValueTest extends TestCase {
|
||||
$this->checkVerifix($schema, "", true, "", true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, " ", false, "", true, true, true, false);
|
||||
$this->checkVerifix($schema, " ", true, "", true, true, true, true);
|
||||
$this->checkVerifix($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->checkVerifix($schema, " text ", false, "text", true, true, true, false);
|
||||
$this->checkVerifix($schema, " text ", true, "text", true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, false, false, null, true, false, true, true);
|
||||
$this->checkVerifix($schema, false, true, null, true, false, true, true);
|
||||
$this->checkVerifix($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);
|
||||
@ -133,11 +132,32 @@ class ScalarValueTest extends TestCase {
|
||||
|
||||
$this->checkVerifix($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->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);
|
||||
|
||||
$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->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams);
|
||||
$this->checkVerifix($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->checkVerifix($schema, null, false, null, true, true, false, false);
|
||||
$this->checkException($schema, null, true, ValueException::class);
|
||||
|
||||
@ -165,9 +185,6 @@ class ScalarValueTest extends TestCase {
|
||||
$this->checkVerifix($schema, "text", false, "text", true, true, false, false);
|
||||
$this->checkException($schema, "text", true, ValueException::class);
|
||||
|
||||
$this->checkVerifix($schema, false, false, null, true, false, true, true);
|
||||
$this->checkVerifix($schema, false, true, null, true, false, true, true);
|
||||
|
||||
$this->checkVerifix($schema, true, false, true, true, true, true, false);
|
||||
$this->checkVerifix($schema, true, true, 1, true, true, true, false);
|
||||
|
||||
@ -185,5 +202,23 @@ class ScalarValueTest extends TestCase {
|
||||
|
||||
$this->checkVerifix($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->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);
|
||||
|
||||
$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->checkVerifix($schema, "", false, null, true, false, true, true, $inputParams);
|
||||
$this->checkVerifix($schema, "", true, null, true, false, true, true, $inputParams);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user