From 9ffc20d6cf926571b932ece829d7b0d9f1be0354 Mon Sep 17 00:00:00 2001 From: haneul Date: Wed, 30 Dec 2009 09:29:09 +0000 Subject: [PATCH] #18577270 #18458117 : improved mail class - support attachments, additional headers, fixed the duplicated mail problem git-svn-id: http://xe-core.googlecode.com/svn/sandbox@7083 201d5d3c-b55e-5fd7-737f-ddc643e51545 --- classes/mail/Mail.class.php | 267 ++++++++++++++++++++++++++++++++---- 1 file changed, 243 insertions(+), 24 deletions(-) diff --git a/classes/mail/Mail.class.php b/classes/mail/Mail.class.php index 761e7bc1f..21657b197 100644 --- a/classes/mail/Mail.class.php +++ b/classes/mail/Mail.class.php @@ -13,9 +13,29 @@ var $title = ''; var $content = ''; var $content_type = 'html'; + var $messageId = null; + var $replyTo = null; + var $bcc = null; + var $attachments = array(); + var $cidAttachments = array(); + var $mainMailPart = null; + var $body = ''; + var $header = ''; + var $eol = ''; + function Mail() { } + function addAttachment($filename, $orgfilename) + { + $this->attachments[$orgfilename] = $filename; + } + + function addCidAttachment($filename, $cid) + { + $this->cidAttachments[$cid] = $filename; + } + function setSender($name, $email) { $this->sender_name = $name; $this->sender_email = $email; @@ -32,7 +52,7 @@ } function getReceiptor() { - if($this->receiptor_name) return sprintf("%s <%s>", '=?utf-8?b?'.base64_encode($this->receiptor_name).'?=', $this->receiptor_email); + if($this->receiptor_name && $this->receiptor_name != $this->receiptor_email) return sprintf("%s <%s>", '=?utf-8?b?'.base64_encode($this->receiptor_name).'?=', $this->receiptor_email); return $this->receiptor_email; } @@ -44,6 +64,20 @@ return '=?utf-8?b?'.base64_encode($this->title).'?='; } + function setBCC($bcc) + { + $this->bcc = $bcc; + } + + function setMessageID($messageId) { + $this->messageId = $messageId; + } + + function setReplyTo($replyTo) + { + $this->replyTo = $replyTo; + } + function setContent($content) { $content = preg_replace_callback('/]+)>/i',array($this,'replaceResourceRealPath'), $content); $this->content = $content; @@ -58,38 +92,103 @@ } function getHTMLContent() { - return chunk_split(base64_encode($this->content_type=='html'?nl2br($this->content):$this->content)); + return chunk_split(base64_encode($this->content_type!='html'?nl2br($this->content):$this->content)); } function setContentType($mode = 'html') { $this->content_type = $mode=='html'?'html':''; } + function procAttachments() + { + if(count($this->attachments) > 0) + { + $this->body = $this->header.$this->body; + $boundary = '----=='.uniqid(rand(),true); + $this->header = "Content-Type: multipart/mixed;".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol; + $this->body = "--".$boundary.$this->eol.$this->body.$this->eol.$this->eol; + $res = array(); + $res[] = $this->body; + foreach($this->attachments as $filename => $attachment) + { + $type = $this->returnMIMEType($filename); + $file_str = FileHandler::readFile($attachment); + $chunks = chunk_split(base64_encode($file_str)); + $tempBody = sprintf( + "--".$boundary.$this->eol. + "Content-Type: %s;".$this->eol. + "\tname=\"%s\"".$this->eol. + "Content-Transfer-Encoding: base64".$this->eol. + "Content-Description: %s".$this->eol. + "Content-Disposition: attachment;".$this->eol. + "\tfilename=\"%s\"".$this->eol.$this->eol. + "%s".$this->eol.$this->eol, + $type, + $filename, + $filename, + $filename, + $chunks); + $res[] = $tempBody; + } + $this->body = implode("", $res); + $this->body .= "--".$boundary."--"; + } + } + + function procCidAttachments() + { + if(count($this->cidAttachments) > 0) + { + $this->body = $this->header.$this->body; + $boundary = '----=='.uniqid(rand(),true); + $this->header = "Content-Type: multipart/relative;".$this->eol."\ttype=\"multipart/alternative\";".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol; + $this->body = "--".$boundary.$this->eol.$this->body.$this->eol.$this->eol; + $res = array(); + $res[] = $this->body; + foreach($this->cidAttachments as $cid => $attachment) + { + $filename = basename($attachment); + $type = $this->returnMIMEType(FileHandler::getRealPath($attachment)); + $file_str = FileHandler::readFile($attachment); + $chunks = chunk_split(base64_encode($file_str)); + $tempBody = sprintf( + "--".$boundary.$this->eol. + "Content-Type: %s;".$this->eol. + "\tname=\"%s\"".$this->eol. + "Content-Transfer-Encoding: base64".$this->eol. + "Content-ID: <%s>".$this->eol. + "Content-Description: %s".$this->eol. + "Content-Location: %s".$this->eol.$this->eol. + "%s".$this->eol.$this->eol, + $type, + $filename, + $cid, + $filename, + $filename, + $chunks); + $res[] = $tempBody; + } + $this->body = implode("", $res); + $this->body .= "--".$boundary."--"; + } + } + + function send() { $boundary = '----=='.uniqid(rand(),true); - $eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n"; + $this->eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n"; - $headers = sprintf( - "From: %s".$eol. - "To: %s".$eol. - "MIME-Version: 1.0".$eol. - "Content-Type: multipart/alternative;".$eol."\tboundary=\"%s\"".$eol.$eol. - "", - $this->getSender(), - $this->getReceiptor(), - $boundary - ); - - $body = sprintf( - "--%s".$eol. - "Content-Type: text/plain; charset=utf-8; format=flowed".$eol. - "Content-Transfer-Encoding: base64".$eol. - "Content-Disposition: inline".$eol.$eol. + $this->header = "Content-Type: multipart/alternative;".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol; + $this->body = sprintf( + "--%s".$this->eol. + "Content-Type: text/plain; charset=utf-8; format=flowed".$this->eol. + "Content-Transfer-Encoding: base64".$this->eol. + "Content-Disposition: inline".$this->eol.$this->eol. "%s". - "--%s".$eol. - "Content-Type: text/html; charset=utf-8".$eol. - "Content-Transfer-Encoding: base64".$eol. - "Content-Disposition: inline".$eol.$eol. + "--%s".$this->eol. + "Content-Type: text/html; charset=utf-8".$this->eol. + "Content-Transfer-Encoding: base64".$this->eol. + "Content-Disposition: inline".$this->eol.$this->eol. "%s". "--%s--". "", @@ -100,7 +199,23 @@ $boundary ); - return mail($this->receiptor_email, $this->getTitle(), $body, $headers); + $this->procCidAttachments(); + $this->procAttachments(); + + $headers = sprintf( + "From: %s".$this->eol. + "%s". + "%s". + "%s". + "MIME-Version: 1.0".$this->eol."", + $this->getSender(), + $this->messageId?("Message-ID: <".$this->messageId.">".$this->eol):"", + $this->replyTo?("Reply-To: <".$this->replyTo.">".$this->eol):"", + $this->bcc?("Bcc: ".$this->bcc.$this->eol):"" + ); + $headers .= $this->header; + + return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers); } function checkMailMX($email_address) { @@ -117,5 +232,109 @@ if( preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address) ) return $email_address; else return ''; } + + function returnMIMEType($filename) + { + preg_match("|\.([a-z0-9]{2,4})$|i", $filename, $fileSuffix); + + switch(strtolower($fileSuffix[1])) + { + case "js" : + return "application/x-javascript"; + + case "json" : + return "application/json"; + + case "jpg" : + case "jpeg" : + case "jpe" : + return "image/jpg"; + + case "png" : + case "gif" : + case "bmp" : + case "tiff" : + return "image/".strtolower($fileSuffix[1]); + + case "css" : + return "text/css"; + + case "xml" : + return "application/xml"; + + case "doc" : + case "docx" : + return "application/msword"; + + case "xls" : + case "xlt" : + case "xlm" : + case "xld" : + case "xla" : + case "xlc" : + case "xlw" : + case "xll" : + return "application/vnd.ms-excel"; + + case "ppt" : + case "pps" : + return "application/vnd.ms-powerpoint"; + + case "rtf" : + return "application/rtf"; + + case "pdf" : + return "application/pdf"; + + case "html" : + case "htm" : + case "php" : + return "text/html"; + + case "txt" : + return "text/plain"; + + case "mpeg" : + case "mpg" : + case "mpe" : + return "video/mpeg"; + + case "mp3" : + return "audio/mpeg3"; + + case "wav" : + return "audio/wav"; + + case "aiff" : + case "aif" : + return "audio/aiff"; + + case "avi" : + return "video/msvideo"; + + case "wmv" : + return "video/x-ms-wmv"; + + case "mov" : + return "video/quicktime"; + + case "zip" : + return "application/zip"; + + case "tar" : + return "application/x-tar"; + + case "swf" : + return "application/x-shockwave-flash"; + + default : + if(function_exists("mime_content_type")) + { + $fileSuffix = mime_content_type($filename); + } + + return "unknown/" . trim($fileSuffix[0], "."); + } + } } ?>