Help - Trouble decoding email subject header [SOLVED]

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
paulcobb
Forum Newbie
Posts: 4
Joined: Thu May 28, 2009 1:21 pm

Help - Trouble decoding email subject header [SOLVED]

Post by paulcobb »

Hi,

I am writing a script that checks an IMAP email account and retrieves the message, subject,sender etc. the script then forwards this on using send mail.

If the email subject is long I get an error Warning: iconv_mime_decode() [function.iconv-mime-decode]: Malformed string in XXX

I have worked around this by changin the iconv_mime_decode by setting the bitmask to '2' continue if error. But now the string is shortened!

Any ideas please

Here is the part of the code that deals with decoding the header:

Code: Select all

$struct     = imap_fetchstructure($mbox, $i);
    $header     = imap_headerinfo($mbox, $i, 80, 80);
    $subject    = $header->fetchsubject;
    $subjectdecoded = iconv_mime_decode($subject, 2, "ISO-8859-1");
    
   
Thanks,

Paul
Last edited by paulcobb on Mon Jun 08, 2009 4:59 pm, edited 2 times in total.
User avatar
Darhazer
DevNet Resident
Posts: 1011
Joined: Thu May 14, 2009 3:00 pm
Location: HellCity, Bulgaria

Re: Help - Trouble decoding email subject header

Post by Darhazer »

What $subjects looks like when it is long? maybe it is split into 2 lines and contains \n character ?
paulcobb
Forum Newbie
Posts: 4
Joined: Thu May 28, 2009 1:21 pm

Re: Help - Trouble decoding email subject header

Post by paulcobb »

Hi,

Sorry it took me a while to reply!

Here is a full breakdown of the problem.

I have set up an email account which only receives email 'alerts', I have written a script below that accesses the email account downloads the emails, checks them for specific phrase in the subject, and if present sends out an email to an SMS gateway (email to SMS) I need the subject of the original email to be passed to the SMS gateway.

I have obviously altered to generic domains, and added a debug 'if' to send the email to me insted of the SMS gateway

Code: Select all

 
#!/usr/local/bin/php -q
<?php
 
# -- USER DEFINED SETTINGS -----------------------------------------------
 
$imap_server    = "my mail server";
$imap_port  = "143";                // 143 for IMAP
$imap_user  = "email account user";
$imap_password  = "email account password";
 
// The following variable and the subject line of the email must match
// in order for the email to be posted to Twitter.
$filter = "Property Alert";
 
 
$debug='1';
 
 
$filterlower = strtolower($filter);
$imap_mailbox   = "{" . $imap_server . ":" . $imap_port . "}";
$imap_type      = "IMAP";
 
# Login to the specified IMAP server.
$mbox = imap_open("{" . $imap_server . ":" . $imap_port . "/imap/notls}INBOX", $imap_user, $imap_password);
if (!$mbox) {
    die("Error connecting to the mail server ...\n");
}
 
# If there are no messages on the server then quit.
$mbox_info = imap_status($mbox, "{" . $imap_server . ":" . $imap_port . "/imap/notls}INBOX", SA_MESSAGES);
if ($mbox_info) {
    if ($mbox_info->messages <= 0) {
        echo "There are no messages awaiting on the server ...\n";
        imap_close($mbox);
        exit;
    }
}
 
if ($debug == 1) {
    echo "<h1>Headers in INBOX</h1>\n";
    $headers = imap_headers($mbox);
    echo "<code>";
    print_r($headers);
    echo "</code><br /><br />";
 
    if ($headers == false) {
        echo "Call failed<br />\n";
    } else {
        foreach ($headers as $val) {
            echo $val . "<br />\n";
       }
    }
}
 
