X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FContent%2FText%2FBBCode.php;h=ebaef2b29d1accf43625b1e56c9cdcafc7fb61e1;hb=9665f4ed415d34cbcf09df8c6ca04882303e9544;hp=532397c13acca4a98de6e1dbd7e95a0ec2a3f4a5;hpb=d376ed6f61a195fc119cd86aaf47843a9191e41f;p=friendica.git diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 532397c13a..ebaef2b29d 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1,34 +1,36 @@ %s
', $data["url"], $data["title"]); } else { @@ -707,7 +709,7 @@ class BBCode if ($data["description"] != "" && $data["description"] != $data["title"]) { // Sanitize the HTML by converting it to BBCode - $bbcode = html2bbcode($data["description"]); + $bbcode = HTML::toBBCode($data["description"]); $return .= sprintf('
%s
', trim(self::convert($bbcode))); } if ($data["type"] == "link") { @@ -762,27 +764,6 @@ class BBCode return $text . "\n" . $data["after"]; } - private static function cleanCss($input) - { - $cleaned = ""; - - $input = strtolower($input); - - for ($i = 0; $i < strlen($input); $i++) { - $char = substr($input, $i, 1); - - if (($char >= "a") && ($char <= "z")) { - $cleaned .= $char; - } - - if (!(strpos(" #;:0123456789-_.%", $char) === false)) { - $cleaned .= $char; - } - } - - return $cleaned; - } - /** * Converts [url] BBCodes in a format that looks fine on Mastodon. (callback function) * @@ -790,7 +771,7 @@ class BBCode * @param array $match Array with the matching values * @return string reformatted link including HTML codes */ - private static function convertUrlForMastodonCallback($match) + private static function convertUrlForOStatusCallback($match) { $url = $match[1]; @@ -803,73 +784,24 @@ class BBCode return $match[0]; } - return self::convertUrlForMastodon($url); + return self::convertUrlForOStatus($url); } /** - * @brief Converts [url] BBCodes in a format that looks fine on Mastodon and GNU Social. + * @brief Converts [url] BBCodes in a format that looks fine on OStatus systems. * @param string $url URL that is about to be reformatted * @return string reformatted link including HTML codes */ - private static function convertUrlForMastodon($url) + private static function convertUrlForOStatus($url) { $parts = parse_url($url); $scheme = $parts['scheme'] . '://'; $styled_url = str_replace($scheme, '', $url); - $html = '' . - ''; - if (strlen($styled_url) > 30) { - $html .= '%s' . - ''; - - $ellipsis = substr($styled_url, 0, 30); - $rest = substr($styled_url, 30); - return sprintf($html, $url, $scheme, $ellipsis, $rest); - } else { - $html .= '%s'; - return sprintf($html, $url, $scheme, $styled_url); - } - } - - /** - * @brief Shortens [url] BBCodes in a format that looks less ugly than the full address. (callback function) - * @param array $match Array with the matching values - * @return string reformatted link including HTML codes - */ - private static function shortenVisibleUrlCallback($match) - { - $url = $match[1]; - - if (isset($match[2]) && ($match[1] != $match[2])) { - return $match[0]; - } - - $parts = parse_url($url); - if (!isset($parts['scheme'])) { - return $match[0]; + $styled_url = substr($styled_url, 0, 30) . "…"; } - return self::shortenVisibleUrl($url); - } - - /** - * @brief Shortens [url] BBCodes in a format that looks less ugly than the full address. - * @param string $url URL that is about to be reformatted - * @return string reformatted link including HTML codes - */ - private static function shortenVisibleUrl($url) - { - $parts = parse_url($url); - $scheme = $parts['scheme'] . '://'; - $styled_url = str_replace($scheme, '', $url); - -// Currently deactivated, due to preview problems inside of Diaspora -// if (strlen($styled_url) > 30) { -// $styled_url = substr($styled_url, 0, 30) . "…"; -// } - $html = '%s'; return sprintf($html, $url, $styled_url); @@ -1246,7 +1178,7 @@ class BBCode $text = Cache::get($match[1]); if (is_null($text)) { - $a = get_app(); + $a = self::getApp(); $stamp1 = microtime(true); @@ -1269,7 +1201,7 @@ class BBCode $doc = new DOMDocument(); @$doc->loadHTML($body); - $xpath = new DomXPath($doc); + $xpath = new DOMXPath($doc); $list = $xpath->query("//meta[@name]"); foreach ($list as $node) { $attr = []; @@ -1305,7 +1237,7 @@ class BBCode $text = Cache::get($match[1]); if (is_null($text)) { - $a = get_app(); + $a = self::getApp(); $stamp1 = microtime(true); @@ -1329,7 +1261,7 @@ class BBCode $doc = new DOMDocument(); @$doc->loadHTML($body); - $xpath = new DomXPath($doc); + $xpath = new DOMXPath($doc); $list = $xpath->query("//meta[@name]"); foreach ($list as $node) { $attr = []; @@ -1392,7 +1324,7 @@ class BBCode */ public static function convert($text, $try_oembed = true, $simple_html = false, $for_plaintext = false) { - $a = get_app(); + $a = self::getApp(); /* * preg_match_callback function to replace potential Oembed tags with Oembed content @@ -1441,7 +1373,7 @@ class BBCode // After we're finished processing the bbcode we'll // replace all of the event code with a reformatted version. - $ev = bbtoevent($text); + $ev = Event::fromBBCode($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 @@ -1501,11 +1433,8 @@ class BBCode $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::convertUrlForMastodonCallback', $text); - $text = preg_replace_callback("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", 'self::convertUrlForMastodonCallback', $text); - } else { - $text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism", 'self::shortenVisibleUrlCallback', $text); - $text = preg_replace_callback("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", 'self::shortenVisibleUrlCallback', $text); + $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); @@ -1605,8 +1534,8 @@ class BBCode if (strpos($text, '[/map]') !== false) { $text = preg_replace_callback( "/\[map\](.*?)\[\/map\]/ism", - function ($match) { - return str_replace($match[0], '

