[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /********************************************************************************* 3 ** The contents of this file are subject to the vtiger CRM Public License Version 1.0 4 * ("License"); You may not use this file except in compliance with the License 5 * The Original Code is: vtiger CRM Open Source 6 * The Initial Developer of the Original Code is vtiger. 7 * Portions created by vtiger are Copyright (C) vtiger. 8 * All Rights Reserved. 9 * 10 ********************************************************************************/ 11 12 /** 13 * This class provides structured way of accessing details of email. 14 */ 15 class Vtiger_MailRecord { 16 // FROM address(es) list 17 var $_from; 18 // TO address(es) list 19 var $_to; 20 //var $_replyto; 21 22 // CC address(es) list 23 var $_cc; 24 // BCC address(es) list 25 var $_bcc; 26 // DATE 27 var $_date; 28 // SUBJECT 29 var $_subject; 30 // BODY (either HTML / PLAIN message) 31 var $_body; 32 // CHARSET of the body content 33 var $_charset; 34 // If HTML message was set as body content 35 var $_isbodyhtml; 36 // PLAIN message of the original email 37 var $_plainmessage = false; 38 // HTML message of the original email 39 var $_htmlmessage = false; 40 // ATTACHMENTS list of the email 41 var $_attachments = false; 42 // UNIQUEID associated with the email 43 var $_uniqueid = false; 44 45 // Flag to avoid re-parsing the email body. 46 var $_bodyparsed = false; 47 48 /** DEBUG Functionality. */ 49 var $debug = false; 50 function log($message=false) { 51 if(!$message) $message = $this->__toString(); 52 53 global $log; 54 if($log && $this->debug) { $log->debug($message); } 55 else if($this->debug) { 56 echo var_export($message, true) . "\n"; 57 } 58 } 59 60 /** 61 * String representation of the object. 62 */ 63 function __toString() { 64 $tostring = ''; 65 $tostring .= 'FROM: [' . implode(',', $this->_from) . ']'; 66 $tostring .= ',TO: [' . implode(',', $this->_to) . ']'; 67 if (!empty($this->_cc)) 68 $tostring .= ',CC: [' . implode(',', $this->_cc) . ']'; 69 if (!empty($this->_bcc)) 70 $tostring .= ',BCC: [' . implode(',', $this->_bcc) . ']'; 71 $tostring .= ',DATE: [' . $this->_date . ']'; 72 $tostring .= ',SUBJECT: [' . $this->_subject . ']'; 73 return $tostring; 74 } 75 76 /** 77 * Constructor. 78 */ 79 function __construct($imap, $messageid, $fetchbody=true) { 80 $this->__parseHeader($imap, $messageid); 81 if($fetchbody) $this->__parseBody($imap, $messageid); 82 } 83 84 /** 85 * Get body content as Text. 86 */ 87 function getBodyText($striptags=true) { 88 $bodytext = $this->_body; 89 90 if($this->_plainmessage) { 91 $bodytext = $this->_plainmessage; 92 } else if($this->_isbodyhtml) { 93 // TODO This conversion can added multiple lines if 94 // content is displayed directly on HTML page 95 $bodytext = preg_replace("/<br>/", "\n", $bodytext); 96 $bodytext = strip_tags($bodytext); 97 } 98 return $bodytext; 99 } 100 101 /** 102 * Get body content as HTML. 103 */ 104 function getBodyHTML() { 105 $bodyhtml = $this->_body; 106 if(!$this->_isbodyhtml) { 107 $bodyhtml = preg_replace( Array("/\r\n/", "/\n/"), Array('<br>','<br>'), $bodyhtml ); 108 } 109 return $bodyhtml; 110 } 111 112 /** 113 * Fetch the mail body from server. 114 */ 115 function fetchBody($imap, $messageid) { 116 if(!$this->_bodyparsed) $this->__parseBody($imap, $messageid); 117 } 118 119 /** 120 * Parse the email id from the mail header text. 121 * @access private 122 */ 123 function __getEmailIdList($inarray) { 124 if(empty($inarray)) return Array(); 125 $emails = Array(); 126 foreach($inarray as $emailinfo) { 127 $emails[] = $emailinfo->mailbox . '@' . $emailinfo->host; 128 } 129 return $emails; 130 } 131 132 /** 133 * Helper function to convert the encoding of input to target charset. 134 */ 135 static function __convert_encoding($input, $to, $from = false) { 136 static $mb_function = NULL; 137 static $iconv_function = NULL; 138 139 if ($mb_function === NULL) $mb_function = function_exists('mb_convert_encoding'); 140 if ($iconv_function === NULL) $iconv_function = function_exists('iconv'); 141 142 if($mb_function) { 143 if(!$from) $from = mb_detect_encoding($input); 144 145 if(strtolower(trim($to)) == strtolower(trim($from))) { 146 return $input; 147 } else { 148 return mb_convert_encoding($input, $to, $from); 149 } 150 } 151 return $input; 152 } 153 154 /** 155 * MIME decode function to parse IMAP header or mail information 156 */ 157 static function __mime_decode($input, &$words=null, $targetEncoding='UTF-8') { 158 if(is_null($words)) $words = array(); 159 $returnvalue = $input; 160 161 preg_match_all('/=\?([^\?]+)\?([^\?]+)\?([^\?]+)\?=/', $input, $matches); 162 array_filter($matches); 163 if(count($matches[0])>0){ 164 $decodedArray= imap_mime_header_decode($input); 165 foreach($decodedArray as $part=>$prop){ 166 $decodevalue=$prop->text; 167 $charset=$prop->charset; 168 $value = self::__convert_encoding($decodevalue, $targetEncoding, $charset); 169 array_push($words, $value); 170 } 171 } 172 if(!empty($words)) { 173 $returnvalue = implode('', $words); 174 } 175 return $returnvalue; 176 } 177 178 /** 179 * MIME encode function to prepare input to target charset supported by normal IMAP clients. 180 */ 181 static function __mime_encode($input, $encoding='Q', $charset='iso-8859-1') { 182 $returnvalue = $input; 183 $encoded = false; 184 185 if(strtoupper($encoding) == 'B' ) { 186 $returnvalue = self::__convert_encoding($input, $charset); 187 $returnvalue = base64_encode($returnvalue); 188 $encoded = true; 189 } else { 190 $returnvalue = self::__convert_encoding($input, $charset); 191 if(function_exists('imap_qprint')) { 192 $returnvalue = imap_qprint($returnvalue); 193 $encoded = true; 194 } else { 195 // TODO: Handle case when imap_qprint is not available. 196 } 197 } 198 if($encoded) { 199 $returnvalue = "=?$charset?$encoding?$returnvalue?="; 200 } 201 return $returnvalue; 202 } 203 204 /** 205 * Parse header of the email. 206 * @access private 207 */ 208 function __parseHeader($imap, $messageid) { 209 $this->_from = Array(); 210 $this->_to = Array(); 211 212 $mailheader = imap_headerinfo($imap, $messageid); 213 214 $this->_uniqueid = $mailheader->message_id; 215 216 $this->_from = $this->__getEmailIdList($mailheader->from); 217 $this->_to = $this->__getEmailIdList($mailheader->to); 218 $this->_cc = $this->__getEmailIdList($mailheader->cc); 219 $this->_bcc = $this->__getEmailIdList($mailheader->bcc); 220 221 $this->_date = $mailheader->udate; 222 223 $this->_subject = self::__mime_decode($mailheader->subject); 224 if(!$this->_subject) $this->_subject = 'Untitled'; 225 } 226 // Modified: http://in2.php.net/manual/en/function.imap-fetchstructure.php#85685 227 function __parseBody($imap, $messageid) { 228 $structure = imap_fetchstructure($imap, $messageid); 229 230 $this->_plainmessage = ''; 231 $this->_htmlmessage = ''; 232 $this->_body = ''; 233 $this->_isbodyhtml = false; 234 235 if($structure->parts) { /* multipart */ 236 foreach($structure->parts as $partno0=>$p) { 237 $this->__getpart($imap, $messageid, $p, $partno0+1); 238 } 239 } else { /* not multipart */ 240 $this->__getpart($imap, $messageid, $structure, 0); 241 } 242 243 // Set the body (either plain or html content) 244 if($this->_htmlmessage != '') { 245 $this->_body = $this->_htmlmessage; 246 $this->_isbodyhtml = true; 247 } else { 248 $this->_body = $this->_plainmessage; 249 } 250 251 if($this->_attachments) { 252 $this->log("Attachments: "); 253 $filename = array(); 254 $content = array(); 255 $attachmentKeys = array_keys($this->_attachments); 256 for ($i = 0; $i < count($attachmentKeys); $i++) { 257 $filename[$i] = self::__mime_decode($attachmentKeys[$i]); 258 $content[$i] = $this->_attachments[$attachmentKeys[$i]]; 259 } 260 unset($this->_attachments); 261 for ($i = 0; $i < count($attachmentKeys); $i++) { 262 $this->_attachments[$filename[$i]] = $content[$i]; 263 } 264 $this->log(array_keys($this->_attachments)); 265 } 266 267 $this->_bodyparsed = true; 268 } 269 // Modified: http://in2.php.net/manual/en/function.imap-fetchstructure.php#85685 270 function __getpart($imap, $messageid, $p, $partno) { 271 // $partno = '1', '2', '2.1', '2.1.3', etc if multipart, 0 if not multipart 272 273 // DECODE DATA 274 $data = ($partno)? 275 imap_fetchbody($imap,$messageid,$partno): // multipart 276 imap_body($imap,$messageid); // not multipart 277 278 // Any part may be encoded, even plain text messages, so check everything. 279 if ($p->encoding==4) $data = quoted_printable_decode($data); 280 elseif ($p->encoding==3) $data = base64_decode($data); 281 // no need to decode 7-bit, 8-bit, or binary 282 283 // PARAMETERS 284 // get all parameters, like charset, filenames of attachments, etc. 285 $params = array(); 286 if ($p->parameters) { 287 foreach ($p->parameters as $x) $params[ strtolower( $x->attribute ) ] = $x->value; 288 } 289 if ($p->dparameters) { 290 foreach ($p->dparameters as $x) $params[ strtolower( $x->attribute ) ] = $x->value; 291 } 292 293 // ATTACHMENT 294 // Any part with a filename is an attachment, 295 // so an attached text file (type 0) is not mistaken as the message. 296 if ($params['filename'] || $params['name']) { 297 // filename may be given as 'Filename' or 'Name' or both 298 $filename = ($params['filename'])? $params['filename'] : $params['name']; 299 // filename may be encoded, so see imap_mime_header_decode() 300 if(!$this->_attachments) $this->_attachments = Array(); 301 $this->_attachments[$filename] = $data; // TODO: this is a problem if two files have same name 302 } 303 304 // TEXT 305 elseif ($p->type==0 && $data) { 306 $this->_charset = $params['charset']; // assume all parts are same charset 307 $data = self::__convert_encoding($data, 'UTF-8', $this->_charset); 308 309 // Messages may be split in different parts because of inline attachments, 310 // so append parts together with blank row. 311 if (strtolower($p->subtype)=='plain') $this->_plainmessage .= trim($data) ."\n\n"; 312 else $this->_htmlmessage .= $data ."<br><br>"; 313 } 314 315 // EMBEDDED MESSAGE 316 // Many bounce notifications embed the original message as type 2, 317 // but AOL uses type 1 (multipart), which is not handled here. 318 // There are no PHP functions to parse embedded messages, 319 // so this just appends the raw source to the main message. 320 elseif ($p->type==2 && $data) { 321 $this->_plainmessage .= trim($data) ."\n\n"; 322 } 323 324 // SUBPART RECURSION 325 if ($p->parts) { 326 foreach ($p->parts as $partno0=>$p2) 327 $this->__getpart($imap,$messageid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc. 328 } 329 } 330 } 331 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |