Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending base64 emails with SWIFTMAIL

I am just trying to get my multipart emails encoded with base64 and send via swiftmail. Here is the code I have so far:

$message = Swift_Message::newInstance("Email Template Test")
    ->setBoundary($boundary)
    ->setFrom(array('[email protected]' => 'Mailer Service'))
    ->setTo(array("[email protected]","[email protected]"))
    ->setBody($plaintext)
    ->addPart($htmlmail,"text/html");

$headers = $message->getHeaders();
$headers->addTextHeader('Content-Transfer-Encoding','base64');

$contenttype = $message->getHeaders()->get('Content-Type');
$contenttype->setValue('multipart/alternative');

As far as I can see from the documentation (which I don't find too clear), The Content-Transfer-Encoding header is a text header, so i should be able to set it as above. Before this, I ran an output of all the current headers, and Content-Transfer-Encoding was not listed in there, so It needed to be set. Hence why in the above code I have tried to set it.

The output is fine, I get the emails, they work, but when I view source they are not encoded. I have tried with the same above code but changing $plaintext to base64_encode($plaintext), but just received the encoded message. How is it done>

like image 907
Chud37 Avatar asked Oct 20 '22 10:10

Chud37


1 Answers

In version 5.4 you can set the encoder. Otherwise Swift_Message will use the native encoder to encode the message.

$message = \Swift_Message::newInstance("Email Template Test");
$message->setEncoder(\Swift_Encoding::getBase64Encoding());
//...

Additionally there is a bug (as of version 4 and 5) with encoding and addPart. Where the MimePart will not inherit the encoding from the origin message. To do this you need to manually create the MimePart and attach it to the origin message.

$part = \Swift_MimePart::newInstance();
$part->setEncoder($message->getEncoder());
$part->setBody($htmlmail, 'text/html');
$message->attach($part);

This will automatically add the Content-Type: multipart/alternative; boundary=****, boundary charset and Content-Transfer-Encoding: base64 header information as well.

Result:

var_dump($message->toString());

string 'Message-ID: <[email protected]>
Date: Thu, 14 Jan 2016 20:45:30 +0000
Subject: Email Template Test
From: Mailer Service <[email protected]>
To: [email protected], [email protected]
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="_=_swift_v4_1452804330_b0a47ad936ba98d2f513294958a235d0_=_"


--_=_swift_v4_1452804330_b0a47ad936ba98d2f513294958a235d0_=_
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

VGhpcyBpcyBhbiBodG1sIG1lc3NhZ2U=

--_=_swift_v4_1452804330_b0a47ad936ba98d2f513294958a235d0_=_
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

VGhpcyBpcyBhIHRleHQgbWVzc2FnZQ==

--_=_swift_v4_1452804330_b0a47ad936ba98d2f513294958a235d0_=_--
' (length=751)

SwiftMailer 6

In swiftmailer 6 the Swift_Encoding class and ::newInstance() methods were removed.

The original usage of \Swift_Encoding::getBase64Encoding(), looked like

public static function getBase64Encoding()
{
    return self::_lookup('mime.base64contentencoder');
}


private static function _lookup($key)
{
    return Swift_DependencyContainer::getInstance()->lookup($key);
}

Therefor you can call the mime.base64contentencoder directly from the Swift_DependencyContainer instead.

$encoder = \Swift_DependencyContainer::getInstance()->lookup('mime.base64contentencoder');

$message = (new \Swift_Message("Email Template Test"))
    ->setEncoder($encoder);
like image 161
Will B. Avatar answered Oct 23 '22 06:10

Will B.