Invio di e-mail
Stai 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
Scarica e installa la libreria utilizzando Composer:
composer require nette/mail
Creazione di un'e-mail
L'e-mail è un oggetto della classe Nette\Mail\Message. La 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 te. 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 inviare 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 invii 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 usi le e-mail insieme a Nette Application, cioè con i presenter, potresti 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 puoi ottenerlo facendotelo 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 puoi accedere facendotelo 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 vuoi impostare returnPath
e il server continua a sovrascriverlo, usa
$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 perssl
timeout
– 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.
Puoi impostare la firma delle e-mail per il mailer direttamente nella configurazione. Se non usi 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 utilizzi l'intero framework, ma solo questa libreria, leggi 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, aggiungi 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 |