<?php
	require_once('htmlfilter.php');
	/**
	 * Filters text messages for various uses
	 * 		 	
	 * @package core
	 */
	
	class filter
	{
		/**
		 * Create script-safe HTML from raw HTML
		 *
		 * Note that the function inline_attachments() in util.php is used to convert inline attachments to
		 * the correct HTML to show the message in the browser window.
		 *
		 * @see inline_attachments()
		 *
		 * @param string $html The HTML text
		 * @param string $storeid MAPI binary entryid, is used for the inline attachments and new mail
		 * @param string $entryid MAPI message entryid, is used for the inline attachments and new mail
		 * @return string safe html		
		 */		 		
		function safeHTML($html, $storeid = false, $entryid = false)
		{
			// Save all "<" symbols
			$html = preg_replace("/<(?=[^a-zA-Z\/\!\?\%])/", "&lt;", $html); 
			// Opera6 bug workaround
			$html = str_replace("\xC0\xBC", "&lt;", $html);
			
			if(!DISABLE_HTMLBODY_FILTER){
				// Filter '<script>'
				$html = $this->filterScripts($html);
			}
			
			if($storeid && $entryid){
				// Set GLOBALS for preg_replace_callback functions.
				$GLOBALS["preg_replace"] = array();
				$GLOBALS["preg_replace"]["storeid"] = $storeid;
				$GLOBALS["preg_replace"]["entryid"] = $entryid;
			}

			// Set GLOBALS for preg_replace_callback functions.
			$GLOBALS["preg_replace"] = array();
			$GLOBALS["preg_replace"]["storeid"] = $storeid;
			$GLOBALS["preg_replace"]["entryid"] = $entryid;

			// Replace all 'mailto:..' with link to compose new mail
			$html = preg_replace_callback('/<(a[^>]*)(href)=(["\'])?mailto:([^"\'>\?]+)\??([^"\'>]*)(["\']?)([^>]*)>/msi','mailto_newmail',$html);
			
			// remove 'base target' if exists
			$html = preg_replace("/<base[^>]*target=[^>]*\/?>/msi",'',$html);
			
			// Add 'base target' after the head-tag
			$base = '<base target="_blank">';
			$html = preg_replace("/<(head[^>]*)>/msi",('<$1>'.$base),$html);

			// if no head-tag was found (no base target is then added), add the 'base target' above the file
			if(strpos($html, $base)===false){
				$html = $base . $html;
			}

			// add default font
			$font = '<style type="text/css">body { font-family: monospace; }</style>';
			$html = preg_replace("/<(head[^>]*)>/msi",('<$1>'.$font),$html);

			// if no head-tag was found (no default font is then added), add the 'font default' above the file
			if(strpos($html, $font)===false){
				$html = $font . $html;
			}

			return $html;
		} 
		
		/**
		 * Filter scripts from HTML
		 *
		 * @access private
		 * @param string $str string which should be filtered
		 * @return string string without any script tags		
		 */		 		
		function filterScripts($str)
		{
			return magicHTML($str, 0);
		} 
	
		/**
		 * Convert HTML to text
		 *
		 * @param string $str the html which should be converted to text
		 * @return string plain text version of the given $str				
		 */		 		
		function html2text($str)
		{
			return $this->unhtmlentities(preg_replace(
					Array("'<(HEAD|SCRIPT|STYLE|TITLE)[^>]*?>.*?</(HEAD|SCRIPT|STYLE|TITLE)[^>]*?>'si",
						"'(\r|\n)'",
						"'<BR[^>]*?>'i",
						"'<P[^>]*?>'i",
						"'<\/?\w+[^>]*>'e",
						"'<![^>]*>'s"
						),
					Array("",
						"",
						"\r\n",
						"\r\n\r\n",
						"",
						""),
					$str));
		} 
		
		/**
		 * Remove HTML entities and convert them to single characters where possible
		 *
		 * @access private
		 * @param string $str string which should be converted
		 * @return string converted string						
		 */
		function unhtmlentities ($string)
		{
			$trans_tbl = get_html_translation_table(HTML_ENTITIES);
			$trans_tbl = array_flip($trans_tbl);
			return strtr($string, $trans_tbl);
		} 
	
		/**
		 * Remove script tags from HTML source
		 *
		 * @access private
		 * @param string $str the html which the events should be filtered
		 * @return string html with no 'on' events				
		 */
		function _filter_tag($str)
		{
			// fix $str when called by preg_replace_callback
			if (is_array($str)) $str = $str[0];
			
			// fix unicode
			$str = preg_replace_callback("|(%[0-9A-Z]{2})|i", create_function('$str', 'return chr(hexdec($str[0]));'), $str);

			$matches = Array(
				// (\bON\w+(?!.)) - matches string beginning with 'on' only if the string is not followed by '.'	for example 'online.nl' will not be matched, whereas 'onmouse' will be.
				"'(\bON\w+(?!.))'i", // events
				"'(HREF)( *= *[\"\']?\w+SCRIPT *:[^\"\' >]+)'i", // links
				"'\n'",
				"'\r'"
				);
			$replaces = Array(
				"\\1_filtered",
				"\\1_filtered\\2",
				" ",
				" ",
				);
			return preg_replace($matches, $replaces, $str);
		}
	} 
?>
