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

Mail

Envoi de
Emails

Envoi d'e-mails

Vous vous apprêtez à envoyer des e-mails, par exemple des newsletters ou des confirmations de commande ? Nette Framework fournit les outils nécessaires avec une API très agréable. Nous allons vous montrer :

  • comment créer un e-mail, y compris les pièces jointes
  • comment l'envoyer
  • comment combiner e-mails et templates

Installation

Vous pouvez télécharger et installer la bibliothèque à l'aide de Composer :

composer require nette/mail

Création d'un e-mail

L'e-mail est un objet de la classe Nette\Mail\Message. Créons-le comme ceci :

$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
	->addTo('petr@example.com')
	->addTo('jirka@example.com')
	->setSubject('Confirmation de commande')
	->setBody("Bonjour,\nvotre commande a été acceptée.");

Tous les paramètres saisis doivent être en UTF-8.

En plus d'indiquer le destinataire avec la méthode addTo(), vous pouvez également indiquer le destinataire en copie addCc(), ou le destinataire en copie cachée addBcc(). Dans toutes ces méthodes, y compris setFrom(), nous pouvons écrire l'adresse de trois manières :

$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');

Le corps de l'e-mail écrit en HTML est transmis via la méthode setHtmlBody() :

$mail->setHtmlBody('<p>Bonjour,</p><p>votre commande a été acceptée.</p>');

Vous n'avez pas besoin de créer l'alternative texte, Nette la générera automatiquement pour vous. Et si l'e-mail n'a pas de sujet défini, il essaiera de le récupérer à partir de l'élément <title>.

Il est également extraordinairement facile d'insérer des images dans le corps HTML. Il suffit de passer le chemin où se trouvent physiquement les images comme deuxième paramètre, et Nette les inclura automatiquement dans l'e-mail :

// ajoute automatiquement /path/to/images/background.gif à l'e-mail
$mail->setHtmlBody(
	'<b>Bonjour</b> <img src="background.gif">',
	'/path/to/images',
);

L'algorithme d'insertion d'images recherche ces motifs : <img src=...>, <body background=...>, url(...) à l'intérieur de l'attribut HTML style et la syntaxe spéciale [[...]].

L'envoi d'e-mails peut-il être encore plus simple ?

Un e-mail est comme une carte postale. N'envoyez jamais de mots de passe ou d'autres informations d'identification par e-mail.

Pièces jointes

Il est bien sûr possible d'ajouter des pièces jointes à l'e-mail. La méthode addAttachment(string $file, ?string $content = null, ?string $contentType = null) est utilisée à cet effet.

// insère le fichier /path/to/example.zip dans l'e-mail sous le nom example.zip
$mail->addAttachment('/path/to/example.zip');

// insère le fichier /path/to/example.zip nommé info.zip dans l'e-mail
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// insère le fichier example.txt avec le contenu "Bonjour John !" dans l'e-mail
$mail->addAttachment('example.txt', 'Bonjour John !');

Templates

Si vous envoyez des e-mails HTML, il est naturel de les écrire dans le système de templates Latte. Comment faire ?

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

Fichier email.latte :

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

	<p>Votre commande numéro {$orderId} a été acceptée.</p>
</body>
</html>

Nette insère automatiquement toutes les images, définit le sujet en fonction de l'élément <title> et génère une alternative texte au HTML.

Utilisation dans Nette Application

Si vous utilisez les e-mails conjointement avec Nette Application, c'est-à-dire avec des presenters, vous voudrez peut-être créer des liens dans les templates en utilisant l'attribut n:href ou la balise {link}. Latte ne les connaît pas par défaut, mais il est très facile de les ajouter. L'objet Nette\Application\LinkGenerator, capable de créer des liens, peut être obtenu en le demandant via l'injection de dépendances :

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;
	}
}

Dans le template, nous créons ensuite les liens comme nous en avons l'habitude. Tous les liens créés via LinkGenerator seront absolus.

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

Envoi de l'e-mail

Mailer est la classe responsable de l'envoi des e-mails. Elle implémente l'interface Nette\Mail\Mailer et plusieurs mailers pré-faits sont disponibles, que nous allons présenter.

