From b9a87cb6ca329bad894c688baaaa3e1243c06179 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@users.sourceforge.net>
Date: Sun, 6 Aug 2006 18:34:37 +0000
Subject: [PATCH] =?UTF-8?q?M=E9ga=20debuggage=20de=20la=20classe=20CMailFi?=
 =?UTF-8?q?le.=20Modif=20pour:=20Fonctionner=20sous=20MAC.=20Permettre=20g?=
 =?UTF-8?q?estion=20mail=20html.=20G=E9rer=20les=20serveur=20qui=20ne=20co?=
 =?UTF-8?q?mprenne=20pas=20les=20RFC2822.=20Permettre=20de=20sp=E9cifier?=
 =?UTF-8?q?=20son=20propre=20serveur=20SMTP.=20Avoir=20des=20traces=20plus?=
 =?UTF-8?q?=20parlantes.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 htdocs/adherents/adherent.class.php           |   5 +-
 htdocs/bon-prelevement.class.php              |   6 +-
 htdocs/comm/mailing/fiche.php                 |  13 +-
 htdocs/compta/facture.php                     |  78 ++--
 .../prelevement/rejet-prelevement.class.php   |   6 +-
 htdocs/lib/CMailFile.class.php                | 400 ++++++++++++------
 htdocs/notify.class.php                       |   6 +-
 htdocs/user.class.php                         |   5 +-
 .../factures-impayees-commerciaux.php         |   6 +-
 scripts/mailing/mailing-send.php              |  65 ++-
 10 files changed, 383 insertions(+), 207 deletions(-)

diff --git a/htdocs/adherents/adherent.class.php b/htdocs/adherents/adherent.class.php
index 2da6e1d8313..68c9f8a97e2 100644
--- a/htdocs/adherents/adherent.class.php
+++ b/htdocs/adherents/adherent.class.php
@@ -159,6 +159,7 @@ class Adherent
 		      );
 		$texttosend = preg_replace ($patterns, $replace, $text);
 		$subjectosend = preg_replace ($patterns, $replace, $subject);
+		$msgishtml=0;
 		
 		// Envoi mail confirmation
         include_once(DOL_DOCUMENT_ROOT."/lib/CMailFile.class.php");
@@ -166,7 +167,9 @@ class Adherent
         $from=$conf->email_from;
         if ($conf->global->ADHERENT_MAIL_FROM) $from=$conf->global->ADHERENT_MAIL_FROM;
         
-        $mailfile = new CMailFile($subject,$this->email,$from,$mesg,array(),array(),array());
+        $mailfile = new CMailFile($subject,$this->email,$from,$mesg,
+        							array(),array(),array(),
+        							'', '', 0, $msgishtml);
 
         if ($mailfile->sendfile())
         {
diff --git a/htdocs/bon-prelevement.class.php b/htdocs/bon-prelevement.class.php
index 7866035e903..338f2f49ea8 100644
--- a/htdocs/bon-prelevement.class.php
+++ b/htdocs/bon-prelevement.class.php
@@ -494,6 +494,8 @@ class BonPrelevement
                 $arr_file = array();
                 $arr_mime = array();
                 $arr_name = array();
+                $msgishtml=0;
+                
                 if ($joinfile == 1)
                 {
                     $arr_file = array(DOL_DATA_ROOT.'/prelevement/bon/'.$this->ref.'.ps');
@@ -501,7 +503,9 @@ class BonPrelevement
                     $arr_name = array($this->ref.".ps");
                 }
 
-                $mailfile = new CMailFile($subject,$sendto,$from,$message,$arr_file,$arr_mime,$arr_name);
+                $mailfile = new CMailFile($subject,$sendto,$from,$message,
+                							$arr_file,$arr_mime,$arr_name,
+                							'', '', 0, $msgishtml);
 
                 $result=$mailfile->sendfile();
 
diff --git a/htdocs/comm/mailing/fiche.php b/htdocs/comm/mailing/fiche.php
index 665381f7093..5c131f16edb 100644
--- a/htdocs/comm/mailing/fiche.php
+++ b/htdocs/comm/mailing/fiche.php
@@ -73,17 +73,24 @@ if ($_POST["action"] == 'send')
         $arr_mime = array();
         $arr_name = array();
 
-        $mailfile = new CMailFile($mil->sujet,$sendto,$from,$mil->body,$arr_file,$arr_mime,$arr_name);
+		// Le message est-il en html
+		$msgishtml=0;	// Non par defaut
+		if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_MAILING) $msgishtml=1;
+		if (eregi('[ \t]*<html>',$message)) $msgishtml=1;						
+
+        $mailfile = new CMailFile($mil->sujet,$sendto,$from,$mil->body,
+        							$arr_file,$arr_mime,$arr_name,
+        							'', '', 0, $msgishtml);
 
         $result=$mailfile->sendfile();
 
-        if($result)
+        if ($result)
         {
             $message='<div class="ok">'.$langs->trans("MailSuccessfulySent",$from,$sendto).'</div>';
         }
         else
         {
-            $message='<div class="error">'.$langs->trans("ResultKo").'</div>';
+            $message='<div class="error">'.$langs->trans("ResultKo").'<br>'.$mailfile->error.'</div>';
         }
 
         $_GET["action"]='';
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index cfe80d60e3a..4a49c05e950 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -622,7 +622,7 @@ if ($_GET['action'] == 'down' && $user->rights->facture->creer)
 /*
  * Action envoi de mail
  */
-if ($_POST['action'] == 'send' || $_POST['action'] == 'relance')
+if (($_POST['action'] == 'send' || $_POST['action'] == 'relance') && ! $_POST['cancel'])
 {
 	$langs->load('mails');
 
@@ -698,43 +698,52 @@ if ($_POST['action'] == 'send' || $_POST['action'] == 'relance')
 
 				// Envoi de la facture
 				$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt);
-
-				if ($mailfile->sendfile())
+				if ($mailfile->error)
 				{
-					$msg='<div class="ok">'.$langs->trans('MailSuccessfulySent',$from,$sendto).'.</div>';
-
-					// Insertion action
-					require_once(DOL_DOCUMENT_ROOT.'/contact.class.php');
-					require_once(DOL_DOCUMENT_ROOT.'/actioncomm.class.php');
-					$actioncomm = new ActionComm($db);
-					$actioncomm->type_id     = $actiontypeid;
-					$actioncomm->label       = $actionmsg2;
-					$actioncomm->note        = $actionmsg;
-					$actioncomm->date        = time();
-					$actioncomm->percent     = 100;
-					$actioncomm->contact     = new Contact($db,$sendtoid);
-					$actioncomm->societe     = new Societe($db,$fac->socidp);
-					$actioncomm->user        = $user;   // User qui a fait l'action
-					$actioncomm->facid       = $fac->id;
-
-					$ret=$actioncomm->add($user);       // User qui saisit l'action
-
-					if ($ret < 0)
+					$msg='<div class="error">'.$mailfile->error.'</div>';
+				}
+				else
+				{
+					if ($mailfile->sendfile())
 					{
-						dolibarr_print_error($db);
+						$msg='<div class="ok">'.$langs->trans('MailSuccessfulySent',$from,$sendto).'.</div>';
+	
+						// Insertion action
+						require_once(DOL_DOCUMENT_ROOT.'/contact.class.php');
+						require_once(DOL_DOCUMENT_ROOT.'/actioncomm.class.php');
+						$actioncomm = new ActionComm($db);
+						$actioncomm->type_id     = $actiontypeid;
+						$actioncomm->label       = $actionmsg2;
+						$actioncomm->note        = $actionmsg;
+						$actioncomm->date        = time();
+						$actioncomm->percent     = 100;
+						$actioncomm->contact     = new Contact($db,$sendtoid);
+						$actioncomm->societe     = new Societe($db,$fac->socidp);
+						$actioncomm->user        = $user;   // User qui a fait l'action
+						$actioncomm->facid       = $fac->id;
+	
+						$ret=$actioncomm->add($user);       // User qui saisit l'action
+	
+						if ($ret < 0)
+						{
+							dolibarr_print_error($db);
+						}
+						else
+						{
+							// Renvoie sur la fiche
+							Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$fac->id.'&msg='.urlencode($msg));
+							exit;
+						}
 					}
 					else
 					{
-						// Renvoie sur la fiche
-						Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$fac->id.'&msg='.urlencode($msg));
-						exit;
+						$langs->load("other");
+						$msg='<div class="error">';
+						$msg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
+						if ($mailfile->error) $msg.='<br>'.$mailfile->error;
+						$msg.='</div>';
 					}
 				}
-				else
-				{
-					$langs->load("other");
-					$msg='<div class="error">'.$langs->trans('ErrorFailedToSendMail',$from,$sendto).' !</div>';
-				}
 			}
 			else
 			{
@@ -963,7 +972,6 @@ if ($_GET['action'] == 'create')
 	if (! $_GET['propalid'] && ! $_GET['commandeid'] && ! $_GET['contratid']) print '">';
 	print ' '.$langs->trans("Currency".$conf->monnaie);
 	print '</td><td>'.img_info().' ';
-	$absolute_discount=$soc->getCurrentDiscount();
 	if ($absolute_discount)
 	{
 		print $langs->trans("CompanyHasAbsoluteDiscount",$absolute_discount,$langs->trans("Currency".$conf->monnaie));
@@ -1523,7 +1531,6 @@ else
 			print '<tr><td>'.$langs->trans('Discounts').'</td><td colspan="5">';
 			if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client);
 			else print $langs->trans("CompanyHasNoRelativeDiscount");
-			$absolute_discount=$soc->getCurrentDiscount();
 			print '. ';
 			if ($absolute_discount)
 			{
@@ -2286,8 +2293,8 @@ else
 			$filename=sanitize_string($fac->ref);
 			$filedir=$conf->facture->dir_output . '/' . sanitize_string($fac->ref);
 			$urlsource=$_SERVER['PHP_SELF'].'?facid='.$fac->id;
-      $genallowed=($fac->statut == 1 && $user->rights->facture->creer);
-      $delallowed=$user->rights->facture->supprimer;
+			$genallowed=($fac->statut == 1 && $user->rights->facture->creer);
+			$delallowed=$user->rights->facture->supprimer;
 
 			$var=true;
 
@@ -2496,6 +2503,7 @@ else
 				$formmail->withfile=1;
 				$formmail->withbody=1;
 				$formmail->withdeliveryreceipt=1;
+				$formmail->withcancel=1;
 				// Tableau des substitutions
 				$formmail->substit['__FACREF__']=$fac->ref;
 				// Tableau des param�tres compl�mentaires du post
diff --git a/htdocs/compta/prelevement/rejet-prelevement.class.php b/htdocs/compta/prelevement/rejet-prelevement.class.php
index 46beb947d15..355880fec57 100644
--- a/htdocs/compta/prelevement/rejet-prelevement.class.php
+++ b/htdocs/compta/prelevement/rejet-prelevement.class.php
@@ -200,7 +200,8 @@ class RejetPrelevement
             $subject = "Pr�l�vement rejet�";
             $sendto = $emuser->fullname." <".$emuser->email.">";
             $from = $this->user->fullname." <".$this->user->email.">";
-    
+    		$msgishtml=0;
+    		
             $arr_file = array();
             $arr_mime = array();
             $arr_name = array();
@@ -210,7 +211,8 @@ class RejetPrelevement
             $message .= "\n\n--\n".$this->user->fullname;
     
             $mailfile = new CMailFile($subject,$sendto,$from,$message,
-                                      $arr_file,$arr_mime,$arr_name);
+                                      $arr_file,$arr_mime,$arr_name,
+                                      '', '', 0, $msgishtml);
             $mailfile->errors_to = $this->user->email;
     
             $result=$mailfile->sendfile();
diff --git a/htdocs/lib/CMailFile.class.php b/htdocs/lib/CMailFile.class.php
index 78cba0d1169..4afb84f0eeb 100644
--- a/htdocs/lib/CMailFile.class.php
+++ b/htdocs/lib/CMailFile.class.php
@@ -24,7 +24,7 @@
  * Lots of code inspired from Dan Potter's CMailFile class
  *
  * If chunk_split does not works on your system, change the call to chunk_split
- * to my_chunk_split 
+ * to _chunk_split 
  */
 
 /**
@@ -47,8 +47,7 @@
 class CMailFile
 {
     var $subject;
-    var $addr_from_email;
-    var $addr_from_name;
+    var $addr_from;
     var $addr_to;
     var $addr_cc;
     var $addr_bcc;
@@ -58,77 +57,72 @@ class CMailFile
     var $mime_boundary;
     var $smtp_headers;
     var $deliveryreceipt;
+    
+    var $eol;
+    var $atleastonefile=0;
+    var $error='';
+    
 
     /**
-            \brief CMailFile
-            \param subject              sujet
-            \param to                   email destinataire ("Nom <email>" ou "email" ou "<email>")
-            \param from                 email emetteur ("Nom <email>" ou "email" ou "<email>")
-            \param msg                  message
-            \param filename_list        tableau de fichiers attach�s
-            \param mimetype_list        tableau des types des fichiers attach�s
-            \param mimefilename_list    tableau des noms des fichiers attach�s
-            \param addr_cc              email cc
-            \param addr_bcc             email bcc
+            \brief 	CMailFile
+            \param 	subject             sujet
+            \param 	to                  email destinataire (RFC 2822: "Nom prenom <email>[, ...]" ou "email[, ...]" ou "<email>[, ...]")
+            \param 	from                email emetteur     (RFC 2822: "Nom prenom <email>[, ...]" ou "email[, ...]" ou "<email>[, ...]")
+            \param 	msg                 message
+            \param 	filename_list       tableau de fichiers attach�s
+            \param 	mimetype_list       tableau des types des fichiers attach�s
+            \param 	mimefilename_list   tableau des noms des fichiers attach�s
+            \param 	addr_cc             email cc
+            \param 	addr_bcc            email bcc
+            \param	msgishtml			message is a html message
     */
     function CMailFile($subject,$to,$from,$msg,
                        $filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),
-                       $addr_cc="",$addr_bcc="",$deliveryreceipt=0)
+                       $addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0)
     {
-        dolibarr_syslog("CMailFile::CMailfile: from=$from, to=$to, filename_list[0]=$filename_list[0], mimetype_list[0]=$mimetype_list[0] mimefilename_list[0]=$mimefilename_list[0]");
-
+        dolibarr_syslog("CMailFile::CMailfile: from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc");
+        dolibarr_syslog("CMailFile::CMailfile: subject=$subject, deliveryreceipt=$deliveryreceipt, msgishtml=$msgishtml");
+        foreach ($filename_list as $i => $val)
+        {
+        	if ($filename_list[$i])
+        	{
+        		$this->atleastonefile=1;
+        		dolibarr_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i]);
+			}
+		}
         $this->mime_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->msgishtml = $msgishtml;
