Index: branches/5.3.x/core/kernel/db/dbitem.php =================================================================== diff -u -N -r15938 -r16111 --- branches/5.3.x/core/kernel/db/dbitem.php (.../dbitem.php) (revision 15938) +++ branches/5.3.x/core/kernel/db/dbitem.php (.../dbitem.php) (revision 16111) @@ -1,6 +1,6 @@ getRequestProtectedFields($hash); + if ( $skip_fields ) { $set_fields = array_diff($set_fields, $skip_fields); } @@ -319,23 +319,43 @@ } /** + * Returns fields, that are not allowed to be changed from request. + * + * @param array $fields_hash Fields hash. + * + * @return array + */ + protected function getRequestProtectedFields(array $fields_hash) + { + // by default don't allow changing ID or foreign key from request + $config = $this->getUnitConfig(); + + $fields = Array (); + $fields[] = $config->getIDField(); + + $parent_prefix = $config->getParentPrefix(); + + if ( $parent_prefix && $this->isLoaded() && !$this->Application->isAdmin ) { + // don't allow changing foreign key of existing item from request + $fields[] = $config->getForeignKey($parent_prefix); + } + + return $fields; + } + + /** * Sets object fields from $hash array * @param Array $hash - * @param Array|null $skip_fields * @param Array|null $set_fields * @return void * @access public */ - public function SetDBFieldsFromHash($hash, $skip_fields = Array (), $set_fields = Array ()) + public function SetDBFieldsFromHash($hash, $set_fields = Array ()) { if ( !$set_fields ) { $set_fields = array_keys($hash); } - if ( $skip_fields ) { - $set_fields = array_diff($set_fields, $skip_fields); - } - $set_fields = array_intersect($set_fields, array_keys($this->Fields)); foreach ($set_fields as $field_name) { @@ -431,6 +451,7 @@ if ($field_values) { $this->FieldValues = array_merge($this->FieldValues, $field_values); $this->OriginalFieldValues = $this->FieldValues; + $this->Loaded = true; } else { return $this->Clear(); @@ -443,7 +464,6 @@ $this->UpdateFormattersSubFields(); // used for updating separate virtual date/time fields from DB timestamp (for example) $this->raiseEvent('OnAfterItemLoad', $this->GetID()); - $this->Loaded = true; return true; } @@ -614,11 +634,34 @@ $this->Application->RemoveVar($var_name); } else { - $this->Application->StoreVar($var_name, serialize($pending_actions)); + $this->Application->StoreVar($var_name, serialize($this->sortPendingActions($pending_actions))); } } /** + * Sorts pending actions the way, that `delete` action will come before other actions. + * + * @param array $pending_actions Pending actions. + * + * @return array + */ + protected function sortPendingActions(array $pending_actions) + { + usort($pending_actions, array($this, 'comparePendingActions')); + + return $pending_actions; + } + + protected function comparePendingActions($pending_action_a, $pending_action_b) + { + if ( $pending_action_a['action'] == $pending_action_b['action'] ) { + return 0; + } + + return $pending_action_a['action'] == 'delete' ? -1 : 1; + } + + /** * Allows to skip certain fields from getting into sql queries * * @param string $field_name @@ -727,15 +770,7 @@ $this->saveCustomFields(); $this->raiseEvent('OnAfterItemUpdate'); - if ( !isset($update_fields) ) { - $this->OriginalFieldValues = $this->FieldValues; - } - else { - foreach ($update_fields as $update_field) { - $this->OriginalFieldValues[$update_field] = $this->FieldValues[$update_field]; - } - } - + // Preserve OriginalFieldValues during recursive Update() method calls. $this->Loaded = true; if ( !$this->IsTempTable() ) { @@ -920,6 +955,8 @@ // insert into temp table (id is not auto-increment field) $insert_id = $this->FieldValues[$this->IDField]; } + + $temp_id = $this->GetID(); $this->setID($insert_id); $this->OriginalFieldValues = $this->FieldValues; @@ -938,7 +975,7 @@ $this->setTempID(); } - $this->raiseEvent('OnAfterItemCreate'); + $this->raiseEvent('OnAfterItemCreate', null, array('temp_id' => $temp_id)); $this->Loaded = true; return true; @@ -1569,4 +1606,4 @@ return $merge_with; } -} \ No newline at end of file +}