base64 encoding

woober

Member
Hi!
Is it possible to encode email body via base64 (all html and plain text) using mailwizz?
Or is there any workaround?
For example, I can see "Delivery server -> PHP Mail" option and if I can place some php-script on the server or somewhere... so.... mailwizz will try to delivery emails via this php-script which will just encode html body to base64 and change MIME type - somethink like that
 
I have just created this extension. Install it from Backend -> Extend -> Extensions and enable it then send a test email/campaign.
When that extension is enabled, it will hook into the sending process and will alter the sending params by encoding in base64 the email body.
If you need to change the extension, it will be uploaded in apps/extensions folder in a folder named encode-email-body.
If you take a look in that folder and open the only file inside, this is the part that matters:
PHP:
 public function run()
    {
        Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
            $params['body']      = base64_encode($params['body']);
            $params['plainText'] = base64_encode($params['plainText']);
            return $params;
        });
    }
As an example, if you only need to apply this for servers of type PHP Mail, then your code will look like:
PHP:
 public function run()
    {
        Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
            if ($server->type == 'php-email') {
                $params['body']      = base64_encode($params['body']);
                $params['plainText'] = base64_encode($params['plainText']);
            }
            return $params;
        });
    }
P.S: I haven't tested the extension, it's meant as a starting point anyway.
Thanks.
 
I have just created this extension. Install it from Backend -> Extend -> Extensions and enable it then send a test email/campaign.
When that extension is enabled, it will hook into the sending process and will alter the sending params by encoding in base64 the email body.
If you need to change the extension, it will be uploaded in apps/extensions folder in a folder named encode-email-body.
If you take a look in that folder and open the only file inside, this is the part that matters:
PHP:
public function run()
    {
        Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
            $params['body']      = base64_encode($params['body']);
            $params['plainText'] = base64_encode($params['plainText']);
            return $params;
        });
    }
As an example, if you only need to apply this for servers of type PHP Mail, then your code will look like:
PHP:
public function run()
    {
        Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
            if ($server->type == 'php-email') {
                $params['body']      = base64_encode($params['body']);
                $params['plainText'] = base64_encode($params['plainText']);
            }
            return $params;
        });
    }
P.S: I haven't tested the extension, it's meant as a starting point anyway.
Thanks.
Yeap! this script encode plain text and html, But it doesn't work normally, Mail Provider can not decrypt(unencode) base64 text to normal text, because of mailwizz header content-transfer-encoding.
I mean, If I send email with body "Hi there", then on gmail I can not see this text, I see encoded text "SGkgdGhlcmU="

See my test email headers:
PHP:
--_=_swift_v4_1425465606_d17665d8e7f4321e30abcad14e18916d_=_
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable  <------ !!!!! --- I THINK THIS IS WRONG HEADER

0JrQvtGC0LXQvdC+0LosINC60LDQuiDRgtGLINC/0L7QttC40LLQsNC10YjRjD8=3D

--_=_swift_v4_1425465606_d17665d8e7f4321e30abcad14e18916d_=_
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit     <------ !!!!! --- I THINK THIS IS WRONG HEADER

PCFET0NUWVBFIGh0bWw+CjxodG1sPjxoZWFkPjx0aXRsZT48L3RpdGxlPjxtZXRhIG5hbWU9ImNoYXJzZXQiIGNvbnRlbnQ9InV0Zi04Ij48L2hlYWQ+PGJvZHk+CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgPGNlbnRlcj4mIzEwNTA7JiMxMDg2OyYjMTA5MDsmIzEwNzc7JiMxMDg1OyYjMTA4NjsmIzEwODI7LCAmIzEwODI7JiMxMDcyOyYjMTA4MjsgJiMxMDkwOyYjMTA5OTsgJiMxMDg3OyYjMTA4NjsmIzEwNzg7JiMxMDgwOyYjMTA3NDsmIzEwNzI7JiMxMDc3OyYjMTA5NjsmIzExMDA7PzwvY2VudGVyPjxpbWcgd2lkdGg9IjEiIGhlaWdodD0iMSIgc3JjPSJodHRwOi8vcnVtYWlsc2VuZGVyLnJ1L2luZGV4LnBocC9jYW1wYWlnbnMvd3AxMTY0dzFvYzFkZS90cmFjay1vcGVuaW5nL25iOTQ0Nzk5OWQ1MzEiIGFsdD0iIiAvPgo8L2JvZHk+PC9odG1sPgo=

