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 = []; } }