public function save($data = []) { if (!$this->persistence) { throw new Exception(['Model is not associated with any database']); } if ($data) { $this->set($data); } return $this->atomic(function () { if ($this->hook('beforeSave') === false) { return $this; } $is_update = $this->loaded(); if ($is_update) { $data = []; $dirty_join = false; foreach ($this->dirty as $name => $junk) { $field = $this->hasElement($name); if (!$field || $field->read_only || $field->never_persist || $field->never_save) { continue; } // get the value of the field $value = $this->get($name); if (isset($field->join)) { $dirty_join = true; // storing into a different table join $field->join->set($name, $value); } else { $data[$name] = $value; } } // No save needed, nothing was changed if (!$data && !$dirty_join) { return $this; } if ($this->hook('beforeUpdate', [&$data]) === false) { return $this; } $this->persistence->update($this, $this->id, $data); $this->hook('afterUpdate', [&$data]); } else { $data = []; foreach ($this->get() as $name => $value) { $field = $this->hasElement($name); if (!$field || $field->read_only || $field->never_persist || $field->never_save) { continue; } if (isset($field->join)) { // storing into a different table join $field->join->set($name, $value); } else { $data[$name] = $value; } } if ($this->hook('beforeInsert', [&$data]) === false) { return $this; } // Collect all data of a new record $this->id = $this->persistence->insert($this, $data); $this->hook('afterInsert', [$this->id]); if ($this->reload_after_save !== false) { $d = $this->dirty; $this->dirty = []; $this->reload(); $this->_dirty_after_reload = $this->dirty; $this->dirty = $d; } } $this->hook('afterSave'); if ($this->loaded()) { $this->dirty = $this->_dirty_after_reload; } return $this; }); }