[mod] Adding embedded images to emails

3rd party code for phpList

[mod] Adding embedded images to emails

Postby rjc » 7:17pm, Mon 06 Aug, 2007

I'd really like to see images added to a message (via the Add Image icon etc) embedded so they appear in people's email programs without them having to click "Show Images".

As discussed in my other post (see topic 10082 posted by rjc), images in the template are embedded and so show up in emails without any intervention. However, images added through the Add Image icon aren't embedded, and so most users will have to click "show images" in their email program to see what they are.
rjc
PL Nut
 
Posts: 28
Joined: 10:57pm, Mon 11 Dec, 2006

Postby rjc » 5:56pm, Fri 14 Sep, 2007

In case anyone is wondering, I worked out how to embed images in the content section into emails. :lol:


IN admin/class.phplistmailer.php

AFTER:
$this->find_html_images($templateid);

ADD:
// RJC ADDED
$this->find_html_images($html);
// END RJC ADDED
rjc
PL Nut
 
Posts: 28
Joined: 10:57pm, Mon 11 Dec, 2006

thanks

Postby lola4 » 2:38pm, Thu 27 Sep, 2007

Thanks. Yes, it works now.
lola4
phpList newbie
 
Posts: 1
Joined: 2:36pm, Thu 27 Sep, 2007

Postby Roderic » 4:39pm, Thu 27 Sep, 2007

Let's assume I got a prepared HTML-message I'd like to send, with references to images. Where do I put these or how exactly do I include them?

Rod
Roderic
phpLister
 
Posts: 6
Joined: 12:48pm, Wed 13 Dec, 2006

Embedding images in content

Postby KerryO » 3:02pm, Wed 03 Oct, 2007

I, too, would love to be able to do this. I added the code, but still can't get it to work. RJC, could you give a step-by-step for us newbies?
KerryO
phpLister
 
Posts: 5
Joined: 9:58pm, Tue 02 Oct, 2007

Postby rjc » 6:19am, Thu 04 Oct, 2007

There's been a couple of requests to do a step-by-step, so here we go. First, I assume you've made the changes to the code as detailed in my post above...

The next step is to add images. Before images can be used in emails, they must be uploaded to the server. Roderic in his post posed the question of links to external images (ie an image on your or another website, referenced by an img url link); however, a link to an image on a website doesn't seem to work with this method, as it is still not embedded.

I'm using FCKeditor, and assume you are the same (it's the default).

The correct way to add an image is:

1) Log in to phplist Administration
2) Click on the "Send A Message" link on the right-hand side menu
3) In the phplist - Send A Message page, make sure you are on the "Content" tab.
4) In the text area, type your message, and then click wherever you want the image inserted
5) Click on the "Insert/Edit Image" icon (the picture of the mountains with the sun shining in the yellow sky), above the text area (just below the B [Bold] icon).
6) A window will pop up called Image Properties. Simply putting a url here will not do the job; what you need to do is to click the "Browse Server" button on the right-hand side.
(If you can't see the Browse Server button, make sure you have specified a folder in your config.php {admin/config/config.php} in the line:
Code: Select all
define("FCKIMAGES_DIR","uploadimagesdir");   //note your name may be different. Mine is uploadimagesdir
and that exact folder name actually exists on your server {in your phplist folder; e.g. phplist/uploadimagesdir}, set with permissions of either 755 or 777, whatever works for you; other knowledgebase articles talk about this).
7) A second window will pop up, showing all images uploaded to your special folder on the server. If you have not done this before, it will be empty.
8 ) Down the bottom of this window, it says "Upload a new file into this folder", with a Browse button. Click the Browse button, find the file on your computer, and click OK. Then click the "Upload" button on the far right to upload it to your server.
9) After it's uploaded, click on it's name in the window, and it will close the window and return the information to the Image Properties window.
10) Type in an Alternative Text, describing the picture, set other options (e.g. set Align to either left or right to wrap text around the image so it doesn't look odd...)
11) Click OK
12) When you send the message, the image should be embedded in the email.
rjc
PL Nut
 
Posts: 28
Joined: 10:57pm, Mon 11 Dec, 2006

Postby rjc » 4:23pm, Fri 05 Oct, 2007

Oh No! I've found that my work-around doesn't actually work for many cases! :cry:

Please ignore my post immediately above... I now have a way that will embed files even if they're not uploaded through the method described above.

My first method worked... as long as that file had been uploaded somewhere as a file included in a template. Silly me to test using photos from an old template! It did NOT work for any "fresh-out-of-the-box" photos. A few more changes were needed, after spending MANY :x hours trying to work out what's going on!

For completeness, I will list the whole thing again in this post. Ignore my previous posts.


