'fieldset',
'#title' => t('BBCode filter'),
'#collapsible' => TRUE,
'#collapsed' => FALSE);
$bbcode_filter["bbcode_make_links_$format"] = array(
'#type' => 'select',
'#title' => t('Convert addresses to links'),
'#default_value' => variable_get("bbcode_make_links_$format", 1),
'#options' => array(t('Disabled'), t('Enabled')),
'#description' => t('Turn web and e-mail addresses into clickable links. This is useful if content authors do not explicitly mark addresses as links with [url] and [email] tags.'));
$bbcode_filter["bbcode_encode_mailto_$format"] = array(
'#type' => 'select',
'#title' => t('Email address encoding'),
'#default_value' => variable_get("bbcode_encode_mailto_$format", 1),
'#options' => array(t('Disabled'), t('Enabled')),
'#description' => t('Whether to encode email addresses with javascript. With this method you will have clickable mailto links, but it will be a bit harder for spam robots to collect them.'));
$bbcode_filter["bbcode_paragraph_breaks_$format"] = array(
'#type' => 'select',
'#title' => t('Smart paragraph and line breaks'),
'#default_value' => variable_get("bbcode_paragraph_breaks_$format", 2),
'#options' => array(t('Disabled'), t('Line breaks only'), t('Line and paragraph breaks')),
'#description' => t('Add line and paragraph breaks to text, excluding text in preformatted code blocks. If you disable this option, you need to enable Drupal\'s "Line break converter". Don\'t use both together!'));
$bbcode_filter["bbcode_debug_$format"] = array(
'#type' => 'select',
'#title' => t('Print debugging info'),
'#default_value' => variable_get("bbcode_debug_$format", 0),
'#options' => array(t('Disabled'), t('Enabled')),
'#description' => t('Print BBCode parse date and execution time. This option should be disabled on production sites. You may need to clear the cache after changing this option.'));
$body = '[img]http://localhost/J1.5/images/stories/powered_by.png " onmouseover="alert(\'hello world\')[/img]';
_bbcode_filter_process($body);
print ("
");
print_r($body);
print ("
");
}
function _bbcode_filter_process(&$body, $format = -1) {
$quote_text = t('Quote:');
$quote_user = t('\\1 wrote:');
// Encode all script tags to prevent XSS html injection attacks
$body = preg_replace(array('#]*)>#i'), array('<script\\1>', '</script\\1>'), $body);
// Find all [code] tags and check if they contain a newline. If we find a newline,
// that [code] should be rendered as a block, otherwise it will still be inline
$mode = variable_get("bbcode_paragraph_breaks_$format", 2);
$pre = array(); $i = 0;
if (preg_match_all('#\[code(?::\w+)?\](.*?)\[/code(?::\w+)?\]#si', $body, $code_tags, PREG_SET_ORDER)) {
foreach ($code_tags as $code_tag) {
$code_tag[1] = str_replace(array('<', '>'), array('<', '>'), $code_tag[1]);
if (strpos($code_tag[1], "\n") === FALSE)
$body = str_replace($code_tag[0], ''. $code_tag[1] .'', $body);
elseif ($mode) {
// Strip preformatted code blocks from text during line break processing, replaced below
$body = str_replace($code_tag[0], "***pRe_sTrInG$i***", $body);
$pre[$i++] = '
'. $code_tag[1] .'
';
}
else
$body = str_replace($code_tag[0], '
'. $code_tag[1] .'
', $body);
}
}
// Apply line and paragraph breaks (skipping preformatted code)
if ($mode) {
if ($mode == 1) // Line breaks only (starting with PHP 4.0.5, nl2br() is XHTML compliant)
$body = nl2br($body);
if ($mode == 2) { // Line and paragraph breaks (may not always be XHTML compliant)
$body = preg_replace("/(\r\n|\n|\r)/", "\n", $body);
$body = preg_replace("/\n\n+/", "\n\n", $body);
$parts = explode("\n\n", $body);
for ($i=0; $i/', $parts[$i]) )
$parts[$i] = nl2br($parts[$i]);
// Some tags should not be in paragraph blocks
if ( !preg_match('/^(?:<|\[)(?:table|list|ol|ul|pre|select|form|blockquote|hr)/i', $parts[$i]) )
$parts[$i] = '
'. $parts[$i] .'
';
}
$body = implode("\n\n", $parts);
}
// Reinsert preformatted code blocks
foreach ($pre as $i => $code_tag)
$body = str_replace("***pRe_sTrInG$i***", $code_tag, $body);
}
// Add closing tags to prevent users from disruping your site's HTML
// (required for nestable tags only: [list] and [quote])
preg_match_all('/\[quote/i', $body, $matches);
$opentags = count($matches['0']);
preg_match_all('/\[\/quote\]/i', $body, $matches);
$unclosed = $opentags - count($matches['0']);
for ($i = 0; $i < $unclosed; $i++)
$body .= '[/quote]';
preg_match_all('/\[list/i', $body, $matches);
$opentags = count($matches['0']);
preg_match_all('/\[\/list\]/i', $body, $matches);
$unclosed = $opentags - count($matches['0']);
for ($i = 0; $i < $unclosed; $i++)
$body .= '[/list]';
// Define BBCode tags
$preg = array(
// Implement [notag]
'#\[notag(?::\w+)?\](.*?)\[/notag(?::\w+)?\]#sie' => '_bbcode_notag_tag(\'\\1\')',
// Headings and indexes - articles will almost always need them
'#\[h([1-6])(?::\w+)?\](.*?)\[/h[1-6](?::\w+)?\]#sie' => '_bbcode_generate_heading(\\1, \'\\2\')',
'#\[index\s*/?\]#sie' => '_bbcode_generate_index($body)',
'#\[index style=(ol|ul)\]#sie' => '_bbcode_generate_index($body, \'\\1\')',
// Font, text and alignment
'#\[color=([\#\w]+)(?::\w+)?\](.*?)\[/color(?::\w+)?\]#si' => '\\2',
'#\[size=(\d+)(?::\w+)?\](.*?)\[/size(?::\w+)?\]#sie' => '_bbcode_size_tag(\\1, \'\\2\')',
'#\[font=([\w\s]+)(?::\w+)?\](.*?)\[/font(?::\w+)?\]#si' => '\\2',
'#\[align=(\w+)(?::\w+)?\](.*?)\[/align(?::\w+)?\]#si' => '\\2',
'#\[float=(left|right)(?::\w+)?\](.*?)\[/float(?::\w+)?\]#si' => '\\2',
'#\[justify(?::\w+)?\](.*?)\[/justify(?::\w+)?\]#si' => '
',
// Links without a protocol, with a protocol, and with good looking text
'#\[url(?::\w+)?\]www\.([\w:;&,%+~!=@\/\.\-\#\?]+?)\[/url(?::\w+)?\]#si' => '\\1',
'#\[url(?::\w+)?\]([\w:;&,%+~!=@\/\.\-\#\?]+?)\[/url(?::\w+)?\]#si' => '\\1',
'#\[url=www\.([\w:;&,%+~!=@\/\.\-\#\?]+?)\](.*?)\[/url(?::\w+)?\]#si' => '\\2',
'#\[url=([\w:;&,%+~!=@\/\.\-\#\?]+?)\](.*?)\[/url(?::\w+)?\]#si' => '\\2',
// Anchor tags for linking within documents
'#\[anchor=(\w+)(?::\w+)?\](.*?)\[/anchor(?::\w+)?\]#si' => '\\2',
// Images without or with client-side sizing
'#\[img(?::\w+)?\]([\w:;&,~%+!=@\/\.\-\#\?]+)\[/img(?::\w+)?\]#si' => '',
'#\[img=(\d+)x(\d+)(?::\w+)?\]([\w:;&,~%+!=@\/\.\-\#\?]+)\[/img(?::\w+)?\]#si' => '',
'#\[img=([\w\s:;,\.\-\'\(\)]+)(?::\w+)?\]([\w:;&,~%+!=@\/\.\-\#\?]+)\[/img(?::\w+)?\]#si' => '',
'#\[img align=(left|right|center)(?::\w+)?\]([\w:;&,~%+!=@\/\.\-\#\?]+)\[/img(?::\w+)?\]#si' => '',
// Flash animations and other special effects
'#\[flash=(\d+)x(\d+)(?::\w+)?\]([\w:;&,~%+!=@\/\.\-\#\?]+)\[/flash(?::\w+)?\]#si' => '',
'#\[move(?::\w+)?\](.*?)\[/move(?::\w+)?\]#si' => '',
// Acronyms & abbreviations - show description when mouse moves over tag
'#\[acronym=([\w\s-,\.]+)(?::\w+)?\](.*?)\[/acronym(?::\w+)?\]#si' => '\\2',
'#\[abbr=([\w\s-,\.]+)(?::\w+)?\](.*?)\[/abbr(?::\w+)?\]#si' => '\\2',
// Quoting with or without specifying the source
'#\[quote(?::\w+)?\]#i' => '
',
);
$body = preg_replace(array_keys($preg), array_values($preg), $body);
// Simple replacements (str_replace is faster than preg_replace)
$str = array(
// Horizontal delimiter
'[hr]' => '',
// Force line break
'[br]' => ' ',
// Force space
'[sp]' => ' ',
);
$body = str_replace(array_keys($str), array_values($str), $body);
// We cannot evaluate the variable in callback function because
// there is no way to pass the $format variable
if (variable_get("bbcode_encode_mailto_$format", 1)) {
// Replacing email addresses with encoded html
$body = preg_replace_callback('#\[email(?::\w+)?\]([\w\.\-\+~@]+)\[/email(?::\w+)?\]#si', '_bbcode_encode_mailto', $body);
$body = preg_replace_callback('#\[email=(.*?)(?::\w+)?\](.*?)\[/email(?::\w+)?\]#si', '_bbcode_encode_mailto', $body);
}
else {
$body = preg_replace(
array('#\[email(?::\w+)?\](.*?)\[/email(?::\w+)?\]#si','#\[email=(.*?)(?::\w+)?\]([\w\s]+)\[/email(?::\w+)?\]#si'),
array('\\1', '\\2'),
$body);
}
// Turns web and e-mail addresses into clickable links
if (variable_get("bbcode_make_links_$format", 1)) {
// pad with a space so we can match things at the start of the 1st line
$ret = ' ' . $body;
// matches an "xxx://yyyy" URL at the start of a line, or after a space.
// xxxx can only be alpha characters.
// yyyy is anything up to the first space, newline, comma, double quote or <
$ret = preg_replace('#(?<=^|[\t\r\n >\(\[\]\|])([a-z]+?://[\w\-]+\.([\w\-]+\.)*\w+(:[0-9]+)?(/[^ "\'\(\n\r\t<\)\[\]\|]*)?)((?\1', $ret);
// matches a "www|ftp.xxxx.yyyy[/zzzz]" kinda lazy URL thing
// Must contain at least 2 dots. xxxx contains either alphanum, or "-"
// zzzz is optional.. will contain everything up to the first space, newline,
// comma, double quote or <.
$ret = preg_replace('#([\t\r\n >\(\[\|])(www|ftp)\.(([\w\-]+\.)*[\w]+(:[0-9]+)?(/[^ \"\'\(\n\r\t<\)\[\]\|]*)?)#i', '\1\2.\3', $ret);
// matches an email@domain type address at the start of a line, or after a space.
// Note: Only the followed chars are valid; alphanums, "-", "_" and or ".".
if (variable_get("bbcode_encode_mailto_$format", 1))
$ret = preg_replace_callback("#([\t\r\n ])([a-z0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", '_bbcode_encode_mailto', $ret);
else
$ret = preg_replace('#([\t\r\n ])([a-z0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i', '\\1\\2@\\3', $ret);
// Remove our padding
$body = substr($ret, 1);
}
return $body;
}
function _bbcode_generate_heading($level, $text) {
$anchor = preg_replace('/([\s]+)/', '_', $text);
$anchor = preg_replace('/([\W]+)/', '', $anchor);
return ''. $text .'';
}
function _bbcode_generate_index($body, $tag = 'ol') {
$level = 0;
$index = '<'. $tag .">\n";
$close_tags = 0;
if (preg_match_all('#\[h([1-6]).*?\](.*?)\[/h([1-6]).*?\]#si', $body, $head_tags, PREG_SET_ORDER)) {
foreach ($head_tags as $head_tag) {
if ($level == 0) $level = $head_tag[1];
$anchor = preg_replace('/([\s]+)/', '_', $head_tag[2]);
$anchor = preg_replace('/([\W]+)/', '', $anchor);
if ($head_tag[1] > $level) {
$index .= '<'. $tag .">\n";
$index .= '