================
mail.inc.php
================

[code]<?php

/**
 * Represents an e-mail message
 * 
 * @version 1.0.04-07-07
 * @copyright http://creativecommons.org/licenses/by-sa/2.5/
 * @author Boaz den Besten
 * @contact: www.n3rd.nl
 * @PHPversion: 5.2.3-dev
 *
 */
class clsMail{
	
	/**
	 * De bound, (splitst het bericht als dat nodig is)
	 *
	 * @var String Bound
	 */
	private $m_sBound = '';
	
	/**
	 * Het Content type van het bericht (clsMail::TEXT || clsMail::HTML)
	 *
	 * @var Intger Content Type
	 */
	private $m_sContentType = '';
	
	/**
	 * Het adres van de Zender
	 *
	 * @var String Zender Adres
	 */
	private $m_sSender = '';
	
	/**
	 * Bevat het adres waarnaar geantwoord moet worden
	 * 
	 * @var Antwoord adres.
	 */
	private $m_sReplyTo = '';
	
	/**
	 * Bevat de mail adressen van de ontvangers
	 * 
	 * @var Array
	 */
	private $m_aRecievers = array();
	
	/**
	 * Bevat de mail adressen van ontvangers van een Carbon Copy
	 *
	 * @var Array
	 */
	private $m_aCarbonCopy = array();
	
	/**
	 * Bevat de mail adressen van ontvangers van een Blind Carbon Copy
	 *
	 * @var Array
	 */
	private $m_aBlindCarbonCopy = array();
	
	/**
	 * Headers die aan het bericht toegevoegd worden
	 * 
	 * @var String 
	 */
	private $m_aHeaders	= array();
	
	/**
	 * Het bericht dat verzonden zal worden
	 * 
	 * @var String
	 */
	private $m_sMessage	= '';
	
	/**
	 * Het onderwerp van de Mail
	 * 
	 * @var String
	 */
	private $m_sSubject	= '';
	
	/**
	 * Collectie van bijlagen
	 *
	 * @var Array
	 */
	private $m_aAttachments = array();
	
	/**
	 * Content type zo instellen dat een TEXT mail verzonden wordt (default)
	 * 
	 * @access public
	 */
	const TEXT = 1;
	
	/**
	 * Content type zo instellen dat een HTML mail verzonden wordt
	 *
	 * @access public
	 */
	const HTML = 2;
	
	/**
	 * Constuctor, voegt meteen standaard headers in.
	 *
	 * @param boolean $p_bDefaultHeaders
	 * @param int $p_nContentType
	 */
	public function __construct($p_nContentType=self::TEXT, $p_bDefaultHeaders=true){
		$this->m_sBound =  md5(uniqid(time()));
		
		if($p_bDefaultHeaders === true){
			$this->addHeader('MIME-Version: 1.0');
			
			switch($p_nContentType){
				case self::HTML:
					$this->m_sContentType = 'Content-Type: text/html; charset=iso-8859-1';
					break;
				case self::TEXT:
				default:
					$this->m_sContentType = 'Content-type: text/plain; charset=iso-8859-1';
			}
			
			$this->addHeader('X-Priority: 3');
			$this->addHeader('X-MSMail-Priority: Normal');
			$this->addHeader('X-Originating-IP: '.$_SERVER['REMOTE_ADDR']);
		}
	}
	
	/**
	 * Om mail Injection te voorkomen
	 *
	 * @param String $p_sInput
	 * @return String
	 */
	private function protectHeaders($p_sInput){
		$aReplace = array("\n", "\r");
		$sReturn = str_replace($aReplace, "", $p_sInput);
		
		return $sReturn;
	}
	
	/**
	 * Zet een afzender adhv e-mail adres
	 * 
	 * @throws mailException Invalid mail adress
	 * @param String $p_sSenderEmail
	 */
	public function setSender($p_sSender){
		if(filter_var($p_sSender, FILTER_VALIDATE_EMAIL) === false){
			throw new mailException('Invalid sender E-mail', 301);
		}
	
		$this->m_sSender = $this->protectHeaders($p_sSender);
	}
	
