class SendMailException extends ErrorException {}
/**
* Class SendMail
*/
class SendMail
{
const CONTENT_TYPE_PLAIN = 1;
const CONTENT_TYPE_HTML = 2;
const CONTENT_ENCODING_BASE64 = 1;
const CONTENT_ENCODING_QUOTED_PRINTTABLE = 2;
private $_params = array(
'email' => '',
'from_name' => '',
'from_email' => '',
'subject' => 'Без темы',
'message' => '',
'notify' => false,
'priority' => '3 (Normal)',
'charset' => 'utf-8',
'content_type' => 'plain',
'content_encoding' => 'quoted-printable',
'time_limit' => 30
);
private $_rgContentType = array( 1 => 'plain',
2 => 'html'
);
private $_rgContentEncoding = array( 1 => 'base64',
2 => 'quoted-printable'
);
/**
* Адрес и имя отправителя.
*
* @param string $fromEmail
* @param string|null $fromName
*/
public function __construct($fromEmail, $fromName = null)
{
$this->_params['from_email'] = $fromEmail;
$this->_params['from_name'] = $fromName;
}
/**
* Адрес и имя отправителя.
*
* @param string $email
* @param string|null $name
* @return SendMail
*/
public static function from($email, $name = null) {
return new self($email, $name);
}
/**
* Адресат (можно массив адресов).
*
* @param string|array $email
* @param string|null $name
* @return $this
*/
public function to($email, $name = null)
{
return $this;
}
/**
* Тема сообщения.
*
* @param $subject
* @return $this
*/
public function subject($subject)
{
$this->_params['subject'] = $subject;
return $this;
}
/**
* Тело сообщения.
*
* @param $message
* @return $this
*/
public function message($message)
{
$this->_params['message'] = $message;
return $this;
}
/**
* Путь до прикрепляемого файла (можно массив).
*
* @param string|array $files
* @return $this
*/
public function files($files)
{
$this->_params
['files'] = is_array($files) ?
$files : array($files); return $this;
}
/**
* Кодировка (по умолчанию utf-8).
*
* @param string $charset
* @return $this
*/
public function charset($charset = 'utf-8')
{
$this->_params['charset'] = $charset;
return $this;
}
/**
* Приоритет письма.
* true, если важное. По умолчанию false.
*
* @param bool $important
* @return $this
*/
public function important($important = false)
{
if($important)
$this->_params['priority'] = '1 (High)';
return $this;
}
/**
* Уведомлять о прочтении.
* По умолчанию false.
*
* @param bool $notify
* @return $this
*/
public function notify($notify = false)
{
$this->_params['notify'] = $notify;
return $this;
}
/**
* Тип сообщения (по умолчанию text/plain).
*
* @param int $content_type
* @return $this
*/
public function content_type($content_type = 1)
{
$this->_params['content_type'] = (
!isset($this->_rgContentType
[$content_type]) ?
$this->_rgContentType
[1
] : $this->_rgContentType
[$content_type] );
return $this;
}
/**
* Тип конвертации сообщения (по умолчанию 'quoted-printable').
*
* @param int $encoding
* @return $this
*/
public function content_encoding($encoding = 2)
{
$this->_params['content_encoding'] = (
!isset($this->_rgContentEncoding
[$encoding]) ?
$this->_rgContentEncoding
[2
] : $this->_rgContentEncoding
[$encoding] );
return $this;
}
/**
* set_time_limit (по умолчанию == 30с.).
*
* @param int $time_limit
* @return $this
*/
public function time_limit($time_limit = 30)
{
$this->_params['time_limit'] = $time_limit;
return $this;
}
/**
* Отправка почты.
*
* @throws Exception
* @throws SendMailException
*/
public function send()
{
if(empty($this->_params
['email'])) { throw new SendMailException('Не указан адрес получателя: email()');
}
if(empty($this->_params
['from_email'])) { throw new SendMailException('Не указан адрес отправителя: from($email, [$name])');
}
$this->_send();
}
private function _send()
{
if($this->_params['from_name'])
{
$this->_params['from_name'] = $this->_encodeMimeheader($this->_params['from_name']);
$header = "From: " . $this->_params['from_name'] . " <" . $this->_params['from_email'] . ">\r\n";
if($this->_params['notify'])
$header .= "Disposition-Notification-To: " . $this->_params['from_name'] . " <" . $this->_params['from_email'] . ">\r\n";
}
else
{
$header = "From: " . $this->_params['from_email'] . "\r\n";
if($this->_params['notify'])
$header .= "Disposition-Notification-To: " . $this->_params['from_email'] . "\r\n";
}
$header .= (
"Reply-To: " . $this->_params['from_email'] . "\r\n" .
"X-Priority: " . $this->_params['priority'] . "\r\n" .
"MIME-Version: 1.0\r\n"
);
// Если есть прикреплённые файлы
if(!empty($this->_params
['files'])) {
$header .= (
"Content-Type: multipart/mixed; boundary=\"" . $bound . "\"\r\n" .
"This is a multi-part message in MIME format.\r\n"
);
$message = (
"--" . $bound . "\r\n" .
"Content-Type: text/" . $this->_params['content_type'] . "; charset=" . $this->_params['charset'] . "\r\n" .
"Content-Transfer-Encoding: " . $this->_params['content_encoding'] . "\r\n\r\n" .
$this->_strEncoding($this->_params['message']) . "\r\n\r\n"
);
$finfo = NULL;
foreach($this->_params['files'] as $file_name)
{
{
throw new Exception(
'Файл <b>' . $file_name . '</b> не найден!'
);
}
$mimeType = $finfo ?
finfo_file($finfo, $file_name) : ( );
$name = preg_replace('~.*([^/|\\\]+)$~U', '$1', $file_name); $name = $this->_encodeMimeheader
(iconv('cp1251', 'UTF-8', $name));
$message .= (
"--" . $bound . "\r\n" .
"Content-Type: " . $mimeType . "; name=" . $name . "\r\n" .
"Content-Transfer-Encoding: base64\r\n" .
"Content-Disposition: attachment; filename=\"" . $name . "\"; size=" . filesize($file_name) . ";\r\n\r\n" . );
}
$message .= $bound . "--";
if($finfo)
}
else // Если нет файлов
{
$header .= (
"Content-type: text/" . $this->_params['content_type'] . "; charset=" . $this->_params['charset'] . "\r\n" .
"Content-Transfer-Encoding: " . $this->_params['content_encoding'] . "\r\n"
);
$message = $this->_strEncoding($this->_params['message']);
}
$this->_params['subject'] = $this->_encodeMimeheader($this->_params['subject']);
// Отправка сообщения
foreach($this->_params['email'] as $email)
{
$email = empty($email[1
]) ?
$email[0
] : $this->_encodeMimeheader
($email[1]) . ' <' . $email[0] . '>';
@mail($email, $this->_params
['subject'], $message, $header); }
}
private function _strEncoding($str)
{
if($this->_params['content_encoding'] == 'base64')
if($this->_params['content_encoding'] == 'quoted-printable')
{
return quoted_printable_encode($str);
throw new Exception(
'Для конвертации строки в quoted-printable требуется одна из 2х функций:<br>' .
'quoted_printable_encode<br>imap_8bit<br><br>' .
'В противном случае конвертируйте сообщение в base64.<br>' .
'Константа ' . __CLASS__ . '::CONTENT_ENCODING_BASE64'
);
}
}
private function _encodeMimeheader($str) {
return '=?' . $this->_params
['charset'].'?B?' . base64_encode($str) . '?='; }
}