🐛 N°6284 - Add data-object-key

This commit is contained in:
jf-cbd
2024-12-31 15:01:36 +01:00
parent a151e40b75
commit 11fc958a7b
8 changed files with 27 additions and 47 deletions

View File

@@ -3104,29 +3104,13 @@ TXT
* @throws \Exception
* @since 3.0.0
*/
public static function GetMentionedObjectsFromText(string $sText, string $sFormat = self::ENUM_TEXT_FORMAT_HTML): array
public static function GetMentionedObjectsFromText(string $sText): array
{
// First transform text so it can be parsed
switch ($sFormat) {
case static::ENUM_TEXT_FORMAT_HTML:
$sText = static::HtmlToText($sText);
break;
$aMentionedObjects = [];
$aMentionMatches = [];
$sText = html_entity_decode($sText);
default:
// Don't transform it
break;
}
// Then parse text to find objects
$aMentionedObjects = array();
$aMentionMatches = array();
// Note: As the sanitizer (or CKEditor autocomplete plugin? 🤔) removes data-* attributes from the hyperlink,
// - we can't use the following (simpler) regexp that only checks data attributes on hyperlinks, which would have worked for hyperlinks pointing to any GUIs: '/<a\s*([^>]*)data-object-class="([^"]*)"\s*data-object-id="([^"]*)">/i'
// - instead we use a regexp to match the following pattern '[Some object label](<APP_ROOT_URL>...&class=<OBJECT_CLASS>&id=<OBJECT_ID>...)' which only works for the backoffice
// If we change the sanitizer, we might want to switch to the other regexp as it's universal and easier to read
$sAppRootUrlForRegExp = addcslashes(utils::GetAbsoluteUrlAppRoot(), '/&');
preg_match_all("/\[([^\]]*)\]\({$sAppRootUrlForRegExp}[^\)]*\&class=([^\)\&]*)\&id=([\d]*)[^\)]*\)/i", $sText, $aMentionMatches);
preg_match_all('/<a\s*([^>]*)data-object-class="([^"]*)"\s*data-object-key="([^"]*)"/i', $sText, $aMentionMatches);
foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) {
$sMatchedClass = $aMentionMatches[2][$iMatchIdx];

View File

@@ -4025,7 +4025,7 @@ abstract class DBObject implements iDisplay
foreach ($aUpdatedLogAttCodes as $sAttCode) {
/** @var \ormCaseLog $oUpdatedCaseLog */
$oUpdatedCaseLog = $this->Get($sAttCode);
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry(ormCaseLog::ENUM_FORMAT_HTML)));
}
// 3 - Trigger for those objects

View File