	/**
	 * Zet een antwoord adres adhv e-mail adres
	 * 
	 * @throws mailException Invalid mail adress
	 * @param String $p_sReplyTo
	 */
	public function setReplyTo($p_sReplyTo){
		if(filter_var($p_sReplyTo, FILTER_VALIDATE_EMAIL) === false){
			throw new mailException('Invalid Reply-To e-mail', 305);
		}
	
		$this->m_sReplyTo = $this->protectHeaders($p_sReplyTo);
	}
	
	/**
	 * Voeg een ontvanger toe adhv E-mail adres
	 *
	 * @throws mailException Invalid mail adress
	 * @param String $p_sRecieverEmail
	 */
	public function addReciever($p_sRecieverEmail){
		if(filter_var($p_sRecieverEmail, FILTER_VALIDATE_EMAIL) === false){
			throw new mailException('Invalid reciever E-mail', 302);
		}
		
		$this->m_aRecievers[] = $this->protectHeaders($p_sRecieverEmail);
	}
	
	/**
	 * Voeg een ontvanger van een Carbon Copy toe adhv Mail Adress
	 *
	 * @throws mailException Invalid mail adress
	 * @param String E-mail adres
	 */
	public function addCarbonCopy($p_sMailAdress){
		if(filter_var($p_sMailAdress, FILTER_VALIDATE_EMAIL) === false){
			throw new mailException('Invalid Carbon Copy E-mail', 303);
		}
		
		$this->m_aCarbonCopy[] = $this->protectHeaders($p_sMailAdress);
	}
	
	/**
	 * Voeg een ontvanger van een Blind Carbon Copy toe adhv Mail Adress
	 *
	 * @throws mailException Invalid mail adress
	 * @param String E-mail adres
	 */
	public function addBlindCarbonCopy($p_sMailAdress){
		if(filter_var($p_sMailAdress, FILTER_VALIDATE_EMAIL) === false){
			throw new mailException('Invalid Blind Carbon Copy E-mail', 304);
		}
		
		$this->m_aBlindCarbonCopy[] = $this->protectHeaders($p_sMailAdress);
	}
	
	/**
	 * Zet het onderwerp
	 *
	 * @param String Mail Onderwerp
	 */
	public function setSubject($p_sSubject){
		$this->m_sSubject = $this->protectHeaders($p_sSubject);
	}
	
	/**
	 * Voeg iets toe aan de e-mail body.
	 *
	 * @param String Message Part
	 */
	public function addMessage($p_sMessage){
		$this->m_sMessage .= $p_sMessage;
	}
	
	/**
	 * Een header toevoegen
	 *
	 * @param String Mail Header
	 */
	public function addHeader($p_sHeader){
		$this->m_aHeaders[] = $this->protectHeaders($p_sHeader);
	}
	
	/**
	 * Verkrijg het adres van de zender
	 *
	 * @return String Zender Adres
	 */
	public function getSender(){
		return $this->m_sSender;
	}
	
	/**
	 * Verkrijg de headers
	 *
	 * @return String Mail Headers
	 */
	private function getHeaders(){
		$this->addHeader('From: '.$this->m_sSender);
		
		if(!empty($this->m_sReplyTo)){
			$this->addHeader('Reply-To: '.$this->m_sReplyTo);
		}
		
		if(count($this->m_aCarbonCopy) > 0){
			$this->addHeader('Cc: '.implode(', ', $this->m_aCarbonCopy));
		}
		
		if(count($this->m_aBlindCarbonCopy) > 0){
			$this->addHeader('Bcc: '.implode(', ', $this->m_aBlindCarbonCopy));
		}
		
		if(count($this->m_aAttachments) == 0){
			$this->addHeader($this->m_sContentType);
		}
		
		return $this->m_aHeaders;
	}
	
