<?php
// +---------------------------------------------------------------------------------------+
// | TenderSystem                                                                          |
// +---------------------------------------------------------------------------------------+
// | The contents of this file are subject to the TenderSystem Public License Version 1.1  |
// | ("License"); you may not use this file except in compliance with the License. You may |
// | obtain a copy of the License at http://www.tendersystem.com/tpl/                      |
// |                                                                                       |
// | Software distributed under the License is distributed on an "AS IS" basis, WITHOUT    |
// | WARRANTY OF ANY KIND, either express or implied. See the License for the specific     |
// | language governing rights and limitations under the License.                          |
// |                                                                                       |
// | All copies of the Covered Code must include the "Powered by TenderSystem" logo and    |
// | ValueCard copyright notice on every user interface screen and in every outgoing       |
// | email in the same form as they appear in the distribution.                            |
// |                                                                                       |
// | The Original Code is: TenderSystem                                                    |
// | The Initial Developer of the Original Code is ValueCard (Pty) Limited.                |
// | Portions created by ValueCard are Copyright (C) 2002 ValueCard (Pty) Limited.         |
// | All Rights Reserved.                                                                  |
// | Contributor(s): __________________.                                                   |
// +---------------------------------------------------------------------------------------+

/**
* Email class
* @package TenderSystem
* @subpackage generic
* @copyright Copyright &copy; 2002, ValueCard (Pty) Ltd
* @license http://www.tendersystem.com/tpl/ TenderSystem Public License
* @version 
*/

// Security - ensure that file never called directly
// not required if global variables are off or API is hosted on a non-public server
if (eregi(basename(__FILE__),$_SERVER['PHP_SELF'])) {
    die ("You can't access this file directly...");
}

