public function update()
{
if ($this->changed()) {
foreach ($this->_fields as $name => $field) {
if ($field instanceof Sprig_Field_Timestamp and $field->auto_now_update) {
// Set the value to the current timestamp
$this->{$name} = time();
}
}
// Check the updated data
$data = $this->check($this->changed());
$values = $relations = array();
foreach ($data as $name => $value) {
$field = $this->_fields[$name];
if (!$field->in_db) {
if ($field instanceof Sprig_Field_ManyToMany) {
// Relationships have been changed
$relations[$name] = $value;
}
// Skip all fields that are not in the database
continue;
}
// Change the field name to the column name
$values[$field->column] = $field->_database_wrap($value);
}
if ($values) {
$query = DB::update($this->_table)->set($values);
if (is_array($this->_primary_key)) {
foreach ($this->_primary_key as $field) {
$query->where($this->_fields[$field]->column, '=', $this->_fields[$field]->_database_wrap($this->_original[$field]));
}
} else {
$query->where($this->_fields[$this->_primary_key]->column, '=', $this->_fields[$this->_primary_key]->_database_wrap($this->_original[$this->_primary_key]));
}
$query->execute($this->_db);
}
if ($relations) {
foreach ($relations as $name => $value) {
$field = $this->_fields[$name];
$model = Sprig::factory($field->model);
if (isset($field->left_foreign_key) and $field->left_foreign_key) {
$left_fk = $field->left_foreign_key;
} else {
$left_fk = $this->fk();
}
if (isset($field->right_foreign_key) and $field->right_foreign_key) {
$right_fk = $field->right_foreign_key;
} else {
$right_fk = $model->fk();
}
// Find old relationships that must be deleted
if ($old = array_diff($this->_original[$name], $value)) {
// TODO this needs testing
$old = array_map(array($this->_fields[$this->_primary_key], '_database_wrap'), $old);
DB::delete($field->through)->where($left_fk, '=', $this->_fields[$this->_primary_key]->_database_wrap($this->{$this->_primary_key}))->where($right_fk, 'IN', $old)->execute($this->_db);
}
// Find new relationships that must be inserted
if ($new = array_diff($value, $this->_original[$name])) {
foreach ($new as $id) {
DB::insert($field->through, array($left_fk, $right_fk))->values(array($this->_fields[$this->_primary_key]->_database_wrap($this->{$this->_primary_key}), $model->field($model->pk())->_database_wrap($id)))->execute($this->_db);
}
}
}
}
// Reset the original data for this record
$this->_original = $this->as_array();
// Everything has been updated
$this->_changed = array();
}
return $this;
}