--_=_swift_v4_1425465606_d17665d8e7f4321e30abcad14e18916d_=_--
I think this will work normally if both headers will be
Content-Transfer-Encoding: base64
But how can I change them via you script...thats the good question for me =))
 
Okay, i assume we can add one more hook and try something like this:
Open the file: "apps/common/components/mailer/MailerSwiftMailer.php" and at line 368, in the setMessage method, you have this line:
PHP:
return $this;

make it:
PHP:
$this->_message = Yii::app()->hooks->applyFilters('mailer_after_create_message_instance', $message, $params->toArray(), $this);              
return $this;
And save your file.

Next, open the file "apps/extensions/encode-email-body/EncodeEmailBodyExt.php" and make the run() method look like:
PHP:
public function run()
{
    Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
        $params['body'] = base64_encode($params['body']);
        $params['onlyPlainText'] = true;
        Yii::app()->hooks->addFilter('mailer_after_create_message_instance', function($message, $params, $mailer){
            if ($mailer instanceof MailerSwiftMailer) {
                $message->setChildren(array());
                $message->setEncoder(Swift_Encoding::getBase64Encoding());
                $message->setBody($params['body'], 'text/plain', Yii::app()->charset);
            }
            return $message;
        });
        return $params;
    });
}
and try again, maybe this time it's more luck.
 
Okay, i assume we can add one more hook and try something like this:
Open the file: "apps/common/components/mailer/MailerSwiftMailer.php" and at line 368, in the setMessage method, you have this line:
PHP:
return $this;

make it:
PHP:
$this->_message = Yii::app()->hooks->applyFilters('mailer_after_create_message_instance', $message, $params->toArray(), $this);             
return $this;
And save your file.

Next, open the file "apps/extensions/encode-email-body/EncodeEmailBodyExt.php" and make the run() method look like:
PHP:
public function run()
{
    Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
        $params['body'] = base64_encode($params['body']);
        $params['onlyPlainText'] = true;
        Yii::app()->hooks->addFilter('mailer_after_create_message_instance', function($message, $params, $mailer){
            if ($mailer instanceof MailerSwiftMailer) {
                $message->setChildren(array());
                $message->setEncoder(Swift_Encoding::getBase64Encoding());
                $message->setBody($params['body'], 'text/plain', Yii::app()->charset);
            }
            return $message;
        });
        return $params;
    });
}
and try again, maybe this time it's more luck.
Yeap, I can see that for now header contain "Content-Transfer-Encoding: base64" text but situation is the same =(
Moreover for now mailwizz make double-encode text: text "Hi there" ->encoded to "SGkgdGhlcmU=" ->encoded second time to "U0drZ2RHaGxjbVU9".
And for now headers doesn't contain sections with text (or encoded text)
Content-Type: text/plain; charset=utf-8
...........
Content-Type: text/html; charset=utf-8
...........
 
Moreover for now mailwizz make double-encode text: text "Hi there" ->encoded to "SGkgdGhlcmU=" ->encoded second time to "U0drZ2RHaGxjbVU9".
What if you delete this line from the extension file:
PHP:
$params['body'] = base64_encode($params['body']);
?
 
What if you delete this line from the extension file:
PHP:
$params['body'] = base64_encode($params['body']);
?
Yes, for now double-encoding problem is solved, but html is displaying like plaintext. I mean something like that:
PHP:
<!DOCTYPE html>
<html><head><title></title><meta name="charset" content="utf-8"></head><body>
            <div style="text-align:center;">&#1050;&#1086;&#1090;&#1077;&#1085;&#1086;&#1082;, &#1082;&#1072;&#1082; &#1090;&#1099; &#1087;&#1086;&#1078;&#1080;&#1074;&#1072;&#1077;&#1096;&#1100;?</div><img width="1" height="1" src="http://domain/index.php/campaigns/od624e4aa61d5/track-opening/oq7182t49sdf6" alt="" />
</body></html>
&#1050; - cyrillic symbols which are displaying as text.
Moreover, I can not see plain text section in header, maybe because
PHP:
$params['onlyPlainText'] = true;
 
That's the tricky part because this part of code:
PHP:
$message->setChildren(array());
$message->setEncoder(Swift_Encoding::getBase64Encoding());
$message->setBody($params['body'], 'text/plain', Yii::app()->charset);
Resets pretty much everything and puts back the body as plain text.

You could remove $params['onlyPlainText'] = true; and then change the above in:
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding());
$message->setBody($params['body'], 'text/html', Yii::app()->charset);