# Cycle through the mailbox and send new mail as an SMS.
if ($debug == 1) {
    echo "<h1>Mailbox Contents</h1>\n";
}
for ($i = 1; $i <= imap_num_msg($mbox); $i++) {
    $struct     = imap_fetchstructure($mbox, $i);
    $header     = imap_headerinfo($mbox, $i, 80, 80);
    $subject    = $header->fetchsubject;
    $subjectdecoded = iconv_mime_decode($subject, 1, "ISO-8859-1");
    $subjectfinal = $subjectdecoded;
    $subjectlower = strtolower($subjectdecoded);
    if (($struct->type == 0) && (sizeof($struct->parts) == 0))
        {$message   = imap_fetchbody($mbox, $i, "1");}
    else
        {$message   = imap_body($mbox, $i);}
    $message = trim(substr($message, 0, 154));
    $message = strip_tags($message, "<a><br><br />");
    $message = urlencode($message);
 
    # IF there are actual characters in the message AND
    # IF the subject of the email matches the subject specified in the options above
    # THEN attempt to post the message to SMS gateway via email.
    
    
    $pos = strpos($subjectlower,$filterlower);
 
    if(strlen($message) > 0 && $pos !== false) {
        if ($debug == 1) {
            echo "From: " . $header->fromaddress . "<br />\n";
            echo "Subj: " . $subjectfinal . "<br /><br />\n\n";
            //echo nl2br($message) . "<br /><br />\n\n";
            
        }
        
        # Send SMS Alert
        //$notifysms = 'cell phone number';
        $admin_email = 'fromemail@mydomain';
        $headers = 'From: ' . $admin_email . "\r\n" .'Reply-To: ' . $admin_email . "\r\n" .'X-Mailer: PHP/';
        $smssubject = 'From: '. $header->fromaddress .' '.$subjectfinal.'.';
        //$to = $notifysms.'.mysmsgateway.com';    //  email to sms gateway
        $smsbody = "Please Check your Email for Details.\n";
        //mail($to, $smssubject, $smsbody, $headers);
        if ($debug == 1) {
        echo "Mail sent to: " . $to . "<br />\n";
        echo "Subject: " . $smssubject . "<br />\n";
        echo "Filter: " .$pos."<br />\n";
        $to = 'debugemail@mydomain.com';
        mail($to, $subject, $smsbody, $headers);
        }
        
    } else {
        echo "Message " . $i . "; ERROR: non-existent message or security subject string mismatch <br />\nStructure Type: ".$struct->type."<br />\nEncoding: ".$struct->encoding."<br />\nPOS: ".$pos."<br />\nSubject: ".$subject."<br />\nFilter Lower: ".$filterlower."<br />\nSubject Decoded: ".$subjectdecoded."<br />\nSubject Final: ".$subjectfinal."<br />\nSubject Lower: ".$subjectlower." ...<br />\n ...<br />\n";
        $to = 'debugemail@mydomain.com';
        $errorsubject = 'WEB ALERT ERROR REPORT';
        $headers = 'From: ' . $admin_email . "\r\n" .'Reply-To: ' . $admin_email . "\r\n" .'X-Mailer: PHP/';
        $errorbody ="Structure Type:".$struct->type."<br />\nEncoding: ".$struct->encoding."<br />\nPOS: ".$pos."<br />\nSubject: ".$subject."<br />\nFilter Lower: ".$filterlower."<br />\nSubject Decoded: ".$subjectdecoded."<br />\nSubject Final: ".$subjectfinal."<br />\nSubject Lower: ".$subjectlower." ...<br />\n";
        mail($to, $errorsubject, $errorbody, $headers);
    }
 
    imap_delete($mbox, $i);
}
 
imap_expunge($mbox);
imap_close($mbox);
?>
 
 
The problem seems to be created around lines 63-65 as follows:
If I send my own test email to the imap box with the subject 'property alert' all works fine, the full subject is passed to the mail function and arrives intact.

If I go live using this then if the subject is not decode correctly and I get a

Code: Select all

Warning: iconv_mime_decode() [function.iconv-mime-decode]: Malformed string in /mypath/myfile.php on line 64
My subject should read "Property Alert - Whitehaven, Cumbria - £64,000 Great location, recently refurbished"

In my debug mode I can see that the subject looks like this "?iso-8859-1?Q?Property_Alert_-_Whitehaven=2C_Cumbria_-_=A364=2C000_Great?= =?is"

If I change the icinv_mime_decode parameter from 1 to 2 th malformed string error goes but the subject is now limited to around 57 characters, and intermittently has code added to the end as follows:
"Property Alert - Whitehaven, Cumbria - £64,000 Great =?is"

I initially ran the script without the iconv_mime_decode and the subject looked like this:
"Subject: =?iso-8859-1?Q?Property_Alert_-_Whitehaven=2C_Cumbria_-_=A364=2C000_Great?= =?is"
thought this was a decoding issue so added the line:

Code: Select all

$subjectdecoded = iconv_mime_decode($subject, 2, "ISO-8859-1");
with no change

Anyone come across this before or any pointers to a solution would be greatly appreciated.

Many thanks,

Paul
Last edited by Benjamin on Mon Jun 08, 2009 11:00 am, edited 1 time in total.
Reason: Changed code type from text to php.
paulcobb
Forum Newbie
Posts: 4
Joined: Thu May 28, 2009 1:21 pm

Re: Help - Trouble decoding email subject header

Post by paulcobb »

Hi all,

I have changed this code:

Code: Select all

    $header     = imap_headerinfo($mbox, $i, 80, 80);
    $subject    = $header->fetchsubject;
    $subjectdecoded = iconv_mime_decode($subject, 2, "ISO-8859-1");
to this:

Code: Select all

    $header     = imap_headerinfo($mbox, $i, 80, 150);
    $subject    = $header->fetchsubject;
    $subjectdecoded = iconv_mime_decode($subject, 1, "ISO-8859-1");
Problem solved!
Post Reply