N°4741 - Factorize activation of on mention triggers

This commit is contained in:
Molkobain
2022-03-06 11:54:39 +01:00
parent 2fab7de34b
commit 2299983db3

View File

@@ -2936,52 +2936,7 @@ abstract class DBObject implements iDisplay
}
// - TriggerOnObjectMention
// 1 - Check if any caselog updated
$aChanges = $this->m_aOrigValues;
$aUpdatedLogAttCodes = array();
foreach($aChanges as $sAttCode => $value)
{
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
if($oAttDef instanceof AttributeCaseLog && $value->GetModifiedEntry() !== '')
{
$aUpdatedLogAttCodes[] = $sAttCode;
}
}
// 2 - Find mentioned objects
$aMentionedObjects = array();
foreach ($aUpdatedLogAttCodes as $sAttCode) {
/** @var \ormCaseLog $oUpdatedCaseLog */
$oUpdatedCaseLog = $this->Get($sAttCode);
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
}
// 3 - Trigger for those objects
// TODO: This should be refactored and moved into the caselogs loop, otherwise, we won't be able to know which case log triggered the action.
foreach ($aMentionedObjects as $sMentionedClass => $aMentionedIds) {
foreach ($aMentionedIds as $sMentionedId) {
/** @var \DBObject $oMentionedObject */
$oMentionedObject = MetaModel::GetObject($sMentionedClass, $sMentionedId);
$aTriggerArgs = $this->ToArgs('this') + array('mentioned->object()' => $oMentionedObject);
$aParams = array('class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), array(), $aParams);
while ($oTrigger = $oSet->Fetch())
{
/** @var \TriggerOnObjectMention $oTrigger */
try {
// Ensure to handle only mentioned object in the trigger's scope
if ($oTrigger->IsMentionedObjectInScope($oMentionedObject) === false) {
continue;
}
$oTrigger->DoActivate($aTriggerArgs);
}
catch (Exception $e) {
utils::EnrichRaisedException($oTrigger, $e);
}
}
}
}
$this->ActivateOnMentionTriggers(true);
return $this->m_iKey;
}
@@ -3245,50 +3200,7 @@ abstract class DBObject implements iDisplay
// Activate any existing trigger
$sClass = get_class($this);
// - TriggerOnObjectMention
// 1 - Check if any caselog updated
$aUpdatedLogAttCodes = array();
foreach($aChanges as $sAttCode => $value)
{
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
if($oAttDef instanceof AttributeCaseLog)
{
$aUpdatedLogAttCodes[] = $sAttCode;
}
}
// 2 - Find mentioned objects
$aMentionedObjects = array();
foreach ($aUpdatedLogAttCodes as $sAttCode) {
/** @var \ormCaseLog $oUpdatedCaseLog */
$oUpdatedCaseLog = $this->Get($sAttCode);
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
}
// 3 - Trigger for those objects
// TODO: This should be refactored and moved into the caselogs loop, otherwise, we won't be able to know which case log triggered the action.
foreach ($aMentionedObjects as $sMentionedClass => $aMentionedIds) {
foreach ($aMentionedIds as $sMentionedId) {
/** @var \DBObject $oMentionedObject */
$oMentionedObject = MetaModel::GetObject($sMentionedClass, $sMentionedId);
$aTriggerArgs = $this->ToArgs('this') + array('mentioned->object()' => $oMentionedObject);
$aParams = array('class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), array(), $aParams);
while ($oTrigger = $oSet->Fetch())
{
/** @var \TriggerOnObjectMention $oTrigger */
try {
// Ensure to handle only mentioned object in the trigger's scope
if ($oTrigger->IsMentionedObjectInScope($oMentionedObject) === false) {
continue;
}
$oTrigger->DoActivate($aTriggerArgs);
}
catch (Exception $e) {
utils::EnrichRaisedException($oTrigger, $e);
}
}
}
}
$this->ActivateOnMentionTriggers(false);
$bHasANewExternalKeyValue = false;
$aHierarchicalKeys = array();
@@ -3501,6 +3413,74 @@ abstract class DBObject implements iDisplay
return $this->m_iKey;
}
/**
* Activate TriggerOnObjectMention triggers for the current object
*
* @param bool $bNewlyCreatedObject
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @throws \OQLException
* @since 3.0.1 N°4741
*/
private function ActivateOnMentionTriggers(bool $bNewlyCreatedObject): void
{
$sClass = get_class($this);
$aChanges = $bNewlyCreatedObject ? $this->m_aOrigValues : $this->ListChanges();
// 1 - Check if any caselog updated
$aUpdatedLogAttCodes = [];
foreach ($aChanges as $sAttCode => $value) {
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
if ($oAttDef instanceof AttributeCaseLog) {
// Skip empty log on creation
if ($bNewlyCreatedObject && $value->GetModifiedEntry() === '') {
continue;
}
$aUpdatedLogAttCodes[] = $sAttCode;
}
}
// 2 - Find mentioned objects
$aMentionedObjects = [];
foreach ($aUpdatedLogAttCodes as $sAttCode) {
/** @var \ormCaseLog $oUpdatedCaseLog */
$oUpdatedCaseLog = $this->Get($sAttCode);
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
}
// 3 - Trigger for those objects
// TODO: This should be refactored and moved into the caselogs loop, otherwise, we won't be able to know which case log triggered the action.
foreach ($aMentionedObjects as $sMentionedClass => $aMentionedIds) {
foreach ($aMentionedIds as $sMentionedId) {
/** @var \DBObject $oMentionedObject */
$oMentionedObject = MetaModel::GetObject($sMentionedClass, $sMentionedId);
$aTriggerArgs = $this->ToArgs('this') + ['mentioned->object()' => $oMentionedObject];
$aParams = ['class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL)];
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), [], $aParams);
while ($oTrigger = $oSet->Fetch())
{
/** @var \TriggerOnObjectMention $oTrigger */
try {
// Ensure to handle only mentioned object in the trigger's scope
if ($oTrigger->IsMentionedObjectInScope($oMentionedObject) === false) {
continue;
}
$oTrigger->DoActivate($aTriggerArgs);
}
catch (Exception $e) {
utils::EnrichRaisedException($oTrigger, $e);
}
}
}
}
}
/**
* @internal
* Save updated fields previous values for {@see DBObject::DBUpdate()} callbacks