If that ain't work either, then disable this extension, and in the MailerSwiftMailer.php look for:
PHP:
$message->setEncoder(Swift_Encoding::get8BitEncoding());
and transform it into:
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding());

If none will work, i'm kind of out of idea :D
 
That's the tricky part because this part of code:
PHP:
$message->setChildren(array());
$message->setEncoder(Swift_Encoding::getBase64Encoding());
$message->setBody($params['body'], 'text/plain', Yii::app()->charset);
Resets pretty much everything and puts back the body as plain text.

You could remove $params['onlyPlainText'] = true; and then change the above in:
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding());
$message->setBody($params['body'], 'text/html', Yii::app()->charset);

If that ain't work either, then disable this extension, and in the MailerSwiftMailer.php look for:
PHP:
$message->setEncoder(Swift_Encoding::get8BitEncoding());
and transform it into:
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding());

If none will work, i'm kind of out of idea :D
I didn't try to add
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding());
$message->setBody($params['body'], 'text/html', Yii::app()->charset);
But changed
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding());
and it works!!! (extention disabled for now) For now HTML version of email encoded via base64.
But plaintext version is the still
PHP:
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Moreover if I check doesn't send plaintext version it still sends.:) Maybe I broke some code. I mean, I don't want to send plaintext version, but I can see Content-Type: text/plain; charset=utf-8 section in header. Maybe I should reinstall Mailwizz...:eek:
 
In this case things are simple.

1. Undo the changes you did in MailerSwiftMailer.php file.
2. Download the attached archive, extract it and upload the resulted file in apps/common/components/mailer folder.
3. Go to Backend -> Settings -> Common and for the SystemMailer select "My Swiftmailer" instead of "Swiftmailer"
4. If you don't want to send plain text at all, edit the newsly uploaded file and at line 152 you have:
PHP:
$message->addPart($plainText, 'text/plain', Yii::app()->charset);
make it:
PHP:
// $message->addPart($plainText, 'text/plain', Yii::app()->charset);

Basically what we do above is to create a custom mailer that extends from the default one and override the setMessage method so that we add a custom encoder ($message->setEncoder(Swift_Encoding::getBase64Encoding())) and optionally to disable sending plain text emails.

At any time when you don't want to use this mailer, simply change it from settings.
 

Attachments

  • MailerMySwiftMailer.zip
    2 KB · Views: 24
In this case things are simple.

1. Undo the changes you did in MailerSwiftMailer.php file.
2. Download the attached archive, extract it and upload the resulted file in apps/common/components/mailer folder.
3. Go to Backend -> Settings -> Common and for the SystemMailer select "My Swiftmailer" instead of "Swiftmailer"
4. If you don't want to send plain text at all, edit the newsly uploaded file and at line 152 you have:
PHP:
$message->addPart($plainText, 'text/plain', Yii::app()->charset);
make it:
PHP:
// $message->addPart($plainText, 'text/plain', Yii::app()->charset);

Basically what we do above is to create a custom mailer that extends from the default one and override the setMessage method so that we add a custom encoder ($message->setEncoder(Swift_Encoding::getBase64Encoding())) and optionally to disable sending plain text emails.

At any time when you don't want to use this mailer, simply change it from settings.
I've uploaded your php file to apps/common/components/mailer, but I can not see "My Swiftmailer" in the list, I can see only Swiftmailser, PHP Mailer, DummyMailer -that's all. Tryed to restart apache - nothing changed.
 
Riiiigghtttt...
Okay, one more step of coding for you:
Create the file apps/common/components/mailer/MyMailer.php and put this into it:
PHP:
<?php if ( ! defined('MW_PATH')) exit('No direct script access allowed');

class MyMailer extends Mailer
{
    protected function getMailers()
    {
        if ($this->_mailers !== null && $this->_mailers instanceof CMap) {
            return $this->_mailers;
        }  
     
        parent::getMailers();
     
        $this->_mailers->mergeWith(array(
            'MySwiftMailer' => array(
                'class'   => 'common.components.mailer.MailerMySwiftMailer',
            ),
        ));
     
        return $this->_mailers;
    }
 
}

