add inline image to a message sent with swiftmailer
Asked Answered
G

5

13

Please excuse my php but, Im using Swiftmailer to send emails from a clients website. They've requested to add an image or two as a signature etc and so looking at the swiftmailer spec here

http://swiftmailer.org/docs/messages.html

They suggest either adding an inline image like this

$message->embed(Swift_Image::fromPath('http://site.tld/image here'))

or like this(in 2 steps)

$cid = $message->embed(Swift_Image::fromPath('image here'));

then in the emails body section add

<img src="' . $cid . '" alt="Image" />'

Both steps ive tried but to no avail. When i hit the send email button, i get this error which i dont quite know what to make of it.

Call to a member function embed() on a non-object in /home/content/78/5152878/html/4testing/erase/ask-doc-proc2.php on line 89

The only thing i added to my already working code and email was the image code directly from the example in the docs pages. This error obviously prevents the email from being sent. if i remove it then it sends emails fine. Since i need to add an image to this,

Any help is greatly appreciated. Thank you

edit: this is the portion where the email is built and sent $cid= $message->embed(Swift_EmbeddedFile::fromPath('http://myforecyte.com/dev/pic.jpg'));

->setTo( $docEmail)

->setBody("Hello" . "\r\n\r\n" .  
$fullName . " has visited MyForeCYTE.com. Upon their visit they have requested to learn more about the test. \r\n\r\n" . 
"Please visit www.ClarityWomensHealth.com to find out more about The ForeCYTE Breast Health Test, or call our customer support line at 1 (877) 722-6339.  \r\n\r\n" .
"We look forward to hearing from you. \r\n\r\n" .
"Thank You," , 'text/plain')

->addPart("Hello" . ",</b><br/><br/>" . 
"<b>" . $fullName . "</b> has visited www.MyForeCYTE.com. Upon their visit they have requested to learn more about the test. <br/>" . 
"Please visit www.ClarityWomensHealth.com to find out more about The ForeCYTE Breast Health Test, or call our customer support line at 1 (877) 722-6339.<br/> " . 
"We look forward to hearing from you. <br/><br/><br/>" . "<img src='" . $cid. "' alt='pic'/>" .

"Thank you " , 'text/html')
;
Gatepost answered 21/3, 2013 at 0:51 Comment(19)
Since you are not showing the filename for image here, it's a bit hard to tell if it's properly formatted.Leucomaine
Can you show the complete code where you build the message?Thenceforward
What's on line 89 of ask-doc-proc2.php file?Leucomaine
To answer your questions @ Fred, the "image here" is "filename.jpg". As far as "whats on line 89, its this , " $cid = $message->embed(Swift_Image::fromPath('myforecyte.com/dev/Ariana_Perez.jpg')); "Gatepost
@Gatepost Have you tried adding http:// or if you're on www - http://www. before myforecyte.com?Leucomaine
Hi Fred, yep ive dont that but still the same message.Gatepost
Is http://myforecyte.com/dev/Ariana_Perez.jpg the file you wish to have displayed? If so, try making it all lowercase. Sometimes servers play mean tricks with file conventions as such. I'm picking at straws here I know, but am trying to go by process of elimination.Leucomaine
Have you done a var_dump( );?Leucomaine
No i appreciate it @Fred. I went ahead and changed "Ariana_Perez.jpg" to "pic.jpg" and nope, no good.Gatepost
Do a var_dump(); for $message and $cid and show the results.Leucomaine
When i do var_dump($message); or the same for cid, nothing prints on the page, i still get the same errorGatepost
Are all your paths set right? I'm baffled.Leucomaine
yeah i mean, im stumped too. The only path on the whole email is the one for the image which is this one 'myforecyte.com/dev/pic.jpg' ....im lost aswellGatepost
when i remove that line for the picture, the email sends fineGatepost
now since when doing var dump, since it doesnt show me anything , could that be a problem in its self?Gatepost
Maybe. From what I found so far about an empty var_dump result is and I quote "You most likely have html tags in your string that are being rendered by the browser." You may have single quotes where double quotes are required, hard to say. Are you headers set to send out as text/html?Leucomaine
What about display_errors, is it "on"?Leucomaine
i went ahead and added the rest of the code that handles the email buildGatepost
Ok. Well, one last resort. What's your PHP file(s) encoded as? If it's UTF-8, is it with or without the BOM? Am picking at another straw, but not leaving it out of the equation. I doubt it but worth a shot.Leucomaine
G
10

After all the running around i found an alternate solution. Swiftmailer allows 2 methods in which to perform the same thing.

one is the embed() function

and the other one is the attach() function

so to the code above, i removed the "embed()" since it wasn't working for me and added these 2 lines below and it works

    ->attach(Swift_Attachment::fromPath('path to image here.jpg')  
->setDisposition('inline'));

and it worked 100%

Gatepost answered 21/3, 2013 at 3:34 Comment(1)
you called it on $message like $message->attach(Swift_Attachment::fromPath('path to image here.jpg') ->setDisposition('inline')); ?Mouldon
L
8

None of the answers really worked for me. I had to include inline images, using CID. What I had to do, to make it work:

$attachment = Swift_Image::newInstance($data, $filename, $mimeType)
    ->setDisposition('inline');

$cid = $message->embed($attachment); // Generates "cid:something"

Important part is using Swift_Image class. Then the image in html should be:

<img src="cid:something" ... />

I think this solution works without doing something hacky with swiftmailer (ver. 5.4.2). It is exactly how the documentation says.

Remember to test multiple email clients (gmail, thunderbird, apple mail, web clients...) if the inline images work. For example using Swift_Attachment, inline images showed in gmail, but not in some web clients. Using Swift_Image, it worked everywhere.

Lyophilize answered 9/6, 2016 at 8:31 Comment(0)
V
6

The accepted answer doesn't work (version tested: 5.4.2). (Mine works but could be perfected)

Instead, looking inside the "Original" (Gmail: Show Original) I've found that swiftmailer is omitting adding 2 headers to the attachment, namely:

Content-ID: <ABC123>
X-Attachment-Id: ABC123

ABC123 is the cid we have to put in the body where we want the inline to be showed:

So thanks to this question: I found the way to fix it for swiftmailer (that is even against swiftmailer documentation, but it works while theirs do not)

this is the final (ugly) code:

$attachment = Swift_Attachment::fromPath('image.jpg')->setDisposition('inline');
$attachment->getHeaders()->addTextHeader('Content-ID', '<ABC123>');
$attachment->getHeaders()->addTextHeader('X-Attachment-Id', 'ABC123');
$cid = $message->embed($attachment);
$img = '<img src="cid:ABC123"/>';
$html = "
<html>
<head>
</head>
<body>
$img
</body>
</html>
";
$message->setBody($html, 'text/html');
Vomitory answered 19/5, 2016 at 23:54 Comment(2)
This is a working solution, thank you very much for this piece of code!Scissile
Thank you very much, working for me in Laravel 5.8. One thing - assigning to $cid is confusing, since you don't need this variable.Humidity
M
2

I know this is an old question (with an accepted answer), but for anyone having the same problem, the Swift_Image::fromPath($image_path) method expects the image path to be local (a filesystem path):

Swift_Image::fromPath("/local/path/to/image.jpg");
// Local path = great success

Thus the below will fail if your image path is external (starting with https://, etc.):

Swift_Image::fromPath("https://external.path/to/image.jpg");
// External path = epic fail

For external images, you should use:

# Load the image file
$data = file_get_contents($image_path);
# Get the filename
$filename = explode("?",basename($image_path))[0];
# Get the mime type
$finfo = new \finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->buffer($buffer);
# Load the image file
$image_file = new \Swift_Image($data, $filename, $mime_type);
# Set the disposition to inline
$image_file->setDisposition('inline');
Martimartial answered 20/7, 2020 at 15:25 Comment(0)
A
0

If you use laravel, try to add public_path() at the beginning of the path, e.g.:

<img src="<?php echo $message->embed(public_path().'/img/backend/name.jpg); ?>">
Asphalt answered 16/1, 2018 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.