X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FContent%2FText%2FBBCode.php;h=da09e13dd9b8dfc5a243a9480d4b3de5b9207186;hb=9bf065c9d8343ff2d2b6b5a7514a78471a0bedd4;hp=6d2b152ee8de490c8013f3364023b2ac63aaeb8a;hpb=fabc90e9dd5f1c4280a9bfa6c6930a3fc985f87a;p=friendica.git
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index 6d2b152ee8..da09e13dd9 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -11,9 +11,9 @@ use Exception;
use Friendica\BaseObject;
use Friendica\Content\OEmbed;
use Friendica\Content\Smilies;
-use Friendica\Core\Addon;
use Friendica\Core\Cache;
use Friendica\Core\Config;
+use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
@@ -37,13 +37,14 @@ class BBCode extends BaseObject
*
* @param string $body Message body
* @return array
- * 'type' -> Message type ("link", "video", "photo")
- * 'text' -> Text before the shared message
- * 'after' -> Text after the shared message
- * 'image' -> Preview image of the message
- * 'url' -> Url to the attached message
- * 'title' -> Title of the attachment
- * 'description' -> Description of the attachment
+ * 'type' -> Message type ("link", "video", "photo")
+ * 'text' -> Text before the shared message
+ * 'after' -> Text after the shared message
+ * 'image' -> Preview image of the message
+ * 'url' -> Url to the attached message
+ * 'title' -> Title of the attachment
+ * 'description' -> Description of the attachment
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function getOldAttachmentData($body)
{
@@ -66,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]);
@@ -85,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];
}
@@ -108,13 +108,14 @@ class BBCode extends BaseObject
*
* @param string $body Message body
* @return array
- * 'type' -> Message type ("link", "video", "photo")
- * 'text' -> Text before the shared message
- * 'after' -> Text after the shared message
- * 'image' -> Preview image of the message
- * 'url' -> Url to the attached message
- * 'title' -> Title of the attachment
- * 'description' -> Description of the attachment
+ * 'type' -> Message type ("link", "video", "photo")
+ * 'text' -> Text before the shared message
+ * 'after' -> Text after the shared message
+ * 'image' -> Preview image of the message
+ * 'url' -> Url to the attached message
+ * 'title' -> Title of the attachment
+ * 'description' -> Description of the attachment
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function getAttachmentData($body)
{
@@ -242,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.
@@ -268,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) {
@@ -284,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];
@@ -298,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);
@@ -345,13 +350,14 @@ class BBCode extends BaseObject
/**
* @brief Converts a BBCode text into plaintext
*
+ * @param $text
* @param bool $keep_urls Whether to keep URLs in the resulting plaintext
*
* @return string
*/
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);
}
@@ -446,6 +452,7 @@ class BBCode extends BaseObject
* @brief Truncates imported message body string length to max_import_size
* @param string $body
* @return string
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function limitBodySize($body)
{
@@ -532,10 +539,11 @@ class BBCode extends BaseObject
* Note: Can produce a [bookmark] tag in the returned string
*
* @brief Processes [attachment] tags
- * @param string $return
+ * @param string $return
* @param bool|int $simplehtml
- * @param bool $tryoembed
+ * @param bool $tryoembed
* @return string
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function convertAttachment($return, $simplehtml = false, $tryoembed = true)
{
@@ -557,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"]);
@@ -777,10 +785,10 @@ class BBCode extends BaseObject
/**
* Performs a preg_replace within the boundaries of all named BBCode tags in a text
*
- * @param type $pattern Preg pattern string
- * @param type $replace Preg replace string
- * @param type $name BBCode tag name
- * @param type $text Text to search
+ * @param string $pattern Preg pattern string
+ * @param string $replace Preg replace string
+ * @param string $name BBCode tag name
+ * @param string $text Text to search
* @return string
*/
public static function pregReplaceInTag($pattern, $replace, $name, $text)
@@ -930,6 +938,7 @@ class BBCode extends BaseObject
* @param boolean $is_quote_share Whether there is content before the [share] block
* @param integer $simplehtml Mysterious integer value depending on the target network/formatting style
* @return string
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function convertShareCallback(array $attributes, array $author_contact, $content, $is_quote_share, $simplehtml)
{
@@ -943,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['author'] . ':
' . "\n"; + + if (!empty($attributes['posted']) && !empty($attributes['link'])) { + $headline = 'â² ' . $attributes['author'] . ' - ' . $attributes['posted'] . ' GMT
' . "\n"; + } + $text = ($is_quote_share? '' . trim($content) . '' . "\n"; - if ($attributes['link'] != '') { - $text .= '' . "\n"; + if (empty($attributes['posted']) && !empty($attributes['link'])) { + $text .= '' . "\n"; } } @@ -968,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'])) { @@ -1021,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]"; @@ -1080,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/") { @@ -1129,21 +1135,23 @@ 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 * @param int $simple_html * @param bool $for_plaintext * @return string + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function convert($text, $try_oembed = true, $simple_html = false, $for_plaintext = false) + public static function convert($text, $try_oembed = true, $simple_html = 0, $for_plaintext = false) { $a = self::getApp(); @@ -1168,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
@@ -1237,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",
@@ -1249,130 +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"], ['$1
';
- // Check for [code] text
- $text = preg_replace("/\[code\](.*?)\[\/code\]/ism", "$CodeLayout", $text);
-
// Declare the format for [spoiler] layout
$SpoilerLayout = '$1'; @@ -1513,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", - "
$2", - $text); + "
$2", + $text); } // Declare the format for [quote] layout @@ -1535,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); } @@ -1557,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); @@ -1583,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", '