<?php


class MailCatcher
{
	
	
	private $values_arr;
	private $db;
	
	function __construct($db) {
		
		$this->db = $db;
		
	}
	/**
	 * This functions parses the second part of an RFC 1984 report message (the machine readable part)
	 * and retrives the status of the report and the recepient
	 * more info on RFC 1984 is found here: http://www.rfc-archive.org/getrfc.php?rfc=1894
	 *
	 * @param string $msg_body the DSN of the message in RFC1894 format.
	 */
	private function parse_body($msg_body)
	{						
									
		//RFC1894 parsts are using RFC 822 rules

		//the lines have 2 parts and are seperatet by ':'.
		//The functions looks for "Final-Recipient", which contains the recepient mail adress.
		//further we are looking for the status and arrival date
	
		preg_match_all("/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)\r\n/m",$msg_body,$Dsn_lines  );
		for($x=0;$x< count($Dsn_lines[0]);$x++)
		{
			if( trim($Dsn_lines[1][$x]) == "Final-Recipient"  )
			{
				$tmp = split(";",$Dsn_lines[2][$x]);
				$this->values_arr[mail_adress] = $tmp[1];
			}
		/*	elseif (trim($Dsn_lines[1][$x]) == "Action")
			{
				if(trim($Dsn_lines[2][$x]) == "failed")
				{
				//	echo "Delivery failed!  ";
				}
				else
				{
				//	echo "Unkown report  ";
				}
			}*/
			elseif(trim($Dsn_lines[1][$x]) == "Status")
			{
				$this->values_arr[status] = $Dsn_lines[2][$x];
			}
			elseif(trim($Dsn_lines[1][$x]) == "Arrival-Date")
			{
				$this->values_arr[arrival_date] = date("Y-m-d H:i:s",strtotime( $Dsn_lines[2][$x]))  ;
			}
		}
		
	}
	/**
	 * If the send mail is returned to sender, the function finds some data like id,subject and date of that send message
	 * We also attach RMstatId to automaticly send mails! 
	 * 
	 * @param unknown_type $msg_header - the header of the returned mail
	 */
	private function get_returned_mail_data($msg_header)
	{
		preg_match_all('/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)\r\n/m', $msg_header , $head_parts);
		
		for($j=0;$j<count($head_parts[1]);$j++)
		{
			if( strtolower( $head_parts[1][$j] ) == "message-id")
			{
				$this->values_arr[send_mail_id] = $head_parts[2][$j];
			}
			elseif(strtolower( $head_parts[1][$j] ) == "subject")
			{
				$this->values_arr[send_subject] = $head_parts[2][$j];
			}
			elseif(strtolower( $head_parts[1][$j] ) == "date")
			{
				$this->values_arr['send_date'] = date("Y-m-d H:i:s",strtotime( $head_parts[2][$j]));
			
			}
			elseif( $head_parts[1][$j]  == "RMstatId")
			{
				$this->values_arr['RMstatId'] = $head_parts[2][$j];
			}
		}
	}
	
