X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FContent%2FText%2FBBCode.php;h=da09e13dd9b8dfc5a243a9480d4b3de5b9207186;hb=9bf065c9d8343ff2d2b6b5a7514a78471a0bedd4;hp=f2254606451a101db6d5c1c919e4c810ddf64129;hpb=ae806a593dd87759c3d8b2dbf86d01fc3a2b6c3a;p=friendica.git
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index f225460645..da09e13dd9 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -67,13 +67,12 @@ class BBCode extends BaseObject
$post["after"] = trim(substr($body, $pos + strlen($data[0])));
} else {
$post["text"] = trim(str_replace($data[0], "", $body));
+ $post["after"] = '';
}
$attacheddata = $data[2];
- $URLSearchString = "^\[\]";
-
- if (preg_match("/\[img\]([$URLSearchString]*)\[\/img\]/ism", $attacheddata, $matches)) {
+ if (preg_match("/\[img\](.*?)\[\/img\]/ism", $attacheddata, $matches)) {
$picturedata = Image::getInfoFromURL($matches[1]);
@@ -86,12 +85,12 @@ class BBCode extends BaseObject
}
}
- if (preg_match("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism", $attacheddata, $matches)) {
+ if (preg_match("/\[bookmark\=(.*?)\](.*?)\[\/bookmark\]/ism", $attacheddata, $matches)) {
$post["url"] = $matches[1];
$post["title"] = $matches[2];
}
if (!empty($post["url"]) && (in_array($post["type"], ["link", "video"]))
- && preg_match("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", $attacheddata, $matches)) {
+ && preg_match("/\[url\=(.*?)\](.*?)\[\/url\]/ism", $attacheddata, $matches)) {
$post["url"] = $matches[1];
}
@@ -244,14 +243,18 @@ class BBCode extends BaseObject
// Simplify image codes
$body = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $body);
- $URLSearchString = "^\[\]";
-
- $body = preg_replace("/\[img\=([$URLSearchString]*)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $body);
+ $body = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", '[img]$1[/img]', $body);
- if (preg_match_all("(\[url=([$URLSearchString]*)\]\s*\[img\]([$URLSearchString]*)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) {
+ if (preg_match_all("(\[url=(.*?)\]\s*\[img\](.*?)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) {
if ((count($pictures) == 1) && !$has_title) {
- // Checking, if the link goes to a picture
- $data = ParseUrl::getSiteinfoCached($pictures[0][1], true);
+ if (!empty($item['object-type']) && ($item['object-type'] == ACTIVITY_OBJ_IMAGE)) {
+ // Replace the preview picture with the real picture
+ $url = str_replace('-1.', '-0.', $pictures[0][2]);
+ $data = ['url' => $url, 'type' => 'photo'];
+ } else {
+ // Checking, if the link goes to a picture
+ $data = ParseUrl::getSiteinfoCached($pictures[0][1], true);
+ }
// Workaround:
// Sometimes photo posts to the own album are not detected at the start.
@@ -270,14 +273,14 @@ class BBCode extends BaseObject
}
$post["preview"] = $pictures[0][2];
- $post["text"] = str_replace($pictures[0][0], "", $body);
+ $post["text"] = trim(str_replace($pictures[0][0], "", $body));
} else {
$imgdata = Image::getInfoFromURL($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"] = str_replace($pictures[0][0], "", $body);
+ $post["text"] = trim(str_replace($pictures[0][0], "", $body));
}
}
} elseif (count($pictures) > 0) {
@@ -286,7 +289,7 @@ class BBCode extends BaseObject
$post["image"] = $pictures[0][2];
$post["text"] = $body;
}
- } elseif (preg_match_all("(\[img\]([$URLSearchString]*)\[\/img\])ism", $body, $pictures, PREG_SET_ORDER)) {
+ } elseif (preg_match_all("(\[img\](.*?)\[\/img\])ism", $body, $pictures, PREG_SET_ORDER)) {
if ((count($pictures) == 1) && !$has_title) {
$post["type"] = "photo";
$post["image"] = $pictures[0][1];
@@ -300,8 +303,8 @@ class BBCode extends BaseObject
}
// Test for the external links
- preg_match_all("(\[url\]([$URLSearchString]*)\[\/url\])ism", $body, $links1, PREG_SET_ORDER);
- preg_match_all("(\[url\=([$URLSearchString]*)\].*?\[\/url\])ism", $body, $links2, PREG_SET_ORDER);
+ preg_match_all("(\[url\](.*?)\[\/url\])ism", $body, $links1, PREG_SET_ORDER);
+ preg_match_all("(\[url\=(.*?)\].*?\[\/url\])ism", $body, $links2, PREG_SET_ORDER);
$links = array_merge($links1, $links2);
@@ -354,7 +357,7 @@ class BBCode extends BaseObject
*/
public static function toPlaintext($text, $keep_urls = true)
{
- $naked_text = preg_replace('/\[(.+?)\]\s*/','', $text);
+ $naked_text = preg_replace('/\[.+?\]/','', $text);
if (!$keep_urls) {
$naked_text = preg_replace('#https?\://[^\s<]+[^\s\.\)]#i', '', $naked_text);
}
@@ -562,7 +565,7 @@ class BBCode extends BaseObject
}
$return = '';
- if ($simplehtml == 7) {
+ if (in_array($simplehtml, [7, 9])) {
$return = self::convertUrlForOStatus($data["url"]);
} elseif (($simplehtml != 4) && ($simplehtml != 0)) {
$return = sprintf('%s
', $data["url"], $data["title"]);
@@ -949,15 +952,19 @@ class BBCode extends BaseObject
$text = ($is_quote_share? '
' : '') . '
' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ':
' . "\n" . $content;
break;
case 3: // Diaspora
- $headline = '' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . $mention . ':
' . "\n";
-
if (stripos(Strings::normaliseLink($attributes['link']), 'http://twitter.com/') === 0) {
$text = ($is_quote_share? '
' : '') . '' . $attributes['link'] . '
' . "\n";
} else {
+ $headline = 'â² ' . $attributes['author'] . ':
' . "\n";
+
+ if (!empty($attributes['posted']) && !empty($attributes['link'])) {
+ $headline = 'â² ' . $attributes['author'] . ' - ' . $attributes['posted'] . ' GMT
' . "\n";
+ }
+
$text = ($is_quote_share? '
' : '') . $headline . '' . trim($content) . '
' . "\n";
- if ($attributes['link'] != '') {
- $text .= '[l]
' . "\n";
+ if (empty($attributes['posted']) && !empty($attributes['link'])) {
+ $text .= '[Source]
' . "\n";
}
}
@@ -974,16 +981,9 @@ class BBCode extends BaseObject
$text = ($is_quote_share? '
' : '') . '' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ':
' . "\n" . $content;
break;
case 7: // statusnet/GNU Social
+ case 9: // ActivityPub
$text = ($is_quote_share? '
' : '') . '' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' @' . $author_contact['addr'] . ': ' . $content . '
' . "\n";
break;
- case 9: // Google+
- $text = ($is_quote_share? '
' : '') . '' . html_entity_decode('♲ ', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ':
' . "\n";
- $text .= '' . $content . '
' . "\n";
-
- if ($attributes['link'] != '') {
- $text .= '' . $attributes['link'] . '
';
- }
- break;
default:
// Transforms quoted tweets in rich attachments to avoid nested tweets
if (stripos(Strings::normaliseLink($attributes['link']), 'http://twitter.com/') === 0 && OEmbed::isAllowedURL($attributes['link'])) {
@@ -1027,7 +1027,7 @@ class BBCode extends BaseObject
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
- $a->saveTimestamp($stamp1, "network");
+ $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
if (substr($curl_info["content_type"], 0, 6) == "image/") {
$text = "[url=" . $match[1] . "]" . $match[1] . "[/url]";
@@ -1086,7 +1086,7 @@ class BBCode extends BaseObject
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
- $a->saveTimestamp($stamp1, "network");
+ $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
// if its a link to a picture then embed this picture
if (substr($curl_info["content_type"], 0, 6) == "image/") {
@@ -1135,13 +1135,14 @@ class BBCode extends BaseObject
* Simple HTML values meaning:
* - 0: Friendica display
* - 1: Unused
- * - 2: Used for Google+, Windows Phone push, Friendica API
+ * - 2: Used for Windows Phone push, Friendica API
* - 3: Used before converting to Markdown in bb2diaspora.php
* - 4: Used for WordPress, Libertree (before Markdown), pump.io and tumblr
* - 5: Unused
* - 6: Unused
* - 7: Used for dfrn, OStatus
* - 8: Used for WP backlink text setting
+ * - 9: ActivityPub
*
* @param string $text
* @param bool $try_oembed
@@ -1175,17 +1176,18 @@ class BBCode extends BaseObject
return $return;
};
- // Extracting multi-line code blocks before the whitespace processing
+ // Extracting code blocks before the whitespace processing and the autolinker
$codeblocks = [];
- $text = preg_replace_callback("#\[code(?:=([^\]]*))?\](.*?)\[\/code\]#is",
+ $text = preg_replace_callback("#\[code(?:=([^\]]*))?\](.*?)\[\/code\]#ism",
function ($matches) use (&$codeblocks) {
- $return = $matches[0];
+ $return = '#codeblock-' . count($codeblocks) . '#';
if (strpos($matches[2], "\n") !== false) {
- $return = '#codeblock-' . count($codeblocks) . '#';
-
- $codeblocks[] = '' . trim($matches[2], "\n\r") . '
';
+ $codeblocks[] = '' . trim($matches[2], "\n\r") . '
';
+ } else {
+ $codeblocks[] = '' . $matches[2] . '
';
}
+
return $return;
},
$text
@@ -1244,6 +1246,25 @@ class BBCode extends BaseObject
$text = trim($text);
$text = str_replace("\r\n", "\n", $text);
+ // Remove linefeeds inside of the table elements. See issue #6799
+ $search = ["\n[th]", "[th]\n", " [th]", "\n[/th]", "[/th]\n", "[/th] ",
+ "\n[td]", "[td]\n", " [td]", "\n[/td]", "[/td]\n", "[/td] ",
+ "\n[tr]", "[tr]\n", " [tr]", "[tr] ", "\n[/tr]", "[/tr]\n", " [/tr]", "[/tr] ",
+ "[table]\n", "[table] ", " [table]", "\n[/table]", " [/table]", "[/table] "];
+ $replace = ["[th]", "[th]", "[th]", "[/th]", "[/th]", "[/th]",
+ "[td]", "[td]", "[td]", "[/td]", "[/td]", "[/td]",
+ "[tr]", "[tr]", "[tr]", "[tr]", "[/tr]", "[/tr]", "[/tr]", "[/tr]",
+ "[table]", "[table]", "[table]", "[/table]", "[/table]", "[/table]"];
+ do {
+ $oldtext = $text;
+ $text = str_replace($search, $replace, $text);
+ } while ($oldtext != $text);
+
+ // Replace these here only once
+ $search = ["\n[table]", "[/table]\n"];
+ $replace = ["[table]", "[/table]"];
+ $text = str_replace($search, $replace, $text);
+
// removing multiplicated newlines
if (Config::get("system", "remove_multiplicated_lines")) {
$search = ["\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]", "[/li]\n", "\n[li]", "\n[ul]", "[/ul]\n", "\n\n[share ", "[/attachment]\n",
@@ -1256,139 +1277,11 @@ class BBCode extends BaseObject
} while ($oldtext != $text);
}
- // Set up the parameters for a URL search string
- $URLSearchString = "^\[\]";
- // Set up the parameters for a MAIL search string
- $MAILSearchString = $URLSearchString;
-
- // if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
- if (!$for_plaintext) {
- // Autolink feature (thanks to http://code.seebz.net/p/autolink-php/)
- // Currently disabled, since the function is too greedy
- // $autolink_regex = "`([^\]\=\"']|^)(https?\://[^\s<]+[^\s<\.\)])`ism";
- $autolink_regex = "/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism";
- $text = preg_replace($autolink_regex, '$1[url]$2[/url]', $text);
- if ($simple_html == 7) {
- $text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
- $text = preg_replace_callback("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
- }
- } else {
- $text = preg_replace("(\[url\]([$URLSearchString]*)\[\/url\])ism", " $1 ", $text);
- $text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'self::removePictureLinksCallback', $text);
- }
-
-
// Handle attached links or videos
$text = self::convertAttachment($text, $simple_html, $try_oembed);
- $text = str_replace(["\r","\n"], ['
', '
'], $text);
-
- // Remove all hashtag addresses
- if ((!$try_oembed || $simple_html) && !in_array($simple_html, [3, 7])) {
- $text = preg_replace("/([#@!])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $text);
- } elseif ($simple_html == 3) {
- // The ! is converted to @ since Diaspora only understands the @
- $text = preg_replace("/([@!])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
- '@$3',
- $text);
- } elseif ($simple_html == 7) {
- $text = preg_replace("/([@!])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
- '$1$3',
- $text);
- } elseif (!$simple_html) {
- $text = preg_replace("/([@!])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
- '$1$3',
- $text);
- }
-
- // Bookmarks in red - will be converted to bookmarks in friendica
- $text = preg_replace("/#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $text);
- $text = preg_replace("/#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[bookmark=$1]$2[/bookmark]', $text);
- $text = preg_replace("/#\[url\=[$URLSearchString]*\]\^\[\/url\]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i",
- "[bookmark=$1]$2[/bookmark]", $text);
-
- if (in_array($simple_html, [2, 6, 7, 8, 9])) {
- $text = preg_replace_callback("/([^#@!])\[url\=([^\]]*)\](.*?)\[\/url\]/ism", "self::expandLinksCallback", $text);
- //$Text = preg_replace("/[^#@!]\[url\=([^\]]*)\](.*?)\[\/url\]/ism", ' $2 [url]$1[/url]', $Text);
- $text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", ' $2 [url]$1[/url]',$text);
- }
-
- if ($simple_html == 5) {
- $text = preg_replace("/[^#@!]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[url]$1[/url]', $text);
- }
-
- // Perform URL Search
- if ($try_oembed) {
- $text = preg_replace_callback("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", $try_oembed_callback, $text);
- }
-
- if ($simple_html == 5) {
- $text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", '[url]$1[/url]', $text);
- } else {
- $text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", '[url=$1]$2[/url]', $text);
- }
-
- // Handle Diaspora posts
- $text = preg_replace_callback(
- "&\[url=/?posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
- function ($match) {
- return "[url=" . System::baseUrl() . "/display/" . $match[1] . "]" . $match[2] . "[/url]";
- }, $text
- );
-
- $text = preg_replace_callback(
- "&\[url=/people\?q\=(.*)\](.*)\[\/url\]&Usi",
- function ($match) {
- return "[url=" . System::baseUrl() . "/search?search=%40" . $match[1] . "]" . $match[2] . "[/url]";
- }, $text
- );
-
- // Server independent link to posts and comments
- // See issue: https://github.com/diaspora/diaspora_federation/issues/75
- $expression = "=diaspora://.*?/post/([0-9A-Za-z\-_@.:]{15,254}[0-9A-Za-z])=ism";
- $text = preg_replace($expression, System::baseUrl()."/display/$1", $text);
-
- /* Tag conversion
- * Supports:
- * - #[url=][/url]
- * - [url=]#[/url]
- */
- $text = preg_replace_callback("/(?:#\[url\=[$URLSearchString]*\]|\[url\=[$URLSearchString]*\]#)(.*?)\[\/url\]/ism", function($matches) {
- return '#'
- . XML::escape($matches[1])
- . '';
- }, $text);
-
- // We need no target="_blank" for local links
- // convert links start with System::baseUrl() as local link
- $escapedBaseUrl = str_replace('://', '\:\/\/', System::baseUrl());
- $text = preg_replace("/\[url\]($escapedBaseUrl)([$URLSearchString]*)\[\/url\]/ism", '$1$2', $text);
- $text = preg_replace("/\[url\=($escapedBaseUrl)([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$3', $text);
- // convert links that start with / as local link
- $text = preg_replace("/\[url\](\/[$URLSearchString]*)\[\/url\]/ism", '$1', $text);
- $text = preg_replace("/\[url\=(\/[$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $text);
-
- $text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '$1', $text);
- $text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $text);
-
- // Red compatibility, though the link can't be authenticated on Friendica
- $text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '$2', $text);
-
-
- // we may need to restrict this further if it picks up too many strays
- // link acct:user@host to a webfinger profile redirector
-
- $text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', 'acct:$1@$2', $text);
-
- // Perform MAIL Search
- $text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '$1', $text);
- $text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '$2', $text);
-
// leave open the posibility of [map=something]
// this is replaced in Item::prepareBody() which has knowledge of the item location
-
if (strpos($text, '[/map]') !== false) {
$text = preg_replace_callback(
"/\[map\](.*?)\[\/map\]/ism",
@@ -1398,6 +1291,7 @@ class BBCode extends BaseObject
$text
);
}
+
if (strpos($text, '[map=') !== false) {
$text = preg_replace_callback(
"/\[map=(.*?)\]/ism",
@@ -1407,6 +1301,7 @@ class BBCode extends BaseObject
$text
);
}
+
if (strpos($text, '[map]') !== false) {
$text = preg_replace("/\[map\]/", '', $text);
}
@@ -1473,9 +1368,9 @@ class BBCode extends BaseObject
$endlessloop = 0;
while ((((strpos($text, "[/list]") !== false) && (strpos($text, "[list") !== false)) ||
- ((strpos($text, "[/ol]") !== false) && (strpos($text, "[ol]") !== false)) ||
- ((strpos($text, "[/ul]") !== false) && (strpos($text, "[ul]") !== false)) ||
- ((strpos($text, "[/li]") !== false) && (strpos($text, "[li]") !== false))) && (++$endlessloop < 20)) {
+ ((strpos($text, "[/ol]") !== false) && (strpos($text, "[ol]") !== false)) ||
+ ((strpos($text, "[/ul]") !== false) && (strpos($text, "[ul]") !== false)) ||
+ ((strpos($text, "[/li]") !== false) && (strpos($text, "[li]") !== false))) && (++$endlessloop < 20)) {
$text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '', $text);
$text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '', $text);
$text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '', $text);
@@ -1500,17 +1395,12 @@ class BBCode extends BaseObject
// This is actually executed in Item::prepareBody()
+ $nosmile = strpos($text, '[nosmile]') !== false;
$text = str_replace('[nosmile]', '', $text);
// Check for font change text
$text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "$2", $text);
- // Declare the format for [code] layout
-
- $CodeLayout = '$1
';
- // Check for [code] text
- $text = preg_replace("/\[code\](.*?)\[\/code\]/ism", "$CodeLayout", $text);
-
// Declare the format for [spoiler] layout
$SpoilerLayout = '$1
';
@@ -1529,8 +1419,8 @@ class BBCode extends BaseObject
$endlessloop = 0;
while ((strpos($text, "[/spoiler]")!== false) && (strpos($text, "[spoiler=") !== false) && (++$endlessloop < 20)) {
$text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism",
- "
" . $t_wrote . "$2
",
- $text);
+ "
" . $t_wrote . "$2
",
+ $text);
}
// Declare the format for [quote] layout
@@ -1551,8 +1441,8 @@ class BBCode extends BaseObject
$endlessloop = 0;
while ((strpos($text, "[/quote]")!== false) && (strpos($text, "[quote=") !== false) && (++$endlessloop < 20)) {
$text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
- "" . $t_wrote . "
$2
",
- $text);
+ "" . $t_wrote . "
$2
",
+ $text);
}
@@ -1573,7 +1463,7 @@ class BBCode extends BaseObject
$text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '', $text);
$text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '', $text);
- $text = preg_replace_callback("/\[img\=([$URLSearchString]*)\](.*?)\[\/img\]/ism",
+ $text = preg_replace_callback("/\[img\=(.*?)\](.*?)\[\/img\]/ism",
function ($matches) use ($simple_html) {
$matches[1] = self::proxyUrl($matches[1], $simple_html);
$matches[2] = htmlspecialchars($matches[2], ENT_COMPAT);
@@ -1599,14 +1489,6 @@ class BBCode extends BaseObject
$text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '', $text);
$text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '', $text);
- // Shared content
- $text = self::convertShare(
- $text,
- function (array $attributes, array $author_contact, $content, $is_quote_share) use ($simple_html) {
- return self::convertShareCallback($attributes, $author_contact, $content, $is_quote_share, $simple_html);
- }
- );
-
$text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism", '
', $text);
$text = preg_replace("/\[crypt(.*?)\](.*?)\[\/crypt\]/ism", '
', $text);
//$Text = preg_replace("/\[crypt=(.*?)\](.*?)\[\/crypt\]/ism", '
', $Text);
@@ -1620,9 +1502,9 @@ class BBCode extends BaseObject
$text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", $try_oembed_callback, $text);
} else {
$text = preg_replace("/\[video\](.*?)\[\/video\]/ism",
- '$1', $text);
+ '$1', $text);
$text = preg_replace("/\[audio\](.*?)\[\/audio\]/ism",
- '$1', $text);
+ '$1', $text);
}
// html5 video and audio
@@ -1649,7 +1531,7 @@ class BBCode extends BaseObject
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '', $text);
} else {
$text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism",
- 'https://www.youtube.com/watch?v=$1', $text);
+ 'https://www.youtube.com/watch?v=$1', $text);
}
if ($try_oembed) {
@@ -1664,7 +1546,7 @@ class BBCode extends BaseObject
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '', $text);
} else {
$text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism",
- 'https://vimeo.com/$1', $text);
+ 'https://vimeo.com/$1', $text);
}
// oembed tag
@@ -1691,10 +1573,124 @@ class BBCode extends BaseObject
}
// Replace non graphical smilies for external posts
- if ($simple_html) {
+ if (!$nosmile && !$for_plaintext) {
$text = Smilies::replace($text);
}
+ // if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
+ if (!$for_plaintext) {
+ $text = preg_replace(Strings::autoLinkRegEx(), '[url]$1[/url]', $text);
+ if (in_array($simple_html, [7, 9])) {
+ $text = preg_replace_callback("/\[url\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
+ $text = preg_replace_callback("/\[url\=(.*?)\](.*?)\[\/url\]/ism", 'self::convertUrlForOStatusCallback', $text);
+ }
+ } else {
+ $text = preg_replace("(\[url\](.*?)\[\/url\])ism", " $1 ", $text);
+ $text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'self::removePictureLinksCallback', $text);
+ }
+
+ $text = str_replace(["\r","\n"], ['
', '
'], $text);
+
+ // Remove all hashtag addresses
+ if ((!$try_oembed || $simple_html) && !in_array($simple_html, [3, 7, 9])) {
+ $text = preg_replace("/([#@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $text);
+ } elseif ($simple_html == 3) {
+ // The ! is converted to @ since Diaspora only understands the @
+ $text = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
+ '@$3',
+ $text);
+ } elseif (in_array($simple_html, [7, 9])) {
+ $text = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
+ '$1$3',
+ $text);
+ } elseif (!$simple_html) {
+ $text = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism",
+ '$1$3',
+ $text);
+ }
+
+ // Bookmarks in red - will be converted to bookmarks in friendica
+ $text = preg_replace("/#\^\[url\](.*?)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $text);
+ $text = preg_replace("/#\^\[url\=(.*?)\](.*?)\[\/url\]/ism", '[bookmark=$1]$2[/bookmark]', $text);
+ $text = preg_replace("/#\[url\=.*?\]\^\[\/url\]\[url\=(.*?)\](.*?)\[\/url\]/i",
+ "[bookmark=$1]$2[/bookmark]", $text);
+
+ if (in_array($simple_html, [2, 6, 7, 8])) {
+ $text = preg_replace_callback("/([^#@!])\[url\=([^\]]*)\](.*?)\[\/url\]/ism", "self::expandLinksCallback", $text);
+ //$Text = preg_replace("/[^#@!]\[url\=([^\]]*)\](.*?)\[\/url\]/ism", ' $2 [url]$1[/url]', $Text);
+ $text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", ' $2 [url]$1[/url]',$text);
+ }
+
+ if ($simple_html == 5) {
+ $text = preg_replace("/[^#@!]\[url\=(.*?)\](.*?)\[\/url\]/ism", '[url]$1[/url]', $text);
+ }
+
+ // Perform URL Search
+ if ($try_oembed) {
+ $text = preg_replace_callback("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", $try_oembed_callback, $text);
+ }
+
+ if ($simple_html == 5) {
+ $text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", '[url]$1[/url]', $text);
+ } else {
+ $text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism", '[url=$1]$2[/url]', $text);
+ }
+
+ // Handle Diaspora posts
+ $text = preg_replace_callback(
+ "&\[url=/?posts/([^\[\]]*)\](.*)\[\/url\]&Usi",
+ function ($match) {
+ return "[url=" . System::baseUrl() . "/display/" . $match[1] . "]" . $match[2] . "[/url]";
+ }, $text
+ );
+
+ $text = preg_replace_callback(
+ "&\[url=/people\?q\=(.*)\](.*)\[\/url\]&Usi",
+ function ($match) {
+ return "[url=" . System::baseUrl() . "/search?search=%40" . $match[1] . "]" . $match[2] . "[/url]";
+ }, $text
+ );
+
+ // Server independent link to posts and comments
+ // See issue: https://github.com/diaspora/diaspora_federation/issues/75
+ $expression = "=diaspora://.*?/post/([0-9A-Za-z\-_@.:]{15,254}[0-9A-Za-z])=ism";
+ $text = preg_replace($expression, System::baseUrl()."/display/$1", $text);
+
+ /* Tag conversion
+ * Supports:
+ * - #[url=][/url]
+ * - [url=]#[/url]
+ */
+ $text = preg_replace_callback("/(?:#\[url\=.*?\]|\[url\=.*?\]#)(.*?)\[\/url\]/ism", function($matches) {
+ return '#'
+ . XML::escape($matches[1])
+ . '';
+ }, $text);
+
+ // We need no target="_blank" for local links
+ // convert links start with System::baseUrl() as local link without the target="_blank" attribute
+ $escapedBaseUrl = preg_quote(System::baseUrl(), '/');
+ $text = preg_replace("/\[url\](".$escapedBaseUrl.".*?)\[\/url\]/ism", '$1', $text);
+ $text = preg_replace("/\[url\=(".$escapedBaseUrl.".*?)\](.*?)\[\/url\]/ism", '$2', $text);
+
+ $text = preg_replace("/\[url\](.*?)\[\/url\]/ism", '$1', $text);
+ $text = preg_replace("/\[url\=(.*?)\](.*?)\[\/url\]/ism", '$2', $text);
+
+ // Red compatibility, though the link can't be authenticated on Friendica
+ $text = preg_replace("/\[zrl\=(.*?)\](.*?)\[\/zrl\]/ism", '$2', $text);
+
+
+ // we may need to restrict this further if it picks up too many strays
+ // link acct:user@host to a webfinger profile redirector
+
+ $text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', 'acct:$1@$2', $text);
+
+ // Perform MAIL Search
+ $text = preg_replace("/\[mail\](.*?)\[\/mail\]/", '$1', $text);
+ $text = preg_replace("/\[mail\=(.*?)\](.*?)\[\/mail\]/", '$2', $text);
+
// Unhide all [noparse] contained bbtags unspacefying them
// and triming the [noparse] tag.
@@ -1728,6 +1724,14 @@ class BBCode extends BaseObject
$regex = '#<([^>]*?)(href)="(?!' . implode('|', $allowed_link_protocols) . ')(.*?)"(.*?)>#ism';
$text = preg_replace($regex, '<$1$2="javascript:void(0)"$4 data-original-href="$3" class="invalid-href" title="' . L10n::t('Invalid link protocol') . '">', $text);
+ // Shared content
+ $text = self::convertShare(
+ $text,
+ function (array $attributes, array $author_contact, $content, $is_quote_share) use ($simple_html) {
+ return self::convertShareCallback($attributes, $author_contact, $content, $is_quote_share, $simple_html);
+ }
+ );
+
if ($saved_image) {
$text = self::interpolateSavedImagesIntoItemBody($text, $saved_image);
}
@@ -1746,7 +1750,7 @@ class BBCode extends BaseObject
// Clean up the HTML by loading and saving the HTML with the DOM.
// Bad structured html can break a whole page.
- // For performance reasons do it only with ativated item cache or at export.
+ // For performance reasons do it only with activated item cache or at export.
if (!$try_oembed || (get_itemcachepath() != "")) {
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
@@ -1918,7 +1922,7 @@ class BBCode extends BaseObject
// unmask the special chars back to HTML
$text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['<', '>', '&'], $text);
- $a->saveTimestamp($stamp1, "parser");
+ $a->getProfiler()->saveTimestamp($stamp1, "parser", System::callstack());
// Libertree has a problem with escaped hashtags.
$text = str_replace(['\#'], ['#'], $text);
@@ -1962,7 +1966,7 @@ class BBCode extends BaseObject
$string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2', $string);
// ignore anything in a code block
- $string = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $string);
+ $string = preg_replace('/\[code.*?\].*?\[\/code\]/sm', '', $string);
// Force line feeds at bbtags
$string = str_replace(['[', ']'], ["\n[", "]\n"], $string);