public function set($field, $value = null)
{
if (func_num_args() == 1) {
if (is_array($field)) {
foreach ($field as $key => $value) {
if ($key === '0' || $key === 0) {
$this->set($value);
} else {
$this->set($key, $value);
}
}
return $this;
} else {
$value = $field;
$field = $this->title_field;
}
}
$field = $this->normalizeFieldName($field);
$f = $this->hasElement($field);
try {
if ($f && $this->hook('normalize', [$f, $value]) !== false) {
$value = $f->normalize($value);
}
} catch (Exception $e) {
$e->addMoreInfo('field', $field);
$e->addMoreInfo('value', $value);
$e->addMoreInfo('f', $f);
throw $e;
}
$default_value = $f ? $f->default : null;
$original_value = array_key_exists($field, $this->dirty) ? $this->dirty[$field] : (isset($f) && isset($f->default) ? $f->default : null);
$current_value = array_key_exists($field, $this->data) ? $this->data[$field] : $original_value;
if (gettype($value) == gettype($current_value) && $value == $current_value) {
// do nothing, value unchanged
return $this;
}
if ($f) {
// perform bunch of standard validation here. This can be re-factored in the future.
if ($f->read_only) {
throw new Exception(['Attempting to change read-only field', 'field' => $field, 'model' => $this]);
}
if ($f->enum && $f->type != 'boolean') {
if ($value === '') {
$value = null;
}
if (!in_array($value, $f->enum, true) && $value !== null) {
throw new Exception(['This is not one of the allowed values for the field', 'field' => $field, 'model' => $this, 'value' => $value, 'enum' => $f->enum]);
}
}
}
if (array_key_exists($field, $this->dirty) && (gettype($this->dirty[$field]) == gettype($value) && $this->dirty[$field] == $value)) {
unset($this->dirty[$field]);
} elseif (!array_key_exists($field, $this->dirty)) {
$this->dirty[$field] = array_key_exists($field, $this->data) ? $this->data[$field] : $default_value;
}
$this->data[$field] = $value;
return $this;
}