Le framework ajoute automatiquement au conteneur DI un service de type Nette\Mail\Mailer construit sur la base de la configuration, auquel vous pouvez accéder en le demandant via l'injection de dépendances.

SendmailMailer

Le mailer par défaut est SendmailMailer, qui utilise la fonction PHP mail. Exemple d'utilisation :

$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);

Si vous souhaitez définir le returnPath et que votre serveur le réécrit constamment, utilisez $mailer->commandArgs = '-fmon@email.fr'.

SmtpMailer

Pour envoyer du courrier via un serveur SMTP, utilisez SmtpMailer.

$mailer = new Nette\Mail\SmtpMailer(
	host: 'smtp.gmail.com',
	username: 'franta@gmail.com',
	password: '*****',
	encryption: 'ssl',
);
$mailer->send($mail);

Les paramètres supplémentaires suivants peuvent être passés au constructeur :

  • port – s'il n'est pas défini, le port par défaut 25 ou 465 pour ssl sera utilisé
  • timeout – timeout pour la connexion SMTP
  • persistent – utiliser une connexion persistante
  • clientHost – définir l'en-tête Host du client
  • streamOptions – permet de définir les options de contexte SSL pour la connexion

FallbackMailer

Il n'envoie pas directement les e-mails, mais relaie l'envoi via un ensemble de mailers. Si un mailer échoue, il réessaie avec le suivant. Si le dernier échoue également, il recommence depuis le premier.

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

Comme paramètres supplémentaires dans le constructeur, nous pouvons indiquer le nombre de tentatives et le temps d'attente en millisecondes.

DKIM

DKIM (DomainKeys Identified Mail) est une technologie visant à accroître la fiabilité des e-mails, qui aide également à détecter les messages falsifiés. Le message envoyé est signé avec la clé privée du domaine de l'expéditeur et cette signature est stockée dans l'en-tête de l'e-mail. Le serveur du destinataire compare cette signature avec la clé publique stockée dans les enregistrements DNS du domaine. Si la signature correspond, cela prouve que l'e-mail provient réellement du domaine de l'expéditeur et qu'il n'a pas été modifié pendant la transmission.

Vous pouvez configurer la signature des e-mails pour le mailer directement dans la configuration. Si vous n'utilisez pas l'injection de dépendances, elle est utilisée de cette manière :

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

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

Configuration

Aperçu des options de configuration pour Nette Mail. Si vous n'utilisez pas l'ensemble du framework, mais seulement cette bibliothèque, lisez comment charger la configuration.

Pour l'envoi d'e-mails, le mailer Nette\Mail\SendmailMailer est utilisé par défaut, qui n'est pas configuré davantage. Cependant, nous pouvons le basculer vers Nette\Mail\SmtpMailer :

mail:
	# utilise SmtpMailer
	smtp: true       # (bool) la valeur par défaut est false

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) la valeur par défaut est null (a l'alias 'secure')
	clientHost: ...  # (string) la valeur par défaut est $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) la valeur par défaut est false

	# contexte pour la connexion au serveur SMTP, la valeur par défaut est stream_context_get_default()
	context:
		ssl:         # aperçu des options sur https://www.php.net/manual/fr/context.ssl.php
			allow_self_signed: ...
			...
		http:        # aperçu des options sur https://www.php.net/manual/fr/context.http.php
			header: ...
			...

Avec l'option context › ssl › verify_peer: false, vous pouvez désactiver la vérification des certificats SSL. Nous déconseillons fortement de le faire, car l'application deviendrait vulnérable. Ajoutez plutôt les certificats au magasin.

Pour augmenter la fiabilité, nous pouvons signer les e-mails en utilisant la technologie DKIM :

mail:
	dkim:
		domain: myweb.com
		selector: lovenette
		privateKey: %appDir%/cert/dkim.priv
		passPhrase: ...

Services DI

Ces services sont ajoutés au conteneur DI :

Nom Type Description
mail.mailer Nette\Mail\Mailer classe envoyant les e-mails
mail.signer Nette\Mail\Signer signature DKIM
version: 4.0