0, "default" => 1, "title" => 2, "required" => 3, "nullable" => 4, "desc" => 5, "analyzer_func" => 6, "extractor_func" => 7, "parser_func" => 8, "normalizer_func" => 9, "messages" => 10, "formatter_func" => 11, "format" => 12, "" => 13, "name" => 14, ]; /** * indiquer si $definition est une définition de schéma scalaire que * {@link normalize()} pourrait normaliser */ static function isa_definition($definition): bool { # chaine ou null if ($definition === null) return true; if (is_string($definition)) return true; if (!is_array($definition)) return false; # nature explicitement spécifiée if (array_key_exists("", $definition)) { $nature = $definition[""]; if ($nature === "scalar") return true; if (is_array($nature) && array_key_exists(0, $nature) && $nature[0] === "scalar") { return true; } return false; } # un unique élément chaine à l'index 0 $count = count($definition); $haveIndex0 = array_key_exists(0, $definition); if ($count == 1 && $haveIndex0 && ($definition[0] === null || is_string($definition[0]))) { return true; } # un élément à l'index 0, et d'autres éléments return $haveIndex0 && $count > 1; } static function normalize($definition): array { if (!is_array($definition)) $definition = [$definition]; # s'assurer que toutes les clés existent avec leur valeur par défaut $index = 0; foreach (self::METASCHEMA_KEYS as $key) { if (!array_key_exists($key, $definition)) { if (array_key_exists($index, $definition)) { $definition[$key] = $definition[$index]; unset($definition[$index]); $index++; } else { $definition[$key] = self::METASCHEMA[$key][1]; } } } # réordonner les clés numériques if (cl::have_num_keys($definition)) { $keys = array_keys($definition); $index = 0; foreach ($keys as $key) { if (!is_int($key)) continue; $definition[$index] = $definition[$key]; unset($definition[$key]); $index++; } } # type $types = []; $deftype = $definition["type"]; $nullable = $definition["nullable"]; if ($deftype === null) { $types[] = null; $nullable = true; } else { if (!is_array($deftype)) { if (!is_string($deftype)) throw SchemaException::invalid_type($deftype); $deftype = explode("|", $deftype); } foreach ($deftype as $type) { if ($type === null || $type === "null") { $nullable = true; continue; } if (!is_string($type)) throw SchemaException::invalid_type($type); if (substr($type, 0, 1) == "?") { $type = substr($type, 1); $nullable = true; } if ($type === "") throw SchemaException::invalid_type($type); $type = cl::get(ref_types::ALIASES, $type, $type); $types = array_merge($types, explode("|", $type)); } if (!$types) throw SchemaException::invalid_schema("scalar: type is required"); $types = array_keys(array_fill_keys($types, true)); } $definition["type"] = $types; $definition["nullable"] = $nullable; # nature $nature = $definition[""]; self::ensure_array($nature); if (!array_key_exists(0, $nature) || $nature[0] !== "scalar") { throw SchemaException::invalid_schema("expected scalar nature"); } $definition[""] = $nature; # autres éléments self::ensure_nstring($definition["title"]); self::ensure_bool($definition["required"]); self::ensure_bool($definition["nullable"]); self::ensure_ncontent($definition["desc"]); self::ensure_ncallable($definition["analyzer_func"]); self::ensure_ncallable($definition["extractor_func"]); self::ensure_ncallable($definition["parser_func"]); self::ensure_ncallable($definition["normalizer_func"]); self::ensure_narray($definition["messages"]); self::ensure_ncallable($definition["formatter_func"]); self::ensure_nkey($definition["name"]); return $definition; } function __construct($definition=null, bool $normalize=true) { if ($definition === null) $definition = static::SCHEMA; if ($normalize) $definition = self::normalize($definition); $this->definition = $definition; } function isScalar(): bool { return true; } }