modifs.mineures sans commentaires
This commit is contained in:
parent
4e379ac5d8
commit
6266d3020d
|
@ -68,7 +68,7 @@ abstract class Schema implements ArrayAccess {
|
|||
/** retourner true si le schéma est de nature scalaire */
|
||||
function isScalar(?ScalarSchema &$scalar=null): bool { return false; }
|
||||
|
||||
abstract function newValue(?Value &$value=null, &$dest=null, $key=null): Value;
|
||||
abstract function newValue(?Value &$value=null, &$dest=null, $destKey=null): Value;
|
||||
|
||||
#############################################################################
|
||||
# key & properties
|
||||
|
|
|
@ -45,10 +45,10 @@ class AssocSchema extends Schema {
|
|||
return true;
|
||||
}
|
||||
|
||||
function newValue(?Value &$value=null, &$dest=null, $key=null): Value {
|
||||
function newValue(?Value &$value=null, &$dest=null, $destKey=null): Value {
|
||||
if (!($value instanceof AssocValue)) $value = new AssocValue($this);
|
||||
if ($dest instanceof Input) $input = $dest;
|
||||
else $input = new Input($dest);
|
||||
return $value->reset($input, $key);
|
||||
return $value->reset($input, $destKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ class ListSchema extends Schema {
|
|||
return true;
|
||||
}
|
||||
|
||||
function newValue(?Value &$value=null, &$dest=null, $key=null): Value {
|
||||
function newValue(?Value &$value=null, &$dest=null, $destKey=null): Value {
|
||||
if (!($value instanceof ListValue)) $value = new ListValue($this);
|
||||
return $value->reset($dest, $key);
|
||||
return $value->reset($dest, $destKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use nur\sery\schema\Result;
|
|||
/**
|
||||
* Class ScalarResult: résultat de l'analyse ou de la normalisation d'une valeur
|
||||
*
|
||||
* @property bool $resultAvailable le résultat est-il disponible?
|
||||
* @property bool $present la valeur existe-t-elle?
|
||||
* @property bool $available si la valeur existe, est-elle disponible?
|
||||
* @property bool $null si la valeur est disponible, est-elle nulle?
|
||||
|
@ -19,7 +20,7 @@ use nur\sery\schema\Result;
|
|||
* @property string|null $message message si la valeur n'est pas valide
|
||||
*/
|
||||
class ScalarResult extends Result {
|
||||
const KEYS = ["present", "available", "null", "valid", "normalized", "orig", "message"];
|
||||
const KEYS = ["resultAvailable", "present", "available", "null", "valid", "normalized", "orig", "message"];
|
||||
|
||||
function isScalar(?ScalarResult &$scalar=null): bool { $scalar = $this; return true; }
|
||||
|
||||
|
@ -38,6 +39,7 @@ class ScalarResult extends Result {
|
|||
function reset(): void {
|
||||
$this->result = array_merge(
|
||||
array_fill_keys(static::KEYS, null), [
|
||||
"resultAvailable" => false,
|
||||
"present" => false,
|
||||
"available" => false,
|
||||
"null" => false,
|
||||
|
@ -67,18 +69,14 @@ class ScalarResult extends Result {
|
|||
$message = str_replace("{orig}", strval($orig), $message);
|
||||
}
|
||||
|
||||
protected function getMessages(ScalarSchema $schema): ?array {
|
||||
return $schema->messages;
|
||||
}
|
||||
|
||||
protected function getMessage(string $key, ScalarSchema $schema): string {
|
||||
$messages = $this->getMessages($schema);
|
||||
$message = cl::get($messages, $key);
|
||||
$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) {
|
||||
|
@ -95,6 +93,7 @@ class ScalarResult extends Result {
|
|||
}
|
||||
|
||||
function setUnavailable(ScalarSchema $schema): int {
|
||||
$this->resultAvailable = true;
|
||||
$this->present = true;
|
||||
$this->available = false;
|
||||
if (!$schema->required) {
|
||||
|
@ -111,6 +110,7 @@ class ScalarResult extends Result {
|
|||
}
|
||||
|
||||
function setNull(ScalarSchema $schema): int {
|
||||
$this->resultAvailable = true;
|
||||
$this->present = true;
|
||||
$this->available = true;
|
||||
$this->null = true;
|
||||
|
@ -127,6 +127,7 @@ class ScalarResult extends Result {
|
|||
}
|
||||
|
||||
function setInvalid($value, ScalarSchema $schema): int {
|
||||
$this->resultAvailable = true;
|
||||
$this->present = true;
|
||||
$this->available = true;
|
||||
$this->null = false;
|
||||
|
@ -140,6 +141,7 @@ class ScalarResult extends Result {
|
|||
}
|
||||
|
||||
function setValid(): int {
|
||||
$this->resultAvailable = true;
|
||||
$this->present = true;
|
||||
$this->available = true;
|
||||
$this->null = false;
|
||||
|
@ -148,6 +150,7 @@ class ScalarResult extends Result {
|
|||
}
|
||||
|
||||
function setNormalized(): int {
|
||||
$this->resultAvailable = true;
|
||||
$this->present = true;
|
||||
$this->available = true;
|
||||
$this->null = false;
|
||||
|
|
|
@ -180,9 +180,9 @@ class ScalarSchema extends Schema {
|
|||
return true;
|
||||
}
|
||||
|
||||
function newValue(?Value &$value=null, &$dest=null, $key=null): Value {
|
||||
if (!($value instanceof ScalarValue)) $value = new ScalarValue($this);
|
||||
return $value->reset($dest, $key);
|
||||
function newValue(?Value &$value=null, &$dest=null, $destKey=null): Value {
|
||||
if ($value instanceof ScalarValue) return $value->reset($dest, $destKey);
|
||||
else return ($value = new ScalarValue($this, $dest, $destKey));
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
|
|
@ -72,16 +72,38 @@ class ScalarValue extends Value {
|
|||
$result->reset();
|
||||
if (!$input->isPresent($destKey)) return $result->setMissing($schema);
|
||||
$haveType = false;
|
||||
$firstType = null;
|
||||
$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;
|
||||
if ($type->canAnalyze($input, $destKey)) {
|
||||
$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);
|
||||
|
@ -91,17 +113,33 @@ class ScalarValue extends Value {
|
|||
else return $result->setValid();
|
||||
}
|
||||
if (is_string($value)) return ref_analyze::STRING;
|
||||
else return $result->setInvalid($schema, $schema);
|
||||
else return $result->setInvalid($value, $schema);
|
||||
}
|
||||
|
||||
function verifix(?bool $throw=null): bool {
|
||||
$type = $this->getType();
|
||||
$destKey = $this->destKey;
|
||||
$value = $this->input->get($destKey);
|
||||
$modified = $type->verifix($value, $this->result, $this->schema);
|
||||
if ($throw === null) $throw = $this->defaultThrow;
|
||||
if ($this->result->valid) $this->input->set($value, $destKey);
|
||||
else $this->result->throw($throw);
|
||||
$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;
|
||||
}
|
||||
|
||||
|
@ -151,6 +189,6 @@ class ScalarValue extends Value {
|
|||
}
|
||||
|
||||
function format($format=null): string {
|
||||
return $this->getType()->format($this->input->get($this->destKey), $format);
|
||||
return $this->type->format($this->input->get($this->destKey), $format);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,6 @@ use nur\sery\schema\Schema;
|
|||
* Interface IType: un type de données
|
||||
*/
|
||||
interface IType {
|
||||
/** ce type peut-il analyser la donnée dans $input[$destKey] ? */
|
||||
function canAnalyze(Input $input, $destKey): bool;
|
||||
|
||||
/** la donnée $input[$destKey] est-elle disponible? */
|
||||
function isAvailable(Input $input, $destKey): bool;
|
||||
|
||||
|
|
|
@ -16,19 +16,12 @@ class tint implements IType {
|
|||
if ($int !== null) self::ensure_int($int);
|
||||
}
|
||||
|
||||
function canAnalyze(Input $input, $destKey): bool {
|
||||
if (!$input->isAvailable()) return true;
|
||||
$value = $input->get($destKey);
|
||||
if ($value === false || $value === null) return true;
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
function isAvailable(Input $input, $destKey): bool {
|
||||
return $input->isAvailable($destKey) && $input->get($destKey) !== false;
|
||||
}
|
||||
|
||||
function isNull($value): bool {
|
||||
return $value === null;
|
||||
return $value === null || (is_string($value) && trim($value) === "");
|
||||
}
|
||||
|
||||
const INT_PATTERN = '/^[-+]?[0-9]+(?:\.[0-9]*)?$/';
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?php
|
||||
namespace nur\sery\schema\types;
|
||||
|
||||
use nur\b\ValueException;
|
||||
use nur\sery\schema\_scalar\ScalarResult;
|
||||
use nur\sery\schema\_scalar\ScalarSchema;
|
||||
use nur\sery\schema\_scalar\ScalarValue;
|
||||
use nur\sery\schema\input\Input;
|
||||
use nur\sery\schema\Result;
|
||||
use nur\sery\schema\Schema;
|
||||
|
@ -18,13 +16,6 @@ class tstring implements IType {
|
|||
if ($string !== null) self::ensure_string($string);
|
||||
}
|
||||
|
||||
function canAnalyze(Input $input, $destKey): bool {
|
||||
if (!$input->isAvailable()) return true;
|
||||
$value = $input->get($destKey);
|
||||
if ($value === false || $value === null) return true;
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
function isAvailable(Input $input, $destKey): bool {
|
||||
return $input->isAvailable($destKey) && $input->get($destKey) !== false;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class schemaTest extends TestCase {
|
|||
self::assertSame(12, $intv->get());
|
||||
self::assertSame(12, $int);
|
||||
self::assertSame("12", $intv->format());
|
||||
self::assertSame("0012", $intv->format("%4u"));
|
||||
self::assertSame("0012", $intv->format("%04u"));
|
||||
|
||||
$intv->set("12");
|
||||
self::assertSame(12, $intv->get());
|
||||
|
@ -31,8 +31,52 @@ class schemaTest extends TestCase {
|
|||
$intv->set(" 12 ");
|
||||
self::assertSame(12, $intv->get());
|
||||
|
||||
self::assertException(Exception::class, $intvSetter(true));
|
||||
$intv->set(true);
|
||||
self::assertSame(1, $intv->get());
|
||||
|
||||
// valeur non requise donc retourne null
|
||||
$intv->set(false);
|
||||
self::assertNull($intv->get());
|
||||
|
||||
self::assertException(Exception::class, $intvSetter("a"));
|
||||
self::assertException(Exception::class, $intvSetter([]));
|
||||
self::assertException(Exception::class, $intvSetter(["a"]));
|
||||
}
|
||||
|
||||
function testRequiredInt() {
|
||||
/** @var ScalarValue $intv */
|
||||
Schema::nv($intv, $int, null, $schema, [
|
||||
"int", null,
|
||||
"required" => true,
|
||||
]);
|
||||
$intvSetter = function($value) use($intv) {
|
||||
return function() use($intv, $value) {
|
||||
$intv->set($value);
|
||||
};
|
||||
};
|
||||
|
||||
self::assertException(Exception::class, $intvSetter(null));
|
||||
self::assertException(Exception::class, $intvSetter(""));
|
||||
self::assertException(Exception::class, $intvSetter(" "));
|
||||
|
||||
$intv->set(12);
|
||||
self::assertSame(12, $intv->get());
|
||||
self::assertSame(12, $int);
|
||||
self::assertSame("12", $intv->format());
|
||||
self::assertSame("0012", $intv->format("%04u"));
|
||||
|
||||
$intv->set("12");
|
||||
self::assertSame(12, $intv->get());
|
||||
|
||||
$intv->set(" 12 ");
|
||||
self::assertSame(12, $intv->get());
|
||||
|
||||
$intv->set(true);
|
||||
self::assertSame(1, $intv->get());
|
||||
|
||||
// valeur requise donc lance une exception
|
||||
self::assertException(Exception::class, $intvSetter(false));
|
||||
|
||||
self::assertException(Exception::class, $intvSetter("a"));
|
||||
self::assertException(Exception::class, $intvSetter([]));
|
||||
self::assertException(Exception::class, $intvSetter(["a"]));
|
||||
|
@ -66,7 +110,7 @@ class schemaTest extends TestCase {
|
|||
self::assertSame(12, $intv->get());
|
||||
self::assertSame(12, $int);
|
||||
self::assertSame("12", $intv->format());
|
||||
self::assertSame("0012", $intv->format("%4u"));
|
||||
self::assertSame("0012", $intv->format("%04u"));
|
||||
|
||||
$intv->set("12");
|
||||
self::assertSame(12, $int);
|
||||
|
@ -74,8 +118,63 @@ class schemaTest extends TestCase {
|
|||
$intv->set(" 12 ");
|
||||
self::assertSame(12, $int);
|
||||
|
||||
self::assertException(Exception::class, $intvSetter(true));
|
||||
$intv->set(true);
|
||||
self::assertSame(1, $int);
|
||||
|
||||
// valeur non requise donc retourne null
|
||||
$intv->set(false);
|
||||
self::assertNull($intv->get());
|
||||
|
||||
self::assertException(Exception::class, $intvSetter("a"));
|
||||
self::assertException(Exception::class, $intvSetter([]));
|
||||
self::assertException(Exception::class, $intvSetter(["a"]));
|
||||
}
|
||||
|
||||
function testRequiredNint() {
|
||||
/** @var ScalarValue $intv */
|
||||
Schema::nv($intv, $int, null, $schema, [
|
||||
"?int", null,
|
||||
"required" => true,
|
||||
]);
|
||||
$intvSetter = function($value) use($intv) {
|
||||
return function() use($intv, $value) {
|
||||
$intv->set($value);
|
||||
};
|
||||
};
|
||||
|
||||
$intv->set(null);
|
||||
self::assertNull($intv->get());
|
||||
self::assertNull($int);
|
||||
self::assertSame("", $intv->format());
|
||||
|
||||
$intv->set("");
|
||||
self::assertNull($intv->get());
|
||||
self::assertNull($int);
|
||||
self::assertSame("", $intv->format());
|
||||
|
||||
$intv->set(" ");
|
||||
self::assertNull($intv->get());
|
||||
self::assertNull($int);
|
||||
self::assertSame("", $intv->format());
|
||||
|
||||
$intv->set(12);
|
||||
self::assertSame(12, $intv->get());
|
||||
self::assertSame(12, $int);
|
||||
self::assertSame("12", $intv->format());
|
||||
self::assertSame("0012", $intv->format("%04u"));
|
||||
|
||||
$intv->set("12");
|
||||
self::assertSame(12, $int);
|
||||
|
||||
$intv->set(" 12 ");
|
||||
self::assertSame(12, $int);
|
||||
|
||||
$intv->set(true);
|
||||
self::assertSame(1, $int);
|
||||
|
||||
// valeur requise donc lance une exception
|
||||
self::assertException(Exception::class, $intvSetter(false));
|
||||
|
||||
self::assertException(Exception::class, $intvSetter("a"));
|
||||
self::assertException(Exception::class, $intvSetter([]));
|
||||
self::assertException(Exception::class, $intvSetter(["a"]));
|
||||
|
@ -97,7 +196,7 @@ class schemaTest extends TestCase {
|
|||
Schema::nv($isv, $is, null, $iss, "int|string");
|
||||
|
||||
$isv->set("12");
|
||||
self::assertSame(12, $is);
|
||||
self::assertSame("12", $is);
|
||||
$isv->set(12);
|
||||
self::assertSame(12, $is);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue