66
77 class BBCodePlusPlugin extends MantisFormattingPlugin {
88 # placeholders for MantisCoreFormatting values.
9+ private $ t_MantisCoreFormatting = OFF ;
910 private $ t_MantisCoreFormatting_process_text = OFF ;
1011 private $ t_MantisCoreFormatting_process_urls = OFF ;
11- private $ t_MantisCoreFormatting_process_buglinks = OFF ;
12- private $ t_MantisCoreFormatting_process_vcslinks = OFF ;
1312 private $ t_bbCode = null ;
1413 private $ t_HTML = null ;
1514 //-------------------------------------------------------------------
@@ -22,7 +21,7 @@ function register() {
2221 $ this ->name = plugin_lang_get ( 'title ' );
2322 $ this ->description = plugin_lang_get ( 'description ' );
2423 $ this ->page = 'config ' ;
25- $ this ->version = '1.3.3 ' ;
24+ $ this ->version = '1.3.5 ' ;
2625
2726 $ this ->requires ['MantisCore ' ] = '1.3.0 ' ;
2827 # this plugin can coexist with MantisCoreFormatting.
@@ -64,14 +63,9 @@ function init() {
6463 $ this ->add_tags ();
6564 # store original configuration values.
6665 if ( plugin_is_loaded ('MantisCoreFormatting ' ) ) {
67- $ this ->t_MantisCoreFormatting_process_text = config_get ( 'plugin_MantisCoreFormatting_process_text ' );
68- $ this ->t_MantisCoreFormatting_process_urls = config_get ( 'plugin_MantisCoreFormatting_process_urls ' );
69- $ this ->t_MantisCoreFormatting_process_buglinks = config_get ( 'plugin_MantisCoreFormatting_process_buglinks ' );
70- if ( config_is_set ( 'plugin_MantisCoreFormatting_process_vcslinks ' ) ) {
71- $ this ->t_MantisCoreFormatting_process_vcslinks = config_get ( 'plugin_MantisCoreFormatting_process_vcslinks ' );
72- } else {
73- $ this ->t_MantisCoreFormatting_process_vcslinks = OFF ;
74- }
66+ $ this ->t_MantisCoreFormatting = ON ;
67+ $ this ->t_MantisCoreFormatting_process_text = $ this ->t_MantisCoreFormatting && config_get ( 'plugin_MantisCoreFormatting_process_text ' );
68+ $ this ->t_MantisCoreFormatting_process_urls = $ this ->t_MantisCoreFormatting && config_get ( 'plugin_MantisCoreFormatting_process_urls ' );
7569 }
7670 }
7771 //-------------------------------------------------------------------
@@ -199,17 +193,15 @@ public function rss( $p_event, $p_string ) {
199193 * @return string Formatted text
200194 */
201195 public function email ( $ p_event , $ p_string ) {
202-
203- $ p_string = string_strip_hrefs ( $ p_string );
204- $ p_string = string_process_bug_link ( $ p_string , FALSE );
205- $ p_string = string_process_bugnote_link ( $ p_string , FALSE );
206- $ p_string = $ this ->string_process_cvs_link ( $ p_string , FALSE );
196+ #$p_string = string_strip_hrefs( $p_string );
197+ #$p_string = string_process_bug_link( $p_string, FALSE );
198+ #$p_string = string_process_bugnote_link( $p_string, FALSE );
199+ #$p_string = $this->string_process_cvs_link( $p_string, FALSE );
207200
208201 if ( ON == plugin_config_get ( 'process_email ' ) )
209202 $ p_string = $ this ->string_process_bbcode ( $ p_string );
210203 else
211204 $ p_string = $ this ->string_strip_bbcode ( $ p_string );
212-
213205 return $ p_string ;
214206 }
215207 //-------------------------------------------------------------------
@@ -240,6 +232,7 @@ function add_tags() {
240232 # BBCode parsers.
241233 $ this ->t_bbCode ->addParser ('link ' , '/\[url\](.*?)\[\/url\]/s ' , '<a ' . $ t_extra_link_tags . ' href="$1">$1</a> ' , '$1 ' );
242234 $ this ->t_bbCode ->addParser ('namedlink ' , '/\[url\=(.*?)\](.*?)\[\/url\]/s ' , '<a ' . $ t_extra_link_tags . ' href="$1">$2</a> ' , '$2 ' );
235+ $ this ->t_bbCode ->addParser ('mention ' , '/\[url\=(.*?)\ mention](.*?)\[\/url\]/s ' , '<span class="mention"><a ' . $ t_extra_link_tags . ' href="$1">$2</a></span> ' , '$2 ' );
243236 $ this ->t_bbCode ->addParser ('email ' , '/\[email\]([a-z0-9\-_\.\+]+@[a-z0-9\-]+\.[a-z0-9\-\.]+?)\[\/email\]/s ' , '<a ' . $ t_extra_link_tags . ' href="mailto:$1">$1</a> ' , '$1 ' );
244237 $ this ->t_bbCode ->addParser ('named-email ' , '/\[email=([a-z0-9\-_\.\+]+@[a-z0-9\-]+\.[a-z0-9\-\.]+?)\](.+?)\[\/email\]/s ' , '<a ' . $ t_extra_link_tags . ' href="mailto:$1">$2</a> ' , '$2 ' );
245238 $ this ->t_bbCode ->addParser ('color ' , '/\[color=([\#a-z0-9]+?)\](.*?)\[\/color\]/s ' , '<span class="bbcolor-$1">$2</span> ' , '$2 ' );
@@ -264,8 +257,6 @@ function add_tags() {
264257 $ this ->t_bbCode ->addParser ('named-quote ' , '/\[quote=(\w+)\](.*?)\[\/quote\]/s ' ,
265258 '<blockquote class="bbcodeplus blockquote"><p class="mb-0">$2</p><footer class="bbcodeblus blockquote-footer"><cite title="$1">$1</cite></footer></blockquote> ' ,
266259 '$1 wrote: $2 ' );
267- # HTML parsers (to convert bug links and bugnote links when the Mantis Formatting plugin is running).
268- $ this ->t_HTML ->addParser ('link ' , '/<a href="(.*?)">(.*?)<\/a>/s ' , '[url=$1]$2[/url] ' , '$2 ' );
269260 }
270261 //-------------------------------------------------------------------
271262 /**
@@ -275,45 +266,38 @@ function add_tags() {
275266 * @return string $p_string
276267 */
277268 function string_process_bbcode ( $ p_string , $ p_multiline = TRUE ) {
278- # strip all active href so we can properly process them
279- $ p_string = string_strip_hrefs ( $ p_string );
280-
281- # escape all html code inside <code> tags.
282- $ p_string = $ this ->string_escape_code ( $ p_string );
283- $ p_string = $ this ->t_HTML ->except ('linebreak ' )->parse ($ p_string );
284-
285- # if mantis core formatting plugin process text feature is off, then we do our own.
269+ // convert mentions and titled links to BBCode mentions (if available).
270+ $ p_string = preg_replace ( '/<span class="mention"><a .*?href="(.*?)">(.*?)<\/a><\/span>/is ' , '[url=$1 mention]$2[/url] ' , $ p_string );
271+ $ p_string = preg_replace ( '/<a href="([^"]*)" title="([^"]*)">([^"]*)<\/a>/is ' , '[url=$1]$3[/url] ' , $ p_string );
272+ # strip all the auto generated URLs by MantisCoreFormatting plugin to avoid mangling.
273+ if ( ON == $ this ->t_MantisCoreFormatting_process_urls ) {
274+ $ p_string = string_strip_hrefs ( $ p_string );
275+ }
276+ # if mantis core formatting plugin process text feature is off, we need to sanitize the html,
277+ # for safety. this is the only functionality we will support when the MantisCoreFormatting plugin is
278+ # not enabled or when the text processing is disabled.
286279 if ( OFF == $ this ->t_MantisCoreFormatting_process_text ) {
287280 $ p_string = string_html_specialchars ( $ p_string );
281+ $ p_string = string_restore_valid_html_tags ( $ p_string , $ p_multiline );
288282 }
289-
290- # process bug and note links (if not already addressed.)
291- if ( ON == $ this ->t_MantisCoreFormatting_process_buglinks ) {
292- # reconstruct bugnote and bug links to BBCode
293- # bug note links (need to be done before bug note links).
294- $ p_string = preg_replace ( '/\/view\.php\?id\=([0-9]+)\#c([0-9]+)/is ' , '~$2 ' , $ p_string );
295- # bug links.
296- $ p_string = preg_replace ( '/\/view\.php\?id\=([0-9]+)/is ' , '#$1 ' , $ p_string );
297- }
298- # process the bug/bugnote links.
299- $ p_string = string_process_bugnote_link ( $ p_string , TRUE );
300- $ p_string = string_process_bug_link ( $ p_string , TRUE );
301- # process the CVS links (if applicable)
302- if ( OFF == $ this ->t_MantisCoreFormatting_process_vcslinks ) {
303- $ p_string = $ this ->string_process_cvs_link ( $ p_string );
304- }
305-
283+ # convert all remaining major html items to bbcode for uniform processing.
284+ $ p_string = $ this ->t_HTML ->except ('linebreak ' )->parse ($ p_string );
285+ # escape all html code inside <code> tags.
286+ $ p_string = $ this ->string_escape_code ( $ p_string );
306287 # parse the BBCode.
307288 $ p_string = $ this ->t_bbCode ->parse ($ p_string );
308289 # process new lines (while respecting code blocks);
309290 if ( OFF == $ this ->t_MantisCoreFormatting_process_text && $ p_multiline ) {
310291 # convert newlines to html breaks.
292+ $ p_string = string_preserve_spaces_at_bol ( $ p_string );
311293 $ p_string = string_nl2br ($ p_string );
312294 }
313295
314296 # remove extra breaks added by use of string_nl2br.
315297 $ p_string = preg_replace ( '/(<ul.*?>)<br \/>/is ' , '$1 ' , $ p_string );
316298 $ p_string = preg_replace ( '/(<ol.*?>)<br \/>/is ' , '$1 ' , $ p_string );
299+ $ p_string = preg_replace ( '/<\/ol><br \/>/is ' , '</ol> ' , $ p_string );
300+ $ p_string = preg_replace ( '/<\/ul><br \/>/is ' , '</ul> ' , $ p_string );
317301 $ p_string = preg_replace ( '/<\/li><br \/>/is ' , '</li> ' , $ p_string );
318302 $ p_string = preg_replace ( '/(<li>.*?)<br \/>/is ' , '$1 ' , $ p_string );
319303 $ p_string = preg_replace ( '/(<hr\/>.*?)<br \/>/is ' , '$1 ' , $ p_string );
@@ -322,11 +306,14 @@ function string_process_bbcode( $p_string, $p_multiline = TRUE ) {
322306 $ p_string = preg_replace ( '/(<div.*?>)<br \/>/is ' , '$1 ' , $ p_string );
323307 $ p_string = preg_replace ( '/<\/div><br \/>/is ' , '</div> ' , $ p_string );
324308 $ p_string = preg_replace ( '/<\/thead><br \/>/is ' , '</thead> ' , $ p_string );
309+ $ p_string = preg_replace ( '/<tbody><br \/>/is ' , '<tbody> ' , $ p_string );
325310 $ p_string = preg_replace ( '/<\/tbody><br \/>/is ' , '</tbody> ' , $ p_string );
311+ $ p_string = preg_replace ( '/<\/table><br \/>/is ' , '</table> ' , $ p_string );
326312 $ p_string = preg_replace ( '/<\/tr><br \/>/is ' , '</tr> ' , $ p_string );
327313 $ p_string = preg_replace ( '/<\/th><br \/>/is ' , '</th> ' , $ p_string );
328314 $ p_string = preg_replace ( '/<\/td><br \/>/is ' , '</td> ' , $ p_string );
329-
315+ $ p_string = preg_replace ( '/<\/pre><br \/>/is ' , '</pre> ' , $ p_string );
316+ $ p_string = preg_replace ( '/<\/blockquote><br \/>/is ' , '</blockquote> ' , $ p_string );
330317 # return the processed string.
331318 return $ p_string ;
332319 }
@@ -338,15 +325,25 @@ function string_process_bbcode( $p_string, $p_multiline = TRUE ) {
338325 * @return string $p_string
339326 */
340327 function string_escape_code ( $ p_string ) {
341-
342- if (OFF == $ this ->t_MantisCoreFormatting_process_text ) {
343- # escape any HTML entities in order to properly display HTML source code.
344- $ p_string = preg_replace_callback ('/\[code(.*?)\](.*?)\[\/code\]/s ' , function ($ match ) { return "[code " . strtolower ($ match [1 ]) . "] " . htmlentities ($ match [2 ]) . "[/code] " ; }, $ p_string );
345- } else {
346- # because Mantis Core formatting already does html entity escaping, we don't need to do it again.
347- $ p_string = preg_replace_callback ('/\[code(.*?)\](.*?)\[\/code\]/s ' , function ($ match ) { return "[code " . strtolower ($ match [1 ]) . "] " . $ match [2 ] . "[/code] " ; }, $ p_string );
348- }
349-
328+ # store value in var (due to issues with $this inside callbacks.)
329+ $ mantisCoreFormatting = $ this ->t_MantisCoreFormatting ;
330+ $ p_string = preg_replace_callback ('/\[code(.*?)\](.*?)\[\/code\]/s ' , function ($ match )
331+ # use is only supported on PHP 5.3+.
332+ use ( $ mantisCoreFormatting ) {
333+ # account for <br /> in code block (when using html syntax).
334+ $ code = $ match [2 ];
335+ if ( ON == $ mantisCoreFormatting ) {
336+ # preview somehow uses \n only.
337+ $ code = preg_replace ( '/<br \/>\n/is ' , "\n" , $ code );
338+ # everywhere else uses \r\n.
339+ $ code = preg_replace ( '/<br \/>\r\n/is ' , "\r\n" , $ code );
340+ }
341+ # encode the remaining <br />.
342+ $ code = str_replace ("<br /> " ,htmlentities ("<br /> " ), $ code );
343+ # return the code.
344+ return "[code " . strtolower ($ match [1 ]) . "] " . $ code . "[/code] " ;
345+ }, $ p_string );
346+ # return the formatted code.
350347 return $ p_string ;
351348 }
352349 //-------------------------------------------------------------------
@@ -358,43 +355,19 @@ function string_escape_code( $p_string ) {
358355 */
359356 function string_strip_bbcode ( $ p_string ) {
360357 # perform sanitation before parsing.
358+ // convert mentions and titled links to BBCode mentions (if available).
359+ $ p_string = preg_replace ( '/<span class="mention"><a .*?href="(.*?)">(.*?)<\/a><\/span>/is ' , '$2 ($1) ' , $ p_string );
360+ $ p_string = preg_replace ( '/<a href="([^"]*)" title="([^"]*)">([^"]*)<\/a>/is ' , '$3 ($1) ' , $ p_string );
361361 # strip all active href so we can properly process them
362362 $ p_string = string_strip_hrefs ( $ p_string );
363363 # escape all html code inside <code> tags.
364364 $ p_string = $ this ->string_escape_code ( $ p_string );
365365 $ p_string = $ this ->t_HTML ->parse ($ p_string );
366-
367366 # strip the BBCode
368367 $ p_string = $ this ->t_bbCode ->stripTags ($ p_string );
369-
370368 # return the processed string.
371369 return $ p_string ;
372370 }
373371 //-------------------------------------------------------------------
374- /**
375- * process the $p_string and convert filenames in the format
376- * cvs:filename.ext or cvs:filename.ext:n.nn to a html link
377- * if $p_include_anchor is true, include an <a href="..."> tag,
378- * otherwise, just insert the URL as text
379- * @param string $p_string
380- * @param bool $p_include_anchor
381- * @return string
382- */
383- function string_process_cvs_link ( $ p_string , $ p_include_anchor = true ) {
384- if ( config_is_set ('cvs_web ' ) ) {
385- $ t_cvs_web = config_get ( 'cvs_web ' );
386-
387- if ( $ p_include_anchor ) {
388- $ t_replace_with = '[CVS] <a href=" ' . $ t_cvs_web . '\\1?rev= \\4" target="_new"> \\1</a> \\5 ' ;
389- } else {
390- $ t_replace_with = '[CVS] ' . $ t_cvs_web . '\\1?rev= \\4 \\5 ' ;
391- }
392-
393- return preg_replace ( '/cvs:([^\.\s:,\?!<]+(\.[^\.\s:,\?!<]+)*)(:)?(\d\.[\d\.]+)?([\W\s])?/i ' , $ t_replace_with , $ p_string );
394- } else {
395- return $ p_string ;
396- }
397- }
398- //-------------------------------------------------------------------
399372 }
400373?>
0 commit comments