+
+        // Genere en-tete dans $this->smtp_headers
         $this->subject = $subject;
-        if (eregi('(.*)<(.+)>',$from,$regs))
-        {
-            $this->addr_from_name  = trim($regs[1]);
-            $this->addr_from_email = trim($regs[2]);
-        }
-        else
-        {
-            $this->addr_from_name  = $from;
-            $this->addr_from_email = $from;
-        }
+        $this->addr_from = $from;
         $this->addr_to = $to;
         $this->addr_cc = $addr_cc;
         $this->addr_bcc = $addr_bcc;
         $this->deliveryreceipt = $deliveryreceipt;
         $this->smtp_headers = $this->write_smtpheaders();
-        $this->text_body = $this->write_body($msg, $filename_list);
-        if (count($filename_list))
+
+		// Genere en-tete suite dans $this->mime_headers
+        if ($this->atleastonefile)
         {
             $this->mime_headers = $this->write_mimeheaders($filename_list, $mimefilename_list);
-            $this->text_encoded = $this->attach_file($filename_list,$mimetype_list,$mimefilename_list);
-        }
-    }
-
+		}
 
-    /**
-            \brief permet d'attacher un fichier
-            \param filename_list
-            \param mimetype_list
-            \param mimefilename_list
-    */
-    function attach_file($filename_list,$mimetype_list,$mimefilename_list)
-    {
-        for ($i = 0; $i < count($filename_list); $i++)
+		// Genere corps message dans $this->text_body
+        $this->text_body = $this->write_body($msg, $filename_list);
+        
+        // Genere corps message suite (fichiers attach�s) dans $this->text_encoded
+        if ($this->atleastonefile)
         {
-            dolibarr_syslog("CMailFile::attach_file: i=$i");
-            $encoded = $this->encode_file($filename_list[$i]);
-            if ($encoded != -1)
-            {
-                if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
-                $out = $out . "--" . $this->mime_boundary . "\n";
-                if (! $mimetype_list[$i]) { $mimetype_list[$i] = "application/octet-stream"; }
-                $out .= "Content-type: " . $mimetype_list[$i] . "; name=\"$filename_list[$i]\";\n";
-                $out .= "Content-Transfer-Encoding: base64\n";
-                $out .= "Content-disposition: attachment; filename=\"$filename_list[$i]\"\n\n";
-                $out .= $encoded . "\n";
-            }
+            $this->text_encoded = $this->write_files($filename_list,$mimetype_list,$mimefilename_list);
         }
-        $out = $out . "--" . $this->mime_boundary . "--" . "\n";
-        return $out;
+        
     }
 
 
@@ -137,166 +131,294 @@ class CMailFile
             \param      sourcefile
             \return     <0 si erreur, fichier encod� si ok
     */
