N°2875 - Default triggers/action are created during first install/upgrade of 3.0.0 for DM classes with a log attribute in order to allow Person mention out of the box

This commit is contained in:
Molkobain
2021-10-19 15:15:43 +02:00
parent cdf5789d62
commit 0811fd4aa7
3 changed files with 116 additions and 2 deletions

View File

@@ -95,6 +95,111 @@ if (!class_exists('StructureInstaller'))
*/
public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
{
if (version_compare($sPreviousVersion, '3.1.0', '<'))
{
SetupLog::Info("Adding default triggers/action for Person objects mentions. All DM classes with at least 1 log attribute will be concerned...");
$sPersonClass = 'Person';
$sPersonStateAttCode = MetaModel::GetStateAttributeCode($sPersonClass);
$sPersonOwnerOrgAttCode = UserRightsProfile::GetOwnerOrganizationAttCode($sPersonClass);
$iClassesWithLogCount = 0;
$aCreatedTriggerIds = [];
foreach (MetaModel::EnumRootClasses() as $sRootClass) {
foreach (MetaModel::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_ALL, true) as $sClass) {
$aLogAttCodes = MetaModel::GetAttributesList($sClass, ['AttributeCaseLog']);
// Skip class with log attribute
if (count($aLogAttCodes) === 0) {
continue;
}
// Prepare the mentioned_filter OQL
$oPersonSearch = DBObjectSearch::FromOQL("SELECT $sPersonClass");
// - Add status condition if attribute present
if (empty($sPersonStateAttCode) === false) {
$oPersonSearch->AddConditionExpression(new BinaryExpression(
new FieldExpression($sPersonStateAttCode),
'=',
new ScalarExpression('active')
));
}
// - Check if the classes have a silo attribute so we can use them in the mentioned_filter
if (empty($sPersonOwnerOrgAttCode) === false) {
// Filter on current contact org.
$oCurrentContactExpr = new BinaryExpression(
new FieldExpression($sPersonOwnerOrgAttCode),
'=',
new VariableExpression("current_contact->org_id")
);
// Filter on class owner org. if any
$sClassOwnerOrgAttCode = UserRightsProfile::GetOwnerOrganizationAttCode($sClass);
$oOwnerOrgExpr = empty($sClassOwnerOrgAttCode) ? null : new BinaryExpression(
new FieldExpression($sPersonOwnerOrgAttCode),
'=',
new VariableExpression("this->$sClassOwnerOrgAttCode")
);
// No owner org, simple condition
if ($oOwnerOrgExpr === null) {
$oPersonSearch->AddConditionExpression($oCurrentContactExpr);
}
// Owner org, condition is either from owner org or current contact's
else {
$oOrExpr = new BinaryExpression($oCurrentContactExpr, 'OR', $oOwnerOrgExpr);
$oPersonSearch->AddConditionExpression($oOrExpr);
}
}
// Build the trigger
$oTrigger = MetaModel::NewObject('TriggerOnObjectMention');
$oTrigger->Set('description', 'Person mentioned on '.$sClass);
$oTrigger->Set('target_class', $sClass);
$oTrigger->Set('mentioned_filter', $oPersonSearch->ToOQL());
$oTrigger->DBInsert();
SetupLog::Info("|- Created trigger \"{$oTrigger->Get('description')}\" for class $sClass.");
$aCreatedTriggerIds[] = $oTrigger->GetKey();
$iClassesWithLogCount++;
// Note: We break because we only have to create one trigger/action for the class hierarchy as it will be for all their log attributes
break;
}
}
// Build the corresponding action and link it to the triggers
if (count($aCreatedTriggerIds) > 0) {
$oAction = MetaModel::NewObject('ActionEmail');
$oAction->Set('name', 'Email mentioned person');
$oAction->Set('status', 'enabled');
$oAction->Set('from', '$current_contact->email$');
$oAction->Set('to', 'SELECT Person WHERE id = :mentioned->id');
$oAction->Set('subject', 'You have been mentioned in "$this->friendlyname$"');
$oAction->Set('body', '<p>Hello $mentioned->first_name$,</p>
<p>You have been mentioned by $current_contact->friendlyname$ in $this->hyperlink()$</p>'
);
/** @var \ormLinkSet $oOrm */
$oOrm = $oAction->Get('trigger_list');
foreach ($aCreatedTriggerIds as $sTriggerId) {
$oLink = new lnkTriggerAction();
$oLink->Set('trigger_id', $sTriggerId);
$oOrm->AddItem($oLink);
}
$oAction->Set('trigger_list', $oOrm);
$oAction->DBInsert();
SetupLog::Info("|- Created action \"{$oAction->Get('name')}\" and linked it to the previously created triggers.");
}
if ($iClassesWithLogCount === 0) {
SetupLog::Info("... no trigger/action created as there is no DM class with a log attribute.");
} else {
SetupLog::Info("... default triggers/action successfully created for $iClassesWithLogCount classes.");
}
}
}
}
}

View File

@@ -2415,6 +2415,7 @@ EOF
$sMarker = utils::ReadParam('marker', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$sNeedle = utils::ReadParam('needle', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$sHostClass = utils::ReadParam('host_class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
$iHostId = (int) utils::ReadParam('host_id', 0, false, utils::ENUM_SANITIZATION_FILTER_INTEGER);
// Check parameters
if($sMarker === '') {
@@ -2439,6 +2440,13 @@ EOF
// Retrieve restricting scopes from triggers if any
if (strlen($sHostClass) > 0) {
if ($iHostId > 0) {
$oHostObj = MetaModel::GetObject($sHostClass, $iHostId);
} else {
// Object is being created, use a dummy object as we have no way to recreate it
$oHostObj = MetaModel::NewObject($sHostClass);
}
$aTriggerMentionedSearches = [];
$aTriggerSetParams = array('class_list' => MetaModel::EnumParentClasses($sHostClass, ENUM_PARENT_CLASSES_ALL));
@@ -2479,7 +2487,7 @@ EOF
new BinaryExpression(new FieldExpression('friendlyname', $sSearchMainClassAlias), 'LIKE', new VariableExpression('needle'))
);
$oSet = new DBObjectSet($oSearch, array(), array('needle' => "%$sNeedle%"));
$oSet = new DBObjectSet($oSearch, array(), array('needle' => "%$sNeedle%", 'this' => $oHostObj));
$oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => array()));
$oSet->SetLimit(MetaModel::GetConfig()->Get('max_autocomplete_results'));
// Note: We have to this manually because of a bug in DBSearch not checking the user prefs. by default.

View File

@@ -210,7 +210,8 @@ class CaseLogEntryForm extends UIContentBlock
if (isset($aConfig['mentions'])) {
foreach ($aConfig['mentions'] as $iIdx => $aData) {
$sFeed = $aConfig['mentions'][$iIdx]['feed'];
$aConfig['mentions'][$iIdx]['feed'] = utils::AddParameterToUrl($sFeed, 'host_class', $this->GetObjectClass());
$sFeed = utils::AddParameterToUrl($sFeed, 'host_class', $this->GetObjectClass());
$aConfig['mentions'][$iIdx]['feed'] = utils::AddParameterToUrl($sFeed, 'host_id', $this->GetObjectId());
}
}
$this->oTextInput->SetConfig($aConfig);