当前位置:Linux教程 - Php - 最好的邮件编码解码类

最好的邮件编码解码类

<?php
  
function build_text_body($body) {
        return
"\n<pre>".$this->make_link_clickable($this->linesize(htmlspecialchars($body),85))."</pre>\n";
    }

    function
decode_qp($text) {
        
$text = quoted_printable_decode($text);
        
/*
        $text = str_replace("\r","",$text);
        $text = ereg_replace("=\n", "", $text);
        $text = str_replace("\n","\r\n",$text);
        */
        
$text = ereg_replace("=\r", "\r", $text);
        return
$text;
    }

    function
make_link_clickable($text){
        
$text = eregi_replace("([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])",
            
"<a class=\"autolink\" href=\"\\1://\\2\\3\" target=\"_new\">\\1://\\2\\3</a>", $text);
        
$text = eregi_replace("([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,3})","<a class=\"autolink\"  href=\"newmsg.php?mailto=\\1&nameto=\\1\">\\1</a>", $text);
        return
$text;
    }

    function
process_message($header,$body) {
        global
$mime_show_html;
        
$mail_info = $this->get_mail_info($header);

        
$ctype = $mail_info["content-type"];
        
$ctenc = $mail_info["content-transfer-encoding"];

        if(
$ctype == "") $ctype = "text/plain";

        
$type = $ctype;

        
$ctype = split(";",$ctype);
        
$types = split("/",$ctype[0]);

        
$maintype = strtolower($types[0]);
        
$subtype = strtolower($types[1]);

        switch(
$maintype) {
        case
"text":
            
$body = $this->compile_body($body,$ctenc);
            switch(
$subtype) {
            case
"html":
                if(!
$mime_show_html)
                    
$body = $this->build_text_body(strip_tags($body));
                
$msgbody = $body;
                break;
            default:
                
$msgbody = $this->build_text_body($body);
                break;
            }
            break;
        case
"multipart":
            switch(
$subtype) {
            case
"mixed":
                
$boundary = $this->get_boundary($type);
                
$part = $this->split_parts($boundary,$body);

                for(
$i=0;$i<count($part);$i++) {
                    
$thispart = trim($part[$i]);

                    if(
$thispart != "") {
                        
$email = $this->fetch_structure($thispart);
    
                        
$header = $email["header"];
                        
$body = $email["body"];
                        
$headers = $this->decode_header($header);
                        
$ctype = $headers["content-type"];
    
                        
$Actype = split(";",$headers["content-type"]);
                        
$types = split("/",$Actype[0]); $rctype = strtolower($Actype[0]);
    
                        if(
$rctype == "multipart/alternative")
                            
$msgbody = $this->build_alternative_body($ctype,$body);
                        elseif(
$rctype == "text/plain" && strpos($headers["content-disposition"],"name") === false) {
                            
$msgbody = $this->build_text_body($this->compile_body($body,$headers["content-transfer-encoding"]));
                        } elseif(
$rctype == "text/html" && strpos($headers["content-disposition"],"name") === false) {
                            
$body = $this->compile_body($body,$headers["content-transfer-encoding"]);
                            if(!
$mime_show_html)
                                
$body = $this->build_text_body(strip_tags($body));
                            
$msgbody = $body;
                        } elseif(
$rctype == "multipart/related" && strpos($headers["content-disposition"],"name") === false) {
                            
$msgbody = $this->build_related_body($ctype,$body);
                        } else {
                            
$thisattach = $this->build_attach($header,$body,$boundary,$i);
                        }
                    }
                }
                break;
            case
"alternative":
                
$msgbody = $this->build_alternative_body($ctype[1],$body);
                break;
            case
"related":
                
$msgbody = $this->build_related_body($type,$body);
                break;
            default:
                
$thisattach = $this->build_attach($header,$body,"",0);
            }
            break;
        default:
            
$thisattach = $this->build_attach($header,$body,"",0);
        }
        return
$msgbody;
    }

    function