-    function encode_file($sourcefile)
+    function _encode_file($sourcefile)
     {
         if (is_readable($sourcefile))
         {
             $fd = fopen($sourcefile, "r");
             $contents = fread($fd, filesize($sourcefile));
-            $encoded = chunk_split(base64_encode($contents));
-            //$encoded = my_chunk_split(base64_encode($contents));
+            $encoded = chunk_split(base64_encode($contents), 68, $this->eol);
+            //$encoded = _chunk_split(base64_encode($contents));
             fclose($fd);
             return $encoded;
         }
         else
         {
-            dolibarr_syslog("CMailFile::encode_file: Can't read file '$sourcefile'");
+            $this->error="Error: Can't read file '$sourcefile'";
+            dolibarr_syslog("CMailFile::encode_file: ".$this->error);
             return -1;
         }
     }
 
     /**
             \brief     Envoi le mail
-            \return    boolean     vrai si mail envoy�, faux sinon
+            \return    boolean     true si mail envoy�, false sinon
     */
     function sendfile()
     {
-        global $conf;
+        global $conf,$langs;
         
         $headers = $this->smtp_headers . $this->mime_headers;
-        $message=$this->text_body . $this->text_encoded;
+        $message = $this->text_body . $this->text_encoded;
 
-        // Fix si windows, la fonction mail ne traduit pas les \n, il faut donc y mettre
-        // des champs \r\n (impos�s par SMTP).
-        if (eregi('^win',PHP_OS))
-        {
-            $message = eregi_replace("\r","", $this->text_body . $this->text_encoded);
-            $message = eregi_replace("\n","\r\n", $message);
-        }
-        
-        dolibarr_syslog("CMailFile::sendfile addr_to=".$this->addr_to.", subject=".$this->subject);
-        //dolibarr_syslog("CMailFile::sendfile message=\n".$message);
-        //dolibarr_syslog("CMailFile::sendfile header=\n".$headers);
+        dolibarr_syslog("CMailFile::sendfile addr_to_name=".$this->addr_to_name.", addr_to_email=".$this->addr_to_email.", subject=".$this->subject);
+        dolibarr_syslog("CMailFile::sendfile header=\n".$headers);
+        dolibarr_syslog("CMailFile::sendfile message=\n".$message);
+        //$this->send_to_file();
 
         $errorlevel=error_reporting();
         //error_reporting($errorlevel ^ E_WARNING);   // D�sactive warnings
+
         if (! $conf->global->MAIN_DISABLE_ALL_MAILS)
         {
+			if ($conf->global->MAIN_MAIL_SMTP_SERVER)	ini_set('SMTP',$conf->global->MAIN_MAIL_SMTP_SERVER);
+			if ($conf->global->MAIN_MAIL_SMTP_PORT) 	ini_set('smtp_port',$conf->global->MAIN_MAIL_SMTP_PORT);
+
 	        if ($this->errors_to)
 	        {
-	            dolibarr_syslog("CMailFile::sendfile with errorsto : ".$this->errors_to);
-	            $res = mail($this->addr_to,$this->subject,stripslashes($message),$headers,"-f".$this->errors_to);
+	            dolibarr_syslog("CMailFile::sendfile: mail start SMTP=".ini_get('SMTP').", PORT=".ini_get('smtp_port').", with errorsto : ".getValidAddress($this->errors_to,1));
+	            $res = mail(getValidAddress($this->addr_to,2),$this->subject,stripslashes($message),$headers,"-f".getValidAddress($this->errors_to,2));
+	        }
+	        else
+	        {
+	            dolibarr_syslog("CMailFile::sendfile: mail start SMTP=".ini_get('SMTP').", PORT=".ini_get('smtp_port'));
+	            $res = mail(getValidAddress($this->addr_to,2),$this->subject,stripslashes($message),$headers);
+	        }
+	        if (! $res) 
+	        {
+	        	$this->error=$langs->trans("Failed to send mail to SMTP=".ini_get('SMTP').", PORT=".ini_get('smtp_port')."<br>Check your server logs and your firewalls setup");
+	        	dolibarr_syslog("CMailFile::sendfile: mail end res=$res ".$this->error);
 	        }
 	        else
 	        {
-	            dolibarr_syslog("CMailFile::sendfile");
-	            $res = mail($this->addr_to,$this->subject,stripslashes($message),$headers);
+	        	dolibarr_syslog("CMailFile::sendfile: mail end res=$res");
 	        }
-	        //if (! $res) $this->error= 
+
+			if ($conf->global->MAIN_MAIL_SMTP_SERVER)	ini_restore('SMTP');
+			if ($conf->global->MAIN_MAIL_SMTP_PORT) 	ini_restore('smtp_port');
+		}
+		else
+		{
+            dolibarr_syslog("CMailFile::sendfile: No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS");
 		}
-        error_reporting($errorlevel);              // R�active niveau erreur origine
 
-        //$this->write_to_file();
+        error_reporting($errorlevel);              // R�active niveau erreur origine
 
         return $res;
     }
 
+
     /**
      *    \brief  Ecrit le mail dans un fichier.
      *            Utilisation pour le debuggage
      */
-    function write_to_file()
+    function send_to_file()
     {
         $headers = $this->smtp_headers . $this->mime_headers;
         $message = $this->text_body . $this->text_encoded;
 
-        $fp = fopen("/tmp/mail","w");
+        $fp = fopen("/tmp/dolibarr_mail","w");
         fputs($fp, $headers);
         fputs($fp, $message);
         fclose($fp);
     }
 
+
     /**
-            \brief 	Permet d'ecrire le corps du message
-            \param 	msgtext
-            \param 	filename_list
+            \brief		Cr�ation des headers smtp
+            \remarks	On construit tout avec \n. Toute correction se fait plus tard.
     */
