ZF : envoyer des images embarquées dans un mail

Dans mon précédent article, je vous ai présenté comment envoyer un mail avec une pièce jointe. Dans la même ligné, je vais vous montrer ici comment envoyer des pièces jointes en ligne.

Qu’est qu’une pièce jointe embarquée ?

Le principe est d’attacher le fichier directement à l’intérieur du mail. Si vous créer un lien interne vers ce fichier, vous ne le verrez alors pas en tant que pièce jointe à télécharger. Ce système présente des avantages comme des inconvénients.

La principale utilisation est l’inclusion des fichiers images directement dans le mail habituellement insérées par des liens distants. Voici une liste non exhaustive des avantages et inconvénients de l’insertion d’image distantes face l’insertion dans le mail.

Prenons l’exemple d’un mail contenant 4ko de contenu HTML et 100ko d’images.

Image embarquée Image distante
Avantages
  • image disponible hors ligne une fois le mail téléchargé.
  • certain de voir les images à l’ouverture (pas de blocage).
  • le mail est plus léger, les images étant distantes, seul 4ko sont téléchargés sur votre boite mail.
Inconvénients
  • le poids du mail peut devenir conséquent (ex: 104ko), prenant donc de la place dans la boite.
  • la plupart des lecteurs de mails récents bloquent les images distantes à l’ouverture.
  • les images ne sont pas disponibles si la lecture du mail se fait hors ligne.

Le plus contraignent est la lourdeur du mail lorsqu’on y inclue les images. Les serveurs de mails limites généralement la taille des mails et la taille de la boite mail. Attention à ne pas trop abuser de ce type d’envoi. En outre, vous êtes certain que le lecteur verra les images sans cliquer sur l’avertissement habituel (d’après mes quelques tests).

En pratique

Bon, après cette mise au point, il est temps de toucher un peu de code. Je vais pour le moment simplement récupérer le code de mon précédent article et le transformer.

Rappel du code précédent :

