Page MenuHomeIn-Portal Phabricator

D504.id1309.diff
No OneTemporary

File Metadata

Created
Thu, Feb 6, 6:36 AM

D504.id1309.diff

Index: branches/5.2.x/core/kernel/db/db_event_handler.php
===================================================================
--- branches/5.2.x/core/kernel/db/db_event_handler.php
+++ branches/5.2.x/core/kernel/db/db_event_handler.php
@@ -1909,8 +1909,9 @@
$object->setPendingActions(null, true);
- $changes_var_name = $this->Prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $this->Application->RemoveVar($changes_var_name);
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->forgetChanges($this->Prefix);
/** @var kTempTablesHandler $temp_handler */
$temp_handler = $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler', Array ('parent_event' => $event));
@@ -1949,8 +1950,6 @@
/** @var kTempTablesHandler $temp_handler */
$temp_handler = $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler', Array ('parent_event' => $event));
- $changes_var_name = $this->Prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
-
if ( !$this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$live_ids = $temp_handler->SaveEdit($event->getEventParam('master_ids') ? $event->getEventParam('master_ids') : Array ());
@@ -1969,7 +1968,9 @@
/** @var kDBItem $object */
$object = $event->getObject();
- $this->SaveLoggedChanges($changes_var_name, $object->ShouldLogChanges());
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->saveLoggedChanges($this->Prefix, $object->ShouldLogChanges());
}
else {
$event->status = kEvent::erFAIL;
@@ -1985,101 +1986,22 @@
}
/**
- * Saves changes made in temporary table to log
+ * Saves changes made in the temporary table to log.
*
- * @param string $changes_var_name
- * @param bool $save
- * @return void
- * @access public
+ * @param string $changes_var_name Changes var name.
+ * @param boolean $save Save changes.
+ *
+ * @return void
+ * @deprecated 5.2.2-B3
+ * @see ChangeLogHelper::saveLoggedChanges()
*/
public function SaveLoggedChanges($changes_var_name, $save = true)
{
- // 1. get changes, that were made
- $changes = $this->Application->RecallVar($changes_var_name);
- $changes = $changes ? unserialize($changes) : Array ();
- $this->Application->RemoveVar($changes_var_name);
-
- if (!$changes) {
- // no changes, skip processing
- return ;
- }
-
- // TODO: 2. optimize change log records (replace multiple changes to same record with one change record)
-
- $to_increment = Array ();
-
- // 3. collect serials to reset based on foreign keys
- foreach ($changes as $index => $rec) {
- if (array_key_exists('DependentFields', $rec)) {
-
- foreach ($rec['DependentFields'] as $field_name => $field_value) {
- // will be "ci|ItemResourceId:345"
- $to_increment[] = $rec['Prefix'] . '|' . $field_name . ':' . $field_value;
-
- // also reset sub-item prefix general serial
- $to_increment[] = $rec['Prefix'];
- }
-
- unset($changes[$index]['DependentFields']);
- }
-
- unset($changes[$index]['ParentId'], $changes[$index]['ParentPrefix']);
- }
-
- // 4. collect serials to reset based on changed ids
- foreach ($changes as $change) {
- $to_increment[] = $change['MasterPrefix'] . '|' . $change['MasterId'];
-
- if ($change['MasterPrefix'] != $change['Prefix']) {
- // also reset sub-item prefix general serial
- $to_increment[] = $change['Prefix'];
-
- // will be "ci|ItemResourceId"
- $to_increment[] = $change['Prefix'] . '|' . $change['ItemId'];
- }
- }
-
- // 5. reset serials collected before
- $to_increment = array_unique($to_increment);
- $this->Application->incrementCacheSerial($this->Prefix);
-
- foreach ($to_increment as $to_increment_mixed) {
- if (strpos($to_increment_mixed, '|') !== false) {
- list ($to_increment_prefix, $to_increment_id) = explode('|', $to_increment_mixed, 2);
- $this->Application->incrementCacheSerial($to_increment_prefix, $to_increment_id);
- }
- else {
- $this->Application->incrementCacheSerial($to_increment_mixed);
- }
- }
-
- // save changes to database
- $sesion_log_id = $this->Application->RecallVar('_SessionLogId_');
-
- if (!$save || !$sesion_log_id) {
- // saving changes to database disabled OR related session log missing
- return ;
- }
-
- $add_fields = Array (
- 'PortalUserId' => $this->Application->RecallVar('user_id'),
- 'SessionLogId' => $sesion_log_id,
- );
-
- $change_log_table = $this->Application->getUnitOption('change-log', 'TableName');
-
- foreach ($changes as $rec) {
- $this->Conn->doInsert(array_merge($rec, $add_fields), $change_log_table);
- }
-
- $this->Application->incrementCacheSerial('change-log');
-
- $sql = 'UPDATE ' . $this->Application->getUnitOption('session-log', 'TableName') . '
- SET AffectedItems = AffectedItems + ' . count($changes) . '
- WHERE SessionLogId = ' . $sesion_log_id;
- $this->Conn->Query($sql);
+ kUtil::deprecatedMethod(__METHOD__, '5.2.2-B3', 'ChangeLogHelper::saveLoggedChanges');
- $this->Application->incrementCacheSerial('session-log');
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->saveLoggedChanges($this->Prefix, $save);
}
/**
@@ -2100,8 +2022,9 @@
$this->Application->RemoveVar($event->getPrefixSpecial() . '_modified');
- $changes_var_name = $this->Prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $this->Application->RemoveVar($changes_var_name);
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->forgetChanges($this->Prefix);
$event->SetRedirectParam('opener', 'u');
}
@@ -2271,8 +2194,9 @@
$this->Application->SetVar($event->getPrefixSpecial() . '_id', 0);
$this->Application->SetVar($event->getPrefixSpecial() . '_PreCreate', 1);
- $changes_var_name = $this->Prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $this->Application->RemoveVar($changes_var_name);
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->forgetChanges($this->Prefix);
$event->redirect = false;
}
Index: branches/5.2.x/core/kernel/db/dbitem.php
===================================================================
--- branches/5.2.x/core/kernel/db/dbitem.php
+++ branches/5.2.x/core/kernel/db/dbitem.php
@@ -1147,46 +1147,15 @@
$this->Conn->Query('UPDATE '.$this->TableName.' SET `'.$this->IDField.'` = '.$new_id.' WHERE `'.$this->IDField.'` = '.$this->GetID());
- if ($this->ShouldLogChanges(true)) {
- // Updating TempId in ChangesLog, if changes are disabled
- $ses_var_name = $this->Application->GetTopmostPrefix($this->Prefix) . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $changes = $this->Application->RecallVar($ses_var_name);
- $changes = $changes ? unserialize($changes) : Array ();
-
- if ($changes) {
- foreach ($changes as $key => $rec) {
- if ($rec['Prefix'] == $this->Prefix && $rec['ItemId'] == $this->GetID()) {
- // change log for record, that's ID was just updated -> update in change log record too
- $changes[$key]['ItemId'] = $new_id;
- }
-
- if ($rec['MasterPrefix'] == $this->Prefix && $rec['MasterId'] == $this->GetID()) {
- // master item id was changed
- $changes[$key]['MasterId'] = $new_id;
- }
-
- if (in_array($this->Prefix, $rec['ParentPrefix']) && $rec['ParentId'][$this->Prefix] == $this->GetID()) {
- // change log record of given item's sub item -> update changed id's in dependent fields
- $changes[$key]['ParentId'][$this->Prefix] = $new_id;
-
- if (array_key_exists('DependentFields', $rec)) {
- // these are fields from table of $rec['Prefix'] table!
- // when one of dependent fields goes into idfield of it's parent item, that was changed
- $parent_table_key = $this->Application->getUnitOption($rec['Prefix'], 'ParentTableKey');
- $parent_table_key = is_array($parent_table_key) ? $parent_table_key[$this->Prefix] : $parent_table_key;
-
- if ($parent_table_key == $this->IDField) {
- $foreign_key = $this->Application->getUnitOption($rec['Prefix'], 'ForeignKey');
- $foreign_key = is_array($foreign_key) ? $foreign_key[$this->Prefix] : $foreign_key;
-
- $changes[$key]['DependentFields'][$foreign_key] = $new_id;
- }
- }
- }
- }
- }
-
- $this->Application->StoreVar($ses_var_name, serialize($changes));
+ if ( $this->ShouldLogChanges(true) ) {
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->updateForeignKeys(
+ array('Prefix' => $this->Prefix, 'IdField' => $this->IDField),
+ $new_id,
+ $this->GetID(),
+ $this->Application->GetTopmostPrefix($this->Prefix)
+ );
}
$old_id = $this->GetID();
@@ -1214,14 +1183,12 @@
$this->Application->StoreVar($main_prefix . '_modified', '1', true); // true for optional
if ( $this->ShouldLogChanges(true) ) {
- $this->LogChanges($main_prefix, $mode, $update_fields);
-
- if (!$this->IsTempTable()) {
- /** @var kDBEventHandler $handler */
- $handler = $this->Application->recallObject($this->Prefix . '_EventHandler');
+ /** @var ChangeLogHelper $change_log_helper */
+ $change_log_helper = $this->Application->recallObject('ChangeLogHelper');
+ $change_log_helper->logChanges($this, $mode, $update_fields);
- $ses_var_name = $main_prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $handler->SaveLoggedChanges($ses_var_name, $this->ShouldLogChanges());
+ if ( !$this->IsTempTable() ) {
+ $change_log_helper->saveLoggedChanges($this->Prefix, $this->ShouldLogChanges());
}
}
}
@@ -1242,97 +1209,6 @@
return $log_changes && !$this->Application->getUnitOption($this->Prefix, 'ForceDontLogChanges');
}
- protected function LogChanges($main_prefix, $mode, $update_fields = null)
- {
- if ( !$mode ) {
- return ;
- }
-
- $ses_var_name = $main_prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $changes = $this->Application->RecallVar($ses_var_name);
- $changes = $changes ? unserialize($changes) : Array ();
-
- $fields_hash = Array (
- 'Prefix' => $this->Prefix,
- 'ItemId' => $this->GetID(),
- 'OccuredOn' => adodb_mktime(),
- 'MasterPrefix' => $main_prefix,
- 'Action' => $mode,
- );
-
- if ( $this->Prefix == $main_prefix ) {
- // main item
- $fields_hash['MasterId'] = $this->GetID();
- $fields_hash['ParentPrefix'] = Array ($main_prefix);
- $fields_hash['ParentId'] = Array ($main_prefix => $this->GetID());
- }
- else {
- // sub item
- // collect foreign key values (for serial reset)
- $foreign_keys = $this->Application->getUnitOption($this->Prefix, 'ForeignKey', Array ());
- $dependent_fields = $fields_hash['ParentId'] = $fields_hash['ParentPrefix'] = Array ();
- /** @var Array $foreign_keys */
-
- if ( is_array($foreign_keys) ) {
- foreach ($foreign_keys as $prefix => $field_name) {
- $dependent_fields[$field_name] = $this->GetDBField($field_name);
- $fields_hash['ParentPrefix'][] = $prefix;
- $fields_hash['ParentId'][$prefix] = $this->getParentId($prefix);
- }
- }
- else {
- $dependent_fields[$foreign_keys] = $this->GetDBField($foreign_keys);
- $fields_hash['ParentPrefix'] = Array ( $this->Application->getUnitOption($this->Prefix, 'ParentPrefix') );
- $fields_hash['ParentId'][ $fields_hash['ParentPrefix'][0] ] = $this->getParentId('auto');
- }
-
- $fields_hash['DependentFields'] = $dependent_fields;
-
-
- // works only, when main item is present in url, when sub-item is changed
- $master_id = $this->Application->GetVar($main_prefix . '_id');
-
- if ( $master_id === false ) {
- // works in case of we are not editing topmost item, when sub-item is created/updated/deleted
- $master_id = $this->getParentId('auto', true);
- }
-
- $fields_hash['MasterId'] = $master_id;
- }
-
- switch ( $mode ) {
- case ChangeLog::UPDATE:
- $changed_fields = $this->GetChangedFields();
-
- if ( $update_fields ) {
- $changed_fields = array_intersect_key(
- $changed_fields,
- array_combine($update_fields, $update_fields)
- );
- }
-
- $to_save = array_merge($this->GetTitleField(), $changed_fields);
- break;
-
- case ChangeLog::CREATE:
- $to_save = $this->GetTitleField();
- break;
-
- case ChangeLog::DELETE:
- $to_save = array_merge($this->GetTitleField(), $this->GetRealFields());
- break;
-
- default:
- $to_save = Array ();
- break;
- }
-
- $fields_hash['Changes'] = serialize($to_save);
- $changes[] = $fields_hash;
-
- $this->Application->StoreVar($ses_var_name, serialize($changes));
- }
-
/**
* Returns current item parent's ID
*
Index: branches/5.2.x/core/kernel/utility/temp_handler.php
===================================================================
--- branches/5.2.x/core/kernel/utility/temp_handler.php
+++ branches/5.2.x/core/kernel/utility/temp_handler.php
@@ -74,6 +74,23 @@
protected $parentEvent = null;
/**
+ * Change Log helper.
+ *
+ * @var $changeLogHelper
+ */
+ protected $changeLogHelper;
+
+ /**
+ * Creates class instance.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->changeLogHelper = $this->Application->recallObject('ChangeLogHelper');
+ }
+
+ /**
* Sets new parent event to the object
*
* @param kEvent $event
@@ -697,7 +714,7 @@
WHERE ' . $master['IdField'] . ' = 0';
$this->Conn->Query($query);
- $this->UpdateChangeLogForeignKeys($master, $live_ids[$an_id], $an_id);
+ $this->changeLogHelper->updateForeignKeys($master, $live_ids[$an_id], $an_id, $this->Prefix);
}
}
@@ -783,55 +800,9 @@
return $connection;
}
- function UpdateChangeLogForeignKeys($master, $live_id, $temp_id)
- {
- if ($live_id == $temp_id) {
- return ;
- }
-
- $prefix = $master['Prefix'];
- $main_prefix = $this->Application->GetTopmostPrefix($prefix);
- $ses_var_name = $main_prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
- $changes = $this->Application->RecallVar($ses_var_name);
- $changes = $changes ? unserialize($changes) : Array ();
-
- foreach ($changes as $key => $rec) {
- if ($rec['Prefix'] == $prefix && $rec['ItemId'] == $temp_id) {
- // main item change log record
- $changes[$key]['ItemId'] = $live_id;
- }
-
- if ($rec['MasterPrefix'] == $prefix && $rec['MasterId'] == $temp_id) {
- // sub item change log record
- $changes[$key]['MasterId'] = $live_id;
- }
-
- if (in_array($prefix, $rec['ParentPrefix']) && $rec['ParentId'][$prefix] == $temp_id) {
- // parent item change log record
- $changes[$key]['ParentId'][$prefix] = $live_id;
-
- if (array_key_exists('DependentFields', $rec)) {
- // these are fields from table of $rec['Prefix'] table!
- // when one of dependent fields goes into idfield of it's parent item, that was changed
- $parent_table_key = $this->Application->getUnitOption($rec['Prefix'], 'ParentTableKey');
- $parent_table_key = is_array($parent_table_key) ? $parent_table_key[$prefix] : $parent_table_key;
-
- if ($parent_table_key == $master['IdField']) {
- $foreign_key = $this->Application->getUnitOption($rec['Prefix'], 'ForeignKey');
- $foreign_key = is_array($foreign_key) ? $foreign_key[$prefix] : $foreign_key;
-
- $changes[$key]['DependentFields'][$foreign_key] = $live_id;
- }
- }
- }
- }
-
- $this->Application->StoreVar($ses_var_name, serialize($changes));
- }
-
function UpdateForeignKeys($master, $live_id, $temp_id)
{
- $this->UpdateChangeLogForeignKeys($master, $live_id, $temp_id);
+ $this->changeLogHelper->updateForeignKeys($master, $live_id, $temp_id, $this->Prefix);
foreach ($master['SubTables'] as $sub_table) {
$foreign_key_field = is_array($sub_table['ForeignKey']) ? getArrayValue($sub_table, 'ForeignKey', $master['Prefix']) : $sub_table['ForeignKey'];
Index: branches/5.2.x/core/units/helpers/ChangeLogHelper.php
===================================================================
--- branches/5.2.x/core/units/helpers/ChangeLogHelper.php
+++ branches/5.2.x/core/units/helpers/ChangeLogHelper.php
@@ -0,0 +1,316 @@
+<?php
+/**
+* @version $Id$
+* @package In-Portal
+* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
+* @license GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+class ChangeLogHelper extends kHelper
+{
+
+ /**
+ * Forgets changes.
+ *
+ * @param string $main_prefix Main prefix.
+ *
+ * @return void
+ */
+ public function forgetChanges($main_prefix)
+ {
+ $ses_var_name = $this->getSessionVariableName($main_prefix, $main_prefix);
+ $this->Application->RemoveVar($ses_var_name);
+ }
+
+ /**
+ * Updates the foreign keys in the changelog for a given table based on the provided identifiers.
+ *
+ * This method ensures that all references to the temporary ID in the changelog are updated to use
+ * the live ID, while considering dependencies and relationships between items.
+ *
+ * @param array $table_info Table info.
+ * @param integer $live_id Live ID.
+ * @param integer $temp_id Temp ID.
+ * @param string $caller_prefix Caller prefix.
+ *
+ * @return void
+ */
+ public function updateForeignKeys(array $table_info, $live_id, $temp_id, $caller_prefix)
+ {
+ if ( $live_id == $temp_id ) {
+ return;
+ }
+
+ $prefix = $table_info['Prefix'];
+ $main_prefix = $this->Application->GetTopmostPrefix($prefix);
+
+ $ses_var_name = $this->getSessionVariableName($main_prefix, $caller_prefix);
+ $changes = $this->Application->RecallVar($ses_var_name);
+ $changes = $changes ? unserialize($changes) : array();
+
+ if ( !$changes ) {
+ return;
+ }
+
+ foreach ( $changes as $key => $rec ) {
+ // The main item changelog record.
+ if ( $rec['Prefix'] == $prefix && $rec['ItemId'] == $temp_id ) {
+ $changes[$key]['ItemId'] = $live_id;
+ }
+
+ // The subitem changelog record.
+ if ( $rec['MasterPrefix'] == $prefix && $rec['MasterId'] == $temp_id ) {
+ $changes[$key]['MasterId'] = $live_id;
+ }
+
+ // The parent item changelog record.
+ if ( in_array($prefix, $rec['ParentPrefix']) && $rec['ParentId'][$prefix] == $temp_id ) {
+ $changes[$key]['ParentId'][$prefix] = $live_id;
+
+ if ( array_key_exists('DependentFields', $rec) ) {
+ /*
+ * These are fields from the $rec['Prefix'] table!
+ * Used, when one of the dependent fields uses IdField of its changed parent item.
+ */
+ $parent_table_key = $this->Application->getUnitOption($rec['Prefix'], 'ParentTableKey');
+ $parent_table_key = is_array($parent_table_key) ? $parent_table_key[$prefix] : $parent_table_key;
+
+ if ( $parent_table_key == $table_info['IdField'] ) {
+ $foreign_key = $this->Application->getUnitOption($rec['Prefix'], 'ForeignKey');
+ $foreign_key = is_array($foreign_key) ? $foreign_key[$prefix] : $foreign_key;
+
+ $changes[$key]['DependentFields'][$foreign_key] = $live_id;
+ }
+ }
+ }
+ }
+
+ $this->Application->StoreVar($ses_var_name, serialize($changes));
+ }
+
+ /**
+ * Logs changes for a database item, tracking relevant details for create, update, or delete actions.
+ *
+ * @param kDBItem $object Object.
+ * @param integer $mode Mode (e.g., create, update, delete).
+ * @param array|null $update_fields Update fields.
+ *
+ * @return void
+ */
+ public function logChanges(kDBItem $object, $mode, array $update_fields = null)
+ {
+ if ( !$mode ) {
+ return;
+ }
+
+ $prefix = $object->Prefix;
+ $main_prefix = $this->Application->GetTopmostPrefix($prefix);
+
+ $ses_var_name = $this->getSessionVariableName($main_prefix, $prefix);
+ $changes = $this->Application->RecallVar($ses_var_name);
+ $changes = $changes ? unserialize($changes) : array();
+
+ $fields_hash = array(
+ 'Prefix' => $prefix,
+ 'ItemId' => $object->GetID(),
+ 'OccuredOn' => adodb_mktime(),
+ 'MasterPrefix' => $main_prefix,
+ 'Action' => $mode,
+ );
+
+ if ( $prefix == $main_prefix ) {
+ // Main item.
+ $fields_hash['MasterId'] = $object->GetID();
+ $fields_hash['ParentPrefix'] = array($main_prefix);
+ $fields_hash['ParentId'] = array($main_prefix => $object->GetID());
+ }
+ else {
+ /*
+ * Subitem.
+ * Collect foreign key values (for serial reset).
+ */
+ $foreign_keys = $this->Application->getUnitOption($prefix, 'ForeignKey', array());
+ $dependent_fields = $fields_hash['ParentId'] = $fields_hash['ParentPrefix'] = array();
+ /** @var Array $foreign_keys */
+
+ if ( is_array($foreign_keys) ) {
+ foreach ( $foreign_keys as $foreign_key_prefix => $foreign_key_field_name ) {
+ $dependent_fields[$foreign_key_field_name] = $object->GetDBField($foreign_key_field_name);
+ $fields_hash['ParentPrefix'][] = $foreign_key_prefix;
+ $fields_hash['ParentId'][$foreign_key_prefix] = $object->getParentId($foreign_key_prefix);
+ }
+ }
+ else {
+ $dependent_fields[$foreign_keys] = $object->GetDBField($foreign_keys);
+ $fields_hash['ParentPrefix'] = array(
+ $this->Application->getUnitOption($prefix, 'ParentPrefix'),
+ );
+ $fields_hash['ParentId'][$fields_hash['ParentPrefix'][0]] = $object->getParentId('auto');
+ }
+
+ $fields_hash['DependentFields'] = $dependent_fields;
+
+ // Works only when the main item is present in url when a subitem is changed.
+ $master_id = $this->Application->GetVar($main_prefix . '_id');
+
+ if ( $master_id === false ) {
+ // Works in case when we're not editing topmost item, when subitem is created/updated/deleted.
+ $master_id = $object->getParentId('auto', true);
+ }
+
+ $fields_hash['MasterId'] = $master_id;
+ }
+
+ switch ( $mode ) {
+ case ChangeLog::UPDATE:
+ $changed_fields = $object->GetChangedFields();
+
+ if ( $update_fields ) {
+ $changed_fields = array_intersect_key(
+ $changed_fields,
+ array_combine($update_fields, $update_fields)
+ );
+ }
+
+ $to_save = array_merge($object->GetTitleField(), $changed_fields);
+ break;
+
+ case ChangeLog::CREATE:
+ $to_save = $object->GetTitleField();
+ break;
+
+ case ChangeLog::DELETE:
+ $to_save = array_merge($object->GetTitleField(), $object->GetRealFields());
+ break;
+
+ default:
+ $to_save = array();
+ break;
+ }
+
+ $fields_hash['Changes'] = serialize($to_save);
+ $changes[] = $fields_hash;
+
+ $this->Application->StoreVar($ses_var_name, serialize($changes));
+ }
+
+ /**
+ * Saves changes made in the temporary table to log.
+ *
+ * @param string $prefix Prefix.
+ * @param boolean $save Save changes.
+ *
+ * @return void
+ */
+ public function saveLoggedChanges($prefix, $save = true)
+ {
+ $main_prefix = $this->Application->GetTopmostPrefix($prefix);
+
+ // 1. get changes that were made.
+ $ses_var_name = $this->getSessionVariableName($main_prefix, $prefix);
+ $changes = $this->Application->RecallVar($ses_var_name);
+ $changes = $changes ? unserialize($changes) : array();
+ $this->Application->RemoveVar($ses_var_name);
+
+ if ( !$changes ) {
+ // No changes, skip processing.
+ return;
+ }
+
+ // TODO: 2. optimize change log records (replace multiple changes to same record with one change record).
+ $to_increment = array();
+
+ // 3. collect serials to reset based on foreign keys
+ foreach ( $changes as $index => $rec ) {
+ if ( array_key_exists('DependentFields', $rec) ) {
+ foreach ( $rec['DependentFields'] as $field_name => $field_value ) {
+ // Will be "ci|ItemResourceId:345".
+ $to_increment[] = $rec['Prefix'] . '|' . $field_name . ':' . $field_value;
+
+ // Also reset sub-item prefix general serial.
+ $to_increment[] = $rec['Prefix'];
+ }
+
+ unset($changes[$index]['DependentFields']);
+ }
+
+ // Remove keys that don't have corresponding columns in the "ChangeLogs" database table.
+ unset($changes[$index]['ParentId'], $changes[$index]['ParentPrefix']);
+ }
+
+ // 4. collect serials to reset based on changed ids
+ foreach ( $changes as $change ) {
+ $to_increment[] = $change['MasterPrefix'] . '|' . $change['MasterId'];
+
+ if ( $change['MasterPrefix'] != $change['Prefix'] ) {
+ // Also reset sub-item prefix general serial.
+ $to_increment[] = $change['Prefix'];
+
+ // Will be "ci|ItemResourceId".
+ $to_increment[] = $change['Prefix'] . '|' . $change['ItemId'];
+ }
+ }
+
+ // 5. reset serials collected before
+ $to_increment = array_unique($to_increment);
+ $this->Application->incrementCacheSerial($prefix);
+
+ foreach ( $to_increment as $to_increment_mixed ) {
+ if ( strpos($to_increment_mixed, '|') !== false ) {
+ list ($to_increment_prefix, $to_increment_id) = explode('|', $to_increment_mixed, 2);
+ $this->Application->incrementCacheSerial($to_increment_prefix, $to_increment_id);
+ }
+ else {
+ $this->Application->incrementCacheSerial($to_increment_mixed);
+ }
+ }
+
+ // Save changes to a database.
+ $session_log_id = $this->Application->RecallVar('_SessionLogId_');
+
+ if ( !$save || !$session_log_id ) {
+ // Saving changes to database disabled OR related session log missing.
+ return;
+ }
+
+ $add_fields = array(
+ 'PortalUserId' => $this->Application->RecallVar('user_id'),
+ 'SessionLogId' => $session_log_id,
+ );
+
+ $change_log_table = $this->Application->getUnitOption('change-log', 'TableName');
+
+ foreach ( $changes as $rec ) {
+ $this->Conn->doInsert(array_merge($rec, $add_fields), $change_log_table);
+ }
+
+ $this->Application->incrementCacheSerial('change-log');
+
+ $sql = 'UPDATE ' . $this->Application->getUnitOption('session-log', 'TableName') . '
+ SET AffectedItems = AffectedItems + ' . count($changes) . '
+ WHERE SessionLogId = ' . $session_log_id;
+ $this->Conn->Query($sql);
+
+ $this->Application->incrementCacheSerial('session-log');
+ }
+
+ /**
+ * Returns change log session variable name.
+ *
+ * @param string $main_prefix Main prefix.
+ * @param string $prefix Prefix.
+ *
+ * @return string
+ */
+ protected function getSessionVariableName($main_prefix, $prefix)
+ {
+ return $main_prefix . '_changes_' . $this->Application->GetTopmostWid($prefix);
+ }
+
+}
Index: branches/5.2.x/core/units/helpers/helpers_config.php
===================================================================
--- branches/5.2.x/core/units/helpers/helpers_config.php
+++ branches/5.2.x/core/units/helpers/helpers_config.php
@@ -78,5 +78,6 @@
Array ('pseudo' => 'AjaxFormHelper', 'class' => 'AjaxFormHelper', 'file' => 'ajax_form_helper.php', 'build_event' => ''),
Array ('pseudo' => 'kCronHelper', 'class' => 'kCronHelper', 'file' => 'cron_helper.php', 'build_event' => ''),
Array ('pseudo' => 'kUploadHelper', 'class' => 'kUploadHelper', 'file' => 'upload_helper.php', 'build_event' => ''),
+ Array ('pseudo' => 'ChangeLogHelper', 'class' => 'ChangeLogHelper', 'file' => 'ChangeLogHelper.php', 'build_event' => ''),
),
);

Event Timeline