result = new ScalarResult(); $this->context = $context; if ($value !== null) { # n'initialiser que si $value n'est pas null $this->reset($value, $valueKey); } else { # il faut au moins que le type soit disponible $this->resetContext(false); } } protected WrapperContext $context; function getKeys(): array { return ScalarSchema::KEYS; } /** @param string|int|null $key */ function select($key): ScalarWrapper { if ($key !== null) throw ValueException::invalid_key($key); return $this; } /** analyser la valeur et résoudre son type */ protected static function _analyze0(WrapperContext $context): int { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; $valueKey = $context->valueKey; /** @var ScalarResult $result */ $result = $context->result; $default = $schema->default; if (!$input->isPresent($valueKey)) { if ($default !== null) { $input->set($default, $valueKey); return $result->setNormalized(); } else { return $result->setMissing($schema); } } $schemaTypes = $schema->type; if ($schemaTypes instanceof IType) { $type = $schemaTypes; } else { # type union $haveType = false; $types = []; $type = $firstType = null; $value = null; # d'abord chercher un type pour lequel c'est une valeur normalisée $index = 0; $haveValue = false; foreach ($schemaTypes as $key => $name) { if ($key === $index) { $index++; $args = null; } else { $args = $name; $name = $key; } $type = types::get($schema->nullable, $name, $args, $schema->getDefinition()); if ($firstType === null) $firstType = $type; $types[] = $type; if ($type->isAvailable($input, $valueKey)) { if (!$haveValue) { $value = $input->get($valueKey); $haveValue = true; } if ($type->isValid($value, $normalized) && $normalized) { $haveType = true; break; } } } # ensuite chercher un type pour lequel la valeur est valide if (!$haveType) { foreach ($types as $type) { if ($type->isAvailable($input, $valueKey) && $type->isValid($value)) { $haveType = true; break; } } } # sinon prendre le premier type if (!$haveType) { $type = $firstType; } } $context->type = $type; if (!$type->isAvailable($input, $valueKey)) { if ($default !== null) { $input->set($default, $valueKey); return $result->setNormalized(); } else { return $result->setUnavailable($schema); } } $value = $input->get($valueKey); $missing = $type->getMissingValue($haveMissing); if ($haveMissing && $value === $missing) { if ($default !== null) { $input->set($default, $valueKey); return $result->setNormalized(); } else { return $result->setMissing($schema); } } $context->origValue = $context->value = $value; if ($type->isNull($value)) { return $result->setNull($schema); } elseif (is_string($value)) { return ref_analyze::STRING; } elseif ($type->isValid($value, $normalized)) { if ($normalized) return $result->setNormalized(); else return $result->setValid(); } else { return $result->setInvalid($value, $schema); } } /** * @param ScalarWrapper $wrapper */ static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; $valueKey = $context->valueKey; /** @var ScalarResult $result */ $result = $context->result; /** @var func $analyzerFunc */ $analyzerFunc = $schema->analyzerFunc; if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context, $wrapper]); else $what = self::_analyze0($context); if ($what !== ref_analyze::STRING) return $what; $value = $context->value; try { /** @var func $extractorFunc */ $extractorFunc = $schema->extractorFunc; if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context, $wrapper]); else $extracted = $context->type->extract($value); $context->value = $extracted; } catch (ValueException $e) { return $result->setInvalid($context->origValue, $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, $wrapper]); else $parsed = $context->type->parse($extracted); $context->value = $parsed; } catch (ValueException $e) { return $result->setInvalid($context->origValue, $schema, $e); } $normalized = $parsed === $context->origValue; if ($normalized) { $input->set($parsed, $valueKey); return $result->setNormalized(); } else { $input->set($extracted, $valueKey); return $result->setValid($parsed); } } /** * @param ScalarWrapper $wrapper */ static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; $valueKey = $context->valueKey; /** @var ScalarResult $result */ $result = $context->result; $normalize = false; $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 $input->set(null, $valueKey); } elseif ($result->valid && !$result->normalized) { $normalizedValue = $result->normalizedValue; if ($normalizedValue !== null) { # la valeur normalisée est disponible $input->set($normalizedValue, $valueKey); $result->normalizedValue = null; $modified = true; } else { # normaliser la valeur $normalize = true; } } } else { $normalize = true; } if ($normalize) { $value = $input->get($valueKey); /** @var func $normalizerFunc */ $normalizerFunc = $schema->normalizerFunc; if ($normalizerFunc !== null) { $orig = $value; $value = $normalizerFunc->invoke([$orig, $context, $wrapper]); $modified = $value !== $orig; } else { $modified = $context->type->normalize($value, $result, $schema); } if ($result->valid) $input->set($value, $valueKey); } return $modified; } }