Next, open apps/common/config/main-custom.php, it looks like:
PHP:
return array(

    // application components
    'components' => array(
        'db' => array(
            'connectionString'  => 'mysql:host=localhost;dbname=aaa',
            'username'          => 'aaa',
            'password'          => 'aaa',
            'tablePrefix'       => '',
        ),
    ),
);

and you need to overload the mailer component, so make it look like:
PHP:
return array(

    // application components
    'components' => array(
        'db' => array(
            'connectionString'  => 'mysql:host=localhost;dbname=aaa',
            'username'          => 'aaa',
            'password'          => 'aaa',
            'tablePrefix'       => '',
        ),
        'mailer' => array(
            'class' => 'common.components.mailer.MyMailer',
        ),
    ),
);
So all you have to do is to add:
PHP:
'mailer' => array(
            'class' => 'common.components.mailer.MyMailer',
        ),
in the right place.
After doing the above, check your backend -> settings -> common.

Please note that we're doing the following just to avoid any problems when you update mailwizz :)
Thanks.

P.S: I've edited the code since i have posted it first time.
 
Last edited:
I've created MyMailer.php in apps/common/components/mailer/ , copy-pasted your text in it.
Then in apps/common/config/main-custom.php this section looks like
PHP:
......
return array(

    // application components
    'components' => array(
        'db' => array(
            'connectionString'  => 'mysql:host=localhost;dbname=DBNAME',
            'username'          => 'DBUSER',
            'password'          => 'DBPASSWORD',
            'tablePrefix'       => 'DBPREFIX',
        ),
        'mailer' => array(
            'class' => 'common.components.mailer.MyMailer',
        ),
    ),
);
But unfortunately I still can not see it in the list...:(.
Your original file "MailerMySwiftMailer.php" still placed in apps/common/components/mailer/
 
I've edited my code a bit, did you get the updated version?
it's about the first part, changed from:
PHP:
$this->_mailers->add(array(
    'MySwiftMailer' => array(
        'class'   => 'common.components.mailer.MailerMySwiftMailer',
    ),
));

to

PHP:
$this->_mailers->mergeWith(array(
    'MySwiftMailer' => array(
        'class'   => 'common.components.mailer.MailerMySwiftMailer',
    ),
));


Your original file "MailerMySwiftMailer.php" still placed in apps/common/components/mailer/
That's okay, it should be there.
 
I've edited my code a bit, did you get the updated version?
it's about the first part, changed from:
PHP:
$this->_mailers->add(array(
    'MySwiftMailer' => array(
        'class'   => 'common.components.mailer.MailerMySwiftMailer',
    ),
));

to

PHP:
$this->_mailers->mergeWith(array(
    'MySwiftMailer' => array(
        'class'   => 'common.components.mailer.MailerMySwiftMailer',
    ),
));



That's okay, it should be there.
Yes, for now I can see My SwiftMailer in the list, I checked it in Common settings as default mailer, but it doesn't encode text. =)
I can see in your file "MailerMySwiftMailer.php" that it's contain
PHP:
$message->setEncoder(Swift_Encoding::getBase64Encoding()); // THIS CHANGED
But if this line ($message->setEncoder(Swift_Encoding::getBase64Encoding()) present in main mailer "MailerSwiftMailer.php" it work fine (encode email)
 
Hello @twisted1919,
You can upload the file to the dropbox again, I want to add the file to Extension, to use too encode-email-body.
Thank you.

I have just created this extension. Install it from Backend -> Extend -> Extensions and enable it then send a test email/campaign.
When that extension is enabled, it will hook into the sending process and will alter the sending params by encoding in base64 the email body.
If you need to change the extension, it will be uploaded in apps/extensions folder in a folder named encode-email-body.
If you take a look in that folder and open the only file inside, this is the part that matters:
PHP:
 public function run()
    {
        Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
            $params['body']      = base64_encode($params['body']);
            $params['plainText'] = base64_encode($params['plainText']);
            return $params;
        });
    }
As an example, if you only need to apply this for servers of type PHP Mail, then your code will look like:
PHP:
 public function run()
    {
        Yii::app()->hooks->addFilter('delivery_server_before_send_email', function($params, $server) {
            if ($server->type == 'php-email') {
                $params['body']      = base64_encode($params['body']);
                $params['plainText'] = base64_encode($params['plainText']);
            }
            return $params;
        });
    }
P.S: I haven't tested the extension, it's meant as a starting point anyway.
Thanks.
 
Back
Top