3
votes

I'm using swiftmailer to send emails and I would like to have the same attachment for : * HTML version (text/html) as inline image (cid) * Text version (text/plain) as attachment

I'm testing the email with Mozilla Thunderbird 45.3.0 on Ubuntu.

I've have been playing around with ->setBody, ->addPart, ->embed and ->attach methods, but I always broke one of the version (i.e. get the email in plain text either I view the message as HTML or Text).

My test code looks like (with valid SMTP address and file path of course) :

function swiftMail() {
    require_once './vendor/swiftmailer/swiftmailer/lib/swift_required.php';
    //Create the Transport
    $transport = Swift_SmtpTransport::newInstance('smtp.mail.com', 25);
    //Create the Mailer using your created Transport
    $mailer = Swift_Mailer::newInstance($transport);
    // Create the message
    $message = Swift_Message::newInstance()
        // Give the message a subject
        ->setSubject('SwiftMailer test // ' . uniqid('', true))
        // Set the From address with an associative array
        ->setFrom(array('[email protected]' => 'Me'))
        // Set the To addresses with an associative array
        ->setTo(array('[email protected]' => 'Me'));

    // attach the image as attachment
    $message->attach(Swift_Attachment::fromPath('./path/to/file.png')->setFilename('cool_image.png'));

    // set the email's body as plain text
    $message->setBody('My amazing body in plain text', 'text/plain');

    // add the email's HTML part to the message
    $message->addPart(
        '<!doctype html>' .
        '<html>' .
        ' <head><meta charset="UTF-8"></head>' .
        ' <body>' .
        '  Here is an image <br />'.
        '  <img src="' . $message->embed(Swift_Image::fromPath('./path/to/file.png')->setFilename('inline_cool_image.png')) . '" alt="Inline Image" /><br />' .
        '  Rest of message' .
        ' </body>' .
        '</html>',
        'text/html' // Mark the content-type as HTML
    );

    // send the message
    if (!$mailer->send($message, $failures))
    {
        echo "Failures:";
        print_r($failures);
    }
}

The following code result in two attachments (which could be fine) and only the plain text version available (which is not fine).

Is there a way to get attachments used as inline HTML image source and as standard attachment in plain text email ?

2

2 Answers

6
votes

I ran into the exact same problem and was able to fix it by adding the plaintext part with addPart() instead of setBody().

$message->addPart('My amazing body in plain text', 'text/plain');

Based on your example, it would be:

function swiftMail() {
    require_once './vendor/swiftmailer/swiftmailer/lib/swift_required.php';
    //Create the Transport
    $transport = Swift_SmtpTransport::newInstance('smtp.mail.com', 25);
    //Create the Mailer using your created Transport
    $mailer = Swift_Mailer::newInstance($transport);
    // Create the message
    $message = Swift_Message::newInstance()
        // Give the message a subject
        ->setSubject('SwiftMailer test // ' . uniqid('', true))
        // Set the From address with an associative array
        ->setFrom(array('[email protected]' => 'Me'))
        // Set the To addresses with an associative array
        ->setTo(array('[email protected]' => 'Me'));

    // attach the image as attachment
    $message->attach(Swift_Attachment::fromPath('./path/to/file.png')->setFilename('cool_image.png'));

    // set the email's body as plain text
    $message->addPart('My amazing body in plain text', 'text/plain');

    // add the email's HTML part to the message
    $message->addPart(
        '<!doctype html>' .
        '<html>' .
        ' <head><meta charset="UTF-8"></head>' .
        ' <body>' .
        '  Here is an image <br />'.
        '  <img src="' . $message->embed(Swift_Image::fromPath('./path/to/file.png')->setFilename('inline_cool_image.png')) . '" alt="Inline Image" /><br />' .
        '  Rest of message' .
        ' </body>' .
        '</html>',
        'text/html' // Mark the content-type as HTML
    );

    // send the message
    if (!$mailer->send($message, $failures))
    {
        echo "Failures:";
        print_r($failures);
    }
}

Tested with SwiftMailer version 5.4.4, Thunderbird 45.5.0 on macOS and the Gmail web interface.

0
votes

try adding ->setDisposition('inline') to your Swift_Image

Swift_Image::fromPath('./path/to/file.png')->setFilename('inline_cool_image.png')->setDisposition('inline')