build_attach($header,$body,$boundary,$part) {
        global
$mail,$temporary_directory,$userfolder;

        
$headers = $this->decode_header($header);
        
$cdisp = $headers["content-disposition"];
        
$ctype = $headers["content-type"]; $ctype2 = explode(";",$ctype); $ctype2 = $ctype2[0];
        
        
$Atype = split("/",$ctype);
        
$Acdisp = split(";",$cdisp);

        
$tenc = $headers["content-transfer-encoding"];

        if(
$temp) $dir_to_save = $userfolder; //"temporary_files/";

        
if($Atype[0] == "message") {
            
$divpos = strpos($body,"\n\r");
            
$attachheader = substr($body,0,$divpos);
            
$attachheaders = $this->decode_header($attachheader);
            
$filename = $this->decode_mime_string($attachheaders["subject"]);
            if(
$filename == "")
                
$filename = uniqid("");
            
$filename = substr(ereg_replace("[^A-Za-z0-9]","_",$filename),0,20).".eml";
        } else {
            
$fname = $Acdisp[1];
            
$filename = substr($fname,strpos($fname,"filename=")+9,strlen($fname));
            if(
$filename == "")
                
$filename = substr($ctype,strpos($ctype,"name=")+5,strlen($ctype));
            if(
substr($filename,0,1) == "\"" && substr($filename,-1) == "\"")
                
$filename = substr($filename,1,strlen($filename)-2);
            
$filename = $this->decode_mime_string($filename);
        }


        if(
$Atype[0] != "message")
            
$body = $this->compile_body($body,$tenc);

        
$indice = count($this->content["attachments"]);
        
$this->content["attachments"][$indice]["name"] = $filename;
        
$this->content["attachments"][$indice]["size"] = strlen($body);
        
$this->content["attachments"][$indice]["temp"] = $temp;
        
$this->content["attachments"][$indice]["content-type"] = $ctype2; //$Atype[0];
        
$this->content["attachments"][$indice]["content-disposition"] = $Acdisp[0];
        
$this->content["attachments"][$indice]["boundary"] = $boundary;
        
$this->content["attachments"][$indice]["part"] = $part;
        return
$this->content["attachments"][$indice];
    }

    function
compile_body($body,$enctype) {
        
$enctype = explode(" ",$enctype); $enctype = $enctype[0];
        if(
strtolower($enctype) == "base64")
            
$body = base64_decode($body);
        elseif(
strtolower($enctype) == "quoted-printable")
            
$body = $this->decode_qp($body);
        return
$body;

    }

    function
download_attach($header,$body,$down=1) {
        
$headers = $this->decode_header($header);

        
$cdisp = $headers["content-disposition"];
        
$ctype = $headers["content-type"];

        
$type = split(";",$ctype); $type = $type[0];
        
$Atype = split("/",$ctype);
        
$Acdisp = split(";",$cdisp);
        
$tenc = strtolower($headers["content-transfer-encoding"]);

        if(
$Atype[0] == "message") {
            
$divpos = strpos($body,"\n\r");
            
$attachheader = substr($body,0,$divpos);
            
$attachheaders = $this->decode_header($attachheader);
            
$filename = $this->decode_mime_string($attachheaders["subject"]);
            if(
$filename == "")
                
$filename = uniqid("");
            
$filename = substr(ereg_replace("[^A-Za-z0-9]","_",$filename),0,20);
            
$filename .= ".eml";
        } else {
            
$fname = $Acdisp[1];
            
$filename = substr($fname,strpos(strtolower($fname),"filename=")+9,strlen($fname));
            if(
$filename == "")
                
$filename = substr($ctype,strpos(strtolower($ctype),"name=")+5,strlen($ctype));
            if(
substr($filename,0,1) == "\"" && substr($filename,-1) == "\"")
                
$filename = substr($filename,1,strlen($filename)-2);
            
$filename = $this->decode_mime_string($filename);
        }

        if(
$Atype[0] != "message")
            
$body = $this->compile_body($body,$tenc);

        
$content_type = ($down)?"application/octet-stream":strtolower($type);
        
$filesize = strlen($body);

        
header("Content-Type: $content_type; name=\"$filename\"\r\n"
        
."Content-Length: $filesize\r\n");
        
$cdisp = ($down)?"attachment":"inline";
        
header("Content-Disposition: $cdisp; filename=\"$filename\"\r\n");
        echo(
$body);
    }

    function
