diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 396952ace9c..878e0372ab3 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -55,7 +55,6 @@ class CMailFile var $eol; var $eol2; - var $atleastonefile=0; var $error=''; var $smtps; // Contains SMTPs object (if this method is used) @@ -74,7 +73,7 @@ class CMailFile // Image var $html; var $image_boundary; - var $atleastoneimage=0; + var $atleastoneimage=0; // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used). var $html_images=array(); var $images_encoded=array(); var $image_types = array('gif' => 'image/gif', @@ -108,7 +107,7 @@ class CMailFile */ function __construct($subject,$to,$from,$msg,$filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),$addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0,$errors_to='',$css='',$trackid='',$moreinheader='') { - global $conf; + global $conf, $dolibarr_main_data_root; // We define end of line (RFC 821). $this->eol="\r\n"; @@ -160,8 +159,12 @@ class CMailFile if ($this->msgishtml) { $this->html = $msg; - $findimg = $this->findHtmlImages($conf->fckeditor->dir_output); + if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS)) + { + $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias'); + } + // Define if there is at least one file if ($findimg) { @@ -231,17 +234,6 @@ class CMailFile // Define body in text_body $text_body = $this->write_body($msg); - // Encode images - $images_encoded = ''; - if ($this->atleastoneimage) - { - $images_encoded.= $this->write_images($this->images_encoded); - // always end related and end alternative after inline images - $images_encoded.= "--" . $this->related_boundary . "--" . $this->eol; - $images_encoded.= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; - $images_encoded.= $this->eol; - } - // Add attachments to text_encoded if ($this->atleastonefile) { @@ -255,8 +247,8 @@ class CMailFile // comme des injections mail par les serveurs de messagerie. $this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers); - $this->message = 'This is a message with multiple parts in MIME format.'.$this->eol; - $this->message.= $text_body . $images_encoded . $files_encoded; + $this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol; + $this->message.= $text_body . $files_encoded; $this->message.= "--" . $this->mixed_boundary . "--" . $this->eol; } else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') @@ -917,7 +909,7 @@ class CMailFile $out.= "Content-Type: multipart/mixed; boundary=\"".$this->mixed_boundary."\"".$this->eol2; $out.= "Content-Transfer-Encoding: 8bit".$this->eol2; - + dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out); return $out; } @@ -973,23 +965,23 @@ class CMailFile $out.= "--" . $this->alternative_boundary . $this->eol; } - if ($this->msgishtml) - { - // Check if html header already in message - $strContent = $this->checkIfHTML($msgtext); - } - else - { - $strContent = $msgtext; - } - // Make RFC821 Compliant, replace bare linefeeds - $strContent = preg_replace("/(?global->MAIN_FIX_FOR_BUGGED_MTA)) { $strContent = preg_replace("/\r\n/si", "\n", $strContent); } + $strContentAltText = ''; + if ($this->msgishtml) + { + $strContentAltText = html_entity_decode(strip_tags($strContent)); + $strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n")); + + // Check if html header already in message, if not complete the message + $strContent = $this->checkIfHTML($strContent); + } + // Make RFC2045 Compliant, split lines //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content $strContent = rtrim(wordwrap($strContent)); // TODO Using this method creates unexpected line break on text/plain content. @@ -999,14 +991,30 @@ class CMailFile if ($this->atleastoneimage) { $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; - $out.= $this->eol.strip_tags($strContent).$this->eol; // Add plain text message + $out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message $out.= "--" . $this->alternative_boundary . $this->eol; $out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol; $out.= $this->eol; $out.= "--" . $this->related_boundary . $this->eol; } + + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part + { + $out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol; + $out.= $this->eol; + $out.= "--" . $this->alternative_boundary . $this->eol; + $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; + $out.= $this->eol.$strContentAltText.$this->eol; + $out.= "--" . $this->alternative_boundary . $this->eol; + } + $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol; $out.= $this->eol.$strContent.$this->eol; + + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part + { + $out.= "--" . $this->alternative_boundary . "--". $this->eol; + } } else { @@ -1016,6 +1024,16 @@ class CMailFile $out.= $this->eol; + // Encode images + if ($this->atleastoneimage) + { + $out .= $this->write_images($this->images_encoded); + // always end related and end alternative after inline images + $out .= "--" . $this->related_boundary . "--" . $this->eol; + $out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; + $out .= $this->eol; + } + return $out; } @@ -1184,14 +1202,15 @@ class CMailFile $extensions = array_keys($this->image_types); - preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); + preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); // If "xxx.ext" or 'xxx.ext' found if ($matches) { $i=0; foreach ($matches[1] as $full) { - if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) + + if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) // If xxx is 'file=aaa' { $img = $regs[1]; diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index e7c7b343ac9..c99ca2c4850 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -1283,15 +1283,23 @@ class SMTPs // Make RFC821 Compliant, replace bare linefeeds $strContent = preg_replace("/(?_msgContent[$strType] = array(); $this->_msgContent[$strType]['mimeType'] = $strMimeType; $this->_msgContent[$strType]['data'] = $strContent; - + $this->_msgContent[$strType]['dataText'] = $strContentAltText; + if ( $this->getMD5flag() ) $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3); //} @@ -1304,6 +1312,8 @@ class SMTPs */ function getBodyContent() { + global $conf; + // Generate a new Boundary string $this->_setBoundary(); @@ -1318,7 +1328,7 @@ class SMTPs die ("Sorry, no content"); // If we have ONE, we can use the simple format - else if( $keyCount === 1 ) + else if( $keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) { $_msgData = $this->_msgContent; $_msgData = $_msgData[$_types[0]]; @@ -1336,7 +1346,7 @@ class SMTPs } // If we have more than ONE, we use the multi-part format - else if( $keyCount > 1 ) + else if( $keyCount >= 1 || ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) { // Since this is an actual multi-part message // We need to define a content message Boundary @@ -1351,14 +1361,18 @@ class SMTPs $content .= "\r\n"; $content .= "--" . $this->_getBoundary('mixed') . "\r\n"; - - if (key_exists('image', $this->_msgContent)) + + if (key_exists('image', $this->_msgContent)) // If inline image found { $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; $content .= "\r\n"; $content .= "--" . $this->_getBoundary('alternative') . "\r\n"; } + + // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment' + + // Loop through message content array foreach ($this->_msgContent as $type => $_content ) { @@ -1409,13 +1423,24 @@ class SMTPs if (key_exists('image', $this->_msgContent)) { $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; - $content.= "\r\n" . strip_tags($_content['data']) . "\r\n"; // Add plain text message + $content.= "\r\n" . ($_content['dataText']?$_content['dataText']:strip_tags($_content['data'])) . "\r\n"; // Add plain text message $content.= "--" . $this->_getBoundary('alternative') . "\r\n"; $content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n"; $content.= "\r\n"; $content.= "--" . $this->_getBoundary('related') . "\r\n"; } - + + if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part + { + $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n"; + $content .= "\r\n"; + $content .= "--" . $this->_getBoundary('alternative') . "\r\n"; + + $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n"; + $content.= "\r\n". $_content['dataText'] . "\r\n"; + $content.= "--" . $this->_getBoundary('alternative') . "\r\n"; + } + $content .= 'Content-Type: ' . $_content['mimeType'] . '; ' // . 'charset="' . $this->getCharSet() . '"'; . 'charset=' . $this->getCharSet() . ''; @@ -1431,7 +1456,14 @@ class SMTPs if ( $this->getMD5flag() ) $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n"; - $content .= "\r\n" . $_content['data'] . "\r\n\r\n"; + $content .= "\r\n" . $_content['data'] . "\r\n"; + + if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part + { + $content.= "--" . $this->_getBoundary('alternative') . "--". "\r\n"; + } + + $content .= "\r\n"; } }