-    function write_body($msgtext, $filename_list)
+    function write_smtpheaders()
     {
-    	global $conf;
-        $out='';
-        if (count($filename_list))
-        {
-            $out = "--" . $this->mime_boundary . "\n";
-            $out .= "Content-Type: text/plain; charset=\"iso8859-15\"\n\n";
-            //	  $out = $out . "Content-Type: text/plain; charset=\"us-ascii\"\n\n";
-        }
-        if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_MAILING)
+        $out = "";
+
+		// Sender
+        //$out .= "X-Sender: ".getValidAddress($this->addr_from,2).$this->eol;
+		$out .= "From: ".getValidAddress($this->addr_from,0).$this->eol;
+        $out .= "Return-Path: ".getValidAddress($this->addr_from,0).$this->eol;
+        if (isset($this->reply_to)  && $this->reply_to)  $out .= "Reply-To: ".getValidAddress($this->reply_to,2).$this->eol;
+        if (isset($this->errors_to) && $this->errors_to) $out .= "Errors-To: ".getValidAddress($this->errors_to,2).$this->eol;
+
+		// Receiver
+        if (isset($this->addr_cc)   && $this->addr_cc)   $out .= "Cc: ".getValidAddress($this->addr_cc,2).$this->eol;
+        if (isset($this->addr_bcc)  && $this->addr_bcc)  $out .= "Bcc: ".getValidAddress($this->addr_bcc,2).$this->eol;
+
+        // Accus� r�ception
+        if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $out .= "Disposition-Notification-To: ".getValidAddress($this->addr_from,1).$this->eol;
+
+        $out .= "X-Mailer: Dolibarr version " . DOL_VERSION .$this->eol;
+        //$out .= "X-Priority: 3\n";
+       
+        if ($this->msgishtml)
         {
-        	$out .= "<html><BODY>\n";
-        	$out .= "<html><head><title></title></head><body>";
-          $out .= $msgtext;
-          $out .= "</body></html>";
+        	$out.= "Content-Type: text/html; charset=\"iso-8859-1\"".$this->eol;
+        	$out.= "Content-Transfer-Encoding: 8bit".$this->eol;
         }
         else
         {
-        	$out .= $msgtext . "\n";
+			$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
+		}
+
+        dolibarr_syslog("CMailFile::write_smtpheaders $out");
+        return $out;
+    }
+
+
+    /**
+            \brief 		Cr�ation header MIME
+            \param 		filename_list
+            \param 		mimefilename_list
+            \remarks	On construit tout avec \n. Toute correction se fait plus tard.
+    */
+    function write_mimeheaders($filename_list, $mimefilename_list)
+    {
+		$mimedone=0;
+        for ($i = 0; $i < count($filename_list); $i++)
+        {
+        	if ($filename_list[$i])
+        	{
+				if (! $mimedone)
+				{
+			        $out = "";
+			        $out.= "MIME-Version: 1.0".$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];
+            	$out.= "X-attachments: $filename_list[$i]".$this->eol;
+        	}
         }
+      	$out.= $this->eol;
         return $out;
     }
 
     /**
-            \brief cr�ation des headers mime
-            \param filename_list
-            \param mimefilename_list
+            \brief 		Permet d'ecrire le corps du message
+            \param 		msgtext
+            \param 		filename_list
+            \remarks	On construit tout avec \n. Toute correction se fait plus tard.
     */
