[UTIL][Formatting] Fix group mentions

This commit is contained in:
Diogo Peralta Cordeiro 2021-12-27 21:16:39 +00:00
parent c40e38c5ba
commit f5b06e2c7e
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
2 changed files with 46 additions and 46 deletions

View File

@ -475,21 +475,6 @@ class Actor extends Entity
return $url; return $url;
} }
public static function getPlaceholderUri(string $nickname, int $type = self::PERSON, int $uri_type = Router::ABSOLUTE_URL): string
{
switch ($type) {
case self::PERSON:
case self::ORGANIZATION:
case self::BUSINESS:
case self::BOT:
return Router::url('actor_view_nickname', ['nickname' => $nickname], $uri_type);
case self::GROUP:
return Router::url('group_actor_view_nickname', ['nickname' => $nickname], $uri_type);
default:
throw new BugFoundException('Actor type added but `Actor::getPlaceholderUri` was not updated');
}
}
public function getAliases(): array public function getAliases(): array
{ {
return array_keys($this->getAliasesWithIDs()); return array_keys($this->getAliasesWithIDs());

View File

@ -211,14 +211,14 @@ abstract class Formatting
$matches = []; $matches = [];
if (preg_match('/^ *\[?([^,]+(, ?[^,]+)*)\]? *$/', $input, $matches)) { if (preg_match('/^ *\[?([^,]+(, ?[^,]+)*)\]? *$/', $input, $matches)) {
switch ($split_type) { switch ($split_type) {
case self::SPLIT_BY_BOTH: case self::SPLIT_BY_BOTH:
$arr = preg_split($split_type, $matches[1], 0, \PREG_SPLIT_NO_EMPTY); $arr = preg_split($split_type, $matches[1], 0, \PREG_SPLIT_NO_EMPTY);
break; break;
case self::SPLIT_BY_COMMA: case self::SPLIT_BY_COMMA:
$arr = preg_split('/, ?/', $matches[1]); $arr = preg_split('/, ?/', $matches[1]);
break; break;
default: default:
$arr = explode($split_type[0], $matches[1]); $arr = explode($split_type[0], $matches[1]);
} }
$output = str_replace([' \'', '\'', ' "', '"'], '', $arr); $output = str_replace([' \'', '\'', ' "', '"'], '', $arr);
$output = F\map($output, F\ary('trim', 1)); $output = F\map($output, F\ary('trim', 1));
@ -234,7 +234,7 @@ abstract class Formatting
{ {
$text = self::quoteAndRemoveControlCodes($text); $text = self::quoteAndRemoveControlCodes($text);
// Split \n\n into paragraphs, process each paragrah and merge // Split \n\n into paragraphs, process each paragraph and merge
return implode("\n", F\map(explode("\n\n", $text), function (string $paragraph) use ($language) { return implode("\n", F\map(explode("\n\n", $text), function (string $paragraph) use ($language) {
$paragraph = nl2br($paragraph, use_xhtml: false); $paragraph = nl2br($paragraph, use_xhtml: false);
Event::handle('RenderPlainTextNoteContent', [&$paragraph, $language]); Event::handle('RenderPlainTextNoteContent', [&$paragraph, $language]);
@ -268,13 +268,13 @@ abstract class Formatting
return mb_substr($str, 0, $length); return mb_substr($str, 0, $length);
} }
$str = transliterator_transliterate('Any-Latin;' // any charset to latin compatible $str = transliterator_transliterate('Any-Latin;' // any charset to latin compatible
. 'NFD;' // decompose . 'NFD;' // decompose
. '[:Nonspacing Mark:] Remove;' // remove nonspacing marks (accents etc.) . '[:Nonspacing Mark:] Remove;' // remove nonspacing marks (accents etc.)
. 'NFC;' // composite again . 'NFC;' // composite again
. '[:Punctuation:] Remove;' // remove punctuation (.,¿? etc.) . '[:Punctuation:] Remove;' // remove punctuation (.,¿? etc.)
. 'Lower();' // turn into lowercase . 'Lower();' // turn into lowercase
. 'Latin-ASCII;', // get ASCII equivalents (ð to d for example) . 'Latin-ASCII;', // get ASCII equivalents (ð to d for example)
$str, ); $str, );
return mb_substr(preg_replace('/[^\pL\pN]/u', '', $str), 0, $length); return mb_substr(preg_replace('/[^\pL\pN]/u', '', $str), 0, $length);
} }
@ -294,11 +294,12 @@ abstract class Formatting
// XXX: We remove <span> because when content is in html the tag comes as #<span>hashtag</span> // XXX: We remove <span> because when content is in html the tag comes as #<span>hashtag</span>
$text = str_replace('<span>', '', $text); $text = str_replace('<span>', '', $text);
if (Event::handle('StartFindMentions', [$actor, $text, &$mentions])) { if (Event::handle('StartFindMentions', [$actor, $text, &$mentions])) {
$matches = self::findMentionsRaw($text, '@');
foreach ($matches as $match) { // Person mentions
$person_matches = self::findMentionsRaw($text, '@');
foreach ($person_matches as $match) {
try { try {
$nickname = Nickname::normalize($match[0], check_already_used: false); $nickname = Nickname::normalize($match[0], check_already_used: false, check_is_allowed: false);
} catch (NicknameException) { } catch (NicknameException) {
// Bogus match? Drop it. // Bogus match? Drop it.
continue; continue;
@ -354,20 +355,34 @@ abstract class Formatting
// 'url' => $url, ]; // 'url' => $url, ];
// } // }
// Group mentions
$group_matches = self::findMentionsRaw($text, '!'); $group_matches = self::findMentionsRaw($text, '!');
foreach ($group_matches as $group_match) { foreach ($group_matches as $match) {
$nickname = Nickname::normalize($group_match[0], check_already_used: false, check_is_allowed: false); try {
$group = LocalGroup::getActorByNickname($nickname); $nickname = Nickname::normalize($match[0], check_already_used: false, check_is_allowed: false);
} catch (NicknameException) {
// Bogus match? Drop it.
continue;
}
$mentions[] = [ $mentioned = LocalGroup::getActorByNickname($nickname);
'mentioned' => [$group],
'type' => 'group', if ($mentioned instanceof Actor) {
'text' => $group_match[0], $url = $mentioned->getUri(); // prefer the URI as URL, if it is one.
'position' => $group_match[1], if (!Common::isValidHttpUrl($url)) {
'length' => mb_strlen($group_match[0]), $url = $mentioned->getUrl();
'url' => !\is_null($group) ? $group->getUri() : Actor::getPlaceholderUri($nickname, Actor::GROUP), }
'title' => $group?->getFullname() ?? $group?->getNickname(),
]; $mentions[] = [
'mentioned' => [$mentioned],
'type' => 'group',
'text' => $match[0],
'position' => $match[1],
'length' => mb_strlen($match[0]),
'title' => $mentioned?->getFullname() ?? $mentioned?->getNickname(),
'url' => $url,
];
}
} }
Event::handle('EndFindMentions', [$actor, $text, &$mentions]); Event::handle('EndFindMentions', [$actor, $text, &$mentions]);