public function normalize($value)
{
if (!$this->owner->strict_types) {
return $value;
}
if ($value === null) {
return;
}
$f = $this;
// only string type fields can use empty string as legit value, for all
// other field types empty value is the same as no-value, nothing or null
if ($f->type && $f->type != 'string' && $value === '') {
return;
}
switch ($f->type) {
case 'string':
if (!is_scalar($value)) {
throw new Exception('Field value must be a string');
}
$value = trim($value);
break;
case 'integer':
if (!is_numeric($value)) {
throw new Exception('Field value must be an integer');
}
$value = (int) $value;
break;
case 'float':
if (!is_numeric($value)) {
throw new Exception('Field value must be a float');
}
$value = (double) $value;
break;
case 'money':
if (!is_numeric($value)) {
throw new Exception('Field value must be numeric');
}
$value = round($value, 4);
break;
case 'boolean':
if (is_bool($value)) {
break;
}
if (isset($f->enum) && is_array($f->enum)) {
if (isset($f->enum[0]) && $value === $f->enum[0]) {
$value = false;
} elseif (isset($f->enum[1]) && $value === $f->enum[1]) {
$value = true;
}
} elseif (is_numeric($value)) {
$value = (bool) $value;
}
if (!is_bool($value)) {
throw new Exception('Field value must be a boolean');
}
break;
case 'date':
case 'datetime':
case 'time':
$class = isset($f->dateTimeClass) ? $f->dateTimeClass : 'DateTime';
if (is_numeric($value)) {
$value = new $class('@' . $value);
} elseif (is_string($value)) {
$value = new $class($value);
} elseif (!$value instanceof $class) {
throw new Exception(['Field value must be a ' . $f->type, 'class' => $class, 'value class' => get_class($value)]);
}
break;
case 'array':
if (!is_array($value)) {
throw new Exception('Field value must be a array');
}
break;
case 'object':
if (!is_object($value)) {
throw new Exception('Field value must be a object');
}
break;
case 'int':
case 'str':
case 'bool':
throw new Exception(['Use of obsolete field type abbreviation. Use "integer", "string", "boolean" etc.', 'type' => $f->type]);
break;
}
return $value;
}