From 54a1221e4a0b30da884b2f20a81df576dbfa304d Mon Sep 17 00:00:00 2001 From: jf-cbd <121934370+jf-cbd@users.noreply.github.com> Date: Mon, 17 Aug 2026 10:37:40 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B08123=20-=20Improve=20on=20mention=20data?= =?UTF-8?q?=20parsing=20(#749)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/utils.inc.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/application/utils.inc.php b/application/utils.inc.php index f8fe7a1842..4f0ded9679 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -3022,7 +3022,6 @@ TXT * Note: Only works for backoffice URLs for now * * @param string $sText Text containing the mentioned objects to be found - * @param string $sFormat {@uses static::ENUM_TEXT_FORMAT_HTML, ...} * * @return array Array of object classes / IDs for the ones found in $sText * @@ -3037,15 +3036,23 @@ TXT public static function GetMentionedObjectsFromText(string $sText): array { $aMentionedObjects = []; - $aMentionMatches = []; - $sText = html_entity_decode($sText); - $aMentionAllowedClasses = MetaModel::GetConfig()->Get('mentions.allowed_classes'); - preg_match_all('/]*)data-object-class="([^"]*)"\s.*data-object-key="([^"]*)"\s*([^>]*)>(.*)<\/a>/Ui', $sText, $aMentionMatches); - foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) { - $sMatchedClass = $aMentionMatches[2][$iMatchIdx]; - $sMatchedId = $aMentionMatches[3][$iMatchIdx]; - $sMatchedName = $aMentionMatches[5][$iMatchIdx]; + $oDom = new \DOMDocument(); + $bPreviousUseInternalErrors = libxml_use_internal_errors(true); // to keep processing even in case of "invalid" HTML, cf. testGetMentionedObjectsFromText + + try { + $oDom->loadHTML(''.$sText); + } finally { + libxml_clear_errors(); + libxml_use_internal_errors($bPreviousUseInternalErrors); + } + $oXpath = new \DOMXPath($oDom); + $oNodes = $oXpath->query('//a[@data-object-class and @data-object-key]'); + + foreach ($oNodes as $oObjNode) { + $sMatchedClass = $oObjNode->getAttribute('data-object-class'); + $sMatchedId = $oObjNode->getAttribute('data-object-key'); + $sMatchedName = trim($oObjNode->textContent); // Ensure that what we found is actually configured as a mention $sMentionPrefix = array_search($sMatchedClass, $aMentionAllowedClasses);