In admin/class.phplistmailer.php

Change 1:

AFTER:
Code: Select all
$this->find_html_images($templateid);


ADD:
Code: Select all
$this->find_html_images($html);   // Not actually sure if this is needed; I'll leave it in for now because it's almost 3:00am


Change 2:

REPLACE:
Code: Select all
for($i=0; $i<count($images[1]); $i++){
  if($this->image_exists($templateid,$images[1][$i])){
    $html_images[] = $images[1][$i];
    $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
  }
}


WITH:

Code: Select all
for($i=0; $i<count($images[1]); $i++){
  $html_images[] = $images[1][$i];
  $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
}


Change 3:

AFTER:
Code: Select all
$this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);


ADD:
Code: Select all
} else {
  $content=file_get_contents($html_images[$i],FALSE,NULL);
  $content = base64_encode($content);
  $content_type = $this->image_types[substr($html_images[$i], strrpos($html_images[$i], '.') + 1)];
  $cid = $this->add_html_image($content, basename($html_images[$i]), $content_type);
  $this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);


The php function file_get_contents can read non-file-system images (ie images off a website), so images don't actually have to be uploaded, unlike what I said in my previous post.

My apologies to all those who tried the first fix without success. This one seems to now work fine in my tests.

Onwards phplist! May you incorporate all the fixes and enhancements that are provided amidst hours of relentless and infuriating code-searching!
rjc
PL Nut
 
Posts: 28
Joined: 10:57pm, Mon 11 Dec, 2006

Postby rjc » 5:20pm, Fri 05 Oct, 2007

Just in case I didn't make myself clear, all you should have to do is reference an image in your html with eg an img tag (or let phplist do it for you by using the "Insert/Edit Image" button underneath the "B" icon, and the fix above should take care of actually getting the file off the internet location wherever it is and embedding it in your email.
rjc
PL Nut
 
Posts: 28
Joined: 10:57pm, Mon 11 Dec, 2006

Postby KerryO » 8:05pm, Fri 05 Oct, 2007

Hi RJC,
Thanks very much for working on this. It took me forever just to figure out how to get rid of that ugly orange bar at the bottom of my messages, so I can't imagine trying to figure out something so complicated as what you're doing. I couldn't get it to work last night with your first fix, though I did learn not to put "xxxxxxxx" in my test e-mail. I kept wondering why my test e-mails said "success" in phplist, but didn't arrive in my mailbox. I finally figured out the spam filter for my ISP zapped it, thinking those x's were x-rated. When I changed "xxxxxxxx" to "blah blah blah" it worked fine. I better be careful when I list the shirt sizes for our track club and put "extra extra extra large" instead of XXX-Lg!

Anyway, I tried the second fix. I'm getting boxes and a red x, and it's not asking me to download the images, but neither is it showing them in the e-mail. I'm choosing the pictures from an image uploaded to the server in my "uploadimages" file. I've attached my modified class.phplistmailer.php file. Maybe I didn't make the changes properly? Thanks very much for your help.
KerryO
phpLister
 
Posts: 5
Joined: 9:58pm, Tue 02 Oct, 2007

Postby tauno » 2:21am, Wed 17 Oct, 2007

KerryO wrote:
Anyway, I tried the second fix. I'm getting boxes and a red x, and it's not asking me to download the images, but neither is it showing them in the e-mail.


Same here, it didn't work. But then I changed the
Code: Select all
$content=file_get_contents($html_images[$i],FALSE,NULL);


to
Code: Select all
$content=file_get_contents($html_images[$i],FILE_BINARY);

and it works perfect.
tauno
phpList newbie
 
Posts: 3
Joined: 2:14am, Wed 17 Oct, 2007

Postby KerryO » 2:05am, Fri 19 Oct, 2007

Okay, I'm back to try and work on this puzzle. Tauno, could you save me a lot of time and tell me what file that code is located in so I can change it? It's not in my class.phplistmailer.php. Also, for RJC's change #3, my code looks a little different in that it has
Code: Select all
$this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);#@@@
          }
        }
      }
    }
Do I add the new code inbetween the semi-colon and the #sign after the last Body)? I did that and now it looks like this:

Code: Select all
if(!empty($html_images)){
        // If duplicate images are embedded, they may show up as attachments, so remove them.
        $html_images = array_unique($html_images);
        sort($html_images);
        for($i=0; $i<count>get_template_image($templateid,$html_images[$i])){
            $content_type = $this->image_types[substr($html_images[$i], strrpos($html_images[$i], '.') + 1)];
            $cid = $this->add_html_image($image, basename($html_images[$i]), $content_type);
            $this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);
} else {
$content=file_get_contents($html_images[$i],FALSE,NULL);
$content = base64_encode($content);
$content_type = $this->image_types[substr($html_images[$i], strrpos($html_images[$i], '.') + 1)];
$cid = $this->add_html_image($content, basename($html_images[$i]), $content_type);
$this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);



