/** * Persist an object to the data store. An insert or update will be executed based * on whether the primary key has a value. use $form_insert to override this * in the case of a primary key that is not an auto_increment * * @access public * @param Object $obj the object to persist * @param bool $force_insert (default = false) * @return int the auto_increment id (insert) or the number of records updated (update) */ public function Save($obj, $force_insert = false) { $objectclass = get_class($obj); $fms = $this->GetFieldMaps($objectclass); $pk = $obj->GetPrimaryKeyName(); $id = $obj->{$pk}; $table = $fms[$pk]->TableName; $pkcol = $fms[$pk]->ColumnName; $returnval = ""; $pk_is_auto_insert = strlen($id) == 0; // if there is no value for the primary key, this is an insert $is_insert = $force_insert || $pk_is_auto_insert; // fire the OnSave event in case the object needs to prepare itself // if OnSave returns false, then don't proceed with the save $this->Observe("Firing " . get_class($obj) . "->OnSave({$is_insert})", OBSERVE_DEBUG); if (!$obj->OnSave($is_insert)) { $this->Observe("" . get_class($obj) . "->OnSave({$is_insert}) returned FALSE. Exiting without saving", OBSERVE_WARN); return false; } $sql = ""; if (!$is_insert) { // this is an update // remove this class from the cache before saving $this->DeleteCache($objectclass, $id); $sql = "update `{$table}` set "; $delim = ""; foreach ($fms as $fm) { if (!$fm->IsPrimaryKey && $fm->FieldType != FM_CALCULATION) { $prop = $fm->PropertyName; $val = $obj->{$prop}; try { $sql .= $delim . "`" . $fm->ColumnName . "` = " . $this->GetQuotedSql($val); } catch (Exception $ex) { throw new Exception("Error escaping property '{$prop}'. value could not be converted to string"); } $delim = ", "; } } $sql .= " where {$pkcol} = '" . $this->Escape($id) . "'"; $returnval = $this->DataAdapter->Execute($sql); $obj->OnUpdate(); // fire OnUpdate event } else { // this is an insert $sql = "insert into `{$table}` ("; $delim = ""; foreach ($fms as $fm) { // we don't want to include the primary key if this is an auto-increment table if (!$fm->IsPrimaryKey || $force_insert) { // calculated fields are not directly bound to a column and do not get persisted if ($fm->FieldType != FM_CALCULATION) { $prop = $fm->PropertyName; $val = $obj->{$prop}; $sql .= $delim . "`" . $fm->ColumnName . "`"; $delim = ", "; } } } $sql .= ") values ("; $delim = ""; foreach ($fms as $fm) { // use the save logic inserting values as with the column names above if (!$fm->IsPrimaryKey || $force_insert) { if ($fm->FieldType != FM_CALCULATION) { $prop = $fm->PropertyName; $val = $obj->{$prop}; try { $sql .= $delim . ' ' . $this->GetQuotedSql($val); } catch (Exception $ex) { throw new Exception("Error escaping property '{$prop}'. value could not be converted to string"); } $delim = ", "; } } } $sql .= ")"; // for the insert we also need to get the insert id of the primary key $returnval = $this->DataAdapter->Execute($sql); if ($pk_is_auto_insert) { $returnval = $this->DataAdapter->GetLastInsertId(); $obj->{$pk} = $returnval; } $obj->OnInsert(); // fire OnInsert event } return $returnval; }