My Notes

September 21, 2008

Inline images into HTML email with Zend Framework

Filed under: Zend Framework — Tags: , — davidnussio @ 9:32 am

I’m lerning zend framework and I’m looking for a way to send HTML email with inline images.
Some times ago I used http://ez.no/ezcomponents Mail class to do this, but now I’m using Zend Framework and I want use only the last one. After look into the Zend API/Manual, I checkout from svn ZendFramework and ezcomponent to take idea, the result is:

<?php
error_reporting(E_ALL);
$paths = explode(PATH_SEPARATOR, get_include_path());
$paths&#91;&#93; = dirname(dirname(dirname(dirname(__FILE__)))) . '/library';
set_include_path(implode(PATH_SEPARATOR, $paths));

require_once 'Zend/Loader.php';
require_once 'Zend/Mail.php';

class Demo_Zend_Mail_InlineImages extends Zend_Mail
{
    public function buildHtml()
    {
        // Important, without this line the example don't work!
        // The images will be attached to the email but these will be not
        // showed inline
        $this->setType(Zend_Mime::MULTIPART_RELATED);

        $matches = array();
        preg_match_all("#<img.*?src=&#91;'\"&#93;file://(&#91;^'\"&#93;+)#i",
                       $this->getBodyHtml(true),
                       $matches);
        $matches = array_unique($matches[1]);

        if (count($matches ) > 0) {
            foreach ($matches as $key => $filename) {
                if (is_readable($filename)) {
                    $at = $this->createAttachment(file_get_contents($filename));
                    $at->type = $this->mimeByExtension($filename);
                    $at->disposition = Zend_Mime::DISPOSITION_INLINE;
                    $at->encoding = Zend_Mime::ENCODING_BASE64;
                    $at->id = 'cid_' . md5_file($filename);
                    $this->setBodyHtml(str_replace('file://' . $filename,
                                       'cid:' . $at->id,
                                       $this->getBodyHtml(true)),
                                       'UTF-8',
                                       Zend_Mime::ENCODING_8BIT);
                }
            }
        }
    }

    public function mimeByExtension($filename)
    {
        if (is_readable($filename) ) {
            $extension = pathinfo($filename, PATHINFO_EXTENSION);
            switch ($extension) {
                case 'gif':
                    $type = 'image/gif';
                    break;
                case 'jpg':
                case 'jpeg':
                    $type = 'image/jpg';
                    break;
                case 'png':
                    $type = 'image/png';
                    break;
                default:
                    $type = 'application/octet-stream';
            }
      }

      return $type;
  }
}

$mail = new Demo_Zend_Mail_InlineImages();
$mail->setBodyText('Pure text message...');
$mail->setBodyHtml('<b>Test</b> '
                   . 'Text... ... <img src="file://photo.png" alt="" /> ...
'
                   . 'Text... <img src="file://photo2.png" alt="" />
',
                   'UTF-8',
                   Zend_Mime::MULTIPART_RELATED);
$mail->setFrom('somebody@example.com', 'Some Sender');
$mail->addTo('david@example.com', 'Some Recipient');
$mail->setSubject('Test Subject');
$mail->buildHtml();
$mail->send();

I write this file (InlineImages.php) into ZendFramework/demos/Zend/Mail/, I putted two images photo.png and photo2.png in the same directory and I tested using command line: php InlineImages.php

I want to improve this code to be able to pass different protocol instead file://, for example like http://.

Zend Framework
Site: framework.zend.com
API: http://framework.zend.com/apidoc/core/
Manual: http://framework.zend.com/manual/en/

ezcomponet
Site: http://ez.no/ezcomponents
mail class docs: http://ezcomponents.org/docs/tutorials/Mail

Ciao

Advertisements

8 Comments »

  1. You’re pretty close to having any protocol supported… Since PHP supports streams (file://, http://, etc…), relative paths and absolute paths, all you have to do is remove the file:// from your regex and grab the entire filename specified in the src attribute for the image tags. From there, PHP will handle it without any problems within file_get_contents(). You’ll also obviously have to change your str_replace() line to accomodate for the fact that you’re no longer searching for file://. That’s where a little bit of extra work will be needed to get the filename path (minus the file:// part) and put cid: before it.

    I’ve actually been inspired by your work here since I was looking to do the exact same thing, and I’ve taken your idea and made it much better with a few code fixes, as well as by overriding the setBodyHtml() function instead of creating a new function.

    Comment by Eli Sand — April 28, 2009 @ 11:26 pm

  2. Great work, I’ve been using Zend Mail for a long time, and this makes MIME emails so much easier!

    Comment by Chris — May 30, 2011 @ 9:41 am

  3. Will the above code work with high volume email?

    I just discovered PHP mail() is unreliable when sending high volume email which I need to do (I am not spamming but allowing schools to communicate with their parents).

    I was directed to Zend but have read somewhere that I should be using an SMTP_Relay. I found my hosting provider limits me to 250 emails per day (the alternative is extremely costly). The above code doesn’t appear to use an SMTP relay (or does it?). Is the above routine reliable for high volume email?

    Comment by rihallix — January 20, 2012 @ 4:47 am

  4. […] the Zend Framework developers there is a faster way.  I’ve implemented the code developed by David Nussio in the following […]

    Pingback by Inserting images in email with Zend Framework | Zend Developer — February 1, 2012 @ 10:59 pm

  5. you should get content of html body like this

    $zend_mime_part = $this->getBodyHtml();
    $html = quoted_printable_decode($zend_mime_part->getContent());

    Comment by Nariman — March 7, 2012 @ 7:38 am

  6. Great Work! thank you

    Comment by bilge — May 12, 2012 @ 10:16 am

  7. Helped a lot, thank you

    Comment by Mad Yoga — January 24, 2013 @ 4:51 pm

  8. The code is quite interesting. It really helped.
    Thank you!

    Comment by Ekta Gupta — August 11, 2015 @ 10:13 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: