2023-11-09 10:03:35 +04:00
|
|
|
<?php
|
2023-11-28 00:20:42 +04:00
|
|
|
namespace nur\sery\schema\_scalar;
|
2023-11-09 10:03:35 +04:00
|
|
|
|
2023-12-28 12:33:17 +04:00
|
|
|
use nulib\ValueException;
|
2023-11-27 22:39:35 +04:00
|
|
|
use nur\sery\schema\input\Input;
|
2023-12-28 19:33:13 +04:00
|
|
|
use nur\sery\schema\ref\ref_analyze;
|
2023-11-27 22:39:35 +04:00
|
|
|
use nur\sery\schema\Result;
|
2023-12-28 19:33:13 +04:00
|
|
|
use nur\sery\schema\types;
|
2023-11-09 10:03:35 +04:00
|
|
|
use nur\sery\schema\types\IType;
|
2023-11-27 22:39:35 +04:00
|
|
|
use nur\sery\schema\Value;
|
2023-11-09 10:03:35 +04:00
|
|
|
|
2023-11-27 22:39:35 +04:00
|
|
|
class ScalarValue extends Value {
|
2023-12-28 19:44:57 +04:00
|
|
|
function __construct(ScalarSchema $schema, &$dest=null, $destKey=null, bool $defaultVerifix=true, bool $defaultThrow=true) {
|
2023-11-27 22:39:35 +04:00
|
|
|
$this->schema = $schema;
|
2023-12-28 19:33:13 +04:00
|
|
|
$this->defaultVerifix = $defaultVerifix;
|
2023-12-28 19:44:57 +04:00
|
|
|
$this->defaultThrow = $defaultThrow;
|
2023-11-28 08:20:33 +04:00
|
|
|
$this->result = new ScalarResult();
|
2023-12-28 19:33:13 +04:00
|
|
|
$this->reset($dest, $destKey);
|
2023-11-27 22:39:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }
|
2023-11-09 10:03:35 +04:00
|
|
|
|
2023-11-25 10:04:24 +04:00
|
|
|
/** @var ScalarSchema schéma de cette valeur */
|
|
|
|
protected $schema;
|
|
|
|
|
2023-11-27 22:39:35 +04:00
|
|
|
/** @var Input source et destination de la valeur */
|
|
|
|
protected $input;
|
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
/** @var string|int|null clé de la valeur dans le tableau destination */
|
2023-11-28 00:20:42 +04:00
|
|
|
protected $destKey;
|
2023-11-27 22:39:35 +04:00
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
/** @var bool */
|
|
|
|
protected $defaultVerifix;
|
|
|
|
|
2023-12-28 19:44:57 +04:00
|
|
|
/** @var bool */
|
|
|
|
protected $defaultThrow;
|
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
/** @var IType type de la valeur après analyse */
|
2023-11-28 08:20:33 +04:00
|
|
|
protected $type;
|
|
|
|
|
|
|
|
/** @var ?ScalarResult résultat de l'analyse de la valeur */
|
2023-11-25 10:04:24 +04:00
|
|
|
protected $result;
|
2023-11-09 10:34:36 +04:00
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
function reset(&$dest, $destKey=null, ?bool $verifix=null): Value {
|
2023-11-27 22:39:35 +04:00
|
|
|
if ($dest instanceof Input) $input = $dest;
|
|
|
|
else $input = new Input($dest);
|
|
|
|
$this->input = $input;
|
2023-11-28 00:20:42 +04:00
|
|
|
$this->destKey = $destKey;
|
2023-12-28 19:33:13 +04:00
|
|
|
$this->type = null;
|
|
|
|
$this->_analyze();
|
2023-12-28 19:44:57 +04:00
|
|
|
if ($verifix == null) $verifix = $this->defaultVerifix;
|
2023-11-27 22:39:35 +04:00
|
|
|
if ($verifix) $this->verifix();
|
|
|
|
return $this;
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
|
2023-11-28 08:20:33 +04:00
|
|
|
function getKeys(): array {
|
|
|
|
return [null];
|
|
|
|
}
|
|
|
|
|
|
|
|
function getValue($key=null): Value {
|
|
|
|
if ($key === null) return $this;
|
|
|
|
throw ValueException::invalid_key($key);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** analyser la valeur et résoudre son type */
|
|
|
|
function _analyze(): int {
|
|
|
|
$schema = $this->schema;
|
|
|
|
$input = $this->input;
|
|
|
|
$destKey = $this->destKey;
|
|
|
|
$result = $this->result;
|
|
|
|
$result->reset();
|
2023-12-28 19:33:13 +04:00
|
|
|
if (!$input->isPresent($destKey)) return $result->setMissing($schema);
|
|
|
|
$haveType = false;
|
|
|
|
$firstType = null;
|
|
|
|
foreach ($schema->type as $name) {
|
|
|
|
$type = types::get($name);
|
|
|
|
if ($firstType === null) $firstType = $type;
|
|
|
|
if ($type->canAnalyze($input, $destKey)) {
|
|
|
|
$haveType = true;
|
|
|
|
$this->type = $type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$haveType) $type = $this->type = $firstType;
|
|
|
|
if (!$type->isAvailable($input, $destKey)) return $result->setUnavailable($schema);
|
2023-11-28 08:53:40 +04:00
|
|
|
$value = $input->get($destKey);
|
2023-12-28 19:33:13 +04:00
|
|
|
if ($type->isNull($value)) return $result->setNull($schema);
|
|
|
|
if ($type->isValid($value, $normalized)) {
|
|
|
|
if ($normalized) return $result->setNormalized();
|
|
|
|
else return $result->setValid();
|
|
|
|
}
|
|
|
|
if (is_string($value)) return ref_analyze::STRING;
|
2023-12-28 21:00:41 +04:00
|
|
|
else return $result->setInvalid($schema, $schema);
|
2023-11-28 08:20:33 +04:00
|
|
|
}
|
|
|
|
|
2023-12-28 19:44:57 +04:00
|
|
|
function verifix(?bool $throw=null): bool {
|
2023-12-28 19:33:13 +04:00
|
|
|
$type = $this->getType();
|
|
|
|
$destKey = $this->destKey;
|
|
|
|
$value = $this->input->get($destKey);
|
2023-12-28 21:00:41 +04:00
|
|
|
$modified = $type->verifix($value, $this->result, $this->schema);
|
2023-12-28 19:44:57 +04:00
|
|
|
if ($throw === null) $throw = $this->defaultThrow;
|
2023-12-28 19:33:13 +04:00
|
|
|
if ($this->result->valid) $this->input->set($value, $destKey);
|
|
|
|
else $this->result->throw($throw);
|
|
|
|
return $modified;
|
2023-11-27 22:39:35 +04:00
|
|
|
}
|
2023-11-09 10:03:35 +04:00
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
function getResult(): Result {
|
|
|
|
return $this->result;
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
function isPresent(): bool {
|
|
|
|
return $this->result->present;
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
|
2023-11-27 22:39:35 +04:00
|
|
|
function getType(): IType {
|
2023-11-09 10:03:35 +04:00
|
|
|
return $this->type;
|
|
|
|
}
|
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
function isAvailable(): bool {
|
|
|
|
return $this->result->available;
|
|
|
|
}
|
|
|
|
|
2023-12-03 22:44:29 +04:00
|
|
|
function isValid(): bool {
|
2023-12-28 19:33:13 +04:00
|
|
|
return $this->result->valid;
|
2023-11-27 22:39:35 +04:00
|
|
|
}
|
|
|
|
|
2023-12-03 22:44:29 +04:00
|
|
|
function isNormalized(): bool {
|
2023-12-28 19:33:13 +04:00
|
|
|
return $this->result->normalized;
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
function get($default=null) {
|
|
|
|
if ($this->result->available) return $this->input->get($this->destKey);
|
|
|
|
else return $default;
|
|
|
|
}
|
|
|
|
|
|
|
|
function set($value, ?bool $verifix=null): Value {
|
|
|
|
$this->input->set($value, $this->destKey);
|
|
|
|
$this->_analyze();
|
|
|
|
if ($verifix === null) $verifix = $this->defaultVerifix;
|
|
|
|
if ($verifix) $this->verifix();
|
|
|
|
return $this;
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
|
2023-12-28 19:44:57 +04:00
|
|
|
function unset(?bool $verifix=null): Value {
|
2023-12-28 19:33:13 +04:00
|
|
|
$this->input->unset($this->destKey);
|
|
|
|
$this->_analyze();
|
|
|
|
if ($verifix === null) $verifix = $this->defaultVerifix;
|
|
|
|
if ($verifix) $this->verifix();
|
2023-12-28 19:44:57 +04:00
|
|
|
return $this;
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
|
2023-12-28 19:33:13 +04:00
|
|
|
function format($format=null): string {
|
|
|
|
return $this->getType()->format($this->input->get($this->destKey), $format);
|
2023-11-09 10:03:35 +04:00
|
|
|
}
|
|
|
|
}
|