X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FContent%2FText%2FBBCode.php;h=35f4979d11fe7ae943310e0d73b15488356ec857;hb=3e51a23bd50327b3a2a9fd5401ff504f6d2b1d08;hp=7d1c429765337e48d374f07c223eff9c18e7d0ed;hpb=2c00e3ad363c09fc40e6bebacdad4c027f002460;p=friendica.git diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 7d1c429765..35f4979d11 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -243,6 +243,9 @@ class BBCode extends BaseObject $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); + if (preg_match_all("(\[url=([$URLSearchString]*)\]\s*\[img\]([$URLSearchString]*)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) { if ((count($pictures) == 1) && !$has_title) { // Checking, if the link goes to a picture @@ -340,159 +343,30 @@ class BBCode extends BaseObject } /** - * @brief Convert a message into plaintext for connectors to other networks + * @brief Converts a BBCode text into plaintext * - * @param array $b The message array that is about to be posted - * @param int $limit The maximum number of characters when posting to that network - * @param bool $includedlinks Has an attached link to be included into the message? - * @param int $htmlmode This triggers the behaviour of the bbcode conversion - * @param string $target_network Name of the network where the post should go to. + * @param bool $keep_urls Whether to keep URLs in the resulting plaintext * - * @return string The converted message + * @return string */ - public static function toPlaintext($b, $limit = 0, $includedlinks = false, $htmlmode = 2, $target_network = "") + public static function toPlaintext($text, $keep_urls = true) { - // Remove the hash tags - $URLSearchString = "^\[\]"; - $body = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $b["body"]); - - // Add an URL element if the text contains a raw link - $body = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url]$2[/url]', $body); - - // Remove the abstract - $body = self::stripAbstract($body); - - // At first look at data that is attached via "type-..." stuff - // This will hopefully replaced with a dedicated bbcode later - //$post = self::getAttachedData($b["body"]); - $post = self::getAttachedData($body, $b); - - if (($b["title"] != "") && ($post["text"] != "")) { - $post["text"] = trim($b["title"]."\n\n".$post["text"]); - } elseif ($b["title"] != "") { - $post["text"] = trim($b["title"]); - } - - $abstract = ""; - - // Fetch the abstract from the given target network - if ($target_network != "") { - $default_abstract = self::getAbstract($b["body"]); - $abstract = self::getAbstract($b["body"], $target_network); - - // If we post to a network with no limit we only fetch - // an abstract exactly for this network - if (($limit == 0) && ($abstract == $default_abstract)) { - $abstract = ""; - } - } else {// Try to guess the correct target network - switch ($htmlmode) { - case 8: - $abstract = self::getAbstract($b["body"], NETWORK_TWITTER); - break; - case 7: - $abstract = self::getAbstract($b["body"], NETWORK_STATUSNET); - break; - case 6: - $abstract = self::getAbstract($b["body"], NETWORK_APPNET); - break; - default: // We don't know the exact target. - // We fetch an abstract since there is a posting limit. - if ($limit > 0) { - $abstract = self::getAbstract($b["body"]); - } - } - } - - if ($abstract != "") { - $post["text"] = $abstract; - - if ($post["type"] == "text") { - $post["type"] = "link"; - $post["url"] = $b["plink"]; - } - } - - $html = self::convert($post["text"].$post["after"], false, $htmlmode); - $msg = HTML::toPlaintext($html, 0, true); - $msg = trim(html_entity_decode($msg, ENT_QUOTES, 'UTF-8')); - - $link = ""; - if ($includedlinks) { - if ($post["type"] == "link") { - $link = $post["url"]; - } elseif ($post["type"] == "text") { - $link = $post["url"]; - } elseif ($post["type"] == "video") { - $link = $post["url"]; - } elseif ($post["type"] == "photo") { - $link = $post["image"]; - } - - if (($msg == "") && isset($post["title"])) { - $msg = trim($post["title"]); - } - - if (($msg == "") && isset($post["description"])) { - $msg = trim($post["description"]); - } - - // If the link is already contained in the post, then it neeedn't to be added again - // But: if the link is beyond the limit, then it has to be added. - if (($link != "") && strstr($msg, $link)) { - $pos = strpos($msg, $link); - - // Will the text be shortened in the link? - // Or is the link the last item in the post? - if (($limit > 0) && ($pos < $limit) && (($pos + 23 > $limit) || ($pos + strlen($link) == strlen($msg)))) { - $msg = trim(str_replace($link, "", $msg)); - } elseif (($limit == 0) || ($pos < $limit)) { - // The limit has to be increased since it will be shortened - but not now - // Only do it with Twitter (htmlmode = 8) - if (($limit > 0) && (strlen($link) > 23) && ($htmlmode == 8)) { - $limit = $limit - 23 + strlen($link); - } - - $link = ""; - - if ($post["type"] == "text") { - unset($post["url"]); - } - } - } + $naked_text = preg_replace('/\[(.+?)\]/','', $text); + if (!$keep_urls) { + $naked_text = preg_replace('#https?\://[^\s<]+[^\s\.\)]#i', '', $naked_text); } - if ($limit > 0) { - // Reduce multiple spaces - // When posted to a network with limited space, we try to gain space where possible - while (strpos($msg, " ") !== false) { - $msg = str_replace(" ", " ", $msg); - } - - // Twitter is using its own limiter, so we always assume that shortened links will have this length - if (iconv_strlen($link, "UTF-8") > 0) { - $limit = $limit - 23; - } + return $naked_text; + } - if (iconv_strlen($msg, "UTF-8") > $limit) { - if (($post["type"] == "text") && isset($post["url"])) { - $post["url"] = $b["plink"]; - } elseif (!isset($post["url"])) { - $limit = $limit - 23; - $post["url"] = $b["plink"]; - // Which purpose has this line? It is now uncommented, but left as a reminder - //} elseif (strpos($b["body"], "[share") !== false) { - // $post["url"] = $b["plink"]; - } elseif (PConfig::get($b["uid"], "system", "no_intelligent_shortening")) { - $post["url"] = $b["plink"]; - } - $msg = Plaintext::shorten($msg, $limit); - } + private static function proxyUrl($image, $simplehtml = false) + { + // Only send proxied pictures to API and for internal display + if (in_array($simplehtml, [false, 2])) { + return proxy_url($image); + } else { + return $image; } - - $post["text"] = trim($msg); - - return($post); } public static function scaleExternalImages($srctext, $include_link = true, $scale_replace = false) @@ -698,13 +572,13 @@ class BBCode extends BaseObject } if ($data["image"] != "") { - $return .= sprintf('
', $data["url"], proxy_url($data["image"]), $data["title"]); + $return .= sprintf('
', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]); } elseif ($data["preview"] != "") { - $return .= sprintf('
', $data["url"], proxy_url($data["preview"]), $data["title"]); + $return .= sprintf('
', $data["url"], self::proxyUrl($data["preview"], $simplehtml), $data["title"]); } if (($data["type"] == "photo") && ($data["url"] != "") && ($data["image"] != "")) { - $return .= sprintf('', $data["url"], proxy_url($data["image"]), $data["title"]); + $return .= sprintf('', $data["url"], self::proxyUrl($data["image"], $simplehtml), $data["title"]); } else { $return .= sprintf('

%s

', $data['url'], $data['title']); } @@ -975,7 +849,7 @@ class BBCode extends BaseObject // it loops over the array starting from the first element and going sequentially // to the last element $newbody = str_replace('[$#saved_image' . $cnt . '#$]', - '' . L10n::t('Image/photo') . '', $newbody); + '' . L10n::t('Image/photo') . '', $newbody); $cnt++; } @@ -1292,13 +1166,17 @@ class BBCode extends BaseObject private static function textHighlightCallback($match) { + // Fallback in case the language doesn't exist + $return = '[code]' . $match[2] . '[/code]'; + if (in_array(strtolower($match[1]), ['php', 'css', 'mysql', 'sql', 'abap', 'diff', 'html', 'perl', 'ruby', - 'vbscript', 'avrc', 'dtd', 'java', 'xml', 'cpp', 'python', 'javascript', 'js', 'sh']) + 'vbscript', 'avrc', 'dtd', 'java', 'xml', 'cpp', 'python', 'javascript', 'js', 'sh', 'bash']) ) { - return text_highlight($match[2], strtolower($match[1])); + $return = text_highlight($match[2], strtolower($match[1])); } - return $match[0]; + + return $return; } /** @@ -1576,7 +1454,7 @@ class BBCode extends BaseObject $text = preg_replace("(\[u\](.*?)\[\/u\])ism", '$1', $text); // Check for strike-through text - $text = preg_replace("(\[s\](.*?)\[\/s\])ism", '$1', $text); + $text = preg_replace("(\[s\](.*?)\[\/s\])ism", '$1', $text); // Check for over-line text $text = preg_replace("(\[o\](.*?)\[\/o\])ism", '$1', $text); @@ -1703,12 +1581,12 @@ class BBCode extends BaseObject // [img=widthxheight]image source[/img] $text = preg_replace_callback( "/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", - function ($matches) { + function ($matches) use ($simple_html) { if (strpos($matches[3], "data:image/") === 0) { return $matches[0]; } - $matches[3] = proxy_url($matches[3]); + $matches[3] = self::proxyUrl($matches[3], $simple_html); return "[img=" . $matches[1] . "x" . $matches[2] . "]" . $matches[3] . "[/img]"; }, $text @@ -1717,16 +1595,24 @@ 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", + function ($matches) use ($simple_html) { + $matches[1] = self::proxyUrl($matches[1], $simple_html); + $matches[2] = htmlspecialchars($matches[2], ENT_COMPAT); + return '' . $matches[2] . ''; + }, + $text); + // Images // [img]pathtoimage[/img] $text = preg_replace_callback( "/\[img\](.*?)\[\/img\]/ism", - function ($matches) { + function ($matches) use ($simple_html) { if (strpos($matches[1], "data:image/") === 0) { return $matches[0]; } - $matches[1] = proxy_url($matches[1]); + $matches[1] = self::proxyUrl($matches[1], $simple_html); return "[img]" . $matches[1] . "[/img]"; }, $text @@ -1747,15 +1633,15 @@ class BBCode extends BaseObject // Try to Oembed if ($try_oembed) { - $text = preg_replace("/\[video\](.*?\.(ogg|ogv|oga|ogm|webm|mp4))\[\/video\]/ism", '', $text); - $text = preg_replace("/\[audio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3))\[\/audio\]/ism", '', $text); + $text = preg_replace("/\[video\](.*?\.(ogg|ogv|oga|ogm|webm|mp4).*?)\[\/video\]/ism", '', $text); + $text = preg_replace("/\[audio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3).*?)\[\/audio\]/ism", '', $text); $text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", $try_oembed_callback, $text); $text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", $try_oembed_callback, $text); } else { - $text = preg_replace("/\[video\](.*?)\[\/video\]/", + $text = preg_replace("/\[video\](.*?)\[\/video\]/ism", '$1', $text); - $text = preg_replace("/\[audio\](.*?)\[\/audio\]/", + $text = preg_replace("/\[audio\](.*?)\[\/audio\]/ism", '$1', $text); } @@ -1848,10 +1734,12 @@ class BBCode extends BaseObject $text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'self::unescapeNoparseCallback', $text); $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'self::unescapeNoparseCallback', $text); - + /// @todo What is the meaning of these lines? $text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $text); $text = preg_replace('/\&\#039\;/', '\'', $text); - $text = preg_replace('/\"\;/', '"', $text); + + // Currently deactivated, it made problems with " inside of alt texts. + //$text = preg_replace('/\"\;/', '"', $text); // fix any escaped ampersands that may have been converted into links $text = preg_replace('/\<([^>]*?)(src|href)=(.*?)\&\;(.*?)\>/ism', '<$1$2=$3&$4>', $text); @@ -1930,7 +1818,7 @@ class BBCode extends BaseObject * @param string $addon The addon for which the abstract is meant for * @return string The abstract */ - private static function getAbstract($text, $addon = "") + public static function getAbstract($text, $addon = "") { $abstract = ""; $abstracts = [];