<?php
// namespace core;

/**
* Simple mail sender may be add SMTP ... 
*/
class Mailer{
	const STRIP_RETURN_PATH = TRUE;
	private $_recipient = NULL;
	private $_subject = NULL;
	private $_message = NULL;
	private $_headers = NULL;
	/** sender/cc/cco is a part of header construction **/
	private $_sender = NULL;
	private $_cc = NULL;
	private $_bcc = NULL;
	/** If different reply address needed **/
	private $_replyRecipient = NULL;
	/** Any files that attached to document holds as array **/
	private $_attachments = array();
	/** This is an error message for internal use **/
	private $_eMessage = "";

	public function __construct($recipient = NULL,$subject = NULL,$message = NULL,$headers = NULL){
		$this->_recipient = $recipient;
		$this->_subject = $subject;
		$this->_message = $message;
		$this->_headers = $headers;
		return $this;
	}
	
	/**
	* Sending the mail if minimal is filled
	* I currently omitted all error expressions... and using plain message that can be pulled without stacking all... :)
	* @return bool false on empty or failure
	**/
	public function send(){
		if(is_null($this->_recipient)){
			throw new Exception("Must have at least one _recipient.");
			// $this->_eMessage .= "Must have at least one _recipient.";
			// return false;
		}
		if(is_null($this->_sender)){
			throw new Exception("Must have one, and only one sender set.");
			// $this->_eMessage .= "Must have one, and only one sender set.";
			// return false;
		}
		/* The message actually can be send without any title (empty one) */
		if(is_null($this->_subject)){
			throw new Exception("EMAIL must have some subject or not?!");
			// $this->_eMessage .= "EMAIL must have some subject or not?!";
			// return false;
		}
		if(is_null($this->_message)){
			throw new Exception("Message is empty.");
			// $this->_eMessage .= "Message is empty!";
			// return false;
		}

// $_recipient = $this->_recipient;//"prromap@hotmail.com";
// $_subject = $this->_subject;//"My _subject!";
// $_headers = 'Content-type: text/html; charset=UTF-8'.PHP_EOL;
// $_headers .= 'Content-Transfer-Encoding: 8BIT'.PHP_EOL;
// $_headers .= 'From: '. $this->_sender.PHP_EOL;
// $message = $this->_message;
// $su_ccess = mail($_recipient,$_subject,$message,$_headers);

		/* Build the header for current message */
		$this->headersBuild();
		$send = mail($this->_recipient, $this->_subject, $this->_message, $this->_headers);
		if(!$send){
			throw new Exception("Server couldn't send the email to : ".$this->_recipient);
		}else{
			return true;
		}
	}

	/**
	* Adding one or more recipient to currently composed mail 
	**/
	public function addRecipient($name, $address){
		$this->_recipient .= (is_null($this->_recipients)) ? ("$name <$address>") : (", $name <$address>");
		return $this;
	}

	/**
	* Add Carbon Copy to secondary recipients any other interested parties receive a copy of a message addressed primarily to another
	**/
	public function addCC($name, $address){
		$this->_cc .= (is_null($this->_cc)) ? ("$name <$address>") : (", $name <$address>");
		return $this;
	}

	/**
	* Add Blind Carbon Copy field receive a copy of the message, but are not shown on any other recipient's copy
	**/
	public function addBCC($name, $address){
		$this->_bcc .= (is_null($this->_bcc)) ? ("$name <$address>") : (", $name <$address>");
		return $this;
	}

	/**
	* Set the sender address in addition will set as default reply recipient if non filled 
	**/
	public function setSender($name,$address){
		$this->_sender = "$name <$address>".PHP_EOL;
		if(is_null($this->_replyRecipient)){
			$this->_replyRecipient = "$name <$address>".PHP_EOL;
		}
		return $this;
	}

	/**
	* Set different reply address if needed, if not set will be used from default sender
	**/
	public function setReplyTo($name,$address){
		$this->_replyRecipient = "$name <$address>".PHP_EOL;
		return $this;
	}

	/**
	* Set the subject of current mail, actually may be left empty...
	*/
	public function setSubject($_subject){
		$this->_subject = $_subject;
		return $this;
	}

	/**
	* The content of the message itself that will be sent
	*/
	public function setMessage($_message) {
		$this->_message = $_message;
		return $this;
	}

	/**
	* Attach file to current mail, just pass the path to file
	**/
	public function attachFile($filePath) {
		$this->_attachments[] = $filePath;
		return $this;
	}

	/**
	* This could be called on try and catch to get the non HAZARDUS messages when try to send mail is failed...
	**/
	public function getMessage(){
		return $this->_eMessage;
	}

