Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display inline image attachments with wp_mail

I have a problem.

I would like to attach an image to an email and also display it inline, with some other php-generated content. The problem is I don't have the slightest ideea how to use inline a file attachment array used by wp_mail to attach.

My solution was to encode the images in base64 and put them inline the HTML like this:

<img alt="The Alt" src="data:image/png;base64,*etc*etc*etc" />

But the problem is that Gmail / Outlook remove the src data from the image. So it lands as

<img alt="The Alt" />

Any clues what to modify (headers to work with base64) or how to use attachment to embed them inline?

like image 278
Eek Avatar asked Mar 26 '13 19:03

Eek


4 Answers

I needed this in a small better way because I'm sending multiple mails in one step and not all mails should have the same embedded images. So I'm using this solution from Constantin but with my Modifications :-)

wp_mail('[email protected]', 'First mail without attachments', 'Test 1');

$phpmailerInitAction = function(&$phpmailer) {
    $phpmailer->AddEmbeddedImage(__DIR__ . '/img/header.jpg', 'header');
    $phpmailer->AddEmbeddedImage(__DIR__ . '/img/footer.png', 'footer');
};
add_action('phpmailer_init', $phpmailerInitAction);
wp_mail('[email protected]', 'Mail with embedded images', 'Example <img src="cid:header" /><br /><img src="cid:footer" />', [
    'Content-Type: text/html; charset=UTF-8'
], [
    __DIR__ . '/files/terms.pdf'
]);
remove_action('phpmailer_init', $phpmailerInitAction);

wp_mail('[email protected]', 'Second mail without attachments', 'Test 2');

The first wp_mail will be without attachments. The second wp_mail will contain embedded images. The third wp_mail will be without attachments.

It's working fine for now 😎

like image 96
Patrick Avatar answered Nov 07 '22 16:11

Patrick


wp_mail uses the PHPMailer class. This class has all the functionality needed for inline attachments. To change the phpmailer object before wp_mail() sends the email you could use the filter phpmailer_init.

$body = '
Hello John,
checkout my new cool picture.
<img src="cid:my-cool-picture-uid" width="300" height="400">

Thanks, hope you like it ;)';

That was an example of how to insert the picture in you email body.

$file = '/path/to/file.jpg'; //phpmailer will load this file
$uid = 'my-cool-picture-uid'; //will map it to this UID
$name = 'file.jpg'; //this will be the file name for the attachment

global $phpmailer;
add_action( 'phpmailer_init', function(&$phpmailer)use($file,$uid,$name){
    $phpmailer->SMTPKeepAlive = true;
    $phpmailer->AddEmbeddedImage($file, $uid, $name);
});

//now just call wp_mail()
wp_mail('[email protected]','Hi John',$body);

That's all.

like image 32
Constantin Avatar answered Nov 07 '22 14:11

Constantin


If you get an unexpected T_FUNCTION error, it is due to the PHP version < 5.3. In that case, create a function to do it in a more traditional way:

function attachInlineImage() {  
  global $phpmailer;  
  $file = '/path/to/file.jpg'; //phpmailer will load this file  
  $uid = 'my-cool-picture-uid'; //will map it to this UID  
  $name = 'file.jpg'; //this will be the file name for the attachment  
  if (is_file($file)) {  
    $phpmailer->AddEmbeddedImage($file, $uid, $name);  
  }  
}  

add_action('phpmailer_init','attachInlineImage');  
like image 24
Tomy Avatar answered Nov 07 '22 14:11

Tomy


I created this class to manage adding an image to email body and clean up after itself.

Also if you define SENDGRID_PASSWORD, it will use Sendgrid instead of your server to send emails

This article is a step by step guid on how to embed images in email body using wordpress

https://codewriteups.com/embed-images-in-email-body-using-wp_mail-and-phpmailer

<?php

/*
 * Send HTML Emails with inline images
 */
class Custom_Mailer
{
    public $email_attachments = [];

    public function send($to, $subject, $body, $headers, $attachments)
    {
        /* Used by "phpmailer_init" hook to add attachments directly to PHPMailer  */
        $this->email_attachments = $attachments;

        /* Setup Before send email */
        add_action('phpmailer_init', [$this, 'add_attachments_to_php_mailer']);
        add_filter('wp_mail_content_type', [$this, 'set_content_type']);
        add_filter('wp_mail_from', [$this, 'set_wp_mail_from']);
        add_filter('wp_mail_from_name', [$this, 'wp_mail_from_name']);
        
        /* Send Email */
        $is_sent = wp_mail($to, $subject, $body, $headers);
        
        /* Cleanup after send email */
        $this->email_attachments = [];
        remove_action('phpmailer_init', [$this, 'add_attachments_to_php_mailer']);
        remove_filter('wp_mail_content_type', [$this, 'set_content_type']);
        remove_filter('wp_mail_from', [$this, 'set_wp_mail_from']);
        remove_filter('wp_mail_from_name', [$this, 'wp_mail_from_name']);

        return $is_sent;
    }

    public function add_attachments_to_php_mailer(&$phpmailer)
    {
        $phpmailer->SMTPKeepAlive=true;
        
        /* Sendgrid */
        if (defined('SENDGRID_PASSWORD')) {
            $phpmailer->IsSMTP();
            $phpmailer->Host="smtp.sendgrid.net";
            $phpmailer->Port = 587;
            $phpmailer->SMTPAuth = true;
            $phpmailer->SMTPSecure = 'tls';
            $phpmailer->Username="apikey";
            $phpmailer->Password = SENDGRID_PASSWORD;   /* api key from sendgrid */
        }

        /* Add attachments to mail */
        foreach ($this->email_attachments as $attachment) {
            if (file_exists($attachment['path'])) {
                $phpmailer->AddEmbeddedImage($attachment['path'], $attachment['cid']);
            }
        }
    }

    public function set_content_type()
    {
        return "text/html";
    }
    
    public function set_wp_mail_from($email)
    {
        //Make sure the email is from the same domain
        //as your website to avoid being marked as spam.
        return strip_tags(get_option('admin_email'));
    }

    public function wp_mail_from_name($name)
    {
        return get_bloginfo('name');
    }
}

Usage:

/* Set mail parameters */
$to = '[email protected]';
$subject = 'Inline Img';
$body = '<h1>Image:</h1> <img src="cid:my_img_cid"/>';
$headers = "";
$my_attachments = [
    [
        "cid" => "my_img_cid", /* used in email body */
        "path" => plugin_dir_path(__FILE__) . '/my_img.png',
    ],
];

$custom_mailer = new Custom_Mailer();
$custom_mailer->send($to, $subject, $body, $headers, $my_attachments);
like image 1
Abdelrahman Maged Avatar answered Nov 07 '22 15:11

Abdelrahman Maged