* @copyright 2009 - 2014 Eoghan O'Brien * @license http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt MIT * @version 1.4 * @link http://github.com/eoghanobrien/php-simple-mail */ /** * Simple Mail class. * * @category SimpleMail * @package SimpleMail * @author Eoghan O'Brien * @copyright 2009 - 2014 Eoghan O'Brien * @license http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt MIT * @version 1.4 * @link http://github.com/eoghanobrien/php-simple-mail */ class SimpleMail { /** * @var int $_wrap */ protected $_wrap = 78; /** * @var array $_to */ protected $_to = array(); /** * @var string $_subject */ protected $_subject; /** * @var string $_message */ protected $_message; /** * @var array $_headers */ protected $_headers = array(); /** * @var string $_parameters */ protected $_params; /** * @var array $_attachments */ protected $_attachments = array(); /** * __construct * * Resets the class properties. */ public function __construct() { $this->reset(); } /** * reset * * Resets all properties to initial state. * * @return SimpleMail */ public function reset() { $this->_to = array(); $this->_headers = array(); $this->_subject = null; $this->_message = null; $this->_wrap = 78; $this->_params = null; $this->_attachments = array(); return $this; } /** * setTo * * @param string $email The email address to send to. * @param string $name The name of the person to send to. * * @return SimpleMail */ public function setTo($email, $name) { $this->_to[] = $this->formatHeader((string) $email, (string) $name); return $this; } /** * getTo * * Return an array of formatted To addresses. * * @return array */ public function getTo() { return $this->_to; } /** * setSubject * * @param string $subject The email subject * * @return SimpleMail */ public function setSubject($subject) { $this->_subject = $this->encodeUtf8( $this->filterOther((string) $subject) ); return $this; } /** * getSubject function. * * @return string */ public function getSubject() { return $this->_subject; } /** * setMessage * * @param string $message The message to send. * * @return SimpleMail */ public function setMessage($message) { $this->_message = str_replace("\n.", "\n..", (string) $message); return $this; } /** * getMessage * * @return string */ public function getMessage() { return $this->_message; } /** * addAttachment * * @param string $path The file path to the attachment. * @param string $filename The filename of the attachment when emailed. * * @return SimpleMail */ public function addAttachment($path, $filename = null) { $filename = empty($filename) ? basename($path) : $filename; $this->_attachments[] = array( 'path' => $path, 'file' => $filename, 'data' => $this->getAttachmentData($path) ); return $this; } /** * getAttachmentData * * @param string $path The path to the attachment file. * * @return string */ public function getAttachmentData($path) { $filesize = filesize($path); $handle = fopen($path, "r"); $attachment = fread($handle, $filesize); fclose($handle); return chunk_split(base64_encode($attachment)); } /** * setFrom * * @param string $email The email to send as from. * @param string $name The name to send as from. * * @return SimpleMail */ public function setFrom($email, $name) { $this->addMailHeader('From', (string) $email, (string) $name); return $this; } /** * addMailHeader * * @param string $header The header to add. * @param string $email The email to add. * @param string $name The name to add. * * @return SimpleMail */ public function addMailHeader($header, $email = null, $name = null) { $address = $this->formatHeader((string) $email, (string) $name); $this->_headers[] = sprintf('%s: %s', (string) $header, $address); return $this; } /** * addGenericHeader * * @param string $header The generic header to add. * @param mixed $value The value of the header. * * @return SimpleMail */ public function addGenericHeader($header, $value) { $this->_headers[] = sprintf( '%s: %s', (string) $header, (string) $value ); return $this; } /** * getHeaders * * Return the headers registered so far as an array. * * @return array */ public function getHeaders() { return $this->_headers; } /** * setAdditionalParameters * * Such as "-fyouremail@yourserver.com * * @param string $additionalParameters The addition mail parameter. * * @return SimpleMail */ public function setParameters($additionalParameters) { $this->_params = (string) $additionalParameters; return $this; } /** * getAdditionalParameters * * @return string */ public function getParameters() { return $this->_params; } /** * setWrap * * @param int $wrap The number of characters at which the message will wrap. * * @return SimpleMail */ public function setWrap($wrap = 78) { $wrap = (int) $wrap; if ($wrap < 1) { $wrap = 78; } $this->_wrap = $wrap; return $this; } /** * getWrap * * @return int */ public function getWrap() { return $this->_wrap; } /** * hasAttachments * Checks if the email has any registered attachments. * * @return bool */ public function hasAttachments() { return !empty($this->_attachments); } /** * assembleAttachment * * @return string */ public function assembleAttachmentHeaders() { $uid = $this->getUniqueId(); $eol = PHP_EOL; $head = array(); $head[] = "{$eol}MIME-Version: 1.0"; $head[] = "Content-Type: multipart/mixed; boundary=\"{$uid}\"{$eol}"; $head[] = "This is a multi-part message in MIME format."; $head[] = "--{$uid}"; $head[] = "Content-type:text/html; charset=\"utf-8\""; $head[] = "Content-Transfer-Encoding: 7bit{$eol}"; $head[] = $this->_message . "{$eol}"; $head[] = "--{$uid}"; foreach ($this->_attachments as $attachment) { $head[] = $this->getAttachmentMimeTemplate($attachment, $uid); } return join("{$eol}", $head); } /** * getAttachmentMimeTemplate() * * @param array $attachment An array containing 'file' and 'data' keys. * @param string $uid A unique identifier for the boundary. * * @return string */ public function getAttachmentMimeTemplate($attachment, $uid) { $eol = PHP_EOL; $file = $attachment['file']; $data = $attachment['data']; $head = array(); $head[] = "Content-Type: application/octet-stream; name=\"{$file}\""; $head[] = "Content-Transfer-Encoding: base64"; $head[] = "Content-Disposition: attachment; filename=\"{$file}\"{$eol}"; $head[]= "{$data}{$eol}"; $head[]= "--{$uid}"; return implode($eol, $head); } /** * send * * @throws \RuntimeException on no 'To: ' address to send to. * @return boolean */ public function send() { $to = $this->getToForSend(); $headers = $this->getHeadersForSend(); if (empty($to)) { throw new \RuntimeException( 'Unable to send, no To address has been set.' ); } if ($this->hasAttachments()) { $message = ''; $headers .= $this->assembleAttachmentHeaders(); } else { $message = $this->getWrapMessage(); } date_default_timezone_set('America/New_York'); return mail($to, $this->_subject, $message, $headers, $this->_params); } /** * debug * * @return string */ public function debug() { return '
' . print_r($this, true) . '
'; } /** * magic __toString function. * * @return string */ public function __toString() { return print_r($this, true); } /** * formatHeader * * Formats a display address for emails according to RFC2822 e.g. * Name * * @param string $email The email address. * @param string $name The display name. * * @return string */ public function formatHeader($email, $name = null) { $email = $this->filterEmail($email); if (empty($name)) { return $email; } $name = $this->encodeUtf8($this->filterName($name)); return sprintf('"%s" <%s>', $name, $email); } /** * encodeUtf8() * * @param string $value The value to encode. * * @return string */ public function encodeUtf8($value) { $value = trim($value); if (preg_match('/(\s)/', $value)) { return $this->encodeUtf8Words($value); } return $this->encodeUtf8Word($value); } /** * encodeUtf8Word() * * @param string $value The word to encode. * * @return string */ public function encodeUtf8Word($value) { return sprintf('=?UTF-8?B?%s?=', base64_encode($value)); } /** * encodeUtf8Words() * * @param string $value The words to encode. * * @return string */ public function encodeUtf8Words($value) { $words = explode(' ', $value); $encoded = array(); foreach ($words as $word) { $encoded[] = $this->encodeUtf8Word($word); } return join($this->encodeUtf8Word(' '), $encoded); } /** * filterEmail * * Removes any carriage return, line feed, tab, double quote, comma * and angle bracket characters before sanitizing the email address. * * @param string $email The email to filter. * * @return string */ public function filterEmail($email) { $rule = array( "\r" => '', "\n" => '', "\t" => '', '"' => '', ',' => '', '<' => '', '>' => '' ); $email = strtr($email, $rule); $email = filter_var($email, FILTER_SANITIZE_EMAIL); return $email; } /** * filterName * * Removes any carriage return, line feed or tab characters. Replaces * double quotes with single quotes and angle brackets with square * brackets, before sanitizing the string and stripping out html tags. * * @param string $name The name to filter. * * @return string */ public function filterName($name) { $rule = array( "\r" => '', "\n" => '', "\t" => '', '"' => "'", '<' => '[', '>' => ']', ); $filtered = filter_var( $name, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES ); return trim(strtr($filtered, $rule)); } /** * filterOther * * Removes any carriage return, line feed or tab characters before * sanitizing. * * @param string $data The data to filter. * * @return string */ public function filterOther($data) { $rule = array( "\r" => '', "\n" => '', "\t" => '' ); return strtr(filter_var($data, FILTER_SANITIZE_STRING), $rule); } /** * getHeadersForSend() * * @return string */ public function getHeadersForSend() { if (empty($this->_headers)) { return ''; } return join(PHP_EOL, $this->_headers); } /** * getToForSend() * * @return string */ public function getToForSend() { if (empty($this->_to)) { return ''; } return join(', ', $this->_to); } /** * getUniqueId() * * @return string */ public function getUniqueId() { return md5(uniqid(time())); } /** * getWrapMessage() * * @return string */ public function getWrapMessage() { return wordwrap($this->_message, $this->_wrap); } }