	/**
	 * Verkrijg het gedeelte van de mail body
	 *
	 * @return String Mail Body
	 */
	private function getMailBody(){
		if(count($this->m_aAttachments) > 0){
			$sBody = '--'.$this->m_sBound.PHP_EOL;
			$sBody .= $this->m_sContentType.PHP_EOL;
			$sBody .= PHP_EOL;
			$sBody .= $this->m_sMessage;
			$sBody .= implode(PHP_EOL, $this->m_aAttachments);
		}else{
			$sBody = $this->m_sMessage;
		}
		
		return $sBody;
	}
	
	/**
	 * Bijlage toevoegen
	 *
	 * @throws mailException ICould not open/read mail attachement
	 * @param String Bestands locatie / naam
	 */
	public function addAttachment($sFileName){
		if(count($this->m_aAttachments) == 0){
			$this->addHeader('Content-Type: multipart/mixed; boundary="'.$this->m_sBound.'"');
		}
		
		if(!$rFile = @fopen($sFileName, 'r')){
			throw new mailException('Could not open mail attachment.', 401);
		}
		
        if(!$sContent = @fread($rFile, filesize($sFileName))){
        	throw new mailException('Could not read mail attachment.', 402);
        }
        
        fclose($rFile);
		
		$sAttachment = '--'.$this->m_sBound.PHP_EOL;
		$sAttachment .= 'Content-Type: application/octet-stream; name="'.basename($sFileName).'"'.PHP_EOL;
		$sAttachment .= 'Content-Transfer-Encoding: base64'.PHP_EOL;
		$sAttachment .= 'Content-Disposition: attachment; filename="'.basename($sFileName).'"'.PHP_EOL;
		$sAttachment .= PHP_EOL;
		$sAttachment .= chunk_split(base64_encode($sContent)).PHP_EOL;
		
		$this->m_aAttachments[] = $sAttachment;
	}
	
	public function send(){
		if(!mail(implode(', ', $this->m_aRecievers), $this->m_sSubject, $this->getMailBody(), implode(PHP_EOL, $this->getHeaders()))){
			throw new mailException('Mail could not be send.', 501);
		}
	}
	
}

/**
 * handels mailExceptions
 * 
 * @version 1.0.04-07-07
 * @copyright http://creativecommons.org/licenses/by-sa/2.5/
 * @author Boaz den Besten
 * @contact: www.n3rd.nl
 * @PHPversion: 5.2.3-dev
 *
 */
class mailException extends Exception{
	
	/**
	 * Waar moet de logfile gemaakt (indien true)
	 * 
	 * @var String
	 */
	private $m_sLogFile = 'log/mail.log';
	
	/**
	 * Tijd dat er een Exception gegooid wordt
	 * 
	 * @var String
	 */
	private $m_sTime;
	
	/**
	 * __construct method van de parent overschrijven
	 *
	 * @param String $p_sMessage
	 * @param int $p_nCode
	 * @param boolean $p_bLogToFile
	 */
	public function __construct($p_sMessage, $p_nCode=0, $p_bLogToFile=true){
		parent::__construct($p_sMessage, $p_nCode);
		$this->m_sTime = date("d-m-Y H:i");
		
		if($p_bLogToFile){
			$this->writeLogFile();
		}
	}
	
	/**
	 * De tijd van de mailException aanroep verkrijgen:
	 *
	 * @return String
	 */
	public function getTime(){
		return $this->m_sTime;
	}
	
	/**
	 * Visitor IP verkrijgen:
	 *
	 * @return String
	 */
	public function getIp(){
		return $_SERVER['REMOTE_ADDR'];
	}
	
	/**
	 * Fouten in een LogFile opslaan als dat aan staat.
	 */
	private function writeLogFile(){
		$sPut = '['.$this->getTime().'] - [Error#: '.$this->getCode().'] [Error: '.$this->getMessage().'] - [Page: '.basename($this->getFile()).' Line: '.$this->getLine().'] - [Visitor: '.$this->getIp().']'.PHP_EOL;
		
		file_put_contents($this->m_sLogFile, $sPut, FILE_APPEND);
	}
	
}

?>[/code]