diff --git a/css/light-grey.css b/css/light-grey.css
index c0949a8cc..37afbf0a0 100644
--- a/css/light-grey.css
+++ b/css/light-grey.css
@@ -919,4 +919,22 @@ span.form_validation {
}
.wiki_broken_link {
text-decoration: line-through;
-}
\ No newline at end of file
+}
+.synoptics, .synoptics tr td {
+ background: transparent;
+ padding:10px;
+ font-size:1em;
+ vertical-align:middle;
+ color:#fff;
+ text-align:center;
+}
+.synoptics tr td.arrow {
+ color:#333;
+ border-top: 1px dashed #333;
+ width:100px;
+}
+.synoptics tr.synoptics_header td {
+ color:#000; font-size:1em;
+ vertical-align:middle;
+ text-align:center;
+}
diff --git a/dictionaries/dictionary.itop.core.php b/dictionaries/dictionary.itop.core.php
index 67b9eb290..1cd8af296 100644
--- a/dictionaries/dictionary.itop.core.php
+++ b/dictionaries/dictionary.itop.core.php
@@ -239,13 +239,13 @@ Dict::Add('EN US', 'English', 'English', array(
Dict::Add('EN US', 'English', 'English', array(
'Class:Event' => 'Log Event',
'Class:Event+' => 'An application internal event',
- 'Class:Event/Attribute:message' => 'message',
+ 'Class:Event/Attribute:message' => 'Message',
'Class:Event/Attribute:message+' => 'short description of the event',
- 'Class:Event/Attribute:date' => 'date',
+ 'Class:Event/Attribute:date' => 'Date',
'Class:Event/Attribute:date+' => 'date and time at which the changes have been recorded',
- 'Class:Event/Attribute:userinfo' => 'user info',
+ 'Class:Event/Attribute:userinfo' => 'User info',
'Class:Event/Attribute:userinfo+' => 'identification of the user that was doing the action that triggered this event',
- 'Class:Event/Attribute:finalclass' => 'type',
+ 'Class:Event/Attribute:finalclass' => 'Type',
'Class:Event/Attribute:finalclass+' => '',
));
@@ -329,6 +329,21 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:EventWebService/Attribute:data+' => 'Result data',
));
+//
+// Class: EventLoginUsage
+//
+
+Dict::Add('EN US', 'English', 'English', array(
+ 'Class:EventLoginUsage' => 'Login Usage',
+ 'Class:EventLoginUsage+' => 'Connection to the application',
+ 'Class:EventLoginUsage/Attribute:user_id' => 'Login',
+ 'Class:EventLoginUsage/Attribute:user_id+' => 'Login',
+ 'Class:EventLoginUsage/Attribute:contact_name' => 'User Name',
+ 'Class:EventLoginUsage/Attribute:contact_name+' => 'User Name',
+ 'Class:EventLoginUsage/Attribute:contact_email' => 'User Email',
+ 'Class:EventLoginUsage/Attribute:contact_email+' => 'Email Address of the User',
+));
+
//
// Class: Action
//
@@ -479,5 +494,47 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:lnkTriggerAction/Attribute:order+' => 'Actions execution order',
));
-
+//
+// Synchro Data Source
+//
+Dict::Add('EN US', 'English', 'English', array(
+ 'Core:SynchroAttributes' => 'Attributes',
+ 'Core:SynchroStatus' => 'Status',
+ 'Core:Synchro:ErrorsLabel' => 'Errors',
+ 'Core:Synchro:CreatedLabel' => 'Created',
+ 'Core:Synchro:ModifiedLabel' => 'Modified',
+ 'Core:Synchro:UnchangedLabel' => 'Unchanged',
+ 'Core:Synchro:ReconciledErrorsLabel' => 'Errors',
+ 'Core:Synchro:ReconciledLabel' => 'Reconciled',
+ 'Core:Synchro:ReconciledNewLabel' => 'Created',
+ 'Core:SynchroReconcile:Yes' => 'Yes',
+ 'Core:SynchroReconcile:No' => 'No',
+ 'Core:SynchroUpdate:Yes' => 'Yes',
+ 'Core:SynchroUpdate:No' => 'No',
+ 'Core:Synchro:LastestStatus' => 'Latest Status',
+ 'Core:Synchro:History' => 'Synchronization History',
+ 'Core:Synchro:NeverRun' => 'This synchro was never run. No log yet.',
+ 'Core:Synchro:SynchroEndedOn_Date' => 'The latest synchronization ended on %1$s.',
+ 'Core:Synchro:SynchroRunningStartedOn_Date' => 'The synchronization started on $1$s is still running...',
+ 'Menu:DataSources' => 'Synchronization Data Sources',
+ 'Menu:DataSources+' => 'All Synchronization Data Sources',
+ 'Core:Synchro:label_repl_ignored' => 'Ignored (%1$d)',
+ 'Core:Synchro:label_repl_disappeared' => 'Disappeared (%1$d)',
+ 'Core:Synchro:label_repl_existing' => 'Existing (%1$d)',
+ 'Core:Synchro:label_repl_new' => 'New (%1$d)',
+ 'Core:Synchro:label_obj_deleted' => 'Deleted (%1$d)',
+ 'Core:Synchro:label_obj_obsoleted' => 'Obsoleted (%1$d)',
+ 'Core:Synchro:label_obj_disappeared_errors' => 'Errors (%1$d)',
+ 'Core:Synchro:label_obj_unchanged' => 'Unchanged (%1$d)',
+ 'Core:Synchro:label_obj_updated' => 'Updated (%1$d)',
+ 'Core:Synchro:label_obj_updated_errors' => 'Errors (%1$d)',
+ 'Core:Synchro:label_obj_new_unchanged' => 'Unchanged (%1$d)',
+ 'Core:Synchro:label_obj_new_updated' => 'Updated (%1$d)',
+ 'Core:Synchro:label_obj_created' => 'Created (%1$d)',
+ 'Core:Synchro:label_obj_new_errors' => 'Errors (%1$d)',
+ 'Core:Synchro:History' => 'Synchronization History',
+ 'Core:SynchroLogTitle' => '%1$s - %2$s',
+ 'Core:Synchro:Nb_Replica' => '%1$s Replica',
+ 'Core:Synchro:Nb_Objects' => '%1$s Objects',
+));
?>
diff --git a/synchro/synchrodatasource.class.inc.php b/synchro/synchrodatasource.class.inc.php
index d6503b1a1..6428983ee 100644
--- a/synchro/synchrodatasource.class.inc.php
+++ b/synchro/synchrodatasource.class.inc.php
@@ -138,111 +138,119 @@ class SynchroDataSource extends cmdbAbstractObject
}
}
$oPage->Table($aAttribs, $aValues);
- $oPage->SetCurrentTab(Dict::S('Core:SynchroStatus'));
-
- $sSelectSynchroLog = 'SELECT SynchroLog WHERE sync_source_id = :source_id';
- $oSetSynchroLog = new CMDBObjectSet(DBObjectSearch::FromOQL($sSelectSynchroLog), array('start_date' => false) /* order by*/, array('source_id' => $this->GetKey()));
-
- if ($oSetSynchroLog->Count() > 0)
- {
- $oLastLog = $oSetSynchroLog->Fetch();
- $sStartDate = $oLastLog->Get('start_date');
- $oLastLog->Get('stats_nb_replica_seen');
- if ($oLastLog->Get('status') == 'running')
- {
- // Still running !
- $oPage->p('
'.Dict::Format('Core:Synchro:SynchroRunningStartedOn_Date', $sStartDate).'
');
- }
- else
- {
- $sEndDate = $oLastLog->Get('end_date');
- $oPage->p(''.Dict::Format('Core:Synchro:SynchroEndedOn_Date', $sEndDate).'
');
- }
-
- $iDeleted = $oLastLog->Get('stats_nb_obj_deleted');
- $iObsoleted = $oLastLog->Get('stats_nb_obj_obsoleted');
- $iDisappearedErrors = $oLastLog->Get('stats_nb_obj_obsoleted_errors') + $oLastLog->Get('stats_nb_obj_deleted_errors');
- $iUpdated = $oLastLog->Get('stats_nb_obj_updated');
- $iUpdatedErrors = $oLastLog->Get('stats_nb_obj_updated_errors');
- $iReconciled = $oLastLog->Get('stats_nb_replica_reconciled');
- $iReconciledErrors = $oLastLog->Get('stats_nb_replica_reconciled_errors');
- $iCreated = $oLastLog->Get('stats_nb_obj_created');
- $iCreatedErrors = $oLastLog->Get('stats_nb_obj_created_errors');
- $iDisappeared = $iDisappearedErrors + $iObsoleted + $iDeleted;
- $iNewErrors = $iCreatedErrors + $iReconciledErrors;
- $iNew = $iCreated + $iCreatedErrors + $iReconciled + $iReconciledErrors;
- $iExisting = $oLastLog->Get('stats_nb_replica_seen') - $iNew;
- $iUnchanged = $iExisting - $iUpdated - $iUpdatedErrors;
- $iIgnored = $oLastLog->Get('stats_nb_replica_total') - $iNew - $iExisting - $iDisappeared;
-
- $fOpacity = 0.3;
- $sNewOpacity = ($iNew ==0) ? "opacity:$fOpacity;" : "";
- $sExistingOpacity = ($iExisting ==0) ? "opacity:$fOpacity;" : "";
- $sDisappearedOpacity = ($iDisappeared ==0) ? "opacity:$fOpacity;" : "";
- $sIgnoredOpacity = ($iIgnored ==0) ? "opacity:$fOpacity;" : "";
-
- $sCreateOpacity = ($iCreated ==0) ? "opacity:$fOpacity;" : "";
- $sReconciledOpacity = ($iReconciled ==0) ? "opacity:$fOpacity;" : "";
- $sNewErrorsOpacity = ($iNewErrors ==0) ? "opacity:$fOpacity;" : "";
-
- $sUnchangedOpacity = ($iUnchanged ==0) ? "opacity:$fOpacity;" : "";
- $sUpdatedOpacity = ($iUpdated ==0) ? "opacity:$fOpacity;" : "";
- $sUpdatedErrorsOpacity = ($iUpdatedErrors ==0) ? "opacity:$fOpacity;" : "";
-
- $sDeletedOpacity = ($iDeleted ==0) ? "opacity:$fOpacity;" : "";
- $sObsoletedOpacity = ($iObsoleted ==0) ? "opacity:$fOpacity;" : "";
- $sDisappearedErrorsOpacity = ($iDisappearedErrors ==0) ? "opacity:$fOpacity;" : "";
-
- $oPage->add(
-<<
- .synoptics, .synoptics tr td { background: transparent; padding:10px; font-size:1em; vertical-align:middle; color:#fff; text-align:center;}
- .synoptics tr td.arrow { color:#333; border-top: 1px dashed #333; width:100px; }
-
-
-
- | Ignored ($iIgnored) | |
-
-
- | Disappeared ($iDisappeared) | => | Deleted ($iDeleted) |
-
-
- | Obsoleted ($iObsoleted) |
-
-
- | Errors ($iDisappearedErrors) |
-
-
- | Existing ($iExisting) | => | Unchanged ($iUnchanged) |
-
-
- | Updated ($iUpdated) |
-
-
- | Errors ($iUpdatedErrors) |
-
-
- | New ($iNew) | => | Errors ($iNewErrors) |
-
-
- | Reconciled ($iReconciled) |
-
-
- | Created ($iCreated) |
-
-
-EOF
- );
- }
- else
- {
- $oPage->p(''.Dict::S('Core:Synchro:NeverRun').'
');
- }
-
+ $this->DisplayStatusTab($oPage);
}
parent::DisplayBareRelations($oPage, $bEditMode);
}
+ /**
+ * Displays the status (SynchroLog) of the datasource in a graphical manner
+ * @param $oPage WebPage
+ * @return void
+ */
+ protected function DisplayStatusTab(WebPage $oPage)
+ {
+ $oPage->SetCurrentTab(Dict::S('Core:SynchroStatus'));
+
+ $sSelectSynchroLog = 'SELECT SynchroLog WHERE sync_source_id = :source_id';
+ $oSetSynchroLog = new CMDBObjectSet(DBObjectSearch::FromOQL($sSelectSynchroLog), array('start_date' => false) /* order by*/, array('source_id' => $this->GetKey()));
+
+ if ($oSetSynchroLog->Count() > 0)
+ {
+ $oLastLog = $oSetSynchroLog->Fetch();
+ $sStartDate = $oLastLog->Get('start_date');
+ $oLastLog->Get('stats_nb_replica_seen');
+ if ($oLastLog->Get('status') == 'running')
+ {
+ // Still running !
+ $oPage->p(''.Dict::Format('Core:Synchro:SynchroRunningStartedOn_Date', $sStartDate).'
');
+ }
+ else
+ {
+ $sEndDate = $oLastLog->Get('end_date');
+ $oPage->p(''.Dict::Format('Core:Synchro:SynchroEndedOn_Date', $sEndDate).'
');
+ }
+
+ $oPage->add('');
+ $oPage->add(''.Dict::S('Core:Synchro:History').'');
+ $oSetSynchroLog->Rewind();
+ $oPage->add('');
+ $oPage->add(' | ');
+ $iDeleted = $oLastLog->Get('stats_nb_obj_deleted');
+ $iObsoleted = $oLastLog->Get('stats_nb_obj_obsoleted');
+ $iDisappearedErrors = $oLastLog->Get('stats_nb_obj_obsoleted_errors') + $oLastLog->Get('stats_nb_obj_deleted_errors');
+ $iUpdated = $oLastLog->Get('stats_nb_obj_updated');
+ $iUpdatedErrors = $oLastLog->Get('stats_nb_obj_updated_errors');
+ $iNewUpdated = $oLastLog->Get('stats_nb_obj_new_updated');
+ $iNewUnchanged = $oLastLog->Get('stats_nb_obj_new_unchanged');
+ $iReconciledErrors = $oLastLog->Get('stats_nb_replica_reconciled_errors');
+ $iCreated = $oLastLog->Get('stats_nb_obj_created');
+ $iCreatedErrors = $oLastLog->Get('stats_nb_obj_created_errors');
+ $iDisappeared = $iDisappearedErrors + $iObsoleted + $iDeleted;
+ $iNewErrors = $iCreatedErrors + $iReconciledErrors;
+ $iNew = $iCreated + $iCreatedErrors + $iNewUpdated + $iNewUnchanged + $iReconciledErrors;
+ $iExisting = $oLastLog->Get('stats_nb_replica_seen') - $iNew;
+ $iUnchanged = $iExisting - $iUpdated - $iUpdatedErrors;
+ $iIgnored = $oLastLog->Get('stats_nb_replica_total') - $iNew - $iExisting - $iDisappeared;
+
+ $iNbObjects = $iNew + $iExisting + $iDisappeared;
+ $iReplicas = $iNbObjects + $iIgnored;
+ $sNbReplica = Dict::Format('Core:Synchro:Nb_Replica', "$iReplicas");
+ $sNbObjects = Dict::Format('Core:Synchro:Nb_Objects', "$iNbObjects");
+ $oPage->add(
+<<
+
+
+EOF
+);
+ $oPage->add($this->HtmlBox('repl_ignored', $iIgnored, '#999').'| | ');
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('repl_disappeared', $iDisappeared, '#630', 'rowspan="3"').'| => | '.$this->HtmlBox('obj_deleted', $iDeleted, '#000'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_obsoleted', $iDisappeared, '#630'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_disappeared_errors', $iDisappearedErrors, '#C00'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('repl_existing', $iExisting, '#093', 'rowspan="3"').'| => | '.$this->HtmlBox('obj_unchanged', $iUnchanged, '#393'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_updated', $iUpdated, '#3C3'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_updated_errors', $iUpdatedErrors, '#C00'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('repl_new', $iNew, '#339', 'rowspan="4"').'| => | '.$this->HtmlBox('obj_new_unchanged', $iNewUnchanged, '#393'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_new_updated', $iNewUpdated, '#3C3'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_created', $iCreated, '#339'));
+ $oPage->add(" \n");
+ $oPage->add($this->HtmlBox('obj_new_errors', $iNewErrors, '#C00'));
+ $oPage->add(" \n |
\n");
+ $oPage->add('');
+ }
+ else
+ {
+ $oPage->p(''.Dict::S('Core:Synchro:NeverRun').'
');
+ }
+ }
+
+ public function HtmlBox($sId, $iCount, $sColor, $sHTMLAttribs = '')
+ {
+ $sCount = "$iCount";
+ $sLabel = Dict::Format('Core:Synchro:label_'.$sId, $iCount);
+ $sOpacity = ($iCount==0) ? "opacity:0.3;" : "";
+ return "$sLabel | ";
+ }
public function GetAttributeFlags($sAttCode)
{
if (($sAttCode == 'scope_class') && (!$this->IsNew()))
@@ -445,8 +453,10 @@ EOF
$oStatLog->Set('stats_nb_obj_created_errors', 0);
$oStatLog->Set('stats_nb_obj_updated', 0);
$oStatLog->Set('stats_nb_obj_updated_errors', 0);
- $oStatLog->Set('stats_nb_replica_reconciled', 0);
+// $oStatLog->Set('stats_nb_replica_reconciled', 0);
$oStatLog->Set('stats_nb_replica_reconciled_errors', 0);
+ $oStatLog->Set('stats_nb_obj_new_updated', 0);
+ $oStatLog->Set('stats_nb_obj_new_unchanged',0);
$sSelectTotal = "SELECT SynchroReplica WHERE sync_source_id = :source_id";
$oSetTotal = new DBObjectSet(DBObjectSearch::FromOQL($sSelectTotal), array() /* order by*/, array('source_id' => $this->GetKey()));
@@ -841,12 +851,14 @@ class SynchroLog extends cmdbAbstractObject
MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_obj_created_errors", array("allowed_values"=>null, "sql"=>"stats_nb_obj_created_errors", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_obj_updated", array("allowed_values"=>null, "sql"=>"stats_nb_obj_updated", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_obj_updated_errors", array("allowed_values"=>null, "sql"=>"stats_nb_obj_updated_errors", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
- MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_replica_reconciled", array("allowed_values"=>null, "sql"=>"stats_nb_replica_reconciled", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
+// MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_replica_reconciled", array("allowed_values"=>null, "sql"=>"stats_nb_replica_reconciled", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_replica_reconciled_errors", array("allowed_values"=>null, "sql"=>"stats_nb_replica_reconciled_errors", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
+ MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_obj_new_updated", array("allowed_values"=>null, "sql"=>"stats_nb_obj_new_updated", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
+ MetaModel::Init_AddAttribute(new AttributeInteger("stats_nb_obj_new_unchanged", array("allowed_values"=>null, "sql"=>"stats_nb_obj_new_unchanged", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
// Display lists
- MetaModel::Init_SetZListItems('details', array('sync_source_id', 'start_date', 'end_date', 'status', 'stats_nb_replica_total', 'stats_nb_replica_seen', 'stats_nb_obj_created', 'stats_nb_replica_reconciled', 'stats_nb_obj_updated', 'stats_nb_obj_obsoleted', 'stats_nb_obj_deleted',
- 'stats_nb_obj_created_errors', 'stats_nb_replica_reconciled_errors', 'stats_nb_obj_updated_errors', 'stats_nb_obj_obsoleted_errors', 'stats_nb_obj_deleted_errors')); // Attributes to be displayed for the complete details
+ MetaModel::Init_SetZListItems('details', array('sync_source_id', 'start_date', 'end_date', 'status', 'stats_nb_replica_total', 'stats_nb_replica_seen', 'stats_nb_obj_created', /*'stats_nb_replica_reconciled',*/ 'stats_nb_obj_updated', 'stats_nb_obj_obsoleted', 'stats_nb_obj_deleted',
+ 'stats_nb_obj_created_errors', 'stats_nb_replica_reconciled_errors', 'stats_nb_obj_updated_errors', 'stats_nb_obj_obsoleted_errors', 'stats_nb_obj_deleted_errors', 'stats_nb_obj_new_unchanged', 'stats_nb_obj_new_updated')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('sync_source_id', 'start_date', 'end_date', 'status', 'stats_nb_replica_seen')); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
@@ -1005,12 +1017,12 @@ class SynchroReplica extends DBObject
if ($oDataSource->Get('action_on_one') == 'update')
{
$oDestObj = $oDestSet->Fetch();
- $this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_replica_reconciled');
+ $this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_obj_new', 'stats_nb_replica_reconciled_errors');
$this->Set('dest_id', $oDestObj->GetKey());
$this->Set('status_dest_creator', false);
$this->Set('dest_class', get_class($oDestObj));
- $oStatLog->Inc('stats_nb_replica_reconciled');
+ $oStatLog->Inc('stats_nb_replica_reconciled'); //@@@
}
else
{
@@ -1037,7 +1049,7 @@ class SynchroReplica extends DBObject
{
// assumed to be 'take_first'
$oDestObj = $oDestSet->Fetch();
- $this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_replica_reconciled');
+ $this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_obj_new', 'stats_nb_replica_reconciled_errors');
$this->Set('dest_id', $oDestObj->GetKey());
$this->Set('status_dest_creator', false);
$this->Set('dest_class', get_class($oDestObj));
@@ -1055,7 +1067,7 @@ class SynchroReplica extends DBObject
}
else
{
- $this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_obj_updated');
+ $this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_obj', 'stats_nb_obj_updated_errors');
}
break;
@@ -1067,7 +1079,7 @@ class SynchroReplica extends DBObject
/**
* Updates the destination object with the Extended data found in the synchro_data_XXXX table
*/
- protected function UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, &$oStatLog, &$aTraces, $sStatsCode)
+ protected function UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, &$oStatLog, &$aTraces, $sStatsCode, $sStatsCodeError)
{
$aValueTrace = array();
foreach($aAttributes as $sAttCode)
@@ -1081,9 +1093,18 @@ class SynchroReplica extends DBObject
}
try
{
- $oDestObj->DBUpdateTracked($oChange);
- $aTraces[] = "Updated object ".$oDestObj->GetHyperLink()." (".implode(', ', $aValueTrace).")";
- $oStatLog->Inc($sStatsCode);
+ // Really modified ?
+ if ($oDestObj->IsModified())
+ {
+ $oDestObj->DBUpdateTracked($oChange);
+ $aTraces[] = "Updated object ".$oDestObj->GetHyperLink()." (".implode(', ', $aValueTrace).")";
+ $oStatLog->Inc($sStatsCode.'_updated');
+ }
+ else
+ {
+ $aTraces[] = "Unchanged object ".$oDestObj->GetHyperLink()." (".implode(', ', $aValueTrace).")";
+ $oStatLog->Inc($sStatsCode.'_unchanged');
+ }
$this->Set('status_last_error', '');
$this->Set('status', 'synchronized');
@@ -1092,7 +1113,7 @@ class SynchroReplica extends DBObject
{
$aTraces[] = "Failed to update destination object: {$e->getMessage()}";
$this->SetLastError('Unable to update destination object: ', $e);
- $oStatLog->Inc($sStatsCode.'_errors');
+ $oStatLog->Inc($sStatsCodeError);
}
}