get_mail_info($header) {
        
$myarray = Array();
        
$headers = $this->decode_header($header);

        
/*
        echo("<pre>");
        print_r($headers);
        echo("</pre>");
        */

        
$message_id = $headers["message-id"];

        if(
substr($message_id,0,1) == "<" && substr($message_id,-1) == ">")
            
$message_id = substr($message_id,1,strlen($message_id)-2);

        
$myarray["content-type"] = $headers["content-type"];
        
$myarray["content-transfer-encoding"] = str_replace("GM","-",$headers["content-transfer-encoding"]);
        
$myarray["message-id"] = $message_id;

        
$received = $headers["received"];

        if(
$received != "") {
            
$received = explode(";",$received);
            
$mydate = $received[1];
        } else
            
$mydate = $headers["date"];

        
$myarray["date"] = $this->build_mime_date($mydate);
        
$myarray["subject"] = $this->decode_mime_string($headers["subject"]);
        
$myarray["from"] = $this->get_names($headers["from"]);
        
$myarray["to"] = $this->get_names($headers["to"]);
        
$myarray["cc"] = $this->get_names($headers["cc"]);
        
$myarray["status"] = $headers["status"];
        
$myarray["read"] = ($headers["status"] == "N")?0:1;

        return
$myarray;

    }

    function
build_mime_date($mydate) {

        
$mydate = explode(",",$mydate);
        
$mydate = trim($mydate[count($mydate)-1]);
        
$parts = explode(" ",$mydate);
        if(
count($parts) < 4) { return time(); }
        
$day = $parts[0];

        switch(
strtolower($parts[1])) {
            case
"jan": $mon = 1; break;
            case
"feb":    $mon = 2; break;
            case
"mar":    $mon = 3; break;
            case
"apr":    $mon = 4; break;
            case
"may":    $mon = 5; break;
            case
"jun": $mon = 6; break;
            case
"jul": $mon = 7; break;
            case
"aug": $mon = 8; break;
            case
"sep": $mon = 9; break;
            case
"oct": $mon = 10; break;
            case
"nov": $mon = 11; break;
            case
"dec": $mon = 12; break;
        }
        
        
$year = $parts[2];
        
$ahours = explode(":",$parts[3]);
        
$hour = $ahours[0]; $min = $ahours[1]; $sec = $ahours[2];

        return
mktime ($hour, $min, $sec, $mon, $day, $year);

    }

    function
initialize($email) {
        
$email = $this->fetch_structure($email);
        
$body = $email["body"];
        
$header = $email["header"];
        
$mail_info = $this->get_mail_info($header);

        
$this->content["headers"] = $header;
        
$this->content["date"] = $mail_info["date"];
        
$this->content["subject"] = $mail_info["subject"];
        
$this->content["message-id"] = $mail_info["message-id"];
        
$this->content["from"] = $mail_info["from"];
        
$this->content["to"] = $mail_info["to"];
        
$this->content["cc"] = $mail_info["cc"];
        
$this->content["body"] = $this->process_message($header,$body);
        
$this->content["read"] = $mail_info["read"];
    }

    function
split_parts($boundary,$body) {
        
$startpos = strpos($body,"$boundary")+strlen("$boundary")+2;
        
$lenbody = strpos($body,"\r\n$boundary--") - $startpos;
        
$body = substr($body,$startpos,$lenbody);
        return
split($boundary."\r\n",$body);
    }

    function
get_boundary($ctype){
        
$boundary = trim(substr($ctype,strpos(strtolower($ctype),"boundary=")+9,strlen($ctype)));
        
$boundary = split(";",$boundary);$boundary = $boundary[0];

        if(
substr($boundary,0,1) == "\"" && substr($boundary,-1) == "\"")
            
$boundary = substr($boundary,1,strlen($boundary)-2);
        
$boundary = "--".$boundary;
        return
$boundary;
    }

    function
set_as($email,$type=1) {
        
$status = ($type)?"Y":"N";
        
$tempmail = $this->fetch_structure($email);
        
$thisheader = $tempmail["header"];
        
$mail_info = $this->get_mail_info($thisheader);
        
$decoded_headers = $this->decode_header($thisheader);

        while(list(
$key,$val) = each($decoded_headers))
            if (
eregi("status",$key)) {
                
$newmail .= ucfirst($key).": $status\r\n"; $headerok = 1;
            } else
$newmail .= ucfirst($key).": ".trim($val)."\r\n";
        if(!
$headerok) $newmail .= "Status: $status\r\n";
        
$newmail = trim($newmail)."\r\n\r\n".trim($tempmail["body"]);
        return
$newmail;
    }

}
?>