diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index d111437dff..55a46b88aa 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -913,13 +913,18 @@ class BBCode
default:
$text = ($is_quote_share ? "\n" : '');
- $contact = Contact::getByURL($attributes['profile'], false, ['network']);
+ $contact = Contact::getByURL($attributes['profile'], false, ['network', 'url', 'alias']);
$network = $contact['network'] ?? Protocol::PHANTOM;
+ if (!empty($contact)) {
+ $profile = Contact::getProfileLink($contact);
+ } else {
+ $profile = $attributes['profile'];
+ }
$gsid = ContactSelector::getServerIdForProfile($attributes['profile']);
$tpl = Renderer::getMarkupTemplate('shared_content.tpl');
$text .= self::SHARED_ANCHOR . Renderer::replaceMacros($tpl, [
- '$profile' => $attributes['profile'],
+ '$profile' => $profile,
'$avatar' => $attributes['avatar'],
'$author' => $attributes['author'],
'$link' => $attributes['link'],
@@ -1984,12 +1989,25 @@ class BBCode
'$1$3',
$text
);
- } elseif (in_array($simple_html, [self::INTERNAL, self::EXTERNAL, self::TWITTER_API])) {
+ } elseif (in_array($simple_html, [self::EXTERNAL, self::TWITTER_API])) {
$text = preg_replace(
"/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
'$1$3',
$text
);
+ } elseif ($simple_html == self::INTERNAL) {
+ if (preg_match_all("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", $text, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $contact = Contact::getByURL($match[2], false, ['network', 'url', 'alias']);
+ if (!empty($contact)) {
+ $url = Contact::getProfileLink($contact);
+ } else {
+ $url = $match[2];
+ }
+ $text = str_replace($match[0], '' . $match[1] . '' . $match[3] . '', $text);
+ }
+
+ }
} elseif ($simple_html == self::MASTODON_API) {
$text = preg_replace(
"/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
diff --git a/src/Protocol/ATProtocol/Processor.php b/src/Protocol/ATProtocol/Processor.php
index 2c0e2528c5..1ac2a9f00c 100755
--- a/src/Protocol/ATProtocol/Processor.php
+++ b/src/Protocol/ATProtocol/Processor.php
@@ -506,13 +506,10 @@ class Processor
break;
case 'app.bsky.richtext.facet#mention':
- $contact = Contact::getByURL($feature->did, null, ['id']);
- if (!empty($contact['id'])) {
- $url = $this->baseURL . '/contact/' . $contact['id'];
- if (substr($linktext, 0, 1) == '@') {
- $prefix .= '@';
- $linktext = substr($linktext, 1);
- }
+ $url = $feature->did;
+ if (substr($linktext, 0, 1) == '@') {
+ $prefix .= '@';
+ $linktext = substr($linktext, 1);
}
break;
diff --git a/tests/datasets/api.fixture.php b/tests/datasets/api.fixture.php
index 1596726114..5a31cfb3b9 100644
--- a/tests/datasets/api.fixture.php
+++ b/tests/datasets/api.fixture.php
@@ -13,11 +13,11 @@ use Friendica\Model\Notification;
return [
'gserver' => [
[
- 'url' => 'https://friendica.local',
- 'nurl' => 'http://friendica.local',
- 'register_policy' => 0,
+ 'url' => 'https://friendica.local',
+ 'nurl' => 'http://friendica.local',
+ 'register_policy' => 0,
'registered-users' => 0,
- 'network' => 'unkn',
+ 'network' => 'unkn',
],
],
// Base test config to avoid notice messages
@@ -88,6 +88,11 @@ return [
'uri' => 'https://friendica.local/profile/mutualcontact',
'guid' => '46',
],
+ [
+ 'id' => 49,
+ 'uri' => 'https://domain.tld/profile/remotecontact',
+ 'guid' => '49',
+ ],
[
'id' => 100,
'uri' => 'https://friendica.local/posts/100',
@@ -214,6 +219,23 @@ return [
'network' => Protocol::DFRN,
'location' => 'DFRN',
],
+ [
+ 'id' => 49,
+ 'uid' => 0,
+ 'uri-id' => 43,
+ 'name' => 'Remote user',
+ 'nick' => 'remotecontact',
+ 'self' => 0,
+ 'nurl' => 'http://domain.tld/profile/remotecontact',
+ 'url' => 'https://domain.tld/profile/remotecontact',
+ 'alias' => 'https://domain.tld/~remotecontact',
+ 'about' => 'User used in tests',
+ 'pending' => 0,
+ 'blocked' => 0,
+ 'rel' => Contact::FOLLOWER,
+ 'network' => Protocol::ACTIVITYPUB,
+ 'location' => 'AP',
+ ],
],
'apcontact' => [
[
@@ -343,7 +365,7 @@ return [
'suscipit aut facilis ut inventore omnis exercitationem quo magnam ' .
'consequatur maxime aut illum soluta quaerat natus unde aspernatur ' .
'et sed beatae nihil ullam temporibus corporis ratione blanditiis',
- 'plink' => 'https://friendica.local/display/6',
+ 'plink' => 'https://friendica.local/display/6',
],
[
'uri-id' => 100,
@@ -912,8 +934,8 @@ return [
],
'profile' => [
[
- 'id' => 1,
- 'uid' => 42,
+ 'id' => 1,
+ 'uid' => 42,
'locality' => 'DFRN',
],
],
@@ -933,18 +955,18 @@ return [
],
'group_member' => [
[
- 'id' => 1,
- 'gid' => 1,
+ 'id' => 1,
+ 'gid' => 1,
'contact-id' => 43,
],
[
- 'id' => 2,
- 'gid' => 1,
+ 'id' => 2,
+ 'gid' => 1,
'contact-id' => 43,
],
[
- 'id' => 3,
- 'gid' => 2,
+ 'id' => 3,
+ 'gid' => 2,
'contact-id' => 43,
],
],
diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php
index 9c61e10887..c7c7220cd9 100644
--- a/tests/src/Content/Text/BBCodeTest.php
+++ b/tests/src/Content/Text/BBCodeTest.php
@@ -615,4 +615,27 @@ Lucas: For the right price, yes.[/share]',
self::assertEquals($expected, $actual);
}
+
+ public function dataProfileLink(): array
+ {
+ return [
+ 'mention' => [
+ 'expected' => 'Test 1: @Remote contact',
+ 'text' => 'Test 1: @[url=https://domain.tld/profile/remotecontact]Remote contact[/url]',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataProfileLink
+ *
+ * @param string $expected Expected BBCode output
+ * @param string $text Input text
+ */
+ public function testProfileLink(string $expected, string $text)
+ {
+ $actual = BBCode::convertForUriId(0, $text);
+
+ self::assertEquals($expected, $actual);
+ }
}