<?php
/*======================================================================*\
|| #################################################################### ||
|| # vBulletin 4.0.5
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2000-2010 vBulletin Solutions Inc. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/
/*
$fontoptions = makeJavascriptArray('vbcode_font_options');
$sizeoptions = makeJavascriptArray('vbcode_size_options');
$coloroptions = makeJavascriptArray('vbcode_color_options');
*/
// ###################### Start WYSIWYG_getparsedhtml #######################
function parse_wysiwyg_html($html, $ishtml = 0, $forumid = 0, $allowsmilie = 1)
{
global $vbulletin;
if ($ishtml)
{
// parse HTML into vbcode
// I DON'T THINK THIS IS EVER USED NOW - KIER
$html = convert_wysiwyg_html_to_bbcode($html);
}
else
{
$html = unhtmlspecialchars($html, 0);
}
// parse the message back into WYSIWYG-friendly HTML
require_once(DIR . '/includes/class_bbcode_alt.php');
$wysiwyg_parser = new vB_BbCodeParser_Wysiwyg($vbulletin, fetch_tag_list());
$wysiwyg_parser->set_parse_userinfo($vbulletin->userinfo);
return $wysiwyg_parser->parse($html, $forumid, $allowsmilie);
}
// ###################### Start safeUrl #######################
function sanitize_url($type, $url, $delimiter = '\\"')
{
static $find, $replace;
if (!is_array($find))
{
$find = array('<', '>', '\\"');
$replace = array('<', '>', '"');
}
$delimiter = str_replace('\\"', '"', $delimiter);
return str_replace('\\"', '"', $type) . '=' . $delimiter . str_replace($find, $replace, $url) . $delimiter;
}
// ###################### Start getsmilietext #######################
function fetch_smilie_text($smilieid)
{
global $vbulletin;
static $smilies;
// build the smilies array if we haven't already
if (!is_array($smilies))
{
$smilies = array();
// attempt to get smilies from the datastore smiliecache
if (is_array($vbulletin->smiliecache))
{
foreach($vbulletin->smiliecache AS $smilie)
{
$smilies["$smilie[smilieid]"] = $smilie['smilietext'];
}
}
// query smilies from the database
else
{
$getsmilies = $vbulletin->db->query_read_slave("SELECT smilieid, smilietext FROM " . TABLE_PREFIX . "smilie");
while ($smilie = $vbulletin->db->fetch_array($getsmilies))
{
$smilies["$smilie[smilieid]"] = $smilie['smilietext'];
}
$vbulletin->db->free_result($getsmilies);
}
}
// return the smilietext for this smilie
return $smilies["$smilieid"];
}
// ###################### Start WYSIWYG_html2vbcode #######################
function convert_wysiwyg_html_to_bbcode($text, $allowhtml = false, $p_two_linebreak = false)
{
global $vbulletin;
// debug code
$vbulletin->input->clean_gpc('r', 'showhtml', TYPE_BOOL);
if ($vbulletin->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', // check for the WYSIWYG editor being lame with URL tags followed by bbcode tags
'#(<[^<>]+ (src|href))=(\'|"|)??(.*)(\\3)#esiU' // make < and > safe in inside URL/IMG tags so they don't get stripped by strip_tags
), array(
'<a href="\1"\3>\4</a>[\2', // check for the browser (you know who you are!) being lame with URL tags followed by bbcode tags
"sanitize_url('\\1', '\\4', '\\3')" // make < and > safe in inside URL/IMG tags so they don't get stripped by strip_tags
), $text
);
($hook = vBulletinHook::fetch_hook('wysiwyg_parse_start')) ? eval($hook) : false;
// 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 ' ' to ' '
$val = str_replace(' ', ' ', $val);
// convert 4 x to \t
$val = preg_replace('#( ){4}#siU', "\t", $val);
// replace text in original text
$text = str_replace($orig, $val, $text);
}
}*/
// replace with a regular space
$text = str_replace(' ', ' ', $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
(
#'#^(<div>\s*)+#si', // multiple <DIV>s at string start
#'#(\s*</div>)+$#si', // multiple </DIV>s at string end
'#<(h[0-9]+)[^>]*>(.*)</\\1>#siU', // headings
'#<img[^>]+smilieid="(\d+)".*>#esiU', // smilies
'#<img[^>]+src=(\'|")(.*)(\\1).*>#esiU', // img tag
//'#<a[^>]+href=(\'|")mailto:(.*)(\\1).*>(.*)</a>#siU', // email tag
//'#<a[^>]+href=(\'|")(.*)(\\1).*>(.*)</a>#siU', // url tag
//'#\s*<(p|div) align=(\'|"|)(.*)\\2>(.*)</\\1>#siU', // <p align=...> to double newline
//'#<p.*>(.*)</p>#siU', // convert <p> to double newline
'#<br.*>#siU', // <br> to newline
'#<a name=[^>]*>(.*)</a>#siU', // kill named anchors
'#\[(html|php)\]((?>[^\[]+?|(?R)|.))*\[/\\1\]#siUe', // strip html from php tags
//'#\[url=(\'|"|"|)<A href="(.*)/??">\\2/??</A>\\1\](.*)\[/url\]#siU', // strip linked URLs from manually entered [url] tags
'#\[url=(\'|"|"|)<A href="(.*)/??">\\2/??</A>#siU', // strip linked URLs from manually entered [url] tags (generic)
);
$pregreplace = array
(
#'<DIV>', // multiple <DIV>s at string start
#'</DIV>', // multiple </DIV>s at string end
is_bbcode_tag_allowed('b') ? "[B]\\2[/B]\n\n" : "\\2\n\n", // headings
"fetch_smilie_text(\\1)", // smilies
"handle_wysiwyg_img('\\2', '\\0')", // img tag
//'[EMAIL="\2"]\4[/EMAIL]', // email tag
//'[URL="\2"]\4[/URL]', // url tag
//"[\\3]\\4[/\\3]", // <p align=...> to double newline
//"\\1\n\n", // <p> to double newline
"\n", // <br> to newline
'\1', // kill named anchors
"strip_tags_callback('\\0')", // strip html from php tags
//'[URL=$1$2$1]$3[/URL]', // strip linked URLs from manually entered [url] tags
'[URL=$1$2', //`strip linked URLs from manually entered [url] tags (generic)
);
$text = preg_replace($pregfind, $pregreplace, $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', // fix some list issues
'#<p></p>#i', // kill empty <p> tags
'#<p.*>#iU', // kill any extra <p> tags
//'#(\[/quote\])(\s?\r?\n){0,1}#si', // kill extra whitespace after a [/quote] tag
);
$pregreplace = array(
"\\1\n", // fix some list issues
'', // kill empty <p> tags
"\n", // kill any extra <p> tags
//'\1', // kill extra whitespace after a [/quote] tag
);
$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 " because browsers don't auto-encode quotes
$strfind = array
(
'<', // un-htmlspecialchars <
'>', // un-htmlspecialchars >
'&', // un-htmlspecialchars &
);
$strreplace = array
(
'<', // un-htmlspecialchars <
'>', // un-htmlspecialchars >
'&', // un-htmlspecialchars &
);
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);
($hook = vBulletinHook::fetch_hook('wysiwyg_parse_complete')) ? eval($hook) : false;
// debug code
$vbulletin->input->clean_gpc('r', 'showhtml', TYPE_BOOL);
if ($vbulletin->debug AND $vbulletin->GPC['showhtml'])
{
$GLOBALS['header'] .= "<table class=\"tborder\" cellpadding=\"4\" cellspacing=\"1\" width=\"100%\">
<tr><td class=\"thead\">WYSIWYG HTML</td></tr>
<tr><td class=\"alt1\">" . nl2br(htmlspecialchars($otext)) . "</td></tr>
<tr><td class=\"thead\">Parsed BBcode</td></tr>
<tr><td class=\"alt1\">" . nl2br(htmlspecialchars($text)) . "</td></tr>\n</table>";
}
// return parsed text
return trim($text);
}
/**
* Determines if the specified BB code tag is globally enabled.
*
* @param string Tag name
*
* @return bool
*/
function is_bbcode_tag_allowed($tag)
{
global $vbulletin;
$flag_value = 0;
switch (strtolower($tag))
{
case 'b':
case 'i':
case 'u':
$flag_value = ALLOW_BBCODE_BASIC;
break;
case 'color':
$flag_value = ALLOW_BBCODE_COLOR;
break;
case 'size':
$flag_value = ALLOW_BBCODE_SIZE;
break;
case 'font':
$flag_value = ALLOW_BBCODE_FONT;
break;
case 'left':
case 'right':
case 'center':
$flag_value = ALLOW_BBCODE_ALIGN;
break;
case 'list':
$flag_value = ALLOW_BBCODE_LIST;
break;
case 'indent':
// allowed if either is enabled
$flag_value = ALLOW_BBCODE_ALIGN | ALLOW_BBCODE_LIST;
break;
case 'email':
case 'url':
case 'thread':
case 'post':
$flag_value = ALLOW_BBCODE_URL;
break;
case 'php':
$flag_value = ALLOW_BBCODE_PHP;
break;
case 'code':
$flag_value = ALLOW_BBCODE_CODE;
break;
case 'html':
$flag_value = ALLOW_BBCODE_HTML;
break;
default:
return true;
}
return ($vbulletin->options['allowedbbcodes'] & $flag_value ? true : false);
}
// ###################### Start handle_wysiwyg_img #######################
// named differently since it's not parsed via parse_wysiwyg_recurse
function handle_wysiwyg_img($img_url, $fullurl)
{
$img_url = str_replace('\\"', '"', $img_url);
$fullurl = str_replace('\\"', '"', $fullurl);
// handle image attachments stored locally in our db
if (preg_match('#attachment.php\?attachmentid=(\d+)#si', $img_url, $matches) AND preg_match('#class=(\'|"|)([a-z0-9_-\s]+)?\s*previewthumb\s*([a-z0-9_-\s]+)?(\\1)#si', $fullurl))
{
return '[ATTACH=CONFIG]' . $matches[1] . '[/ATTACH]';
}
// handle images with a relative path
else if (!preg_match('#^https?://#i', $img_url))
{
// prefix with the URL to this board
return '[IMG]'. create_full_url($img_url) . '[/IMG]';
}
// handle fully qualified/external image urls, ex. from an rss feed
else
{
return '[IMG]' . $img_url . '[/IMG]';
}
}
// ###################### Start parse_style_attribute #######################
function parse_style_attribute($tagoptions, &$prependtags, &$appendtags)
{
$searchlist = array(
array('tag' => 'left', 'option' => false, 'regex' => '#text-align:\s*(left);?#i'),
array('tag' => 'center', 'option' => false, 'regex' => '#text-align:\s*(center);?#i'),
array('tag' => 'right', 'option' => false, 'regex' => '#text-align:\s*(right);?#i'),
array('tag' => 'color', 'option' => true, 'regex' => '#(?<![a-z0-9-])color:\s*([^;]+);?#i', 'match' => 1),
array('tag' => 'font', 'option' => true, 'regex' => '#font-family:\s*(\'|)([^;,\']+)\\1[^;]*;?#i', 'match' => 2),
array('tag' => 'b', 'option' => false, 'regex' => '#font-weight:\s*(bold);?#i'),
array('tag' => 'i', 'option' => false, 'regex' => '#font-style:\s*(italic);?#i'),
array('tag' => 'u', 'option' => false, 'regex' => '#text-decoration:\s*(underline);?#i')
);
$style = parse_wysiwyg_tag_attribute('style=', $tagoptions);
$style = preg_replace(
'#(?<![a-z0-9-])color:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)(;?)#ie',
'sprintf("color: #%02X%02X%02X$4", $1, $2, $3)',
$style
);
foreach ($searchlist AS $searchtag)
{
if (!is_bbcode_tag_allowed($searchtag['tag']))
{
continue;
}
if (preg_match($searchtag['regex'], $style, $matches))
{
$prependtags .= '[' . strtoupper($searchtag['tag']) . iif($searchtag['option'] == true, '=' . $matches["$searchtag[match]"]) . ']';
$appendtags = '[/' . strtoupper($searchtag['tag']) . "]$appendtags";
}
}
}
// ###################### Start parse_wysiwyg_anchor #######################
function parse_wysiwyg_anchor($aoptions, $text)
{
global $vbulletin;
$href = parse_wysiwyg_tag_attribute('href=', $aoptions);
if (!trim($href))
{
return parse_wysiwyg_recurse('a', $text, 'parse_wysiwyg_anchor');
}
if (substr($href, 0, 7) == 'mailto:')
{
$tag = 'email';
$href = substr($href, 7);
}
else
{
$tag = 'url';
if (!preg_match('#^[a-z0-9]+:#i', $href))
{
// relative URL, prefix it with the URL to this board
$href = create_full_url($href);
}
}
$tag = strtoupper($tag);
if ($vbulletin->options['allowedbbcodes'] & ALLOW_BBCODE_URL)
{
return "[$tag=\"$href\"]" . parse_wysiwyg_recurse('a', $text, 'parse_wysiwyg_anchor') . "[/$tag]";
}
else
{
// can't auto link, return a plaintext version
$inner_text = parse_wysiwyg_recurse('a', $text, 'parse_wysiwyg_anchor');
if ($inner_text != $href)
{
return "$inner_text ($href)";
}
else
{
return $href;
}
}
}
// ###################### Start WYSIWYG_paraparser #######################
function parse_wysiwyg_paragraph($poptions, $text)
{
$style = parse_wysiwyg_tag_attribute('style=', $poptions);
$align = parse_wysiwyg_tag_attribute('align=', $poptions);
// only allow left/center/right alignments
switch ($align)
{
case 'left':
case 'center':
case 'right':
break;
default:
$align = '';
}
$align = strtoupper($align);
$prepend = '';
$append = '';
parse_style_attribute($poptions, $prepend, $append);
if ($align AND is_bbcode_tag_allowed($align))
{
$prepend .= "[$align]";
$append .= "[/$align]";
}
// ick ick -- hack to allow p's to be have 2 line breaks
global $p_two_linebreak;
if ($p_two_linebreak)
{
$append .= "\n\n";
}
else
{
$append .= "\n";
}
return $prepend . parse_wysiwyg_recurse('p', $text, 'parse_wysiwyg_paragraph') . $append;
}
// ###################### Start parse_wysiwyg_span #######################
function parse_wysiwyg_span($spanoptions, $text)
{
$prependtags = '';
$appendtags = '';
parse_style_attribute($spanoptions, $prependtags, $appendtags);
return $prependtags . parse_wysiwyg_recurse('span', $text, 'parse_wysiwyg_span') . $appendtags;
}
// ###################### Start WYSIWYG_divparser #######################
function parse_wysiwyg_div($divoptions, $text)
{
$prepend = '';
$append = '';
parse_style_attribute($divoptions, $prepend, $append);
$align = parse_wysiwyg_tag_attribute('align=', $divoptions);
// only allow left/center/right alignments
switch ($align)
{
case 'left':
case 'center':
case 'right':
break;
default:
$align = '';
}
$align = strtoupper($align);
if ($align AND is_bbcode_tag_allowed($align))
{
$prepend .= "[$align]";
$append .= "[/$align]";
}
$append .= "\n";
return $prepend . parse_wysiwyg_recurse('div', $text, 'parse_wysiwyg_div') . $append;
}
// ###################### Start WYSIWYG_listelementparser #######################
function parse_wysiwyg_list_element($listoptions, $text)
{
if (!is_bbcode_tag_allowed('list'))
{
return "$text\n";
}
return '[*]' . rtrim($text);
}
// ###################### Start WYSIWYG_listparser #######################
function parse_wysiwyg_list($listoptions, $text, $tagname)
{
$longtype = parse_wysiwyg_tag_attribute('class=', $listoptions);
$listtype = trim(preg_replace('#"?LIST-STYLE-TYPE:\s*([a-z0-9_-]+);?"?#si', '\\1', $longtype));
if (empty($listtype) AND $tagname == 'ol')
{
$listtype = 'decimal';
}
$text = preg_replace('#<li>((?'.'>[^[<]+?|(?!</li).)*)(?=</?ol|</?ul|<li|\[list|\[/list)#siU', '<li>\\1</li>', $text);
$text = parse_wysiwyg_recurse('li', $text, 'parse_wysiwyg_list_element');
if (!is_bbcode_tag_allowed('list'))
{
return $text;
}
$validtypes = array(
'upper-alpha' => 'A',
'lower-alpha' => 'a',
'upper-roman' => 'I',
'lower-roman' => 'i',
'decimal' => '1'
);
if (!isset($validtypes["$listtype"]))
{
$opentag = '[LIST]'; // default to bulleted
}
else
{
$opentag = '[LIST=' . $validtypes[$listtype] . ']';
}
return $opentag . parse_wysiwyg_recurse($tagname, $text, 'parse_wysiwyg_list') . '[/LIST]';
}
// ###################### Start WYSIWYG_fontparser #######################
function parse_wysiwyg_font($fontoptions, $text)
{
$tags = array(
'font' => 'face=',
'size' => 'size=',
'color' => 'color='
);
$prependtags = '';
$appendtags = '';
$fontoptionlen = strlen($fontoptions);
foreach ($tags AS $vbcode => $locate)
{
$optionvalue = parse_wysiwyg_tag_attribute($locate, $fontoptions);
if ($optionvalue)
{
$vbcode = strtoupper($vbcode);
$prependtags .= "[$vbcode=$optionvalue]";
$appendtags = "[/$vbcode]$appendtags";
}
}
parse_style_attribute($fontoptions, $prependtags, $appendtags);
return $prependtags . parse_wysiwyg_recurse('font', $text, 'parse_wysiwyg_font') . $appendtags;
}
// ###################### Start WYSIWYG_bbcodereplace #######################
function parse_wysiwyg_code_replacement($options, $text, $tagname, $parseto)
{
$useoptions = array(); // array of (key) tag name; (val) option to read. If tag name isn't found, no option is used
if (trim($text) == '')
{
return '';
}
if (!is_bbcode_tag_allowed($parseto))
{
return $text;
}
$parseto = strtoupper($parseto);
if (empty($useoptions["$tagname"]))
{
$text = parse_wysiwyg_recurse($tagname, $text, 'parse_wysiwyg_code_replacement', $parseto);
return "[$parseto]{$text}[/$parseto]";
}
else
{
$optionvalue = parse_wysiwyg_tag_attribute($useoptions["$tagname"], $options);
if ($optionvalue)
{
return "[$parseto=$optionvalue]{$text}[/$parseto]";
}
else
{
return "[$parseto]{$text}[/$parseto]";
}
}
}
// ###################### Start WYSIWYG_recursiveparser #######################
function parse_wysiwyg_recurse($tagname, $text, $functionhandle, $extraargs = '')
{
$tagname = strtolower($tagname);
$open_tag = "<$tagname";
$open_tag_len = strlen($open_tag);
$close_tag = "</$tagname>";
$close_tag_len = strlen($close_tag);
$beginsearchpos = 0;
do {
$textlower = strtolower($text);
$tagbegin = @strpos($textlower, $open_tag, $beginsearchpos);
if ($tagbegin === false)
{
break;
}
$strlen = strlen($text);
// we've found the beginning of the tag, now extract the options
$inquote = '';
$found = false;
$tagnameend = false;
for ($optionend = $tagbegin; $optionend <= $strlen; $optionend++)
{
$char = $text{$optionend};
if (($char == '"' OR $char == "'") AND $inquote == '')
{
$inquote = $char; // wasn't in a quote, but now we are
}
else if (($char == '"' OR $char == "'") AND $inquote == $char)
{
$inquote = ''; // left the type of quote we were in
}
else if ($char == '>' AND !$inquote)
{
$found = true;
break; // this is what we want
}
else if (($char == '=' OR $char == ' ') AND !$tagnameend)
{
$tagnameend = $optionend;
}
}
if (!$found)
{
break;
}
if (!$tagnameend)
{
$tagnameend = $optionend;
}
$offset = $optionend - ($tagbegin + $open_tag_len);
$tagoptions = substr($text, $tagbegin + $open_tag_len, $offset);
$acttagname = substr($textlower, $tagbegin + 1, $tagnameend - $tagbegin - 1);
if ($acttagname != $tagname)
{
$beginsearchpos = $optionend;
continue;
}
// now find the "end"
$tagend = strpos($textlower, $close_tag, $optionend);
if ($tagend === false)
{
break;
}
// if there are nested tags, this </$tagname> won't match our open tag, so we need to bump it back
$nestedopenpos = strpos($textlower, $open_tag, $optionend);
while ($nestedopenpos !== false AND $tagend !== false)
{
if ($nestedopenpos > $tagend)
{ // the tag it found isn't actually nested -- it's past the </$tagname>
break;
}
$tagend = strpos($textlower, $close_tag, $tagend + $close_tag_len);
$nestedopenpos = strpos($textlower, $open_tag, $nestedopenpos + $open_tag_len);
}
if ($tagend === false)
{
$beginsearchpos = $optionend;
continue;
}
$localbegin = $optionend + 1;
$localtext = $functionhandle($tagoptions, substr($text, $localbegin, $tagend - $localbegin), $tagname, $extraargs);
$text = substr_replace($text, $localtext, $tagbegin, $tagend + $close_tag_len - $tagbegin);
// this adjusts for $localtext having more/less characters than the amount of text it's replacing
$beginsearchpos = $tagbegin + strlen($localtext);
} while ($tagbegin !== false);
return $text;
}
// ###################### Start WYSIWYG_readoption #######################
function parse_wysiwyg_tag_attribute($option, $text)
{
if (($position = strpos($text, $option)) !== false)
{
$delimiter = $position + strlen($option);
if ($text{$delimiter} == '"')
{ // read to another "
$delimchar = '"';
}
else if ($text{$delimiter} == '\'')
{
$delimchar = '\'';
}
else
{ // read to a space
$delimchar = ' ';
}
$delimloc = strpos($text, $delimchar, $delimiter + 1);
if ($delimloc === false)
{
$delimloc = strlen($text);
}
else if ($delimchar == '"' OR $delimchar == '\'')
{
// don't include the delimiters
$delimiter++;
}
return trim(substr($text, $delimiter, $delimloc - $delimiter));
}
else
{
return '';
}
}
// ###################### Start strip_tags_callback #######################
function strip_tags_callback($text)
{
$text = str_replace('\\"', '"', $text);
return strip_tags($text, '<p>');
}
/*======================================================================*\
|| ####################################################################
|| # CVS: $RCSfile$ - $Revision: 34202 $
|| ####################################################################
\*======================================================================*/
?>