phplibrary/src/Mail.php

252 lines
6.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Класс для работы с почтой
* http://en.wikipedia.org/wiki/MIME
*/
namespace ctiso;
use ctiso\Path,
Exception;
class Mail
{
/** @var string */
public $_from;
/** @var string */
public $_to;
/** @var string */
public $_subject;
/** @var string */
public $content;
/** @var string */
public $copy;
/** @var string */
private $encoding;
/** @var string */
private $_notify = null;
/** @var array */
protected $attachment = array();
/** @var string */
protected $uniqid;
/** @var string */
protected $type = "text/plain";
function __construct()
{
$this->setEncoding("UTF-8");
$this->uniqid = strtoupper(uniqid((string)time())); // Идентефикатор разделителя
}
/**
* Установка отправителя
*/
function from(string $name): void
{
// filter_var($name, FILTER_VALIDATE_EMAIL);
$this->_from = $name;
}
/**
* Установка получателя
*/
function to(string $name): void
{
$this->_to = $name;
}
/**
* @param string $name
*/
function replyTo($name): void
{}
/**
* Установка получателей копии
*/
function copy(string $name): void
{
$this->copy = $name;
}
function notify(string $notify): void
{
$this->_notify = $notify;
}
/**
* Тема письма
*/
function subject(string $subject): void
{
$this->_subject = $subject;
}
/**
* Текст письма
*/
function setContent(string $text): void
{
$this->content = $text;
}
/**
* Кодировка текста в письме
*/
function setEncoding(string $encoding): void
{
$this->encoding = $encoding;
}
/**
* Добавление вложения из файла
* @param string $filename
* @param string|false $name
*/
function addAttachment(string $filename, $name = false): void
{
if (file_exists($filename)) {
$file = fopen($filename, "rb");
if (is_resource($file)) {
$data = fread($file, filesize($filename));
$this->attachment[] = ($name) ? [$data, $name] : [$data, basename($filename)];
}
}
}
/**
* Установка типа содержимого
* @param string $type
*/
function setType($type): void
{
$this->type = $type;
}
/**
* Добавление вложения из строки с указанием имени файла
* @param string $data
* @param string $name
*/
function addAttachmentRaw($data, string $name): void
{
$this->attachment[] = [$data, $name];
}
/**
* @param string $var
* @param string $val
*/
function quote($var, $val): string
{
return ";" . PHP_EOL . "\t" . $var . "=\"" . $val . "\"";
}
/**
* Общий формат тегов MIME
* @see http://tools.ietf.org/html/rfc2045
*
* @param string $name
* @param string $value
* @param array $args
*/
function mimeTag($name, $value, array $args = []): string
{
assert(is_string($name));
assert(is_string($value));
return $name . ": " . $value . implode("", array_map([$this, 'quote'], array_keys($args), array_values($args))) . PHP_EOL;
}
/**
*
* @see http://tools.ietf.org/html/rfc2047
*/
function encodedWord(string $text, string $encoding = 'B'): string
{
return "=?{$this->encoding}?$encoding?" . base64_encode($text) . "?=";
}
/**
* Тело сообщения
*/
function getMessage(): string
{
$message = "--" . $this->uniqid . PHP_EOL;
$message .= $this->mimeTag("Content-Type", $this->type, ['charset' => $this->encoding]);
$message .= $this->mimeTag("Content-Transfer-Encoding", "8bit");
$message .= PHP_EOL . $this->content . PHP_EOL . PHP_EOL;
/*
* Вложения
* http://tools.ietf.org/html/rfc2046#section-5.1.3
*/
foreach ($this->attachment as $value) {
list($data, $name) = $value;
$message .= "--" . $this->uniqid . PHP_EOL;
$message .= $this->mimeTag("Content-Type", "application/octet-stream", ['name' => basename($name)]);
$message .= $this->mimeTag("Content-Transfer-Encoding", "base64");
$message .= $this->mimeTag("Content-Disposition", "attachment", ['filename' => basename($name)]);
$message .= PHP_EOL . chunk_split(base64_encode($data)) . PHP_EOL;
}
return $message;
}
/**
* Заголовок сообщения
*/
function getHeader(): string
{
$head = $this->mimeTag("MIME-Version", "1.0");
$head .= $this->mimeTag("From", $this->_from);
$head .= $this->mimeTag("X-Mailer", "CMS Tool");
$head .= $this->mimeTag("Reply-To", $this->_from);
if (is_string($this->_notify)) {
$head .= $this->mimeTag("Disposition-Notification-To", "\"" . $this->_notify . "\" <" . $this->_from . ">");
}
$head .= $this->mimeTag("Content-Type", "multipart/mixed", ["boundary" => $this->uniqid]);
if ($this->copy) {
$head .= $this->mimeTag("BCC", $this->copy);
}
$head .= PHP_EOL;
return $head;
}
function getSubject(): string
{
return $this->encodedWord($this->_subject);
}
/**
* Вывод строки для сохранения в формате .eml
*/
function eml(): string
{
return "To: " . $this->_to . PHP_EOL . "Subject: {$this->getSubject()}" . PHP_EOL . $this->getHeader() . $this->getMessage();
}
/**
* Отправка почты
*/
function send(): bool
{
$result = mail($this->_to, $this->getSubject(), $this->getMessage(), $this->getHeader());
if (! $result) {
file_put_contents(Path::resolveFile("send.eml"), $this->eml());
throw new Exception('Невозможно отправить почту');
}
return $result;
}
function clear(): void
{
foreach ($this->attachment as $key => &$value) {
unset($this->attachment[$key]);
}
$this->attachment = [];
}
}