diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index f40160c9de..ab7300da18 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -1158,6 +1158,40 @@ class BBCode
return $match[1] . '[url=' . $data['url'] . ']' . $data['nick'] . '[/url]';
}
+ /**
+ * Normalize links to Youtube and Vimeo to a unified format.
+ *
+ * @param string $text
+ * @return string
+ */
+ private static function normalizeVideoLinks(string $text): string
+ {
+ $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
+ $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
+ $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
+ $text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
+
+ $text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
+ $text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
+
+ return $text;
+ }
+
+ /**
+ * Expand Youtube and Vimeo links to
+ *
+ * @param string $text
+ * @return string
+ */
+ public static function expandVideoLinks(string $text): string
+ {
+ $text = self::normalizeVideoLinks($text);
+ $text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '[url=https://www.youtube.com/watch?v=$1]https://www.youtube.com/watch?v=$1[/url]', $text);
+ $text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '[url=https://vimeo.com/$1]https://vimeo.com/$1[/url]', $text);
+
+ return $text;
+ }
+
/**
* Converts a BBCode message for a given URI-ID to a HTML message
*
@@ -1655,12 +1689,9 @@ class BBCode
// Backward compatibility, [iframe] support has been removed in version 2020.12
$text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '$1', $text);
- // Youtube extensions
- $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
- $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
- $text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/shorts\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
- $text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $text);
+ $text = self::normalizeVideoLinks($text);
+ // Youtube extensions
if ($try_oembed) {
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '', $text);
} else {
@@ -1671,9 +1702,7 @@ class BBCode
);
}
- $text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
- $text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $text);
-
+ // Vimeo extensions
if ($try_oembed) {
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '', $text);
} else {
diff --git a/src/Module/Api/Mastodon/Statuses.php b/src/Module/Api/Mastodon/Statuses.php
index dad0451fc4..a8f1dc1c66 100644
--- a/src/Module/Api/Mastodon/Statuses.php
+++ b/src/Module/Api/Mastodon/Statuses.php
@@ -76,16 +76,9 @@ class Statuses extends BaseApi
throw new HTTPException\NotFoundException('Item with URI ID ' . $this->parameters['id'] . ' not found for user ' . $uid . '.');
}
- // The imput is defined as text. So we can use Markdown for some enhancements
- $body = Markdown::toBBCode($request['status']);
-
- if (DI::pConfig()->get($uid, 'system', 'api_auto_attach', false) && preg_match("/\[url=[^\[\]]*\](.*)\[\/url\]\z/ism", $body, $matches)) {
- $body = preg_replace("/\[url=[^\[\]]*\].*\[\/url\]\z/ism", PageInfo::getFooterFromUrl($matches[1]), $body);
- }
-
$item['title'] = '';
$item['uid'] = $post['uid'];
- $item['body'] = $body;
+ $item['body'] = $this->formatStatus($request['status'], $uid);
$item['network'] = $post['network'];
$item['gravity'] = $post['gravity'];
$item['verb'] = $post['verb'];
@@ -190,13 +183,6 @@ class Statuses extends BaseApi
$owner = User::getOwnerDataById($uid);
- // The imput is defined as text. So we can use Markdown for some enhancements
- $body = Markdown::toBBCode($request['status']);
-
- if (DI::pConfig()->get($uid, 'system', 'api_auto_attach', false) && preg_match("/\[url=[^\[\]]*\](.*)\[\/url\]\z/ism", $body, $matches)) {
- $body = preg_replace("/\[url=[^\[\]]*\].*\[\/url\]\z/ism", PageInfo::getFooterFromUrl($matches[1]), $body);
- }
-
$item = [];
$item['network'] = Protocol::DFRN;
$item['uid'] = $uid;
@@ -204,7 +190,7 @@ class Statuses extends BaseApi
$item['contact-id'] = $owner['id'];
$item['author-id'] = $item['owner-id'] = Contact::getPublicIdByUserId($uid);
$item['title'] = '';
- $item['body'] = $body;
+ $item['body'] = $this->formatStatus($request['status'], $uid);
$item['app'] = $this->getApp();
switch ($request['visibility']) {
@@ -415,4 +401,28 @@ class Statuses extends BaseApi
}
return $item;
}
+
+ /**
+ * Format the status via Markdown and a link description if enabled for this user
+ *
+ * @param string $status
+ * @param integer $uid
+ * @return string
+ */
+ private function formatStatus(string $status, int $uid): string
+ {
+ // The input is defined as text. So we can use Markdown for some enhancements
+ $status = Markdown::toBBCode($status);
+
+ if (!DI::pConfig()->get($uid, 'system', 'api_auto_attach', false)) {
+ return $status;
+ }
+
+ $status = BBCode::expandVideoLinks($status);
+ if (preg_match("/\[url=[^\[\]]*\](.*)\[\/url\]\z/ism", $status, $matches)) {
+ $status = preg_replace("/\[url=[^\[\]]*\].*\[\/url\]\z/ism", PageInfo::getFooterFromUrl($matches[1]), $status);
+ }
+
+ return $status;
+ }
}