imap_fetchbody - Encoded body error - php

I am trying to fetch a particular section of an email body using:
$message = imap_fetchbody ($imap_stream,$n,1);
This works fine for emails sent using Outlook, Hotmail, Yahoo etc. But when I try and fetch the body of the an email sent from a Blackberry or Andriod device, the message is encoded and scrambled such as:
xmb250IHN0eWxlPSdjb2xvcjojRjk3MWIxMDNiMTEyYjExOGI0N2I1MWI1
Although the body is encoded, the header is fine. How do I decode the message body of en email sent from an Android or Blackberry device?
Thank you,
Chris.

You should be able to run imap_fetchstructure to get the encoded value. If that value equals 3 you need to decode via imap_base64.
I've used the following before (Can't remember if it was ever tested with sent mobile email before though):
$structure = imap_fetchstructure($stream, $msgno);
$text = imap_fetchbody($stream, $msgno, $partnum);
if($structure->encoding == 3) {
$text = imap_base64($text);
} else if($structure->encoding == 4) {
$text = imap_qprint($text);
}

Related

Quoted-printable Email Subject lines not getting decoded by email clients

I've written a WordPress plugin which sends out new post notifications. There is a setting to convert subject lines from html entites to quoted-printable so they'll display in UTF-8 on any email client. A few weeks ago I started getting reports that the quoted-printable subject line was being kept as-is instead of being decoded.
Sample Subject header:
Subject: =?UTF-8?Q?[Pranamanasyoga]=20Foro=20Pranamanasyoga=20:=20estr?= =?UTF-8?Q?=C3=A9s=20y=20resilencia?=
I cannot replicate it locally and have not been able to find any common denominators between reporters.
The code that generates the quoted-printable line is this:
<?php
$enc = iconv_get_encoding( 'internal_encoding' ); // this is UTF-8
$preferences = ['input-charset' => $enc, 'output-charset' => "UTF-8", 'scheme' => 'Q' ];
$filtered_subject = '[Pranamanasyoga] Foro Pranamanasyoga : estrés y resilencia';
$encoded = iconv_mime_encode( 'Subject', html_entity_decode( $filtered_subject ), $preferences );
$encoded = substr( $encoded, strlen( 'Subject: ' ) );
If I try decoding it, it works fine:
$decoded = iconv_mime_decode($encoded, 0, "UTF-8");
var_dump(['encoded' => $encoded, 'decoded' => $decoded])."\n";
Result:
array(2) {
["encoded"]=>
string(102) "=?UTF-8?Q?[Pranamanasyoga]=20Foro=20Pranamanasyoga=20:=20estr?=
=?UTF-8?Q?=C3=A9s=20y=20resilencia?="
["decoded"]=>
string(59) "[Pranamanasyoga] Foro Pranamanasyoga : estrés y resilencia"
}
One thing I noticed, but think is not related is that my code actually adds a newline before the second =?UTF-8?Q? piece and the email subject header does not have it. Decoding the strings with- and without the newline works the same.
Does anyone have ideas/suggestions on what may be causing the email clients (Gmail included) to display the string as-is, instead of decoding it to UTF-8?
P.S. While writing this I saw a suggestion to use mb_encode_mimeheader() in a different thread. It seems to work well with iconv_mime_decode() in my test code, but the output string is indeed different from the original one:
[Pranamanasyoga] Foro Pranamanasyoga : =?UTF-8?Q?estr=C3=A9s=20y=20resile?=
=?UTF-8?Q?ncia?=
Could it be that email clients would prefer this format over the original one?

How detect if message body is TNEF format (winmail.dat)?

How detect/check if message body is tnef format (winmail.dat) using PHP?
I don't want to decode, just want to check. I using imap_fetchbody and imap_body for get BODY, I need get mimetype (or like) for check if is "tnef format", like this:
if (in_array($bodyMimeType, array('application/tnef', 'application/x-tnef', 'application/ms-tnef'))) {
//Decode
}
I tried:
$structure = imap_fetchstructure($imap, $messageId, FT_UID);
echo 'sub-type:', $structure->subtype, PHP_EOL;
echo 'encoding:', $structure->encoding, PHP_EOL;
I think there's no way to know without decoding, I'm decoding it and check the status if it is successful using exec(), exec("tnef {$datfile} 2>&1", $output, $status), if it is successfully decoded, $status will be 0.

How to parse japanese char (utf8?) from imap_fetchbody?