@@ -278,7 +278,7 @@ class HTMLDOMSanitizer extends DOMSanitizer
protected static $aTagsWhiteList = array(
'html' => array(),
'body' => array(),
'a' => array('href', 'name', 'style', 'class', 'target', 'title', 'data-role', 'data-object-class', 'data-object-id'),
'a' => array('href', 'name', 'style', 'class', 'target', 'title', 'data-role', 'data-object-class', 'data-object-id', 'data-object-key'),
'p' => array('style', 'class'),
'blockquote' => array('style', 'class'),
'br' => array(),

3
node_modules/.package-lock.json generated vendored
View File

@@ -71,7 +71,8 @@
},
"node_modules/ckeditor5-itop-build": {
"version": "3.2.0",
"resolved": "git+ssh://git@github.com/Combodo/ckeditor5-itop-build.git#7366299c6c4b659736b958c5e9496e98c22a3c36"
"resolved": "git+ssh://git@github.com/Combodo/ckeditor5-itop-build.git#7dcf9fc9b0010e121f1d8a4d28eca0219fcb6e35",
"license": "SEE LICENSE IN LICENSE.md"
},
"node_modules/clipboard": {
"version": "2.0.11",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

7
package-lock.json generated
View File

@@ -104,7 +104,8 @@
},
"node_modules/ckeditor5-itop-build": {
"version": "3.2.0",
"resolved": "git+ssh://git@github.com/Combodo/ckeditor5-itop-build.git#7366299c6c4b659736b958c5e9496e98c22a3c36"
"resolved": "git+ssh://git@github.com/Combodo/ckeditor5-itop-build.git#7dcf9fc9b0010e121f1d8a4d28eca0219fcb6e35",
"license": "SEE LICENSE IN LICENSE.md"
},
"node_modules/clipboard": {
"version": "2.0.11",
@@ -356,8 +357,8 @@
}
},
"ckeditor5-itop-build": {
"version": "git+ssh://git@github.com/Combodo/ckeditor5-itop-build.git#7366299c6c4b659736b958c5e9496e98c22a3c36",
"from": "ckeditor5-itop-build@github:Combodo/ckeditor5-itop-build"
"version": "git+ssh://git@github.com/Combodo/ckeditor5-itop-build.git#7dcf9fc9b0010e121f1d8a4d28eca0219fcb6e35",
"from": "ckeditor5-itop-build@https://github.com/Combodo/ckeditor5-itop-build.git"
},
"clipboard": {
"version": "2.0.11",

View File

@@ -651,16 +651,16 @@ class utilsTest extends ItopTestCase
*
* @throws \Exception
*/
public function testGetMentionedObjectsFromText($sInput, $sFormat, $aExceptedMentionedObjects)
public function testGetMentionedObjectsFromText($sInput, $aExceptedMentionedObjects)
{
// Emulate the "Case provider mechanism" (reason: the data provider requires utils constants not available before the application startup)
echo "testGetMentionedObjectsFromText: input = $sInput\n";
$aTestedMentionedObjects = utils::GetMentionedObjectsFromText($sInput, $sFormat);
$aTestedMentionedObjects = utils::GetMentionedObjectsFromText($sInput);
$sExpectedAsString = print_r($aExceptedMentionedObjects, true);
$sTestedAsString = print_r($aTestedMentionedObjects, true);
$this->assertEquals($sTestedAsString, $sExpectedAsString, "Found mentioned objects don't match. Got: $sTestedAsString, expected $sExpectedAsString");
$this->assertEquals($sExpectedAsString, $sTestedAsString, "Found mentioned objects don't match. Got: $sTestedAsString, expected $sExpectedAsString");
}
/**
@@ -675,34 +675,28 @@ class utilsTest extends ItopTestCase
"Begining
Second line
End",
utils::ENUM_TEXT_FORMAT_HTML,
[],
],
'1 UserRequest' => [
"Begining
Before link <a href=\"$sAbsUrlAppRoot/pages/UI.php?operation=details&amp;class=UserRequest&amp;id=12345&amp;foo=bar\">R-012345</a> After link
End",
utils::ENUM_TEXT_FORMAT_HTML,
<<<HTML
<p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="UserRequest" data-object-key="12345" data-object-id="#Test Ticket" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">#Test Ticket</a>After link</p><p>End</p>
HTML,
[
'UserRequest' => ['12345'],
],
],
'2 UserRequests' => [
"Begining
Before link <a href=\"$sAbsUrlAppRoot/pages/UI.php?operation=details&amp;class=UserRequest&amp;id=12345&amp;foo=bar\">R-012345</a> After link
And <a href=\"$sAbsUrlAppRoot/pages/UI.php&amp;operation=details&amp;class=UserRequest&amp;id=987654&amp;foo=bar\">R-987654</a>
End",
utils::ENUM_TEXT_FORMAT_HTML,
<<<HTML
<div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="UserRequest" data-object-key="12345" data-object-id="#Test Ticket 1" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">#Test Ticket</a> After link</p><p>And <a data-role="object-mention" data-object-class="UserRequest" data-object-key="987654" data-object-id="#Test Ticket 2" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=987654">#Test Ticket</a></p><p>End</p></div>
HTML,
[
'UserRequest' => ['12345', '987654'],
],
],
'1 UserRequest, 1 Person' => [
"Begining
Before link <a href=\"$sAbsUrlAppRoot/pages/UI.php?operation=details&amp;class=UserRequest&amp;id=12345&amp;foo=bar\">R-012345</a> After link
And <a href=\"$sAbsUrlAppRoot/pages/UI.php?operation=details&amp;class=Person&amp;id=3&amp;foo=bar\">Claude Monet</a>
End",
utils::ENUM_TEXT_FORMAT_HTML,
<<<HTML
<div class="ibo-activity-entry--main-information-content"><div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="UserRequest" data-object-key="12345" data-object-id="#Test Ticket" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">#Test Ticket</a> After link</p><p>And <a data-role="object-mention" data-object-class="Person" data-object-key="3" data-object-id="@Agatha Christie" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=3">@Agatha Christie</a></p><p>End</p></div></div>
HTML,
[
'UserRequest' => ['12345'],
'Person' => ['3'],