PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Inline Grafiken in HTML E-Mails mit Zend_Mail automatisch versenden

with 4 comments

Ich (Ralf Eggert) stand neulich vor dem Problem, dass ich alle Grafiken in einer HTML E-Mail automatisch als Inline-Images identifizieren und dann an die E-Mail anhängen wollte. Die Grundidee zur Lösung des Problems ist es, mit einem regulären Ausdruck alle Grafiken zu finden und dann entsprechend anzuhängen. Beim Versand gab es ein paar Probleme, die ich zusammen mit Michaels Hilfe lösen konnte. Und genau deshalb findet ihr hier nun diesen kurzen Gastbeitrag.

Der Code unten zeigt ein komplettes lauffähiges Beispiel. Nach der Konfiguration wird auch gleich ein Zend_Mail Objekt erstellt und der HTML Bereich mit Inhalten bestückt. Über preg_match_all und array_filter werden alle Fundstellen in IMG Tags, im BACKGROUND Attribut sowie im Inline-CSS gefunden. Das Array mit den Ergebnissen wird dann durchlaufen. Abhängig davon, ob es sich um Grafiken auf dem Server oder externe Grafiken handelt, wird dann das entsprechende Attachment erstellt.

Zusätzlich muss im HTML Bereich der E-Mail auch jeweils der alte Verweis auf die Grafik durch den Verweis auf das Attachment ausgetauscht werden. Wichtig ist noch, dass der Typ der E-Mail auf Zend_Mime::MULTIPART_RELATED gesetzt wird. Danach kann der Versand erfolgen.

Ich hoffe, dieses Skript hilft dem einen oder anderen weiter.

<?php
set_include_path(implode(PATH_SEPARATOR, array(
	realpath(dirname(__FILE__) . '/library'),
	get_include_path(),
)));

date_default_timezone_set('Europe/Berlin');

require_once('Zend/Loader/Autoloader.php');
$autoloader = Zend_Loader_Autoloader::getInstance();

$mailSender = 'absender@domain.de';
$nameSender = 'Absender';
$mailRecipient = 'empfaenger@domain.de';
$nameRecipient = 'Empfaenger';
$mailSubject = 'Testmail mit inline img';
$htmlBody = '<b>html</b><br/><img src="sexy-sprite.png"><br/>
			<table background="error_messages.png"><tr><td>Zelle</td></tr></table>
			<br/><img src="http://www.fremdedomain.de/bild2.jpg">';
$textBody = 'text here';

// build mail
$mail = new Zend_Mail('UTF-8');
$mail->setFrom($mailSender, $nameSender);
$mail->addTo($mailRecipient, $nameRecipient);
$mail->setSubject($mailSubject);

// find images
preg_match_all('^url\((.*)\)|src="(.*)"|background="(.*)"^iU', $htmlBody, $imageList);

// combine findings
$imageList = array_filter(array_merge($imageList[1], $imageList[2], $imageList[3]));

// check image list
if (count($imageList) > 0) {
	// loop through image list
	foreach ($imageList as $key => $value) {
		if (substr($value, 0, 4) == 'http') {
			$filePath = 'img/' . basename($value);
			file_put_contents($filePath, file_get_contents($value));
		} else {
			$filePath = 'img/' . $value;
		}
		$fileName = basename($filePath);
		$fileType = getimagesize($filePath);

		// create attachment
		$att = $mail->createAttachment(file_get_contents($filePath));
		$att->type = $fileType['mime'];
		$att->disposition = Zend_Mime::DISPOSITION_INLINE;
		$att->encoding = Zend_Mime::ENCODING_BASE64;
		$att->filename = $fileName;
		$att->id = md5($att->filename);

		// change body
		$htmlBody = str_replace($imageList[$key], 'cid:'.$att->id, $htmlBody);
	}
}

$mail->setType(Zend_Mime::MULTIPART_RELATED);
$mail->setBodyText($textBody);
$mail->setBodyHtml($htmlBody);

$config = array('auth' 	=> 'login',
	'username' 	=> 'absender@domain.de',
	'password' 	=> 'SMTPPASSWORD');
$mail->send(new Zend_Mail_Transport_Smtp('mail.domain.de', $config));

Written by Ralf Eggert

Mai 6th, 2010 at 9:33 am

4 Responses to 'Inline Grafiken in HTML E-Mails mit Zend_Mail automatisch versenden'

Subscribe to comments with RSS or TrackBack to 'Inline Grafiken in HTML E-Mails mit Zend_Mail automatisch versenden'.

  1. Top!

    Genau das wollte ich heute nachrüsten. Gut dass ich noch nicht angefangen habe. 😉

    Danke!

    Otto

    6 Mai 10 at 21:34

  2. Danke Ralf! Hat mir sehr geholfen. PS: Habe dein Buch gelesen freu mich auf die zweite Auflage. Weiter so!

    Alex

    21 Sep 10 at 21:00

  3. Vielen Dank für den super Artikel!

    Anbei ein kleiner Verbesserungsvorschlag:
    Hab das ganze wie oben beschrieben umgesetzt. In meiner HTML-E-Mail kommen einige Grafiken mehrmals vor (5 x.gif Platzhalter). Eine davon wird in der Mail richtig gesetzt, die restlichen 4 zeigt mit Outlook als Attachment an, weil die Schleife versucht ein und die selbe Grafik mehrmals anzuhängen.

    Mit folgender Anpassung lässt sich das ganze recht einfach lösen:

    Vorher:
    $imageList = array_filter(array_merge($imageList[1], $imageList[2], $imageList[3]));

    Nachher:
    $imageList = array_filter(array_merge($imageList[1], $imageList[2], $imageList[3]));
    $imageList = array_unique($imageList);

    JBrooks

    22 Sep 10 at 10:49

  4. Whoa Dieser Blog sieht genau wie meine alte! Es ist auf eine ganz different subject, aber es hat so ziemlich das gleiche layout und Design.
    Ausstehende Wahl der Farben!

    Brustvergrößerung Vorher Nachhe

    12 Jan 13 at 19:21

Leave a Reply

You can add images to your comment by clicking here.