diff --git a/ChangeLog b/ChangeLog index 40ee2daf181..e359939ecb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -158,7 +158,8 @@ The following changes may create regressions for some external modules, but were * The signature of API get for intervention has been modified to match other get api on other objects. * The directory /build has been moved into /dev/build. * The API to create a website account /idthirdparty/accounts/site is now POST (instead of PUT) and to update is PUT (instead of PATCH). - +* Debug v22 - Invert option TICKET_DO_NOT_INCLUDE_LINK_TO_CUSTOMER (that add link to backoffice interface link when it should remain private) + into TICKET_INCLUDE_LINK_TO_PUBLIC_INTERFACE_IN_MESSAGE. It also avoid often emails marked as SPAM due to suspicious link. ***** ChangeLog for 21.0.1 compared to 21.0.0 ***** diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 1ebce1304cd..0112dad48b1 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -198,7 +198,7 @@ if ($action == 'updateMask') { include_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; $notification_email = GETPOST('TICKET_NOTIFICATION_EMAIL_FROM', 'alpha'); - $notification_email_description = "Sender of ticket replies sent from Dolibarr"; + $notification_email_description = "Email of user allowed to send ticket replies from Dolibarr"; if (!empty($notification_email)) { $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_FROM', $notification_email, 'chaine', 0, $notification_email_description, $conf->entity); } else { // If an empty e-mail address is providen, use the global "FROM" since an empty field will cause other issues @@ -208,6 +208,17 @@ if ($action == 'updateMask') { $error++; } + $notification_email_replyto = GETPOST('TICKET_NOTIFICATION_EMAIL_REPLYTO', 'alpha'); + $notification_email_replyto_description = "Email that must appears as the sender of ticket replies sent from Dolibarr"; + if (!empty($notification_email)) { + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_REPLYTO', $notification_email_replyto, 'chaine', 0, $notification_email_replyto_description, $conf->entity); + } else { + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_REPLYTO', getDolGlobalString('MAIN_MAIL_EMAIL_FROM'), 'chaine', 0, $notification_email_replyto_description, $conf->entity); + } + if (!($res > 0)) { + $error++; + } + // altairis : differentiate notification email FROM and TO $notification_email_to = GETPOST('TICKET_NOTIFICATION_EMAIL_TO', 'alpha'); $notification_email_to_description = "Notified e-mail for ticket replies sent from Dolibarr"; @@ -645,7 +656,7 @@ if (!getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) { print "\n"; } -// Email to send notifications +// Email of sender allowed to send technical notifications print ''; print ''; print img_picto('', 'email', 'class="pictofixedwidth"'); @@ -655,6 +666,16 @@ print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationFro print ''; print ''; +// Email that must appears as the sender of email notifications +print ''; +print ''; +print img_picto('', 'email', 'class="pictofixedwidth"'); +print ''; +print ''; +print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationReplyToHelp"), 1, 'help'); +print ''; +print ''; + print ''; print ''; diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 83932c4e6ca..baaa3e1ad95 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -145,7 +145,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO $result = $object->fetch($id); if (method_exists($object, "fetch_thirdparty") && !in_array($object->element, array('member', 'user', 'expensereport', 'societe', 'contact'))) { - $resultthirdparty = $object->fetch_thirdparty(); + $object->fetch_thirdparty(); $thirdparty = $object->thirdparty; if (is_object($thirdparty)) { $sendtosocid = $thirdparty->id; diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index af1f947b6fc..4c5ababb764 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -205,26 +205,26 @@ class CMailFile /** * CMailFile * - * @param string $subject Topic/Subject of mail - * @param string $to Recipients emails (RFC 2822: "Name firstname [, ...]" or "email[, ...]" or "[, ...]"). Note: the keyword '__SUPERVISOREMAIL__' is not allowed here and must be replaced by caller. - * @param string $from Sender email (RFC 2822: "Name firstname [, ...]" or "email[, ...]" or "[, ...]") - * @param string $msg Message - * @param ?string[] $filename_list List of files to attach (full path of filename on file system) - * @param ?string[] $mimetype_list List of MIME type of attached files - * @param ?string[] $mimefilename_list List of attached file name in message - * @param string $addr_cc Email cc (Example: 'abc@def.com, ghk@lmn.com') - * @param string $addr_bcc Email bcc (Note: This is autocompleted with MAIN_MAIL_AUTOCOPY_TO if defined) - * @param int<0,1> $deliveryreceipt Ask a delivery receipt - * @param int<-1,1> $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown make autodetection (with fast mode, not reliable) - * @param string $errors_to Email for errors-to - * @param string|array $css Css option (should be array, legacy: empty string if none) - * @param string $trackid Tracking string (contains type and id of related element) - * @param string $moreinheader More in header. $moreinheader must contains the "\r\n" at end of each line - * @param string $sendcontext 'standard', 'emailing', 'ticket', 'password', ... (used to define which sending mode and parameters to use) - * @param string $replyto Reply-to email (will be set to the same value than From by default if not provided) - * @param string $upload_dir_tmp Temporary directory (used to convert images embedded as img src=data:image) - * @param string $in_reply_to Message-ID of the message we reply to - * @param string $references String with list of Message-ID of the thread ('<123> <456> ...') + * @param string $subject Topic/Subject of mail + * @param string $to Recipients emails (RFC 2822: "Name firstname [, ...]" or "email[, ...]" or "[, ...]"). Note: the keyword '__SUPERVISOREMAIL__' is not allowed here and must be replaced by caller. + * @param string $from Sender email (RFC 2822: "Name firstname [, ...]" or "email[, ...]" or "[, ...]") + * @param string $msg Message + * @param ?string[] $filename_list List of files to attach (full path of filename on file system) + * @param ?string[] $mimetype_list List of MIME type of attached files + * @param ?string[] $mimefilename_list List of attached file name in message + * @param string $addr_cc Email cc (Example: 'abc@def.com, ghk@lmn.com') + * @param string $addr_bcc Email bcc (Note: This is autocompleted with MAIN_MAIL_AUTOCOPY_TO if defined) + * @param int<0,1> $deliveryreceipt Ask a delivery receipt + * @param int<-1,1> $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown make autodetection (with fast mode, not reliable) + * @param string $errors_to Email for errors-to + * @param string|array $css Css option (should be array, legacy: empty string if none) + * @param string $trackid Tracking string (contains type and id of related element) + * @param string $moreinheader More in header. $moreinheader must contains the "\r\n" at end of each line + * @param string $sendcontext 'standard', 'emailing', 'ticket', 'password', ... (used to define which sending mode and parameters to use) + * @param string $replyto Reply-to email (will be set to the same value than From by default if not provided) + * @param string $upload_dir_tmp Temporary directory (used to convert images embedded as img src=data:image) + * @param string $in_reply_to Message-ID of the message we reply to + * @param string $references String with list of Message-ID of the thread ('<123> <456> ...') */ public 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', $replyto = '', $upload_dir_tmp = '', $in_reply_to = '', $references = '') { diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index c837f139d1d..4ae6257903b 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -1685,10 +1685,19 @@ class FormTicket } */ - // From + // From (and Reply-To if defined) $from = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_FROM'); - print ''.$langs->trans("MailFrom").''; - print ''.img_picto('', 'email', 'class="pictofixedwidth"').$from.''; + $replyto = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_REPLYTO'); + print ''.$langs->trans("MailFrom"); + if ($replyto) { + print ' ('.$langs->trans("MailReply").')'; + } + print ''; + print ''.img_picto('', 'email', 'class="pictofixedwidth"').$from; + if ($replyto) { + print ' ('.$replyto.')'; + } + print ''; // Recipients / adressed-to print ''.$langs->trans('MailRecipients'); diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index 9f7f0dc4f8f..ea7be84fbc2 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -72,8 +72,10 @@ TicketPublicAccess=A public interface requiring no identification is available a TicketSetupDictionaries=The type of ticket, severity and analytic codes are configurable from dictionaries TicketParamModule=Module variable setup TicketParamMail=Email setup -TicketEmailNotificationFrom=Sender e-mail for notification on tickets (creation of ticket or update messages) -TicketEmailNotificationFromHelp=Sender e-mail to use to send the notification emails for tickets creation or message addition. For example noreply@example.com +TicketEmailNotificationFrom=E-mail of sender allowed to send technical notification about tickets (creation of ticket or update messages) +TicketEmailNotificationFromHelp=Sender e-mail to use as the From to send the notification emails for tickets creation or message addition. For example: noreply@example.com or robot@example.com +TicketEmailNotificationReplyTo=E-mail that must appears to recipient as the sender of the notification (creation of ticket or update messages) +TicketEmailNotificationReplyToHelp=Sender e-mail to use as the Reply-To to send the notification emails for tickets creation or message addition. If defined, this is the email that the recipient will reply to instead of the From. For example: support@example.com TicketEmailNotificationTo=Notify ticket creation to this e-mail address TicketEmailNotificationToHelp=If present, this e-mail address will be notified of a ticket creation (in addition to any other default recipients) TicketNewEmailBodyLabel=Text message sent after creating a ticket diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index eea1abdabe6..368c475d9c7 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2902,9 +2902,11 @@ class Ticket extends CommonObject $from = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_FROM'); + $replyto = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_REPLYTO'); + // don't try to send email if no recipient if (!empty($sendto)) { - $this->sendTicketMessageByEmail($subject, $message, 0, $sendto, $listofpaths, $listofmimes, $listofnames, $sendtocc, $from); + $this->sendTicketMessageByEmail($subject, $message, 0, $sendto, $listofpaths, $listofmimes, $listofnames, $sendtocc, $from, $replyto); } } @@ -3075,9 +3077,10 @@ class Ticket extends CommonObject * @param string[] $mimefilename_list List of attached file name in message * @param array $array_receiver_cc Array of receiver in CC. Example array('john@doe.com') * @param string $from Email from + * @param string $replyto Reply to * @return boolean True if mail sent to at least one receiver, false otherwise */ - public function sendTicketMessageByEmail($subject, $message, $send_internal_cc = 0, $array_receiver = array(), $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $array_receiver_cc = array(), $from = '') + public function sendTicketMessageByEmail($subject, $message, $send_internal_cc = 0, $array_receiver = array(), $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $array_receiver_cc = array(), $from = '', $replyto = '') { global $conf, $langs, $user; @@ -3117,34 +3120,34 @@ class Ticket extends CommonObject if (is_array($array_receiver) && count($array_receiver) > 0) { //foreach ($array_receiver as $key => $receiver) { - $deliveryreceipt = 0; - $filepath = $filename_list; - $filename = $mimefilename_list; - $mimetype = $mimetype_list; + $deliveryreceipt = 0; + $filepath = $filename_list; + $filename = $mimefilename_list; + $mimetype = $mimetype_list; - // Send email + // Send email - $old_MAIN_MAIL_AUTOCOPY_TO = getDolGlobalString('MAIN_MAIL_AUTOCOPY_TO'); + $old_MAIN_MAIL_AUTOCOPY_TO = getDolGlobalString('MAIN_MAIL_AUTOCOPY_TO'); if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; } - $upload_dir_tmp = $conf->user->dir_output."/".$user->id.'/temp'; + $upload_dir_tmp = $conf->user->dir_output."/".$user->id.'/temp'; - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $trackid = "tic".$this->id; + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $trackid = "tic".$this->id; - $moreinheader = 'X-Dolibarr-Info: sendTicketMessageByEmail'."\r\n"; + $moreinheader = 'X-Dolibarr-Info: sendTicketMessageByEmail'."\r\n"; if (!empty($this->email_msgid)) { // We must also add 1 entry In-Reply-To: <$this->email_msgid> with Message-ID we respond from (See RFC5322). $moreinheader .= 'In-Reply-To: <'.$this->email_msgid.'>'."\r\n"; // TODO We should now be able to give the in_reply_to as a dedicated parameter of new CMailFile() instead of into $moreinheader. } - // We should add here also a header 'References:' - // According to RFC5322, we should add here all the References fields of the initial message concatenated with - // the Message-ID of the message we respond from (but each ID must be once). - $references = ''; + // We should add here also a header 'References:' + // According to RFC5322, we should add here all the References fields of the initial message concatenated with + // the Message-ID of the message we respond from (but each ID must be once). + $references = ''; if (!empty($this->origin_references)) { // $this->origin_references should be '<'.$this->origin_references.'>' $references .= (empty($references) ? '' : ' ').$this->origin_references; } @@ -3156,11 +3159,15 @@ class Ticket extends CommonObject // TODO We should now be able to give the references as a dedicated parameter of new CMailFile() instead of into $moreinheader. } - $receiverstring = ''; + $receiverstring = ''; foreach ($array_receiver as $key => $receiver) { $receiverstring .= ($receiverstring ? ',' : '').$receiver; } - $mailfile = new CMailFile($subject, $receiverstring, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', $trackid, $moreinheader, 'ticket', '', $upload_dir_tmp); + + $sendcontext = 'ticket'; + + // Send email + $mailfile = new CMailFile($subject, $receiverstring, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', $trackid, $moreinheader, $sendcontext, $replyto, $upload_dir_tmp); if ($mailfile->error) {