Prepare code to use different SMTP servers.

This commit is contained in:
Laurent Destailleur 2017-04-18 01:39:06 +02:00
parent 0994622bf8
commit 3da0aea168
3 changed files with 351 additions and 338 deletions

View File

@ -27,7 +27,7 @@
*/ */
/** /**
* \file htdocs/admin/dict.php * \file htdocs/admin/mails_templates.php
* \ingroup setup * \ingroup setup
* \brief Page to administer data tables * \brief Page to administer data tables
*/ */
@ -119,12 +119,14 @@ $formmail=new FormMail($db);
if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES))
{ {
$tmp=$formmail->getAvailableSubstitKey('form'); $tmp=$formmail->getAvailableSubstitKey('form');
$tmp['__(AnyTransKey)__']='__(AnyTransKey)__';
$helpsubstit = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp); $helpsubstit = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp);
$helpsubstitforlines = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp); $helpsubstitforlines = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp);
} }
else else
{ {
$tmp=$formmail->getAvailableSubstitKey('formwithlines'); $tmp=$formmail->getAvailableSubstitKey('formwithlines');
$tmp['__(AnyTransKey)__']='__(AnyTransKey)__';
$helpsubstit = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp); $helpsubstit = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp);
$tmp=$formmail->getAvailableSubstitKey('formforlines'); $tmp=$formmail->getAvailableSubstitKey('formforlines');
$helpsubstitforlines = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp); $helpsubstitforlines = $langs->trans("AvailableVariables").':<br>'.implode('<br>', $tmp);

View File

