aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/bbcode.php660
-rw-r--r--include/network.php7
-rw-r--r--tests/unit/includes/BBCodeTest.php138
3 files changed, 479 insertions, 326 deletions
diff --git a/include/bbcode.php b/include/bbcode.php
index a1e56b15f..54c2330ab 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -809,36 +809,56 @@ function oblanguage_necallback($matches) {
return '';
}
-function bb_observer($Text) {
-
- $observer = App::get_observer();
+/**
+ * Process [observer] tags in the source text.
+ *
+ * @param string $text The source BBCode text.
+ * @param ?array $observer Array containing the observer we render for, or
+ * null if none.
+ *
+ * @return A string where the [observer] tags have been processed.
+ */
+function bb_observer(string $text, ?array $observer): string {
- if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
+ if ((strpos($text,'[/observer]') !== false) || (strpos($text,'[/rpost]') !== false)) {
+ $text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $text);
+ $text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $text);
if ($observer) {
- $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text);
+ $text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $text);
+ $text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $text);
+ $text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $text);
} else {
- $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text);
+ $text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $text);
+ $text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $text);
+ $text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $text);
}
}
- $channel = App::get_channel();
+ return $text;
+}
+
+/**
+ * Process [channel] tags in the source text.
+ *
+ * @param string $text The source BBCode text.
+ * @param ?array $channel Array containing the channel we render for, or
+ * null if none.
+ *
+ * @return A string where the [channel] tags have been processed.
+ */
+function bb_channel(string $text, ?array $channel): string {
- if (strpos($Text,'[/channel]') !== false) {
+ if (strpos($text,'[/channel]') !== false) {
if ($channel) {
- $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text);
- $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text);
+ $text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $text);
+ $text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $text);
} else {
- $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text);
- $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text);
+ $text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $text);
+ $text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $text);
}
}
-
- return $Text;
+ return $text;
}
function bb_imgoptions($match) {
@@ -957,7 +977,7 @@ function bb_code_unprotect_sub($match) {
}
function bb_code($match) {
- if(strpos($match[0], PHP_EOL))
+ if(strpos($match[0], PHP_EOL) !== false)
return '<pre><code>' . bb_code_protect(trim($match[1])) . '</code></pre>';
else
return '<code class="inline-code">' . bb_code_protect(trim($match[1])) . '</code>';
@@ -1095,9 +1115,22 @@ function parseIdentityAwareHTML($Text) {
}
-function bbcode($Text, $options = []) {
+/**
+ * Converts Hubzilla flavoured BBCode to HTML.
+ *
+ * @param string $text BBCode formatted text
+ *
+ * @param array $options Optional arguments to controll how the conversion
+ * is to be done.
+ * - `tryoembed` (`true`) - Whether we should try to generate link previews/oembeds.
+ * - `cache` (`false`) - Avoids some processing if true, unsure about the significancd of it for now.
+ * - `newwin` (`true`) - Wether links should open in a new window (`target="_blank"`)
+ *
+ * @return A string containing the resulting HTML code.
+ */
+function bbcode($text, $options = []) {
- if (!$Text) {
+ if (!$text) {
return EMPTY_STR;
}
@@ -1105,139 +1138,119 @@ function bbcode($Text, $options = []) {
$options = [];
}
- $preserve_nl = ((array_key_exists('preserve_nl',$options)) ? $options['preserve_nl'] : false);
$tryoembed = ((array_key_exists('tryoembed',$options)) ? $options['tryoembed'] : true);
$cache = ((array_key_exists('cache',$options)) ? $options['cache'] : false);
$newwin = ((array_key_exists('newwin',$options)) ? $options['newwin'] : true);
$target = (($newwin) ? ' target="_blank" ' : '');
- call_hooks('bbcode_filter', $Text);
+ /**
+ * @hooks bbcode_filter
+ * * _string_ **bbcode** - The raw bbcode input before converting it to HTML.
+ */
+ call_hooks('bbcode_filter', $text);
if(isset($options['drop_media'])) {
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace('/\[img(.*?)\[\/(img)\]/ism', '', $Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace('/\[img(.*?)\[\/(img)\]/ism', '', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace('/\[audio(.*?)\[\/(audio)\]/ism', '', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace('/\[audio(.*?)\[\/(audio)\]/ism', '', $text);
}
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace('/\[video(.*?)\[\/(video)\]/ism', '', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace('/\[video(.*?)\[\/(video)\]/ism', '', $text);
}
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace('/\[zmg(.*?)\[\/(zmg)\]/ism', '', $Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace('/\[zmg(.*?)\[\/(zmg)\]/ism', '', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace('/\[zaudio(.*?)\[\/(zaudio)\]/ism', '', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace('/\[zaudio(.*?)\[\/(zaudio)\]/ism', '', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace('/\[zvideo(.*?)\[\/(zvideo)\]/ism', '', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace('/\[zvideo(.*?)\[\/(zvideo)\]/ism', '', $text);
}
}
- $Text = bb_format_attachdata($Text);
+ $text = bb_format_attachdata($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.
- $ev = bbtoevent($Text);
+ $ev = bbtoevent($text);
// and the same with polls
- $pl = bbtopoll($Text);
+ $pl = bbtopoll($text);
- // process [observer] tags before we do anything else because we might
- // be stripping away stuff that then doesn't need to be worked on anymore
-
- if($cache)
+ if($cache) {
$observer = false;
- else
+ $channel = false;
+ } else {
$observer = App::get_observer();
-
- if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
- $Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $Text);
- $Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $Text);
-
- if ($observer) {
- $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text);
- } else {
- $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text);
- }
+ $channel = App::get_channel();
}
- if($cache)
- $channel = false;
- else
- $channel = App::get_channel();
+ // process [observer] and [channel] tags before we do anything else because
+ // we might be stripping away stuff that then doesn't need to be worked on
+ // anymore
- if (strpos($Text,'[/channel]') !== false) {
- if ($channel) {
- $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text);
- $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text);
- } else {
- $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text);
- $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text);
- }
- }
+ $text = bb_observer($text, $observer);
+ $text = bb_channel($text, $channel);
- $x = bb_extract_images($Text);
- $Text = $x['body'];
+ $x = bb_extract_images($text);
+ $text = $x['body'];
$saved_images = $x['images'];
- $Text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$Text);
+ $text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$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
- $Text = str_replace("<", "&lt;", $Text);
- $Text = str_replace(">", "&gt;", $Text);
- $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$Text);
- $Text = str_replace(array("\t", " "), array("&nbsp;&nbsp;&nbsp;&nbsp;", "&nbsp;&nbsp;"), $Text);
+ $text = str_replace("<", "&lt;", $text);
+ $text = str_replace(">", "&gt;", $text);
+ $text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$text);
+ $text = str_replace(array("\t", " "), array("&nbsp;&nbsp;&nbsp;&nbsp;", "&nbsp;&nbsp;"), $text);
// Check for [code] text here, before the linefeeds are messed with.
// The highlighter will unescape and re-escape the content.
- if (strpos($Text,'[code=') !== false) {
- $Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text);
+ if (strpos($text,'[code=') !== false) {
+ $text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $text);
}
// Check for [code] text
- if (strpos($Text,'[code]') !== false) {
- $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text);
+ if (strpos($text,'[code]') !== false) {
+ $text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $text);
}
// Check for [code options] text
- if (strpos($Text,'[code ') !== false) {
- $Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $Text);
+ if (strpos($text,'[code ') !== false) {
+ $text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $text);
}
// Hide all [noparse] contained bbtags by spacefying them
- if (strpos($Text,'[noparse]') !== false) {
- $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[noparse]') !== false) {
+ $text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[nobb]') !== false) {
- $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[nobb]') !== false) {
+ $text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[pre]') !== false) {
- $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[pre]') !== false) {
+ $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[summary]') !== false) {
- $Text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[summary]') !== false) {
+ $text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace_callback('/\[img(.*?)\[\/(img)\]/ism','\red_escape_codeblock',$Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace_callback('/\[img(.*?)\[\/(img)\]/ism','\red_escape_codeblock',$text);
}
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace_callback('/\[zmg(.*?)\[\/(zmg)\]/ism','\red_escape_codeblock',$Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace_callback('/\[zmg(.*?)\[\/(zmg)\]/ism','\red_escape_codeblock',$text);
}
// Set up the parameters for a URL search string
@@ -1251,19 +1264,19 @@ function bbcode($Text, $options = []) {
$s2 = '</span>';
$obsBaseURL = $observer['xchan_connurl'];
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
- $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text);
- $Text = str_replace('[observer.url]',$observer['xchan_url'], $Text);
- $Text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $Text);
- $Text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $Text);
- $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text);
- $Text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text);
+ $text = str_replace('[observer.baseurl]', $obsBaseURL, $text);
+ $text = str_replace('[observer.url]',$observer['xchan_url'], $text);
+ $text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $text);
+ $text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $text);
+ $text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $text);
+ $text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $text);
} else {
- $Text = str_replace('[observer.baseurl]', '', $Text);
- $Text = str_replace('[observer.url]','', $Text);
- $Text = str_replace('[observer.name]','', $Text);
- $Text = str_replace('[observer.address]','', $Text);
- $Text = str_replace('[observer.webname]','',$Text);
- $Text = str_replace('[observer.photo]','', $Text);
+ $text = str_replace('[observer.baseurl]', '', $text);
+ $text = str_replace('[observer.url]','', $text);
+ $text = str_replace('[observer.name]','', $text);
+ $text = str_replace('[observer.address]','', $text);
+ $text = str_replace('[observer.webname]','',$text);
+ $text = str_replace('[observer.photo]','', $text);
}
@@ -1272,257 +1285,257 @@ function bbcode($Text, $options = []) {
$urlchars = '[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]';
- if (strpos($Text,'http') !== false) {
+ if (strpos($text,'http') !== false) {
if($tryoembed) {
- $Text = preg_replace_callback("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", 'tryoembed', $Text);
+ $text = preg_replace_callback("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", 'tryoembed', $text);
}
// Is this still desired?
// We already turn naked URLs into links during creation time cleanup_bbcode()
- $Text = preg_replace("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $Text);
+ $text = preg_replace("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $text);
}
$count = 0;
- while (strpos($Text,'[/share]') !== false && $count < 10) {
- $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $Text);
+ while (strpos($text,'[/share]') !== false && $count < 10) {
+ $text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $text);
$count ++;
}
if($tryoembed) {
- if (strpos($Text,'[/url]') !== false) {
- $Text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/url]') !== false) {
+ $text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $text);
}
}
- if (strpos($Text,'[/url]') !== false) {
- $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
- $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
+ if (strpos($text,'[/url]') !== false) {
+ $text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
+ $text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
}
- if (strpos($Text,'[/zrl]') !== false) {
- $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
- $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
+ if (strpos($text,'[/zrl]') !== false) {
+ $text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
+ $text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
}
// Perform MAIL Search
- if (strpos($Text,'[/mail]') !== false) {
- $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
+ if (strpos($text,'[/mail]') !== false) {
+ $text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
}
// leave open the posibility of [map=something]
// this is replaced in prepare_body() which has knowledge of the item location
if ($cache) {
- $Text = str_replace([ '[map]','[/map]' ], [ '','' ], $Text);
- $Text = preg_replace('/\[map=(.*?)\]/ism','$1',$Text);
+ $text = str_replace([ '[map]','[/map]' ], [ '','' ], $text);
+ $text = preg_replace('/\[map=(.*?)\]/ism','$1',$text);
}
else {
- if (strpos($Text,'[/map]') !== false) {
- $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text);
+ if (strpos($text,'[/map]') !== false) {
+ $text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $text);
}
- if (strpos($Text,'[map=') !== false) {
- $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text);
+ if (strpos($text,'[map=') !== false) {
+ $text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $text);
}
- if (strpos($Text,'[map]') !== false) {
- $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text);
+ if (strpos($text,'[map]') !== false) {
+ $text = preg_replace("/\[map\]/", '<div class="map"></div>', $text);
}
}
// Check for bold text
- if (strpos($Text,'[b]') !== false) {
- $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $Text);
+ if (strpos($text,'[b]') !== false) {
+ $text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $text);
}
// Check for Italics text
- if (strpos($Text,'[i]') !== false) {
- $Text = preg_replace("(\[i\](.*?)\[\/i\])ism", '<em>$1</em>', $Text);
+ if (strpos($text,'[i]') !== false) {
+ $text = preg_replace("(\[i\](.*?)\[\/i\])ism", '<em>$1</em>', $text);
}
// Check for Underline text
- if (strpos($Text,'[u]') !== false) {
- $Text = preg_replace("(\[u\](.*?)\[\/u\])ism", '<u>$1</u>', $Text);
+ if (strpos($text,'[u]') !== false) {
+ $text = preg_replace("(\[u\](.*?)\[\/u\])ism", '<u>$1</u>', $text);
}
// Check for strike-through text
- if (strpos($Text,'[s]') !== false) {
- $Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<span style="text-decoration: line-through;">$1</span>', $Text);
+ if (strpos($text,'[s]') !== false) {
+ $text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<span style="text-decoration: line-through;">$1</span>', $text);
}
// Check for over-line text
- if (strpos($Text,'[o]') !== false) {
- $Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span style="text-decoration: overline;">$1</span>', $Text);
+ if (strpos($text,'[o]') !== false) {
+ $text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span style="text-decoration: overline;">$1</span>', $text);
}
- if (strpos($Text,'[sup]') !== false) {
- $Text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '<sup>$1</sup>', $Text);
+ if (strpos($text,'[sup]') !== false) {
+ $text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '<sup>$1</sup>', $text);
}
- if (strpos($Text,'[sub]') !== false) {
- $Text = preg_replace("(\[sub\](.*?)\[\/sub\])ism", '<sub>$1</sub>', $Text);
+ if (strpos($text,'[sub]') !== false) {
+ $text = preg_replace("(\[sub\](.*?)\[\/sub\])ism", '<sub>$1</sub>', $text);
}
// Check for colored text
- if (strpos($Text,'[/color]') !== false) {
- $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "<span style=\"color: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/color]') !== false) {
+ $text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "<span style=\"color: $1;\">$2</span>", $text);
}
// @DEPRECATED: Check for colored text (deprecated in favor of mark which is a html5 standard)
- if (strpos($Text,'[/hl]') !== false) {
- $Text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "<span class=\"default-highlight\">$1</span>", $Text);
- $Text = preg_replace("(\[hl=(.*?)\](.*?)\[\/hl\])ism", "<span style=\"background-color: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/hl]') !== false) {
+ $text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "<span class=\"default-highlight\">$1</span>", $text);
+ $text = preg_replace("(\[hl=(.*?)\](.*?)\[\/hl\])ism", "<span style=\"background-color: $1;\">$2</span>", $text);
}
- if (strpos($Text,'[/mark]') !== false) {
- $Text = preg_replace("(\[mark\](.*?)\[\/mark\])ism", "<mark class=\"mark\">$1</mark>", $Text);
- $Text = preg_replace("(\[mark=(.*?)\](.*?)\[\/mark\])ism", "<mark style=\"background-color: $1;\">$2</mark>", $Text);
+ if (strpos($text,'[/mark]') !== false) {
+ $text = preg_replace("(\[mark\](.*?)\[\/mark\])ism", "<mark class=\"mark\">$1</mark>", $text);
+ $text = preg_replace("(\[mark=(.*?)\](.*?)\[\/mark\])ism", "<mark style=\"background-color: $1;\">$2</mark>", $text);
}
// Check for sized text
// [size=50] --> font-size: 50px (with the unit).
- if (strpos($Text,'[/size]') !== false) {
- $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px;\">$2</span>", $Text);
- $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/size]') !== false) {
+ $text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px;\">$2</span>", $text);
+ $text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1;\">$2</span>", $text);
}
// Check for h1
- if (strpos($Text,'[h1]') !== false) {
- $Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$Text);
- $Text = str_replace(["</h1>\n\n", "</h1>\n"], '</h1>', $Text);
+ if (strpos($text,'[h1]') !== false) {
+ $text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$text);
+ $text = str_replace(["</h1>\n\n", "</h1>\n"], '</h1>', $text);
}
// Check for h2
- if (strpos($Text,'[h2]') !== false) {
- $Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$Text);
- $Text = str_replace(["</h2>\n\n", "</h2>\n"], '</h2>', $Text);
+ if (strpos($text,'[h2]') !== false) {
+ $text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$text);
+ $text = str_replace(["</h2>\n\n", "</h2>\n"], '</h2>', $text);
}
// Check for h3
- if (strpos($Text,'[h3]') !== false) {
- $Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$Text);
- $Text = str_replace(["</h3>\n\n", "</h3>\n"], '</h3>', $Text);
+ if (strpos($text,'[h3]') !== false) {
+ $text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$text);
+ $text = str_replace(["</h3>\n\n", "</h3>\n"], '</h3>', $text);
}
// Check for h4
- if (strpos($Text,'[h4]') !== false) {
- $Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$Text);
- $Text = str_replace(["</h4>\n\n", "</h4>\n"], '</h4>', $Text);
+ if (strpos($text,'[h4]') !== false) {
+ $text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$text);
+ $text = str_replace(["</h4>\n\n", "</h4>\n"], '</h4>', $text);
}
// Check for h5
- if (strpos($Text,'[h5]') !== false) {
- $Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
- $Text = str_replace(["</h5>\n\n", "</h5>\n"], '</h5>', $Text);
+ if (strpos($text,'[h5]') !== false) {
+ $text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$text);
+ $text = str_replace(["</h5>\n\n", "</h5>\n"], '</h5>', $text);
}
// Check for h6
- if (strpos($Text,'[h6]') !== false) {
- $Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
- $Text = str_replace(["</h6>\n\n", "</h6>\n"], '</h6>', $Text);
+ if (strpos($text,'[h6]') !== false) {
+ $text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$text);
+ $text = str_replace(["</h6>\n\n", "</h6>\n"], '</h6>', $text);
}
// Check for table of content without params
- while(strpos($Text,'[toc]') !== false) {
+ while(strpos($text,'[toc]') !== false) {
$toc_id = 'toc-' . random_string(10);
- $Text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc"></ul><script>$(document).ready(function() { let toc_container = $("#' . $toc_id . '").parent().closest("div").attr("id") || ".section-content-wrapper"; $("#' . $toc_id . '").toc({content: "#" + toc_container, headings: "h1,h2,h3,h4"}); });</script>', $Text, 1);
+ $text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc"></ul><script>$(document).ready(function() { let toc_container = $("#' . $toc_id . '").parent().closest("div").attr("id") || ".section-content-wrapper"; $("#' . $toc_id . '").toc({content: "#" + toc_container, headings: "h1,h2,h3,h4"}); });</script>', $text, 1);
}
// Check for table of content with params
- while(strpos($Text,'[toc') !== false) {
+ while(strpos($text,'[toc') !== false) {
$toc_id = 'toc-' . random_string(10);
- $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '<ul id="' . $toc_id . '" class="toc" $1></ul><script>$("#' . $toc_id . '").toc();</script>', $Text, 1);
+ $text = preg_replace("/\[toc([^\]]+?)\]/ism", '<ul id="' . $toc_id . '" class="toc" $1></ul><script>$("#' . $toc_id . '").toc();</script>', $text, 1);
}
// Check for centered text
- if (strpos($Text,'[/center]') !== false) {
- $Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
+ if (strpos($text,'[/center]') !== false) {
+ $text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $text);
}
// Check for footer
- if (strpos($Text,'[/footer]') !== false) {
- $Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $Text);
+ if (strpos($text,'[/footer]') !== false) {
+ $text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $text);
}
// Check for bdi
- if (strpos($Text,'[/bdi]') !== false) {
- $Text = preg_replace("(\[bdi\](.*?)\[\/bdi\])ism", "<bdi>$1</bdi>", $Text);
+ if (strpos($text,'[/bdi]') !== false) {
+ $text = preg_replace("(\[bdi\](.*?)\[\/bdi\])ism", "<bdi>$1</bdi>", $text);
}
// Check for list text
- $Text = preg_replace("/<br \/>\[\*\]/ism",'[*]',$Text);
+ $text = preg_replace("/<br \/>\[\*\]/ism",'[*]',$text);
- $Text = str_replace("[*]", "<li>", $Text);
+ $text = str_replace("[*]", "<li>", $text);
// handle nested lists
$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, "[/dl]") !== false) && (strpos($Text, "[dl") !== false)) ||
- ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
- $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet">$1</ul>', $Text);
- $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>', $Text);
- $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>', $Text);
- $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet">$1</ul>', $Text);
- $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
- $Text = preg_replace("/\[\/li\]<br \/>\[li\]/ism",'[/li][li]',$Text);
- $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $Text);
+ 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, "[/dl]") !== false) && (strpos($text, "[dl") !== false)) ||
+ ((strpos($text, "[/li]") !== false) && (strpos($text, "[li]") !== false))) && (++$endlessloop < 20)) {
+ $text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet">$1</ul>', $text);
+ $text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>', $text);
+ $text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $text);
+ $text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>', $text);
+ $text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>', $text);
+ $text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>', $text);
+ $text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>', $text);
+ $text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet">$1</ul>', $text);
+ $text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $text);
+ $text = preg_replace("/\[\/li\]<br \/>\[li\]/ism",'[/li][li]',$text);
+ $text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $text);
// [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large
// etc. style may be specified for the "terms" in the definition list. The quotation marks
// are also optional. The regex looks intimidating, but breaks down as:
// "[dl" <optional-whitespace> <optional-termStyles> "]" <matchGroup2> "[/dl]"
// where optional-termStyles are: "terms=" <optional-quote> <matchGroup1> <optional-quote>
- $Text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:&quot;|")?([a-zA-Z]+)(?:&quot;|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $Text);
+ $text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:&quot;|")?([a-zA-Z]+)(?:&quot;|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $text);
}
- if (strpos($Text,'[checklist]') !== false) {
- $Text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $Text);
+ if (strpos($text,'[checklist]') !== false) {
+ $text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $text);
}
- if (strpos($Text,'[th]') !== false) {
- $Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>', $Text);
+ if (strpos($text,'[th]') !== false) {
+ $text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>', $text);
}
- if (strpos($Text,'[td]') !== false) {
- $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>', $Text);
+ if (strpos($text,'[td]') !== false) {
+ $text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>', $text);
}
- if (strpos($Text,'[tr]') !== false) {
- $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>', $Text);
+ if (strpos($text,'[tr]') !== false) {
+ $text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>', $text);
}
- if (strpos($Text,'[/table]') !== false) {
- $Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>', $Text);
- $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table class="table table-responsive table-bordered" >$1</table>', $Text);
- $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table class="table table-responsive" >$1</table>', $Text);
+ if (strpos($text,'[/table]') !== false) {
+ $text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>', $text);
+ $text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table class="table table-responsive table-bordered" >$1</table>', $text);
+ $text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table class="table table-responsive" >$1</table>', $text);
}
- $Text = str_replace('</tr><br /><tr>', "</tr>\n<tr>", $Text);
- $Text = str_replace('[hr]', '<hr />', $Text);
+ $text = str_replace('</tr><br /><tr>', "</tr>\n<tr>", $text);
+ $text = str_replace('[hr]', '<hr />', $text);
// This is actually executed in prepare_body()
- $Text = str_replace('[nosmile]', '', $Text);
+ $text = str_replace('[nosmile]', '', $text);
// Check for font change text
- if (strpos($Text,'[/font]') !== false) {
- $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/font]') !== false) {
+ $text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $text);
}
// Check for [spoiler] text
$endlessloop = 0;
- while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text);
+ while ((strpos($text, "[/spoiler]")!== false) and (strpos($text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $text);
}
// Check for [spoiler=Author] text
$endlessloop = 0;
- while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text);
+ while ((strpos($text, "[/spoiler]")!== false) and (strpos($text, "[spoiler=") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $text);
}
// Check for [open] text
$endlessloop = 0;
- while ((strpos($Text, "[/open]")!== false) and (strpos($Text, "[open]") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $Text);
+ while ((strpos($text, "[/open]")!== false) and (strpos($text, "[open]") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $text);
}
// Check for [open=Title] text
$endlessloop = 0;
- while ((strpos($Text, "[/open]")!== false) and (strpos($Text, "[open=") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $Text);
+ while ((strpos($text, "[/open]")!== false) and (strpos($text, "[open=") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $text);
}
@@ -1532,8 +1545,8 @@ function bbcode($Text, $options = []) {
// Check for [quote] text
// handle nested quotes
$endlessloop = 0;
- while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20))
- $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $Text);
+ while ((strpos($text, "[/quote]") !== false) and (strpos($text, "[quote]") !== false) and (++$endlessloop < 20))
+ $text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $text);
// Check for [quote=Author] text
@@ -1541,119 +1554,119 @@ function bbcode($Text, $options = []) {
// handle nested quotes
$endlessloop = 0;
- while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20))
- $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
+ while ((strpos($text, "[/quote]")!== false) and (strpos($text, "[quote=") !== false) and (++$endlessloop < 20))
+ $text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
"<span class=".'"bb-quote"'.">" . $t_wrote . "</span><blockquote>$2</blockquote>",
- $Text);
+ $text);
// Images
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace_callback('/\[\$b64img(.*?)\[\/(img)\]/ism','\red_unescape_codeblock',$Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace_callback('/\[\$b64img(.*?)\[\/(img)\]/ism','\red_unescape_codeblock',$text);
}
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace_callback('/\[\$b64zmg(.*?)\[\/(zmg)\]/ism','\red_unescape_codeblock',$Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace_callback('/\[\$b64zmg(.*?)\[\/(zmg)\]/ism','\red_unescape_codeblock',$text);
}
// [img]pathtoimage[/img]
- if (strpos($Text,'[/img]') !== false) {
+ if (strpos($text,'[/img]') !== false) {
- $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $Text);
+ $text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $text);
}
// [img=pathtoimage]image description[/img]
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $text);
}
// [zmg]pathtoimage[/zmg]
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $text);
}
// [zmg=pathtoimage]image description[/zmg]
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace("/\[zmg=http(.*?)\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace("/\[zmg=http(.*?)\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $text);
}
- $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text);
+ $text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$text);
// style (sanitized)
- if (strpos($Text,'[/style]') !== false) {
- $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $Text);
+ if (strpos($text,'[/style]') !== false) {
+ $text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $text);
}
// crypt
- if (strpos($Text,'[/crypt]') !== false) {
+ if (strpos($text,'[/crypt]') !== false) {
$x = random_string();
- $Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img class="cursor-pointer" src="' .z_root() . '/images/lock_icon.svg" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text);
- $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text);
+ $text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img class="cursor-pointer" src="' .z_root() . '/images/lock_icon.svg" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $text);
+ $text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $text);
}
- if(strpos($Text,'[/app]') !== false) {
- $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app', $Text);
+ if(strpos($text,'[/app]') !== false) {
+ $text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app', $text);
}
- if(strpos($Text,'[/element]') !== false) {
- $Text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism",'bb_parse_element', $Text);
+ if(strpos($text,'[/element]') !== false) {
+ $text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism",'bb_parse_element', $text);
}
// html5 video and audio
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text);
- $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $text);
+ $text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text);
- $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $text);
+ $text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $text);
}
// SVG stuff
- $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $Text);
+ $text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $text);
// Try to Oembed
if ($tryoembed) {
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryoembed', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryoembed', $text);
}
}
// if video couldn't be embedded, link to it instead.
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
// oembed tag
- $Text = oembed_bbcode2html($Text);
+ $text = oembed_bbcode2html($text);
// Avoid triple linefeeds through oembed
- $Text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $Text);
+ $text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $text);
// If we found an event earlier, strip out all the event code and replace with a reformatted version.
// Replace the event-start section with the entire formatted event. The other bbcode is stripped.
@@ -1666,72 +1679,73 @@ function bbcode($Text, $options = []) {
$sub = str_replace('$',"\0",$sub);
- $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text);
+ $text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$text);
- $Text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-timezone\](.*?)\[\/event\-timezone\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
+ $text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$text);
+ $text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$text);
+ $text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$text);
+ $text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$text);
+ $text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$text);
+ $text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$text);
+ $text = preg_replace("/\[event\-timezone\](.*?)\[\/event\-timezone\]/ism",'',$text);
+ $text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$text);
- $Text = str_replace("\0",'$',$Text);
+ $text = str_replace("\0",'$',$text);
}
- if (strpos($Text,'[summary]') !== false) {
- $Text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_unspacefy',$Text);
+ if (strpos($text,'[summary]') !== false) {
+ $text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_unspacefy',$text);
}
- if(strpos($Text,'[/summary]') !== false) {
- $Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/is", 'bb_summary', $Text);
+ if(strpos($text,'[/summary]') !== false) {
+ $text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/is", 'bb_summary', $text);
}
// Unhide all [noparse] contained bbtags unspacefying them
// and triming the [noparse] tag.
- if (strpos($Text,'[noparse]') !== false) {
- $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text);
+ if (strpos($text,'[noparse]') !== false) {
+ $text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $text);
}
- if (strpos($Text,'[nobb]') !== false) {
- $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text);
+ if (strpos($text,'[nobb]') !== false) {
+ $text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $text);
}
- if (strpos($Text,'[pre]') !== false) {
- $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text);
+ if (strpos($text,'[pre]') !== false) {
+ $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $text);
}
// replace escaped links in code= blocks
- $Text = str_replace('%eY9-!','http', $Text);
- $Text = bb_code_unprotect($Text);
+ $text = str_replace('%eY9-!','http', $text);
+ $text = bb_code_unprotect($text);
- $Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $Text);
+ $text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $text);
// fix any escaped ampersands that may have been converted into links
- if(strpos($Text,'&amp;') !== false)
- $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text);
+ if(strpos($text,'&amp;') !== false)
+ $text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $text);
// This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where
// the scheme begins with z (zhttp), h (http(s)), f (ftp(s)), m (mailto), t (tel) and named anchors.
- $Text = preg_replace("/\<(.*?)(src|href)=\"[^zhfmt#](.*?)\>/ism", '<$1$2="">', $Text);
+ $text = preg_replace("/\<(.*?)(src|href)=\"[^zhfmt#](.*?)\>/ism", '<$1$2="">', $text);
- $Text = bb_replace_images($Text, $saved_images);
+ $text = bb_replace_images($text, $saved_images);
// Convert new line chars to html <br /> tags
// nlbr seems to be hopelessly messed up
- // $Text = nl2br($Text);
+ // $text = nl2br($text);
// We'll emulate it.
- $Text = str_replace("\r\n", "\n", $Text);
- $Text = str_replace(["\r", "\n"], '<br />', $Text);
-
-// if ($preserve_nl)
-// $Text = str_replace(array("\n", "\r"), array('', ''), $Text);
+ $text = str_replace("\r\n", "\n", $text);
+ $text = str_replace(["\r", "\n"], '<br />', $text);
- call_hooks('bbcode', $Text);
+ /**
+ * @hooks bbcode
+ * * _string_ **html** - The resulting HTML after converting from bbcode.
+ */
+ call_hooks('bbcode', $text);
- return $Text;
+ return $text;
}
diff --git a/include/network.php b/include/network.php
index c5411e702..d41ba198d 100644
--- a/include/network.php
+++ b/include/network.php
@@ -2138,12 +2138,13 @@ function get_request_string($url) {
}
-/*
+/**
+ * Builds a url from the result of `parse_url`.
*
- * Takes the output of parse_url and builds a URL from it
+ * @param array $parsed_url An associative array as produced by `parse_url`.
*
+ * @return The reassembled URL as a string.
*/
-
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php
index 9fb7ffc2d..f29eeafd4 100644
--- a/tests/unit/includes/BBCodeTest.php
+++ b/tests/unit/includes/BBCodeTest.php
@@ -27,6 +27,55 @@ use Zotlabs\Tests\Unit\UnitTestCase;
class BBCodeTest extends UnitTestCase {
/**
+ * Test converting BBCode to HTML
+ *
+ * @dataProvider bbcode_to_html_provider
+ */
+ public function test_parsing_bbcode_to_html(string $src, string $expected): void {
+ $this->assertBBCode($expected, $src);
+ }
+
+ /**
+ * Test the `[observer]` BBCode tags.
+ *
+ * @dataProvider bbcode_observer_provider
+ */
+ public function test_bbcode_observer(string $src, bool $logged_in, string $lang, string $expected): void {
+ if ($logged_in) {
+ \App::$observer = [
+ 'xchan_addr' => '',
+ 'xchan_name' => '',
+ 'xchan_connurl' => '',
+ 'xchan_photo_l' => '',
+
+ // port required in xchan url due to bug in get_rpost_path
+ 'xchan_url' => 'https://example.com:666',
+ ];
+ } else {
+ \App::$observer = null;
+ }
+
+ \App::$language = $lang;
+
+ $this->assertBBCode($expected, $src);
+ }
+
+ /**
+ * Test parsing the `[channel]` tag.
+ */
+ public function test_bbcode_channel(): void {
+ $src = '[channel=1]This is only for channels[/channel][channel=0]This is for everyone else[/channel]';
+
+ // Verify that the right part is shown to users _not_ in a channel
+ \App::$channel = null;
+ $this->assertBBCode('This is for everyone else', $src);
+
+ // Now verify that the right part is shown to users _in_ a channel
+ \App::$channel = [42];
+ $this->assertBBCode('This is only for channels', $src);
+ }
+
+ /**
* Test converting html to BBCode.
*
* @dataProvider html2bbcode_provider
@@ -35,6 +84,95 @@ class BBCodeTest extends UnitTestCase {
$this->assertEquals($expected, html2bbcode($src));
}
+ /**
+ * Helper method to validate BBCode conversions.
+ *
+ * @param string $expected The expected result of the conversion.
+ * @param string $src The BBCode to be converted.
+ */
+ private function assertBBCode(string $expected, string $src): void {
+ // Note! We turn off trying to create oembeds, as that will trigger a
+ // network request when running the test.
+ $this->assertEquals($expected, bbcode($src, ['tryoembed' => false]));
+ }
+
+ /**
+ * Dataprovider for test_parsing_bbcode_to_html.
+ *
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
+ */
+ private function bbcode_to_html_provider(): array {
+ return [
+ 'code block' => [
+ "[code]\ntestvar = \"this is a test\"\necho \"the message is \$testvar\"\n[/code]",
+ '<pre><code>testvar = "this is a test"<br />echo "the message is $testvar"</code></pre>',
+ ],
+ ];
+ }
+
+ /**
+ * Dataprovider for test_bbcode_observer
+ *
+ * @returns an array of arrays with the following fields:
+ * * `string $src` - The source string to convert
+ * * `bool $logged_in` - Whether we should test with a logged in user
+ * * `string $lang` - The language code of the simulated user
+ * * `string $expected` - The expecte result of the conversion.
+ *
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
+ */
+ private function bbcode_observer_provider(): array {
+ return [
+ 'authenticated observer' => [
+ '[observer=1]This should be visible[/observer][observer=0]but not this[/observer]',
+ true,
+ 'en',
+ 'This should be visible',
+ ],
+ 'unauthenticated observer' => [
+ '[observer=1]This should not be visible[/observer][observer=0]but this should be![/observer]',
+ false,
+ 'en',
+ 'but this should be!',
+ ],
+ 'authenticated observer.language matching' => [
+ '[observer.language=nb]Kun på norsk[/observer][observer.language!=nb]To everybody else[/observer]',
+ true,
+ 'nb',
+ 'Kun på norsk',
+ ],
+ 'authenticated observer.language no match' => [
+ '[observer.language=nb]Kun på norsk[/observer][observer.language!=nb]To everybody else[/observer]',
+ true,
+ 'en',
+ 'To everybody else',
+ ],
+ 'multiple observer blocks' => [
+ '[observer=1]This should be visible,[/observer][observer=0] but not this,[/observer][observer=1] and this as well.[/observer]',
+ true,
+ 'en',
+ 'This should be visible, and this as well.',
+ ],
+ 'authenticated observer rpost' => [
+ '[rpost=a title]This is the body[/rpost]',
+ true,
+ 'en',
+ '<a href="https://example.com:666/rpost?f=&title=a+title&body=This+is+the+body" target="_blank" rel="nofollow noopener">https://example.com:666/rpost?f=&title=a+title&body=This+is+the+body</a>',
+ ],
+ 'unauthenticated observer rpost' => [
+ '[rpost=a title]This is the body[/rpost]',
+ false,
+ 'en',
+ '',
+ ],
+ ];
+ }
+
+ /**
+ * Dataprovider for test_html2bbcode.
+ *
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
+ */
private function html2bbcode_provider(): array {
return [
'paragraph over multiple lines' => [