	/**
	* This one is building the headers and composes the email content if the mail wasn't requested with construct already
	**/
	private function headersBuild() {
		if(!$this->_headers){
			//$this->_headers = "MIME-Version: 1.0".PHP_EOL;
			//$this->_headers .= "To: ".$this->_recipients.PHP_EOL;
			//$this->_headers .= "Content-type: text/html; charset=iso-8859-1".PHP_EOL;
			//$this->_headers .= "X-Mailer: PHP v".phpversion(). PHP_EOL;
			//$this->_headers .= "Message-ID:<".md5(date('r', time())).$this->additional__headers.">". PHP_EOL; 
			if(self::STRIP_RETURN_PATH !== TRUE){
				$this->_headers .= "Reply-To: ".$this->_replyRecipient.PHP_EOL;
				$this->_headers .= "Return-Path: ".$this->_sender.PHP_EOL;
			}
			if($this->_cc){
				$this->_headers .= "Cc: ".$this->_cc .PHP_EOL;
			}
			if($this->_bcc){
				$this->_headers .= "Bcc: ".$this->_bcc .PHP_EOL;
			}
			/* Will hold the message itself with addition content or multi parts if such used */
			$str = "";
			if($this->_attachments) {
				$random_hash = md5(date('r', time()));
				$_headers .= "Content-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"".PHP_EOL;
				$pos = strpos($this->_message, "<html>");
				if($pos === false){
					$str .= "--PHP-mixed-$random_hash".PHP_EOL;
					$str .= "Content-Type: text/plain; charset=UTF-8".PHP_EOL;
					$str .= "Content-Transfer-Encoding: 8BIT".PHP_EOL;
					$str .= $this->_message .' first attachment '.PHP_EOL;
				}
				if($pos == 0){
					$str .= "--PHP-mixed-$random_hash".PHP_EOL;
					$str .= "Content-Type: text/html; charset=UTF-8".PHP_EOL;
					$str .= "Content-Transfer-Encoding: 8BIT".PHP_EOL;
					$str .= $this->_message.' second attachment '.PHP_EOL;
				}
				if($pos > 0){
					$str .= "Content-Type: multipart/alternative; boundary=\"PHP-alt-".$random_hash."\"".PHP_EOL;
					$str .= "--PHP-alt-$random_hash".PHP_EOL;
					$str .= "Content-Type: text/plain; charset=UTF-8".PHP_EOL;
					$str .= "Content-Transfer-Encoding: 8BIT";
					$str .= substr($this->_message, 0, $pos);
					$str .= PHP_EOL;
					$str .= "--PHP-alt-$random_hash".PHP_EOL;
					$str .= "Content-Type: text/html; charset=UTF-8".PHP_EOL;
					$str .= "Content-Transfer-Encoding: 8BIT";
					$str .= substr($this->_message, $pos);
					$str .= "--PHP-alt-$random_hash--".PHP_EOL;
				}
				foreach($this->_attachments as $key => $value) {
					$mime_type = mime_content_type($value);
					// $mime_type = "image/jpeg";
					$attachment = chunk_split(base64_encode(file_get_contents($value)));
					$fileName = basename("$value");
					$str .= "--PHP-mixed-$random_hash".PHP_EOL;
					$str .= "Content-Type: $mime_type; name=\"$fileName\"".PHP_EOL;
					$str .= "Content-Disposition: attachment".PHP_EOL;
					$str .= "Content-Transfer-Encoding: base64".PHP_EOL;
					$str .= PHP_EOL;
					$str .= "$attachment";
					$str .= PHP_EOL;
				}
				$str .= "--PHP-mixed-$random_hash--".PHP_EOL;
			}else{
				$pos = strpos($this->_message, "<html>");
				if($pos === false){
					$_headers .= "Content-Type: text/plain; charset=UTF-8".PHP_EOL;
					$_headers .= "Content-Transfer-Encoding: 8BIT".PHP_EOL;
					$str .= $this->_message .PHP_EOL;
				}
				if($pos === 0){
					$this->_headers .= 'Content-type: text/html; charset=UTF-8'.PHP_EOL;
					$this->_headers .= 'Content-Transfer-Encoding: 8BIT'.PHP_EOL;
					$str .= $this->_message .PHP_EOL;
				}
				if($pos > 0){
					$random_hash = md5(date('r', time()));
					$_headers .= "Content-Type: multipart/alternative; boundary=\"PHP-alt-".$random_hash."\"".PHP_EOL;
					$str .= "--PHP-alt-$random_hash".PHP_EOL;
					$str .= "Content-Type: text/plain; charset=UTF-8".PHP_EOL;
					$str .= "Content-Transfer-Encoding: 8BIT";
					$str .= substr($this->_message, 0, $pos);
					$str .= PHP_EOL;
					$str .= "--PHP-alt-$random_hash".PHP_EOL;
					$str .= "Content-Type: text/html; charset=UTF-8".PHP_EOL;
					$str .= "Content-Transfer-Encoding: 8BIT";
					$str .= substr($this->_message, $pos);
					$str .= "--PHP-alt-$random_hash--".PHP_EOL;
				}
			}
			$this->_headers .= 'From: '.$this->_sender .PHP_EOL;
			$this->_message = $str;
		}
	}
}
/*
// USAGE
$myMessage = "<html>...";
try {
	// minimal requirements _recipient be set
	$dummy = new Mailer();
	$dummy->setSender("My Website", "contact@mywebsite.com");
	$dummy->addRecipient("Holly","holly@email.com");
	$dummy->setSubject("About stuff");
	$dummy->setMessage($myMessage);
	
	// options below are completely optional
	$dummy->addRecipient("Marcus", "marcus@anothermail.org");
	$dummy->addCC("Mr. Carlson", "manager@business.com");
	$dummy->addCCO("Mr. X", "mistery@mindmail.com");
	$dummy->attachFile('../files/file1.txt');
	
	// now we send with try ommited...
	$dummy->send();
} catch (Exception $e) {
	echo $e->getMessage(); // or error
	exit(0);
}
*/