X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FContent%2FText%2FBBCode.php;h=2070d22d131d534b43f3040e6b6683f50f8d3ea1;hb=d609d70bd23a0665fa5dd138630a30731589e56d;hp=d82ec39ec218f656d1b528d02d18807ccacf32ac;hpb=1ee0e6f711ac50050f3e07631974f3f7fcc8f4c7;p=friendica.git
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index d82ec39ec2..2070d22d13 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -55,18 +55,25 @@ class BBCode
// Update this value to the current date whenever changes are made to BBCode::convert
const VERSION = '2021-07-28';
- const INTERNAL = 0;
- const EXTERNAL = 1;
- const API = 2;
- const DIASPORA = 3;
- const CONNECTORS = 4;
- const OSTATUS = 7;
- const TWITTER = 8;
- const BACKLINK = 8;
- const ACTIVITYPUB = 9;
+ const INTERNAL = 0;
+ const EXTERNAL = 1;
+ const MASTODON_API = 2;
+ const DIASPORA = 3;
+ const CONNECTORS = 4;
+ const TWITTER_API = 5;
+ const OSTATUS = 7;
+ const TWITTER = 8;
+ const BACKLINK = 8;
+ const ACTIVITYPUB = 9;
const TOP_ANCHOR = '
';
const BOTTOM_ANCHOR = '
';
+
+ const PREVIEW_NONE = 0;
+ const PREVIEW_NO_IMAGE = 1;
+ const PREVIEW_LARGE = 2;
+ const PREVIEW_SMALL = 3;
+
/**
* Fetches attachment data that were generated the old way
*
@@ -266,8 +273,8 @@ class BBCode
// Get all linked images with alternative image description
if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) {
- if (Photo::isLocal($picture[1])) {
- $post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2]];
+ if ($id = Photo::getIdForName($picture[1])) {
+ $post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2], 'id' => $id];
} else {
$post['remote_images'][] = ['url' => $picture[1], 'description' => $picture[2]];
}
@@ -279,22 +286,25 @@ class BBCode
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) {
- if (Photo::isLocal($picture[1])) {
- $post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => ''];
+ if ($id = Photo::getIdForName($picture[1])) {
+ $post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => '', 'id' => $id];
} else {
$post['remote_images'][] = ['url' => $picture[1], 'description' => ''];
}
}
}
- // if nothing is found, it maybe having an image.
if (!isset($post['type'])) {
- // Simplify image codes
- $body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
- $body = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $body);
$post['text'] = $body;
+ }
- if (preg_match_all("#\[url=([^\]]+?)\]\s*\[img\]([^\[]+?)\[/img\]\s*\[/url\]#ism", $body, $pictures, PREG_SET_ORDER)) {
+ // Simplify image codes
+ $post['text'] = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $post['text']);
+ $post['text'] = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $post['text']);
+
+ // if nothing is found, it maybe having an image.
+ if (!isset($post['type'])) {
+ if (preg_match_all("#\[url=([^\]]+?)\]\s*\[img\]([^\[]+?)\[/img\]\s*\[/url\]#ism", $post['text'], $pictures, PREG_SET_ORDER)) {
if ((count($pictures) == 1) && !$has_title) {
if (!empty($item['object-type']) && ($item['object-type'] == Activity\ObjectType::IMAGE)) {
// Replace the preview picture with the real picture
@@ -322,14 +332,14 @@ class BBCode
}
$post['preview'] = $pictures[0][2];
- $post['text'] = trim(str_replace($pictures[0][0], '', $body));
+ $post['text'] = trim(str_replace($pictures[0][0], '', $post['text']));
} else {
$imgdata = Images::getInfoFromURLCached($pictures[0][1]);
if (($imgdata) && substr($imgdata['mime'], 0, 6) == 'image/') {
$post['type'] = 'photo';
$post['image'] = $pictures[0][1];
$post['preview'] = $pictures[0][2];
- $post['text'] = trim(str_replace($pictures[0][0], '', $body));
+ $post['text'] = trim(str_replace($pictures[0][0], '', $post['text']));
}
}
} elseif (count($pictures) > 0) {
@@ -341,13 +351,12 @@ class BBCode
}
$post['image'] = $pictures[0][2];
- $post['text'] = $body;
foreach ($pictures as $picture) {
$post['text'] = trim(str_replace($picture[0], '', $post['text']));
}
}
- } elseif (preg_match_all("(\[img\](.*?)\[\/img\])ism", $body, $pictures, PREG_SET_ORDER)) {
+ } elseif (preg_match_all("(\[img\](.*?)\[\/img\])ism", $post['text'], $pictures, PREG_SET_ORDER)) {
if ($has_title) {
$post['type'] = 'link';
$post['url'] = $plink;
@@ -356,7 +365,6 @@ class BBCode
}
$post['image'] = $pictures[0][1];
- $post['text'] = $body;
foreach ($pictures as $picture) {
$post['text'] = trim(str_replace($picture[0], '', $post['text']));
}
@@ -396,7 +404,6 @@ class BBCode
if (!isset($post['type'])) {
$post['type'] = 'text';
- $post['text'] = trim($body);
}
if (($post['type'] == 'photo') && empty($post['images']) && !empty($post['remote_images'])) {
@@ -413,6 +420,10 @@ class BBCode
if (isset($data['images'][0])) {
$post['image'] = $data['images'][0]['src'];
}
+ } elseif (preg_match_all("#\[url=([^\]]+?)\]\s*\[img\]([^\[]+?)\[/img\]\s*\[/url\]#ism", $post['text'], $pictures, PREG_SET_ORDER)) {
+ foreach ($pictures as $picture) {
+ $post['text'] = trim(str_replace($picture[0], '', $post['text']));
+ }
}
DI::profiler()->stopRecording();
@@ -424,7 +435,6 @@ class BBCode
*
* @param string $body
* @param boolean $no_link_desc No link description
- *
* @return string with replaced body
*/
public static function removeAttachment(string $body, bool $no_link_desc = false): string
@@ -449,7 +459,6 @@ class BBCode
*
* @param string $text
* @param bool $keep_urls Whether to keep URLs in the resulting plaintext
- *
* @return string
*/
public static function toPlaintext(string $text, bool $keep_urls = true): string
@@ -471,7 +480,7 @@ class BBCode
private static function proxyUrl(string $image, int $simplehtml = self::INTERNAL, int $uriid = 0, string $size = ''): string
{
// Only send proxied pictures to API and for internal display
- if (!in_array($simplehtml, [self::INTERNAL, self::API])) {
+ if (!in_array($simplehtml, [self::INTERNAL, self::MASTODON_API, self::TWITTER_API])) {
return $image;
} elseif ($uriid > 0) {
return Post\Link::getByLink($uriid, $image, $size);
@@ -500,7 +509,7 @@ class BBCode
$c = preg_match_all('/\[img.*?\](.*?)\[\/img\]/ism', $s, $matches, PREG_SET_ORDER);
if ($c) {
foreach ($matches as $mtch) {
- Logger::info('scale_external_image', ['image' => $mtch[1]]);
+ Logger::debug('scale_external_image', ['image' => $mtch[1]]);
$hostname = str_replace('www.', '', substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3));
if (stristr($mtch[1], $hostname)) {
@@ -528,14 +537,14 @@ class BBCode
$Image->scaleDown(640);
$new_width = $Image->getWidth();
$new_height = $Image->getHeight();
- Logger::info('External images scaled', ['orig_width' => $orig_width, 'new_width' => $new_width, 'orig_height' => $orig_height, 'new_height' => $new_height, 'match' => $mtch[0]]);
+ Logger::debug('External images scaled', ['orig_width' => $orig_width, 'new_width' => $new_width, 'orig_height' => $orig_height, 'new_height' => $new_height, 'match' => $mtch[0]]);
$s = str_replace(
$mtch[0],
'[img=' . $new_width . 'x' . $new_height. ']' . $mtch[1] . '[/img]'
. "\n",
$s
);
- Logger::info('New string', ['image' => $s]);
+ Logger::debug('New string', ['image' => $s]);
}
}
}
@@ -585,7 +594,7 @@ class BBCode
if (($textlen + $img_start) > $maxlen) {
if ($textlen < $maxlen) {
- Logger::info('the limit happens before an embedded image');
+ Logger::debug('the limit happens before an embedded image');
$new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
$textlen = $maxlen;
}
@@ -599,7 +608,7 @@ class BBCode
if (($textlen + $img_end) > $maxlen) {
if ($textlen < $maxlen) {
- Logger::info('the limit happens before the end of a non-embedded image');
+ Logger::debug('the limit happens before the end of a non-embedded image');
$new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
$textlen = $maxlen;
}
@@ -622,11 +631,11 @@ class BBCode
if (($textlen + strlen($orig_body)) > $maxlen) {
if ($textlen < $maxlen) {
- Logger::info('the limit happens after the end of the last image');
+ Logger::debug('the limit happens after the end of the last image');
$new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
}
} else {
- Logger::info('the text size with embedded images extracted did not violate the limit');
+ Logger::debug('the text size with embedded images extracted did not violate the limit');
$new_body = $new_body . $orig_body;
}
@@ -651,7 +660,7 @@ class BBCode
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function convertAttachment(string $text, int $simplehtml = self::INTERNAL, bool $tryoembed = true, array $data = [], int $uriid = 0): string
+ public static function convertAttachment(string $text, int $simplehtml = self::INTERNAL, bool $tryoembed = true, array $data = [], int $uriid = 0, int $preview_mode = self::PREVIEW_LARGE): string
{
DI::profiler()->startRecording('rendering');
$data = $data ?: self::getAttachmentData($text);
@@ -686,12 +695,18 @@ class BBCode
$return = sprintf('
' . $content . ''; @@ -1277,7 +1319,7 @@ class BBCode /** * Callback: Expands links from given $match array * - * @param arrat $match Array with link match + * @param array $match Array with link match * @return string BBCode */ private static function expandLinksCallback(array $match): string @@ -1292,7 +1334,7 @@ class BBCode /** * Callback: Cleans picture links * - * @param arrat $match Array with link match + * @param array $match Array with link match * @return string BBCode */ private static function cleanPictureLinksCallback(array $match): string @@ -1558,8 +1600,8 @@ class BBCode $text = str_replace(">", ">", $text); // remove some newlines before the general conversion - $text = preg_replace("/\s?\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "[share$1]$2[/share]", $text); - $text = preg_replace("/\s?\[quote(.*?)\]\s?(.*?)\s?\[\/quote\]\s?/ism", "[quote$1]$2[/quote]", $text); + $text = preg_replace("/\s?\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "\n[share$1]$2[/share]\n", $text); + $text = preg_replace("/\s?\[quote(.*?)\]\s?(.*?)\s?\[\/quote\]\s?/ism", "\n[quote$1]$2[/quote]\n", $text); // when the content is meant exporting to other systems then remove the avatar picture since this doesn't really look good on these systems if (!$try_oembed) { @@ -1606,7 +1648,7 @@ class BBCode /// @todo Have a closer look at the different html modes // Handle attached links or videos - if (in_array($simple_html, [self::API, self::ACTIVITYPUB])) { + if (in_array($simple_html, [self::MASTODON_API, self::TWITTER_API, self::ACTIVITYPUB])) { $text = self::removeAttachment($text); } elseif (!in_array($simple_html, [self::INTERNAL, self::EXTERNAL, self::CONNECTORS])) { $text = self::removeAttachment($text, true); @@ -1869,11 +1911,13 @@ class BBCode if ($try_oembed) { $text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); $text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); + $text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/shorts\/.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); $text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism", $try_oembed_callback, $text); } $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); if ($try_oembed) { @@ -1941,16 +1985,23 @@ class BBCode $text = preg_replace("/([#])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $text); - } elseif (in_array($simple_html, [self::INTERNAL, self::EXTERNAL, self::API])) { + } elseif (in_array($simple_html, [self::INTERNAL, self::EXTERNAL, self::TWITTER_API])) { $text = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $text); + } elseif ($simple_html == self::MASTODON_API) { + $text = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", + '$1$3', + $text); + $text = preg_replace("/([#])\[url\=(.*?)\](.*?)\[\/url\]/ism", + '$1$3', + $text); } else { $text = preg_replace("/([#@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $text); } if (!$for_plaintext) { - if (in_array($simple_html, [self::OSTATUS, self::API, self::ACTIVITYPUB])) { + if (in_array($simple_html, [self::OSTATUS, self::MASTODON_API, self::TWITTER_API, self::ACTIVITYPUB])) { $text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text); $text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForActivityPubCallback', $text); } @@ -2051,7 +2102,7 @@ class BBCode $text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&\;(.*?)\>/ism', '<$1$2=$3&$4>', $text); // sanitizes src attributes (http and redir URLs for displaying in a web page, cid used for inline images in emails) - $allowed_src_protocols = ['//', 'http://', 'https://', 'redir/', 'cid:']; + $allowed_src_protocols = ['//', 'http://', 'https://', 'contact/redir/', 'cid:']; array_walk($allowed_src_protocols, function(&$value) { $value = preg_quote($value, '#');}); @@ -2066,7 +2117,7 @@ class BBCode $allowed_link_protocols[] = '//'; $allowed_link_protocols[] = 'http://'; $allowed_link_protocols[] = 'https://'; - $allowed_link_protocols[] = 'redir/'; + $allowed_link_protocols[] = 'contact/redir/'; array_walk($allowed_link_protocols, function(&$value) { $value = preg_quote($value, '#');}); @@ -2304,7 +2355,7 @@ class BBCode DI::profiler()->startRecording('rendering'); $ret = []; - self::performWithEscapedTags($string, ['noparse', 'pre', 'code', 'img'], function ($string) use (&$ret) { + self::performWithEscapedTags($string, ['noparse', 'pre', 'code', 'img', 'attachment'], function ($string) use (&$ret) { // Convert hashtag links to hashtags $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2 ', $string); @@ -2454,10 +2505,11 @@ class BBCode * @param string $link Post source URL * @param string $posted Post created date * @param string|null $guid Post guid (if any) + * @param string|null $uri Post uri (if any) * @return string * @TODO Rewrite to handle over whole record array */ - public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null): string + public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null, string $uri = null): string { DI::profiler()->startRecording('rendering'); $header = "[share author='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $author) . @@ -2470,6 +2522,10 @@ class BBCode $header .= "' guid='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $guid); } + if ($uri) { + $header .= "' message_id='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $uri); + } + $header .= "']"; DI::profiler()->stopRecording(); @@ -2543,7 +2599,7 @@ class BBCode // Bypass attachment if parse url for a comment if (!$tryAttachment) { DI::profiler()->stopRecording(); - return "\n" . '[url=' . $url . ']' . $siteinfo['title'] . '[/url]'; + return "\n" . '[url=' . $url . ']' . ($siteinfo['title'] ?? $url) . '[/url]'; } // Format it as BBCode attachment