From 0d1229f52211d996be0935bf520584f156eb5d9f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 May 2009 19:10:06 +0000 Subject: [PATCH] New: Can use inline images.Everything seems to work with thunderbird and webmail gmail. New to be tested on other mail browsers. --- htdocs/includes/smtps/SMTPs.php | 105 ++++++++++++++++---- htdocs/lib/CMailFile.class.php | 165 +++++++++++++++++--------------- 2 files changed, 172 insertions(+), 98 deletions(-) diff --git a/htdocs/includes/smtps/SMTPs.php b/htdocs/includes/smtps/SMTPs.php index e2c277e0abf..78c6ca496ab 100644 --- a/htdocs/includes/smtps/SMTPs.php +++ b/htdocs/includes/smtps/SMTPs.php @@ -1610,10 +1610,15 @@ class SMTPs { foreach ( $this->_msgRecipients[$_host][$_which] as $_addr => $_realName ) { - if ( $_realName ) + if ( $_realName ) // DOL_CHANGE FIX + { $_realName = '"' . $_realName . '"'; - - $_RCPT_list[] = $_realName . ' <' . $_addr . '@' . $_host . '>'; + $_RCPT_list[] = $_realName . ' <' . $_addr . '@' . $_host . '>'; + } + else + { + $_RCPT_list[] = $_addr . '@' . $_host; + } } } } @@ -1977,10 +1982,12 @@ class SMTPs /* * @TODO Investigate "nested" boundary message parts */ - $content = 'Content-Type: multipart/mixed;' . "\r\n" - . ' boundary="' . $this->_getBoundary() . '"' . "\r\n" - . "\r\n" - . 'This is a multi-part message in MIME format.' . "\r\n"; + $content = 'Content-Type: multipart/related; boundary="' . $this->_getBoundary() . '"' . "\r\n"; +// TODO Restore +// . "\r\n" +// . 'This is a multi-part message in MIME format.' . "\r\n"; + $content .= "Content-Transfer-Encoding: 8bit" . "\r\n"; + $content .= "\r\n"; // Loop through message content array foreach ($this->_msgContent as $type => $_content ) @@ -1991,7 +1998,8 @@ class SMTPs foreach ( $_content as $_file => $_data ) { - $content .= "\r\n--" . $this->_getBoundary() . "\r\n" + // TODO Restore "\r\n" + $content .= "--" . $this->_getBoundary() . "\r\n" . 'Content-Disposition: attachment; filename="' . $_data['fileName'] . '"' . "\r\n" . 'Content-Type: ' . $_data['mimeType'] . '; name="' . $_data['fileName'] . '"' . "\r\n" . 'Content-Transfer-Encoding: base64' . "\r\n" @@ -2004,18 +2012,43 @@ class SMTPs . $_data['data'] . "\r\n"; } } + // DOL_CHANGE LDR + else if ( $type == 'image' ) + { + // loop through all images + foreach ( $_content as $_image => $_data ) + { + // TODO Restore "\r\n" + $content .= "--" . $this->_getBoundary() . "\r\n"; + + $content .= 'Content-Type: ' . $_data['mimeType'] . '; name="' . $_data['imageName'] . '"' . "\r\n" + . 'Content-Transfer-Encoding: base64' . "\r\n" + . 'Content-Disposition: inline; filename="' . $_data['imageName'] . '"' . "\r\n" + . 'Content-ID: <' . $_data['cid'] . '> ' . "\r\n"; + + if ( $this->getMD5flag() ) + $content .= 'Content-MD5: ' . $_data['md5'] . "\r\n"; + + $content .= "\r\n" + . $_data['data'] . "\r\n"; + } + } else { - $content .= "\r\n--" . $this->_getBoundary() . "\r\n" + // TODO Restore "\r\n" + $content .= "--" . $this->_getBoundary() . "\r\n" . 'Content-Type: ' . $_content['mimeType'] . '; ' - . 'charset="' . $this->getCharSet() . '"'; - $content .= ( $type == 'html') ? '; name="HTML Part"' : ''; +// . 'charset="' . $this->getCharSet() . '"'; + . 'charset=' . $this->getCharSet() . ''; + +// TODO Restore +// $content .= ( $type == 'html') ? '; name="HTML Part"' : ''; $content .= "\r\n"; - $content .= 'Content-Transfer-Encoding: '; - $content .= ( $type == 'html') ? 'quoted-printable' : $this->getTransEncodeType(); - $content .= "\r\n" - . 'Content-Disposition: inline' . "\r\n" - . 'Content-Description: ' . $type . ' message' . "\r\n"; +// $content .= 'Content-Transfer-Encoding: '; +// $content .= ( $type == 'html') ? 'quoted-printable' : $this->getTransEncodeType(); +// $content .= "\r\n" +// . 'Content-Disposition: inline' . "\r\n" +// . 'Content-Description: ' . $type . ' message' . "\r\n"; if ( $this->getMD5flag() ) $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n"; @@ -2026,7 +2059,8 @@ class SMTPs } // Close message boundries - $content .= "\r\n--" . $this->_getBoundary() . '--' . "\r\n" ; +// $content .= "\r\n--" . $this->_getBoundary() . '--' . "\r\n" ; + $content .= "--" . $this->_getBoundary() . '--' . "\r\n" ; } return $content; @@ -2066,6 +2100,36 @@ class SMTPs } } + + // DOL_CHANGE LDR + /** + * Method public void setImageInline( string ) + * + * Image attachments are added to the content array as sub-arrays, + * allowing for multiple images for each outbound email + * + * @param string $strContent Image data to attach to message + * @param string $strImageName Image Name to give to attachment + * @param string $strMimeType Image Mime Type of attachment + * @return void + * + */ + function setImageInline ( $strContent, $strImageName = 'unknown', $strMimeType = 'unknown', $strImageCid = 'unknown' ) + { + if ( $strContent ) + { + $this->_msgContent['image'][$strImageName]['mimeType'] = $strMimeType; + $this->_msgContent['image'][$strImageName]['imageName'] = $strImageName; + $this->_msgContent['image'][$strImageName]['cid'] = $strImageCid; + $this->_msgContent['image'][$strImageName]['data'] = $strContent; + + if ( $this->getMD5flag() ) + $this->_msgContent['image'][$strFileName]['md5'] = md5($strContent); + } + } + // END DOL_CHANGE LDR + + /** * Method public void setSensitivity( string ) * @@ -2361,9 +2425,9 @@ class SMTPs function socket_send_str ( $_strSend, $_returnCode = null, $CRLF = "\r\n" ) { - if ($this->_debug) $this->log.=$_strSend . ": "; + if ($this->_debug) $this->log.=$_strSend; // DOL_CHANGE LDR for log fputs($this->socket, $_strSend . $CRLF); - if ($this->_debug) $this->log.=$_returnCode . "
"; + if ($this->_debug) $this->log.=' ('.$_returnCode.')' . $CRLF; if ( $_returnCode ) return $this->server_parse($this->socket, $_returnCode); @@ -2435,6 +2499,9 @@ class SMTPs /** * $Log$ + * Revision 1.8 2009/05/13 19:10:07 eldy + * New: Can use inline images.Everything seems to work with thunderbird and webmail gmail. New to be tested on other mail browsers. + * * Revision 1.7 2009/05/13 14:49:30 eldy * Fix: Make code so much simpler and solve a lot of problem with new version. * diff --git a/htdocs/lib/CMailFile.class.php b/htdocs/lib/CMailFile.class.php index f5befb94a50..5677357b479 100644 --- a/htdocs/lib/CMailFile.class.php +++ b/htdocs/lib/CMailFile.class.php @@ -89,9 +89,14 @@ class CMailFile { global $conf; + // On definit fin de ligne + $this->eol="\n"; + if (eregi('^win',PHP_OS)) $this->eol="\r\n"; + if (eregi('^mac',PHP_OS)) $this->eol="\r"; + // Evite caractere bizarre avec les accents //Todo l'envoi par mailing donne des caractères bizarre, - // alors que l'envoi d'un document facture ou autre est correcte + // alors que l'envoi d'un document facture ou autre est correcte $subject = $subject; $from = $from; @@ -151,15 +156,10 @@ class CMailFile $this->mime_boundary = md5(uniqid("dolibarr")); // On defini related_boundary - $this->related_boundary = md5(uniqid("dolibarr")); + // $this->related_boundary = md5(uniqid("dolibarr")); // On defini alternative_boundary - $this->alternative_boundary = md5(uniqid("dolibarr")); - - // On definit fin de ligne - $this->eol="\n"; - if (eregi('^win',PHP_OS)) $this->eol="\r\n"; - if (eregi('^mac',PHP_OS)) $this->eol="\r"; + // $this->alternative_boundary = md5(uniqid("dolibarr")); $smtp_headers = ""; $mime_headers = ""; @@ -182,15 +182,17 @@ class CMailFile $mime_headers = $this->write_mimeheaders($filename_list, $mimefilename_list); // } - // On encode les images - // if ($this->atleastoneimage) - // { - $images_encoded = $this->write_images($this->images_encoded); if (! empty($this->html)) $msg = $this->html; - // } // Corps message dans $text_body - $text_body = $this->write_body($msg, $filename_list); + $text_body = $this->write_body($msg); + + // On encode les images + if ($this->atleastoneimage) + { + $images_encoded = $this->write_images($this->images_encoded); + //print 'xx'.sizeof($this->images_encoded['encoded']); + } // Corps message suite (fichiers attaches) dans $text_encoded if ($this->atleastonefile) @@ -219,7 +221,7 @@ class CMailFile $smtps->setCharSet($conf->file->character_set_client); $smtps->setSubject($this->encodetorfc2822($subject)); - $smtps->setTO($to); + $smtps->setTO(getValidAddress($to,2)); $smtps->setFrom($from); //if ($this->atleastoneimage) $msg = $this->html; @@ -236,7 +238,7 @@ class CMailFile { foreach ($this->images_encoded as $img) { - $smtps->setImage($img['image_encoded'],$img['name'],$img['content_type'],$img['cid']); + $smtps->setImageInline($img['image_encoded'],$img['name'],$img['content_type'],$img['cid']); } } @@ -293,9 +295,6 @@ class CMailFile //dol_syslog("CMailFile::sendfile message=\n".$message); - if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail(); - - // Si Windows, addr_from doit obligatoirement etre defini if (isset($_SERVER["WINDIR"])) { @@ -327,7 +326,11 @@ class CMailFile $bounce = $this->addr_from != '' ? "-f {$this->addr_from}" : ""; } - $res = mail($dest,$this->encodetorfc2822($this->subject),stripslashes($this->message),$this->headers, $bounce); + $this->message=stripslashes($this->message); + + if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail(); + + $res = mail($dest,$this->encodetorfc2822($this->subject),$this->message,$this->headers, $bounce); if (! $res) { @@ -367,6 +370,7 @@ class CMailFile if (! empty($conf->global->MAIN_MAIL_SMTPS_PW)) $this->smtps->setPW($conf->global->MAIN_MAIL_SMTPS_PW); //$smtps->_msgReplyTo = 'reply@web.com'; + $dest=$this->smtps->getFrom('org'); if (! $dest) { @@ -510,7 +514,9 @@ class CMailFile if (! $this->atleastonefile) $out.= "Content-Type: text/plain; boundary=\"".$this->mime_boundary."\"".$this->eol; $out.= "Content-Transfer-Encoding: 8bit".$this->eol; } - */ + */ + + $out.=$this->eol; dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out, LOG_DEBUG); return $out; } @@ -534,7 +540,7 @@ class CMailFile { //if (! $mimedone) //{ - // $out.= "Content-Type: multipart/mixed; boundary=\"".$this->mime_boundary."\"".$this->eol; + // $out.= "Content-Type: multipart/mixed; boundary=\"".$this->mime_boundary."\"".$this->eol; // $mimedone=1; //} if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i]; @@ -542,10 +548,10 @@ class CMailFile //if ($mimedone!=2 && $this->atleastoneimage) //{ -// $out.= "--" . $this->mime_boundary . $this->eol; -// $out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol; -// $mimedone=2; -// } + // $out.= "--" . $this->mime_boundary . $this->eol; + // $out.= "Content-Type: multipart/related; boundary=\"".$this->related_boundary."\"".$this->eol; + // $mimedone=2; + // } } } } @@ -556,11 +562,10 @@ class CMailFile } /** - * \brief Permet d'ecrire le corps du message + * \brief Permet d'ecrire le corps du message (mode = 'mail') * \param msgtext - * \param filename_list */ - function write_body($msgtext, $filename_list) + function write_body($msgtext) { global $conf; @@ -571,44 +576,57 @@ class CMailFile if ($this->msgishtml) { $out.= "--" . $this->mime_boundary . $this->eol; - $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol; + $out.= "Content-Type: text/html; charset=\"".$conf->file->character_set_client."\"".$this->eol; } else { $out.= "--" . $this->mime_boundary . $this->eol; - $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol; + $out.= "Content-Type: text/plain; charset=\"".$conf->file->character_set_client."\"".$this->eol; } $out.= $this->eol; // } if ($this->msgishtml) { // Check if html header already in message - $out.= $this->checkIfHTML($msgtext); + $strContent = $this->checkIfHTML($msgtext); /*if ($this->atleastonefile || $this->atleastoneimage) - { + { if ($this->atleastonefile && $this->atleastoneimage) { - $out.= $this->eol . "--" . $this->related_boundary . $this->eol; + $out.= $this->eol . "--" . $this->related_boundary . $this->eol; } else { - $out.= $this->eol . "--" . $this->mime_boundary . $this->eol; + $out.= $this->eol . "--" . $this->mime_boundary . $this->eol; } - }*/ + }*/ } else { - $out.= $msgtext.$this->eol; + $strContent.= $msgtext; /* if ($this->atleastonefile || $this->atleastoneimage) { $out.= $this->eol . "--" . $this->mime_boundary . $this->eol; }*/ } + // Make RFC821 Compliant, replace bare linefeeds + $strContent = preg_replace("/(?eol; + return $out; } + /** + * Correct an uncomplete html string + * + * @param unknown_type $msg + * @return unknown + */ function checkIfHTML($msg) { if (!eregi('^[ \t]*eol . "--" . $this->mime_boundary . $this->eol; $out = $msg; } - $out.=$this->eol; - return $out; } @@ -654,6 +669,7 @@ class CMailFile $out.= "Content-Type: " . $mimetype_list[$i] . "; name=\"".$filename_list[$i]."\"".$this->eol; $out.= "Content-Transfer-Encoding: base64".$this->eol; $out.= "Content-Disposition: attachment; filename=\"".$filename_list[$i]."\"".$this->eol; + $out.= "Content-Description: \""."File Attachment"."\"".$this->eol; $out.= $this->eol; $out.= $encoded; $out.= $this->eol; @@ -666,8 +682,35 @@ class CMailFile } } - // Fin de tous les attachements - // $out.= "--" . $this->mime_boundary . "--" . $this->eol; + return $out; + } + + + /** + \brief Permet d'attacher une image + \param images_list Tableau + \return out Chaine images encodees + */ + function write_images($images_list) + { + $out = ''; + + if ($images_list) + { + foreach ($images_list as $img) + { + dol_syslog("CMailFile::write_images: i=$i"); + + $out.= "--" . $this->mime_boundary . $this->eol; + $out.= "Content-Type: " . $img["content_type"] . "; name=\"".$img["name"]."\"".$this->eol; + $out.= "Content-Transfer-Encoding: base64".$this->eol; + $out.= "Content-Disposition: inline; filename=\"".$img["name"]."\"".$this->eol; + $out.= "Content-ID: <".$img["cid"].">".$this->eol; + $out.= $this->eol; + $out.= $img["image_encoded"]; + $out.= $this->eol; + } + } return $out; } @@ -788,6 +831,7 @@ class CMailFile foreach ($this->html_images as $img) { + // Read imahe file if ($image = file_get_contents($images_dir.'/'.$img["name"])) { // On garde que le nom de l'image @@ -797,7 +841,6 @@ class CMailFile $this->images_encoded[$i]['name'] = $imgName; $this->images_encoded[$i]['content_type'] = $img["content_type"]; $this->images_encoded[$i]['cid'] = $img["cid"]; - // Encodage de l'image $this->images_encoded[$i]["image_encoded"] = chunk_split(base64_encode($image), 68, $this->eol); } @@ -817,42 +860,6 @@ class CMailFile } } - /** - \brief Permet d'attacher une image - \param images_list Tableau - \return out Chaine images encodees - */ - function write_images($images_list) - { - $out = ''; - - if ($images_list) - { - foreach ($images_list as $img) - { - dol_syslog("CMailFile::write_images: i=$i"); - - $out.= "--" . $this->mime_boundary . $this->eol; - $out.= "Content-Type: " . $img["content_type"] . "; name=\"".$img["name"]."\"".$this->eol; - $out.= "Content-Transfer-Encoding: base64".$this->eol; - $out.= "Content-Disposition: inline; filename=\"".$img["name"]."\"".$this->eol; - $out.= "Content-ID: <".$img["cid"].">".$this->eol; - $out.= $this->eol; - $out.= $img["image_encoded"]; - $out.= $this->eol; - } - } -/* else - { - return 0; - } -*/ - - // Fin de tous les attachements - // $out.= "--" . $this->mime_boundary . "--" . $this->eol; - - return $out; - } }