' . Map::byLocation($match[1]) . '

', $match[0]); + function ($match) use ($simple_html) { + return str_replace($match[0], '

' . Map::byLocation($match[1], $simple_html) . '

', $match[0]); }, $text ); @@ -1614,14 +1543,14 @@ class BBCode if (strpos($text, '[map=') !== false) { $text = preg_replace_callback( "/\[map=(.*?)\]/ism", - function ($match) { - return str_replace($match[0], '

' . Map::byCoordinates(str_replace('/', ' ', $match[1])) . '

', $match[0]); + function ($match) use ($simple_html) { + return str_replace($match[0], '

' . Map::byCoordinates(str_replace('/', ' ', $match[1]), $simple_html) . '

', $match[0]); }, $text ); } if (strpos($text, '[map]') !== false) { - $text = preg_replace("/\[map\]/", '
', $text); + $text = preg_replace("/\[map\]/", '

', $text); } // Check for headers @@ -1668,7 +1597,7 @@ class BBCode $text = preg_replace_callback( "(\[style=(.*?)\](.*?)\[\/style\])ism", function ($match) { - return "" . $match[2] . ""; + return "" . $match[2] . ""; }, $text ); @@ -1677,7 +1606,7 @@ class BBCode $text = preg_replace_callback( "(\[class=(.*?)\](.*?)\[\/class\])ism", function ($match) { - return "" . $match[2] . ""; + return "" . $match[2] . ""; }, $text ); @@ -1882,7 +1811,7 @@ class BBCode // start which is always required). Allow desc with a missing summary for compatibility. if ((x($ev, 'desc') || x($ev, 'summary')) && x($ev, 'start')) { - $sub = format_event_html($ev, $simple_html); + $sub = Event::getHTML($ev, $simple_html); $text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism", '', $text); $text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism", '', $text); @@ -2021,4 +1950,148 @@ class BBCode return $abstract; } + + /** + * @brief Callback function to replace a Friendica style mention in a mention for Diaspora + * + * @param array $match Matching values for the callback + * @return string Replaced mention + */ + private static function bbCodeMention2DiasporaCallback($match) + { + $contact = Contact::getDetailsByURL($match[3]); + + if (empty($contact['addr'])) { + $contact = Probe::uri($match[3]); + } + + if (empty($contact['addr'])) { + return $match[0]; + } + + $mention = '@{' . $match[2] . '; ' . $contact['addr'] . '}'; + return $mention; + } + + /** + * @brief Converts a BBCode text into Markdown + * + * This function converts a BBCode item body to be sent to Markdown-enabled + * systems like Diaspora and Libertree + * + * @param string $text + * @param bool $for_diaspora Diaspora requires more changes than Libertree + * @return string + */ + 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 + if ($for_diaspora) { + $text = self::removeShareInformation($text); + } + + /** + * Transform #tags, strip off the [url] and replace spaces with underscore + */ + $url_search_string = "^\[\]"; + $text = preg_replace_callback("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/i", + function ($matches) { + return '#' . str_replace(' ', '_', $matches[2]); + }, + $text + ); + + // Converting images with size parameters to simple images. Markdown doesn't know it. + $text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $text); + + // Extracting multi-line code blocks before the whitespace processing/code highlighter in self::convert() + $codeblocks = []; + + $text = preg_replace_callback("#\[code(?:=([^\]]*))?\](.*?)\[\/code\]#is", + function ($matches) use (&$codeblocks) { + $return = $matches[0]; + if (strpos($matches[2], "\n") !== false) { + $return = '#codeblock-' . count($codeblocks) . '#'; + + $prefix = '````' . $matches[1] . PHP_EOL; + $codeblocks[] = $prefix . trim($matches[2]) . PHP_EOL . '````'; + } + return $return; + }, + $text + ); + + // Convert it to HTML - don't try oembed + if ($for_diaspora) { + $text = self::convert($text, false, 3); + + // Add all tags that maybe were removed + if (preg_match_all("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/ism", $original_text, $tags)) { + $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)) { + $tagline .= '#' . $tag . ' '; + } + } + $text = $text . " " . $tagline; + } + } else { + $text = self::convert($text, false, 4); + } + + // 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); + + $stamp1 = microtime(true); + + // Now convert HTML to Markdown + $converter = new HtmlConverter(); + $text = $converter->convert($text); + + // unmask the special chars back to HTML + $text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['<', '>', '&'], $text); + + $a->save_timestamp($stamp1, "parser"); + + // Libertree has a problem with escaped hashtags. + $text = str_replace(['\#'], ['#'], $text); + + // Remove any leading or trailing whitespace, as this will mess up + // the Diaspora signature verification and cause the item to disappear + $text = trim($text); + + if ($for_diaspora) { + $url_search_string = "^\[\]"; + $text = preg_replace_callback( + "/([@]\[(.*?)\])\(([$url_search_string]*?)\)/ism", + ['self', 'bbCodeMention2DiasporaCallback'], + $text + ); + } + + // Restore code blocks + $text = preg_replace_callback('/#codeblock-([0-9]+)#/iU', + function ($matches) use ($codeblocks) { + $return = ''; + if (isset($codeblocks[intval($matches[1])])) { + $return = $codeblocks[$matches[1]]; + } + return $return; + }, + $text + ); + + Addon::callHooks('bb2diaspora', $text); + + return $text; + } }