diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php
index 8c0441e84c..e242e3699f 100644
--- a/application/cmdbabstract.class.inc.php
+++ b/application/cmdbabstract.class.inc.php
@@ -5356,6 +5356,7 @@ JS
/**
* @param array $aChanges
* @param bool $bIsNew
+ * @param string|null $sStimulusBeingApplied
*
* @return void
* @throws \ArchivedObjectException
@@ -5369,6 +5370,21 @@ JS
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied, 'cmdb_change' => self::GetCurrentChange()]);
}
+ //////////////
+ /// READ
+ ///
+
+ /**
+ * @return void
+ * @throws \CoreException
+ * @since 3.3.0
+ */
+ final public function FireEventReadDetails(): void
+ {
+
+ $this->FireEvent(EVENT_DB_TRACEABILITY);
+ }
+
//////////////
/// DELETE
///
diff --git a/application/datamodel.application.xml b/application/datamodel.application.xml
index eb18e600f4..aeef634653 100644
--- a/application/datamodel.application.xml
+++ b/application/datamodel.application.xml
@@ -519,6 +519,23 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
+
+ Object details read from outside iTop
+
+
+ cmdbAbstractObject
+
+
+
+ The object unarchived
+ DBObject
+
+
+ Debug string
+ string
+
+
+
Document downloaded
diff --git a/core/csvbulkexport.class.inc.php b/core/csvbulkexport.class.inc.php
index 0e4ded3460..ae9cd9eb5c 100644
--- a/core/csvbulkexport.class.inc.php
+++ b/core/csvbulkexport.class.inc.php
@@ -340,6 +340,7 @@ EOF
$sField = '';
$oObj = $aRow[$sAlias];
+ $oObj->FireEventReadDetails();
if ($oObj != null) {
switch ($sAttCode) {
case 'id':
diff --git a/core/dbobject.class.php b/core/dbobject.class.php
index 9c82be25a2..1c9a91d2a9 100644
--- a/core/dbobject.class.php
+++ b/core/dbobject.class.php
@@ -6247,7 +6247,9 @@ abstract class DBObject implements iDisplay
}
/**
+ * @param array $aChanges
* @param bool $bIsNew
+ * @param string|null $sStimulusBeingApplied
*
* @return void
* @since 3.1.0
@@ -6256,6 +6258,18 @@ abstract class DBObject implements iDisplay
{
}
+ //////////////
+ /// READ
+ ///
+
+ /**
+ * @return void
+ * @since 3.3.0
+ */
+ public function FireEventReadDetails(): void
+ {
+ }
+
//////////////
/// DELETE
///
diff --git a/core/excelbulkexport.class.inc.php b/core/excelbulkexport.class.inc.php
index 8cf9be44e1..7987603f98 100644
--- a/core/excelbulkexport.class.inc.php
+++ b/core/excelbulkexport.class.inc.php
@@ -293,6 +293,7 @@ EOF
$sAttCode = $aFieldSpec['sAttCode'];
$oObj = $aRow[$sAlias];
+ $oObj->FireEventReadDetails();
$sField = '';
if ($oObj) {
$sField = $this->GetValue($oObj, $sAttCode);
diff --git a/core/htmlbulkexport.class.inc.php b/core/htmlbulkexport.class.inc.php
index b0d4a93484..0c5a1c92a0 100644
--- a/core/htmlbulkexport.class.inc.php
+++ b/core/htmlbulkexport.class.inc.php
@@ -144,6 +144,7 @@ class HTMLBulkExport extends TabularBulkExport
$sAttCode = $aFieldSpec['sAttCode'];
$oObj = $aRow[$sAlias];
+ $oObj->FireEventReadDetails();
$sField = '';
if ($oObj) {
$sField = $this->GetValue($oObj, $sAttCode);
diff --git a/core/restservices.class.inc.php b/core/restservices.class.inc.php
index 02bf355f8d..a5896ca1ce 100644
--- a/core/restservices.class.inc.php
+++ b/core/restservices.class.inc.php
@@ -531,6 +531,7 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
}
while ($oObject = $oObjectSet->Fetch()) {
+ $oObject->FireEventReadDetails();
$oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
}
$oResult->message = "Found: ".$oObjectSet->Count();
@@ -605,6 +606,7 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
if ($oElement instanceof RelationObjectNode) {
$oObject = $oElement->GetProperty('object');
if ($oObject) {
+ $oObject->FireEventReadDetails();
if ($bEnableRedundancy && $sDirection == 'down') {
// Add only the "reached" objects
if ($oElement->GetProperty('is_reached')) {
diff --git a/core/spreadsheetbulkexport.class.inc.php b/core/spreadsheetbulkexport.class.inc.php
index 2006729ba0..664bf16baa 100644
--- a/core/spreadsheetbulkexport.class.inc.php
+++ b/core/spreadsheetbulkexport.class.inc.php
@@ -233,7 +233,6 @@ EOF
public function GetNextChunk(&$aStatus)
{
$sRetCode = 'run';
- $iPercentage = 0;
$oSet = new DBObjectSet($this->oSearch);
$oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']);
@@ -261,6 +260,7 @@ EOF
$sField = '';
/** @var \DBObject $oObj */
$oObj = $aRow[$sAlias];
+ $oObj->FireEventReadDetails();
if ($oObj == null) {
$sData .= " | ";
continue;
diff --git a/core/xmlbulkexport.class.inc.php b/core/xmlbulkexport.class.inc.php
index c31968f3d1..c361b1d867 100644
--- a/core/xmlbulkexport.class.inc.php
+++ b/core/xmlbulkexport.class.inc.php
@@ -146,6 +146,7 @@ class XMLBulkExport extends BulkExport
}
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
$oObj = $aObjects[$sAlias];
+ $oObj->FireEventReadDetails();
if (is_null($oObj)) {
$sData .= "<$sClassName alias=\"$sAlias\" id=\"null\">\n";
} else {