Mail

Invio
Email

Invio di e-mail

Avete intenzione di inviare e-mail come newsletter o conferme d'ordine? Nette Framework fornisce gli strumenti necessari con un'API molto bella. Vi mostreremo:

  • come creare un'e-mail, compresi gli allegati
  • come inviarla
  • come combinare e-mail e modelli

Installazione

Scaricare e installare il pacchetto utilizzando Composer:

composer require nette/mail

Creazione di e-mail

L'e-mail è un oggetto Nette\Mail\Message:

$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('peter@example.com')
	->addTo('jack@example.com')
	->setSubject('Order Confirmation')
	->setBody("Hello, Your order has been accepted.");

Tutti i parametri devono essere codificati in UTF-8.

Oltre a specificare i destinatari con il metodo addTo(), è possibile specificare il destinatario della copia con addCc(), o il destinatario della copia cieca con addBcc(). Tutti questi metodi, compreso setFrom(), accettano il destinatario in tre modi:

$mail->setFrom('john.doe@example.com');
$mail->setFrom('john.doe@example.com', 'John Doe');
$mail->setFrom('John Doe <john.doe@example.com>');

Il corpo di un messaggio di posta elettronica scritto in HTML viene passato con il metodo setHtmlBody():

$mail->setHtmlBody('<p>Hello,</p><p>Your order has been accepted.</p>');

Non è necessario creare un testo alternativo, Nette lo genererà automaticamente per voi. E se l'email non ha un oggetto impostato, questo verrà preso dall'elemento <title> elemento.

Anche le immagini possono essere inserite con estrema facilità nel corpo HTML di un'e-mail. Basta passare il percorso in cui si trovano fisicamente le immagini come secondo parametro e Nette le includerà automaticamente nell'e-mail:

// aggiunge automaticamente /path/to/images/background.gif all'email
$mail->setHtmlBody(
	'<b>Ciao</b> <img src="background.gif">',
	'/path/to/images',
);

L'algoritmo di incorporamento delle immagini supporta i seguenti 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?

Le e-mail sono come cartoline. Non inviate mai password o altre credenziali via e-mail.

Allegati

Naturalmente è possibile allegare allegati alle e-mail. Utilizzate l'indirizzo addAttachment(string $file, string $content = null, string $contentType = null).

// inserisce il file /path/to/example.zip nella mail con il nome example.zip
$mail->addAttachment('/path/to/example.zip');

// inserisce il file /path/to/example.zip nell'e-mail con il nome info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// Allega il nuovo contenuto del file example.txt "Hello John!".
$mail->addAttachment('example.txt', 'Hello John!');

Modelli

Se inviate e-mail in HTML, è un'ottima idea scriverle nel sistema di template Latte. Come fare?

$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',
	);

File email.latte:

<html>
<head>
	<meta charset="utf-8">
	<title>Order Confirmation</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>Hello,</p>

	<p>Your order number {$orderId} has been accepted.</p>
</body>
</html>

Nette inserisce automaticamente tutte le immagini, imposta l'oggetto in base all'elemento <title> e genera un testo alternativo per il corpo dell'HTML.

Utilizzo nell'applicazione Nette

Se utilizzate i messaggi di posta elettronica insieme all'applicazione Nette, ad esempio i presentatori, potreste voler creare dei collegamenti nei modelli utilizzando l'attributo n:href o il tag {link}. Latte fondamentalmente non li conosce, ma è molto facile aggiungerli. La creazione di collegamenti può essere fatta con l'oggetto Nette\Application\LinkGenerator, che si ottiene passandoglielo con la 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, il collegamento viene creato come in un normale template. Tutti i collegamenti creati con LinkGenerator sono assoluti:

<a n:href="Presenter:action">Link</a>

Invio di e-mail

Mailer è la classe responsabile dell'invio delle e-mail. Implementa l'interfaccia Nette\Mail\Mailer e sono disponibili diversi mailer già pronti, che presenteremo.

Il framework aggiunge automaticamente al contenitore DI un servizio Nette\Mail\Mailer basato sulla configurazione, che si ottiene passandoglielo 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 si vuole impostare returnPath e il server lo sovrascrive comunque, usare $mailer->commandArgs = '-fmy@email.com'.

SmtpMailer

Per inviare posta tramite il server SMTP, utilizzare 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 i seguenti parametri aggiuntivi:

  • port – se non impostato, verrà utilizzato il valore predefinito 25 o 465 per ssl
  • timeout – timeout per la connessione SMTP
  • persistent – utilizzare una connessione persistente
  • clientHost – designazione del client
  • streamOptions – permette di impostare le opzioni del contesto SSL per la connessione

FallbackMailer

Non invia i messaggi di posta elettronica, ma li invia attraverso un insieme di mailer. Se un mailer fallisce, ripete il tentativo con quello successivo. Se l'ultimo fallisce, ricomincia dal primo.

$mailer = new Nette\Mail\FallbackMailer([
	$smtpMailer,
	$backupSmtpMailer,
	$sendmailMailer,
]);
$mailer->send($mail);

Altri parametri del costruttore sono il numero di ripetizioni e il tempo di attesa in millisecondi.

DKIM

DKIM (DomainKeys Identified Mail) è una tecnologia di posta elettronica affidabile che aiuta anche a rilevare i messaggi falsificati. Il messaggio inviato viene firmato con la chiave privata del dominio del mittente e questa firma viene memorizzata nell'intestazione dell'e-mail. Il server del destinatario confronta questa firma con la chiave pubblica memorizzata nei record DNS del dominio. La corrispondenza della firma dimostra che l'e-mail proviene effettivamente dal dominio del mittente e che il messaggio non è stato modificato durante la trasmissione.

È possibile impostare il mailer per firmare le e-mail nella configurazione. Se non si usa l'iniezione di dipendenza, si usa come segue:

$signer = new Nette\Mail\DkimSigner(
	domain: 'nette.org',
	selector: 'dkim',
	privateKey: file_get_contents('../dkim/dkim.key'),
	passPhrase: '****',
);

$mailer = new Nette\Mail\SendmailMailer; // or SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);

Configurazione di

Panoramica delle opzioni di configurazione di Nette Mail. Se non si utilizza l'intero framework, ma solo questa libreria, leggere come caricare la configurazione.

Per impostazione predefinita, per l'invio delle e-mail viene utilizzato il mailer Nette\Mail\SendmailMailer, che non viene ulteriormente configurato. Tuttavia, è possibile passare a Nette\Mail\SmtpMailer:

mail:
	# usa SmtpMailer
	smtp: true       # (bool) predefinito a false

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) predefinito a null (ha l'alias 'secure')
	clientHost: ...  # (string) predefinito a $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) predefinito a false

	# contesto per la connessione al server SMTP, predefinito con stream_context_get_default()
	context:
		ssl:         # tutte le opzioni a https://www.php.net/manual/en/context.ssl.php
			allow_self_signed: ...
			...
		http:        # tutte le opzioni in https://www.php.net/manual/en/context.http.php
			header: ...
			...

È possibile disabilitare l'autenticazione del certificato SSL utilizzando l'opzione context › ssl › verify_peer: false. Si consiglia vivamente di non farlo**, in quanto renderebbe l'applicazione vulnerabile. Invece, aggiungere certificati all'archivio di fiducia.

Per aumentare l'affidabilità, è possibile 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 contenitore DI:

Nome Tipo Descrizione
mail.mailer Nette\Mail\Mailer classe di invio email
mail.signer Nette\Mail\Signer Firma DKIM
versione: 4.0