Надсилання електронних листів
Чи збираєтеся ви надсилати електронні листи, наприклад, інформаційні бюлетені або підтвердження замовлень? Фреймворк Nette надає необхідні інструменти з дуже зручним API. Ми покажемо:
- як створити електронний лист, включно з вкладеннями
- як відправити
- як об'єднати електронні листи та шаблони
Встановлення
Завантажте та встановіть пакет за допомогою Composer:
composer require nette/mail
Створення електронних листів
Email – це об'єкт Nette\Mail\Message:
$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
->addTo('peter@example.com')
->addTo('jack@example.com')
->setSubject('Подтверждение заказа')
->setBody("Здравствуйте. Ваш заказ принят.");
Усі параметри мають бути закодовані в UTF-8.
Крім зазначення одержувачів за допомогою методу addTo()
, ви також
можете вказати одержувача копії за допомогою addCc()
, або
одержувача прихованої копії за допомогою addBcc()
. Усі ці методи,
включно з setFrom()
, приймають адресата трьома способами:
$mail->setFrom('john.doe@example.com');
$mail->setFrom('john.doe@example.com', 'John Doe');
$mail->setFrom('John Doe <john.doe@example.com>');
Тіло листа, написане у форматі HTML, передається за допомогою методу
setHtmlBody()
:
$mail->setHtmlBody('<p>Hello,</p><p>Ваш заказ принят.</p>');
Вам не потрібно створювати текстовий варіант листа, Nette згенерує його
автоматично за вас. А якщо лист не має теми, її буде взято з елемента
<title>
.
Зображення також можна дуже легко вставити в HTML-тіло листа. Просто передайте шлях, де фізично розташовані зображення, як другий параметр, і Nette автоматично включить їх до листа:
// автоматично додає /path/to/images/background.gif до листа
$mail->setHtmlBody(
'<b>Привіт</b> <img src="background.gif">',
'/path/to/images',
);
Алгоритм вбудовування зображень підтримує такі шаблони:
<img src=...>
, <body background=...>
, url(...)
всередині
HTML-атрибута style
і спеціальний синтаксис [[...]]
.
Чи можна зробити надсилання електронних листів ще простішим?
Електронні листи – це як листівки. Ніколи не надсилайте паролі або інші облікові дані електронною поштою.
Вкладення
Зрозуміло, ви можете прикріплювати вкладення до електронних листів.
Використовуйте команду
addAttachment(string $file, string $content = null, string $contentType = null)
.
// вставляє файл /path/to/example.zip в електронний лист під ім'ям example.zip
$mail->addAttachment('/path/to/example.zip');
// вставляє файл /path/to/example.zip в електронний лист під іменем info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));
// вставляє файл example.txt із текстом "Hello John!"
$mail->addAttachment('example.txt', 'Hello John!');
Шаблони
Якщо ви надсилаєте електронні листи у форматі HTML, чудова ідея – писати їх у системі шаблонів Latte. Як це зробити?
$latte = new Latte\Engine;
$params = [
'orderId' => 123,
];
$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
->addTo('jack@example.com')
->setHtmlBody(
$latte->renderToString('/path/to/email.latte', $params),
'/path/to/images',
);
Файл email.latte
:
<html>
<head>
<meta charset="utf-8">
<title>Подтверждение заказа</title>
<style>
body {
background: url("background.png")
}
</style>
</head>
<body>
<p>Здравствуйте!</p>
<p>Ваш заказ под номером {$orderId} был принят.</p>
</body>
</html>
Nette автоматично вставляє всі зображення, встановлює тему відповідно
до елемента <title>
і генерує текстову альтернативу для
тіла HTML.
Використання в додатку Nette
Якщо ви використовуєте електронну пошту разом із Nette Application, тобто
презентерами, ви можете захотіти створити посилання в шаблонах,
використовуючи атрибут n:href
або тег {link}
. Latte в принципі їх
не знає, але їх дуже легко додати. Створенням посилань може займатися
об'єкт Nette\Application\LinkGenerator
, який ви отримаєте, передавши його за
допомогою впровадження
залежностей.
use Nette;
class MailSender
{
public function __construct(
private Nette\Application\LinkGenerator $linkGenerator,
private Nette\Bridges\ApplicationLatte\TemplateFactory $templateFactory,
) {
}
private function createTemplate(): Nette\Application\UI\Template
{
$template = $this->templateFactory->createTemplate();
$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
return $template;
}
public function createEmail(): Nette\Mail\Message
{
$template = $this->createTemplate();
$html = $template->renderToString('/path/to/email.latte', $params);
$mail = new Nette\Mail\Message;
$mail->setHtmlBody($html);
// ...
return $mail;
}
}
У шаблоні посилання створюється як у звичайному шаблоні. Усі посилання, створені за допомогою LinkGenerator, є абсолютними:
<a n:href="Presenter:action">Link</a>
Надсилання електронних листів
Mailer – це клас, який відповідає за надсилання електронних листів. Він реалізує інтерфейс Nette\Mail\Mailer і пропонує кілька готових поштових програм, які ми представимо.
Фреймворк автоматично додає сервіс Nette\Mail\Mailer
на основі configuration в контейнер DI, який ви отримуєте, передаючи його
за допомогою впровадження
залежностей.
SendmailMailer
За замовчуванням використовується SendmailMailer, який використовує функцію PHP mail. Приклад використання:
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
Якщо ви хочете встановити returnPath
, але сервер все одно
перезаписує його, використовуйте $mailer->commandArgs = '-fmy@email.com'
.
SmtpMailer
Для надсилання пошти через SMTP-сервер використовуйте SmtpMailer
.
$mailer = new Nette\Mail\SmtpMailer(
host: 'smtp.gmail.com',
username: 'franta@gmail.com',
password: '*****',
encryption: 'ssl',
);
$mailer->send($mail);
У конструктор можуть бути передані такі додаткові параметри:
port
– якщо не задано, використовуватиметься стандартне значення 25 або 465 дляssl
.timeout
– тайм-аут для SMTP-з'єднанняpersistent
– використовувати постійне з'єднанняclientHost
– призначення клієнтаstreamOptions
– дозволяє встановити опції контексту SSL для з'єднання
FallbackMailer
Він не надсилає листи електронною поштою, а розсилає їх через набір розсилок. Якщо одна розсилка не вдалася, вона повторює спробу на наступній. Якщо остання з них не працює, то все починається заново з першої.
$mailer = new Nette\Mail\FallbackMailer([
$smtpMailer,
$backupSmtpMailer,
$sendmailMailer,
]);
$mailer->send($mail);
Інші параметри в конструкторі включають число повторів і час очікування в мілісекундах.
DKIM
DKIM (DomainKeys Identified Mail) – це технологія надійної електронної пошти, яка також допомагає виявити підроблені повідомлення. Відправлене повідомлення підписується закритим ключем домену відправника, і цей підпис зберігається в заголовку електронної пошти. Сервер одержувача порівнює цей підпис із відкритим ключем, що зберігається в DNS-записах домену. Звіряючи підпис, можна довести, що електронний лист справді надійшов із домену відправника і що повідомлення не було змінено під час його передавання.
Ви можете налаштувати mailer для підпису електронної пошти в конфігурації. Якщо ви не використовуєте впровадження залежностей, він задається таким чином:
$signer = new Nette\Mail\DkimSigner(
domain: 'nette.org',
selector: 'dkim',
privateKey: file_get_contents('../dkim/dkim.key'),
passPhrase: '****',
);
$mailer = new Nette\Mail\SendmailMailer; // или SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);
Конфігурація
Огляд параметрів конфігурації для Nette Mail. Якщо ви використовуєте не весь фреймворк, а тільки цю бібліотеку, прочитайте Як завантажити файл конфігурації.
За замовчуванням для надсилання листів використовується поштова
програма Nette\Mail\SendmailMailer
, яка більше не налаштовується. Однак ми
можемо переключити його на Nette\Mail\SmtpMailer
:
mail:
# використовуємо SmtpMailer
smtp: true # (bool) за замовчуванням false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
encryption: ... # (ssl|tls|null) за замовчуванням null
clientHost: ... # (string) за замовчуванням $_SERVER['HTTP_HOST']
persistent: ... # (bool) за замовчуванням false
# контекст для підключення до SMTP-сервера, за замовчуванням використовується stream_context_get_default()
context:
ssl: # усі варіанти на https://www.php.net/manual/en/context.ssl.php
allow_self_signed: ...
...
http: # усі варіанти на https://www.php.net/manual/en/context.http.php
header: ...
...
Ви можете вимкнути перевірку автентичності SSL-сертифіката за
допомогою опції context › ssl › verify_peer: false
. Настійно рекомендується
не робити цього, оскільки це зробить додаток вразливим. Натомість,
додайте сертифікати до сховища
довіри.
Щоб підвищити довіру, ми можемо підписувати електронні листи за допомогою технології DKIM:
mail:
dkim:
domain: myweb.com
selector: lovenette
privateKey: %appDir%/cert/dkim.priv
passPhrase: ...
Послуги з проведення розслідувань
Ці сервіси додаються до контейнера DI:
Назва | Тип | Опис |
---|---|---|
mail.mailer |
Nette\Mail\Mailer | клас відправлення електронноїпошти |
mail.signer |
Nette\Mail\Signer | підписання DKIM |