function bbcode_quote($in)
{
global $config, $user;
$in = str_replace("\r\n", "\n", str_replace('\\"', '"', trim($in)));
if (!$in) {
return '';
}
// To let the parser not catch tokens within quote_username quotes we encode them before we start this...
$in = preg_replace('#quote="(.*?)"\\]#ie', "'quote="' . str_replace(array('[', ']', '\\\"'), array('[', ']', '\"'), '\$1') . '"]'", $in);
$tok = ']';
$out = '[';
$in = substr($in, 1);
$close_tags = $error_ary = array();
$buffer = '';
do {
$pos = strlen($in);
for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i) {
$tmp_pos = strpos($in, $tok[$i]);
if ($tmp_pos !== false && $tmp_pos < $pos) {
$pos = $tmp_pos;
}
}
$buffer .= substr($in, 0, $pos);
$tok = $in[$pos];
$in = substr($in, $pos + 1);
if ($tok == ']') {
if (strtolower($buffer) == '/quote' && sizeof($close_tags) && substr($out, -1, 1) == '[') {
// we have found a closing tag
$out .= array_pop($close_tags) . ']';
$tok = '[';
$buffer = '';
/* Add space at the end of the closing tag if not happened before to allow following urls/smilies to be parsed correctly
* Do not try to think for the user. :/ Do not parse urls/smilies if there is no space - is the same as with other bbcodes too.
* Also, we won't have any spaces within $in anyway, only adding up spaces -> #10982
if (!$in || $in[0] !== ' ')
{
$out .= ' ';
}*/
} else {
if (preg_match('#^quote(?:="(.*?)")?$#is', $buffer, $m) && substr($out, -1, 1) == '[') {
$this->parsed_items['quote']++;
// the buffer holds a valid opening tag
if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth']) {
if ($config['max_quote_depth'] == 1) {
// Depth 1 - no nesting is allowed
$error_ary['quote_depth'] = $user->lang('QUOTE_NO_NESTING');
} else {
// There are too many nested quotes
$error_ary['quote_depth'] = $user->lang('QUOTE_DEPTH_EXCEEDED', (int) $config['max_quote_depth']);
}
$out .= $buffer . $tok;
$tok = '[]';
$buffer = '';
continue;
}
array_push($close_tags, '/quote:' . $this->bbcode_uid);
if (isset($m[1]) && $m[1]) {
$username = str_replace(array('[', ']'), array('[', ']'), $m[1]);
$username = preg_replace('#\\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '[$1', $username);
$end_tags = array();
$error = false;
preg_match_all('#\\[((?:/)?(?:[a-z]+))#i', $username, $tags);
foreach ($tags[1] as $tag) {
if ($tag[0] != '/') {
$end_tags[] = '/' . $tag;
} else {
$end_tag = array_pop($end_tags);
$error = $end_tag != $tag ? true : false;
}
}
if ($error) {
$username = $m[1];
}
$out .= 'quote="' . $username . '":' . $this->bbcode_uid . ']';
} else {
$out .= 'quote:' . $this->bbcode_uid . ']';
}
$tok = '[';
$buffer = '';
} else {
if (preg_match('#^quote="(.*?)#is', $buffer, $m)) {
// the buffer holds an invalid opening tag
$buffer .= ']';
} else {
$out .= $buffer . $tok;
$tok = '[]';
$buffer = '';
}
}
}
} else {
/**
* Old quote code working fine, but having errors listed in bug #3572
*
* $out .= $buffer . $tok;
* $tok = ($tok == '[') ? ']' : '[]';
* $buffer = '';
*/
$out .= $buffer . $tok;
if ($tok == '[') {
// Search the text for the next tok... if an ending quote comes first, then change tok to []
$pos1 = stripos($in, '[/quote');
// If the token ] comes first, we change it to ]
$pos2 = strpos($in, ']');
// If the token [ comes first, we change it to [
$pos3 = strpos($in, '[');
if ($pos1 !== false && ($pos2 === false || $pos1 < $pos2) && ($pos3 === false || $pos1 < $pos3)) {
$tok = '[]';
} else {
if ($pos3 !== false && ($pos2 === false || $pos3 < $pos2)) {
$tok = '[';
} else {
$tok = ']';
}
}
} else {
$tok = '[]';
}
$buffer = '';
}
} while ($in);
$out .= $buffer;
if (sizeof($close_tags)) {
$out .= '[' . implode('][', $close_tags) . ']';
}
foreach ($error_ary as $error_msg) {
$this->warn_msg[] = $error_msg;
}
return $out;
}