Compare commits

...

4 Commits

Author SHA1 Message Date
Eric Espie
a7517298c5 N°9617 - Send EVENT on data export for traceability - After Review 2026-07-09 15:49:45 +02:00
Eric Espie
7663be6e6e N°9617 - Send EVENT on data export for traceability 2026-07-09 15:37:52 +02:00
Eric Espie
574b7579c8 N°9617 - Send events on data export for traceability 2026-07-09 14:15:45 +02:00
Eric Espie
6a5f83e767 N°9617 - Send events on data export for traceability
# Conflicts:
#	core/restservices.class.inc.php
2026-07-09 14:15:41 +02:00
10 changed files with 99 additions and 4 deletions

View File

@@ -5368,6 +5368,7 @@ JS
/**
* @param array $aChanges
* @param bool $bIsNew
* @param string|null $sStimulusBeingApplied
*
* @return void
* @throws \ArchivedObjectException
@@ -5381,6 +5382,20 @@ 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(string $sExportType): void
{
$this->FireEvent(EVENT_DATA_EXPORT, ['export_type' => $sExportType]);
}
//////////////
/// DELETE
///

View File

@@ -519,6 +519,31 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
</event_datum>
</event_data>
</event>
<event id="EVENT_DATA_EXPORT" _delta="define">
<name>Object details read from outside iTop</name>
<description><![CDATA[An object details has been read during an export]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object unarchived</description>
<type>DBObject</type>
</event_datum>
<event_datum id="attributes">
<description>Attribute codes exposed (empty means potentially all attributes)</description>
<type>array</type>
</event_datum>
<event_datum id="export_type">
<description>Type of export</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DOWNLOAD_DOCUMENT" _delta="define">
<name>Document downloaded</name>
<description><![CDATA[A document has been downloaded from the GUI]]></description>

View File

@@ -334,12 +334,14 @@ EOF
while ($aRow = $oSet->FetchAssoc()) {
set_time_limit(intval($iLoopTimeLimit));
$aData = [];
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
$aExportedObjects = [];
foreach ($this->aStatusInfo['fields'] as $aFieldSpec) {
$sAlias = $aFieldSpec['sAlias'];
$sAttCode = $aFieldSpec['sAttCode'];
$sField = '';
$oObj = $aRow[$sAlias];
$aExportedObjects[] = $oObj;
if ($oObj != null) {
switch ($sAttCode) {
case 'id':
@@ -366,7 +368,13 @@ EOF
}
$sData .= implode($this->aStatusInfo['separator'], $aData)."\n";
$iCount++;
$aExportedObjects = array_unique($aExportedObjects);
foreach ($aExportedObjects as $oExportedObject) {
$oExportedObject->FireEventReadDetails(get_class($this));
}
}
// Restore original date & time formats
AttributeDateTime::SetFormat($oPrevDateTimeFormat);
AttributeDate::SetFormat($oPrevDateFormat);

View File

@@ -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(string $sExportType): void
{
}
//////////////
/// DELETE
///

View File

@@ -288,11 +288,13 @@ EOF
while ($aRow = $oSet->FetchAssoc()) {
set_time_limit(intval($iLoopTimeLimit));
$aData = [];
$aExportedObjects = [];
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
$sAlias = $aFieldSpec['sAlias'];
$sAttCode = $aFieldSpec['sAttCode'];
$oObj = $aRow[$sAlias];
$aExportedObjects[] = $oObj;
$sField = '';
if ($oObj) {
$sField = $this->GetValue($oObj, $sAttCode);
@@ -301,6 +303,11 @@ EOF
}
fwrite($hFile, json_encode($aData)."\n");
$iCount++;
$aExportedObjects = array_unique($aExportedObjects);
foreach ($aExportedObjects as $oExportedObject) {
$oExportedObject->FireEventReadDetails(get_class($this));
}
}
set_time_limit(intval($iPreviousTimeLimit));
$this->aStatusInfo['position'] += $this->iChunkSize;

View File

@@ -139,6 +139,7 @@ class HTMLBulkExport extends TabularBulkExport
} else {
$sData .= "<tr>";
}
$aExportedObjects = [];
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
$sAlias = $aFieldSpec['sAlias'];
$sAttCode = $aFieldSpec['sAttCode'];
@@ -147,12 +148,18 @@ class HTMLBulkExport extends TabularBulkExport
$sField = '';
if ($oObj) {
$sField = $this->GetValue($oObj, $sAttCode);
$aExportedObjects[] = $oObj;
}
$sValue = ($sField === '') ? '&nbsp;' : $sField;
$sData .= "<td>$sValue</td>";
}
$sData .= "</tr>";
$iCount++;
$aExportedObjects = array_unique($aExportedObjects);
foreach ($aExportedObjects as $oExportedObject) {
$oExportedObject->FireEventReadDetails(get_class($this));
}
}
set_time_limit(intval($iPreviousTimeLimit));
$this->aStatusInfo['position'] += $this->iChunkSize;

View File

@@ -625,6 +625,7 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
}
while ($oObject = $oObjectSet->Fetch()) {
$oObject->FireEventReadDetails(get_class($this));
$oResult->AddObject(0, '', $oObject, $aShowFields, RestUtils::HasRequestedExtendedOutput($sShowFields));
}
$oResult->message = "Found: ".$oObjectSet->Count();
@@ -699,6 +700,7 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
if ($oElement instanceof RelationObjectNode) {
$oObject = $oElement->GetProperty('object');
if ($oObject) {
$oObject->FireEventReadDetails(get_class($this));
if ($bEnableRedundancy && $sDirection == 'down') {
// Add only the "reached" objects
if ($oElement->GetProperty('is_reached')) {

View File

@@ -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']);
@@ -254,7 +253,8 @@ EOF
set_time_limit(intval($iLoopTimeLimit));
$sData .= "<tr>";
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
$aExportedObjects = [];
foreach ($this->aStatusInfo['fields'] as $aFieldSpec) {
$sAlias = $aFieldSpec['sAlias'];
$sAttCode = $aFieldSpec['sAttCode'];
@@ -265,7 +265,7 @@ EOF
$sData .= "<td x:str></td>";
continue;
}
$aExportedObjects[] = $oObj;
switch ($sAttCode) {
case 'id':
$sField = $oObj->GetKey();
@@ -322,6 +322,11 @@ EOF
}
$sData .= "</tr>";
$iCount++;
$aExportedObjects = array_unique($aExportedObjects);
foreach ($aExportedObjects as $oExportedObject) {
$oExportedObject->FireEventReadDetails(get_class($this));
}
}
set_time_limit(intval($iPreviousTimeLimit));
$this->aStatusInfo['position'] += $this->iChunkSize;

View File

@@ -135,6 +135,11 @@ abstract class Trigger extends cmdbAbstractObject
if ($oAction->IsActive()) {
$oKPI = new ExecutionKPI();
$aContextArgs['action->object()'] = $oAction;
if (array_key_exists('this->object()', $aContextArgs)) {
/** @var \DBObject $oObject */
$oObject = $aContextArgs['this->object()'];
$oObject->FireEventReadDetails(get_class($oAction));
}
$oAction->DoExecute($this, $aContextArgs);
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
}

View File

@@ -144,6 +144,7 @@ class XMLBulkExport extends BulkExport
if (count($aAuthorizedClasses) > 1) {
$sData .= "<Row>\n";
}
$aExportedObjects = [];
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
$oObj = $aObjects[$sAlias];
if (is_null($oObj)) {
@@ -151,6 +152,7 @@ class XMLBulkExport extends BulkExport
} else {
$sClassName = get_class($oObj);
$sData .= "<$sClassName alias=\"$sAlias\" id=\"".$oObj->GetKey()."\">\n";
$aExportedObjects[] = $oObj;
}
foreach ($aClass2Attributes[$sAlias] as $sAttCode => $oAttDef) {
if (is_null($oObj)) {
@@ -166,6 +168,11 @@ class XMLBulkExport extends BulkExport
$sData .= "</Row>\n";
}
$iCount++;
$aExportedObjects = array_unique($aExportedObjects);
foreach ($aExportedObjects as $oExportedObject) {
$oExportedObject->FireEventReadDetails(get_class($this));
}
}
set_time_limit(intval($iPreviousTimeLimit));