I am pulling down an email which has english, chinese and japanese in the email.
I was using PHP/EZComponents to do this, but a certain japanese char was just not coming through so I am switching to php imap_* funcs to see if they will work.
This is what I have below, and the output I am getting. I need to decode this somehow... I know this has been well (read:overly/chaotically) documented all over the web, but I dont have time to earn a PHD in this right now. Any help is greatly appreciated.
$hn='{imap.gmail.com:993/imap/ssl}INBOX';
$inbox = imap_open($hn,$username,$password,CL_EXPUNGE);
foreach($emails as $email_number) {
$ov = imap_fetch_overview($inbox,$email_number,0);
$msg = imap_fetchbody($inbox,$email_number,2);
var_dump($msg);
// doesnt work... .. but right idea?
// var_dump( utf8_decode($msg) );
}
PARTIAL OUTPUT:
<font face=3D"Arial"><span lang=3D"EN-US" style=3D"font-size:10.5pt"><br></=
span></font><font color=3D"navy" face=3D"MS Gothic"><span lang=3D"JA" style=
=3D"font-size:10.5pt">=CC=EC=9A=DD=A4=AC=A4=A4=A4=A4=A4=AB=A4=E9=A1=A2</spa=
n></font></p><p style=3D"margin-right:0pt;margin-bottom:12pt;margin-left:0p=
t">
<font color=3D"navy" face=3D"MS Gothic"><span lang=3D"JA" style=3D"font-siz=
e:10.5pt"><br></span></font></p><p style=3D"margin-right:0pt;margin-bottom:=
12pt;margin-left:0pt"><font color=3D"navy" face=3D"MS Gothic"><span lang=3D=
"JA" style=3D"font-size:10.5pt">xxend</span></font></p>
I also met this problem employed imap_fetchbody function to get the mail body.
I found that the string get from imap_fetchbody was converted to quoted-printable string automatically.
I resolved this issue by using imap_qprint function to convert the fetched string body into correct one.

Sending SMS using PHP API with unicode message

I trying to send SMS via RoutoMessaging PHP API. I readed all documentation and examples what i was able to find.
They have PHP example script for sending SMS in unicode format:
<?php
// include RoutoSMS class
include("RoutoTelecomSMS.php");
// creating object
$sms = new RoutoTelecomSMS;
// setting login parameters
$sms->SetUssms->SetOwnNum("44792838383838");
$sms->SetType("unicode");
// get values entered from FORM
$sms->SetNumber($number);
$message="04220432043E04580435002004370435043B0435043D04350020043E0
44704380020044104430020043C04380020043F0430043C043504420020043F043E
043C044304420438043B0435002E002E002E";
$sms->SetMessage($message);
// send SMS and print result
$smsresult = $sms->Send();
print $smsresult;
?>
What i not understand is how i can transform text from submited string to this code needed for including in $message.
Can anyone suggest function to convert text for $message please?
I currently work with PHP version 5.3.3.
The message you are sending is a Cryllic text. It's probably in Serbian. It reads as "Твоје зелене очи су ми памет помутиле..."
Decoding
header('Content-Type: text/html; charset=utf-8');
$str = "04220432043E04580435002004370435043B0435043D04350020043E044704380020044104430020043C04380020043F0430043C043504420020043F043E043C044304420438043B0435002E002E002E";
foreach(str_split($str, 4) as $char) echo "&#x{$char};";
And this is how you would encode the message
$string = "Твоје зелене очи су ми памет помутиле...";
$string = mb_convert_encoding($string, 'UCS-2', 'utf8');
for($i =0; $i < strlen($string); $i++)
echo strtoupper(bin2hex($string[$i]));

How to use special characters in recipients name when using PHP's mail function

How can I send an email formatted as "Name <user#example.com>" to:
ŠŒŽœžŸ¥µÀÁÃÄÅÆÇÉÊËÍÎÏÐÒÓÕÖØÙÜÝßàáâåæçèéëìíîïðñóôõöøùûýÿ <user#example.com>
Obviously, many of these characters will never show up in a name, but in case they do, I would prefer that they do not prevent an email from being successfully sent.
Currently, this fails as noted in Apache's error.log with
Ignoring invalid 'To:' recipient address
'¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ
' Transaction aborted: no recipients specified
If possible, I would like to keep the special characters 'as they are.'
Otherwise, can I use some sort of transliteration function to clean-up the name?
Example of usage:
<?php
$to = "ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ <CHANGED#gmail.com>";
$subject = "Test Subject";
$body = "Test Body";
if (mail($to, $subject, $body)) {
echo("<p>Message successfully sent!</p>");
} else {
echo("<p>Message delivery failed...</p>");
}
?>
mb_encode_mimeheader should do it, just as shown in the example:
mb_internal_encoding('UTF-8');
$name = '山本';
$email = 'yamamoto#example.com';
$addr = mb_encode_mimeheader($name, 'UTF-8', 'Q') . " <$email>";
For better compatibility you should set the header Mime-Version: 1.0 so all mail clients understand you're using MIME encoding.
The final email headers should look like this:
To: =?UTF-8?Q?=E5=B0=81=E3=83=90=E3=83=BC?= <yamamoto#example.com>
Subject: =?UTF-8?Q?=E3=81=93=E3=82=93=E3=81=AB=E3=81=A1=E3=81=AF?=
Mime-Version: 1.0
Renders as:
To: 山本 <yamamoto#example.com>
Subject: こんにちは
Related: https://stackoverflow.com/a/13569317/476
In addition to #deceze's answer, when using Quoted Printable mode it may be necessary to escape any quotes in the name on any to/from/reply-to/etc headers:
$addr = '"'.str_replace('"', '\"', mb_encode_mimeheader($name, 'UTF-8', 'Q'))."\" <$email>";
Perhaps this isn't necessary for all MTAs, but at least for me a name with a " lead the MTA to interpret the header as multiple local addresses.
RFC-821 (2821) tells us, that all and any 8bit-data in headers field must be encoded. Base64 or QuotedPrintable, as you want and can. Most e-mail readers automatically decode encoded strings

Categories