bbcodes)
{
$this->bbcode_init();
}
global $user;
$this->bbcode_bitfield = '';
$bitfield = new bitfield();
$size = strlen($this->message);
foreach ($this->bbcodes as $bbcode_name => $bbcode_data)
{
if (isset($bbcode_data['disabled']) && $bbcode_data['disabled'])
{
foreach ($bbcode_data['regexp'] as $regexp => $replacement)
{
if (preg_match($regexp, $this->message))
{
$this->warn_msg[] = $user->lang['UNAUTHORISED_BBCODE'] . '[' . $bbcode_name . ']';
continue;
}
}
}
else
{
foreach ($bbcode_data['regexp'] as $regexp => $replacement)
{
$this->message = preg_replace($regexp, $replacement, $this->message);
}
}
// Because we add bbcode_uid to all tags, the message length
// will increase whenever a tag is found
$new_size = strlen($this->message);
if ($size != $new_size)
{
$bitfield->set($bbcode_data['bbcode_id']);
$size = $new_size;
}
}
$this->bbcode_bitfield = $bitfield->get_blob();
}
/**
* Prepare some bbcodes for better parsing
*/
function prepare_bbcodes()
{
// Add newline at the end and in front of each quote block to prevent parsing errors (urls, smilies, etc.)
if (strpos($this->message, '[quote') !== false)
{
$in = str_replace("\r\n", "\n", $this->message);
$this->message = preg_replace(array('#\[quote(=".*?")?\]([^\n])#is', '#([^\n])\[\/quote\]#is'), array("[quote\\1]\n\\2", "\\1\n[/quote]"), $this->message);
$this->message = preg_replace(array('#\[quote(=".*?")?\]([^\n])#is', '#([^\n])\[\/quote\]#is'), array("[quote\\1]\n\\2", "\\1\n[/quote]"), $this->message);
}
// Add other checks which needs to be placed before actually parsing anything (be it bbcodes, smilies, urls...)
}
/**
* Init bbcode data for later parsing
*/
function bbcode_init()
{
static $rowset;
// This array holds all bbcode data. BBCodes will be processed in this
// order, so it is important to keep [code] in first position and
// [quote] in second position.
$this->bbcodes = array(
'code' => array('bbcode_id' => 8, 'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#ise' => "\$this->bbcode_code('\$1', '\$2')")),
'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:="(.*?)")?\](.+)\[/quote\]#ise' => "\$this->bbcode_quote('\$0')")),
'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#ise' => "\$this->bbcode_attachment('\$1', '\$2')")),
'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#ise' => "\$this->bbcode_strong('\$1')")),
'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#ise' => "\$this->bbcode_italic('\$1')")),
'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](.*)\[/url\]#iUe' => "\$this->validate_url('\$2', '\$3')")),
'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](https?://)([a-z0-9\-\.,\?!%\*_:;~\\&$@/=\+]+)\[/img\]#ie' => "\$this->bbcode_img('\$1\$2')")),
'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?[1-2]?[0-9])\](.*?)\[/size\]#ise' => "\$this->bbcode_size('\$1', '\$2')")),
'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9A-Fa-f]{6}|[a-z\-]+)\](.*?)\[/color\]!ise' => "\$this->bbcode_color('\$1', '\$2')")),
'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#ise' => "\$this->bbcode_underline('\$1')")),
'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(=[a-z|0-9|(?:disc|circle|square))]+)?\].*\[/list\]#ise' => "\$this->bbcode_parse_list('\$0')")),
'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#ise' => "\$this->validate_email('\$1', '\$2')")),
'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#ie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')"))
);
// Zero the parsed items array
$this->parsed_items = array();
foreach ($this->bbcodes as $tag => $bbcode_data)
{
$this->parsed_items[$tag] = 0;
}
if (!is_array($rowset))
{
global $db;
$rowset = array();
$sql = 'SELECT *
FROM ' . BBCODES_TABLE;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$rowset[] = $row;
}
$db->sql_freeresult($result);
}
foreach ($rowset as $row)
{
$this->bbcodes[$row['bbcode_tag']] = array(
'bbcode_id' => (int) $row['bbcode_id'],
'regexp' => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace']))
);
}
}
/**
* Making some pre-checks for bbcodes as well as increasing the number of parsed items
*/
function check_bbcode($bbcode, &$in)
{
// when using the /e modifier, preg_replace slashes double-quotes but does not
// seem to slash anything else
$in = str_replace("\r\n", "\n", str_replace('\"', '"', $in));
// Trimming here to make sure no empty bbcodes are parsed accidently
if (trim($in) == '')
{
return false;
}
$this->parsed_items[$bbcode]++;
return true;
}
/**
* Transform some characters in valid bbcodes
*/
function bbcode_specialchars($text)
{
$str_from = array('<', '>', '[', ']', '.', ':');
$str_to = array('<', '>', '[', ']', '.', ':');
return str_replace($str_from, $str_to, $text);
}
/**
* Parse size tag
*/
function bbcode_size($stx, $in)
{
global $user, $config;
if (!$this->check_bbcode('size', $in))
{
return '';
}
if ($config['max_' . $this->mode . '_font_size'] && $config['max_' . $this->mode . '_font_size'] < $stx)
{
$this->warn_msg[] = sprintf($user->lang['MAX_FONT_SIZE_EXCEEDED'], $config['max_' . $this->mode . '_font_size']);
}
return '[size=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/size:' . $this->bbcode_uid . ']';
}
/**
* Parse color tag
*/
function bbcode_color($stx, $in)
{
if (!$this->check_bbcode('color', $in))
{
return '';
}
return '[color=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/color:' . $this->bbcode_uid . ']';
}
/**
* Parse u tag
*/
function bbcode_underline($in)
{
if (!$this->check_bbcode('u', $in))
{
return '';
}
return '[u:' . $this->bbcode_uid . ']' . $in . '[/u:' . $this->bbcode_uid . ']';
}
/**
* Parse b tag
*/
function bbcode_strong($in)
{
if (!$this->check_bbcode('b', $in))
{
return '';
}
return '[b:' . $this->bbcode_uid . ']' . $in . '[/b:' . $this->bbcode_uid . ']';
}
/**
* Parse i tag
*/
function bbcode_italic($in)
{
if (!$this->check_bbcode('i', $in))
{
return '';
}
return '[i:' . $this->bbcode_uid . ']' . $in . '[/i:' . $this->bbcode_uid . ']';
}
/**
* Parse img tag
*/
function bbcode_img($in)
{
global $user, $config, $phpEx;
if (!$this->check_bbcode('img', $in))
{
return '';
}
$in = trim($in);
if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
{
$stats = @getimagesize($in);
if ($stats === false)
{
$this->warn_msg[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
}
else
{
if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $stats[1])
{
$this->warn_msg[] = sprintf($user->lang['MAX_IMG_HEIGHT_EXCEEDED'], $config['max_' . $this->mode . '_img_height']);
}
if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $stats[0])
{
$this->warn_msg[] = sprintf($user->lang['MAX_IMG_WIDTH_EXCEEDED'], $config['max_' . $this->mode . '_img_width']);
}
}
}
if ($this->path_in_domain($in))
{
return '[img]' . $in . '[/img]';
}
return '[img:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/img:' . $this->bbcode_uid . ']';
}
/**
* Parse flash tag
*/
function bbcode_flash($width, $height, $in)
{
global $user, $config, $phpEx;
if (!$this->check_bbcode('flash', $in))
{
return '';
}
$in = trim($in);
// Apply the same size checks on flash files as on images
if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
{
if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $height)
{
$this->warn_msg[] = sprintf($user->lang['MAX_FLASH_HEIGHT_EXCEEDED'], $config['max_' . $this->mode . '_img_height']);
}
if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $width)
{
$this->warn_msg[] = sprintf($user->lang['MAX_FLASH_WIDTH_EXCEEDED'], $config['max_' . $this->mode . '_img_width']);
}
}
if ($this->path_in_domain($in))
{
return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
}
return '[flash=' . $width . ',' . $height . ':' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/flash:' . $this->bbcode_uid . ']';
}
/**
* Parse inline attachments [ia]
*/
function bbcode_attachment($stx, $in)
{
if (!$this->check_bbcode('attachment', $in))
{
return '';
}
return '[attachment=' . $stx . ':' . $this->bbcode_uid . ']' . trim($in) . '[/attachment:' . $this->bbcode_uid . ']';
}
/**
* Parse code tag
* Expects the argument to start right after the opening [code] tag and to end with [/code]
*/
function bbcode_code($stx, $in)
{
if (!$this->check_bbcode('code', $in))
{
return '';
}
// We remove the hardcoded elements from the code block here because it is not used in code blocks
// Having it here saves us one preg_replace per message containing [code] blocks
// Additionally, magic url parsing should go after parsing bbcodes, but for safety those are stripped out too...
$htm_match = array(
'#.*?#',
'#.*?#',
'#.*?#',
'#.*?#',
'#";
}
$conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
foreach ($conf as $ini_var)
{
ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
}
// Because highlight_string is specialcharing the text (but we already did this before), we have to reverse this in order to get correct results
$code = html_entity_decode($code);
$code = highlight_string($code, true);
$str_from = array('', '', '
','[', ']', '.', ':');
$str_to = array('', '', '', '[', ']', '.', ':');
if ($remove_tags)
{
$str_from[] = '<?php ';
$str_to[] = '';
$str_from[] = '<?php ';
$str_to[] = '';
}
$code = str_replace($str_from, $str_to, $code);
$code = preg_replace('#^()\n?(.*?)\n?()$#is', '$1$2$3', $code);
if ($remove_tags)
{
$code = preg_replace('#()?\?>#', '', $code);
}
$code = preg_replace('#^(.*)#s', '$2', $code);
$code = preg_replace('#(?:[\n\r\s\t]| )*$#', '', $code);
$out .= "[code=$stx:" . $this->bbcode_uid . ']' . $code . '[/code:' . $this->bbcode_uid . ']';
break;
default:
$out .= '[code:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($code) . '[/code:' . $this->bbcode_uid . ']';
break;
}
if (preg_match('#(.*?)\[code(?:=([a-z]+))?\](.+)#is', $in, $m))
{
$out .= $m[1];
$stx = $m[2];
$in = $m[3];
}
}
while ($in);
return $out;
}
/**
* Parse list bbcode
* Expects the argument to start with a tag
*/
function bbcode_parse_list($in)
{
if (!$this->check_bbcode('list', $in))
{
return '';
}
$out = '[';
// Grab item_start with no item_end
$in = preg_replace('#\[\*\](.*?)(\[\/list\]|\[list(=?(?:[0-9]|[a-z]|))\]|\[\*\])#is', '[*:' . $this->bbcode_uid . ']\1[/*:m:' . $this->bbcode_uid . ']\2', $in);
// Grab them again as backreference
$in = preg_replace('#\[\*\](.*?)(\[\/list\]|\[list(=?(?:[0-9]|[a-z]|))\]|\[\*\])(^\[\/*\])#is', '[*:' . $this->bbcode_uid . ']\1[/*:m:' . $this->bbcode_uid . ']\2', $in);
// Grab end tag following start tag
$in = preg_replace('#\[\/\*:m:' . $this->bbcode_uid . '\](\n|)\[\*\]#is', '[/*:m:' . $this->bbcode_uid . '][*:' . $this->bbcode_uid . ']', $in);
// Replace end tag
$in = preg_replace('#\[\/\*\]#i', '[/*:' . $this->bbcode_uid . ']', $in);
// $tok holds characters to stop at. Since the string starts with a '[' we'll get everything up to the first ']' which should be the opening [list] tag
$tok = ']';
$out = '[';
$in = substr($in, 1);
$list_end_tags = array();
do
{
$pos = strlen($in);
for ($i = 0; $i < strlen($tok); ++$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 $tok is ']' the buffer holds a tag
if ($buffer == '/list' && sizeof($list_end_tags))
{
$out .= array_pop($list_end_tags) . ']';
$tok = '[';
}
else if (preg_match('#list(=?(?:[0-9]|[a-z]|))#i', $buffer, $m))
{
// sub-list, add a closing tag
if (!$m[1] || preg_match('/^(disc|square|circle)$/i', $m[1]))
{
array_push($list_end_tags, '/list:u:' . $this->bbcode_uid);
}
else
{
array_push($list_end_tags, '/list:o:' . $this->bbcode_uid);
}
$out .= $buffer . ':' . $this->bbcode_uid . ']';
$tok = '[';
}
else
{
$out .= $buffer . $tok;
$tok = '[]';
}
}
else
{
// Not within a tag, just add buffer to the return string
$out .= $buffer . $tok;
$tok = ($tok == '[') ? ']' : '[]';
}
}
while ($in);
if (sizeof($list_end_tags))
{
$out .= '[' . implode('][', $list_end_tags) . ']';
}
return $out;
}
/**
* Parse quote bbcode
* Expects the argument to start with a tag
*/
function bbcode_quote($in)
{
global $config, $user;
$in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in)));
if (!$in)
{
return '';
}
$tok = ']';
$out = '[';
$in = substr($in, 1);
$close_tags = $error_ary = array();
$buffer = '';
do
{
$pos = strlen($in);
for ($i = 0; $i < strlen($tok); ++$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 ($buffer == '/quote' && sizeof($close_tags))
{
// we have found a closing tag
// Add space at the end of the closing tag to allow following urls/smilies to be parsed correctly
$out .= array_pop($close_tags) . '] ';
$tok = '[';
$buffer = '';
}
else if (preg_match('#^quote(?:="(.*?)")?$#is', $buffer, $m))
{
$this->parsed_items['quote']++;
// the buffer holds a valid opening tag
if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth'])
{
// there are too many nested quotes
$error_ary['quote_depth'] = sprintf($user->lang['QUOTE_DEPTH_EXCEEDED'], $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 = preg_replace('#\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '[$1', $m[1]);
$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);
if ($end_tag != $tag)
{
$error = true;
}
else
{
$error = false;
}
}
}
if ($error)
{
$username = str_replace('[', '[', str_replace(']', ']', $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
{
$out .= $buffer . $tok;
$tok = ($tok == '[') ? ']' : '[]';
$buffer = '';
}
}
while ($in);
if (sizeof($close_tags))
{
$out .= '[' . implode('][', $close_tags) . ']';
}
foreach ($error_ary as $error_msg)
{
$this->warn_msg[] = $error_msg;
}
return $out;
}
/**
* Validate email
*/
function validate_email($var1, $var2)
{
$var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1)));
$var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2)));
$txt = $var2;
$email = ($var1) ? $var1 : $var2;
$validated = true;
if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
{
$validated = false;
}
if (!$validated)
{
return '[email' . (($var1) ? "=$var1" : '') . ']' . $var2 . '[/email]';
}
$this->parsed_items['email']++;
if ($var1)
{
$retval = '[email=' . $this->bbcode_specialchars($email) . ':' . $this->bbcode_uid . ']' . $txt . '[/email:' . $this->bbcode_uid . ']';
}
else
{
$retval = '[email:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($email) . '[/email:' . $this->bbcode_uid . ']';
}
return $retval;
}
/**
* Validate url
*/
function validate_url($var1, $var2)
{
global $config;
$var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1)));
$var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2)));
$url = ($var1) ? $var1 : $var2;
$valid = false;
if (!$url || ($var1 && !$var2))
{
return '';
}
// Checking urls
if (preg_match('#' . preg_quote(generate_board_url(), '#') . '/([^ \t\n\r<"\']+)#i', $url) ||
preg_match('#([\w]+?://.*?[^ \t\n\r<"\']*)#i', $url) ||
preg_match('#(www\.[\w\-]+\.[\w\-.\~]+(?:/[^ \t\n\r<"\']*)?)#i', $url))
{
$valid = true;
}
if ($valid)
{
$this->parsed_items['url']++;
if (!preg_match('#^[\w]+?://.*?#i', $url))
{
$url = 'http://' . $url;
}
// We take our test url and stick on the first bit of text we get to check if we are really at the domain. If so, lets go!
if (strpos($url, generate_board_url()) !== false && strpos($url, 'sid=') !== false)
{
$url = preg_replace('/(&|\?)sid=[0-9a-f]{32}/', '\1', $url);
}
return ($var1) ? '[url=' . $this->bbcode_specialchars($url) . ':' . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($url) . '[/url:' . $this->bbcode_uid . ']';
}
return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]';
}
/**
* Check if url is pointing to this domain/script_path/php-file
*
* @param string $url the url to check
* @return true if the url is pointing to this domain/script_path/php-file, false if not
*
* @access: private
*/
function path_in_domain($url)
{
global $config, $phpEx, $user;
$check_path = ($user->page['root_script_path'] != '/') ? substr($user->page['root_script_path'], 0, -1) : '/';
// Is the user trying to link to a php file in this domain and script path?
if (strpos($url, ".{$phpEx}") !== false && strpos($url, $check_path) !== false)
{
$server_name = (!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME');
// Forcing server vars is the only way to specify/override the protocol
if ($config['force_server_vars'] || !$server_name)
{
$server_name = $config['server_name'];
}
// Check again in correct order...
$pos_ext = strpos($url, ".{$phpEx}");
$pos_path = strpos($url, $check_path);
$pos_domain = strpos($url, $server_name);
if ($pos_domain !== false && $pos_path >= $pos_domain && $pos_ext >= $pos_path)
{
return true;
}
}
return false;
}
}
/**
* Main message parser for posting, pm, etc. takes raw message
* and parses it for attachments, bbcode and smilies
* @package phpBB3
*/
class parse_message extends bbcode_firstpass
{
var $attachment_data = array();
var $filename_data = array();
// Helps ironing out user error
var $message_status = '';
var $allow_img_bbcode = true;
var $allow_flash_bbcode = true;
var $allow_quote_bbcode = true;
var $mode;
/**
* Init - give message here or manually
*/
function parse_message($message = '')
{
// Init BBCode UID
$this->bbcode_uid = substr(md5(time()), 0, BBCODE_UID_LEN);
if ($message)
{
$this->message = $message;
}
}
/**
* Parse Message
*/
function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $update_this_message = true, $mode = 'post')
{
global $config, $db, $user;
$mode = ($mode != 'post') ? 'sig' : 'post';
$this->mode = $mode;
$this->allow_img_bbcode = $allow_img_bbcode;
$this->allow_flash_bbcode = $allow_flash_bbcode;
$this->allow_quote_bbcode = $allow_quote_bbcode;
// If false, then $this->message won't be altered, the text will be returned instead.
if (!$update_this_message)
{
$tmp_message = $this->message;
$return_message = &$this->message;
}
if ($this->message_status == 'display')
{
$this->decode_message();
}
// Do some general 'cleanup' first before processing message,
// e.g. remove excessive newlines(?), smilies(?)
// Transform \r\n and \r into \n
$match = array('#\r\n?#', "#([\n][\s]+){3,}#", '#(script|about|applet|activex|chrome):#i');
$replace = array("\n", "\n\n", "\\1:");
$this->message = preg_replace($match, $replace, trim($this->message));
// Message length check. -1 disables this check completely.
if ($config['max_' . $mode . '_chars'] != -1)
{
$msg_len = ($mode == 'post') ? strlen($this->message) : strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#is', ' ', $this->message));
if ((!$msg_len && $mode !== 'sig') || $config['max_' . $mode . '_chars'] && $msg_len > $config['max_' . $mode . '_chars'])
{
$this->warn_msg[] = (!$msg_len) ? $user->lang['TOO_FEW_CHARS'] : $user->lang['TOO_MANY_CHARS'];
return $this->warn_msg;
}
}
// Prepare BBcode (just prepares some tags for better parsing)
if ($allow_bbcode && strpos($this->message, '[') !== false)
{
$this->bbcode_init();
$disallow = array('img', 'flash', 'quote');
foreach ($disallow as $bool)
{
if (!${'allow_' . $bool . '_bbcode'})
{
$this->bbcodes[$bool]['disabled'] = true;
}
}
$this->prepare_bbcodes();
}
// Parse smilies
if ($allow_smilies)
{
$this->smilies($config['max_' . $mode . '_smilies']);
}
$num_urls = 0;
// Parse BBCode
if ($allow_bbcode && strpos($this->message, '[') !== false)
{
$this->parse_bbcode();
$num_urls += $this->parsed_items['url'];
}
// Parse URL's
if ($allow_magic_url)
{
$this->magic_url(generate_board_url());
if ($config['max_' . $mode . '_urls'])
{
$num_urls += preg_match_all('#\';
}
$db->sql_freeresult($result);
}
if (sizeof($match))
{
if ($max_smilies)
{
$num_matches = preg_match_all('#' . str_replace('#', '', implode('|', $match)) . '#', $this->message, $matches);
unset($matches);
if ($num_matches !== false && $num_matches > $max_smilies)
{
$this->warn_msg[] = sprintf($user->lang['TOO_MANY_SMILIES'], $max_smilies);
return;
}
}
$this->message = trim(preg_replace($match, $replace, $this->message));
}
}
/**
* Parse Attachments
*/
function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
{
global $config, $auth, $user, $phpbb_root_path, $phpEx;
$error = array();
$num_attachments = sizeof($this->attachment_data);
$this->filename_data['filecomment'] = request_var('filecomment', '', true);
$upload_file = (isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none' && trim($_FILES[$form_name]['name'])) ? true : false;
$add_file = (isset($_POST['add_file'])) ? true : false;
$delete_file = (isset($_POST['delete_file'])) ? true : false;
$edit_comment = (isset($_POST['edit_comment'])) ? true : false;
$cfg = array();
$cfg['max_attachments'] = ($is_message) ? $config['max_attachments_pm'] : $config['max_attachments'];
$forum_id = ($is_message) ? 0 : $forum_id;
if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file)
{
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id))
{
$filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
$error = $filedata['error'];
if ($filedata['post_attach'] && !sizeof($error))
{
$new_entry = array(
'physical_filename' => $filedata['physical_filename'],
'attach_comment' => $this->filename_data['filecomment'],
'real_filename' => $filedata['real_filename'],
'extension' => $filedata['extension'],
'mimetype' => $filedata['mimetype'],
'filesize' => $filedata['filesize'],
'filetime' => $filedata['filetime'],
'attach_id' => 0,
'thumbnail' => $filedata['thumbnail']
);
$this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
$this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
$this->filename_data['filecomment'] = '';
// This Variable is set to false here, because Attachments are entered into the
// Database in two modes, one if the id_list is 0 and the second one if post_attach is true
// Since post_attach is automatically switched to true if an Attachment got added to the filesystem,
// but we are assigning an id of 0 here, we have to reset the post_attach variable to false.
//
// This is very relevant, because it could happen that the post got not submitted, but we do not
// know this circumstance here. We could be at the posting page or we could be redirected to the entered
// post. :)
$filedata['post_attach'] = false;
}
}
else
{
$error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']);
}
}
if ($preview || $refresh || sizeof($error))
{
// Perform actions on temporary attachments
if ($delete_file)
{
include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
$index = (int) key($_POST['delete_file']);
// delete selected attachment
if (!$this->attachment_data[$index]['attach_id'])
{
phpbb_unlink($this->attachment_data[$index]['physical_filename'], 'file');
if ($this->attachment_data[$index]['thumbnail'])
{
phpbb_unlink($this->attachment_data[$index]['physical_filename'], 'thumbnail');
}
}
else
{
delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id'])));
}
unset($this->attachment_data[$index]);
$this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message);
// Reindex Array
$this->attachment_data = array_values($this->attachment_data);
}
else if ($edit_comment || $add_file || $preview)
{
if ($edit_comment)
{
$actual_comment_list = request_var('comment_list', array(''), true);
$edit_comment = request_var('edit_comment', array(0 => ''));
$edit_comment = key($edit_comment);
$this->attachment_data[$edit_comment]['attach_comment'] = $actual_comment_list[$edit_comment];
}
if (($add_file || $preview) && $upload_file)
{
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_'))
{
$filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
$error = array_merge($error, $filedata['error']);
if (!sizeof($error))
{
$new_entry = array(
'physical_filename' => $filedata['physical_filename'],
'attach_comment' => $this->filename_data['filecomment'],
'real_filename' => $filedata['real_filename'],
'extension' => $filedata['extension'],
'mimetype' => $filedata['mimetype'],
'filesize' => $filedata['filesize'],
'filetime' => $filedata['filetime'],
'attach_id' => 0,
'thumbnail' => $filedata['thumbnail']
);
$this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
$this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
$this->filename_data['filecomment'] = '';
}
}
else
{
$error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']);
}
}
}
}
foreach ($error as $error_msg)
{
$this->warn_msg[] = $error_msg;
}
}
/**
* Get Attachment Data
*/
function get_submitted_attachment_data($check_user_id = false)
{
global $user, $db, $phpbb_root_path, $phpEx, $config;
$this->filename_data['filecomment'] = request_var('filecomment', '', true);
$this->attachment_data = (isset($_POST['attachment_data'])) ? $_POST['attachment_data'] : array();
$check_user_id = ($check_user_id === false) ? $user->data['user_id'] : $check_user_id;
// Regenerate data array...
$attach_ids = $filenames = array();
foreach ($this->attachment_data as $pos => $var_ary)
{
if ($var_ary['attach_id'])
{
$attach_ids[(int) $this->attachment_data[$pos]['attach_id']] = $pos;
}
else
{
$filenames[$pos] = '';
set_var($filenames[$pos], $this->attachment_data[$pos]['physical_filename'], 'string');
$filenames[$pos] = basename($filenames[$pos]);
}
}
$this->attachment_data = array();
// Regenerate already posted attachments...
if (sizeof($attach_ids))
{
// Get the data from the attachments
$sql = 'SELECT attach_id, physical_filename, real_filename, extension, mimetype, filesize, filetime, thumbnail
FROM ' . ATTACHMENTS_TABLE . '
WHERE attach_id IN (' . implode(', ', array_keys($attach_ids)) . ')
AND poster_id = ' . $check_user_id;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (isset($attach_ids[$row['attach_id']]))
{
$pos = $attach_ids[$row['attach_id']];
$this->attachment_data[$pos] = $row;
set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true);
unset($attach_ids[$row['attach_id']]);
}
}
$db->sql_freeresult($result);
if (sizeof($attach_ids))
{
trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR);
}
}
// Regenerate newly uploaded attachments
if (sizeof($filenames))
{
include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
$sql = 'SELECT attach_id
FROM ' . ATTACHMENTS_TABLE . "
WHERE LOWER(physical_filename) IN ('" . implode("', '", array_map('strtolower', $filenames)) . "')";
$result = $db->sql_query_limit($sql, 1);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($row)
{
trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR);
}
foreach ($filenames as $pos => $physical_filename)
{
$this->attachment_data[$pos] = array(
'physical_filename' => $physical_filename,
'extension' => strtolower(filespec::get_extension($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename)),
'filesize' => filespec::get_filesize($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename),
'attach_id' => 0,
'thumbnail' => (file_exists($phpbb_root_path . $config['upload_path'] . '/thumb_' . $physical_filename)) ? 1 : 0,
);
set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true);
set_var($this->attachment_data[$pos]['real_filename'], $_POST['attachment_data'][$pos]['real_filename'], 'string', true);
set_var($this->attachment_data[$pos]['filetime'], $_POST['attachment_data'][$pos]['filetime'], 'int');
if (strpos($_POST['attachment_data'][$pos]['mimetype'], 'image/') !== false)
{
set_var($this->attachment_data[$pos]['mimetype'], $_POST['attachment_data'][$pos]['mimetype'], 'string');
}
else
{
$this->attachment_data[$pos]['mimetype'] = filespec::get_mimetype($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename);
}
}
}
}
/**
* Parse Poll
*/
function parse_poll(&$poll)
{
global $auth, $user, $config;
$poll_max_options = $poll['poll_max_options'];
// Parse Poll Option text ;)
$tmp_message = $this->message;
$this->message = $poll['poll_option_text'];
$poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], $poll['enable_urls'], $poll['enable_smilies'], $poll['img_status'], false, false, false);
$this->message = $tmp_message;
// Parse Poll Title
$tmp_message = $this->message;
$this->message = $poll['poll_title'];
$poll['poll_title'] = $this->parse($poll['enable_bbcode'], $poll['enable_urls'], $poll['enable_smilies'], $poll['img_status'], false, false, false);
$this->message = $tmp_message;
unset($tmp_message);
$poll['poll_options'] = explode("\n", trim($poll['poll_option_text']));
$poll['poll_options_size'] = sizeof($poll['poll_options']);
if (sizeof($poll['poll_options']) == 1)
{
$this->warn_msg[] = $user->lang['TOO_FEW_POLL_OPTIONS'];
}
else if ($poll['poll_options_size'] > (int) $config['max_poll_options'])
{
$this->warn_msg[] = $user->lang['TOO_MANY_POLL_OPTIONS'];
}
else if ($poll_max_options > $poll['poll_options_size'])
{
$this->warn_msg[] = $user->lang['TOO_MANY_USER_OPTIONS'];
}
if (!$poll['poll_title'] && $poll['poll_options_size'])
{
$this->warn_msg[] = $user->lang['NO_POLL_TITLE'];
}
$poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']);
}
}
?>