Nette Mail
State per inviare e-mail, ad esempio newsletter o conferme d'ordine? Nette Framework fornisce gli strumenti necessari con un'API molto piacevole. Vedremo:
- come creare un'e-mail, incluse le allegate
- come inviarla
- come collegare e-mail e template
Installazione
Scaricate e installate la libreria utilizzando lo strumento Composer:
composer require nette/mail
Creazione di un'e-mail
L'e-mail è un oggetto della classe Nette\Mail\Message. Lo creiamo ad esempio così:
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->addTo('jirka@example.com')
->setSubject('Conferma ordine')
->setBody("Buongiorno,\nil suo ordine è stato ricevuto.");
Tutti i parametri inseriti devono essere in UTF-8.
Oltre a specificare il destinatario con il metodo addTo(), è possibile specificare anche il destinatario della
copia addCc(), o il destinatario della copia nascosta addBcc(). In tutti questi metodi, incluso
setFrom(), possiamo scrivere l'indirizzo in tre modi:
$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');
Il corpo dell'e-mail scritto in HTML viene passato con il metodo setHtmlBody():
$mail->setHtmlBody('<p>Buongiorno,</p><p>il suo ordine è stato ricevuto.</p>');
Non è necessario creare l'alternativa testuale, Nette la genererà automaticamente per voi. E se l'e-mail non ha un oggetto
impostato, cercherà di prenderlo dall'elemento <title>.
È anche straordinariamente facile inserire immagini nel corpo HTML. Basta passare come secondo parametro il percorso dove si trovano fisicamente le immagini, e Nette le includerà automaticamente nell'e-mail:
// aggiunge automaticamente /path/to/images/background.gif all'e-mail
$mail->setHtmlBody(
'<b>Hello</b> <img src="background.gif">',
'/path/to/images',
);
L'algoritmo che inserisce le immagini cerca questi pattern: <img src=...>,
<body background=...>, url(...) all'interno dell'attributo HTML style e la sintassi
speciale [[...]].
L'invio di e-mail può essere ancora più semplice?
L'e-mail è come una cartolina. Non inviate mai password o altri dati di accesso via e-mail.
Allegati
Naturalmente, è possibile inserire allegati nell'e-mail. A questo serve il metodo
addAttachment(string $file, ?string $content = null, ?string $contentType = null).
// inserisce il file /path/to/example.zip nell'e-mail con il nome example.zip
$mail->addAttachment('/path/to/example.zip');
// inserisce il file /path/to/example.zip nell'e-mail chiamato info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));
// inserisce il file example.txt nell'e-mail con il contenuto "Hello John!"
$mail->addAttachment('example.txt', 'Hello John!');
Template
Se inviate e-mail HTML, è naturale scriverle nel sistema di template Latte. Come fare?
$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',
);
File email.latte:
<html>
<head>
<meta charset="utf-8">
<title>Conferma ordine</title>
<style>
body {
background: url("background.png")
}
</style>
</head>
<body>
<p>Buongiorno,</p>
<p>Il suo ordine numero {$orderId} è stato ricevuto.</p>
</body>
</html>
Nette inserirà automaticamente tutte le immagini, imposterà l'oggetto secondo l'elemento <title> e
genererà l'alternativa testuale all'HTML.
Utilizzo in Nette Application
Se usate le e-mail insieme a Nette Application, cioè con i presenter, potreste voler creare link nei template usando
l'attributo n:href o il tag {link}. Latte non li conosce di base, ma è molto facile aggiungerli.
L'oggetto Nette\Application\LinkGenerator può creare link, e potete ottenerlo facendovelo passare tramite dependency injection:
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;
}
}
Nel template, creiamo quindi i link come siamo abituati. Tutti i link creati tramite LinkGenerator saranno assoluti.
<a n:href="Presenter:action">Link</a>
Invio dell'e-mail
Mailer è la classe che si occupa dell'invio delle e-mail. Implementa l'interfaccia Nette\Mail\Mailer e sono disponibili diversi mailer predefiniti che presenteremo.
Il framework aggiunge automaticamente al container DI un servizio di tipo Nette\Mail\Mailer costruito sulla base
della configurazione, a cui potete accedere facendovelo passare tramite dependency injection.
SendmailMailer
Il mailer predefinito è SendmailMailer, che utilizza la funzione PHP mail. Esempio di utilizzo:
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
Se volete impostare returnPath e il server continua a sovrascriverlo, usate
$mailer->commandArgs = '-fMio@email.it'.
SmtpMailer
Per inviare posta tramite un server SMTP si usa SmtpMailer.
$mailer = new Nette\Mail\SmtpMailer(
host: 'smtp.gmail.com',
username: 'franta@gmail.com',
password: '*****',
encryption: 'ssl',
);
$mailer->send($mail);
Al costruttore possono essere passati questi altri parametri:
port– se non impostato, viene utilizzato il predefinito 25 o 465 perssltimeout– timeout per la connessione SMTPpersistent– usare una connessione persistenteclientHost– impostazione dell'header Host del clientstreamOptions– consente di impostare le SSL context options per la connessione
FallbackMailer
Non invia direttamente le e-mail, ma ne gestisce l'invio tramite un set di mailer. Nel caso in cui un mailer fallisca, ripete il tentativo con il successivo. Se fallisce anche l'ultimo, ricomincia dal primo.
$mailer = new Nette\Mail\FallbackMailer([
$smtpMailer,
$backupSmtpMailer,
$sendmailMailer,
]);
$mailer->send($mail);
Come altri parametri nel costruttore possiamo specificare il numero di ripetizioni e il tempo di attesa in millisecondi.
DKIM
DKIM (DomainKeys Identified Mail) è una tecnologia per aumentare l'affidabilità delle e-mail, che aiuta anche a rilevare messaggi contraffatti. Il messaggio inviato è firmato con la chiave privata del dominio del mittente e questa firma è memorizzata nell'intestazione dell'e-mail. Il server del destinatario confronta questa firma con la chiave pubblica memorizzata nei record DNS del dominio. Se la firma corrisponde, viene dimostrato che l'e-mail proviene effettivamente dal dominio del mittente e che durante la trasmissione del messaggio non è stata apportata alcuna modifica.
Potete impostare la firma delle e-mail per il mailer direttamente nella configurazione. Se non usate la dependency injection, si usa in questo modo:
$signer = new Nette\Mail\DkimSigner(
domain: 'nette.org',
selector: 'dkim',
privateKey: file_get_contents('../dkim/dkim.key'),
passPhrase: '****',
);
$mailer = new Nette\Mail\SendmailMailer; // o SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);
Configurazione
Panoramica delle opzioni di configurazione per Nette Mail. Se non utilizzate l'intero framework, ma solo questa libreria, leggete come caricare la configurazione.
Per l'invio di e-mail si utilizza di default il mailer Nette\Mail\SendmailMailer, che non viene ulteriormente
configurato. Possiamo però passare a Nette\Mail\SmtpMailer:
mail:
# usa SmtpMailer
smtp: true # (bool) predefinito è false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
encryption: ... # (ssl|tls|null) predefinito è null (ha alias 'secure')
clientHost: ... # (string) predefinito è $_SERVER['HTTP_HOST']
persistent: ... # (bool) predefinito è false
# contesto per la connessione al server SMTP, predefinito è stream_context_get_default()
context:
ssl: # panoramica delle opzioni su https://www.php.net/manual/en/context.ssl.php
allow_self_signed: ...
...
http: # panoramica delle opzioni su https://www.php.net/manual/en/context.http.php
header: ...
...
Con l'opzione context › ssl › verify_peer: false è possibile disattivare la verifica dei certificati SSL.
Sconsigliamo vivamente di farlo, perché l'applicazione diventerebbe vulnerabile. Invece, aggiungete i certificati allo store.
Per aumentare l'affidabilità, possiamo firmare le e-mail utilizzando la tecnologia DKIM:
mail:
dkim:
domain: myweb.com
selector: lovenette
privateKey: %appDir%/cert/dkim.priv
passPhrase: ...
Servizi DI
Questi servizi vengono aggiunti al container DI:
| Nome | Tipo | Descrizione |
|---|---|---|
mail.mailer |
Nette\Mail\Mailer | classe che invia le e-mail |
mail.signer |
Nette\Mail\Signer | Firma DKIM |