	function catch_mails($server,$user,$pass )
	{
		//setup connections to imap and database		
		$conn = imap_open($server, $user, $pass) or die("Connection to server failed");
				
		
		//retrive the latest date stored in the database
		$last_date = $this->db->SQLexecute( "SELECT max(mail_date) AS ld from _MailCatcher");
		
		
		
		$last = $this->db->fetchAssoc($last_date);
		$msg_in_db = array();
		
		//if there are records in DB...
		if($last )
		{
			//retrive all the mails since the last date (sadly search since doesn't support time)
			$msg_today =imap_search($conn,"since ".date("d-M-Y", strtotime($last['ld'])) );
			
			//retrive all the records from the DB so we don't write the same mail twice
			$sql_rt = $this->db->SQLexecute( "SELECT mail_id from _MailCatcher WHERE mail_date >= '".date("Y-m-d",strtotime($last[ld]))."'"  );
			while ( $row = $this->db->fetchAssoc($sql_rt)   )
			{
				$msg_in_db[] = $row['mail_id'];
			}
		}
		else
		{
			//if there aren't any records in DB we retrieve all mails
			$msg_today =imap_search($conn,"ALL");
		}
		
			
		
		
		//how much reports have we recieved since last time
		$num_reports = 0;
		
		
	//	$msg_today = imap_search($conn,"on ". date("d-M-Y", strtotime("today")) ) ;
	//	$msg_today = imap_search($conn,"all" ) ;
		
		//prepare the insert statement
		$sql_insert = "INSERT INTO `_MailCatcher` (mail_id,report_type,status,checked_user,send_mail_id,mail_address,send_subject,arrival_date,send_date,mail_date,sendStatistic_id,mailMsg) VALUES ";
		//variable that tells us if there are any records to add
		$sql_add = false;
		if(is_array($msg_today))
		{
			foreach ($msg_today as $i)
			{
				
				$mailHeader = @imap_headerinfo($conn, $i); 
				//echo "from: $mailHeader->fromaddress"; 
				//echo "subject: $mailHeader->subject \n<br>";
				//	echo "mail_id = $mailHeader->message_id <br>\n";
			
				$this->values_arr = array();
				//from the header we fetch the message_id and date
				$this->values_arr[mail_id] = $mailHeader->message_id;
				$this->values_arr[mail_date] = date("Y-m-d H:i:s",strtotime($mailHeader->date));
				
				
				
				$st = imap_fetchstructure($conn, $i);
				//we look for REPORTS, other mail doesn't consern us (yet)
				if(strtoupper(trim( $st->subtype) )=="REPORT")
				{
										
					$reportType = 1;
					//the second part of REPORT body is a machine readable report explaination part
					$body = imap_fetchbody($conn, $i,2);
					
					$this->parse_body($body);
					//the third part of REPORT body is the returned message
					$this->get_returned_mail_data(imap_fetchbody($conn,$i,3));
					
					$this->values_arr['mail_msg'] = addslashes( imap_fetchbody($conn, $i,1) );
				}
				else if(strtoupper(trim( $st->subtype) )=="ALTERNATIVE")
				{
					$reportType = 2;
					$this->values_arr['mail_msg'] = addslashes( imap_qprint(   imap_fetchbody($conn, $i,1)) ) ;
					$this->values_arr['mail_adress'] = $mailHeader->from[0]->mailbox.'@'. $mailHeader->from[0]->host;
					/*	echo "<pre>";
						print_r($mailHeader);
						echo "</pre>";
						print_r("<br><br><br>-----------------------------------------------------------------------------------<br><br><br>");*/
				
						
				}
				else if(strtoupper(trim( $st->subtype) )=="MIXED")
				{
					$reportType = 3;
					$this->values_arr['mail_msg'] = addslashes( imap_fetchbody($conn, $i,1.2) ) ;
					$this->values_arr['mail_adress'] = $mailHeader->from[0]->mailbox.'@'. $mailHeader->from[0]->host;
		
				}
					
					
					//check if the mail is already in our database
					if(!in_array($this->values_arr['mail_id'],$msg_in_db) )
					{
						if($sql_add)
							$sql_insert .= ",";
						else $sql_add = true;
							
						$sql_insert .= "( '".$this->values_arr['mail_id']."'";
						$sql_insert .= ",$reportType";									//is_report is set to true
						$sql_insert .= ", '".$this->values_arr['status']."'";
						$sql_insert .= ",0";									//user_checked is set to false
						$sql_insert .= ", '".$this->values_arr['send_mail_id']."'";
						$sql_insert .= ", '".trim($this->values_arr['mail_adress'])."'";
						$sql_insert .= ", '".$this->values_arr['send_subject']."'";
						$sql_insert .= ", '".$this->values_arr['arrival_date']."'";
						$sql_insert .= ", '".$this->values_arr['send_date']."'";
						$sql_insert .= ", '".$this->values_arr['mail_date']."'";
						$sql_insert .= ", '".$this->values_arr['RMstatId']."'";
						$sql_insert .= ", '".$this->values_arr['mail_msg']."')";
						
						$num_reports++;
					
					}
					else
					{
						//messege is already in database
					}
				
			
			}
		}
		
		imap_close($conn);
		
		if($sql_add)
		{
						
			if($this->db->SQLexecute($sql_insert))
				return $num_reports;
			else
				return false;
			
			//the user can check the error true his $db reference!
			/*if( $this->db->IsError())
				echo $this->db->GetError();*/
		}
		else 
			return 0;
			//echo "No messages today!";
		
		
	}
}
?>