diff --git a/application/utils.inc.php b/application/utils.inc.php
index 2292b5a29..1c45e7121 100644
--- a/application/utils.inc.php
+++ b/application/utils.inc.php
@@ -2638,9 +2638,21 @@ class utils
if(!empty($aMentionsAllowedClasses)) {
$aDefaultConf['mentions'] = [];
- foreach($aMentionsAllowedClasses as $sMentionChar => $sMentionClass) {
+ foreach($aMentionsAllowedClasses as $sMentionMarker => $sMentionScope) {
+ // Retrieve mention class
+ // - First test if the conf is a simple Datamodel class
+ if (MetaModel::IsValidClass($sMentionScope)) {
+ $sMentionClass = $sMentionScope;
+ }
+ // - Otherwise it must be a valid OQL
+ else {
+ $oTmpSearch = DBSearch::FromOQL($sMentionScope);
+ $sMentionClass = $oTmpSearch->GetClass();
+ unset($oTmpSearch);
+ }
+
// Note: Endpoints are defaults only and should be overloaded by other GUIs such as the end-users portal
- $sMentionEndpoint = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=cke_mentions&target_class='.$sMentionClass.'&needle={encodedQuery}';
+ $sMentionEndpoint = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=cke_mentions&marker='.$sMentionMarker.'&needle={encodedQuery}';
$sMentionItemUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class='.$sMentionClass.'&id={id}';
$sMentionItemPictureTemplate = (empty(MetaModel::GetImageAttributeCode($sMentionClass))) ? '' : <<{$sMentionItemPictureTemplate}{friendlyname}
HTML;
$sMentionOutputTemplate = <<{$sMentionChar}{friendlyname}
+{$sMentionMarker}{friendlyname}
HTML;
$aDefaultConf['mentions'][] = [
'feed' => $sMentionEndpoint,
- 'marker' => $sMentionChar,
+ 'marker' => $sMentionMarker,
'minChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'),
'itemTemplate' => $sMentionItemTemplate,
'outputTemplate' => $sMentionOutputTemplate,
diff --git a/core/config.class.inc.php b/core/config.class.inc.php
index 98625aff5..c327d7b40 100644
--- a/core/config.class.inc.php
+++ b/core/config.class.inc.php
@@ -1287,9 +1287,9 @@ class Config
],
'mentions.allowed_classes' => [
'type' => 'array',
- 'description' => 'Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete (eg. "@" => "Person")',
+ 'description' => 'Classes which can be mentioned through the autocomplete in the caselogs. Key of the array must be a single character that will trigger the autocomplete, value can be either a DM class or a valid OQL (eg. "@" => "Person", "?" => "SELECT FAQ WHERE status = \'published\')',
'default' => [
- '@' => 'Person',
+ '@' => 'SELECT Person WHERE status = \'active\'',
],
'value' => false,
'source_of_value' => '',
diff --git a/pages/ajax.render.php b/pages/ajax.render.php
index 257dcffe3..587b193f4 100644
--- a/pages/ajax.render.php
+++ b/pages/ajax.render.php
@@ -2677,19 +2677,38 @@ EOF
// TODO 3.0.0: Move this to new ajax render controller?
case 'cke_mentions':
$oPage->SetContentType('application/json');
- $sTargetClass = utils::ReadParam('target_class', '', false, 'class');
+ $sMarker = utils::ReadParam('marker', '', false, 'raw_data');
$sNeedle = utils::ReadParam('needle', '', false, 'raw_data');
// Check parameters
- if($sTargetClass === '') {
- throw new Exception('Invalid parameters, target_class must be specified.');
+ if($sMarker === '') {
+ throw new Exception('Invalid parameters, marker must be specified.');
+ }
+
+ $aMentionsAllowedClasses = MetaModel::GetConfig()->Get('mentions.allowed_classes');
+ if (isset($aMentionsAllowedClasses[$sMarker]) === false) {
+ throw new Exception('Invalid marker "'.$sMarker.'"');
}
$aMatches = array();
if ($sNeedle !== '') {
- $sObjectImageAttCode = MetaModel::GetImageAttributeCode($sTargetClass);
+ // Retrieve scope from marker
+ $sScope = $aMentionsAllowedClasses[$sMarker];
+ if (MetaModel::IsValidClass($sScope)) {
+ $sScope = "SELECT $sScope";
+ }
+ $oSearch = DBSearch::FromOQL($sScope);
- $oSearch = DBObjectSearch::FromOQL("SELECT $sTargetClass WHERE friendlyname LIKE :needle");
+ $sSearchMainClassName = $oSearch->GetClass();
+ $sSearchMainClassAlias = $oSearch->GetClassAlias();
+
+ $sObjectImageAttCode = MetaModel::GetImageAttributeCode($sSearchMainClassName);
+
+ // Add condition to filter on the friendlyname
+ $oSearch->AddConditionExpression(
+ new BinaryExpression(new FieldExpression('friendlyname', $sSearchMainClassAlias), 'LIKE', new VariableExpression('needle'))
+ );
+ //$oSearch = DBObjectSearch::FromOQL("SELECT $sMarker WHERE friendlyname LIKE :needle");
$oSet = new DBObjectSet($oSearch, array(), array('needle' => "%$sNeedle%"));
$oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => array()));
$oSet->SetLimit(MetaModel::GetConfig()->Get('max_autocomplete_results'));
@@ -2712,7 +2731,7 @@ EOF
/** @var \ormDocument $oImage */
$oImage = $oObject->Get($sObjectImageAttCode);
if (!$oImage->IsEmpty()) {
- $aMatch['picture_url'] = $oImage->GetDisplayURL($sTargetClass, $iObjectId, $sObjectImageAttCode);
+ $aMatch['picture_url'] = $oImage->GetDisplayURL($sObjectClass, $iObjectId, $sObjectImageAttCode);
}
}