bbcodes) { $this->bbcode_init(); } global $user; $this->bbcode_bitfield = 0; $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) { $this->bbcode_bitfield |= (1 << $bbcode_data['bbcode_id']); $size = $new_size; } } } 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-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')")) ); $this->parsed_items = array('code' => 0, 'quote' => 0, 'attachment' => 0, 'b' => 0, 'i' => 0, 'url' => 0, 'img' => 0, 'size' => 0, 'color' => 0, 'u' => 0, 'list' => 0, 'email' => 0, 'flash' => 0); if (!is_array($rowset)) { global $db; $rowset = array(); $sql = 'SELECT bbcode_id, bbcode_tag, first_pass_match, first_pass_replace FROM ' . BBCODES_TABLE; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $rowset[] = $row; } } foreach ($rowset as $row) { $this->bbcodes[$row['bbcode_tag']] = array( 'bbcode_id' => intval($row['bbcode_id']), 'regexp' => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace'])) ); } } function check_bbcode($bbcode, &$in) { $in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in))); if (!$in) { return false; } $this->parsed_items[$bbcode]++; return true; } function bbcode_size($stx, $in) { if (!$this->check_bbcode('size', $in)) { return ''; } return '[size=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/size:' . $this->bbcode_uid . ']'; } function bbcode_color($stx, $in) { if (!$this->check_bbcode('color', $in)) { return ''; } return '[color=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/color:' . $this->bbcode_uid . ']'; } function bbcode_underline($in) { if (!$this->check_bbcode('u', $in)) { return ''; } return '[u:' . $this->bbcode_uid . ']' . $in . '[/u:' . $this->bbcode_uid . ']'; } function bbcode_strong($in) { if (!$this->check_bbcode('b', $in)) { return ''; } return '[b:' . $this->bbcode_uid . ']' . $in . '[/b:' . $this->bbcode_uid . ']'; } function bbcode_italic($in) { if (!$this->check_bbcode('i', $in)) { return ''; } return '[i:' . $this->bbcode_uid . ']' . $in . '[/i:' . $this->bbcode_uid . ']'; } function bbcode_img($in) { if (!$this->check_bbcode('img', $in)) { return ''; } return '[img:' . $this->bbcode_uid . ']' . $in . '[/img:' . $this->bbcode_uid . ']'; } function bbcode_flash($width, $height, $in) { if (!$this->check_bbcode('flash', $in)) { return ''; } return '[flash=' . $width . ',' . $height . ':' . $this->bbcode_uid . ']' . $in . '[/flash:' . $this->bbcode_uid . ']'; } // Hardcode inline attachments [ia] function bbcode_attachment($stx, $in) { if (!$this->check_bbcode('attachment', $in)) { return ''; } return '[attachment=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/attachment:' . $this->bbcode_uid . ']'; } // Expects the argument to start right after the opening [code] tag and to end with [/code] function bbcode_code($stx, $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('\"', '"', trim($in))); if (!$in) { return ''; } $this->parsed_items['code']++; // 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); ob_start(); highlight_string($code); $code = ob_get_contents(); ob_end_clean(); $str_from = 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 . ']' . trim($code) . '[/code:' . $this->bbcode_uid . ']'; break; default: $str_from = array('<', '>', '[', ']', '.', ':'); $str_to = array('<', '>', '[', ']', '.', ':'); $out .= '[code:' . $this->bbcode_uid . ']' . str_replace($str_from, $str_to, $code) . '[/code:' . $this->bbcode_uid . ']'; } if (preg_match('#(.*?)\[code(?:=([a-z]+))?\](.+)#is', $in, $m)) { $out .= $m[1]; $stx = $m[2]; $in = $m[3]; } } while ($in); return $out; } // Expects the argument to start with a tag function bbcode_parse_list($in) { if (!$this->check_bbcode('list', $in)) { return ''; } $in = str_replace('\"', '"', $in); $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; } // Expects the argument to start with a tag function bbcode_quote($in) { global $config, $user; $in = trim($in); if (!$in) { return ''; } $tok = ']'; $out = '['; // Add newline at the end and in front of each quote block to prevent parsing errors (urls, smilies, etc.) $in = preg_replace(array('#\[quote(=".*?")?\]([^\n])#is', '#([^\n])\[\/quote\]#is'), array("[quote\\1]\n\\2", "\\1\n[/quote]"), $in); $in = preg_replace(array('#\[quote(=".*?")?\]([^\n])#is', '#([^\n])\[\/quote\]#is'), array("[quote\\1]\n\\2", "\\1\n[/quote]"), $in); $in = substr(str_replace('\"', '"', $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 $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; } function validate_email($var1, $var2) { $txt = stripslashes($var2); $email = ($var1) ? stripslashes($var1) : stripslashes($var2); $validated = true; if (!preg_match('!([a-z0-9]+[a-z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-z0-9]+[a-z0-9\-\._]*\.[a-z]+))!i', $email)) { $validated = false; } if (!$validated) { return '[email' . (($var1) ? "=$var1" : '') . ']' . $var2 . '[/email]'; } $this->parsed_items['email']++; if ($var1) { $retval = '[email=' . $email . ':' . $this->bbcode_uid . ']' . $txt . '[/email:' . $this->bbcode_uid . ']'; } else { $retval = '[email:' . $this->bbcode_uid . ']' . $email . '[/email:' . $this->bbcode_uid . ']'; } return $retval; } function validate_url($var1, $var2) { global $config; $var1 = trim($var1); $var2 = trim($var2); $url = ($var1) ? stripslashes($var1) : stripslashes($var2); $valid = false; if (!$url || ($var1 && !$var2)) { return ''; } $server_protocol = ( $config['cookie_secure'] ) ? 'https://' : 'http://'; $server_port = ( $config['server_port'] <> 80 ) ? ':' . trim($config['server_port']) . '/' : '/'; // relative urls for this board if (preg_match('#' . $server_protocol . trim($config['server_name']) . $server_port . preg_replace('/^\/?(.*?)(\/)?$/', '$1', trim($config['script_path'])) . '/([^ \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; } return ($var1) ? '[url=' . str_replace(array(']', '['), array(']', '['), $url) . ':' . $this->bbcode_uid . ']' . stripslashes($var2) . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $url . '[/url:' . $this->bbcode_uid . ']'; } return '[url' . (($var1) ? '=' . stripslashes($var1) : '') . ']' . stripslashes($var2) . '[/url]'; } } /** * @package phpBB3 * Main message parser for posting, pm, etc. takes raw message * and parses it for attachments, html, bbcode and smilies */ 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; // 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 : public function parse($allow_html, $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->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?#', '#sid=[a-z0-9]*?&?#', "#([\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, even allows empty messsages. 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 || ($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; } } // Parse HTML if ($allow_html && $config['allow_html_tags']) { $this->html($config['allow_html_tags']); } // Parse smilies if ($allow_smilies) { $this->smilies($config['max_' . $mode . '_smilies']); } $num_urls = 0; // Parse BBCode 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->parse_bbcode(); $num_urls += $this->parsed_items['url']; } // Parse URL's if ($allow_magic_url) { $this->magic_url((($config['cookie_secure']) ? 'https://' : 'http://'), $config['server_name'], $config['server_port'], $config['script_path']); if ($config['max_' . $mode . '_urls']) { $num_urls += preg_match_all('#\<$1$2>', $this->message); } } // Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx. // Cuts down displayed size of link if over 50 chars, turns absolute links // into relative versions when the server/script path matches the link function magic_url($server_protocol, $server_name, $server_port, $script_path) { static $match; static $replace; $server_port = ($server_port <> 80 ) ? ':' . trim($server_port) . '/' : '/'; if (!is_array($match)) { $match = $replace = array(); // Be sure to not let the matches cross over. ;) // relative urls for this board $match[] = '#(^|[\n ]|\()(' . preg_quote($server_protocol . trim($server_name) . $server_port . preg_replace('/^\/?(.*?)(\/)?$/', '$1', trim($script_path)), '#') . ')/(.*?([^ \t\n\r<"\'\)]*)?)#i'; $replace[] = '$1$3'; // matches a xxxx://aaaaa.bbb.cccc. ... $match[] = '#(^|[\n ]|\()([\w]+?://.*?([^ \t\n\r<"\'\)]*)?)#ie'; $replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr(str_replace('&', '&', '\$2'), 0, 39) . ' ... ' . substr(str_replace('&', '&', '\$2'), -10) : '\$2') . ''"; // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing $match[] = '#(^|[\n ]|\()(www\.[\w\-]+\.[\w\-.\~]+(?:/[^ \t\n\r<"\'\)]*)?)#ie'; $replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr(str_replace('&', '&', '\$2'), 0, 39) . ' ... ' . substr(str_replace('&', '&', '\$2'), -10) : '\$2') . ''"; // matches an email@domain type address at the start of a line, or after a space. $match[] = '#(^|[\n ]|\()([a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+)#ie'; $replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr('\$2', 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . ''"; } /* IMPORTANT NOTE (Developer inability to do advanced regular expressions) - Acyd Burn: Transforming < (<) to <&lt; in order to bypass the inability of preg_replace supporting multi-character sequences (POSIX - [..]). Since all message text is specialchared by default a match against < will always fail, since it is a < sequence within the text. Replacing with <&lt; and switching back thereafter produces no problems, because < will never show up with &lt; in the same text (due to this specialcharing). The < is put in front of &lt; to let the url break gracefully. I hope someone can lend me a hand here, telling me how to achive the wanted result without switching to ereg_replace. */ $this->message = preg_replace($match, $replace, str_replace('<', '<&lt;', $this->message)); $this->message = str_replace('<&lt;', '<', $this->message); } // Parse Smilies function smilies($max_smilies = 0) { global $db, $user, $phpbb_root_path; static $match; static $replace; // NOTE: There is a memory leak in this block somewhere :\ // See if the static arrays have already been filled on an earlier invocation if (!is_array($match)) { // NOTE: obtain_* function? chaching the table contents? // For now setting the ttl to 10 minutes switch (SQL_LAYER) { case 'mssql': case 'mssql_odbc': $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY LEN(code) DESC'; break; // LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure... default: $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY LENGTH(code) DESC'; break; } $result = $db->sql_query($sql, 600); if ($row = $db->sql_fetchrow($result)) { $match = $replace = array(); do { // (assertion) $match[] = '#(?<=^|[\n ]|\.)' . preg_quote($row['code'], '#') . '#'; $replace[] = '' . $row['emotion'] . ''; } while ($row = $db->sql_fetchrow($result)); } else { $match = $replace = array(); } $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; $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'])); $delete_file = (isset($_POST['delete_file'])); $edit_comment = (isset($_POST['edit_comment'])); $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_gets('m_', 'a_')) { $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'], '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) { $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('')); foreach ($actual_comment_list as $index => $entry) { $this->attachment_data[$index]['comment'] = preg_replace('#&(\#[0-9]+;)#', '&\1', $entry); } } 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'], '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() { $this->filename_data['filecomment'] = request_var('filecomment', '', true); $this->attachment_data = (isset($_POST['attachment_data'])) ? $_POST['attachment_data'] : array(); // $data_prepare = array('physical_filename' => 's', 'real_filename' => 's', 'comment' => 's', 'extension' => 's', 'mimetype' => 's', 'filesize' => 'i', 'filetime' => 'i', 'attach_id' => 'i', 'thumbnail' => 'i'); foreach ($this->attachment_data as $pos => $var_ary) { foreach ($data_prepare as $var => $type) { if ($type == 's') { $this->attachment_data[$pos][$var] = trim(htmlspecialchars(str_replace(array("\r\n", "\r", '\xFF'), array("\n", "\n", ' '), stripslashes($this->attachment_data[$pos][$var])))); } else { $this->attachment_data[$pos][$var] = (int) $this->attachment_data[$pos][$var]; } } } } // 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']; $bbcode_bitfield = $this->bbcode_bitfield; $poll['poll_option_text'] = $this->parse($poll['enable_html'], $poll['enable_bbcode'], $poll['enable_urls'], $poll['enable_smilies'], $poll['img_status'], false, false, false); $this->bbcode_bitfield |= $bbcode_bitfield; $this->message = $tmp_message; // Parse Poll Title $tmp_message = $this->message; $this->message = $poll['poll_title']; $bbcode_bitfield = $this->bbcode_bitfield; $poll['poll_title'] = $this->parse($poll['enable_html'], $poll['enable_bbcode'], $poll['enable_urls'], $poll['enable_smilies'], $poll['img_status'], false, false, false); $this->bbcode_bitfield |= $bbcode_bitfield; $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']); } } ?>