145 lines
4.6 KiB
PHP
145 lines
4.6 KiB
PHP
<?php
|
|
namespace nur\sery\wip\schema\_assoc;
|
|
|
|
use nulib\ValueException;
|
|
use nur\sery\wip\schema\_scalar\ScalarResult;
|
|
use nur\sery\wip\schema\input\Input;
|
|
use nur\sery\wip\schema\Result;
|
|
use nur\sery\wip\schema\types\IType;
|
|
use nur\sery\wip\schema\Wrapper;
|
|
use nur\sery\wip\schema\WrapperContext;
|
|
|
|
class AssocWrapper extends Wrapper {
|
|
function __construct(AssocSchema $schema, &$value=null, $valueKey=null, ?array $params=null) {
|
|
$keys = $schema->getKeys();
|
|
$keyTypes = [];
|
|
$keyWrappers = [];
|
|
foreach ($keys as $key) {
|
|
$keyTypes[$key] = null;
|
|
$keyWrappers[$key] = $schema->getSchema($key)->getWrapper();
|
|
}
|
|
$this->context = $context = new AssocWrapperContext($schema, null, null, $params);
|
|
$context->arrayResult = new ScalarResult();
|
|
$context->keys = $keys;
|
|
$context->keyTypes = $keyTypes;
|
|
$context->keyWrappers = $keyWrappers;
|
|
$context->result = $context->arrayResult;
|
|
|
|
# calculer manuellemet throw ici parce que WrapperContext le met à true par
|
|
# défaut. on veut pouvoir mettre temporairement throw à false si jamais il
|
|
# n'est pas spécifié par l'utilisateur
|
|
$throw = $params["throw"] ?? null;
|
|
# Si $value est null, ne pas lancer d'exception, parce qu'on considère que
|
|
# c'est une initialisation sans conséquences
|
|
if ($throw === null && $value !== null) $throw = true;
|
|
$context->throw = $throw ?? false;
|
|
$this->reset($value, $valueKey);
|
|
$context->throw = $throw ?? true;
|
|
}
|
|
|
|
function isAssoc(?AssocWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
|
|
|
|
/** @var AssocWrapperContext */
|
|
protected WrapperContext $context;
|
|
|
|
protected function resetContext($resetSelectedKey): void {
|
|
$context = $this->context;
|
|
$context->arrayResult->reset();
|
|
foreach ($context->keyWrappers as $wrapper) {
|
|
$wrapper->getResult()->reset();
|
|
}
|
|
$context->analyzed = false;
|
|
$context->normalized = false;
|
|
if ($resetSelectedKey) {
|
|
$context->selectedKey = null;
|
|
$context->type = $context->arrayType;
|
|
$context->result = $context->arrayResult;
|
|
}
|
|
}
|
|
|
|
function getKeys(): array {
|
|
return $this->context->keys;
|
|
}
|
|
|
|
protected function _getWrapper($key): Wrapper {
|
|
$wrapper = $context->keyWrappers[$key] ?? null;
|
|
if ($wrapper === null) throw ValueException::invalid_key($key);
|
|
return $wrapper;
|
|
}
|
|
|
|
/** @param string|int|null $key */
|
|
function select($key=null): Wrapper {
|
|
$context = $this->context;
|
|
if ($key === null) {
|
|
$context->selectedKey = null;
|
|
$context->type = $context->arrayType;
|
|
$context->result = $context->arrayResult;
|
|
return $this;
|
|
}
|
|
$wrapper = $this->_getWrapper($key);
|
|
$context->selectedKey = $key;
|
|
$context->type = $wrapper->getType();
|
|
$context->result = $wrapper->getResult();
|
|
return $wrapper;
|
|
}
|
|
|
|
protected function _analyze(?array $params): int {
|
|
return -1;
|
|
}
|
|
|
|
protected function _normalize(?array $params): bool {
|
|
return false;
|
|
}
|
|
|
|
function getResult($key=false): Result {
|
|
if ($key === false) return $this->context->result;
|
|
elseif ($key === null) return $this->context->arrayResult;
|
|
else return $this->_getWrapper($key)->getResult();
|
|
}
|
|
|
|
function getType($key=false): IType {
|
|
if ($key === false) return $this->context->type;
|
|
elseif ($key === null) return $this->context->arrayType;
|
|
else return $this->_getWrapper($key)->getType();
|
|
}
|
|
|
|
function get($default=null, $key=false) {
|
|
$context = $this->context;
|
|
if (!$context->arrayResult->available) return $default;
|
|
if ($key === false) $key = $context->selectedKey;
|
|
if ($key === null) return $context->input->get($context->valueKey);
|
|
else return $this->_getWrapper($key)->get($default);
|
|
}
|
|
|
|
function set($value, ?array $params=null, $key=false): Wrapper {
|
|
$context = $this->context;
|
|
if ($key === false) $key = $context->selectedKey;
|
|
if ($key === null) {
|
|
$context->input->set($value, $context->valueKey);
|
|
$this->afterModify($params);
|
|
} else {
|
|
$this->_getWrapper($key)->set($value);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
function unset(?array $params=null, $key=false): Wrapper {
|
|
$context = $this->context;
|
|
if ($key === false) $key = $context->selectedKey;
|
|
if ($key === null) {
|
|
$context->input->unset($context->valueKey);
|
|
$this->afterModify($params);
|
|
} else {
|
|
$this->_getWrapper($key)->unset();
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
function format($format=null, $key=false): string {
|
|
$context = $this->context;
|
|
if ($key === false) $key = $context->selectedKey;
|
|
if ($key === null) return $this->_format($context, $format);
|
|
else return $this->_getWrapper($key)->format($format);
|
|
}
|
|
}
|