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); } }