Odesílání e-mailů
Chystáte se odesílat e-maily, například newslettery nebo potvrzení objednávek? Nette Framework poskytuje potřebné nástroje s velmi příjemným API. Ukážeme si:
- jak e-mail vytvořit včetně příloh
- jak ho odeslat
- jak spojit e-maily a šablony
Instalace:
composer require nette/mail
Vytvoření e-mailu
E-mail je objektem třídy Nette\Mail\Message. Vytvoříme jej třeba takto:
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->addTo('jirka@example.com')
->setSubject('Potvrzení objednávky')
->setBody("Dobrý den,\nvaše objednávka byla přijata.");
Všechny zadávané parametry musí být v UTF-8.
Kromě uvedení příjemce metodou addTo()
lze uvést i příjemce kopie addCc()
, nebo příjemce
skryté kopie addBcc()
. Ve všech těchto metodách včetně setFrom()
můžeme adresáta zapsat třemi
způsoby:
$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');
Tělo e-mailu zapsaného v HTML se předává metodou setHtmlBody()
:
$mail->setHtmlBody('<p>Dobrý den,</p><p>vaše objednávka byla přijata.</p>');
Textovou alternativu nemusíte vytvářet, Nette ji vygeneruje automaticky za vás. A pokud e-mail nemá nastavený subjekt,
pokusí se jej převzít z elementu <title>
.
Do HTML těla lze také neobyčejně snadno vkládat obrázky. Stačí jako druhý parametr předat cestu, kde se obrázky fyzicky nacházejí, a Nette je automaticky zahrne do e-mailu:
// automaticky přidá /path/to/images/background.gif do e-mailu
$mail->setHtmlBody(
'<b>Hello</b> <img src="background.gif">',
'/path/to/images'
);
Algoritmus vkládající obrázky vyhledává tyto vzory: <img src=...>
,
<body background=...>
, url(...)
uvnitř HTML atributu style
a speciální syntaxi
[[...]]
.
Může být odesílání e-mailů ještě jednodušší?
E-mail je něco jako pohlednice. Nikdy e-mailem neposílejte hesla ani jiné přístupové údaje.
Přílohy
Do e-mailu lze samozřejmě vkládat přílohy. Slouží k tomu metoda
addAttachment(string $file, string $content = null, string $contentType = null)
.
// vloží do e-mailu soubor /path/to/example.zip pod názvem example.zip
$mail->addAttachment('/path/to/example.zip');
// vloží do e-mailu soubor /path/to/example.zip pojmenovaný info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));
// vloží do e-mailu soubor example.txt s obsahem "Hello John!"
$mail->addAttachment('example.txt', 'Hello John!');
Šablony
Pokud posíláte HTML e-maily, přímo se nabízí je zapisovat v šablonovacím systému Latte. Jak na to?
$latte = new Latte\Engine;
$params = [
'orderId' => 123,
];
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->setHtmlBody(
$latte->renderToString('/path/to/email.latte', $params),
'/path/to/images'
);
Soubor email.latte
:
<html>
<head>
<meta charset="utf-8">
<title>Potvrzení objednávky</title>
<style>
body {
background: url("background.png")
}
</style>
</head>
<body>
<p>Dobrý den,</p>
<p>Vaše objednávka číslo {$orderId} byla přijata.</p>
</body>
</html>
Nette automaticky vloží všechny obrázky, nastaví subject podle elementu <title>
a vygeneruje textovou
alternativu k HTML.
Použití v Nette Application
Pokud e-maily používáte společeně s Nette Application, tj. s presentery, můžete chtít v šablonách vytvářet
odkazy pomocí atributu n:href
nebo značky {link}
. Ty Latte v základu nezná, ale je velmi snadné je
doplnit. Vytvářet odkazy umí objekt Nette\Application\LinkGenerator
, ke kterému se dostanete tak, že si jej
necháte předat pomocí dependency
injection:
use Nette;
class MailSender
{
/** @var Nette\Application\LinkGenerator */
private $linkGenerator;
/** @var Nette\Application\UI\ITemplateFactory */
private $templateFactory;
public function __construct(
Nette\Application\LinkGenerator $linkGenerator,
Nette\Application\UI\ITemplateFactory $templateFactory
)
{
$this->linkGenerator = $linkGenerator;
$this->templateFactory = $templateFactory;
}
private function createTemplate()
{
$template = $this->templateFactory->createTemplate();
$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
return $template;
}
public function createEmail()
{
$template = $this->createTemplate();
$html = $template->renderToString('/path/to/email.latte', $params);
$mail = new Nette\Mail\Message;
$mail->setHtmlBody($html);
// ...
return $mail;
}
}
V šabloně potom vytváříme odkazy tak, jak jsme zvyklí. Všechny odkazy vytvořene přes LinkGenerator budou absolutní.
<a n:href="Presenter:action">Odkaz</a>
Odeslání e-mailu
Mailer je třída zajišťující odesílání e-mailů. Implementuje rozhraní Nette\Mail\IMailer a k dispozici je několik předpřipravených mailerů, které si představíme.
Framework automaticky přidává do DI kontejneru službu typu Nette\Mail\IMailer
sestavenou na základě konfigurace, a ke které se dostanete tak, že si ji necháte předat pomocí dependency injection.
SendmailMailer
Výchozí mailer je SendmailMailer, který používá PHP funkci mail. Příklad použití:
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
Pokud chcete nastavit returnPath
a server vám ho pořád přepisuje, použijte
$mailer->commandArgs = '-fMuj@email.cz'
.
SmtpMailer
K odeslání pošty přes SMTP server slouží SmtpMailer
.
$mailer = new Nette\Mail\SmtpMailer([
'host' => 'smtp.gmail.com',
'username' => 'franta@gmail.com',
'password' => '*****',
'secure' => 'ssl',
]);
$mailer->send($mail);
Pokud neuvedete host
, použije se hodnota z php.ini. V poli lze uvést další tyto klíče:
port
– pokud není nastaven, použije se výchozí 25 nebo 465 prossl
context
– umožňuje nastavit SSL context options pro spojenítimeout
– timeout pro SMTP spojenípersistent
– použít persistent spojeníclientHost
– nastavení hlavičky Host klienta
FallbackMailer
E-maily přímo neodesílá, ale odesílání zprostředkovává přes sadu mailerů. V případě, že jeden mailer selže, zopakuje pokus u dalšího. Pokud selže i poslední, začíná znovu od prvního.
$mailer = new Nette\Mail\FallbackMailer([
$smtpMailer,
$backupSmtpMailer,
$sendmailMailer
]);
$mailer->send($mail);
Jako další parametry v konstruktoru můžeme uvést počet opakování a čekací dobu v milisekundách.
Konfigurace
Přehled konfiguračních voleb pro Nette Mail.
Pro odesílání e-mailů se standardně používá mailer Nette\Mail\SendmailMailer
, který se dále
nekonfiguruje. Můžeme jej však přepnout na Nette\Mail\SmtpMailer
:
mail:
# použije SmtpMailer
smtp: true # (bool) výchozí je false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
secure: ... # (ssl|tls|null) výchozí je null
clientHost: ... # (string) výchozí je $_SERVER['HTTP_HOST']
persistent: ... # (bool) výchozí je false
# kontext pro připojení k SMTP serveru, viz stream_context_create()
context: # (array) výchozí je stream_context_get_default()