', $data['url'], $data['title']);
}
+ }
- if (!empty($data["description"]) && $data["description"] != $data["title"]) {
- // Sanitize the HTML by converting it to BBCode
- $bbcode = HTML::toBBCode($data["description"]);
- $return .= sprintf('
%s
', trim(self::convert($bbcode)));
- }
+ if (!empty($data['description']) && $data['description'] != $data['title']) {
+ // Sanitize the HTML by converting it to BBCode
+ $bbcode = HTML::toBBCode($data['description']);
+ $return .= sprintf('
' . "\n";
+ 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'])) {
- try {
- $text = ($is_quote_share? ' ' : '') . OEmbed::getHTML($attributes['link']);
- } catch (Exception $e) {
- $text = ($is_quote_share? ' ' : '') . sprintf('[bookmark=%s]%s[/bookmark]', $attributes['link'], $content);
- }
- } else {
- $text = ($is_quote_share? "\n" : '');
-
- $tpl = Renderer::getMarkupTemplate('shared_content.tpl');
- $text .= Renderer::replaceMacros($tpl, [
- '$profile' => $attributes['profile'],
- '$avatar' => $attributes['avatar'],
- '$author' => $attributes['author'],
- '$link' => $attributes['link'],
- '$posted' => $attributes['posted'],
- '$content' => trim($content)
- ]);
- }
+ $text = ($is_quote_share? "\n" : '');
+
+ $tpl = Renderer::getMarkupTemplate('shared_content.tpl');
+ $text .= Renderer::replaceMacros($tpl, [
+ '$profile' => $attributes['profile'],
+ '$avatar' => $attributes['avatar'],
+ '$author' => $attributes['author'],
+ '$link' => $attributes['link'],
+ '$posted' => $attributes['posted'],
+ '$content' => trim($content)
+ ]);
break;
}
@@ -1057,10 +1091,10 @@ class BBCode extends BaseObject
private static function removePictureLinksCallback($match)
{
$cache_key = 'remove:' . $match[1];
- $text = Cache::get($cache_key);
+ $text = DI::cache()->get($cache_key);
if (is_null($text)) {
- $a = self::getApp();
+ $a = DI::app();
$stamp1 = microtime(true);
@@ -1071,12 +1105,12 @@ class BBCode extends BaseObject
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
- $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
+ DI::profiler()->saveTimestamp($stamp1, "network", System::callstack());
- if (substr($curl_info["content_type"], 0, 6) == "image/") {
- $text = "[url=" . $match[1] . "]" . $match[1] . "[/url]";
+ if (substr($curl_info['content_type'], 0, 6) == 'image/') {
+ $text = "[url=" . $match[1] . ']' . $match[1] . "[/url]";
} else {
- $text = "[url=" . $match[2] . "]" . $match[2] . "[/url]";
+ $text = "[url=" . $match[2] . ']' . $match[2] . "[/url]";
// if its not a picture then look if its a page that contains a picture link
$body = Network::fetchUrl($match[1]);
@@ -1094,12 +1128,12 @@ class BBCode extends BaseObject
}
}
- if (strtolower($attr["name"]) == "twitter:image") {
- $text = "[url=" . $attr["content"] . "]" . $attr["content"] . "[/url]";
+ if (strtolower($attr['name']) == 'twitter:image') {
+ $text = '[url=' . $attr['content'] . ']' . $attr['content'] . '[/url]';
}
}
}
- Cache::set($cache_key, $text);
+ DI::cache()->set($cache_key, $text);
}
return $text;
@@ -1107,7 +1141,7 @@ class BBCode extends BaseObject
private static function expandLinksCallback($match)
{
- if (($match[3] == "") || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
+ if (($match[3] == '') || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
return ($match[1] . "[url]" . $match[2] . "[/url]");
} else {
return ($match[1] . $match[3] . " [url]" . $match[2] . "[/url]");
@@ -1116,21 +1150,21 @@ class BBCode extends BaseObject
private static function cleanPictureLinksCallback($match)
{
- $a = self::getApp();
+ $a = DI::app();
// When the picture link is the own photo path then we can avoid fetching the link
- $own_photo_url = preg_quote(Strings::normaliseLink($a->getBaseURL()) . '/photos/');
+ $own_photo_url = preg_quote(Strings::normaliseLink(DI::baseUrl()->get()) . '/photos/');
if (preg_match('|' . $own_photo_url . '.*?/image/|', Strings::normaliseLink($match[1]))) {
if (!empty($match[3])) {
- $text = "[img=" . str_replace('-1.', '-0.', $match[2]) . "]" . $match[3] . "[/img]";
+ $text = '[img=' . str_replace('-1.', '-0.', $match[2]) . ']' . $match[3] . '[/img]';
} else {
- $text = "[img]" . str_replace('-1.', '-0.', $match[2]) . "[/img]";
+ $text = '[img]' . str_replace('-1.', '-0.', $match[2]) . '[/img]';
}
return $text;
}
$cache_key = 'clean:' . $match[1];
- $text = Cache::get($cache_key);
+ $text = DI::cache()->get($cache_key);
if (!is_null($text)) {
return $text;
}
@@ -1145,16 +1179,16 @@ class BBCode extends BaseObject
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
- $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
+ DI::profiler()->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/") {
- $text = "[img]" . $match[1] . "[/img]";
+ if (substr($curl_info['content_type'], 0, 6) == 'image/') {
+ $text = '[img]' . $match[1] . '[/img]';
} else {
if (!empty($match[3])) {
- $text = "[img=" . $match[2] . "]" . $match[3] . "[/img]";
+ $text = '[img=' . $match[2] . ']' . $match[3] . '[/img]';
} else {
- $text = "[img]" . $match[2] . "[/img]";
+ $text = '[img]' . $match[2] . '[/img]';
}
// if its not a picture then look if its a page that contains a picture link
@@ -1172,16 +1206,16 @@ class BBCode extends BaseObject
}
}
- if (strtolower($attr["name"]) == "twitter:image") {
+ if (strtolower($attr['name']) == "twitter:image") {
if (!empty($match[3])) {
- $text = "[img=" . $attr["content"] . "]" . $match[3] . "[/img]";
+ $text = "[img=" . $attr['content'] . "]" . $match[3] . "[/img]";
} else {
- $text = "[img]" . $attr["content"] . "[/img]";
+ $text = "[img]" . $attr['content'] . "[/img]";
}
}
}
}
- Cache::set($cache_key, $text);
+ DI::cache()->set($cache_key, $text);
return $text;
}
@@ -1194,7 +1228,7 @@ class BBCode extends BaseObject
}
/**
- * @brief Converts a BBCode message to HTML message
+ * Converts a BBCode message to HTML message
*
* BBcode 2 HTML was written by WAY2WEB.net
* extended to work with Mistpark/Friendica - Mike Macgirvin
@@ -1208,7 +1242,7 @@ class BBCode extends BaseObject
* - 5: Unused
* - 6: Unused
* - 7: Used for dfrn, OStatus
- * - 8: Used for WP backlink text setting
+ * - 8: Used for Twitter, WP backlink text setting
* - 9: ActivityPub
*
* @param string $text
@@ -1218,612 +1252,630 @@ class BBCode extends BaseObject
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function convert($text, $try_oembed = true, $simple_html = 0, $for_plaintext = false)
+ public static function convert($text, $try_oembed = true, $simple_html = self::INTERNAL, $for_plaintext = false)
{
- $a = self::getApp();
-
- /*
- * preg_match_callback function to replace potential Oembed tags with Oembed content
- *
- * $match[0] = [tag]$url[/tag] or [tag=$url]$title[/tag]
- * $match[1] = $url
- * $match[2] = $title or absent
- */
- $try_oembed_callback = function ($match)
- {
- $url = $match[1];
- $title = defaults($match, 2, null);
-
- try {
- $return = OEmbed::getHTML($url, $title);
- } catch (Exception $ex) {
- $return = $match[0];
- }
-
- return $return;
- };
-
- // Extracting code blocks before the whitespace processing and the autolinker
- $codeblocks = [];
-
- $text = preg_replace_callback("#\[code(?:=([^\]]*))?\](.*?)\[\/code\]#ism",
- function ($matches) use (&$codeblocks) {
- $return = '#codeblock-' . count($codeblocks) . '#';
- if (strpos($matches[2], "\n") !== false) {
- $codeblocks[] = '
' . trim($matches[2], "\n\r") . '
';
- } else {
- $codeblocks[] = '' . $matches[2] . '';
- }
+ $a = DI::app();
+
+ $text = self::performWithEscapedTags($text, ['code'], function ($text) use ($try_oembed, $simple_html, $for_plaintext, $a) {
+ $text = self::performWithEscapedTags($text, ['noparse', 'nobb', 'pre'], function ($text) use ($try_oembed, $simple_html, $for_plaintext, $a) {
+ /*
+ * preg_match_callback function to replace potential Oembed tags with Oembed content
+ *
+ * $match[0] = [tag]$url[/tag] or [tag=$url]$title[/tag]
+ * $match[1] = $url
+ * $match[2] = $title or absent
+ */
+ $try_oembed_callback = function ($match)
+ {
+ $url = $match[1];
+ $title = $match[2] ?? null;
- return $return;
- },
- $text
- );
-
- // Hide all [noparse] contained bbtags by spacefying them
- // POSSIBLE BUG --> Will the 'preg' functions crash if there's an embedded image?
-
- $text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'self::escapeNoparseCallback', $text);
- $text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'self::escapeNoparseCallback', $text);
- $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'self::escapeNoparseCallback', $text);
+ try {
+ $return = OEmbed::getHTML($url, $title);
+ } catch (Exception $ex) {
+ $return = $match[0];
+ }
- // Remove the abstract element. It is a non visible element.
- $text = self::stripAbstract($text);
+ return $return;
+ };
- // Move all spaces out of the tags
- $text = preg_replace("/\[(\w*)\](\s*)/ism", '$2[$1]', $text);
- $text = preg_replace("/(\s*)\[\/(\w*)\]/ism", '[/$2]$1', $text);
- // Extract the private images which use data urls since preg has issues with
- // large data sizes. Stash them away while we do bbcode conversion, and then put them back
- // in after we've done all the regex matching. We cannot use any preg functions to do this.
- $extracted = self::extractImagesFromItemBody($text);
- $text = $extracted['body'];
- $saved_image = $extracted['images'];
+ // Remove the abstract element. It is a non visible element.
+ $text = self::stripAbstract($text);
- // If we find any event code, turn it into an event.
- // After we're finished processing the bbcode we'll
- // replace all of the event code with a reformatted version.
+ // Move all spaces out of the tags
+ $text = preg_replace("/\[(\w*)\](\s*)/ism", '$2[$1]', $text);
+ $text = preg_replace("/(\s*)\[\/(\w*)\]/ism", '[/$2]$1', $text);
- $ev = Event::fromBBCode($text);
+ // Extract the private images which use data urls since preg has issues with
+ // large data sizes. Stash them away while we do bbcode conversion, and then put them back
+ // in after we've done all the regex matching. We cannot use any preg functions to do this.
- // Replace any html brackets with HTML Entities to prevent executing HTML or script
- // Don't use strip_tags here because it breaks [url] search by replacing & with amp
+ $extracted = self::extractImagesFromItemBody($text);
+ $text = $extracted['body'];
+ $saved_image = $extracted['images'];
- $text = str_replace("<", "<", $text);
- $text = str_replace(">", ">", $text);
+ // If we find any event code, turn it into an event.
+ // After we're finished processing the bbcode we'll
+ // replace all of the event code with a reformatted version.
- // 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);
+ $ev = Event::fromBBCode($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) {
- $text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "\n[share$1$2]$3[/share]", $text);
- }
+ // Replace any html brackets with HTML Entities to prevent executing HTML or script
+ // Don't use strip_tags here because it breaks [url] search by replacing & with amp
- // Convert new line chars to html tags
+ $text = str_replace("<", "<", $text);
+ $text = str_replace(">", ">", $text);
- // nlbr seems to be hopelessly messed up
- // $Text = nl2br($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);
- // We'll emulate it.
+ // 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) {
+ $text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "\n[share$1$2]$3[/share]", $text);
+ }
- $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",
- "\n[h1]", "[/h1]\n", "\n[h2]", "[/h2]\n", "\n[h3]", "[/h3]\n", "\n[h4]", "[/h4]\n", "\n[h5]", "[/h5]\n", "\n[h6]", "[/h6]\n"];
- $replace = ["\n\n", "\n", "\n", "[/quote]\n", "[/quote]", "[/li]", "[li]", "[ul]", "[/ul]", "\n[share ", "[/attachment]",
- "[h1]", "[/h1]", "[h2]", "[/h2]", "[h3]", "[/h3]", "[h4]", "[/h4]", "[h5]", "[/h5]", "[h6]", "[/h6]"];
- do {
- $oldtext = $text;
+ // Convert new line chars to html tags
+
+ // nlbr seems to be hopelessly messed up
+ // $Text = nl2br($Text);
+
+ // We'll emulate it.
+
+ $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);
- } while ($oldtext != $text);
- }
-
- // Handle attached links or videos
- $text = self::convertAttachment($text, $simple_html, $try_oembed);
-
- // 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",
- function ($match) use ($simple_html) {
- return str_replace($match[0], '
', $text);
+ /// @todo Have a closer look at the different html modes
+ // Handle attached links or videos
+ if ($simple_html == self::ACTIVITYPUB) {
+ $text = self::removeAttachment($text);
+ } elseif (!in_array($simple_html, [self::INTERNAL, self::CONNECTORS])) {
+ $text = self::removeAttachment($text, true);
+ } else {
+ $text = self::convertAttachment($text, $simple_html, $try_oembed);
+ }
- // Check for bold text
- $text = preg_replace("(\[b\](.*?)\[\/b\])ism", '$1', $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",
+ function ($match) use ($simple_html) {
+ return str_replace($match[0], '
' . Map::byLocation($match[1], $simple_html) . '
', $match[0]);
+ },
+ $text
+ );
+ }
- // Check for Italics text
- $text = preg_replace("(\[i\](.*?)\[\/i\])ism", '$1', $text);
+ if (strpos($text, '[map=') !== false) {
+ $text = preg_replace_callback(
+ "/\[map=(.*?)\]/ism",
+ function ($match) use ($simple_html) {
+ return str_replace($match[0], '
', $text);
- // Check for over-line text
- $text = preg_replace("(\[o\](.*?)\[\/o\])ism", '$1', $text);
+ // Check for paragraph
+ $text = preg_replace("(\[p\](.*?)\[\/p\])ism", '
$1
', $text);
- // Check for colored text
- $text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "$2", $text);
+ // Check for bold text
+ $text = preg_replace("(\[b\](.*?)\[\/b\])ism", '$1', $text);
- // Check for sized text
- // [size=50] --> font-size: 50px (with the unit).
- if ($simple_html != 3) {
- $text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "$2", $text);
- $text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "$2", $text);
- } else {
- // Issue 2199: Diaspora doesn't interpret the construct above, nor the or element
- $text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "$2", $text);
- }
+ // Check for Italics text
+ $text = preg_replace("(\[i\](.*?)\[\/i\])ism", '$1', $text);
+ // Check for Underline text
+ $text = preg_replace("(\[u\](.*?)\[\/u\])ism", '$1', $text);
- // Check for centered text
- $text = preg_replace("(\[center\](.*?)\[\/center\])ism", "
$1
", $text);
+ // Check for strike-through text
+ $text = preg_replace("(\[s\](.*?)\[\/s\])ism", '$1', $text);
- // Check for list text
- $text = str_replace("[*]", "
';
+ } else {
+ $return = '' . htmlspecialchars($matches[2], ENT_NOQUOTES, 'UTF-8') . '';
}
+
return $return;
},
$text
@@ -1832,7 +1884,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 activated item cache or at export.
- if (!$try_oembed || (get_itemcachepath() != "")) {
+ if (!$try_oembed || (get_itemcachepath() != '')) {
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
@@ -1840,10 +1892,10 @@ class BBCode extends BaseObject
$doctype = '';
$encoding = '';
- @$doc->loadHTML($encoding.$doctype."".$text."");
+ @$doc->loadHTML($encoding . $doctype . '' . $text . '');
$doc->encoding = 'UTF-8';
$text = $doc->saveHTML();
- $text = str_replace(["", "", $doctype, $encoding], ["", "", "", ""], $text);
+ $text = str_replace(['', '', $doctype, $encoding], ['', '', '', ''], $text);
$text = str_replace('
', '', $text);
@@ -1863,7 +1915,7 @@ class BBCode extends BaseObject
}
/**
- * @brief Strips the "abstract" tag from the provided text
+ * Strips the "abstract" tag from the provided text
*
* @param string $text The text with BBCode
* @return string The same text - but without "abstract" element
@@ -1877,15 +1929,15 @@ class BBCode extends BaseObject
}
/**
- * @brief Returns the value of the "abstract" element
+ * Returns the value of the "abstract" element
*
* @param string $text The text that maybe contains the element
* @param string $addon The addon for which the abstract is meant for
* @return string The abstract
*/
- public static function getAbstract($text, $addon = "")
+ public static function getAbstract($text, $addon = '')
{
- $abstract = "";
+ $abstract = '';
$abstracts = [];
$addon = strtolower($addon);
@@ -1899,7 +1951,7 @@ class BBCode extends BaseObject
$abstract = $abstracts[$addon];
}
- if ($abstract == "" && preg_match("/\[abstract\](.*?)\[\/abstract\]/ism", $text, $result)) {
+ if ($abstract == '' && preg_match("/\[abstract\](.*?)\[\/abstract\]/ism", $text, $result)) {
$abstract = $result[1];
}
@@ -1907,7 +1959,7 @@ class BBCode extends BaseObject
}
/**
- * @brief Callback function to replace a Friendica style mention in a mention for Diaspora
+ * Callback function to replace a Friendica style mention in a mention for Diaspora
*
* @param array $match Matching values for the callback
* [1] = Mention type (! or @)
@@ -1934,7 +1986,7 @@ class BBCode extends BaseObject
}
/**
- * @brief Converts a BBCode text into Markdown
+ * Converts a BBCode text into Markdown
*
* This function converts a BBCode item body to be sent to Markdown-enabled
* systems like Diaspora and Libertree
@@ -1946,8 +1998,6 @@ class BBCode extends BaseObject
*/
public static function toMarkdown($text, $for_diaspora = true)
{
- $a = self::getApp();
-
$original_text = $text;
// Since Diaspora is creating a summary for links, this function removes them before posting
@@ -1971,11 +2021,11 @@ class BBCode extends BaseObject
// Convert it to HTML - don't try oembed
if ($for_diaspora) {
- $text = self::convert($text, false, 3);
+ $text = self::convert($text, false, self::DIASPORA);
// Add all tags that maybe were removed
if (preg_match_all("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/ism", $original_text, $tags)) {
- $tagline = "";
+ $tagline = '';
foreach ($tags[2] as $tag) {
$tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8');
if (!strpos(html_entity_decode($text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) {
@@ -1985,25 +2035,19 @@ class BBCode extends BaseObject
$text = $text . " " . $tagline;
}
} else {
- $text = self::convert($text, false, 4);
+ $text = self::convert($text, false, self::CONNECTORS);
}
- // mask some special HTML chars from conversation to markdown
- $text = str_replace(['<', '>', '&'], ['&_lt_;', '&_gt_;', '&_amp_;'], $text);
-
// If a link is followed by a quote then there should be a newline before it
// Maybe we should make this newline at every time before a quote.
- $text = str_replace(["
"], ["
"], $text);
+ $text = str_replace(['
'], ['
'], $text);
$stamp1 = microtime(true);
// Now convert HTML to Markdown
$text = HTML::toMarkdown($text);
- // unmask the special chars back to HTML
- $text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['<', '>', '&'], $text);
-
- $a->getProfiler()->saveTimestamp($stamp1, "parser", System::callstack());
+ DI::profiler()->saveTimestamp($stamp1, "parser", System::callstack());
// Libertree has a problem with escaped hashtags.
$text = str_replace(['\#'], ['#'], $text);
@@ -2027,76 +2071,97 @@ class BBCode extends BaseObject
}
/**
- * @brief Pull out all #hashtags and @person tags from $string.
- *
- * We also get @person@domain.com - which would make
- * the regex quite complicated as tags can also
- * end a sentence. So we'll run through our results
- * and strip the period from any tags which end with one.
- * Returns array of tags found, or empty array.
- *
- * @param string $string Post content
- *
- * @return array List of tag and person names
- */
- public static function getTags($string)
- {
- $ret = [];
-
- // Convert hashtag links to hashtags
- $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2', $string);
-
- // ignore anything in a code block
- $string = preg_replace('/\[code.*?\].*?\[\/code\]/sm', '', $string);
-
- // Force line feeds at bbtags
- $string = str_replace(['[', ']'], ["\n[", "]\n"], $string);
-
- // ignore anything in a bbtag
- $string = preg_replace('/\[(.*?)\]/sm', '', $string);
-
- // Match full names against @tags including the space between first and last
- // We will look these up afterward to see if they are full names or not recognisable.
-
- if (preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/', $string, $matches)) {
- foreach ($matches[1] as $match) {
- if (strstr($match, ']')) {
- // we might be inside a bbcode color tag - leave it alone
- continue;
- }
-
- if (substr($match, -1, 1) === '.') {
- $ret[] = substr($match, 0, -1);
- } else {
- $ret[] = $match;
- }
- }
- }
-
- // Otherwise pull out single word tags. These can be @nickname, @first_last
- // and #hash tags.
-
- if (preg_match_all('/([!#@][^\^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/', $string, $matches)) {
- foreach ($matches[1] as $match) {
- if (strstr($match, ']')) {
- // we might be inside a bbcode color tag - leave it alone
- continue;
- }
- if (substr($match, -1, 1) === '.') {
- $match = substr($match,0,-1);
- }
- // ignore strictly numeric tags like #1
- if ((strpos($match, '#') === 0) && ctype_digit(substr($match, 1))) {
- continue;
- }
- // try not to catch url fragments
- if (strpos($string, $match) && preg_match('/[a-zA-z0-9\/]/', substr($string, strpos($string, $match) - 1, 1))) {
- continue;
- }
- $ret[] = $match;
- }
- }
-
- return $ret;
- }
+ * Pull out all #hashtags and @person tags from $string.
+ *
+ * We also get @person@domain.com - which would make
+ * the regex quite complicated as tags can also
+ * end a sentence. So we'll run through our results
+ * and strip the period from any tags which end with one.
+ * Returns array of tags found, or empty array.
+ *
+ * @param string $string Post content
+ *
+ * @return array List of tag and person names
+ */
+ public static function getTags($string)
+ {
+ $ret = [];
+
+ // Convert hashtag links to hashtags
+ $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2 ', $string);
+
+ // ignore anything in a code block
+ $string = preg_replace('/\[code.*?\].*?\[\/code\]/sm', '', $string);
+
+ // Force line feeds at bbtags
+ $string = str_replace(['[', ']'], ["\n[", "]\n"], $string);
+
+ // ignore anything in a bbtag
+ $string = preg_replace('/\[(.*?)\]/sm', '', $string);
+
+ // Match full names against @tags including the space between first and last
+ // We will look these up afterward to see if they are full names or not recognisable.
+
+ if (preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/', $string, $matches)) {
+ foreach ($matches[1] as $match) {
+ if (strstr($match, ']')) {
+ // we might be inside a bbcode color tag - leave it alone
+ continue;
+ }
+
+ if (substr($match, -1, 1) === '.') {
+ $ret[] = substr($match, 0, -1);
+ } else {
+ $ret[] = $match;
+ }
+ }
+ }
+
+ // Otherwise pull out single word tags. These can be @nickname, @first_last
+ // and #hash tags.
+
+ if (preg_match_all('/([!#@][^\^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/', $string, $matches)) {
+ foreach ($matches[1] as $match) {
+ if (strstr($match, ']')) {
+ // we might be inside a bbcode color tag - leave it alone
+ continue;
+ }
+
+ if (substr($match, -1, 1) === '.') {
+ $match = substr($match,0,-1);
+ }
+
+ // ignore strictly numeric tags like #1
+ if ((strpos($match, '#') === 0) && ctype_digit(substr($match, 1))) {
+ continue;
+ }
+
+ // try not to catch url fragments
+ if (strpos($string, $match) && preg_match('/[a-zA-z0-9\/]/', substr($string, strpos($string, $match) - 1, 1))) {
+ continue;
+ }
+ $ret[] = $match;
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Perform a custom function on a text after having escaped blocks enclosed in the provided tag list.
+ *
+ * @param string $text
+ * @param array $tagList A list of tag names, e.g ['noparse', 'nobb', 'pre']
+ * @param callable $callback
+ * @return string
+ * @throws Exception
+ *@see Strings::performWithEscapedBlocks
+ *
+ */
+ public static function performWithEscapedTags(string $text, array $tagList, callable $callback)
+ {
+ $tagList = array_map('preg_quote', $tagList);
+
+ return Strings::performWithEscapedBlocks($text, '#\[(?:' . implode('|', $tagList) . ').*?\[/(?:' . implode('|', $tagList) . ')]#ism', $callback);
+ }
}