diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php
index 590495ded..a42c0b5a5 100644
--- a/application/cmdbabstract.class.inc.php
+++ b/application/cmdbabstract.class.inc.php
@@ -4533,8 +4533,6 @@ HTML;
}
} finally {
if (static::IsCrudStackEmpty()) {
- // Avoid signaling the current object that links were modified
- static::RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
static::FireEventDbLinksChangedForAllObjects();
}
}
@@ -5811,6 +5809,7 @@ JS
final protected function FireEventCreateDone(): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
+ $this->FireEventDbLinksChangedForCurrentObject();
$this->FireEvent(EVENT_DB_CREATE_DONE);
}
@@ -5829,6 +5828,7 @@ JS
final protected function FireEventUpdateDone(array $aChanges): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
+ $this->FireEventDbLinksChangedForCurrentObject();
$this->FireEvent(EVENT_DB_UPDATE_DONE, ['changes' => $aChanges]);
}
@@ -5857,6 +5857,7 @@ JS
final protected function FireEventDeleteDone(): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
+ $this->FireEventDbLinksChangedForCurrentObject();
$this->FireEvent(EVENT_DB_DELETE_DONE);
}
@@ -5955,11 +5956,24 @@ JS
return;
}
- $oObject = MetaModel::GetObject($sClass, $sId);
+ // First we are disabling firing the event to avoid reentrance
+ // For example on a Ticket :
+ // - in the Ticket CRUD stack, DBWriteLinks will generate lnkApplicationSolutionToFunctionalCI instances
+ // - therefore the $aObjectsAwaitingEventDbLinksChanged attribute will contain our Ticket
+ // - we have a EVENT_DB_LINKS_CHANGED listener on Ticket that will update impacted items, so it will create new lnkApplicationSolutionToFunctionalCI
+ // We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
+ // By disabling the event to be fired, we can remove the current object from the attribute !
+ /** @noinspection PhpRedundantOptionalArgumentInspection */
+ $oObject = MetaModel::GetObject($sClass, $sId, true);
+ self::SetEventDBLinksChangedBlocked(true);
+ MetaModel::StartReentranceProtection($oObject);
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
-
- // The event listeners might have generated new lnk instances pointing to this object, so removing object from stack to avoid reentrance
+ MetaModel::StopReentranceProtection($oObject);
+ if ($oObject->IsModified()) {
+ $oObject->DBUpdate();
+ }
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
+ cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);
}
/**
diff --git a/datamodels/2.x/itop-change-mgmt-itil/datamodel.itop-change-mgmt-itil.xml b/datamodels/2.x/itop-change-mgmt-itil/datamodel.itop-change-mgmt-itil.xml
index 3c1ed44d1..19868bfb5 100755
--- a/datamodels/2.x/itop-change-mgmt-itil/datamodel.itop-change-mgmt-itil.xml
+++ b/datamodels/2.x/itop-change-mgmt-itil/datamodel.itop-change-mgmt-itil.xml
@@ -1022,8 +1022,7 @@
UpdateImpactedItems();
+ parent::OnInsert();
$this->SetIfNull('creation_date', time());
$this->SetIfNull('last_update', time());
}]]>
@@ -1036,11 +1035,6 @@
protected function OnUpdate()
{
parent::OnUpdate();
- $aChanges = $this->ListChanges();
- if (array_key_exists('functionalcis_list', $aChanges))
- {
- $this->UpdateImpactedItems();
- }
$this->Set('last_update', time());
}]]>
diff --git a/datamodels/2.x/itop-change-mgmt/datamodel.itop-change-mgmt.xml b/datamodels/2.x/itop-change-mgmt/datamodel.itop-change-mgmt.xml
index 7e810881d..9257d2bc4 100755
--- a/datamodels/2.x/itop-change-mgmt/datamodel.itop-change-mgmt.xml
+++ b/datamodels/2.x/itop-change-mgmt/datamodel.itop-change-mgmt.xml
@@ -581,8 +581,7 @@
UpdateImpactedItems();
+ parent::OnInsert();
$this->SetIfNull('creation_date', time());
$this->SetIfNull('last_update', time());
}]]>
@@ -594,12 +593,7 @@
ListChanges();
- if (array_key_exists('functionalcis_list', $aChanges))
- {
- $this->UpdateImpactedItems();
- }
+ parent::OnUpdate();
$this->Set('last_update', time());
}]]>
diff --git a/datamodels/2.x/itop-incident-mgmt-itil/datamodel.itop-incident-mgmt-itil.xml b/datamodels/2.x/itop-incident-mgmt-itil/datamodel.itop-incident-mgmt-itil.xml
index c436eb272..d7bc535d5 100755
--- a/datamodels/2.x/itop-incident-mgmt-itil/datamodel.itop-incident-mgmt-itil.xml
+++ b/datamodels/2.x/itop-incident-mgmt-itil/datamodel.itop-incident-mgmt-itil.xml
@@ -1496,12 +1496,7 @@
Overload-DBObject
ListChanges();
- if (array_key_exists('functionalcis_list', $aChanges))
- {
- $this->UpdateImpactedItems();
- }
+ parent::OnUpdate();
$this->Set('last_update', time());
$this->UpdateChildRequestLog();
$this->UpdateChildIncidentLog();
diff --git a/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml b/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml
index b07c6b6ba..0f8eb7fdc 100755
--- a/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml
+++ b/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml
@@ -1567,11 +1567,6 @@
protected function OnUpdate()
{
parent::OnUpdate();
- $aChanges = $this->ListChanges();
- if (array_key_exists('functionalcis_list', $aChanges))
- {
- $this->UpdateImpactedItems();
- }
$this->Set('last_update', time());
$this->UpdateChildRequestLog();
}]]>
diff --git a/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml b/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml
index 9531732e7..a3f6c14e0 100755
--- a/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml
+++ b/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml
@@ -1610,12 +1610,7 @@
ListChanges();
- if (array_key_exists('functionalcis_list', $aChanges))
- {
- $this->UpdateImpactedItems();
- }
+ parent::OnUpdate();
$this->Set('last_update', time());
$this->UpdateChildRequestLog();
}]]>
diff --git a/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml b/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml
index d78f9f9db..2c4d3819e 100755
--- a/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml
+++ b/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml
@@ -223,23 +223,11 @@
EVENT_DB_LINKS_CHANGED
- UpdateTicketImpactedItems
+ UpdateImpactedItems
0
-
-
- false
- public
- EventListener
- UpdateImpactedItems();
- $this->DBUpdate();
-}
- ]]>
-
false
public
diff --git a/tests/php-unit-tests/unitary-tests/application/cmdbAbstractObjectTest.php b/tests/php-unit-tests/unitary-tests/application/cmdbAbstractObjectTest.php
index f2395d9a0..e2d90b7de 100644
--- a/tests/php-unit-tests/unitary-tests/application/cmdbAbstractObjectTest.php
+++ b/tests/php-unit-tests/unitary-tests/application/cmdbAbstractObjectTest.php
@@ -195,8 +195,8 @@ class cmdbAbstractObjectTest extends ItopDataTestCase {
$oTeam->DBInsert();
$this->assertIsObject($oTeam);
- // 3 links added to person (the Team side is ignored)
- $this->assertEquals(3, self::$aEventCalls[EVENT_DB_LINKS_CHANGED]);
+ // 3 links added to person + 1 for the Team
+ $this->assertEquals(4, self::$aEventCalls[EVENT_DB_LINKS_CHANGED]);
}
/**