$mail = new Zend_Mail('utf-8');
$mail->setSubject('Test d'envoi de mail simple')
	->addTo('destinataire@domaine.tld')
	->setFrom('expediteur@domaine.tld', 'Blount') // expéditeur
	->setBodyText('Contenu du corp du mail au format text.'); // message du mail

$pdf = new Zend_Mime_Part(file_get_contents(dirname(__FILE__).'/newsletter.pdf'));
$pdf->type = 'application/pdf';
$pdf->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
$pdf->encoding = Zend_Mime::ENCODING_BASE64;
$pdf->filename = 'newsletter.pdf';
$mail->addAttachment($pdf);

$mail->send();

Tout d’abord, nous allons changer le type du mail. Pour l’envoi d’une pièce jointe, nous utilisions « multipart/mixed », mais si vous souhaitez référencer les fichiers joints (src, href), il faut utiliser « multipart/related ». Pour cela on utilise la constante appropriée :

$mail->setType(Zend_Mime::MULTIPART_RELATED);

Maintenant que nous pouvons créer des liens vers les fichiers joints, nous allons devoir spécifier un identifiant au fichier. Celui-ci sera utilisé pour cibler le fichier. Nous ajoutons donc cette ligne :

$pdf->id = $mail->createMessageId();

La méthode « createMessageId » s’occupe de créer un identifiant unique en utilisant différents paramètres (nom de domaine, etc.).

Maintenant que nous avons l’identifiant, nous pouvons l’utiliser dans le corp HTML. Voici un exemple :

$mail->setBodyHtml('<a href="cid:'.$pdf->id.'">
    Voir la newsletter au format PDF</a>', 'UTF-8');

Il faut bien mettre cid: suivit de l’ID du fichier à cibler. Sinon, le lien ne fonctionnera pas.

Et c’est tout. Voici le code complet, avec les modifications surlignées :

$mail = new Zend_Mail('utf-8');
$mail->setSubject('Test d'envoi de mail simple')
	->addTo('destinataire@domaine.tld')
	->setFrom('expediteur@domaine.tld', 'Blount') // expéditeur
	->setBodyText('Contenu du corp du mail au format text.') // message du mail
	->setType(Zend_Mime::MULTIPART_RELATED); // changement du type

$pdf = new Zend_Mime_Part(file_get_contents(dirname(__FILE__).'/newsletter.pdf'));
$pdf->id = $mail->createMessageId(); // ID du fichier
$pdf->type = 'application/pdf';
$pdf->disposition = Zend_Mime::DISPOSITION_INLINE;
$pdf->encoding = Zend_Mime::ENCODING_BASE64;
$pdf->filename = 'newsletter.pdf';
$mail->addAttachment($pdf);

// contenu HTML
$mail->setBodyHtml('<a href="cid:'.$pdf->id.'">Voir la newsletter au format PDF</a>', 'UTF-8');

$mail->send();

C’est simple d’utilisation.

Nous allons maintenant remplacer le texte du lien par une image. Nous allons prendre une icône PDF :

Nous créons donc notre pièce jointe :

$image = new Zend_Mime_Part(file_get_contents(dirname(__FILE__).'/icone-pdf.png'));
$image->id = $mail->createMessageId(); // ID du fichier
$image->type = 'image/png';
$image->disposition = Zend_Mime::DISPOSITION_INLINE;
$image->encoding = Zend_Mime::ENCODING_BASE64;
$image->filename = 'icone-pdf.png';
$mail->addAttachment($image);

Ensuite, nous modifions le contenu HTML pour y ajouter l’image :

$mail->setBodyHtml('<a href="cid:'.$pdf->id.'">
	<img src="cid:'.$image->id.'" alt="Voir la newsletter au format PDF"
	 title="Voir la newsletter au format PDF" border="0" /></a>', 'UTF-8');

Toujours sans oublier le cid: dans l’attribut « src ».

De nouveau, je vous met le code complet avec les modifications surlignées :

$mail = new Zend_Mail('utf-8');
$mail->setSubject('Test d'envoi de mail simple')
	->addTo('destinataire@domaine.tld')
	->setFrom('expediteur@domaine.tld', 'Blount') // expéditeur
	->setBodyText('Contenu du corp du mail au format text.') // message du mail
	->setType(Zend_Mime::MULTIPART_RELATED); // changement du type

$pdf = new Zend_Mime_Part(file_get_contents(dirname(__FILE__).'/newsletter.pdf'));
$pdf->id = $mail->createMessageId(); // ID du fichier
$pdf->type = 'application/pdf';
$pdf->disposition = Zend_Mime::DISPOSITION_INLINE;
$pdf->encoding = Zend_Mime::ENCODING_BASE64;
$pdf->filename = 'newsletter.pdf';
$mail->addAttachment($pdf);

$image = new Zend_Mime_Part(file_get_contents(dirname(__FILE__).'/icone-pdf.png'));
$image->id = $mail->createMessageId(); // ID du fichier
$image->type = 'image/png';
$image->disposition = Zend_Mime::DISPOSITION_INLINE;
$image->encoding = Zend_Mime::ENCODING_BASE64;
$image->filename = 'icone-pdf.png';
$mail->addAttachment($image);

// contenu HTML
$mail->setBodyHtml('<a href="cid:'.$pdf->id.'">
	<img src="cid:'.$image->id.'" alt="Voir la newsletter au format PDF"
	 title="Voir la newsletter au format PDF" border="0" /></a>', 'UTF-8');

$mail->send();

Et voila le travail.

Conclusion

C’est vraiment simple à utiliser une fois que le principe est compris. Mais n’oubliez pas, le mail peut devenir très lourd, alors utilisez cette technique seulement si vous êtes sur de ce que vous faites.

Si vous rencontrez un problème, ou une erreur dans l’article, ou tout autre chose, n’hésitez pas à me les communiquer via les commentaires.

6 réflexions au sujet de « ZF : envoyer des images embarquées dans un mail »

  1. Bonjour à tous
    Merci pour ce très bon spot. Je suis débutant et j’apprécie vraiment vos explications et vos exemples de codes.
    Bravo
    Francis

  2. Arf, merci.
    Habituellement, je les détecte, je ne sais pas comment il a fait pour passer à travers du filet (Akismet et moi).
    Au moins, ils sont propres ces spams ^^

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Notifiez-moi des commentaires à venir via email. Vous pouvez aussi vous abonner sans commenter.