/** * This function saves the record matching using the primary key. * * @access public * @override * @param boolean $reload whether the model should be reloaded * after the save is done * @param boolean $mode TRUE=save, FALSE=update, NULL=automatic * @throws Throwable_Marshalling_Exception indicates that model could not be saved */ public function save($reload = FALSE, $mode = NULL) { if (!static::is_savable()) { throw new Throwable_Marshalling_Exception('Message: Failed to save record to database. Reason: Model is not savable.', array(':class' => get_called_class())); } $columns = array_keys($this->fields); if (!empty($columns)) { $builder = DB_SQL::update(static::data_source(DB_DataSource::MASTER_INSTANCE))->table(static::table())->where('id', DB_SQL_Operator::_EQUAL_TO_, $this->fields['id']->value); $ignore_keys = array('id', 'scope', 'parent_id', 'lft', 'rgt'); // Is there any data to save and it's worth to execute the query? $is_worth = FALSE; foreach ($columns as $column) { if ($this->fields[$column]->savable and $this->fields[$column]->modified and !in_array($column, $ignore_keys)) { // Add column values to the query builder $builder->set($column, $this->fields[$column]->value); // It's worth do execute the query. $is_worth = TRUE; } // Mark field as not modified $this->fields[$column]->modified = FALSE; } // Execute the query only if there is data to save if ($is_worth) { $builder->execute(); } $this->metadata['saved'] = $this->hash_code(); } if ($reload) { $this->load(); } }
/** * This function saves the record matching using the primary key. * * @access public * @param boolean $reload whether the model should be reloaded * after the save is done * @param boolean $mode TRUE=save, FALSE=update, NULL=automatic * @throws Throwable_Marshalling_Exception indicates that model could not be saved */ public function save($reload = FALSE, $mode = NULL) { if (!static::is_savable()) { throw new Throwable_Marshalling_Exception('Message: Failed to save record to database. Reason: Model is not savable.', array(':class' => get_called_class())); } $primary_key = static::primary_key(); if (empty($primary_key) or !is_array($primary_key)) { throw new Throwable_Marshalling_Exception('Message: Failed to save record to database. Reason: No primary key has been declared.'); } $data_source = static::data_source(DB_DataSource::MASTER_INSTANCE); $table = static::table(); $columns = array_keys($this->fields); $hash_code = $this->hash_code(); // Set saving mode $do_insert = $mode === NULL ? $hash_code === NULL : (bool) $mode; if (!$do_insert) { // Check if we have to detect saving mode automatically if ($mode === NULL) { // Check if the model has been already saved $do_insert = ($this->metadata['saved'] === NULL or $hash_code != $this->metadata['saved']); // Check if the record exists in database if ($do_insert) { $builder = DB_SQL::select($data_source)->column(DB_SQL::expr(1), 'IsFound')->from($table); foreach ($primary_key as $column) { $builder->where($column, DB_SQL_Operator::_EQUAL_TO_, $this->fields[$column]->value); } $do_insert = !$builder->limit(1)->query()->is_loaded(); } } if (!$do_insert) { if (!empty($columns)) { $builder = DB_SQL::update($data_source)->table($table); // Is there any data to save and it's worth to execute the query? $is_worth = FALSE; foreach ($columns as $column) { if ($this->fields[$column]->savable and $this->fields[$column]->modified) { // Add column values to the query builder $builder->set($column, $this->fields[$column]->value); if (in_array($column, $primary_key) or $this->fields[$column]->value instanceof DB_SQL_Expression) { // Reloading required because primary key has been changed or an SQL expression has been used $reload = TRUE; } // It's worth do execute the query. $is_worth = TRUE; } // Mark field as not modified $this->fields[$column]->modified = FALSE; } // Execute the query only if there is data to save if ($is_worth) { foreach ($primary_key as $column) { $builder->where($column, DB_SQL_Operator::_EQUAL_TO_, $this->fields[$column]->value); } $builder->execute(); } $this->metadata['saved'] = $hash_code; } } } if ($do_insert) { if (!empty($columns)) { $builder = DB_SQL::insert($data_source)->into($table); // Is any data to save and it's worth to execute the query? $is_worth = FALSE; foreach ($columns as $column) { if ($this->fields[$column]->savable and $this->fields[$column]->modified) { // It's worth executing the query. $is_worth = TRUE; // Add column values to the query builder $builder->column($column, $this->fields[$column]->value); if ($this->fields[$column]->value instanceof DB_SQL_Expression) { // Reloading required, if using SQL expressions $reload = TRUE; } } // Mark field as not modified $this->fields[$column]->modified = FALSE; } // Execute the query only if there is data to save if ($is_worth) { if (static::is_auto_incremented() and $hash_code === NULL) { // Execute the query and assign the result to the primary key field $this->fields[$primary_key[0]]->value = $builder->execute(TRUE); // Mark the primary key field as not modified $this->fields[$primary_key[0]]->modified = FALSE; } else { $builder->execute(); } } $this->metadata['saved'] = $this->hash_code(); } } if ($reload) { $primary_key = static::primary_key(); //set the primary keys in a temp variable $temp = new stdClass(); foreach ($primary_key as $column) { $temp->{$column} = $this->{$column}; } //Force reset and then you can reload the model with relations $this->reset(); foreach ($primary_key as $column) { $this->{$column} = $temp->{$column}; } // Reload the record, if it's required $this->load(); } }