#@@@
          }
        }
      }
    }

This is harder than when I took two semesters of Russian in high school. Thanks for your help!
KerryO
phpLister
 
Posts: 5
Joined: 9:58pm, Tue 02 Oct, 2007

Postby KerryO » 11:17am, Fri 19 Oct, 2007

Also - RJC, I tried to substitute the class.phplistmailer.php file you sent me, but then it gave me an error code and wouldn't even let me log in. I only recently installed phplist so I should think my version is current. I don't know why the file swap didn't work, but thanks for sending it along for me to try.
KerryO
phpLister
 
Posts: 5
Joined: 9:58pm, Tue 02 Oct, 2007

Postby tauno » 1:33pm, Fri 19 Oct, 2007

KerryO wrote:Okay, I'm back to try and work on this puzzle. Tauno, could you save me a lot of time and tell me what file that code is located in so I can change it? It's not in my class.phplistmailer.php.


?? It is still in the same file - class.phplistmailer.php. I did all the modifications as per RJC + I changed one of his lines:
Code: Select all
$content=file_get_contents($html_images[$i],FALSE,NULL);

to read
Code: Select all
$content=file_get_contents($html_images[$i],FILE_BINARY);


I am attaching the whole file, so there is no mistake. This file came initially from ver. 2.10.5 and contains all required modifications.

***edit by tauno ***
I can't attach the file for some reason, I'll send it to you directly.

****edit end
tauno
phpList newbie
 
Posts: 3
Joined: 2:14am, Wed 17 Oct, 2007

Postby KerryO » 3:16pm, Fri 19 Oct, 2007

It worked! Hooray! RJC & Tauno - thanks for all your good encoding work, and for your patience with people like me who don't speak the language :D
KerryO
phpLister
 
Posts: 5
Joined: 9:58pm, Tue 02 Oct, 2007

Not sure what I am doing wrong!

Postby wahahey » 11:17am, Tue 23 Oct, 2007

This obviously works - but for some reason I can't get it to! I've followed all the instructions...

Could someone please have a look at my class.phplistmailer.php (below)? - I am a complete novice and would really appreciate any help you can give. I haven't done the latest upgrade yet, but seeing as this post was started a while ago I figure I don't need to in order to get this to work?

