I'm trying to use MailSo library to create MIME message. I have got to the point where next step is to process attachments. Everything is fine when attachments are binary files but when I try to to add plain text attachment as follow
$rResource = "Some plain text goes here";
$sFileName = 'text.txt';
$iFileSize = \strlen("Some plain text goes here");
$bIsInline = false;
$bIsLinked = false;
$sCID = $metadataCID;
$aCustomContentTypeParams = array(\MailSo\Base\Enumerations\Encoding::QUOTED_PRINTABLE_LOWER);
$oMessage->Attachments()->Add(
\MailSo\Mime\Attachment::NewInstance(
$rResource,
$sFileName,
$iFileSize,
$bIsInline,
$bIsLinked,
$sCID,
$aCustomContentTypeParams
)
);
I expect to see that attachment as
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=text.txt
but it always forcing to base64 neither adding charset to content-type part as
Content-Type: text/plain; name="text.txt"
Content-Disposition: attachment; filename="text.txt"
Content-Transfer-Encoding: base64
Any tips on that?
It looks like MailSo library treats all attachments except message/rfc822 as binaries. It will require to rewrite or extend createNewMessageAttachmentBody() private function.
Related
I am trying to put a part with text attachment into mail in my Symfony project.
None of examples I tried works.
On dump(), everything is returning what it should.
Where is the catch?
$projectDir = $this->container->get('kernel')->getProjectDir();
$file = $projectDir . '/web/uploads';
// Send email
$message = $this->container->get('mail')->createTemplatedEmail(
$user->getEmail(),
('Your Text File has arrived!'),
'#WebsiteTemplates/member/view.html.twig',
[
'user' => $user,
]
);
$message->attach(\Swift_Attachment::fromPath($file . '/my-text-file.txt'));
$this->container->get('mail')->sendMessage($message, true);
return;
I know I need to pass it as array for my twig file to work like:
Hello {{ user.email }}!
Here is your Text file: {{ txtFile }}<br>
It returns a file in a email like:
Content-Type: text/x-vcard; name=dmchenry-svb-com.vcf Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=dmchenry-svb-com.vcf QkVHSU46VkNBUkQNClZFUlNJT046My4wDQpSRVY6MjAxOS0wMy0xMVQxNToxODozOVoNCk47Q0hB
im really struggling now and I dont know what im doing wrong.
I have regex for analyzing imap_body. It works perfectly fine in my test case but completly fails in a function.
Heres the test case:
$type = "base64";
$regex_html = "/(?<=Content-Type: text\/html;).*?(Content-Transfer-Encoding:).*?(".$type.").*?(\);).(.*?)(?= --_)/";
$email = "--_004_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_ Content-Type: multipart/alternative; boundary="_000_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_" X-Microsoft-Exchange-Diagnostics: 1;DB6P192MB0231;27:wPFlVOQ8iMAXT+N6591mBRfClfXdhMLmsxh/Y7d1LVbWrHPkVIxvj9+3g1ttW81Vi7Xh16wwzAIakEj5LqQ7s3r7Kr3/lVOL94eT9Ky+Tm+IqokcaiD5Q9lLzBrvUIz0CJDh27WR+m3qUDN87HH0jA== X-Microsoft-Antispam-Mailbox-Delivery: abwl:0;wl:0;pcwl:0;kl:0;iwl:0;ijl:0;dwl:0;dkl:0;rwl:0;ex:0;auth:1;dest:I;WIMS-SenderIP:40.92.69.49;WIMS-SPF:windowslive%2ecom;WIMS-DKIM:windowslive%2ecom;WIMS-822:trojak3d%40windowslive%2ecom;WIMS-PRA:trojak3d%40windowslive%2ecom;WIMS-AUTH:PASS;ENG:(400001000128)(400125000095)(5062000261)(5061607266)(5061608174)(4900095)(4921089)(4950112)(4990090)(102400140)(400001001223)(400125100095)(61617095)(400001002128)(400125200095); --_000_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_ Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 X-Microsoft-Exchange-Diagnostics: 1;DB6P192MB0231;27:wPFlVOQ8iMAXT+N6591mBRfClfXdhMLmsxh/Y7d1LVbWrHPkVIxvj9+3g1ttW81Vi7Xh16wwzAIakEj5LqQ7s3r7Kr3/lVOL94eT9Ky+Tm+IqokcaiD5Q9lLzBrvUIz0CJDh27WR+m3qUDN87HH0jA== X-Microsoft-Antispam-Mailbox-Delivery: abwl:0;wl:0;pcwl:0;kl:0;iwl:0;ijl:0;dwl:0;dkl:0;rwl:0;ex:0;auth:1;dest:I;WIMS-SenderIP:40.92.69.49;WIMS-SPF:windowslive%2ecom;WIMS-DKIM:windowslive%2ecom;WIMS-822:trojak3d%40windowslive%2ecom;WIMS-PRA:trojak3d%40windowslive%2ecom;WIMS-AUTH:PASS;ENG:(400001000128)(400125000095)(5062000261)(5061607266)(5061608174)(4900095)(4921089)(4950112)(4990090)(102400140)(400001001223)(400125100095)(61617095)(400001002128)(400125200095); DQoNCkZyb206IFNlcnZpY2VAcGF5cGFJLmNvbSBbbWFpbHRvOmthaG5paWp1bGVAamlhbnNrb2wu Y29tXQ0KU2VudDogMjggSnVseSAyMDE3IDEwOjE2DQpUbzogdHJvamFrM2RAd2luZG93c2xpdmUu Y29tDQpTdWJqZWN0OiBbUGF5UGFJIGxuY10gU3RhdGVtZW50IGFjY291bnQgdW51c3VhbCBhY3Rp dml0eSBsb2dpbiB0byByZWFjdGl2YXRlZCAwNy8yOC8xNw0KDQpbSW1hZ2UgcmVtb3ZlZCBieSBz ZW5kZXIuIFNpbXBsZUFwcF0NCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQpXZSBuZWVkIHlvdXIgaGVs cCB0byByZXNvbHZlIHVuYXV0aG9yaXplZCBhY3Rpdml0ZXMNCg0KRGVhciBDbGllbnQsDQoNCldl IGp1c3Qgd2FudGVkIHRvIGNvbmZpcm0gdGhhdCB5b3UndmUgY2hhbmdlZCB5b3VyIHBhc3N3b3Jk LiBJZiB5b3UgZGlkbid0IG1ha2UgdGhpcyBjaGFuZ2UsIHBsZWFzZSBjaGVjayBpbmZvcm1hdGlv biBpbiBoZXJlLiBJdCdzIGltcG9ydGFudCB0aGF0IHlvdSBsZXQgdXMga25vdyBiZWNhdXNlIGl0 IGhlbHBzIHVzIHByZXZlbnQgdW5hdXRob3Jpc2VkIHBlcnNvbnMgZnJvbSBhY2Nlc3NpbmcgdGhl IFBheVBhbCBuZXR3b3JrIGFuZCB5b3VyIGFjY291bnQgaW5mb3JtYXRpb24uDQoNCldlJ3ZlIG5v dGljZWQgc29tZSBjaGFuZ2VzIHRvIHlvdXIgdW5zdWFsIHNlbGxpbmcgYWN0aXZpdGllcyBhbmQg d2lsbCBuZWVkIHNvbWUgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB5b3VyIHJlY2VudCBzYWxlcy4N CkNvbmZpcm0geW91ciBlbWFpbDxodHRwOi8vb3cubHkvcWVMMzMwZFl6TzI+DQoNCg0KVGhhbmsg eW91IGZvciB5b3VyIHVuZGVyc3RhbmRpbmcgYW5kIGNvb3BlcmF0aW9uLiBJZiB5b3UgbmVlZCBm dXJ0aGVyIGFzc2lzdGFuY2UsIHBsZWFzZSBjbGljayBDb250YWN0IGF0IHRoZSBib3R0b20gb2Yg YW55IFBheVBhbCBwYWdlLg0KDQpTaW5jZXJlbHksDQoNClBheVBhbA0KDQoNCg0KDQoNCkhlbHAg PGh0dHA6Ly9wYXlwYWwuY29tPiB8IFJlc29sdXRpb24gPGh0dHA6Ly9wYXlwYWwuY29tPiB8IFNl Y3VyaXR5IENlbnRyZTxodHRwOi8vcGF5cGFsLmNvbT4NCg0KUGxlYXNlIGRvIG5vdCByZXBseSB0 byB0aGlzIGVtYWlsLiBUbyBnZXQgaW4gdG91Y2ggd2l0aCB1cywgY2xpY2sgSGVscCAmIENvbnRh Y3QuPGh0dHA6Ly9wYXlwYWwuY29tPg0KDQpDb3B5cmlnaHQgwqkgMTk5OSDigJMgMjAxNyBQYXlQ YWwuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQoNCkNvbnN1bWVyIGFkdmlzb3J5IC0gUGF5UGFsIFB0 ZS4gTHRkLiB0aGUgaG9sZGVyIG9mIFBheVBhbCdzIHN0b3JlZCB2YWx1ZSBmYWNpbGl0eSwgZG9l cyBub3QgcmVxdWlyZSB0aGUgYXBwcm92YWwgb2YgdGhlIE1vbmV0YXJ5IEF1dGhvcml0eSBvZiBT aW5nYXBvcmUuIFVzZXJzIGFyZSBhZHZpc2VkIHRvIHJlYWQgdGhlIHRlcm1zIGFuZCBjb25kaXRp b25zIGNhcmVmdWxseS4NCg0KUGF5UGFsIFBQWDAwMTg4OToyMTNlZTFiZjYxODdlDQoNCg0KDQoN Cg0KDQo= --_000_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_ Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 X-Microsoft-Exchange-Diagnostics: 1;DB6P192MB0231;27:wPFlVOQ8iMAXT+N6591mBRfClfXdhMLmsxh/Y7d1LVbWrHPkVIxvj9+3g1ttW81Vi7Xh16wwzAIakEj5LqQ7s3r7Kr3/lVOL94eT9Ky+Tm+IqokcaiD5Q9lLzBrvUIz0CJDh27WR+m3qUDN87HH0jA== X-Microsoft-Antispam-Mailbox-Delivery: abwl:0;wl:0;pcwl:0;kl:0;iwl:0;ijl:0;dwl:0;dkl:0;rwl:0;ex:0;auth:1;dest:I;WIMS-SenderIP:40.92.69.49;WIMS-SPF:windowslive%2ecom;WIMS-DKIM:windowslive%2ecom;WIMS-822:trojak3d%40windowslive%2ecom;WIMS-PRA:trojak3d%40windowslive%2ecom;WIMS-AUTH:PASS;ENG:(400001000128)(400125000095)(5062000261)(5061607266)(5061608174)(4900095)(4921089)(4950112)(4990090)(102400140)(400001001223)(400125100095)(61617095)(400001002128)(400125200095); PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv VFIvUkVDLWh0bWw0MCI+PGhlYWQ+DQo8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNv bnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCI+DQo8bWV0YSBuYW1lPSJHZW5lcmF0b3Ii IGNvbnRlbnQ9Ik1pY3Jvc29mdCBXb3JkIDE1IChmaWx0ZXJlZCBtZWRpdW0pIj4NCjwhLS1baWYg IW1zb10+PHN0eWxlPnZcOioge2JlaGF2aW9yOnVybCgjZGVmYXVsdCNWTUwpO30NCm9cOioge2Jl aGF2aW9yOnVybCgjZGVmYXVsdCNWTUwpO30NCndcOioge2JlaGF2aW9yOnVybCgjZGVmYXVsdCNW TUwpO30NCi5zaGFwZSB7YmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTCk7fQ0KPC9zdHlsZT48IVtl bmRpZl0tLT48c3R5bGU+PCEtLQ0KLyogRm9udCBEZWZpbml0aW9ucyAqLw0KQGZvbnQtZmFjZQ0K CXtmb250LWZhbWlseTpIZWx2ZXRpY2E7DQoJcGFub3NlLTE6MiAxMSA2IDQgMiAyIDIgMiAyIDQ7 fQ0KQGZvbnQtZmFjZQ0KCXtmb250LWZhbWlseToiQ2FtYnJpYSBNYXRoIjsNCglwYW5vc2UtMToy IDQgNSAzIDUgNCA2IDMgMiA0O30NCkBmb250LWZhY2UNCgl7Zm9udC1mYW1pbHk6Q2FsaWJyaTsN CglwYW5vc2UtMToyIDE1IDUgMiAyIDIgNCAzIDIgNDt9DQovKiBTdHlsZSBEZWZpbml0aW9ucyAq Lw0KcC5Nc29Ob3JtYWwsIGxpLk1zb05vcm1hbCwgZGl2Lk1zb05vcm1hbA0KCXttYXJnaW46MGNt Ow0KCW1hcmdpbi1ib3R0b206LjAwMDFwdDsNCglmb250LXNpemU6MTEuMHB0Ow0KCWZvbnQtZmFt aWx5OiJDYWxpYnJpIixzYW5zLXNlcmlmO30NCmE6bGluaywgc3Bhbi5Nc29IeXBlcmxpbmsNCgl7 bXNvLXN0eWxlLXByaW9yaXR5Ojk5Ow0KCWNvbG9yOmJsdWU7DQoJdGV4dC1kZWNvcmF0aW9uOnVu ZGVybGluZTt9DQphOnZpc2l0ZWQsIHNwYW4uTXNvSHlwZXJsaW5rRm9sbG93ZWQNCgl7bXNvLXN0 eWxlLXByaW9yaXR5Ojk5Ow0KCWNvbG9yOnB1cnBsZTsNCgl0ZXh0LWRlY29yYXRpb246dW5kZXJs aW5lO30NCnAubXNvbm9ybWFsMCwgbGkubXNvbm9ybWFsMCwgZGl2Lm1zb25vcm1hbDANCgl7bXNv LXN0eWxlLW5hbWU6bXNvbm9ybWFsOw0KCW1zby1tYXJnaW4tdG9wLWFsdDphdXRvOw0KCW1hcmdp bi1yaWdodDowY207DQoJbXNvLW1hcmdpbi1ib3R0b20tYWx0OmF1dG87DQoJbWFyZ2luLWxlZnQ6 MGNtOw0KCWZvbnQtc2l6ZToxMS4wcHQ7DQoJZm9udC1mYW1pbHk6IkNhbGlicmkiLHNhbnMtc2Vy aWY7fQ0Kc3Bhbi5FbWFpbFN0eWxlMTkNCgl7bXNvLXN0eWxlLXR5cGU6cGVyc29uYWwtcmVwbHk7 DQoJZm9udC1mYW1pbHk6IkNhbGlicmkiLHNhbnMtc2VyaWY7DQoJY29sb3I6d2luZG93dGV4dDt9 DQouTXNvQ2hwRGVmYXVsdA0KCXttc28tc3R5bGUtdHlwZTpleHBvcnQtb25seTsNCglmb250LWZh bWlseToiQ2FsaWJyaSIsc2Fucy1zZXJpZjsNCgltc28tZmFyZWFzdC1sYW5ndWFnZTpFTi1VUzt9 DQpAcGFnZSBXb3JkU2VjdGlvbjENCgl7c2l6ZTo2MTIuMHB0IDc5Mi4wcHQ7DQoJbWFyZ2luOjcy LjBwdCA3Mi4wcHQgNzIuMHB0IDcyLjBwdDt9DQpkaXYuV29yZFNlY3Rpb24xDQoJe3BhZ2U6V29y ZFNlY3Rpb24xO30NCi0tPjwvc3R5bGU+PCEtLVtpZiBndGUgbXNvIDldPjx4bWw+DQo8bzpzaGFw ZWRlZmF1bHRzIHY6ZXh0PSJlZGl0IiBzcGlkbWF4PSIxMDI2IiAvPg0KPC94bWw+PCFbZW5kaWZd LS0+PCEtLVtpZiBndGUgbXNvIDldPjx4bWw+DQo8bzpzaGFwZWxheW91dCB2OmV4dD0iZWRpdCI+ DQo8bzppZG1hcCB2OmV4dD0iZWRpdCIgZGF0YT0iMSIgLz4NCjwvbzpzaGFwZWxheW91dD48L3ht bD48IVtlbmRpZl0tLT4NCjwvaGVhZD4NCjxib2R5IGxhbmc9IkVOLUdCIiBsaW5rPSJibHVlIiB2 bGluaz0icHVycGxlIj4NCjxkaXYgY2xhc3M9IldvcmRTZWN0aW9uMSI+DQo8cCBjbGFzcz0iTXNv Tm9ybWFsIj48c3BhbiBzdHlsZT0ibXNvLWZhcmVhc3QtbGFuZ3VhZ2U6RU4tVVMiPjxvOnA+Jm5i c3A7PC9vOnA+PC9zcGFuPjwvcD4NCjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJt c28tZmFyZWFzdC1sYW5ndWFnZTpFTi1VUyI+PG86cD4mbmJzcDs8L286cD48L3NwYW4+PC9wPg0K PHAgY2xhc3M9Ik1zb05vcm1hbCI+PGI+PHNwYW4gbGFuZz0iRU4tVVMiPkZyb206PC9zcGFuPjwv Yj48c3BhbiBsYW5nPSJFTi1VUyI+IFNlcnZpY2VAcGF5cGFJLmNvbSBbbWFpbHRvOmthaG5paWp1 bGVAamlhbnNrb2wuY29tXQ0KPGJyPg0KPGI+U2VudDo8L2I+IDI4IEp1bHkgMjAxNyAxMDoxNjxi cj4NCjxiPlRvOjwvYj4gdHJvamFrM2RAd2luZG93c2xpdmUuY29tPGJyPg0KPGI+U3ViamVjdDo8 L2I+IFtQYXlQYUkgbG5jXSBTdGF0ZW1lbnQgYWNjb3VudCB1bnVzdWFsIGFjdGl2aXR5IGxvZ2lu IHRvIHJlYWN0aXZhdGVkIDA3LzI4LzE3PG86cD48L286cD48L3NwYW4+PC9wPg0KPHAgY2xhc3M9 Ik1zb05vcm1hbCI+PG86cD4mbmJzcDs8L286cD48L3A+DQo8ZGl2IGFsaWduPSJjZW50ZXIiPg0K PHRhYmxlIGNsYXNzPSJNc29Ob3JtYWxUYWJsZSIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIg Y2VsbHBhZGRpbmc9IjAiIHdpZHRoPSI1ODAiIHN0eWxlPSJ3aWR0aDo0MzUuMHB0Ij4NCjx0Ym9k eT4NCjx0cj4NCjx0ZCB3aWR0aD0iNTgwIiB2YWxpZ249InRvcCIgc3R5bGU9IndpZHRoOjQzNS4w cHQ7cGFkZGluZzowY20gMGNtIDBjbSAwY20iPg0KPGRpdiBhbGlnbj0iY2VudGVyIj4NCjx0YWJs ZSBjbGFzcz0iTXNvTm9ybWFsVGFibGUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxw YWRkaW5nPSIwIiB3aWR0aD0iMTAwJSIgc3R5bGU9IndpZHRoOjEwMC4wJSI+DQo8dGJvZHk+DQo8 dHI+DQo8dGQgdmFsaWduPSJ0b3AiIHN0eWxlPSJiYWNrZ3JvdW5kOndoaXRlO3BhZGRpbmc6MGNt IDBjbSAxMi4wcHQgMGNtIj4NCjxkaXYgYWxpZ249ImNlbnRlciI+DQo8dGFibGUgY2xhc3M9Ik1z b05vcm1hbFRhYmxlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCIg d2lkdGg9IjU4MCIgc3R5bGU9IndpZHRoOjQzNS4wcHQiPg0KPHRib2R5Pg0KPHRyPg0KPHRkIHdp ZHRoPSI1ODAiIHZhbGlnbj0idG9wIiBzdHlsZT0id2lkdGg6NDM1LjBwdDtwYWRkaW5nOjBjbSAw Y20gMGNtIDBjbSI+DQo8ZGl2IGFsaWduPSJjZW50ZXIiPg0KPHRhYmxlIGNsYXNzPSJNc29Ob3Jt YWxUYWJsZSIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiIHdpZHRo PSI1ODAiIHN0eWxlPSJ3aWR0aDo0MzUuMHB0Ij4NCjx0Ym9keT4NCjx0cj4NCjx0ZCB3aWR0aD0i NTgwIiB2YWxpZ249InRvcCIgc3R5bGU9IndpZHRoOjQzNS4wcHQ7cGFkZGluZzowY20gMGNtIDBj bSAwY20iPg0KPGRpdiBhbGlnbj0iY2VudGVyIj4NCjx0YWJsZSBjbGFzcz0iTXNvTm9ybWFsVGFi bGUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAw JSIgc3R5bGU9IndpZHRoOjEwMC4wJSI+DQo8dGJvZHk+DQo8dHI+DQo8dGQgdmFsaWduPSJ0b3Ai IHN0eWxlPSJwYWRkaW5nOjEyLjBwdCAxMi4wcHQgMGNtIDEyLjBwdCI+DQo8cCBjbGFzcz0iTXNv Tm9ybWFsIj48Yj48c3BhbiBzdHlsZT0iZm9udC1zaXplOjE1LjBwdDtmb250LWZhbWlseTomcXVv dDtIZWx2ZXRpY2EmcXVvdDssc2Fucy1zZXJpZjtjb2xvcjp3aGl0ZSI+PHNwYW4gc3R5bGU9ImJv cmRlcjpzb2xpZCB3aW5kb3d0ZXh0IDEuMHB0O3BhZGRpbmc6MGNtIj48aW1nIHdpZHRoPSIxMjAi IGhlaWdodD0iMTIwIiBzdHlsZT0id2lkdGg6MS4yNWluO2hlaWdodDoxLjI1aW4iIGlkPSJfeDAw MDBfaTEwMjUiIHNyYz0iY2lkOmltYWdlMDAxLmpwZ0AwMUQzMDhCMi5DOTMxRUU5MCIgYWx0PSJJ bWFnZSByZW1vdmVkIGJ5IHNlbmRlci4gU2ltcGxlQXBwIj48L3NwYW4+PG86cD48L286cD48L3Nw YW4+PC9iPjwvcD4NCjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+DQo8L2Rpdj4NCjwv dGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+DQo8L2Rpdj4NCjwvdGQ+DQo8L3RyPg0KPC90 Ym9keT4NCjwvdGFibGU+DQo8L2Rpdj4NCjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+ DQo8L2Rpdj4NCjxwIGNsYXNzPSJNc29Ob3JtYWwiIGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0 LWFsaWduOmNlbnRlcjt2ZXJ0aWNhbC1hbGlnbjp0b3AiPg0KPG86cD4mbmJzcDs8L286cD48L3A+ DQo8ZGl2IGFsaWduPSJjZW50ZXIiPg0KPHRhYmxlIGNsYXNzPSJNc29Ob3JtYWxUYWJsZSIgYm9y ZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIxMDAlIiBzdHls ZT0id2lkdGg6MTAwLjAlO0JPUkRFUi1TUEFDSU5HOiAwIj4NCjx0Ym9keT4NCjx0cj4NCjx0ZCB2 YWxpZ249InRvcCIgc3R5bGU9ImJhY2tncm91bmQ6I0YyRjJGNTtwYWRkaW5nOjBjbSAwY20gMGNt IDBjbSI+DQo8ZGl2IGFsaWduPSJjZW50ZXIiPg0KPHRhYmxlIGNsYXNzPSJNc29Ob3JtYWxUYWJs ZSIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSI1ODAi IHN0eWxlPSJ3aWR0aDo0MzUuMHB0O0JPUkRFUi1TUEFDSU5HOiAwIj4NCjx0Ym9keT4NCjx0cj4N Cjx0ZCB3aWR0aD0iNTgwIiB2YWxpZ249InRvcCIgc3R5bGU9IndpZHRoOjQzNS4wcHQ7cGFkZGlu ZzowY20gMGNtIDBjbSAwY20iPg0KPGRpdiBhbGlnbj0iY2VudGVyIj4NCjx0YWJsZSBjbGFzcz0i TXNvTm9ybWFsVGFibGUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIw IiB3aWR0aD0iNTgwIiBzdHlsZT0id2lkdGg6NDM1LjBwdCI+DQo8dGJvZHk+DQo8dHI+DQo8dGQg d2lkdGg9IjU4MCIgdmFsaWduPSJ0b3AiIHN0eWxlPSJ3aWR0aDo0MzUuMHB0O3BhZGRpbmc6MGNt IDBjbSAwY20gMGNtIj4NCjxkaXYgYWxpZ249ImNlbnRlciI+DQo8dGFibGUgY2xhc3M9Ik1zb05v cm1hbFRhYmxlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCIgd2lk dGg9IjEwMCUiIHN0eWxlPSJ3aWR0aDoxMDAuMCUiPg0KPHRib2R5Pg0KPHRyPg0KPHRkIHN0eWxl PSJwYWRkaW5nOjBjbSAwY20gMGNtIDBjbSI+PC90ZD4NCjwvdHI+DQo8L3Rib2R5Pg0KPC90YWJs ZT4NCjwvZGl2Pg0KPC90ZD4NCjwvdHI+DQo8L3Rib2R5Pg0KPC90YWJsZT4NCjwvZGl2Pg0KPC90 ZD4NCjwvdHI+DQo8L3Rib2R5Pg0KPC90YWJsZT4NCjwvZGl2Pg0KPC90ZD4NCjwvdHI+DQo8L3Ri b2R5Pg0KPC90YWJsZT4NCjwvZGl2Pg0KPHAgY2xhc3M9Ik1zb05vcm1hbCIgYWxpZ249ImNlbnRl ciIgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyO3ZlcnRpY2FsLWFsaWduOnRvcCI+DQo8bzpwPiZu YnNwOzwvbzpwPjwvcD4NCjxkaXYgYWxpZ249ImNlbnRlciI+DQo8dGFibGUgY2xhc3M9Ik1zb05v cm1hbFRhYmxlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCIgd2lk dGg9IjEwMCUiIHN0eWxlPSJ3aWR0aDoxMDAuMCU7Qk9SREVSLVNQQUNJTkc6IDAiPg0KPHRib2R5 Pg0KPHRyPg0KPHRkIHZhbGlnbj0idG9wIiBzdHlsZT0iYmFja2dyb3VuZDp3aGl0ZTtwYWRkaW5n OjBjbSAwY20gMGNtIDBjbSI+DQo8ZGl2IGFsaWduPSJjZW50ZXIiPg0KPHRhYmxlIGNsYXNzPSJN c29Ob3JtYWxUYWJsZSIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAi IHdpZHRoPSI1ODAiIHN0eWxlPSJ3aWR0aDo0MzUuMHB0O0JPUkRFUi1TUEFDSU5HOiAwIj4NCjx0 Ym9keT4NCjx0cj4NCjx0ZCB3aWR0aD0iNTgwIiB2YWxpZ249InRvcCIgc3R5bGU9IndpZHRoOjQz NS4wcHQ7cGFkZGluZzowY20gMGNtIDBjbSAwY20iPg0KPGRpdiBhbGlnbj0iY2VudGVyIj4NCjx0 YWJsZSBjbGFzcz0iTXNvTm9ybWFsVGFibGUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNl bGxwYWRkaW5nPSIwIiB3aWR0aD0iNTgwIiBzdHlsZT0id2lkdGg6NDM1LjBwdCI+DQo8dGJvZHk+ DQo8dHI+DQo8dGQgd2lkdGg9IjU4MCIgdmFsaWduPSJ0b3AiIHN0eWxlPSJ3aWR0aDo0MzUuMHB0 O3BhZGRpbmc6MGNtIDBjbSAwY20gMGNtIj4NCjxkaXYgYWxpZ249ImNlbnRlciI+DQo8dGFibGUg Y2xhc3M9Ik1zb05vcm1hbFRhYmxlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFk ZGluZz0iMCIgd2lkdGg9IjEwMCUiIHN0eWxlPSJ3aWR0aDoxMDAuMCUiPg0KPHRib2R5Pg0KPHRy Pg0KPHRkIHZhbGlnbj0idG9wIiBzdHlsZT0icGFkZGluZzoxMi4wcHQgMTIuMHB0IDEyLjBwdCAx Mi4wcHQiPg0KPHAgc3R5bGU9Im1zby1tYXJnaW4tdG9wLWFsdDoxLjVwdDttYXJnaW4tcmlnaHQ6 MGNtO21hcmdpbi1ib3R0b206MTguMHB0O21hcmdpbi1sZWZ0OjBjbTttc28tbGluZS1oZWlnaHQt YWx0OjkuMHB0Ij4NCjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTYuNXB0O2ZvbnQtZmFtaWx5OiZx dW90O0hlbHZldGljYSZxdW90OyxzYW5zLXNlcmlmO2NvbG9yOiMwMDlDREUiPldlIG5lZWQgeW91 ciBoZWxwIHRvIHJlc29sdmUgdW5hdXRob3JpemVkIGFjdGl2aXRlczxvOnA+PC9vOnA+PC9zcGFu PjwvcD4NCjxwIHN0eWxlPSJtc28tbWFyZ2luLXRvcC1hbHQ6MTAuNXB0O21hcmdpbi1yaWdodDow Y207bWFyZ2luLWJvdHRvbToxOC4wcHQ7bWFyZ2luLWxlZnQ6MGNtO2xpbmUtaGVpZ2h0OjkuMHB0 Ij4NCjxzcGFuIHN0eWxlPSJmb250LXNpemU6OS4wcHQ7Zm9udC1mYW1pbHk6JnF1b3Q7SGVsdmV0 aWNhJnF1b3Q7LHNhbnMtc2VyaWY7Y29sb3I6Izg4ODg4OCI+RGVhciBDbGllbnQsPG86cD48L286 cD48L3NwYW4+PC9wPg0KPHAgc3R5bGU9Im1zby1tYXJnaW4tdG9wLWFsdDoxMC41cHQ7bWFyZ2lu LXJpZ2h0OjBjbTttYXJnaW4tYm90dG9tOjE1LjBwdDttYXJnaW4tbGVmdDowY207bGluZS1oZWln aHQ6MTMuNXB0Ij4NCjxzcGFuIHN0eWxlPSJmb250LXNpemU6OS4wcHQ7Zm9udC1mYW1pbHk6JnF1 b3Q7SGVsdmV0aWNhJnF1b3Q7LHNhbnMtc2VyaWY7Y29sb3I6Izg4ODg4OCI+V2UganVzdCB3YW50 ZWQgdG8gY29uZmlybSB0aGF0IHlvdSd2ZSBjaGFuZ2VkIHlvdXIgcGFzc3dvcmQuIElmIHlvdSBk aWRuJ3QgbWFrZSB0aGlzIGNoYW5nZSwgcGxlYXNlIGNoZWNrIGluZm9ybWF0aW9uIGluIGhlcmUu IEl0J3MgaW1wb3J0YW50IHRoYXQgeW91IGxldCB1cyBrbm93IGJlY2F1c2UgaXQgaGVscHMNCiB1 cyBwcmV2ZW50IHVuYXV0aG9yaXNlZCBwZXJzb25zIGZyb20gYWNjZXNzaW5nIHRoZSBQYXlQYWwg bmV0d29yayBhbmQgeW91ciBhY2NvdW50IGluZm9ybWF0aW9uLjxvOnA+PC9vOnA+PC9zcGFuPjwv cD4NCjxwIHN0eWxlPSJtc28tbWFyZ2luLXRvcC1hbHQ6OS4wcHQ7bWFyZ2luLXJpZ2h0OjBjbTtt YXJnaW4tYm90dG9tOjE4LjBwdDttYXJnaW4tbGVmdDowY207bGluZS1oZWlnaHQ6MTMuNXB0Ij4N CjxzcGFuIHN0eWxlPSJmb250LXNpemU6OS4wcHQ7Zm9udC1mYW1pbHk6JnF1b3Q7SGVsdmV0aWNh JnF1b3Q7LHNhbnMtc2VyaWY7Y29sb3I6Izg4ODg4OCI+V2UndmUgbm90aWNlZCBzb21lIGNoYW5n ZXMgdG8geW91ciB1bnN1YWwgc2VsbGluZyBhY3Rpdml0aWVzIGFuZCB3aWxsIG5lZWQgc29tZSBt b3JlIGluZm9ybWF0aW9uIGFib3V0IHlvdXIgcmVjZW50IHNhbGVzLjxvOnA+PC9vOnA+PC9zcGFu PjwvcD4NCjxkaXYgYWxpZ249ImNlbnRlciI+DQo8dGFibGUgY2xhc3M9Ik1zb05vcm1hbFRhYmxl IiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCIgc3R5bGU9IkJPUkRF Ui1TUEFDSU5HOiAwIj4NCjx0Ym9keT4NCjx0cj4NCjx0ZCBzdHlsZT0iYmFja2dyb3VuZDojMDA5 Q0RFO3BhZGRpbmc6OS4wcHQgMTguMHB0IDkuMHB0IDE4LjBwdDstd2Via2l0LWJvcmRlci1yYWRp dXM6IDRweDtib3JkZXItcmFkaXVzOiA0cHgiPg0KPHAgY2xhc3M9Ik1zb05vcm1hbCIgYWxpZ249 ImNlbnRlciIgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj48c3BhbiBzdHlsZT0iZm9udC1zaXpl OjEwLjBwdDtmb250LWZhbWlseTomcXVvdDtIZWx2ZXRpY2EmcXVvdDssc2Fucy1zZXJpZiI+PGEg aHJlZj0iaHR0cDovL293Lmx5L3FlTDMzMGRZek8yIj48Yj48c3BhbiBzdHlsZT0iY29sb3I6d2hp dGU7dGV4dC1kZWNvcmF0aW9uOm5vbmUiPkNvbmZpcm0geW91ciBlbWFpbDwvc3Bhbj48L2I+PC9h PjxvOnA+PC9vOnA+PC9zcGFuPjwvcD4NCjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+ DQo8L2Rpdj4NCjxwIHN0eWxlPSJtc28tbWFyZ2luLXRvcC1hbHQ6MTIuMHB0O21hcmdpbi1yaWdo dDowY207bWFyZ2luLWJvdHRvbToxOC4wcHQ7bWFyZ2luLWxlZnQ6MGNtO2xpbmUtaGVpZ2h0OjEz LjVwdCI+DQo8c3BhbiBzdHlsZT0iZm9udC1zaXplOjkuMHB0O2ZvbnQtZmFtaWx5OiZxdW90O0hl bHZldGljYSZxdW90OyxzYW5zLXNlcmlmO2NvbG9yOiM4ODg4ODgiPlRoYW5rIHlvdSBmb3IgeW91 ciB1bmRlcnN0YW5kaW5nIGFuZCBjb29wZXJhdGlvbi4gSWYgeW91IG5lZWQgZnVydGhlciBhc3Np c3RhbmNlLCBwbGVhc2UgY2xpY2sgQ29udGFjdCBhdCB0aGUgYm90dG9tIG9mIGFueSBQYXlQYWwg cGFnZS48bzpwPjwvbzpwPjwvc3Bhbj48L3A+DQo8cCBzdHlsZT0ibXNvLW1hcmdpbi10b3AtYWx0 OjEyLjBwdDttYXJnaW4tcmlnaHQ6MGNtO21hcmdpbi1ib3R0b206OS4wcHQ7bWFyZ2luLWxlZnQ6 MGNtO2xpbmUtaGVpZ2h0OjE3LjI1cHQiPg0KPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTo5LjBwdDtm b250LWZhbWlseTomcXVvdDtIZWx2ZXRpY2EmcXVvdDssc2Fucy1zZXJpZjtjb2xvcjojODg4ODg4 Ij5TaW5jZXJlbHksPG86cD48L286cD48L3NwYW4+PC9wPg0KPHAgc3R5bGU9Im1zby1tYXJnaW4t dG9wLWFsdDo3LjVwdDttYXJnaW4tcmlnaHQ6MGNtO21hcmdpbi1ib3R0b206OS4wcHQ7bWFyZ2lu LWxlZnQ6MGNtO2xpbmUtaGVpZ2h0OjE3LjI1cHQiPg0KPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTo5 LjBwdDtmb250LWZhbWlseTomcXVvdDtIZWx2ZXRpY2EmcXVvdDssc2Fucy1zZXJpZjtjb2xvcjoj ODg4ODg4Ij5QYXlQYWw8bzpwPjwvbzpwPjwvc3Bhbj48L3A+DQo8L3RkPg0KPC90cj4NCjwvdGJv ZHk+DQo8L3RhYmxlPg0KPC9kaXY+DQo8L3RkPg0KPC90cj4NCjwvdGJvZHk+DQo8L3RhYmxlPg0K PC9kaXY+DQo8L3RkPg0KPC90cj4NCjwvdGJvZHk+DQo8L3RhYmxlPg0KPC9kaXY+DQo8L3RkPg0K PC90cj4NCjwvdGJvZHk+DQo8L3RhYmxlPg0KPC9kaXY+DQo8cCBjbGFzcz0iTXNvTm9ybWFsIiBh bGlnbj0iY2VudGVyIiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXI7dmVydGljYWwtYWxpZ246dG9w Ij4NCjxvOnA+Jm5ic3A7PC9vOnA+PC9wPg0KPGRpdiBhbGlnbj0iY2VudGVyIj4NCjx0YWJsZSBj bGFzcz0iTXNvTm9ybWFsVGFibGUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRk aW5nPSIwIiB3aWR0aD0iMTAwJSIgc3R5bGU9IndpZHRoOjEwMC4wJTtCT1JERVItU1BBQ0lORzog MCI+DQo8dGJvZHk+DQo8dHI+DQo8dGQgdmFsaWduPSJ0b3AiIHN0eWxlPSJib3JkZXI6bm9uZTti b3JkZXItdG9wOnNvbGlkICNEOERERTQgMS4wcHQ7YmFja2dyb3VuZDojRjJGMkY1O3BhZGRpbmc6 MGNtIDBjbSAxMi4wcHQgMGNtOy13ZWJraXQtYm9yZGVyLXJhZGl1czogMCAwIDRweCA0cHg7Ym9y ZGVyLXJhZGl1czogMCAwIDRweCA0cHgiPg0KPGRpdiBhbGlnbj0iY2VudGVyIj4NCjx0YWJsZSBj bGFzcz0iTXNvTm9ybWFsVGFibGUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRk aW5nPSIwIiB3aWR0aD0iNTgwIiBzdHlsZT0id2lkdGg6NDM1LjBwdDstd2Via2l0LWJvcmRlci1y YWRpdXM6IDAgMCA0cHggNHB4O2JvcmRlci1yYWRpdXM6IDAgMCA0cHggNHB4Ij4NCjx0Ym9keT4N Cjx0cj4NCjx0ZCB3aWR0aD0iNTgwIiB2YWxpZ249InRvcCIgc3R5bGU9IndpZHRoOjQzNS4wcHQ7 cGFkZGluZzowY20gMGNtIDBjbSAwY207Qk9SREVSLVNQQUNJTkc6IDAiPg0KPGRpdiBhbGlnbj0i Y2VudGVyIj4NCjx0YWJsZSBjbGFzcz0iTXNvTm9ybWFsVGFibGUiIGJvcmRlcj0iMCIgY2VsbHNw YWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iNTgwIiBzdHlsZT0id2lkdGg6NDM1LjBw dCI+DQo8dGJvZHk+DQo8dHI+DQo8dGQgd2lkdGg9IjM5MCIgdmFsaWduPSJ0b3AiIHN0eWxlPSJ3 aWR0aDoyOTIuNXB0O3BhZGRpbmc6MGNtIDBjbSAwY20gMGNtIj4NCjxkaXYgYWxpZ249ImNlbnRl ciI+DQo8dGFibGUgY2xhc3M9Ik1zb05vcm1hbFRhYmxlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5n PSIwIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiIHN0eWxlPSJ3aWR0aDoxMDAuMCUiPg0K PHRib2R5Pg0KPHRyPg0KPHRkIHZhbGlnbj0idG9wIiBzdHlsZT0icGFkZGluZzo5LjBwdCAxMi4w cHQgMGNtIDEyLjBwdCI+DQo8cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0iZm9udC1z aXplOjcuNXB0O2ZvbnQtZmFtaWx5OiZxdW90O0hlbHZldGljYSZxdW90OyxzYW5zLXNlcmlmIj48 YSBocmVmPSJodHRwOi8vcGF5cGFsLmNvbSI+PHNwYW4gc3R5bGU9ImNvbG9yOiMwMDlDREUiPkhl bHANCjwvc3Bhbj48L2E+fCA8YSBocmVmPSJodHRwOi8vcGF5cGFsLmNvbSI+PHNwYW4gc3R5bGU9 ImNvbG9yOiMwMDlDREUiPlJlc29sdXRpb24gPC9zcGFuPg0KPC9hPnwgPGEgaHJlZj0iaHR0cDov L3BheXBhbC5jb20iPjxzcGFuIHN0eWxlPSJjb2xvcjojMDA5Q0RFIj5TZWN1cml0eSBDZW50cmU8 L3NwYW4+PC9hPg0KPG86cD48L286cD48L3NwYW4+PC9wPg0KPHA+PHNwYW4gc3R5bGU9ImZvbnQt c2l6ZTo3LjVwdDtmb250LWZhbWlseTomcXVvdDtIZWx2ZXRpY2EmcXVvdDssc2Fucy1zZXJpZiI+ UGxlYXNlIGRvIG5vdCByZXBseSB0byB0aGlzIGVtYWlsLiBUbyBnZXQgaW4gdG91Y2ggd2l0aCB1 cywgY2xpY2sNCjxhIGhyZWY9Imh0dHA6Ly9wYXlwYWwuY29tIj48c3BhbiBzdHlsZT0iY29sb3I6 IzAwOUNERSI+SGVscCAmYW1wOyBDb250YWN0Ljwvc3Bhbj48L2E+PG86cD48L286cD48L3NwYW4+ PC9wPg0KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTo3LjVwdDtm b250LWZhbWlseTomcXVvdDtIZWx2ZXRpY2EmcXVvdDssc2Fucy1zZXJpZiI+PGJyPg0KQ29weXJp Z2h0IMKpIDE5OTkg4oCTIDIwMTcgUGF5UGFsLiBBbGwgcmlnaHRzIHJlc2VydmVkLiA8YnI+DQo8 YnI+DQpDb25zdW1lciBhZHZpc29yeSAtIFBheVBhbCBQdGUuIEx0ZC4gdGhlIGhvbGRlciBvZiBQ YXlQYWwncyBzdG9yZWQgdmFsdWUgZmFjaWxpdHksIGRvZXMgbm90IHJlcXVpcmUgdGhlIGFwcHJv dmFsIG9mIHRoZSBNb25ldGFyeSBBdXRob3JpdHkgb2YgU2luZ2Fwb3JlLiBVc2VycyBhcmUgYWR2 aXNlZCB0byByZWFkIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBjYXJlZnVsbHkuPGJyPg0KPGJy Pg0KUGF5UGFsIFBQWDAwMTg4OToyMTNlZTFiZjYxODdlIDxvOnA+PC9vOnA+PC9zcGFuPjwvcD4N CjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+DQo8L2Rpdj4NCjwvdGQ+DQo8dGQgd2lk dGg9IjE5MCIgdmFsaWduPSJ0b3AiIHN0eWxlPSJ3aWR0aDoxNDIuNXB0O3BhZGRpbmc6MGNtIDBj bSAwY20gMGNtIj48L3RkPg0KPC90cj4NCjwvdGJvZHk+DQo8L3RhYmxlPg0KPC9kaXY+DQo8L3Rk Pg0KPC90cj4NCjwvdGJvZHk+DQo8L3RhYmxlPg0KPC9kaXY+DQo8L3RkPg0KPC90cj4NCjwvdGJv ZHk+DQo8L3RhYmxlPg0KPC9kaXY+DQo8L3RkPg0KPC90cj4NCjwvdGJvZHk+DQo8L3RhYmxlPg0K PC9kaXY+DQo8cCBjbGFzcz0iTXNvTm9ybWFsIj48bzpwPiZuYnNwOzwvbzpwPjwvcD4NCjwvZGl2 Pg0KPC9ib2R5Pg0KPC9odG1sPg0K --_000_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_-- --_004_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_ Content-Type: image/jpeg; name="image001.jpg" Content-Description: image001.jpg Content-Disposition: inline; filename="image001.jpg"; size=500; creation-date="Sat, 29 Jul 2017 20:36:56 GMT"; modification-date="Sat, 29 Jul 2017 20:36:56 GMT" Content-ID: Content-Transfer-Encoding: base64 X-Microsoft-Exchange-Diagnostics: 1;DB6P192MB0231;27:wPFlVOQ8iMAXT+N6591mBRfClfXdhMLmsxh/Y7d1LVbWrHPkVIxvj9+3g1ttW81Vi7Xh16wwzAIakEj5LqQ7s3r7Kr3/lVOL94eT9Ky+Tm+IqokcaiD5Q9lLzBrvUIz0CJDh27WR+m3qUDN87HH0jA== X-Microsoft-Antispam-Mailbox-Delivery: abwl:0;wl:0;pcwl:0;kl:0;iwl:0;ijl:0;dwl:0;dkl:0;rwl:0;ex:0;auth:1;dest:I;WIMS-SenderIP:40.92.69.49;WIMS-SPF:windowslive%2ecom;WIMS-DKIM:windowslive%2ecom;WIMS-822:trojak3d%40windowslive%2ecom;WIMS-PRA:trojak3d%40windowslive%2ecom;WIMS-AUTH:PASS;ENG:(400001000128)(400125000095)(5062000261)(5061607266)(5061608174)(4900095)(4921089)(4950112)(4990090)(102400140)(400001001223)(400125100095)(61617095)(400001002128)(400125200095); /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIf IiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/wAALCAB4AHgBAREA/8QAHwAAAQUBAQEB AQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1Fh ByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZ WmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APZqKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK/9k= --_004_AM4PR0901MB1219E3152878394D9F48EFB982BC0AM4PR0901MB1219_--";
preg_match($regex_html,$email,$return);
print_r($return);
and heres my function:
function multipart_msg_body($inbox, $email_number){
$structure = imap_fetchstructure($inbox, $email_number);
$encoding_type = array("base64","quoted-printable","8bit","7bit","binary");
$message_body_parts = array();
if (array_key_exists(1,$structure->parameters)){
$type = $structure->parameters[1]->value;
if ($type == "multipart/alternative"){
$message = imap_body($inbox, $email_number);
foreach($encoding_type as $type){
$regex_html = '/(?<=Content-Type: text\/html;).*?(Content-Transfer-Encoding:).*?('.$type.').*?(\);).(.*?)(?= --_)/';
$regex_plain = '/(?<=Content-Type: text\/plain;).*?(Content-Transfer-Encoding:).*?('.$type.').*?(\);).(.*?)(?= --_)/';
$body_html = preg_match($regex_html,$message,$html_match);
$body_plain = preg_match($regex_plain,$message,$plain_match);
print_r($html_match);
if ($body_html){
$message_body_parts["html_".$type] = $html_match;
}
if ($body_plain){
$message_body_parts["plain_".$type] = $body_plain;
}
}
print_r($message_body_parts);
}
}
}
Solved:
Different regex was required as imap_body() and print_r(imap_body()) seem to generate a different string to work with.
function multipart_msg_body($inbox, $email_number){
$structure = imap_fetchstructure($inbox, $email_number);
$encoding_type = array("base64","quoted-printable","8bit","7bit","binary");
$message_body_parts = array();
if (array_key_exists(1,$structure->parameters)){
$type = $structure->parameters[1]->value;
if ($type == "multipart/alternative"){
$message = imap_body($inbox, $email_number, FT_INTERNAL);
foreach($encoding_type as $type){
$regex_html = "/(?<=Content-Type: text\/html;).*?(Content-Transfer-Encoding:).*?(".$type.").*?(\);)(.*?)(--_)/s";
$regex_plain = "/(?<=Content-Type: text\/plain;).*?(Content-Transfer-Encoding:).*?(".$type.").*?(\);)(.*?)(--_)/s";
$body_html = preg_match($regex_html,$message,$html_match);
$body_plain = preg_match($regex_plain,$message,$plain_match);
if ($body_html){
$message_body_parts["html_".$type] = $html_match[4];
}
if ($body_plain){
$message_body_parts["plain_".$type] = $plain_match[4];
}
}
return($message_body_parts);
}
}
}
Right, as I suspected, imap_body() is formed slightly different as a variable on its own to what the result of print_r(imap_body()), I've saved the variable into a file and ammended my regex to work with that, all works sweet now.
New regex:
$regex_html = "/(?<=Content-Type: text\/html;).*?(Content-Transfer-Encoding:).*?(".$type.").*?(\);)(.*?)(--_)/s";
hope this helps, a lot easier and possibly quicker way of finding the plain and html body of a multipart imap message. Thanks for all contributions.
I'm trying to send a calendar invite to Gmail using sendgrid and swiftmailer. This is my entire code:
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
require_once('path/to/lib/swift_required.php');
require('path/to/smtpapi-php.php');
$transport = \Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 587);
$transport->setUsername('uname');
$transport->setPassword('pass');
$mailer = \Swift_Mailer::newInstance($transport);
$ical="BEGIN:VCALENDAR\r\n
PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN\r\n
VERSION:2.0\r\n
METHOD:REQUEST\r\n
Content-Type: text/calendar; charset="utf-8"; name=“invite.ics"; method=REQUEST'."\r\n";
Content-Disposition: inline; filename=“invite.ics"'."\r\n;
BEGIN:VEVENT\r\n
ATTENDEE;CN=aaa#aaa.com;RSVP=
TRUE:mailto:aaa#aaa.com\r\n
CLASS:PUBLIC\r\n
CREATED:20110803T133418Z\r\n
DTEND:20150429T035959Z\r\n
DTSTAMP:20110803T095605Z\r\n
DTSTART:$20150429T170000Z\r\n
LAST-MODIFIED:20110803T133418Z\r\n
ORGANIZER;CN=\”bbb\”:mailto:
bbb#bbb.com\r\n
PRIORITY:5\r\n
SEQUENCE:0\r\n
SUMMARY;LANGUAGE=ro:New Event\r\n
TRANSP:OPAQUE\r\n
UID:".MD5(TIME())."-85d2-69b00dea0ad4\r\n
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE\r\n
X-MICROSOFT-CDO-IMPORTANCE:1\r\n
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY\r\n
X-MICROSOFT-DISALLOW-COUNTER:FALSE\r\n
X-MS-OLK-AUTOSTARTCHECK:FALSE\r\n
X-MS-OLK-CONFTYPE:0\r\n
BEGIN:VALARM\r\n
TRIGGER:-PT15M\r\n
ACTION:DISPLAY\r\n
DESCRIPTION:Reminder\r\n
END:VALARM\r\n
END:VEVENT\r\n
END:VCALENDAR\r\n";
$attachment = Swift_Attachment::newInstance()
->setFilename("invite.ics")
->setContentType('multipart/alternative;charset=UTF-8;name="invite.ics";method=REQUEST')
->setBody($ical)
->setDisposition('inline;filename=invite.ics');
$message = new \Swift_Message();
$message->setTo(array('aaa#aaa.com'));
$message->setFrom('bbb#bbb.co');
$message->setSubject('Hello');
$message->attach($attachment);
try {
$response = $mailer->send($message);
print_r($response);
} catch(\Swift_TransportException $e) {
print_r('Bad username / password');
}
?>
</body>
</html>
What is happening is that it is sending the email with the ics attachment but gmail and outlook are not recognizing that its a calendar invite. Can you please help me?
I've used this link as reference:
ics file not recognized by outlook
Some problems I see immediately:
You are not specifying a text/calendar content type.
You are using the wrong quotes in the content-type header and various other places. (” instead of ").
You are embedding triple-newlines (\n\r\n) because you have both a real newline and a \r\n.
This might not fix it, but it's a starting point. I would recommend taking a good look at the source of the email you are sending, and compare it to a correctly working iMip invite. I'd assume it's not the only problem.
I'm trying to add an attachment to emails that I draft but cannot seem to get it to work. I've tried to follow the examples here and here but without success.
Here's what I'm able to do so far:
Connect to the Exchange server
Open the mailbox
Draft an html email
Append the email to the mailbox and have it render the html correctly. (when using text/html as the content-type). Using anything else displays the html as plaintext.
As an additional note, after being drafted, the emails are appended to a mailbox on an Exchange 2010 server and are viewed then sent via Outlook 2010.
Below is my mailer class and the code to draft the email.
mailer.php
<?php
class mailer
{
const USER = 'user';
const PASSWORD = 'pass';
const MAILBOX = '{conn}DRAFTS';
// STRING ORDER: $content-type . $from . $to . $cc . $subject . "\r\n\r\n" . $message
public $message;
public $imap_conn;
public $boundary;
function __construct()
{
// Open the message property so we can start appending strings.
$this->message = '';
// Open the IMAP connection
$this->imap_conn = imap_open(self::MAILBOX,self::USER,self::PASSWORD);
}
public function content_type($string_type)
{
$this->message .= "Content-type:{$string_type}\r\n";
}
public function from($string_from)
{
$this->message .= "From:{$string_from}\r\n";
}
public function to($string_to)
{
$this->message .= "To:{$string_to}\r\n";
}
public function cc($string_cc)
{
$this->message .= "Cc:{$string_cc}\r\n";
}
public function mime($float_mime_version)
{
$this->message .= "MIME-Version:{$float_mime_version}\r\n";
}
public function subject($string_subject)
{
$this->message .= "Subject:{$string_subject}\r\n\r\n";
}
public function message($string_message)
{
$this->message .= "{$string_message}\r\n";
}
public function set_boundary($string_boundary)
{
$this->boundary = $string_boundary;
}
public function append()
{
imap_append($this->imap_conn,self::MAILBOX,$this->message,"\\Draft");
imap_close($this->imap_conn);
}
}
?>
Draft code
// A random hash used for the boundary
$rh = md5(date('c',time()));
$data = chunk_split(base64_encode('Testing'));
$m = new mailer;
$m->set_boundary('--PHP-mixed-' . $rh);
$m->content_type('multipart/mixed; boundary="' . $m->boundary . '"');
$m->mime('1.0');
$m->from('from#mail.com');
$m->to('to#mail.com');
$m->cc('cc1#mail.com,cc2#mail.com');
$m->subject('A new email');
$m->message("
{$m->boundary}
Content-Type: text/html; charset=\"utf-8\"
Content-Transfer-Encoding: base64
Testing my <b>HTML</b>
</br>
{$m->boundary}
Content-Type: application/octet-stream; name=\"test.txt\"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=\"test.txt\"
{$data}
{$m->boundary}--
"));
$m->append();
The message before its appended
Content-type:multipart/mixed; boundary="--PHP-mixed-b408f941593cf92b5a8bd365abb4e64f"
MIME-Version:1.0
From:from#mail.com
To:to#mail.com
Cc:cc1#mail.com
Subject:New Message
--PHP-mixed-b408f941593cf92b5a8bd365abb4e64f
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: "base64"
My <b>html</b> content
--PHP-mixed-b408f941593cf92b5a8bd365abb4e64f
Content-Type: application/octet-stream; name="test.txt"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.txt"
--PHP-mixed-b408f941593cf92b5a8bd365abb4e64f--
Question: How do I add an attachment to an email drafted with PHP via IMAP?
Answer: In short, the issue was in two places.
Improper placement of newlines (\r\n). A single newline should be after each header and two newlines after each ending header of a section. See Figure 1.
Improper boundaries. Boundaries should start with -- followed by a unique string. The ending boundary of the message should begin and end with -- See Figure 2
Figure 1
Content-Type: text/html\r\n
Content-Encoding: base64\r\n\r\n
"Message text here."\r\n
Figure 2
--unique
Content-Type: text/html\r\n
Content-Encoding: base64\r\n\r\n
HTML stuff here.\r\n
--unique
Content-Type: application/octet-stream\r\n
Content-Disposition: attachment; filename=\"logs.csv\"\r\n
Content-Transfer-Encoding: base64\r\n\r\n
Attachment(s)\r\n
--unique--
I plan on doing a more in depth write-up on this as it took me a very long time to get it right.
It would be helpful to have some more information on your debugging so far. Is the file being read successfully? Does anything make it to the mailbox? It would also help me to see an output of the full message before your final append.
I do not know if this will solve it, but from my successful code and your second example, your message should have an extra filename property, and the values wrapped in quotes.
Content-Type: application/octet-stream; name="test.txt"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.txt"
I am developing a PHP application that needs to retrieve arbitrary emails from an email server. Then, the message is completely parsed and stored in a database.
Of course, I have to do a lot of tests as this task is not really trivial with all that different mail formats under the sun. Therefore I started to "collect" emails from certain clients and with different contents.
I would like to have a script so that I can send out those emails automatically to my application to test the mail handling.
Therefore, I need a way to send the raw emails - so that the structure is exactly the same as they would come from the respective client. I have the emails stored as .eml files.
Does somebody know how to send emails by supplying the raw body?
Edit:
To be more specific: I am searching for a way to send out multipart emails by using their source code. For example I would like to be able to use something like that (an email with plain and HTML part, HTML part has one inline attachment).
--Apple-Mail-159-396126150
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
The plain text email!
--=20
=20
=20
--Apple-Mail-159-396126150
Content-Type: multipart/related;
type="text/html";
boundary=Apple-Mail-160-396126150
--Apple-Mail-160-396126150
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=iso-8859-1
<html><head>
<title>Daisies</title>=20
</head><body style=3D"background-attachment: initial; background-origin: =
initial; background-image: =
url(cid:4BFF075A-09D1-4118-9AE5-2DA8295BDF33/bg_pattern.jpg); =
background-position: 50% 0px; ">
[ - snip - the html email content ]
</body></html>=
--Apple-Mail-160-396126150
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename=bg_pattern.jpg
Content-Type: image/jpg;
x-apple-mail-type=stationery;
name="bg_pattern.jpg"
Content-Id: <4BFF075A-09D1-4118-9AE5-2DA8295BDF33/tbg.jpg>
/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAASAAA/+IFOElDQ19QUk9GSUxFAAEB
[ - snip - the image content ]
nU4IGsoTr47IczxmCMvPypi6XZOWKYz/AB42mcaD/9k=
--Apple-Mail-159-396126150--
Using PHPMailer, you can set the body of a message directly:
$mail->Body = 'the contents of one of your .eml files here'
If your mails contain any mime attachments, this will most likely not work properly, as some of the MIME stuff has to go into the mail's headers. You'd have to massage the .eml to extract those particular headers and add them to the PHPMailer mail as a customheader
You could just use the telnet program to send those emails:
$ telnet <host> <port> // execute telnet
HELO my.domain.com // enter HELO command
MAIL FROM: sender#address.com // enter MAIL FROM command
RCPT TO: recipient#address.com // enter RCPT TO command
<past here, without adding a newline> // enter the raw content of the message
[ctrl]+d // hit [ctrl] and d simultaneously to end the message
If you really want to do this in PHP, you can use fsockopen() or stream_socket_client() family. Basically you do the same thing: talking to the mailserver directly.
// open connection
$stream = #stream_socket_client($host . ':' . $port);
// write HELO command
fwrite($stream, "HELO my.domain.com\r\n");
// read response
$data = '';
while (!feof($stream)) {
$data += fgets($stream, 1024);
}
// repeat for other steps
// ...
// close connection
fclose($stream);
You can just use the build in PHP function mail for it. The body part doesnt have to be just text, it can also contain mixed part data.
Keep in mind that this is a proof of concept. The sendEmlFile function could use some more checking, like "Does the file exists" and "Does it have a boundry set". As you mentioned it is for testing/development, I have not included it.
<?php
function sendmail($body,$subject,$to, $boundry='') {
define ("CRLF", "\r\n");
//basic settings
$from = "Example mail<info#example.com>";
//define headers
$sHeaders = "From: ".$from.CRLF;
$sHeaders .= "X-Mailer: PHP/".phpversion().CRLF;
$sHeaders .= "MIME-Version: 1.0".CRLF;
//if you supply a boundry, it will be send with your own data
//else it will be send as regular html email
if (strlen($boundry)>0)
$sHeaders .= "Content-Type: multipart/mixed; boundary=\"".$boundry."\"".CRLF;
else
{
$sHeaders .= "Content-type: text/html;".CRLF."\tcharset=\"iso-8859-1\"".CRLF;
$sHeaders .= "Content-Transfer-Encoding: 7bit".CRLF."Content-Disposition: inline";
}
mail($to,$subject,$body,$sHeaders);
}
function sendEmlFile($subject, $to, $filename) {
$body = file_get_contents($filename);
//get first line "--Apple-Mail-159-396126150"
$boundry = $str = strtok($body, "\n");
sendmail($body,$subject,$to, $boundry);
}
?>
Update:
After some more testing I found that all .eml files are different. There might be a standard, but I had tons of options when exporting to .eml. I had to use a seperate tool to create the file, because you cannot save to .eml by default using outlook.
You can download an example of the mail script. It contains two versions.
The simple version has two files, one is the index.php file that sends the test.eml file. This is just a file where i pasted in the example code you posted in your question.
The advanced version sends an email using an actual .eml file I created. it will get the required headers from the file it self. Keep in mind that this also sets the To and From part of the mail, so change it to match your own/server settings.
The advanced code works like this:
<?php
function sendEmlFile($filename) {
//define a clear line
define ("CRLF", "\r\n");
//eml content to array.
$file = file($filename);
//var to store the headers
$headers = "";
$to = "";
$subject = "";
//loop trough each line
//the first part are the headers, until you reach a white line
while(true) {
//get the first line and remove it from the file
$line = array_shift($file);
if (strlen(trim($line))==0) {
//headers are complete
break;
}
//is it the To header
if (substr(strtolower($line), 0,3)=="to:") {
$to = trim(substr($line, 3));
continue;
}
//Is it the subject header
if (substr(strtolower($line), 0,8)=="subject:") {
$subject = trim(substr($line, 8));
continue;
}
$headers .= $line . CRLF;
}
//implode the remaining content into the body and trim it, incase the headers where seperated with multiple white lines
$body = trim(implode('', $file));
//echo content for debugging
/*
echo $headers;
echo '<hr>';
echo $to;
echo '<hr>';
echo $subject;
echo '<hr>';
echo $body;
*/
//send the email
mail($to,$subject,$body,$headers);
}
//initiate a test with the test file
sendEmlFile("Test.eml");
?>
You could start here
http://www.dreamincode.net/forums/topic/36108-send-emails-using-php-smtp-direct/
I have no idea how good that code is, but it would make a starting point.
What you are doing is connecting direct to port 25 on the remote machine, as you would with telnet, and issuing smtp commands. See eg http://www.yuki-onna.co.uk/email/smtp.html for what's going on (or see Jasper N. Brouwer's answer).
Just make a quick shell script which processes a directory and call it when you want e.g. using at crontab etc
for I in ls /mydir/ do cat I | awk .. | sendmail -options
http://www.manpagez.com/man/1/awk/
You could also just talk to the mail server using the script to send the emls with a templated body..
Edit: I have added the code to Github, for ease of use by other people. https://github.com/xrobau/smtphack
I realise I am somewhat necro-answering this question, but it wasn't answered and I needed to do this myself. Here's the code!
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
class SMTPHack
{
private $phpmailer;
private $smtp;
private $from;
private $to;
/**
* #param string $from
* #param string $to
* #param string $smtphost
* #return void
*/
public function __construct(string $from, string $to, string $smtphost = 'mailrx')
{
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->SMTPAutoTLS = false;
$mail->Host = $smtphost;
$this->phpmailer = $mail;
$this->from = $from;
$this->to = $to;
}
/**
* #param string $helo
* #return SMTP
*/
public function getSmtp(string $helo = ''): SMTP
{
if (!$this->smtp) {
if ($helo) {
$this->phpmailer->Helo = $helo;
}
$this->phpmailer->smtpConnect();
$this->smtp = $this->phpmailer->getSMTPInstance();
$this->smtp->mail($this->from);
$this->smtp->recipient($this->to);
}
return $this->smtp;
}
/**
* #param string $data
* #param string $helo
* #param boolean $quiet
* #return void
* #throws \PHPMailer\PHPMailer\Exception
*/
public function data(string $data, string $helo = '', bool $quiet = true)
{
$smtp = $this->getSmtp($helo);
$prev = $smtp->do_debug;
if ($quiet) {
$smtp->do_debug = 0;
}
$smtp->data($data);
$smtp->do_debug = $prev;
}
}
Using that, you can simply beat PHPMailer into submission with a few simple commands:
$from = 'xrobau#example.com';
$to = 'fred#example.com';
$hack = new SMTPHack($from, $to);
$smtp = $hack->getSmtp('helo.hostname');
$errors = $smtp->getError();
// Assuming this is running in a phpunit test...
$this->assertEmpty($errors['error']);
$testemail = file_get_contents(__DIR__ . '/TestEmail.eml');
$hack->data($testemail);