diff --git a/src/php/time/Time.php b/src/php/time/Time.php index 115c152..dae044f 100644 --- a/src/php/time/Time.php +++ b/src/php/time/Time.php @@ -31,8 +31,13 @@ class Time { else return new static($time); } - static function ensure(&$time): void { - $time = static::withn($time); + static function isa_time($time): bool { + if ($time === null) return false; + if ($time instanceof Time) return true; + if (is_int($time)) return true; + if (is_string($time)) return preg_match(self::PATTERN, $time); + #XXX supporter tous les formats + return false; } static function seconds_now(): int { diff --git a/src/php/types/vdate.php b/src/php/types/vdate.php index 85b1d43..3f102f7 100644 --- a/src/php/types/vdate.php +++ b/src/php/types/vdate.php @@ -4,6 +4,11 @@ namespace nulib\php\types; use nulib\php\time\Date; class vdate { + static function isa($value, bool $strict=false) : bool { + if ($strict) return $value instanceof Date; + else return Date::isa_date($value); + } + static function ensure(&$date): void { $date = Date::with($date); } diff --git a/src/php/types/vdatetime.php b/src/php/types/vdatetime.php index 2f0ecc0..7304438 100644 --- a/src/php/types/vdatetime.php +++ b/src/php/types/vdatetime.php @@ -4,6 +4,11 @@ namespace nulib\php\types; use nulib\php\time\DateTime; class vdatetime { + static function isa($value, bool $strict=false) : bool { + if ($strict) return $value instanceof DateTime; + else return DateTime::isa_datetime($value); + } + static function ensure(&$datetime): void { $datetime = DateTime::with($datetime); } diff --git a/src/php/types/vmixed.php b/src/php/types/vmixed.php index 71630f8..ec02597 100644 --- a/src/php/types/vmixed.php +++ b/src/php/types/vmixed.php @@ -2,6 +2,10 @@ namespace nulib\php\types; class vmixed { + static function isa($value, bool $strict=false) : bool { + return true; + } + static function ensure(&$mixed): void { } diff --git a/src/php/types/vraw.php b/src/php/types/vraw.php index a63d4c1..ef3ee0a 100644 --- a/src/php/types/vraw.php +++ b/src/php/types/vraw.php @@ -2,6 +2,10 @@ namespace nulib\php\types; class vraw { + static function isa($value, bool $strict=false) : bool { + return true; + } + static function ensure(&$raw): void { } diff --git a/src/php/types/vschema.php b/src/php/types/vschema.php index 9d5c024..c32a25a 100644 --- a/src/php/types/vschema.php +++ b/src/php/types/vschema.php @@ -1,6 +1,9 @@ vrawstring::class, "string" => vstring::class, "text" => vtext::class, @@ -27,9 +30,62 @@ class vschema { "time" => vtime::class, ]; - /** indiquer si $value est conforme au schéma */ - static function check($value, array $schema): bool { + private static function get_types($schema): array { + if (is_array($schema)) { + $types = $schema["type"] ?? $schema[0] ?? null; + } elseif (is_string($schema)) { + $types = $schema; + } else { + throw exceptions::invalid_value($schema, "schema"); + } + if (is_string($types)) { + $types = explode(",", $types); + } elseif (!is_array($types)) { + throw exceptions::invalid_value($types, "types"); + } + return $types; + } + private static function get_vclass(array $types, ?bool &$nullable): ?string { + foreach ($types as $type) { + $vclass = self::VCLASSES[$type] ?? null; + if ($vclass !== null) { + $nullable = str::del_prefix($type, "?"); + return $vclass; + } + } + return null; + } + + /** indiquer si $value est conforme au schéma */ + static function check_scalar($value, $schema, bool $strict=false): bool { + $types = self::get_types($schema); + $vclass = self::get_vclass($types, $nullable); + # ce doit être un type supporté + if ($vclass === null) return false; + if ($value === null) return $nullable; + return $vclass::isa($value, $strict); + } + + static function ensure_scalar(&$value, $schema): bool { + $types = self::get_types($schema); + $vclass = self::get_vclass($types, $nullable); + # ce doit être un type supporté + if ($vclass === null) return false; + if ($nullable) $value = $vclass::withn($value); + else $value = $vclass::with($value); + return true; + } + + /** indiquer si $value est conforme au schéma */ + static function check_assoc(?array $array, array $schema): bool { + foreach ($schema as $key => $kschema) { + $required = vbool::with($kschema["required"] ?? false); + $exists = array_key_exists($key, $array); + if (!$exists && $required) return false; + if (!self::check_scalar($array[$key], $kschema)) return false; + } + return true; } /** @@ -37,7 +93,7 @@ class vschema { * - les clés ne sont pas créées si elles n'existent pas * */ - static function ensure(&$value, array $schema): void { + static function ensure_assoc(&$value, array $schema): void { } } diff --git a/src/php/types/vtime.php b/src/php/types/vtime.php index 1c0f9c6..a96dbe8 100644 --- a/src/php/types/vtime.php +++ b/src/php/types/vtime.php @@ -1,9 +1,15 @@