Code: Select all
<php> 'image/gif',
                  'jpg'  => 'image/jpeg',
                  'jpeg'  => 'image/jpeg',
                  'jpe'  => 'image/jpeg',
                  'bmp'  => 'image/bmp',
                  'png'  => 'image/png',
                  'tif'  => 'image/tiff',
                  'tiff'  => 'image/tiff',
                  'swf'  => 'application/x-shockwave-flash'
                  );

    function PHPlistMailer($messageid,$email) {
    #  parent::PHPMailer();
      parent::SetLanguage('en','phpmailer/language/');
      $this->addCustomHeader("X-Mailer: phplist v".VERSION);
      $this->addCustomHeader("X-MessageID: $messageid");
      $this->addCustomHeader("X-ListMember: $email");
      $this->addCustomHeader("Precedence: bulk");
      $this->Host = PHPMAILERHOST;
      $this->Helo = getConfig("website");
      $this->CharSet = getConfig("html_charset");
      if (isset($GLOBALS['phpmailer_smtpuser']) && $GLOBALS['phpmailer_smtpuser'] != '') {
        $this->SMTPAuth = true;
        $this->Username = $GLOBALS['phpmailer_smtpuser'];
        $this->Password = $GLOBALS['phpmailer_smtppassword'];
#        logEvent('Sending authenticated email via '.PHPMAILERHOST);
      }
      $ip = gethostbyname($this->Host);
      if ($GLOBALS["message_envelope"]) {
        $this->Sender = $GLOBALS["message_envelope"];
        $this->addCustomHeader("Errors-To: ".$GLOBALS["message_envelope"]);
      }
      if (!$this->Host || $ip == $this->Host) {
        $this->Mailer = "mail";
#        logEvent('Sending via mail');
      } else {
        $this->Mailer = "smtp";
#        logEvent('Sending via smtp');
      }
    }

    function add_html($html,$text = '',$templateid = 0) {
      $this->Body = $html;
      $this->IsHTML(true);
      if ($text) {
        $this->add_text($text);
      }
      $this->find_html_images($templateid);
      $this->find_html_images($html);
    }
     
     
    function add_text($text) {
      if (!$this->Body) {
        $this->IsHTML(false);
        $this->Body = html_entity_decode($text ,ENT_QUOTES, 'UTF-8' ); #$text;
#        $this->Body = $text;
       } else {
        $this->AltBody = html_entity_decode($text ,ENT_QUOTES, 'UTF-8' );#$text;
      }
    }

    function append_text($text) {
      if ($this->AltBody) {
        $this->AltBody .= html_entity_decode($text ,ENT_QUOTES, 'UTF-8' );#$text;
      } else {
        $this->Body .= html_entity_decode($text ,ENT_QUOTES, 'UTF-8' );#$text;
      }
    }

    function build_message() {
    }

    function send($to_name = "", $to_addr, $from_name, $from_addr, $subject = '', $headers = '',$envelope = '') {
      $this->From = $from_addr;
      $this->FromName = $from_name;
      if (strstr(VERSION, "dev")) {
        # make sure we are not sending out emails to real users
        # when developing
        $this->AddAddress($GLOBALS["developer_email"]);
      } else {
        $this->AddAddress($to_addr);
      }
      $this->Subject = $subject;
      if(!parent::Send()) {
        #echo "Message was not sent <p>";
        logEvent("Mailer Error: " . $this->ErrorInfo);
        return 0;
      }#
      return 1;
    }

    function add_attachment($contents,$filename,$mimetype) {
      // Append to $attachment array
      $cur = count($this->attachment);
      $this->attachment[$cur][0] = chunk_split(base64_encode($contents), 76, $this->LE);
      $this->attachment[$cur][1] = $filename;
      $this->attachment[$cur][2] = $filename;
      $this->attachment[$cur][3] = $this->encoding;
      $this->attachment[$cur][4] = $mimetype;
      $this->attachment[$cur][5] = false; // isStringAttachment
      $this->attachment[$cur][6] = "attachment";
      $this->attachment[$cur][7] = 0;
    }

     function find_html_images($templateid) {
      #if (!$templateid) return;
      // Build the list of image extensions
      while(list($key,) = each($this->image_types))
        $extensions[] = $key;

      preg_match_all('/"([^"]+\.('.implode('|', $extensions).'))"/Ui', $this->Body, $images);

for($i=0; $i<count>Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
}

      if(!empty($html_images)){
        // If duplicate images are embedded, they may show up as attachments, so remove them.
        $html_images = array_unique($html_images);
        sort($html_images);
        for($i=0; $i<count>get_template_image($templateid,$html_images[$i])){
            $content_type = $this->image_types[substr($html_images[$i], strrpos($html_images[$i], '.') + 1)];
            $cid = $this->add_html_image($image, basename($html_images[$i]), $content_type);
            $this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);
            } else {
  $content=file_get_contents($html_images[$i],FILE_BINARY);
  $content = base64_encode($content);
  $content_type = $this->image_types[substr($html_images[$i], strrpos($html_images[$i], '.') + 1)];
  $cid = $this->add_html_image($content, basename($html_images[$i]), $content_type);
  $this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);
            #@@@
          }
        }
      }
    }

    function add_html_image($contents, $name = '', $content_type='application/octet-stream') {
      // Append to $attachment array
      $cid = md5(uniqid(time()));
      $cur = count($this->attachment);
      $this->attachment[$cur][0] = $contents;
      $this->attachment[$cur][1] = '';#$filename;
      $this->attachment[$cur][2] = $name;
      $this->attachment[$cur][3] = $this->encoding;
      $this->attachment[$cur][4] = $content_type;
      $this->attachment[$cur][5] = false; // isStringAttachment
      $this->attachment[$cur][6] = "inline";
      $this->attachment[$cur][7] = $cid;

      return $cid;
    }

    function image_exists($templateid,$filename) {
      $req = Sql_Query(sprintf('select * from %s where template = %d and (filename = "%s" or filename = "%s")',
        $GLOBALS["tables"]["templateimage"],$templateid,$filename,basename($filename)));
      return Sql_Affected_Rows();
    }

     function get_template_image($templateid,$filename){
      $req = Sql_Fetch_Row_Query(sprintf('select data from %s where template = %d and (filename = "%s" or filename = "%s")',
        $GLOBALS["tables"]["templateimage"],$templateid,$filename,basename($filename)));
      return $req[0];
    }

    function EncodeFile ($path, $encoding = "base64") {
      # as we already encoded the contents in $path, return $path
      return chunk_split($path, 76, $this->LE);
    }
}
wahahey
phpList newbie
 
Posts: 2
Joined: 11:06am, Tue 23 Oct, 2007

Next

Return to Contributions: Plug-ins, Add-ons, Mods

Who is online

Users browsing this forum: No registered users and 1 guest