-    function write_mimeheaders($filename_list, $mimefilename_list) {
-        $out = "MIME-version: 1.0\n";
-        $out = $out . "Content-type: multipart/mixed; ";
-        $out = $out . "boundary=\"$this->mime_boundary\"\n";
-        $out = $out . "Content-transfer-encoding: 7BIT\n";
-        for($i = 0; $i < count($filename_list); $i++) {
-            if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
-            $out = $out . "X-attachments: $filename_list[$i];\n\n";
+    function write_body($msgtext, $filename_list)
+    {
+        $out='';
+        if ($this->atleastonefile)
+        {
+            $out.= "--" . $this->mime_boundary . $this->eol;
+	        if ($this->msgishtml)
+	        {
+	        	$out.= "Content-Type: text/html; charset=\"iso-8859-1\"".$this->eol;
+	        }
+            $out.= $this->eol;
+        }
+        if ($this->msgishtml)
+        {
+			// Check if html header already in message
+			$htmlalreadyinmsg=0;
+			if (eregi('^[ \t]*<html>',$msgtext)) $htmlalreadyinmsg=1;
+			
+			if (! $htmlalreadyinmsg) $out .= "<html><head><title></title></head><body>";
+			$out.= $msgtext;
+			if (! $htmlalreadyinmsg) $out .= "</body></html>";
+        }
+        else
+        {
+        	$out.= $msgtext;
         }
+       	$out.= $this->eol;
         return $out;
     }
 
     /**
-            \brief cr�ation des headers smtp
+            \brief 		Permet d'attacher un fichier
+            \param 		filename_list		Tableau
+            \param 		mimetype_list		Tableau
+            \param 		mimefilename_list	Tableau
+            \return		out					Chaine fichiers encod�s
+            \remarks	On construit tout avec \n. Toute correction se fait plus tard.
     */
-    function write_smtpheaders()
+    function write_files($filename_list,$mimetype_list,$mimefilename_list)
     {
-    	global $conf;
         $out = "";
-
-        $out .= "X-Mailer: Dolibarr version " . DOL_VERSION ."\n";
-        $out .= "X-Sender: <$this->addr_from_email>\n";
-        //$out .= "X-Priority: 3\n";
-
-        $out .= "Return-path: <$this->addr_from_email>\n";
-        $out .= "From: $this->addr_from_name <".$this->addr_from_email.">\n";
-
-        if (isset($this->addr_cc)  && $this->addr_cc)  $out .= "Cc: ".$this->addr_cc."\n";
-        if (isset($this->addr_bcc) && $this->addr_bcc) $out .= "Bcc: ".$this->addr_bcc."\n";
-        if (isset($this->reply_to) && $this->reply_to) $out .= "Reply-To: ".$this->reply_to."\n";
         
-        //accus� r�ception
-        if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $out .= "Disposition-Notification-To: ".$this->addr_from_email."\n";
-        
-        //    if($this->errors_to != "")
-        //$out = $out . "Errors-to: ".$this->errors_to."\n";
-        
-        if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_MAILING)
+        for ($i = 0; $i < count($filename_list); $i++)
         {
-        	$out .= "Content-Type: text/html; charset=\"iso-8859-15\"\n";
-        	$out .= "Content-Transfer-Encoding: 8bit\n";
+            if ($filename_list[$i])
+            {
+	            dolibarr_syslog("CMailFile::write_files: i=$i");
+	            $encoded = $this->_encode_file($filename_list[$i]);
+	            if ($encoded >= 0)
+	            {
+	                if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
+	                if (! $mimetype_list[$i]) { $mimetype_list[$i] = "application/octet-stream"; }
+
+	                $out = $out . "--" . $this->mime_boundary . $this->eol;
+	                $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.= $this->eol;
+	                $out.= $encoded;
+	                $out.= $this->eol;
+	            }
+	            else
+	            {
+	            	return $encoded;
+	            }
+			}
         }
 
-        dolibarr_syslog("CMailFile::write_smtpheaders $out");
+		// Fin de tous les attachements
+        $out = $out . "--" . $this->mime_boundary . "--" . $this->eol;
         return $out;
     }
+    
+}
+
+
+/**
+        \brief      Renvoie une adresse accept�e par le serveur SMTP
+        \param      adresses		Exemple: 'Jhon Doe <jhon@doe.com>' ou 'jhon@doe.com'
+        \param		format			0=Auto, 1=emails avec <>, 2=emails sans <>
+        \return	    string			Renvoi: '<john@doe.com>' ou 'Jhon Doe <jhon@doe.com>' ou 'john@doe.com'
+*/
+function getValidAddress($adresses,$format)
+{
+	global $conf;
+	
+	$ret="";
+	
+	$arrayaddress=split(',',$adresses);
 
+	// Boucle sur chaque composant de l'adresse
+	foreach($arrayaddress as $val)
+	{
+	   	if (eregi('^(.*)<(.+)>$',trim($val),$regs))
+	    {
+	        $name  = trim($regs[1]);
+	        $email = trim($regs[2]);
+	    }
+	    else
+	    {
+	        $name  = '';
+	        $email = trim($val);
+	    }
+	
+		if ($format == 2)
+		{
+			$ret=($ret ? $ret.',' : '').$email;
+		}
+		if ($format == 1)
+		{
+			$ret=($ret ? $ret.',' : '').'<'.$email.'>';
+		}
+		if ($format == 0)
+		{
+			if ($conf->global->MAIN_MAIL_NO_FULL_EMAIL) $ret=($ret ? $ret.',' : '').'<'.$email.'>';
+			elseif (! $name) $ret=($ret ? $ret.',' : '').'<'.$email.'>';
+			else $ret=($ret ? $ret.',' : '').$name.' <'.$email.'>';
+		}
+	}
+	
+	return $ret;
 }
 
 
@@ -304,21 +426,21 @@ class CMailFile
         \brief      Permet de diviser une chaine (RFC2045)
         \param      str
         \remarks    function chunk_split qui remplace celle de php si n�c�ssaire
-        \remarks    76 caract�res par ligne, termin� par "\r\n"
+        \remarks    76 caract�res par ligne, termin� par "\n"
 */
