Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Mail

Invio
Email

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 per ssl
  • timeout – timeout per la connessione SMTP
  • persistent – usare una connessione persistente
  • clientHost – impostazione dell'header Host del client
  • streamOptions – 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
versione: 4.0