public function isValid(&$value)
{
if ($value === null && $this->isNullable) {
return true;
}
if ($this->enum) {
return in_array($value, $this->enum, true);
}
foreach ($this->types as $type => $_) {
$type = strtolower($type);
if ($type === 'datetime') {
if ($value instanceof \DateTime) {
return true;
} elseif ($value instanceof \DateTimeImmutable) {
$value = new \DateTime($value->format('c'));
return true;
} elseif (is_string($value) && $value !== '') {
$value = new \DateTime($value);
$value->setTimezone(new DateTimeZone(date_default_timezone_get()));
return true;
} elseif (ctype_digit($value)) {
$value = new \DateTime("@{$value}");
return true;
}
} elseif ($type === 'datetimeimmutable') {
if ($value instanceof \DateTimeImmutable) {
return true;
} elseif ($value instanceof \DateTime) {
$value = new \DateTimeImmutable($value->format('c'));
return true;
} elseif (is_string($value) && $value !== '') {
$tmp = new \DateTimeImmutable($value);
$value = $tmp->setTimezone(new DateTimeZone(date_default_timezone_get()));
return true;
} elseif (ctype_digit($value)) {
$value = new \DateTimeImmutable("@{$value}");
return true;
}
} elseif ($type === 'string') {
if (is_string($value)) {
return true;
}
if (is_int($value) || is_object($value) && method_exists($value, '__toString')) {
$value = (string) $value;
return true;
}
} elseif ($type === 'float') {
if (is_float($value)) {
return true;
}
if (is_numeric($value)) {
settype($value, 'float');
return true;
} elseif (is_string($value)) {
$value = (double) str_replace([' ', ','], ['', '.'], $value);
return true;
}
} elseif ($type === 'int') {
if (is_int($value)) {
return true;
}
if (is_numeric($value)) {
settype($value, 'int');
return true;
} elseif (is_string($value)) {
$value = (int) str_replace([' ', ','], ['', '.'], $value);
return true;
}
} elseif ($type === 'bool') {
if (is_bool($value)) {
return true;
}
if (in_array($value, [0, 0.0, '0', 1, 1.0, '1'], true)) {
$value = (bool) $value;
return true;
}
} elseif ($type === 'array') {
if (is_array($value)) {
return true;
}
} elseif ($type === 'object') {
if (is_object($value)) {
return true;
}
} elseif ($type === 'scalar') {
if (is_scalar($value)) {
return true;
}
} elseif ($type === 'mixed') {
return true;
} else {
if ($value instanceof $type) {
return true;
}
}
}
return false;
}