|
From: Jon O. <jon...@us...> - 2006-06-25 21:52:47
|
Update of /cvsroot/mxbb/core/includes In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv25772/includes Modified Files: mx_functions_tools.php Log Message: Implementing a new mx_post class, to handle all kind of html, bbcode, smilies, links, images etc Index: mx_functions_tools.php =================================================================== RCS file: /cvsroot/mxbb/core/includes/mx_functions_tools.php,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** mx_functions_tools.php 17 Jun 2006 20:09:07 -0000 1.2 --- mx_functions_tools.php 25 Jun 2006 21:52:41 -0000 1.3 *************** *** 16,19 **** --- 16,522 ---- } + // + // This 'include' is needed for the mx_text class + // + include_once($phpbb_root_path . 'includes/bbcode.'.$phpEx); + + /** + * Class mx_text. + * + * This class simplifies all text handling: display text on pages, formatting text for editing and storing. + * - based on phpBB 2.0.x code + * + * Methods: + * - display[_simple]: decode rich/simple text (from db) for display on normal pages + * - decode[_simple]: decode rich/simple text for editing in form fields + * - encode_preview[_simple]: encode rich/simple form data for preview + * - encode[_simple|_username]: encode form data to be stored in db + * + * Note: Be sure to check in what format the methods expect its data + * Note(2): Be sure to init the object before usage. + */ + class mx_text + { + var $orig_word = array(); + var $replacement_word = array(); + + var $highlight_match = ''; + var $highlight_match_color = ''; + var $highlight = ''; + + var $bbcode_uid = ''; // set when encoding data + + // + // Toggles + // + var $html_on = false; + var $bbcode_on = true; + var $smilies_on = false; + var $links_on = true; + var $images_on = true; + + var $allow_all_html_tags = false; + + function init($html_on = false, $bbcode_on = true, $smilies_on = false, $links_on = true, $images_on = true) + { + global $theme; + + // + // Toggles + // + $this->html_on = $html_on; + $this->bbcode_on = $bbcode_on; + $this->smilies_on = $smilies_on; + $this->links_on = $links_on; + $this->images_on = $images_on; + + // + // Define censored word matches + // + obtain_word_list($this->orig_word, $this->replacement_word); + + // + // Was a highlight request part of the URI? + // + if (isset($_GET['highlight'])) + { + // Split words and phrases + $words = explode(' ', trim(htmlspecialchars($_GET['highlight']))); + + for($i = 0; $i < sizeof($words); $i++) + { + if (trim($words[$i]) != '') + { + $this->highlight_match .= (($this->highlight_match != '') ? '|' : '') . str_replace('*', '\w*', preg_quote($words[$i], '#')); + } + } + unset($words); + + $this->highlight = urlencode($_GET['highlight']); + $this->highlight_match = phpbb_rtrim($this->highlight_match, "\\"); + } + + // + // Highlight match color + // + $this->highlight_match_color = $theme['fontcolor3']; + + } + + /** + * decode rich text for display on normal pages. + * + * This method decodes full text and handles html, bbcode, images, links, highlights, censored words etc + * Based on phpBB viewtopic.php and functions_post.php (phpBB 2.0.21) + * + * @param string $text text (from db) + * @param string $bbcode_uid + */ + function display($text, $bbcode_uid = '') + { + // + // strip html if reqd + // + if ( !$this->html_on ) + { + if ( $text != '' ) + { + $text = preg_replace('#(<)([\/]?.*?)(>)#is', "<\\2>", $text); + } + } + + // + // BBCode if reqd + // + if ($text != '' && $bbcode_uid != '') + { + $text = ($this->bbcode_on) ? bbencode_second_pass($text, $bbcode_uid) : preg_replace("/\:$bbcode_uid/si", '', $text); + } + + if ( $text != '' ) + { + $text = make_clickable($text); + } + + // + // Parse smilies + // + if ( $this->smilies_on ) + { + if ( $text != '' ) + { + $text = smilies_pass($text); + } + } + + // + // Highlight active words (primarily for search) + // + if ($this->highlight_match) + { + // This has been back-ported from 3.0 CVS + $text = preg_replace('#(?!<.*)(?<!\w)(' . $this->highlight_match . ')(?!\w|[^<>]*>)#i', '<b style="color:#'.$this->highlight_match_color.'">\1</b>', $text); + } + + // + // Replace naughty words + // + if (count($this->orig_word)) + { + if ($text != '') + { + $text = str_replace('\"', '"', substr(@preg_replace('#(\>(((?>([^><]+|(?R)))*)\<))#se', "@preg_replace(\$this->orig_word, \$this->replacement_word, '\\0')", '>' . $text . '<'), 1, -1)); + } + + } + + // + // Replace newlines (we use this rather than nl2br because + // till recently it wasn't XHTML compliant) + // + if ( $text != '' ) + { + $text = str_replace("\n", "\n<br />\n", $text); + } + + return $text; + } + + /** + * decode simple text for display on normal pages. + * + * Eg: titles, short descriptions etc + * + * @param unknown_type $text + */ + function display_simple($text) + { + if ( $text != '' ) + { + $text = ( count($this->orig_word) ) ? preg_replace($this->orig_word, $this->replacement_word, $text) : $text; + } + + return $text; + } + + /** + * decode rich text for editing in form fields. + * + * @param unknown_type $text + * @param unknown_type $bbcode_uid + * @param unknown_type $refresh + */ + function decode($text, $bbcode_uid = '', $refresh = false) + { + if ($refresh) + { + // + // This is raw _GET/_POST data + // + $text = ( !empty($text) ) ? htmlspecialchars(trim(stripslashes($text))) : ''; + } + + if ( $bbcode_uid != '' ) + { + $text = preg_replace('/\:(([a-z0-9]:)?)' . $bbcode_uid . '/s', '', $text); + } + + $text = str_replace('<', '<', $text); + $text = str_replace('>', '>', $text); + $text = str_replace('<br />', "\n", $text); + + return $text; + } + + /** + * decode simple text for editing in form fields. + * + * Eg: titles, usernames, short descriptions etc + * + * @param unknown_type $text + * @param unknown_type $refresh + */ + function decode_simple($text, $refresh = false) + { + + if ($refresh) + { + // + // This is raw _GET/_POST data + // + $text = ( !empty($text) ) ? htmlspecialchars(trim(stripslashes($text))) : ''; + } + + return $text; + } + + /** + * encode rich form data to be stored in db. + * + * Encode text to be db valid. + * Note: passed "text" should be raw _GET/_POST data + * + * @param unknown_type $text + * @return unknown + */ + function encode($text) + { + global $board_config, $userdata, $lang, $phpEx, $phpbb_root_path; + + $this->bbcode_uid = ''; + + // + // Check message + // + if (!empty($text)) + { + $this->bbcode_uid = ($this->bbcode_on) ? make_bbcode_uid() : ''; + $text = $this->prepare_message(trim($text), $this->html_on, $this->bbcode_on, $this->smilies_on, $this->bbcode_uid); + } + + return str_replace("\'", "''", $text); + } + + /** + * encode simple form data to be stored in db. + * + * @param unknown_type $text + */ + function encode_simple($text) + { + global $board_config, $userdata, $lang, $phpEx, $phpbb_root_path; + + // + // Check $text + // + if (!empty($text)) + { + $text = htmlspecialchars(trim($text)); + } + + return str_replace("\'", "''", $text); + } + + /** + * encode username form data to be stored in db. + * + * @param unknown_type $username + */ + function encode_username($username) + { + global $board_config, $userdata, $lang, $phpEx, $phpbb_root_path; + + // + // Check username + // + if (!empty($username)) + { + $username = phpbb_clean_username($username); + + if (!$userdata['session_logged_in'] || ($userdata['session_logged_in'] && $username != $userdata['username'])) + { + include($phpbb_root_path . 'includes/functions_validate.'.$phpEx); + + $result = validate_username($username); + if ($result['error']) + { + $error_msg .= (!empty($error_msg)) ? '<br />' . $result['error_msg'] : $result['error_msg']; + } + } + else + { + $username = ''; + } + } + + return str_replace("\'", "''", $username); + } + + /** + * encode rich form data for preview + * + * @param unknown_type $text + */ + function encode_preview($text) + { + global $html_entities_match, $html_entities_replace, $board_config; + + if ($this->allow_all_html_tags) + { + $html_entities_match = array(); + $html_entities_replace = array(); + $board_config['allow_html_tags'] = ''; + } + + $text = ( !empty($text) ) ? htmlspecialchars(trim(stripslashes($text))) : ''; + + $bbcode_uid = ( $this->bbcode_on ) ? make_bbcode_uid() : ''; + $text = stripslashes($this->prepare_message(addslashes($this->unprepare_message($text)), $this->html_on, $this->bbcode_on, $this->smilies_on, $bbcode_uid)); + + if( $this->bbcode_on ) + { + $text = bbencode_second_pass($text, $bbcode_uid); + } + + if( !empty($this->orig_word) ) + { + $text = ( !empty($text) ) ? preg_replace($this->orig_word, $this->replacement_word, $text) : ''; + } + + $text = make_clickable($text); + + if( $this->smilies_on ) + { + $text = smilies_pass($text); + } + + $text = str_replace("\n", '<br />', $text); + + return $text; + } + + /** + * encode simple form data for preview + * + * Eg: Works for titles, usernames, etc + * + * @param unknown_type $text + */ + function encode_preview_simple($text) + { + $text = ( !empty($text) ) ? htmlspecialchars(trim(stripslashes($text))) : ''; + + if( !empty($this->orig_word) ) + { + $text = ( !empty($text) ) ? preg_replace($this->orig_word, $this->replacement_word, $text) : ''; + } + + return $text; + } + + // + // This function will prepare a posted message for + // entry into the database. + // - borrowed from phpBB 2.0.21 + // + function prepare_message($message, $html_on, $bbcode_on, $smile_on, $bbcode_uid = 0) + { + global $board_config, $html_entities_match, $html_entities_replace; + + // + // Clean up the message + // + $message = trim($message); + + if ($html_on) + { + // If HTML is on, we try to make it safe + // This approach is quite agressive and anything that does not look like a valid tag + // is going to get converted to HTML entities + $message = stripslashes($message); + $html_match = '#<[^\w<]*(\w+)((?:"[^"]*"|\'[^\']*\'|[^<>\'"])+)?>#'; + $matches = array(); + + $message_split = preg_split($html_match, $message); + preg_match_all($html_match, $message, $matches); + + if (!$this->allow_all_html_tags) // Bypass this check for typical (allow all) html text + { + $message = ''; + + foreach ($message_split as $part) + { + $tag = array(array_shift($matches[0]), array_shift($matches[1]), array_shift($matches[2])); + $message .= preg_replace($html_entities_match, $html_entities_replace, $part) . $this->clean_html($tag); + } + } + + $message = addslashes($message); + $message = str_replace('"', '\"', $message); + } + else + { + $message = preg_replace($html_entities_match, $html_entities_replace, $message); + } + + if($bbcode_on && $bbcode_uid != '') + { + $message = bbencode_first_pass($message, $bbcode_uid); + } + + return $message; + } + + function unprepare_message($message) + { + global $unhtml_specialchars_match, $unhtml_specialchars_replace; + + return preg_replace($unhtml_specialchars_match, $unhtml_specialchars_replace, $message); + } + + /** + * Called from within prepare_message to clean included HTML tags if HTML is + * turned on for that post + * @param array $tag Matching text from the message to parse + */ + function clean_html($tag) + { + global $board_config; + + if (empty($tag[0])) + { + return ''; + } + + $allowed_html_tags = preg_split('/, */', strtolower($board_config['allow_html_tags'])); + $disallowed_attributes = '/^(?:style|on)/i'; + + // Check if this is an end tag + preg_match('/<[^\w\/]*\/[\W]*(\w+)/', $tag[0], $matches); + if (sizeof($matches)) + { + if (in_array(strtolower($matches[1]), $allowed_html_tags)) + { + return '</' . $matches[1] . '>'; + } + else + { + return htmlspecialchars('</' . $matches[1] . '>'); + } + } + + // Check if this is an allowed tag + if (in_array(strtolower($tag[1]), $allowed_html_tags)) + { + $attributes = ''; + if (!empty($tag[2])) + { + preg_match_all('/[\W]*?(\w+)[\W]*?=[\W]*?(["\'])((?:(?!\2).)*)\2/', $tag[2], $test); + for ($i = 0; $i < sizeof($test[0]); $i++) + { + if (preg_match($disallowed_attributes, $test[1][$i])) + { + continue; + } + $attributes .= ' ' . $test[1][$i] . '=' . $test[2][$i] . str_replace(array('[', ']'), array('[', ']'), htmlspecialchars($test[3][$i])) . $test[2][$i]; + } + } + if (in_array(strtolower($tag[1]), $allowed_html_tags)) + { + return '<' . $tag[1] . $attributes . '>'; + } + else + { + return htmlspecialchars('<' . $tag[1] . $attributes . '>'); + } + } + // Finally, this is not an allowed tag so strip all the attibutes and escape it + else + { + return htmlspecialchars('<' . $tag[1] . '>'); + } + } + } + /** * Class: mx_tools. *************** *** 697,716 **** } } - - class mx_post - { - function decode($text, $bbcode_uid = '', $html_on = false, $bbcode_on = true, $smilies_on = false, $links_on = true, $images_on = true) - { - global $board_config; - - return $text; - } - - function encode($text, $bbcode_uid = '', $html_on = false, $bbcode_on = true, $smilies_on = false, $links_on = true, $images_on = true) - { - global $board_config; - - return $text; - } - } ?> \ No newline at end of file --- 1200,1202 ---- |