@ -787,8 +787,8 @@ else
if ($action == 'sendall') if ($action == 'sendall')
{ {
// Define message to recommand from command line // Define message to recommand from command line
$sendingmode=$conf->global->EMAILING_MAIL_SENDMODE;
$sendingmode=$conf->global->MAIN_MAIL_SENDMODE; if (empty($sendingmode)) $sendingmode=$conf->global->MAIN_MAIL_SENDMODE;
if (empty($sendingmode)) $sendingmode='mail'; // If not defined, we use php mail function if (empty($sendingmode)) $sendingmode='mail'; // If not defined, we use php mail function
// MAILING_NO_USING_PHPMAIL may be defined or not. // MAILING_NO_USING_PHPMAIL may be defined or not.

View File

@ -31,16 +31,20 @@
/** /**
* Class to send emails (with attachments or not) * Class to send emails (with attachments or not)
* Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid); * Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid,$moreinheader,$sendcontext);
* $mailfile->sendfile(); * $mailfile->sendfile();
*/ */
class CMailFile class CMailFile
{ {
public $sendcontext;
public $sendmode;
public $sendsetup;
var $subject; // Topic: Subject of email var $subject; // Topic: Subject of email
var $addr_from; // From: Label and EMail of sender (must include '<>'). For example '<myemail@example.com>' or 'John Doe <myemail@example.com>' or '<myemail+trackingid@example.com>'). Note that with gmail smtps, value here is forced by google to account (but not the reply-to). var $addr_from; // From: Label and EMail of sender (must include '<>'). For example '<myemail@example.com>' or 'John Doe <myemail@example.com>' or '<myemail+trackingid@example.com>'). Note that with gmail smtps, value here is forced by google to account (but not the reply-to).
// Sender: Who send the email ("Sender" has sent emails on behalf of "From"). // Sender: Who send the email ("Sender" has sent emails on behalf of "From").
// Use it when the "From" is an email of a domain that is a SPF protected domain, and sending smtp server is not this domain. In such case, add Sender field with an email of the protected domain. // Use it when the "From" is an email of a domain that is a SPF protected domain, and sending smtp server is not this domain. In such case, add Sender field with an email of the protected domain.
// Return-Path: Email where to send bounds. // Return-Path: Email where to send bounds.
var $reply_to; // Reply-To: Email where to send replies from mailer software (mailer use From if reply-to not defined, Gmail use gmail account if reply-to not defined) var $reply_to; // Reply-To: Email where to send replies from mailer software (mailer use From if reply-to not defined, Gmail use gmail account if reply-to not defined)
var $errors_to; // Errors-To: Email where to send errors. var $errors_to; // Errors-To: Email where to send errors.
var $addr_to; var $addr_to;
@ -77,13 +81,13 @@ class CMailFile
var $html_images=array(); var $html_images=array();
var $images_encoded=array(); var $images_encoded=array();
var $image_types = array('gif' => 'image/gif', var $image_types = array('gif' => 'image/gif',
'jpg' => 'image/jpeg', 'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg', 'jpeg' => 'image/jpeg',
'jpe' => 'image/jpeg', 'jpe' => 'image/jpeg',
'bmp' => 'image/bmp', 'bmp' => 'image/bmp',
'png' => 'image/png', 'png' => 'image/png',
'tif' => 'image/tiff', 'tif' => 'image/tiff',
'tiff' => 'image/tiff'); 'tiff' => 'image/tiff');
/** /**
@ -104,13 +108,21 @@ class CMailFile
* @param string $css Css option * @param string $css Css option
* @param string $trackid Tracking string (contains type and id of related element) * @param string $trackid Tracking string (contains type and id of related element)
* @param string $moreinheader More in header. $moreinheader must contains the "\r\n" (TODO not supported for other MAIL_SEND_MODE different than 'phpmail' and 'smtps' for the moment) * @param string $moreinheader More in header. $moreinheader must contains the "\r\n" (TODO not supported for other MAIL_SEND_MODE different than 'phpmail' and 'smtps' for the moment)
* @param string $sendingcontext 'standard', 'emailing', ... * @param string $sendcontext 'standard', 'emailing', ...
*/ */
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='',$sendingcontext='standard') 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='',$sendcontext='standard')
{ {
global $conf, $dolibarr_main_data_root; global $conf, $dolibarr_main_data_root;
$this->sendingcontext = $sendingcontext; $this->sendcontext = $sendcontext;
$this->sendmode = '';
if ($this->sendcontext == 'emailing') $this->sendmode = $conf->global->EMAILING_MAIL_SENDMODE;
if (empty($this->sendmode)) $this->sendmode=$conf->global->MAIN_MAIL_SENDMODE;
if (empty($this->sendmode)) $this->sendmode='mail';
$this->sendsetup = array();
// We define end of line (RFC 821). // We define end of line (RFC 821).
$this->eol="\r\n"; $this->eol="\r\n";
@ -132,17 +144,14 @@ class CMailFile
// On defini alternative_boundary // On defini alternative_boundary
$this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3); // Force md5 hash (does not contains special chars) $this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3); // Force md5 hash (does not contains special chars)
// If ending method not defined dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, trackid=$trackid sendcontext=$sendcontext", LOG_DEBUG);
if (empty($conf->global->MAIN_MAIL_SENDMODE)) $conf->global->MAIN_MAIL_SENDMODE='mail';
dol_syslog("CMailFile::CMailfile: MAIN_MAIL_SENDMODE=".$conf->global->MAIN_MAIL_SENDMODE." charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, trackid=$trackid sendingcontext=$sendingcontext", LOG_DEBUG);
dol_syslog("CMailFile::CMailfile: subject=$subject, deliveryreceipt=$deliveryreceipt, msgishtml=$msgishtml", LOG_DEBUG); dol_syslog("CMailFile::CMailfile: subject=$subject, deliveryreceipt=$deliveryreceipt, msgishtml=$msgishtml", LOG_DEBUG);
if (empty($subject)) if (empty($subject))
{ {
dol_syslog("CMailFile::CMailfile: Try to send an email with empty subject"); dol_syslog("CMailFile::CMailfile: Try to send an email with empty subject");
$this->error='ErrorSubjectIsRequired'; $this->error='ErrorSubjectIsRequired';
return; return;
} }
// Detect if message is HTML (use fast method) // Detect if message is HTML (use fast method)
@ -163,10 +172,10 @@ class CMailFile
{ {
$this->html = $msg; $this->html = $msg;
if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS)) if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS))
{ {
$findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias'); $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias');
} }
// Define if there is at least one file // Define if there is at least one file
if ($findimg) if ($findimg)
@ -196,7 +205,7 @@ class CMailFile
if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO; if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO;
// Action according to choosed sending method // Action according to choosed sending method
if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') if ($this->sendmode == 'mail')
{ {
// Use mail php function (default PHP method) // Use mail php function (default PHP method)
// ------------------------------------------ // ------------------------------------------
@ -218,7 +227,7 @@ class CMailFile
$this->trackid = $trackid; $this->trackid = $trackid;
$smtp_headers = $this->write_smtpheaders(); $smtp_headers = $this->write_smtpheaders();
if (! empty($moreinheader)) $smtp_headers.=$moreinheader; // $moreinheader contains the \r\n if (! empty($moreinheader)) $smtp_headers.=$moreinheader; // $moreinheader contains the \r\n
// Define mime_headers // Define mime_headers
$mime_headers = $this->write_mimeheaders($filename_list, $mimefilename_list); $mime_headers = $this->write_mimeheaders($filename_list, $mimefilename_list);
@ -254,7 +263,7 @@ class CMailFile
$this->message.= $text_body . $files_encoded; $this->message.= $text_body . $files_encoded;
$this->message.= "--" . $this->mixed_boundary . "--" . $this->eol; $this->message.= "--" . $this->mixed_boundary . "--" . $this->eol;
} }
else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') else if ($this->sendmode == 'smtps')
{ {
// Use SMTPS library // Use SMTPS library
// ------------------------------------------ // ------------------------------------------
@ -310,7 +319,7 @@ class CMailFile
$this->smtps=$smtps; $this->smtps=$smtps;
} }
// TODO not stable, in progress // TODO not stable, in progress
else if ($conf->global->MAIN_MAIL_SENDMODE == 'phpmailer') else if ($this->sendmode == 'phpmailer')
{ {
// Use PHPMailer library // Use PHPMailer library
// ------------------------------------------ // ------------------------------------------
@ -362,94 +371,94 @@ class CMailFile
$this->phpmailer->setErrorsTo($errors_to); $this->phpmailer->setErrorsTo($errors_to);
$this->phpmailer->setDeliveryReceipt($deliveryreceipt); $this->phpmailer->setDeliveryReceipt($deliveryreceipt);
} }
else if ($conf->global->MAIN_MAIL_SENDMODE == 'swiftmailer') else if ($this->sendmode == 'swiftmailer')
{ {
// Use Swift Mailer library // Use Swift Mailer library
// ------------------------------------------ // ------------------------------------------
$host = dol_getprefix('email'); $host = dol_getprefix('email');
require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php'; require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php';
// Create the message // Create the message
$this->message = Swift_Message::newInstance(); $this->message = Swift_Message::newInstance();
// Adding a trackid header to a message // Adding a trackid header to a message
$headers = $this->message->getHeaders(); $headers = $this->message->getHeaders();
$headers->addTextHeader('X-Dolibarr-TRACKID', $trackid); $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid);
$headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host; $headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host;
$msgid = $headers->get('Message-ID'); $msgid = $headers->get('Message-ID');
$msgid->setId($headerID); $msgid->setId($headerID);
$headers->addIdHeader('References', $headerID); $headers->addIdHeader('References', $headerID);
// TODO if (! empty($moreinheader)) ... // TODO if (! empty($moreinheader)) ...
// Give the message a subject // Give the message a subject
$this->message->setSubject($this->encodetorfc2822($subject)); $this->message->setSubject($this->encodetorfc2822($subject));
// Set the From address with an associative array // Set the From address with an associative array
//$this->message->setFrom(array('john@doe.com' => 'John Doe')); //$this->message->setFrom(array('john@doe.com' => 'John Doe'));
if (! empty($from)) $this->message->setFrom($this->getArrayAddress($from)); if (! empty($from)) $this->message->setFrom($this->getArrayAddress($from));
// Set the To addresses with an associative array // Set the To addresses with an associative array
if (! empty($to)) $this->message->setTo($this->getArrayAddress($to)); if (! empty($to)) $this->message->setTo($this->getArrayAddress($to));
if (! empty($from)) $this->message->SetReplyTo($this->getArrayAddress($from)); if (! empty($from)) $this->message->SetReplyTo($this->getArrayAddress($from));
$this->message->setCharSet($conf->file->character_set_client); $this->message->setCharSet($conf->file->character_set_client);
if (! empty($this->html)) if (! empty($this->html))
{ {
if (!empty($css)) if (!empty($css))
{ {
$this->css = $css; $this->css = $css;
$this->buildCSS(); $this->buildCSS();
} }
$msg = $this->html; $msg = $this->html;
$msg = $this->checkIfHTML($msg); $msg = $this->checkIfHTML($msg);
} }
if ($this->atleastoneimage) if ($this->atleastoneimage)
{ {
foreach ($this->images_encoded as $img) foreach ($this->images_encoded as $img)
{ {
//$img['fullpath'],$img['image_encoded'],$img['name'],$img['content_type'],$img['cid'] //$img['fullpath'],$img['image_encoded'],$img['name'],$img['content_type'],$img['cid']
$attachment = Swift_Image::fromPath($img['fullpath'], $img['content_type']); $attachment = Swift_Image::fromPath($img['fullpath'], $img['content_type']);
// embed image // embed image
$imgcid = $this->message->embed($attachment); $imgcid = $this->message->embed($attachment);
// replace cid by the one created by swiftmail in html message // replace cid by the one created by swiftmail in html message
$msg = str_replace("cid:".$img['cid'], $imgcid, $msg); $msg = str_replace("cid:".$img['cid'], $imgcid, $msg);
} }
} }
if ($this->msgishtml) { if ($this->msgishtml) {
$this->message->setBody($msg,'text/html'); $this->message->setBody($msg,'text/html');
// And optionally an alternative body // And optionally an alternative body
//$this->message->addPart('Here is the message itself', 'text/plain'); //$this->message->addPart('Here is the message itself', 'text/plain');
} else { } else {
$this->message->setBody($msg,'text/plain'); $this->message->setBody($msg,'text/plain');
// And optionally an alternative body // And optionally an alternative body
//$this->message->addPart('<q>Here is the message itself</q>', 'text/html'); //$this->message->addPart('<q>Here is the message itself</q>', 'text/html');
} }
if ($this->atleastonefile) if ($this->atleastonefile)
{ {
foreach ($filename_list as $i => $val) foreach ($filename_list as $i => $val)
{ {
//$this->message->attach(Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i])); //$this->message->attach(Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]));
$attachment = Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]); $attachment = Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]);
$this->message->attach($attachment); $this->message->attach($attachment);
} }
} }
if (! empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc)); if (! empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc));
if (! empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc)); if (! empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc));
//if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to); //if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to);
if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from)); if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from));
} }
else else
{ {
// Send mail method not correctly defined // Send mail method not correctly defined
// -------------------------------------- // --------------------------------------
$this->error = 'Bad value for MAIN_MAIL_SENDMODE constant'; $this->error = 'Bad value for sendmode';
} }
} }
@ -471,55 +480,55 @@ class CMailFile
if (empty($conf->global->MAIN_DISABLE_ALL_MAILS)) if (empty($conf->global->MAIN_DISABLE_ALL_MAILS))
{ {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($db); $hookmanager = new HookManager($db);
$hookmanager->initHooks(array( $hookmanager->initHooks(array(
'maildao' 'maildao'
)); ));
$reshook = $hookmanager->executeHooks('doactions', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks $reshook = $hookmanager->executeHooks('doactions', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if (! empty($reshook)) if (! empty($reshook))
{ {
$this->error = "Error in hook maildao doactions " . $reshook; $this->error = "Error in hook maildao doactions " . $reshook;
dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR); dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR);
return $reshook; return $reshook;
} }
// Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL // Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL
if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL=10; if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL=10;
$tmparray1 = explode(',', $this->addr_to); $tmparray1 = explode(',', $this->addr_to);
if (count($tmparray1) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL) if (count($tmparray1) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)
{ {
$this->error = 'Too much recipients in to:'; $this->error = 'Too much recipients in to:';
dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING); dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
return false; return false;
} }
if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL=10; if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL=10;
$tmparray2 = explode(',', $this->addr_cc); $tmparray2 = explode(',', $this->addr_cc);
if (count($tmparray2) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL) if (count($tmparray2) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)
{ {
$this->error = 'Too much recipients in cc:'; $this->error = 'Too much recipients in cc:';
dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING); dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
return false; return false;
} }
if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL=10; if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL=10;
$tmparray3 = explode(',', $this->addr_bcc); $tmparray3 = explode(',', $this->addr_bcc);
if (count($tmparray3) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL) if (count($tmparray3) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)
{ {
$this->error = 'Too much recipients in bcc:'; $this->error = 'Too much recipients in bcc:';
dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING); dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
return false; return false;
} }
if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL=10; if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL=10;
if ((count($tmparray1)+count($tmparray2)+count($tmparray3)) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL) if ((count($tmparray1)+count($tmparray2)+count($tmparray3)) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
{ {
$this->error = 'Too much recipients in to:, cc:, bcc:'; $this->error = 'Too much recipients in to:, cc:, bcc:';
dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING); dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
return false; return false;
} }
// Action according to choosed sending method // Action according to choosed sending method
if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') if ($this->sendmode == 'mail')
{ {
// Use mail php function (default PHP method) // Use mail php function (default PHP method)
// ------------------------------------------ // ------------------------------------------
@ -555,14 +564,14 @@ class CMailFile
// Having this variable not defined may create problems with some other sendmail (option -f required) // Having this variable not defined may create problems with some other sendmail (option -f required)
$additionnalparam .= ($additionnalparam?' ':'').(! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? '-f' . $this->getValidAddress($conf->global->MAIN_MAIL_ERRORS_TO,2) : ($this->addr_from != '' ? '-f' . $this->getValidAddress($this->addr_from,2) : '') ); $additionnalparam .= ($additionnalparam?' ':'').(! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? '-f' . $this->getValidAddress($conf->global->MAIN_MAIL_ERRORS_TO,2) : ($this->addr_from != '' ? '-f' . $this->getValidAddress($this->addr_from,2) : '') );
} }
if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_BA)) // To force usage of -ba option. This option tells sendmail to read From: or Sender: to setup sender if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_BA)) // To force usage of -ba option. This option tells sendmail to read From: or Sender: to setup sender
{ {
$additionnalparam .= ($additionnalparam?' ':'').'-ba'; $additionnalparam .= ($additionnalparam?' ':'').'-ba';
} }
if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_ADDPARAM)) $additionnalparam .= ($additionnalparam?' ':'').'-U '.$additionnalparam; // Use -U to add additionnal params if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_ADDPARAM)) $additionnalparam .= ($additionnalparam?' ':'').'-U '.$additionnalparam; // Use -U to add additionnal params
dol_syslog("CMailFile::sendfile: mail start HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port').", additionnal_parameters=".$additionnalparam, LOG_DEBUG); dol_syslog("CMailFile::sendfile: mail start HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port').", additionnal_parameters=".$additionnalparam, LOG_DEBUG);
$this->message=stripslashes($this->message); $this->message=stripslashes($this->message);
@ -600,7 +609,7 @@ class CMailFile
if (! empty($conf->global->MAIN_MAIL_SMTP_SERVER)) ini_restore('SMTP'); if (! empty($conf->global->MAIN_MAIL_SMTP_SERVER)) ini_restore('SMTP');
if (! empty($conf->global->MAIN_MAIL_SMTP_PORT)) ini_restore('smtp_port'); if (! empty($conf->global->MAIN_MAIL_SMTP_PORT)) ini_restore('smtp_port');
} }
else if ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') else if ($this->sendmode == 'smtps')
{ {
// Use SMTPS library // Use SMTPS library
@ -616,7 +625,7 @@ class CMailFile
// If we use SSL/TLS // If we use SSL/TLS
$server=$conf->global->MAIN_MAIL_SMTP_SERVER; $server=$conf->global->MAIN_MAIL_SMTP_SERVER;
if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $server='ssl://'.$server; if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $server='ssl://'.$server;
$port=$conf->global->MAIN_MAIL_SMTP_PORT; $port=$conf->global->MAIN_MAIL_SMTP_PORT;
$this->smtps->setHost($server); $this->smtps->setHost($server);
$this->smtps->setPort($port); // 25, 465...; $this->smtps->setPort($port); // 25, 465...;
@ -624,13 +633,13 @@ class CMailFile
$loginid=''; $loginpass=''; $loginid=''; $loginpass='';
if (! empty($conf->global->MAIN_MAIL_SMTPS_ID)) if (! empty($conf->global->MAIN_MAIL_SMTPS_ID))
{ {
$loginid = $conf->global->MAIN_MAIL_SMTPS_ID; $loginid = $conf->global->MAIN_MAIL_SMTPS_ID;
$this->smtps->setID($loginid); $this->smtps->setID($loginid);
} }
if (! empty($conf->global->MAIN_MAIL_SMTPS_PW)) if (! empty($conf->global->MAIN_MAIL_SMTPS_PW))
{ {
$loginpass = $conf->global->MAIN_MAIL_SMTPS_PW; $loginpass = $conf->global->MAIN_MAIL_SMTPS_PW;
$this->smtps->setPW($loginpass); $this->smtps->setPW($loginpass);
} }
$res=true; $res=true;
@ -668,63 +677,63 @@ class CMailFile
} }
} }
} }
else if ($conf->global->MAIN_MAIL_SENDMODE == 'swiftmailer') else if ($this->sendmode == 'swiftmailer')
{ {
// Use Swift Mailer library // Use Swift Mailer library
// ------------------------------------------ // ------------------------------------------
require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php'; require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php';
// Forcage parametres // Forcage parametres
if (empty($conf->global->MAIN_MAIL_SMTP_SERVER)) $conf->global->MAIN_MAIL_SMTP_SERVER=ini_get('SMTP'); if (empty($conf->global->MAIN_MAIL_SMTP_SERVER)) $conf->global->MAIN_MAIL_SMTP_SERVER=ini_get('SMTP');
if (empty($conf->global->MAIN_MAIL_SMTP_PORT)) $conf->global->MAIN_MAIL_SMTP_PORT=ini_get('smtp_port'); if (empty($conf->global->MAIN_MAIL_SMTP_PORT)) $conf->global->MAIN_MAIL_SMTP_PORT=ini_get('smtp_port');
// If we use SSL/TLS // If we use SSL/TLS
$server=$conf->global->MAIN_MAIL_SMTP_SERVER; $server=$conf->global->MAIN_MAIL_SMTP_SERVER;
$secure=''; $secure='';
//var_dump(stream_get_transports()); //var_dump(stream_get_transports());
if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $secure='ssl'; if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $secure='ssl';
if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $secure='tls'; if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $secure='tls';
$this->transport = Swift_SmtpTransport::newInstance($server, $conf->global->MAIN_MAIL_SMTP_PORT, $secure); $this->transport = Swift_SmtpTransport::newInstance($server, $conf->global->MAIN_MAIL_SMTP_PORT, $secure);
if (! empty($conf->global->MAIN_MAIL_SMTPS_ID)) $this->transport->setUsername($conf->global->MAIN_MAIL_SMTPS_ID); if (! empty($conf->global->MAIN_MAIL_SMTPS_ID)) $this->transport->setUsername($conf->global->MAIN_MAIL_SMTPS_ID);
if (! empty($conf->global->MAIN_MAIL_SMTPS_PW)) $this->transport->setPassword($conf->global->MAIN_MAIL_SMTPS_PW); if (! empty($conf->global->MAIN_MAIL_SMTPS_PW)) $this->transport->setPassword($conf->global->MAIN_MAIL_SMTPS_PW);
//$smtps->_msgReplyTo = 'reply@web.com'; //$smtps->_msgReplyTo = 'reply@web.com';
// Create the Mailer using your created Transport // Create the Mailer using your created Transport
$this->mailer = Swift_Mailer::newInstance($this->transport); $this->mailer = Swift_Mailer::newInstance($this->transport);
if (! empty($conf->global->MAIN_MAIL_DEBUG)) { if (! empty($conf->global->MAIN_MAIL_DEBUG)) {
// To use the ArrayLogger // To use the ArrayLogger
$this->logger = new Swift_Plugins_Loggers_ArrayLogger(); $this->logger = new Swift_Plugins_Loggers_ArrayLogger();
// Or to use the Echo Logger // Or to use the Echo Logger
//$this->logger = new Swift_Plugins_Loggers_EchoLogger(); //$this->logger = new Swift_Plugins_Loggers_EchoLogger();
$this->mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this->logger)); $this->mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this->logger));
} }
// send mail // send mail
try { try {
$result = $this->mailer->send($this->message); $result = $this->mailer->send($this->message);
} catch (Exception $e) { } catch (Exception $e) {
$this->error = $e->getMessage(); $this->error = $e->getMessage();
} }
if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail(); if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
$res = true; $res = true;
if (! empty($this->error) && ! $result) { if (! empty($this->error) && ! $result) {
dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
$res=false; $res=false;
} else { } else {
$this->error = sprintf ("Sent %d messages\n", $result); $this->error = sprintf ("Sent %d messages\n", $result);
} }
} }
else else
{ {
// Send mail method not correctly defined // Send mail method not correctly defined
// -------------------------------------- // --------------------------------------
return 'Bad value for MAIN_MAIL_SENDMODE constant'; return 'Bad value for sendmode';
} }
} }
@ -792,81 +801,81 @@ class CMailFile
$outputfile=$dolibarr_main_data_root."/dolibarr_mail.log"; $outputfile=$dolibarr_main_data_root."/dolibarr_mail.log";
$fp = fopen($outputfile,"w"); $fp = fopen($outputfile,"w");
if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') if ($this->sendmode == 'mail')
{ {
fputs($fp, $this->headers); fputs($fp, $this->headers);
fputs($fp, $this->eol); // This eol is added by the mail function, so we add it in log fputs($fp, $this->eol); // This eol is added by the mail function, so we add it in log
fputs($fp, $this->message); fputs($fp, $this->message);
} }
elseif ($conf->global->MAIN_MAIL_SENDMODE == 'smtps') elseif ($this->sendmode == 'smtps')
{ {
fputs($fp, $this->smtps->log); // this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on fputs($fp, $this->smtps->log); // this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on
} }
elseif ($conf->global->MAIN_MAIL_SENDMODE == 'swiftmailer') elseif ($this->sendmode == 'swiftmailer')
{ {
fputs($fp, $this->logger->dump()); // this->logger is filled only if MAIN_MAIL_DEBUG was set to on fputs($fp, $this->logger->dump()); // this->logger is filled only if MAIN_MAIL_DEBUG was set to on
} }
fclose($fp); fclose($fp);
if (! empty($conf->global->MAIN_UMASK)) if (! empty($conf->global->MAIN_UMASK))
@chmod($outputfile, octdec($conf->global->MAIN_UMASK)); @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
} }
} }
/** /**
* Correct an uncomplete html string * Correct an uncomplete html string
* *
* @param string $msg String * @param string $msg String
* @return string Completed string * @return string Completed string
*/ */
function checkIfHTML($msg) function checkIfHTML($msg)
{ {
if (!preg_match('/^[\s\t]*<html/i',$msg)) if (!preg_match('/^[\s\t]*<html/i',$msg))
{ {
$out = "<html><head><title></title>"; $out = "<html><head><title></title>";
if (!empty($this->styleCSS)) $out.= $this->styleCSS; if (!empty($this->styleCSS)) $out.= $this->styleCSS;
$out.= "</head><body"; $out.= "</head><body";
if (!empty($this->bodyCSS)) $out.= $this->bodyCSS; if (!empty($this->bodyCSS)) $out.= $this->bodyCSS;
$out.= ">"; $out.= ">";
$out.= $msg; $out.= $msg;
$out.= "</body></html>"; $out.= "</body></html>";
} }
else else
{ {
$out = $msg; $out = $msg;
} }
return $out; return $out;
} }
/** /**
* Build a css style (mode = all) into this->styleCSS and this->bodyCSS * Build a css style (mode = all) into this->styleCSS and this->bodyCSS
* *
* @return css * @return css
*/ */
function buildCSS() function buildCSS()
{ {
if (! empty($this->css)) if (! empty($this->css))
{ {
// Style CSS // Style CSS
$this->styleCSS = '<style type="text/css">'; $this->styleCSS = '<style type="text/css">';
$this->styleCSS.= 'body {'; $this->styleCSS.= 'body {';
if ($this->css['bgcolor']) if ($this->css['bgcolor'])
{ {
$this->styleCSS.= ' background-color: '.$this->css['bgcolor'].';'; $this->styleCSS.= ' background-color: '.$this->css['bgcolor'].';';
$this->bodyCSS.= ' bgcolor="'.$this->css['bgcolor'].'"'; $this->bodyCSS.= ' bgcolor="'.$this->css['bgcolor'].'"';
} }
if ($this->css['bgimage']) if ($this->css['bgimage'])
{ {
// TODO recuperer cid // TODO recuperer cid
$this->styleCSS.= ' background-image: url("cid:'.$this->css['bgimage_cid'].'");'; $this->styleCSS.= ' background-image: url("cid:'.$this->css['bgimage_cid'].'");';
} }
$this->styleCSS.= '}'; $this->styleCSS.= '}';
$this->styleCSS.= '</style>'; $this->styleCSS.= '</style>';
} }
} }
/** /**
@ -993,13 +1002,13 @@ class CMailFile
$strContentAltText = html_entity_decode(strip_tags($strContent)); $strContentAltText = html_entity_decode(strip_tags($strContent));
$strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n")); $strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n"));
// Check if html header already in message, if not complete the message // Check if html header already in message, if not complete the message
$strContent = $this->checkIfHTML($strContent); $strContent = $this->checkIfHTML($strContent);
} }
// Make RFC2045 Compliant, split lines // Make RFC2045 Compliant, split lines
//$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content //$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. $strContent = rtrim(wordwrap($strContent)); // TODO Using this method creates unexpected line break on text/plain content.
if ($this->msgishtml) if ($this->msgishtml)
{ {
@ -1019,8 +1028,8 @@ class CMailFile
$out.= $this->eol; $out.= $this->eol;
$out.= "--" . $this->alternative_boundary . $this->eol; $out.= "--" . $this->alternative_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.$strContentAltText.$this->eol; $out.= $this->eol.$strContentAltText.$this->eol;
$out.= "--" . $this->alternative_boundary . $this->eol; $out.= "--" . $this->alternative_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;
@ -1028,7 +1037,7 @@ class CMailFile
if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part after html part 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; $out.= "--" . $this->alternative_boundary . "--". $this->eol;
} }
} }
else else
@ -1042,11 +1051,11 @@ class CMailFile
// Encode images // Encode images
if ($this->atleastoneimage) if ($this->atleastoneimage)
{ {
$out .= $this->write_images($this->images_encoded); $out .= $this->write_images($this->images_encoded);
// always end related and end alternative after inline images // always end related and end alternative after inline images
$out .= "--" . $this->related_boundary . "--" . $this->eol; $out .= "--" . $this->related_boundary . "--" . $this->eol;
$out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol; $out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol;
$out .= $this->eol; $out .= $this->eol;
} }
return $out; return $out;
@ -1074,10 +1083,12 @@ class CMailFile
if ($encoded >= 0) if ($encoded >= 0)
{ {
if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i]; if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
if (! $mimetype_list[$i]) { $mimetype_list[$i] = "application/octet-stream"; } if (! $mimetype_list[$i]) {
$mimetype_list[$i] = "application/octet-stream";
}
$out.= "--" . $this->mixed_boundary . $this->eol; $out.= "--" . $this->mixed_boundary . $this->eol;
$out.= "Content-Disposition: attachment; filename=\"".$filename_list[$i]."\"".$this->eol; $out.= "Content-Disposition: attachment; filename=\"".$filename_list[$i]."\"".$this->eol;
$out.= "Content-Type: " . $mimetype_list[$i] . "; name=\"".$filename_list[$i]."\"".$this->eol; $out.= "Content-Type: " . $mimetype_list[$i] . "; name=\"".$filename_list[$i]."\"".$this->eol;
$out.= "Content-Transfer-Encoding: base64".$this->eol; $out.= "Content-Transfer-Encoding: base64".$this->eol;
$out.= "Content-Description: File Attachment".$this->eol; $out.= "Content-Description: File Attachment".$this->eol;
@ -1137,25 +1148,25 @@ class CMailFile
*/ */
function check_server_port($host,$port) function check_server_port($host,$port)
{ {
global $conf; global $conf;
$_retVal=0; $_retVal=0;
$timeout=5; // Timeout in seconds $timeout=5; // Timeout in seconds
if (function_exists('fsockopen')) if (function_exists('fsockopen'))
{ {
// If we use SSL/TLS // If we use SSL/TLS
if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $host='ssl://'.$host; if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $host='ssl://'.$host;
// tls smtp start with no encryption // tls smtp start with no encryption
//if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $host='tls://'.$host; //if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $host='tls://'.$host;
dol_syslog("Try socket connection to host=".$host." port=".$port); dol_syslog("Try socket connection to host=".$host." port=".$port);
//See if we can connect to the SMTP server //See if we can connect to the SMTP server
if ($socket = @fsockopen( if ($socket = @fsockopen(
$host, // Host to test, IP or domain. Add ssl:// for SSL/TLS. $host, // Host to test, IP or domain. Add ssl:// for SSL/TLS.
$port, // which Port number to use $port, // which Port number to use
$errno, // actual system level error $errno, // actual system level error
$errstr, // and any text that goes with the error $errstr, // and any text that goes with the error
$timeout $timeout
)) // timeout for reading/writing data over the socket )) // timeout for reading/writing data over the socket
{ {
// Windows still does not have support for this timeout function // Windows still does not have support for this timeout function
@ -1225,7 +1236,7 @@ class CMailFile
foreach ($matches[1] as $full) foreach ($matches[1] as $full)
{ {
if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) // If xxx is 'file=aaa' if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs)) // If xxx is 'file=aaa'
{ {
$img = $regs[1]; $img = $regs[1];
@ -1338,12 +1349,12 @@ class CMailFile
if ($email) if ($email)
{ {
$i++; $i++;
$newemail=''; $newemail='';
if ($format == 4) if ($format == 4)
{ {
$newemail = $name?$name:$email; $newemail = $name?$name:$email;
} }
if ($format == 2) if ($format == 2)
{ {
@ -1365,8 +1376,8 @@ class CMailFile
// Stop if we have too much records // Stop if we have too much records
if ($maxnumberofemail && $i >= $maxnumberofemail) if ($maxnumberofemail && $i >= $maxnumberofemail)
{ {
if (count($arrayaddress) > $maxnumberofemail) $ret.='...'; if (count($arrayaddress) > $maxnumberofemail) $ret.='...';
break; break;
} }
} }
} }
@ -1374,38 +1385,38 @@ class CMailFile
return $ret; return $ret;
} }
/** /**
* Return a formatted array of address string for SMTP protocol * Return a formatted array of address string for SMTP protocol
* *
* @param string $address Example: 'John Doe <john@doe.com>, Alan Smith <alan@smith.com>' or 'john@doe.com, alan@smith.com' * @param string $address Example: 'John Doe <john@doe.com>, Alan Smith <alan@smith.com>' or 'john@doe.com, alan@smith.com'
* @return array array of email => name * @return array array of email => name
*/ */
function getArrayAddress($address) function getArrayAddress($address)
{ {
global $conf; global $conf;
$ret=array(); $ret=array();
$arrayaddress=explode(',',$address); $arrayaddress=explode(',',$address);
// Boucle sur chaque composant de l'adresse // Boucle sur chaque composant de l'adresse
foreach($arrayaddress as $val) foreach($arrayaddress as $val)
{ {
if (preg_match('/^(.*)<(.*)>$/i',trim($val),$regs)) if (preg_match('/^(.*)<(.*)>$/i',trim($val),$regs))
{ {
$name = trim($regs[1]); $name = trim($regs[1]);
$email = trim($regs[2]); $email = trim($regs[2]);
} }
else else
{ {
$name = null; $name = null;
$email = trim($val); $email = trim($val);
} }
$ret[$email]=empty($conf->global->MAIN_MAIL_NO_FULL_EMAIL)?$name:null; $ret[$email]=empty($conf->global->MAIN_MAIL_NO_FULL_EMAIL)?$name:null;
} }
return $ret; return $ret;
} }
} }