/**
  * Parses special unmatched HTML tags like <img> and <br>.
  *
  * @param	string	Text pre-parsed
  *
  * @return	string	Parsed text
  */
 protected function parse_unmatched_tags($text)
 {
     require_once DIR . '/includes/functions_wysiwyg.php';
     $text = preg_replace_callback('#<img[^>]+smilieid="(\\d+)".*>#siU', array($this, 'translateSmilieIdTextCallback'), $text);
     $text = preg_replace_callback('#<img[^>]+src=(\'|")(.*)(\\1).*>#siU', function ($matches) {
         return handle_wysiwyg_img($matches[2], $matches[0]);
     }, $text);
     $text = preg_replace('#<br.*>#siU', "\n", $text);
     return $text;
 }
function convert_wysiwyg_html_to_bbcode($text, $allowhtml = false, $p_two_linebreak = false)
{
    global $vbulletin;
    $vb5_config =& vB::getConfig();
    // debug code
    $vbulletin->input->clean_gpc('r', 'showhtml', vB_Cleaner::TYPE_BOOL);
    if ($vb5_config['Misc']['debug'] and $vbulletin->GPC['showhtml']) {
        $otext = $text;
    }
    // deal with some wierdness that can be caused with URL tags in the WYSIWYG editor
    $text = preg_replace(array('#<a href="([^"]*)\\[([^"]+)"(.*)>(.*)\\[\\2</a>#siU'), array('<a href="\\1"\\3>\\4</a>[\\2'), $text);
    $text = preg_replace_callback('#(<[^<>]+ (src|href))=(\'|"|)??(.*)(\\3)#siU', function ($matches) {
        return sanitize_url($matches[1], $matches[4], $matches[3]);
    }, $text);
    // Legacy Hook 'wysiwyg_parse_start' Removed //
    // attempt to remove bad html and keep only that which we intend to parse
    if (!$allowhtml) {
        $text = str_replace('<br/>', '<br />', $text);
        $text = preg_replace('#<script[^>]*>(.*)</script>#siU', '', $text);
        $text = strip_tags($text, '<b><strong><i><em><u><a><div><span><p><blockquote><ol><ul><li><font><img><br><h1><h2><h3><h4><h5><h6>');
    }
    // convert 4 spaces to tabs in code/php/html tags; no longer used
    /*if (preg_match_all('#\[(code|php|html)\](.*)\[/\\1\]#siU', $text, $regs))
    	{
    		foreach($regs[2] AS $key => $val)
    		{
    			$orig = $val;
    			// convert '&nbsp; ' to '&nbsp;&nbsp;'
    			$val = str_replace('&nbsp; ', '&nbsp;&nbsp;', $val);
    			// convert 4 x &nbsp; to \t
    			$val = preg_replace('#(&nbsp;){4}#siU', "\t", $val);
    			// replace text in original text
    			$text = str_replace($orig, $val, $text);
    		}
    	}*/
    // replace &nbsp; with a regular space
    $text = str_replace('&nbsp;', ' ', $text);
    // deal with newline characters
    if (is_browser('mozilla')) {
        $text = preg_replace('#(?<!<br>|<br />|\\r)(\\r\\n|\\n|\\r)#', ' ', $text);
    }
    $text = preg_replace('#(\\r\\n|\\n|\\r)#', '', $text);
    // regex find / replace #1
    $pregfind = array('#<(h[0-9]+)[^>]*>(.*)</\\1>#siU', '#<br.*>#siU', '#<a name=[^>]*>(.*)</a>#siU', '#\\[url=(\'|"|&quot;|)<A href="(.*)/??">\\2/??</A>#siU');
    $pregreplace = array(is_bbcode_tag_allowed('b') ? "[B]\\2[/B]\n\n" : "\\2\n\n", "\n", '\\1', '[URL=$1$2');
    $text = preg_replace($pregfind, $pregreplace, $text);
    $text = preg_replace_callback('#<img[^>]+smilieid="(\\d+)".*>#siU', function ($matches) {
        return fetch_smilie_text($matches[1]);
    }, $text);
    $text = preg_replace_callback('#<img[^>]+src=(\'|")(.*)(\\1).*>#siU', function ($matches) {
        return handle_wysiwyg_img($matches[2], $matches[0]);
    }, $text);
    $text = preg_replace_callback('#\\[(html|php)\\]((?>[^\\[]+?|(?R)|.))*\\[/\\1\\]#siU', function ($matches) {
        return strip_tags_callback($matches[0]);
    }, $text);
    // recursive code parsers
    $text = parse_wysiwyg_recurse('b', $text, 'parse_wysiwyg_code_replacement', 'b');
    $text = parse_wysiwyg_recurse('strong', $text, 'parse_wysiwyg_code_replacement', 'b');
    $text = parse_wysiwyg_recurse('i', $text, 'parse_wysiwyg_code_replacement', 'i');
    $text = parse_wysiwyg_recurse('em', $text, 'parse_wysiwyg_code_replacement', 'i');
    $text = parse_wysiwyg_recurse('u', $text, 'parse_wysiwyg_code_replacement', 'u');
    $text = parse_wysiwyg_recurse('a', $text, 'parse_wysiwyg_anchor');
    $text = parse_wysiwyg_recurse('font', $text, 'parse_wysiwyg_font');
    $text = parse_wysiwyg_recurse('blockquote', $text, 'parse_wysiwyg_code_replacement', 'indent');
    $text = parse_wysiwyg_recurse('ol', $text, 'parse_wysiwyg_list');
    $text = parse_wysiwyg_recurse('ul', $text, 'parse_wysiwyg_list');
    $text = parse_wysiwyg_recurse('div', $text, 'parse_wysiwyg_div');
    $text = parse_wysiwyg_recurse('span', $text, 'parse_wysiwyg_span');
    // ugly ugly hack, but allow p's to be treated as 2 line breaks in some situations
    $GLOBALS['p_two_linebreak'] = $p_two_linebreak;
    $text = parse_wysiwyg_recurse('p', $text, 'parse_wysiwyg_paragraph');
    // regex find / replace #2
    $pregfind = array('#<li>(.*)((?=<li>)|</li>)#iU', '#<p></p>#i', '#<p.*>#iU');
    $pregreplace = array("\\1\n", '', "\n");
    $text = preg_replace($pregfind, $pregreplace, $text);
    // simple tag removals; mainly using PCRE for case insensitivity and /?
    $text = preg_replace('#</?(A|LI|FONT|IMG)>#siU', '', $text);
    // basic string replacements #2; don't replace &quot; because browsers don't auto-encode quotes
    $strfind = array('&lt;', '&gt;', '&amp;');
    $strreplace = array('<', '>', '&');
    if (is_array($vbulletin->smiliecache)) {
        global $vbulletin;
        foreach ($vbulletin->smiliecache as $smilie) {
            // [IMG]images/smilies/frown.gif[/IMG]
            $strfind[] = '[IMG]' . $smilie['smiliepath'] . '[/IMG]';
            $strreplace[] = $smilie['smilietext'];
            // [IMG]http://domain.com/forum/images/smilies/frown.gif[/IMG]
            $strfind[] = '[IMG]' . create_full_url($smilie['smiliepath']) . '[/IMG]';
            $strreplace[] = $smilie['smilietext'];
        }
    }
    $text = str_replace($strfind, $strreplace, $text);
    if (is_browser('mozilla')) {
        // mozilla treats line breaks before/after lists a little differently from IE (see #5774)
        $text = preg_replace('#\\[(list)#i', "\n[\\1", $text);
        $text = preg_replace('#\\[(/list)\\]#i', "[\\1]\n", $text);
    }
    $text = preg_replace('#(?<!\\r|\\n|^)\\[(/list|list|\\*)\\]#i', "\n[\\1]", $text);
    // replace advanced URL tags that should actually be basic ones
    $text = preg_replace('#\\[URL=("|\'|)(.*)\\1\\]\\2\\[/URL\\]#siU', '[URL]$2[/URL]', $text);
    // Legacy Hook 'wysiwyg_parse_complete' Removed //
    // debug code
    $vbulletin->input->clean_gpc('r', 'showhtml', vB_Cleaner::TYPE_BOOL);
    if ($vb5_config['Misc']['debug'] and $vbulletin->GPC['showhtml']) {
        $GLOBALS['header'] .= "<table class=\"tborder\" cellpadding=\"4\" cellspacing=\"1\" width=\"100%\">\n\t\t<tr><td class=\"thead\">WYSIWYG HTML</td></tr>\n\t\t<tr><td class=\"alt1\">" . nl2br(htmlspecialchars($otext)) . "</td></tr>\n\t\t<tr><td class=\"thead\">Parsed BBcode</td></tr>\n\t\t<tr><td class=\"alt1\">" . nl2br(htmlspecialchars($text)) . "</td></tr>\n</table>";
    }
    // return parsed text
    return trim($text);
}