-function my_chunk_split($str)
+function _chunk_split($str)
 {
     $stmp = $str;
     $len = strlen($stmp);
     $out = "";
     while ($len > 0) {
         if ($len >= 76) {
-            $out = $out . substr($stmp, 0, 76) . "\r\n";
+            $out = $out . substr($stmp, 0, 76) . "\n";
             $stmp = substr($stmp, 76);
             $len = $len - 76;
         }
         else {
-            $out = $out . $stmp . "\r\n";
+            $out = $out . $stmp . "\n";
             $stmp = ""; $len = 0;
         }
     }
diff --git a/htdocs/notify.class.php b/htdocs/notify.class.php
index 894e4c3b993..adf517f2dca 100644
--- a/htdocs/notify.class.php
+++ b/htdocs/notify.class.php
@@ -140,7 +140,8 @@ class Notify
                     $subject = $langs->trans("DolibarrNotification");
                     $message = $texte;
                     $filename = split("/",$file);
-
+					$msgishtml=0;
+					
                     $replyto = $conf->notification->email_from;
 
                     $mailfile = new CMailFile($subject,
@@ -149,7 +150,8 @@ class Notify
 	                    $message,
 	                    array($file),
 	                    array("application/pdf"),
-	                    array($filename[sizeof($filename)-1])
+	                    array($filename[sizeof($filename)-1]),
+	                    '', '', 0, $msgishtml
 	                    );
 
                     if ( $mailfile->sendfile() )
diff --git a/htdocs/user.class.php b/htdocs/user.class.php
index c45e8e7aa07..5d8439faae6 100644
--- a/htdocs/user.class.php
+++ b/htdocs/user.class.php
@@ -906,6 +906,7 @@ class User
         require_once DOL_DOCUMENT_ROOT."/lib/CMailFile.class.php";
 
         $subject = $langs->trans("SubjectNewPassword");
+        $msgishtml=0;
         
         $mesg .= "Bonjour,\n\n";
         $mesg .= "Votre mot de passe pour acc�der � Dolibarr a �t� chang� :\n\n";
@@ -917,7 +918,9 @@ class User
         $mesg .= "--\n";
         $mesg.= $user->fullname;
 
-        $mailfile = new CMailFile($subject,$this->email,$conf->email_from,$mesg,array(),array(),array());
+        $mailfile = new CMailFile($subject,$this->email,$conf->email_from,$mesg,
+        							array(),array(),array(),
+        							'', '', 0, $msgishtml);
 
         if ($mailfile->sendfile())
         {
diff --git a/scripts/invoices/factures-impayees-commerciaux.php b/scripts/invoices/factures-impayees-commerciaux.php
index e9b00506585..8efc6115a0b 100644
--- a/scripts/invoices/factures-impayees-commerciaux.php
+++ b/scripts/invoices/factures-impayees-commerciaux.php
@@ -113,7 +113,8 @@ function envoi_mail($oldemail,$message,$total)
     $subject = "[Dolibarr] Liste des factures impay�es";
     $sendto = $oldemail;
     $from = $conf->global->MAIN_EMAIL_FROM;
-
+	$msgishtml = 0;
+	
     print "Envoi mail pour $oldemail, total: $total\n";
     dolibarr_syslog("factures-impayees-commerciaux: send mail to $oldemail");
 
@@ -127,7 +128,8 @@ function envoi_mail($oldemail,$message,$total)
     $mail = new CMailFile($subject,
     $sendto,
     $from,
-    $allmessage,array(),array(),array());
+    $allmessage,array(),array(),array()
+    '', '', 0, $msgishtml);
 
     $mail->errors_to = $errorsto;
 
diff --git a/scripts/mailing/mailing-send.php b/scripts/mailing/mailing-send.php
index 74c98f9e880..20afa73ed48 100644
--- a/scripts/mailing/mailing-send.php
+++ b/scripts/mailing/mailing-send.php
@@ -80,23 +80,28 @@ $sql .= " LIMIT 1";
 $resql=$db->query($sql);
 if ($resql) 
 {
-  $num = $db->num_rows($resql);
-  $i = 0;
-  
-  if ($num == 1)
-    {
-      $obj = $db->fetch_object($resql);
-
-      dolibarr_syslog("mailing-send: mailing ".$id);
-
-      $id       = $obj->rowid;
-      $subject  = $obj->sujet;
-      $message  = $obj->body;
-      $from     = $obj->email_from;
-      $errorsto = $obj->email_errorsto;
-
-      $i++;
-    }
+	$num = $db->num_rows($resql);
+	$i = 0;
+
+	if ($num == 1)
+	{
+		$obj = $db->fetch_object($resql);
+
+		dolibarr_syslog("mailing-send: mailing ".$id);
+
+		$id       = $obj->rowid;
+		$subject  = $obj->sujet;
+		$message  = $obj->body;
+		$from     = $obj->email_from;
+		$errorsto = $obj->email_errorsto;
+
+		// Le message est-il en html
+		$msgishtml=0;	// Non par defaut
+		if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_MAILING) $msgishtml=1;
+		if (eregi('[ \t]*<html>',$message)) $msgishtml=1;						
+		
+		$i++;
+	}
 }
 
 
@@ -129,13 +134,31 @@ if ($resql)
         $i = 0;
         while ($i < $num )
         {
+            $res=1;
+            
             $obj = $db->fetch_object($resql);
 
+            // sendto en RFC2822
             $sendto = stripslashes($obj->prenom). " ".stripslashes($obj->nom) ."<".$obj->email.">";
-            $mail = new CMailFile($subject, $sendto, $from, $message, array(), array(), array());
-            $mail->errors_to = $errorsto;
-    
-            if ( $mail->sendfile() )
+
+            // Fabrication du mail
+            $mail = new CMailFile($subject, $sendto, $from, $message, 
+            						array(), array(), array(),
+            						'', '', 0, $msgishtml);
+            						
+			if ($mail->error)
+			{
+				$res=0;
+			}
+
+            // Envoi du mail
+			if ($res)
+			{
+	            $mail->errors_to = $errorsto;
+    			$res=$mail->sendfile();
+			}
+			
+            if ($res)
             {
                 // Mail envoye avec succes
                 $nbok++;
-- 
GitLab