Class email {
	// set the paramaters
	var $user;
	var $retrieve;
	var $pop;
	var $email;
	var $error;
	var $response;
	var $lang;
	
	function email(&$cfg,&$conn) {
		$this->pop = new pop;
		$this->retrieve = $this->pop->retrieve($cfg);
		$lang = array();
		require($cfg['file']."modules/generic/language/".$cfg['language']."/error.php");
		$this->lang = $lang;
		// proses emails
		$this->proses_email($cfg,$conn);
	}

	function find_info($email) {
		// remove the tags which contain the comment tags
		$email['message'] = preg_replace('/<td+[^>]*id=[^>]*"([^"]+)"[^>]*>/i','\1',$email['message']);
		// NOTE: since php 4.3.0 comments are automatically remove and hardcoded 
		// so can not be ignored with allowable_tags
		$search_array = array("<!--","-->");
		$email['message'] = str_replace($search_array,"|",$email['message']);
		// strip all html tags
		$email['message'] = strip_tags($email['message']);
		// remove apostrophes and quotes as messes up db
		$search_array = array("=","'","\"","\\");
		$replace_array = array("",""," inch","");
		$email['message'] = str_replace($search_array,$replace_array,$email['message']);
		return $this->search_tags($email);
	}

	function search_tags($email) {
		$email_start = strpos($email['message'],"|end|");
		if($email_start) {
			// cut the message
			$email['message'] = substr($email['message'],$email_start);
		}
		$email_end = strpos($email['message'],"|/end|");
		if($email_end) {
			// cut the message
			$email['message'] = substr($email['message'],0,$email_end);
		}
		$info = array();
		while(FALSE !== ($name_start = strpos($email['message'],"|"))) {
			if(FALSE !== ($name_end = strpos($email['message'],"|",$name_start+1))) {
				// tag name
				if($tag_name = substr($email['message'],$name_start + 1,$name_end - ($name_start + 1))) {
					$info_start = $name_end + 1;
					// find ending tag
					if(($info_end = strpos($email['message'],"|/".$tag_name."|")) !== FALSE) {
						// remove anything except in between fields
						$value = trim(substr($email['message'],$info_start,$info_end - $info_start));
						// remove any [name] that some email clients insert
						$value = preg_replace("/\[.*?\]/", "", $value);
						// strip double white spaces
						$value = preg_replace("/\s\s+/", " ", $value);
						$info[$tag_name][] = $value;
					}
				}
			} else {
				return $info;
			}
			// cut the message
			$email['message'] = substr($email['message'],max($name_start,$name_end,$info_start,$info_end));
		}
		return $info;
	}

	function proses_email($cfg,$conn) {
		// log module and function
		$log['module'] = "email";
		$log['function'] = "parse";
		// set allowable mime types
		$allowable_mime = array (
				// images - gif default value
				"image/tiff",
				"image/tiff",
				"image/bmp",
				// documents
				"application/msword",
				"application/vnd.sun.xml.writer",
				"application/pdf",
				"text/xml",
				// spreadsheets
				"application/vnd.ms-excel",
				"application/vnd.sun.xml.calc",
				// archives
				"application/x-gzip",
				"application/gzip",
				"application/x-compressed",
				"application/rar",
				"application/x-tar",
				"application/tar",
				"application/x-bzip2",
				"application/bzip2",
				"application/x-zip",
				"application/zip"
		);
		if ($this->retrieve) {
			$log['parsecount'] = $this->pop->count;
			// loop through every email
			for ($i = 0; $i < $this->pop->count; $i++) {
				// set the email body
				$email['uncoded_message'] = $this->pop->email[$i];
				// decode the email
				$new_mime = new mime();
				$new_mime->decode($email['uncoded_message']);
				// most people set their reply email address correctly
				$email['sender']['email'] = trim(str_replace(array("<",">"),"",$new_mime->return_path));
				// get the senders name which most people set correctly in the from field
				$from = $new_mime->from;
				$begin_pos = strpos($from, "<");
				$end_pos = strpos($from,">");
				// note binary
				if ($begin_pos !== FALSE || $end_pos !== FALSE) {
					$email['sender']['name'] = trim(substr($from,0,$begin_pos));
					// if name not set correctly in reply field
					if (!$email['sender']['email']) {
						// increment starting position
						$begin_pos++;
						$email['sender']['email'] = trim(substr($from,$begin_pos,$end_pos - $begin_pos));
					}
				} else {
					// try and get it from the reply to field
					$email['sender']['name'] = $new_mime->reply_to;
					// last try and see if email address maybe set as from field without name
					if (!$email['sender']['email']) {
						$email['sender']['email'] = trim($email['from']);
					}
				}
				// set the subject and date
				$email['subject'] = $new_mime->subject;
				$email['date'] = $new_mime->date;
				// get the attachments
				if (sizeof($new_mime->mime_parts) > 0) {
					// loop through every attachment and set
					foreach ($new_mime->mime_parts as $mime_part) {
						// best way to determine if correct body is through substitution
						$mime_type = strtolower($mime_part["headers"]["content-type"]);
						$mime_name = $mime_part["headers"]["name"];
						$mime_charset = $mime_part["headers"]["charset"];
						// check transfer encoding
						if($mime_part["headers"]["content-transfer-encoding"] == "quoted-printable") {
							$body = quoted_printable_decode($mime_part["body"]);
						} elseif ($mime_part["headers"]["content-transfer-encoding"] == "base64") {
							$body = base64_decode($mime_part["body"]);
						} else {
							$body = $mime_part["body"];
						}
						if (in_array($mime_type,$allowable_mime) && $mime_name != "tendersystem.gif") {
							// allow multiple attachment
							$attachment = $mime_part["headers"];
							$attachment['body'] = $body;
							$email['attachment'][] = $attachment;
							// move onto next part
							continue;
						} elseif(strpos($mime_type,"image")) {
							// move onto next part
							continue;	
						}
						// check charset
						if($mime_charset !== "UTF-8" && $mime_charset && function_exists("iconv")) {
							// convert to UTF-8
							$n_body = iconv($mime_charset, "UTF-8",$body);
							// if successful
							if($n_body) {
								$body = $n_body;	
							}
						}
						$log_message['headers'] = $mime_part["headers"]; 
						$new_log = new log;
						$new_log->log_request('system',$log_message,$cfg);
						// set all decoded message parts in a string
						$email['message'].= $body;
					}
				}
				$email['message'] = str_replace("&amp;","&",$email['message']);
				// replace all occurences of '=20' with a space
				// word has a nasty habit of inserting 3D after =
				// change back the < and > that word changes
				// remove line breaks and spaces
				$search_array = array("\r\n=","=20","=3D","&lt;","&gt;","\n","&nbsp;","|");
				$replace_array = array(""    ," "  ,"="  ,"<"   ,">"   ," " ," "     ,"");
				$email['message'] = str_replace($search_array,$replace_array,$email['message']);
				$skip_email = FALSE;
				// check if contain special keyword
				if(!empty($cfg['smtp']['keyword'])) {
					foreach($cfg['smtp']['keyword'] as $value) {
						if($value && strpos($email['message'],$value) !== FALSE) {
							$skip_email = TRUE;
						}
					}
				}
				// check type
				if(!$skip_email && $type_start = strpos($email['message'],"<!--emailtype-->")) {
					$type_end = strpos($email['message'],"<!--/emailtype-->",$type_start+16);
					$type = substr($email['message'],$type_start+16,$type_end-($type_start+16));
					$log[$type]++;
					// save the message
					$new_message = new message;
					// set paramaters
					$message['classification'] = $type;
					$message['send_method'] = "email_receive";
					$message['subject'] = $email['subject'];
					$message['reference'] = strtoupper($type);
					$message['body'] = $email['uncoded_message'];
					$message['email'] = $email['sender']['email'];
					// get all the hidden info
					$info = $this->find_info($email);
					// store extracted info in database
					$message['extracted_info'] = print_r($info, true);
					// submit
					$info['messageid'] = $new_message->create_reply($message,$cfg,$conn);
					$info['subject'] = $email['subject'];
					$info['uncoded_message'] = $email['uncoded_message'];
					$info['sender']['email'] = $email['sender']['email'];
					$info['attachment'] = $email['attachment'];
					// response
					$this->response[$type][] = $info;
				} else {
					// Email has no type 
					$error_text = $this->lang[346];
					$new_error = new error;
					$new_error->log("POP","serious",$error_text,$cfg);
					// save email if set
					if ($cfg['pop']['notype']) {
						$message['classification'] = "unknown";
						$message['send_method'] = "email_receive";
						$message['subject'] = $email['subject'];
						$message['reference'] = "UNKNOWN";
						$message['body'] = $email['uncoded_message'];
						$message['email'] = $email['sender']['email'];
						// instantiate 
						$new_message = new message;
						// save
						$info['messageid'] = $new_message->create_reply($message,$cfg,$conn);
					}
					// send email to support
					$message['text'] = $this->lang[347]." ".$email['sender']['name']."<".$email['sender']['email'].">"; 
					$message['class'] = "error";
					$message['type'] = $this->lang[350];
					$message['subject'] = $email['subject'];
					// set the support email
					$email_address = $cfg['smtp']['support']['from']." <".$cfg['smtp']['support']['email'].">";
					// send error mail
					error_log($email['message'],1,$email_address,$message['text']);
					// set response
					$this->response['message'][] = $message;
				}
				// delete the email
				$this->pop->delete_mail($i+1);
				// unset email
				unset($email);
			}
			// close the connection
			$this->pop->close_connection;
		} else {
			if ($this->pop->response['error']) {
				// Error occurred while parsing email
				$this->response['error_text'][] = $log['parse'] = $this->lang[348].$this->pop->response['error'];
			} else {
				$log['parse'] = $this->lang[349];
			}
		}
		$new_log = new log;
		$new_log->log_request('system',$log,$cfg);
	}
}
?>