/** * This function creates a new root node in the specified scope. * * @access public * @static * @param integer $scope the new scope to be create * @param string $name the name to given to the node * @param array $fields an associated array of additional field * name/value pairs * @return DB_ORM_MPTT the newly created root node **/ public static function add_root($scope, $name, array $fields = NULL) { $data_source = static::data_source(DB_DataSource::MASTER_INSTANCE); $table = static::table(); $connection = DB_Connection_Pool::instance()->get_connection($data_source); $connection->lock->add($table)->acquire(); $builder = DB_SQL::insert($data_source)->into($table)->column('scope', $scope)->column('name', $name)->column('parent_id', NULL)->column('lft', 1)->column('rgt', 2); if (is_array($fields)) { foreach ($fields as $field => $value) { $builder->column($field, $value); } } $insert = $builder->statement(); $connection->execute($insert); $id = $connection->get_last_insert_id(); $connection->lock->release(); $model = get_called_class(); $root = new $model(); $root->id = $id; $root->scope = $scope; $root->name = $name; $root->parent_id = NULL; $root->lft = 1; $root->rgt = 2; if (is_array($fields)) { foreach ($fields as $field => $value) { $root->{$field} = $value; } } return $root; }
/** * 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(); } }