dolibarr  20.0.0-alpha
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2005-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2016 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2021 WaĆ«l Almoman <info@almoman.com>
6  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 if (!defined('NOSTYLECHECK')) {
29  define('NOSTYLECHECK', '1');
30 }
31 
32 // Load Dolibarr environment
33 require '../../main.inc.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/emailing.lib.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing.class.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
42 
43 // Load translation files required by the page
44 $langs->loadLangs(array("mails", "admin"));
45 
46 $id = (GETPOSTINT('mailid') ? GETPOSTINT('mailid') : GETPOSTINT('id'));
47 
48 $action = GETPOST('action', 'aZ09');
49 $confirm = GETPOST('confirm', 'alpha');
50 $cancel = GETPOST('cancel', 'aZ09');
51 $urlfrom = GETPOST('urlfrom');
52 $backtopageforcancel = GETPOST('backtopageforcancel');
53 
54 // Initialize technical objects
55 $object = new Mailing($db);
56 $extrafields = new ExtraFields($db);
57 $hookmanager->initHooks(array('mailingcard', 'globalcard'));
58 
59 // Fetch optionals attributes and labels
60 $extrafields->fetch_name_optionals_label($object->table_element);
61 
62 // Load object
63 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
64 
65 // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions)
66 $object->substitutionarray = FormMail::getAvailableSubstitKey('emailing');
67 
68 
69 // Set $object->substitutionarrayfortest
70 $signature = ((!empty($user->signature) && !getDolGlobalString('MAIN_MAIL_DO_NOT_USE_SIGN')) ? $user->signature : '');
71 
72 $targetobject = null; // Not defined with mass emailing
73 
74 $parameters = array('mode' => 'emailing');
75 $substitutionarray = FormMail::getAvailableSubstitKey('emailing', $targetobject);
76 
77 $object->substitutionarrayfortest = $substitutionarray;
78 
79 // List of sending methods
80 $listofmethods = array();
81 //$listofmethods['default'] = $langs->trans('DefaultOutgoingEmailSetup');
82 $listofmethods['mail'] = 'PHP mail function';
83 //$listofmethods['simplemail']='Simplemail class';
84 $listofmethods['smtps'] = 'SMTP/SMTPS socket library';
85 if (version_compare(phpversion(), '7.0', '>=')) {
86  $listofmethods['swiftmailer'] = 'Swift Mailer socket library';
87 }
88 
89 // Security check
90 if (!$user->hasRight('mailing', 'lire') || (!getDolGlobalString('EXTERNAL_USERS_ARE_AUTHORIZED') && $user->socid > 0)) {
92 }
93 if (empty($action) && empty($object->id)) {
94  accessforbidden('Object not found');
95 }
96 
97 $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
98 
99 //$permissiontoread = $user->hasRight('maling', 'read');
100 $permissiontocreate = $user->hasRight('mailing', 'creer');
101 $permissiontovalidatesend = $user->hasRight('mailing', 'valider');
102 $permissiontodelete = $user->hasRight('mailing', 'supprimer');
103 
104 
105 /*
106  * Actions
107  */
108 
109 $parameters = array();
110 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
111 if ($reshook < 0) {
112  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
113 }
114 
115 if (empty($reshook)) {
116  $error = 0;
117 
118  $backurlforlist = DOL_URL_ROOT.'/comm/mailing/list.php';
119 
120  if (empty($backtopage) || ($cancel && empty($id))) {
121  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
122  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
123  $backtopage = $backurlforlist;
124  } else {
125  $backtopage = DOL_URL_ROOT.'/comm/mailing/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
126  }
127  }
128  }
129 
130  if ($cancel) {
131  /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/
132  if (!empty($backtopageforcancel)) {
133  header("Location: ".$backtopageforcancel);
134  exit;
135  } elseif (!empty($backtopage)) {
136  header("Location: ".$backtopage);
137  exit;
138  }
139  $action = '';
140  }
141 
142  // Action clone object
143  if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontocreate) {
144  if (!GETPOST("clone_content", 'alpha') && !GETPOST("clone_receivers", 'alpha')) {
145  setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
146  } else {
147  $result = $object->createFromClone($user, $object->id, GETPOST("clone_content", 'alpha'), GETPOST("clone_receivers", 'alpha'));
148  if ($result > 0) {
149  header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
150  exit;
151  } else {
152  setEventMessages($object->error, $object->errors, 'errors');
153  }
154  }
155  $action = '';
156  }
157 
158  // Action send emailing for everybody
159  if ($action == 'sendallconfirmed' && $confirm == 'yes' && $permissiontovalidatesend) {
160  if (!getDolGlobalString('MAILING_LIMIT_SENDBYWEB')) {
161  // As security measure, we don't allow send from the GUI
162  setEventMessages($langs->trans("MailingNeedCommand"), null, 'warnings');
163  setEventMessages('<textarea cols="70" rows="'.ROWS_2.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>', null, 'warnings');
164  setEventMessages($langs->trans("MailingNeedCommand2"), null, 'warnings');
165  $action = '';
166  } elseif (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') < 0) {
167  setEventMessages($langs->trans("NotEnoughPermissions"), null, 'warnings');
168  $action = '';
169  } else {
170  if ($object->status == 0) {
171  dol_print_error(null, 'ErrorMailIsNotValidated');
172  exit;
173  }
174 
175  $id = $object->id;
176  $subject = $object->sujet;
177  $message = $object->body;
178  $from = $object->email_from;
179  $replyto = $object->email_replyto;
180  $errorsto = $object->email_errorsto;
181  // Is the message in html
182  $msgishtml = -1; // Unknown by default
183  if (preg_match('/[\s\t]*<html>/i', $message)) {
184  $msgishtml = 1;
185  }
186 
187  // Warning, we must not use begin-commit transaction here
188  // because we want to save update for each mail sent.
189 
190  $nbok = 0;
191  $nbko = 0;
192 
193  // We choose mails not already sent for this mailing (statut=0)
194  // or sent in error (statut=-1)
195  $sql = "SELECT mc.rowid, mc.fk_mailing, mc.lastname, mc.firstname, mc.email, mc.other, mc.source_url, mc.source_id, mc.source_type, mc.tag";
196  $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
197  $sql .= " WHERE mc.statut < 1 AND mc.fk_mailing = ".((int) $object->id);
198  $sql .= " ORDER BY mc.statut DESC"; // first status 0, then status -1
199 
200  dol_syslog("card.php: select targets", LOG_DEBUG);
201  $resql = $db->query($sql);
202  if ($resql) {
203  $num = $db->num_rows($resql); // Number of possible recipients
204 
205  if ($num) {
206  dol_syslog("comm/mailing/card.php: nb of targets = ".$num, LOG_DEBUG);
207 
208  $now = dol_now();
209 
210  // Positioning date of start sending
211  $sql = "UPDATE ".MAIN_DB_PREFIX."mailing SET date_envoi='".$db->idate($now)."' WHERE rowid=".((int) $object->id);
212  $resql2 = $db->query($sql);
213  if (!$resql2) {
214  dol_print_error($db);
215  }
216 
217  $thirdpartystatic = new Societe($db);
218  // Loop on each email and send it
219  $iforemailloop = 0;
220 
221  while ($iforemailloop < $num && $iforemailloop < $conf->global->MAILING_LIMIT_SENDBYWEB) {
222  // Here code is common with same loop ino mailing-send.php
223  $res = 1;
224  $now = dol_now();
225 
226  $obj = $db->fetch_object($resql);
227 
228  // sendto en RFC2822
229  $sendto = str_replace(',', ' ', dolGetFirstLastname($obj->firstname, $obj->lastname))." <".$obj->email.">";
230 
231  // Make substitutions on topic and body. From (AA=YY;BB=CC;...) we keep YY, CC, ...
232  $other = explode(';', $obj->other);
233  $tmpfield = explode('=', $other[0], 2);
234  $other1 = (isset($tmpfield[1]) ? $tmpfield[1] : $tmpfield[0]);
235  $tmpfield = explode('=', $other[1], 2);
236  $other2 = (isset($tmpfield[1]) ? $tmpfield[1] : $tmpfield[0]);
237  $tmpfield = explode('=', $other[2], 2);
238  $other3 = (isset($tmpfield[1]) ? $tmpfield[1] : $tmpfield[0]);
239  $tmpfield = explode('=', $other[3], 2);
240  $other4 = (isset($tmpfield[1]) ? $tmpfield[1] : $tmpfield[0]);
241  $tmpfield = explode('=', $other[4], 2);
242  $other5 = (isset($tmpfield[1]) ? $tmpfield[1] : $tmpfield[0]);
243 
244  $signature = ((!empty($user->signature) && !getDolGlobalString('MAIN_MAIL_DO_NOT_USE_SIGN')) ? $user->signature : '');
245 
246  $parameters = array('mode' => 'emailing');
247  $substitutionarray = getCommonSubstitutionArray($langs, 0, array('object', 'objectamount'), $targetobject); // Note: On mass emailing, this is null because be don't know object
248 
249  // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions)
250  $substitutionarray['__ID__'] = $obj->source_id;
251  if ($obj->source_type == "thirdparty") {
252  $result = $thirdpartystatic->fetch($obj->source_id);
253 
254  if ($result > 0) {
255  $substitutionarray['__THIRDPARTY_CUSTOMER_CODE__'] = $thirdpartystatic->code_client;
256  } else {
257  $substitutionarray['__THIRDPARTY_CUSTOMER_CODE__'] = '';
258  }
259  }
260  $substitutionarray['__EMAIL__'] = $obj->email;
261  $substitutionarray['__LASTNAME__'] = $obj->lastname;
262  $substitutionarray['__FIRSTNAME__'] = $obj->firstname;
263  $substitutionarray['__MAILTOEMAIL__'] = '<a href="mailto:'.$obj->email.'">'.$obj->email.'</a>';
264  $substitutionarray['__OTHER1__'] = $other1;
265  $substitutionarray['__OTHER2__'] = $other2;
266  $substitutionarray['__OTHER3__'] = $other3;
267  $substitutionarray['__OTHER4__'] = $other4;
268  $substitutionarray['__OTHER5__'] = $other5;
269  $substitutionarray['__USER_SIGNATURE__'] = $signature; // Signature is empty when ran from command line or taken from user in parameter)
270  $substitutionarray['__SENDEREMAIL_SIGNATURE__'] = $signature; // Signature is empty when ran from command line or taken from user in parameter)
271  $substitutionarray['__CHECK_READ__'] = '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.urlencode($obj->tag).'&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY').'-'.$obj->tag.'-'.$obj->email.'-'.$obj->rowid, "md5").'&email='.urlencode($obj->email).'&mtid='.((int) $obj->rowid).'" width="1" height="1" style="width:1px;height:1px" border="0"/>';
272  $substitutionarray['__UNSUBSCRIBE__'] = '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.urlencode($obj->tag).'&unsuscrib=1&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY').'-'.$obj->tag.'-'.$obj->email.'-'.$obj->rowid, "md5").'&email='.urlencode($obj->email).'&mtid='.((int) $obj->rowid).'" target="_blank" rel="noopener noreferrer">'.$langs->trans("MailUnsubcribe").'</a>';
273  $substitutionarray['__UNSUBSCRIBE_URL__'] = DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.urlencode($obj->tag).'&unsuscrib=1&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY').'-'.$obj->tag.'-'.$obj->email.'-'.$obj->rowid, "md5").'&email='.urlencode($obj->email).'&mtid='.((int) $obj->rowid);
274 
275  $onlinepaymentenabled = 0;
276  if (isModEnabled('paypal')) {
277  $onlinepaymentenabled++;
278  }
279  if (isModEnabled('paybox')) {
280  $onlinepaymentenabled++;
281  }
282  if (isModEnabled('stripe')) {
283  $onlinepaymentenabled++;
284  }
285  if ($onlinepaymentenabled && getDolGlobalString('PAYMENT_SECURITY_TOKEN')) {
286  require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
287  $substitutionarray['__ONLINEPAYMENTLINK_MEMBER__'] = getHtmlOnlinePaymentLink('member', $obj->source_id);
288  $substitutionarray['__ONLINEPAYMENTLINK_DONATION__'] = getHtmlOnlinePaymentLink('donation', $obj->source_id);
289  $substitutionarray['__ONLINEPAYMENTLINK_ORDER__'] = getHtmlOnlinePaymentLink('order', $obj->source_id);
290  $substitutionarray['__ONLINEPAYMENTLINK_INVOICE__'] = getHtmlOnlinePaymentLink('invoice', $obj->source_id);
291  $substitutionarray['__ONLINEPAYMENTLINK_CONTRACTLINE__'] = getHtmlOnlinePaymentLink('contractline', $obj->source_id);
292 
293  $substitutionarray['__SECUREKEYPAYMENT__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN'), 2);
294  if (!getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')) {
295  $substitutionarray['__SECUREKEYPAYMENT_MEMBER__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN'), 2);
296  $substitutionarray['__SECUREKEYPAYMENT_DONATION__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN'), 2);
297  $substitutionarray['__SECUREKEYPAYMENT_ORDER__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN'), 2);
298  $substitutionarray['__SECUREKEYPAYMENT_INVOICE__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN'), 2);
299  $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN'), 2);
300  } else {
301  $substitutionarray['__SECUREKEYPAYMENT_MEMBER__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . 'member'.$obj->source_id, 2);
302  $substitutionarray['__SECUREKEYPAYMENT_DONATION__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . 'donation'.$obj->source_id, 2);
303  $substitutionarray['__SECUREKEYPAYMENT_ORDER__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . 'order'.$obj->source_id, 2);
304  $substitutionarray['__SECUREKEYPAYMENT_INVOICE__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . 'invoice'.$obj->source_id, 2);
305  $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = dol_hash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . 'contractline'.$obj->source_id, 2);
306  }
307  }
308  if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
309  $substitutionarray['__PUBLICLINK_NEWMEMBERFORM__'] = '<a target="_blank" rel="noopener noreferrer" href="'.DOL_MAIN_URL_ROOT.'/public/members/new.php'.((isModEnabled('multicompany')) ? '?entity='.$conf->entity : '').'">'.$langs->trans('BlankSubscriptionForm'). '</a>';
310  }
311  /* For backward compatibility, deprecated */
312  if (isModEnabled('paypal') && getDolGlobalString('PAYPAL_SECURITY_TOKEN')) {
313  $substitutionarray['__SECUREKEYPAYPAL__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN'), 2);
314 
315  if (!getDolGlobalString('PAYPAL_SECURITY_TOKEN_UNIQUE')) {
316  $substitutionarray['__SECUREKEYPAYPAL_MEMBER__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN'), 2);
317  } else {
318  $substitutionarray['__SECUREKEYPAYPAL_MEMBER__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN') . 'membersubscription'.$obj->source_id, 2);
319  }
320 
321  if (!getDolGlobalString('PAYPAL_SECURITY_TOKEN_UNIQUE')) {
322  $substitutionarray['__SECUREKEYPAYPAL_ORDER__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN'), 2);
323  } else {
324  $substitutionarray['__SECUREKEYPAYPAL_ORDER__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN') . 'order'.$obj->source_id, 2);
325  }
326 
327  if (!getDolGlobalString('PAYPAL_SECURITY_TOKEN_UNIQUE')) {
328  $substitutionarray['__SECUREKEYPAYPAL_INVOICE__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN'), 2);
329  } else {
330  $substitutionarray['__SECUREKEYPAYPAL_INVOICE__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN') . 'invoice'.$obj->source_id, 2);
331  }
332 
333  if (!getDolGlobalString('PAYPAL_SECURITY_TOKEN_UNIQUE')) {
334  $substitutionarray['__SECUREKEYPAYPAL_CONTRACTLINE__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN'), 2);
335  } else {
336  $substitutionarray['__SECUREKEYPAYPAL_CONTRACTLINE__'] = dol_hash(getDolGlobalString('PAYPAL_SECURITY_TOKEN') . 'contractline'.$obj->source_id, 2);
337  }
338  }
339  //$substitutionisok=true;
340 
341  complete_substitutions_array($substitutionarray, $langs);
342  $newsubject = make_substitutions($subject, $substitutionarray);
343  $newmessage = make_substitutions($message, $substitutionarray, null, 0);
344 
345  $moreinheader = '';
346  if (preg_match('/__UNSUBSCRIBE_(_|URL_)/', $message)) {
347  $moreinheader = "List-Unsubscribe: <__UNSUBSCRIBE_URL__>\n";
348  $moreinheader = make_substitutions($moreinheader, $substitutionarray);
349  }
350 
351  $arr_file = array();
352  $arr_mime = array();
353  $arr_name = array();
354  $arr_css = array();
355 
356  $listofpaths = dol_dir_list($upload_dir, 'all', 0, '', '', 'name', SORT_ASC, 0);
357  if (count($listofpaths)) {
358  foreach ($listofpaths as $key => $val) {
359  $arr_file[] = $listofpaths[$key]['fullname'];
360  $arr_mime[] = dol_mimetype($listofpaths[$key]['name']);
361  $arr_name[] = $listofpaths[$key]['name'];
362  }
363  }
364 
365  // Mail making
366  $trackid = 'emailing-'.$obj->fk_mailing.'-'.$obj->rowid;
367  $upload_dir_tmp = $upload_dir;
368  $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css, $trackid, $moreinheader, 'emailing', $replyto, $upload_dir_tmp);
369 
370  if ($mail->error) {
371  $res = 0;
372  }
373  /*if (! $substitutionisok)
374  {
375  $mail->error='Some substitution failed';
376  $res=0;
377  }*/
378 
379  // Send mail
380  if ($res) {
381  $res = $mail->sendfile();
382  }
383 
384  if ($res) {
385  // Mail successful
386  $nbok++;
387 
388  dol_syslog("comm/mailing/card.php: ok for #".$iforemailloop.($mail->error ? ' - '.$mail->error : ''), LOG_DEBUG);
389 
390  $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
391  $sql .= " SET statut=1, date_envoi = '".$db->idate($now)."' WHERE rowid=".((int) $obj->rowid);
392  $resql2 = $db->query($sql);
393  if (!$resql2) {
394  dol_print_error($db);
395  } else {
396  //if check read is use then update prospect contact status
397  if (strpos($message, '__CHECK_READ__') !== false) {
398  //Update status communication of thirdparty prospect
399  $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid=".((int) $obj->rowid).")";
400  dol_syslog("card.php: set prospect thirdparty status", LOG_DEBUG);
401  $resql2 = $db->query($sql);
402  if (!$resql2) {
403  dol_print_error($db);
404  }
405 
406  //Update status communication of contact prospect
407  $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=2 WHERE rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.rowid=".((int) $obj->rowid)." AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)";
408  dol_syslog("card.php: set prospect contact status", LOG_DEBUG);
409 
410  $resql2 = $db->query($sql);
411  if (!$resql2) {
412  dol_print_error($db);
413  }
414  }
415  }
416 
417  if (getDolGlobalString('MAILING_DELAY')) {
418  dol_syslog("Wait a delay of MAILING_DELAY=".((float) $conf->global->MAILING_DELAY));
419  usleep((int) ((float) $conf->global->MAILING_DELAY * 1000000));
420  }
421 
422  //test if CHECK READ change statut prospect contact
423  } else {
424  // Mail failed
425  $nbko++;
426 
427  dol_syslog("comm/mailing/card.php: error for #".$iforemailloop.($mail->error ? ' - '.$mail->error : ''), LOG_WARNING);
428 
429  $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
430  $sql .= " SET statut=-1, error_text='".$db->escape($mail->error)."', date_envoi='".$db->idate($now)."' WHERE rowid=".((int) $obj->rowid);
431  $resql2 = $db->query($sql);
432  if (!$resql2) {
433  dol_print_error($db);
434  }
435  }
436 
437  $iforemailloop++;
438  }
439  } else {
440  setEventMessages($langs->transnoentitiesnoconv("NoMoreRecipientToSendTo"), null, 'mesgs');
441  }
442 
443  // Loop finished, set global statut of mail
444  if ($nbko > 0) {
445  $statut = 2; // Status 'sent partially' (because at least one error)
446  setEventMessages($langs->transnoentitiesnoconv("EMailSentToNRecipients", $nbok), null, 'mesgs');
447  } else {
448  if ($nbok >= $num) {
449  $statut = 3; // Send to everybody
450  } else {
451  $statut = 2; // Status 'sent partially' (because not send to everybody)
452  }
453  setEventMessages($langs->transnoentitiesnoconv("EMailSentToNRecipients", $nbok), null, 'mesgs');
454  }
455 
456  $sql = "UPDATE ".MAIN_DB_PREFIX."mailing SET statut=".((int) $statut)." WHERE rowid = ".((int) $object->id);
457  dol_syslog("comm/mailing/card.php: update global status", LOG_DEBUG);
458  $resql2 = $db->query($sql);
459  if (!$resql2) {
460  dol_print_error($db);
461  }
462  } else {
463  dol_syslog($db->error());
464  dol_print_error($db);
465  }
466  $object->fetch($id);
467  $action = '';
468  }
469  }
470 
471  // Action send test emailing
472  if ($action == 'send' && ! $cancel && $permissiontovalidatesend) {
473  $error = 0;
474 
475  $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
476 
477  $object->sendto = GETPOST("sendto", 'alphawithlgt');
478  if (!$object->sendto) {
479  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailTo")), null, 'errors');
480  $error++;
481  }
482 
483  if (!$error) {
484  // Is the message in html
485  $msgishtml = -1; // Unknown = autodetect by default
486  if (preg_match('/[\s\t]*<html>/i', $object->body)) {
487  $msgishtml = 1;
488  }
489 
490  $signature = ((!empty($user->signature) && !getDolGlobalString('MAIN_MAIL_DO_NOT_USE_SIGN')) ? $user->signature : '');
491 
492  $parameters = array('mode' => 'emailing');
493  $substitutionarray = getCommonSubstitutionArray($langs, 0, array('object', 'objectamount'), $targetobject); // Note: On mass emailing, this is null because be don't know object
494 
495  // other are set at begin of page
496  $substitutionarray['__EMAIL__'] = $object->sendto;
497  $substitutionarray['__MAILTOEMAIL__'] = '<a href="mailto:'.$object->sendto.'">'.$object->sendto.'</a>';
498  $substitutionarray['__CHECK_READ__'] = '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag=undefinedintestmode&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY')."-undefinedintestmode-".$obj->sendto."-0", 'md5').'&email='.urlencode($obj->sendto).'&mtid=0" width="1" height="1" style="width:1px;height:1px" border="0"/>';
499  $substitutionarray['__UNSUBSCRIBE__'] = '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag=undefinedintestmode&unsuscrib=1&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY')."-undefinedintestmode-".$obj->sendto."-0", 'md5').'&email='.urlencode($obj->sendto).'&mtid=0" target="_blank" rel="noopener noreferrer">'.$langs->trans("MailUnsubcribe").'</a>';
500  $substitutionarray['__UNSUBSCRIBE_URL__'] = DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag=undefinedintestmode&unsuscrib=1&securitykey='.dol_hash(getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY')."-undefinedintestmode-".$obj->sendto."-0", 'md5').'&email='.urlencode($obj->sendto).'&mtid=0';
501 
502  // Subject and message substitutions
503  complete_substitutions_array($substitutionarray, $langs, $targetobject);
504 
505  $tmpsujet = make_substitutions($object->sujet, $substitutionarray);
506  $tmpbody = make_substitutions($object->body, $substitutionarray);
507 
508  $arr_file = array();
509  $arr_mime = array();
510  $arr_name = array();
511  $arr_css = array();
512 
513  // Add CSS
514  if (!empty($object->bgcolor)) {
515  $arr_css['bgcolor'] = (preg_match('/^#/', $object->bgcolor) ? '' : '#').$object->bgcolor;
516  }
517  if (!empty($object->bgimage)) {
518  $arr_css['bgimage'] = $object->bgimage;
519  }
520 
521  // Attached files
522  $listofpaths = dol_dir_list($upload_dir, 'all', 0, '', '', 'name', SORT_ASC, 0);
523  if (count($listofpaths)) {
524  foreach ($listofpaths as $key => $val) {
525  $arr_file[] = $listofpaths[$key]['fullname'];
526  $arr_mime[] = dol_mimetype($listofpaths[$key]['name']);
527  $arr_name[] = $listofpaths[$key]['name'];
528  }
529  }
530 
531  $trackid = 'emailing-test';
532  $upload_dir_tmp = $upload_dir;
533  $mailfile = new CMailFile($tmpsujet, $object->sendto, $object->email_from, $tmpbody, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $object->email_errorsto, $arr_css, $trackid, '', 'emailing', '', $upload_dir_tmp);
534 
535  $result = $mailfile->sendfile();
536  if ($result) {
537  setEventMessages($langs->trans("MailSuccessfulySent", $mailfile->getValidAddress($object->email_from, 2), $mailfile->getValidAddress($object->sendto, 2)), null, 'mesgs');
538  $action = '';
539  } else {
540  setEventMessages($langs->trans("ResultKo").'<br>'.$mailfile->error.' '.json_encode($result), null, 'errors');
541  $action = 'test';
542  }
543  }
544  }
545 
546  // Action add emailing
547  if ($action == 'add' && $permissiontocreate) {
548  $mesgs = array();
549 
550  $object->messtype = (string) GETPOST("messtype");
551  if ($object->messtype == 'sms') {
552  $object->email_from = (string) GETPOST("from_phone", 'alphawithlgt'); // Must allow 'name <email>'
553  } else {
554  $object->email_from = (string) GETPOST("from", 'alphawithlgt'); // Must allow 'name <email>'
555  }
556  $object->email_replyto = (string) GETPOST("replyto", 'alphawithlgt'); // Must allow 'name <email>'
557  $object->email_errorsto = (string) GETPOST("errorsto", 'alphawithlgt'); // Must allow 'name <email>'
558  $object->title = (string) GETPOST("title");
559  $object->sujet = (string) GETPOST("sujet");
560  $object->body = (string) GETPOST("bodyemail", 'restricthtml');
561  $object->bgcolor = preg_replace('/^#/', '', (string) GETPOST("bgcolor"));
562  $object->bgimage = (string) GETPOST("bgimage");
563 
564  if (!$object->title) {
565  $mesgs[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTitle"));
566  }
567  if ($object->messtype != 'sms' && !$object->sujet) {
568  $mesgs[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTopic"));
569  }
570  if (!$object->body) {
571  $mesgs[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailMessage"));
572  }
573 
574  if (!count($mesgs)) {
575  if ($object->create($user) >= 0) {
576  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
577  exit;
578  }
579  $mesgs[] = $object->error;
580  $mesgs = array_merge($mesgs, $object->errors);
581  }
582 
583  setEventMessages('', $mesgs, 'errors');
584  $action = "create";
585  }
586 
587  // Action update description of emailing
588  if (($action == 'settitle' || $action == 'setemail_from' || $action == 'setemail_replyto' || $action == 'setreplyto' || $action == 'setemail_errorsto' || $action == 'setevenunsubscribe') && $permissiontovalidatesend) {
589  $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
590 
591  if ($action == 'settitle') {
592  $object->title = trim(GETPOST('title', 'alpha'));
593  } elseif ($action == 'setemail_from') {
594  $object->email_from = trim(GETPOST('email_from', 'alphawithlgt')); // Must allow 'name <email>'
595  } elseif ($action == 'setemail_replyto') {
596  $object->email_replyto = trim(GETPOST('email_replyto', 'alphawithlgt')); // Must allow 'name <email>'
597  } elseif ($action == 'setemail_errorsto') {
598  $object->email_errorsto = trim(GETPOST('email_errorsto', 'alphawithlgt')); // Must allow 'name <email>'
599  } elseif ($action == 'settitle' && empty($object->title)) {
600  $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTitle"));
601  } elseif ($action == 'setfrom' && empty($object->email_from)) {
602  $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailFrom"));
603  } elseif ($action == 'setevenunsubscribe') {
604  $object->evenunsubscribe = (GETPOST('evenunsubscribe') ? 1 : 0);
605  }
606 
607  if (!$mesg) {
608  $result = $object->update($user);
609  if ($result >= 0) {
610  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
611  exit;
612  }
613  $mesg = $object->error;
614  }
615 
616  setEventMessages($mesg, $mesgs, 'errors');
617  $action = "";
618  }
619 
620  /*
621  * Action of adding a file in email form
622  */
623  if (GETPOST('addfile') && $permissiontocreate) {
624  $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
625 
626  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
627 
628  // Set tmp user directory
629  dol_add_file_process($upload_dir, 0, 0, 'addedfile', '', null, '', 0);
630 
631  $action = "edit";
632  }
633 
634  // Action of file remove
635  if (GETPOST("removedfile") && $permissiontocreate) {
636  $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
637 
638  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
639 
640  dol_remove_file_process(GETPOST('removedfile'), 0, 0); // We really delete file linked to mailing
641 
642  $action = "edit";
643  }
644 
645  // Action of emailing update
646  if ($action == 'update' && !GETPOST("removedfile") && !$cancel && $permissiontocreate) {
647  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
648 
649  $isupload = 0;
650 
651  if (!$isupload) {
652  $mesgs = array();
653 
654  //$object->messtype = (string) GETPOST("messtype"); // We must not be able to change the messtype
655  $object->sujet = (string) GETPOST("sujet");
656  $object->body = (string) GETPOST("bodyemail", 'restricthtml');
657  $object->bgcolor = preg_replace('/^#/', '', (string) GETPOST("bgcolor"));
658  $object->bgimage = (string) GETPOST("bgimage");
659 
660  if ($object->messtype != 'sms' && !$object->sujet) {
661  $mesgs[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTopic"));
662  }
663  if (!$object->body) {
664  $mesgs[] = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailMessage"));
665  }
666 
667  if (!count($mesgs)) {
668  if ($object->update($user) >= 0) {
669  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
670  exit;
671  }
672  $mesgs[] = $object->error;
673  $mesgs = array_merge($mesgs, $object->errors);
674  }
675 
676  setEventMessages('', $mesgs, 'errors');
677  $action = "edit";
678  } else {
679  $action = "edit";
680  }
681  }
682 
683  // Action of validation confirmation
684  if ($action == 'confirm_valid' && $confirm == 'yes' && $permissiontovalidatesend) {
685  if ($object->id > 0) {
686  $object->valid($user);
687  setEventMessages($langs->trans("MailingSuccessfullyValidated"), null, 'mesgs');
688  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
689  exit;
690  } else {
691  dol_print_error($db);
692  }
693  }
694 
695  // Action of validation confirmation
696  if ($action == 'confirm_settodraft' && $confirm == 'yes' && $permissiontocreate) {
697  if ($object->id > 0) {
698  $result = $object->setStatut(0);
699  if ($result > 0) {
700  //setEventMessages($langs->trans("MailingSuccessfullyValidated"), null, 'mesgs');
701  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
702  exit;
703  } else {
704  setEventMessages($object->error, $object->errors, 'errors');
705  }
706  } else {
707  dol_print_error($db);
708  }
709  }
710 
711  // Resend
712  if ($action == 'confirm_reset' && $confirm == 'yes' && $permissiontocreate) {
713  if ($object->id > 0) {
714  $db->begin();
715 
716  $result = $object->valid($user);
717  if ($result > 0) {
718  $result = $object->reset_targets_status($user);
719  }
720 
721  if ($result > 0) {
722  $db->commit();
723  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
724  exit;
725  } else {
726  setEventMessages($object->error, $object->errors, 'errors');
727  $db->rollback();
728  }
729  } else {
730  dol_print_error($db);
731  }
732  }
733 
734  // Action of delete confirmation
735  if ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
736  if ($object->delete($user)) {
737  $url = (!empty($urlfrom) ? $urlfrom : 'list.php');
738  header("Location: ".$url);
739  exit;
740  }
741  }
742 
743  if ($cancel) {
744  $action = '';
745  }
746 }
747 
748 
749 /*
750  * View
751  */
752 
753 $form = new Form($db);
754 $htmlother = new FormOther($db);
755 
756 $help_url = 'EN:Module_EMailing|FR:Module_Mailing|ES:M&oacute;dulo_Mailing';
757 llxHeader(
758  '',
759  $langs->trans("Mailing"),
760  $help_url,
761  '',
762  0,
763  0,
764  array(
765  '/includes/ace/src/ace.js',
766  '/includes/ace/src/ext-statusbar.js',
767  '/includes/ace/src/ext-language_tools.js',
768  //'/includes/ace/src/ext-chromevox.js'
769  ),
770  array()
771 );
772 
773 
774 if ($action == 'create') {
775  // EMailing in creation mode
776  print '<form name="new_mailing" action="'.$_SERVER['PHP_SELF'].'" method="POST">'."\n";
777  print '<input type="hidden" name="token" value="'.newToken().'">';
778  print '<input type="hidden" name="action" value="add">';
779 
780  $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br><br><span class="small">';
781  foreach ($object->substitutionarray as $key => $val) {
782  $htmltext .= $key.' = '.$langs->trans($val).'<br>';
783  }
784  $htmltext .= '</span></i>';
785 
786 
787  $availablelink = $form->textwithpicto('<span class="opacitymedium">'.$langs->trans("AvailableVariables").'</span>', $htmltext, 1, 'helpclickable', '', 0, 2, 'availvar');
788  //print '<a href="javascript:document_preview(\''.DOL_URL_ROOT.'/admin/modulehelp.php?id='.$objMod->numero.'\',\'text/html\',\''.dol_escape_js($langs->trans("Module")).'\')">'.img_picto($langs->trans("ClickToShowDescription"), $imginfo).'</a>';
789 
790 
791  // Print mail form
792  print load_fiche_titre($langs->trans("NewMailing"), $availablelink, 'object_email');
793 
794  print dol_get_fiche_head(array(), '', '', -3);
795 
796  print '<table class="border centpercent">';
797 
798  print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailTitle").'</td><td><input class="flat minwidth300" name="title" value="'.dol_escape_htmltag(GETPOST('title')).'" autofocus="autofocus"></td></tr>';
799 
800  if (getDolGlobalInt('EMAILINGS_SUPPORT_ALSO_SMS')) {
801  $arrayoftypes = array("email" => "Email", "sms" => "SMS");
802  print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("Type").'</td><td>';
803  print $form->selectarray('messtype', $arrayoftypes, (GETPOSTISSET('messtype') ? GETPOST('messtype') : 'email'), 0, 0);
804 
805  print '<script>
806  $( document ).ready(function() {
807  jQuery("#messtype").on("change", function() {
808  console.log("We change the message ttpe");
809  if (jQuery("#messtype").val() == "email") {
810  jQuery(".fieldsforsms").hide();
811  jQuery(".fieldsforemail").show();
812  }
813  if (jQuery("#messtype").val() == "sms") {
814  jQuery(".fieldsforsms").show();
815  jQuery(".fieldsforemail").hide();
816  }
817  });
818  jQuery("#messtype").change();
819  })
820  </script>';
821 
822  print '</td></tr>';
823  }
824  print '</table>';
825 
826  print '<br><br>';
827 
828  print '<table class="border centpercent">';
829 
830  print '<tr class="fieldsforemail"><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailFrom").'</td><td><input class="flat minwidth200" name="from" value="'.(GETPOSTISSET('from') ? GETPOST('from') : getDolGlobalString('MAILING_EMAIL_FROM')).'"></td></tr>';
831 
832  print '<tr class="fieldsforsms hidden"><td class="fieldrequired titlefieldcreate">'.$langs->trans("PhoneFrom").'</td><td><input class="flat minwidth200" name="fromphone" value="'.(GETPOSTISSET('fromphone') ? GETPOST('fromphone') : getDolGlobalString('MAILING_SMS_FROM')).'" placeholder="+123..."></td></tr>';
833 
834  print '<tr class="fieldsforemail"><td>'.$langs->trans("MailErrorsTo").'</td><td><input class="flat minwidth200" name="errorsto" value="'.getDolGlobalString('MAILING_EMAIL_ERRORSTO', getDolGlobalString('MAIN_MAIL_ERRORS_TO')).'"></td></tr>';
835 
836  // Other attributes
837  $parameters = array();
838  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
839  print $hookmanager->resPrint;
840  if (empty($reshook)) {
841  print $object->showOptionals($extrafields, 'create');
842  }
843 
844  print '</table>';
845  print '<br><br>';
846 
847  print '<table class="border centpercent">';
848  print '<tr class="fieldsforemail"><td class="fieldrequired titlefieldcreate">'.$langs->trans("MailTopic").'</td><td><input class="flat minwidth200 quatrevingtpercent" name="sujet" value="'.dol_escape_htmltag(GETPOST('sujet', 'alphanohtml')).'"></td></tr>';
849  print '<tr class="fieldsforemail"><td>'.$langs->trans("BackgroundColorByDefault").'</td><td colspan="3">';
850  print $htmlother->selectColor(GETPOST('bgcolor'), 'bgcolor', '', 0);
851  print '</td></tr>';
852 
853  $formmail = new FormMail($db);
854  $formmail->withfckeditor = 1;
855  $formmail->withaiprompt = 'html';
856  $formmail->withlayout = 1;
857 
858  print '<tr class="fieldsforemail"><td></td><td class="tdtop">';
859 
860  $out = '';
861  $showlinktolayout = $formmail->withlayout && $formmail->withfckeditor;
862  $showlinktolayoutlabel = $langs->trans("FillMessageWithALayout");
863  $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationemail' : '';
864  $showlinktoailabel = $langs->trans("FillMessageWithAIContent");
865  $formatforouput = 'html';
866  $htmlname = 'bodyemail';
867 
868  // Fill $out
869  include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
870 
871  print $out;
872 
873  print '</td></tr>';
874  print '</table>';
875 
876  print '<div style="padding-top: 10px">';
877  // wysiwyg editor
878  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
879  $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, true, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%');
880  $doleditor->Create();
881  print '</div>';
882 
883  print dol_get_fiche_end();
884 
885  print $form->buttonsSaveCancel("Create", 'Cancel');
886 
887  print '</form>';
888 } else {
889  if ($object->id > 0) {
890  $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
891 
893 
894  if ($action == 'settodraft') {
895  // Confirmation back to draft
896  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("SetToDraft"), $langs->trans("ConfirmUnvalidateEmailing"), "confirm_settodraft", '', '', 1);
897  } elseif ($action == 'valid') {
898  // Confirmation of mailing validation
899  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ValidMailing"), $langs->trans("ConfirmValidMailing"), "confirm_valid", '', '', 1);
900  } elseif ($action == 'reset') {
901  // Confirm reset
902  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ResetMailing"), $langs->trans("ConfirmResetMailing", $object->ref), "confirm_reset", '', '', 2);
903  } elseif ($action == 'delete') {
904  // Confirm delete
905  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id.(!empty($urlfrom) ? '&urlfrom='.urlencode($urlfrom) : ''), $langs->trans("DeleteMailing"), $langs->trans("ConfirmDeleteMailing"), "confirm_delete", '', '', 1);
906  }
907 
908  if ($action != 'edit' && $action != 'edittxt' && $action != 'edithtml') {
909  print dol_get_fiche_head($head, 'card', $langs->trans("Mailing"), -1, 'email');
910 
911  /*
912  * View mode mailing
913  */
914  if ($action == 'sendall') {
915  // Define message to recommend from command line
916  $sendingmode = getDolGlobalString('EMAILING_MAIL_SENDMODE');
917  if (empty($sendingmode)) {
918  $sendingmode = getDolGlobalString('MAIN_MAIL_SENDMODE');
919  }
920  if (empty($sendingmode)) {
921  $sendingmode = 'mail'; // If not defined, we use php mail function
922  }
923 
924  // MAILING_NO_USING_PHPMAIL may be defined or not.
925  // MAILING_LIMIT_SENDBYWEB is always defined to something != 0 (-1=forbidden).
926  // MAILING_LIMIT_SENDBYCLI may be defined or not (-1=forbidden, 0 or undefined=no limit).
927  // MAILING_LIMIT_SENDBYDAY may be defined or not (0 or undefined=no limit).
928  if (getDolGlobalString('MAILING_NO_USING_PHPMAIL') && $sendingmode == 'mail') {
929  // EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
930  // You ensure that every user is using its own SMTP server when using the mass emailing module.
931  $linktoadminemailbefore = '<a href="'.DOL_URL_ROOT.'/admin/mails_emailing.php">';
932  $linktoadminemailend = '</a>';
933  setEventMessages($langs->trans("MailSendSetupIs", $listofmethods[$sendingmode]), null, 'warnings');
934  $messagetoshow = $langs->trans("MailSendSetupIs2", '{s1}', '{s2}', '{s3}', '{s4}');
935  $messagetoshow = str_replace('{s1}', $linktoadminemailbefore, $messagetoshow);
936  $messagetoshow = str_replace('{s2}', $linktoadminemailend, $messagetoshow);
937  $messagetoshow = str_replace('{s3}', $langs->transnoentitiesnoconv("MAIN_MAIL_SENDMODE"), $messagetoshow);
938  $messagetoshow = str_replace('{s4}', $listofmethods['smtps'], $messagetoshow);
939  setEventMessages($messagetoshow, null, 'warnings');
940 
941  if (getDolGlobalString('MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS')) {
942  setEventMessages($langs->trans("MailSendSetupIs3", getDolGlobalString('MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS')), null, 'warnings');
943  }
944  $action = '';
945  } elseif (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') < 0) {
946  if (getDolGlobalString('MAILING_LIMIT_WARNING_PHPMAIL') && $sendingmode == 'mail') {
947  setEventMessages($langs->transnoentitiesnoconv($conf->global->MAILING_LIMIT_WARNING_PHPMAIL), null, 'warnings');
948  }
949  if (getDolGlobalString('MAILING_LIMIT_WARNING_NOPHPMAIL') && $sendingmode != 'mail') {
950  setEventMessages($langs->transnoentitiesnoconv($conf->global->MAILING_LIMIT_WARNING_NOPHPMAIL), null, 'warnings');
951  }
952 
953  // The feature is forbidden from GUI, we show just message to use from command line.
954  setEventMessages($langs->trans("MailingNeedCommand"), null, 'warnings');
955  setEventMessages('<textarea cols="60" rows="'.ROWS_1.'" wrap="soft">php ./scripts/emailings/mailing-send.php '.$object->id.'</textarea>', null, 'warnings');
956  if ($conf->file->mailing_limit_sendbyweb != '-1') { // MAILING_LIMIT_SENDBYWEB was set to -1 in database, but it is allowed to increase it.
957  setEventMessages($langs->trans("MailingNeedCommand2"), null, 'warnings'); // You can send online with constant...
958  }
959  $action = '';
960  } else {
961  if (getDolGlobalString('MAILING_LIMIT_WARNING_PHPMAIL') && $sendingmode == 'mail') {
962  setEventMessages($langs->transnoentitiesnoconv($conf->global->MAILING_LIMIT_WARNING_PHPMAIL), null, 'warnings');
963  }
964  if (getDolGlobalString('MAILING_LIMIT_WARNING_NOPHPMAIL') && $sendingmode != 'mail') {
965  setEventMessages($langs->transnoentitiesnoconv($conf->global->MAILING_LIMIT_WARNING_NOPHPMAIL), null, 'warnings');
966  }
967 
968  $text = '';
969 
970  if (getDolGlobalInt('MAILING_LIMIT_SENDBYDAY') > 0) {
971  $text .= $langs->trans('WarningLimitSendByDay', getDolGlobalInt('MAILING_LIMIT_SENDBYDAY'));
972  $text .= '<br><br>';
973  }
974  $text .= $langs->trans('ConfirmSendingEmailing').'<br>';
975  $text .= $langs->trans('LimitSendingEmailing', getDolGlobalString('MAILING_LIMIT_SENDBYWEB'));
976 
977  if (!isset($conf->global->MAILING_LIMIT_SENDBYCLI) || getDolGlobalInt('MAILING_LIMIT_SENDBYCLI') >= 0) {
978  $text .= '<br><br>';
979  $text .= $langs->trans("MailingNeedCommand");
980  $text .= '<br><textarea class="quatrevingtpercent" rows="'.ROWS_2.'" wrap="soft" disabled>php ./scripts/emailings/mailing-send.php '.$object->id.' '.$user->login.'</textarea>';
981  }
982 
983  print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('SendMailing'), $text, 'sendallconfirmed', '', '', 1, 380, 660, 0, $langs->trans("Confirm"), $langs->trans("Cancel"));
984  }
985  }
986 
987  $linkback = '<a href="'.DOL_URL_ROOT.'/comm/mailing/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
988 
989  $morehtmlref = '<div class="refidno">';
990  // Ref customer
991  $morehtmlref .= $form->editfieldkey("", 'title', $object->title, $object, $user->hasRight('mailing', 'creer'), 'string', '', 0, 1);
992  $morehtmlref .= $form->editfieldval("", 'title', $object->title, $object, $user->hasRight('mailing', 'creer'), 'string', '', null, null, '', 1);
993  $morehtmlref .= '</div>';
994 
995  $morehtmlstatus = '';
996  $nbtry = $nbok = 0;
997  if ($object->status == 2 || $object->status == 3) {
998  $nbtry = $object->countNbOfTargets('alreadysent');
999  $nbko = $object->countNbOfTargets('alreadysentko');
1000 
1001  $morehtmlstatus .= ' ('.$nbtry.'/'.$object->nbemail;
1002  if ($nbko) {
1003  $morehtmlstatus .= ' - '.$nbko.' '.$langs->trans("Error");
1004  }
1005  $morehtmlstatus .= ') &nbsp; ';
1006  }
1007 
1008  dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
1009 
1010  print '<div class="fichecenter">';
1011  print '<div class="fichehalfleft">';
1012  print '<div class="underbanner clearboth"></div>';
1013  print '<table class="border centpercent tableforfield">'."\n";
1014 
1015  // From
1016  print '<tr><td class="titlefield">';
1017  print $form->editfieldkey("MailFrom", 'email_from', $object->email_from, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
1018  print '</td><td>';
1019  print $form->editfieldval("MailFrom", 'email_from', $object->email_from, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
1020  $email = CMailFile::getValidAddress($object->email_from, 2);
1021  if ($email && !isValidEmail($email)) {
1022  $langs->load("errors");
1023  print img_warning($langs->trans("ErrorBadEMail", $email));
1024  } elseif ($email && !isValidMailDomain($email)) {
1025  $langs->load("errors");
1026  print img_warning($langs->trans("ErrorBadMXDomain", $email));
1027  }
1028 
1029  print '</td></tr>';
1030 
1031  // Errors to
1032  if ($object->messtype != 'sms') {
1033  print '<tr><td>';
1034  print $form->editfieldkey("MailErrorsTo", 'email_errorsto', $object->email_errorsto, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
1035  print '</td><td>';
1036  print $form->editfieldval("MailErrorsTo", 'email_errorsto', $object->email_errorsto, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
1037  $email = CMailFile::getValidAddress($object->email_errorsto, 2);
1038  if ($action != 'editemail_errorsto') {
1039  if ($email && !isValidEmail($email)) {
1040  $langs->load("errors");
1041  print img_warning($langs->trans("ErrorBadEMail", $email));
1042  } elseif ($email && !isValidMailDomain($email)) {
1043  $langs->load("errors");
1044  print img_warning($langs->trans("ErrorBadMXDomain", $email));
1045  }
1046  }
1047  print '</td></tr>';
1048  }
1049 
1050  // Reply to
1051  if ($object->messtype != 'sms') {
1052  print '<tr><td>';
1053  print $form->editfieldkey("MailReply", 'email_replyto', $object->email_replyto, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
1054  print '</td><td>';
1055  print $form->editfieldval("MailReply", 'email_replyto', $object->email_replyto, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
1056  $email = CMailFile::getValidAddress($object->email_replyto, 2);
1057  if ($action != 'editemail_replyto') {
1058  if ($email && !isValidEmail($email)) {
1059  $langs->load("errors");
1060  print img_warning($langs->trans("ErrorBadEMail", $email));
1061  } elseif ($email && !isValidMailDomain($email)) {
1062  $langs->load("errors");
1063  print img_warning($langs->trans("ErrorBadMXDomain", $email));
1064  }
1065  }
1066  print '</td></tr>';
1067  }
1068 
1069  print '</table>';
1070  print '</div>';
1071 
1072  print '<div class="fichehalfright">';
1073  print '<div class="underbanner clearboth"></div>';
1074 
1075  print '<table class="border centpercent tableforfield">';
1076 
1077  // Number of distinct emails
1078  print '<tr><td>';
1079  print $langs->trans("TotalNbOfDistinctRecipients");
1080  print '</td><td>';
1081  $nbemail = ($object->nbemail ? $object->nbemail : 0);
1082  if (is_numeric($nbemail)) {
1083  $text = '';
1084  if ((getDolGlobalString('MAILING_LIMIT_SENDBYWEB') && getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') < $nbemail) && ($object->statut == 1 || ($object->statut == 2 && $nbtry < $nbemail))) {
1085  if (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') > 0) {
1086  $text .= $langs->trans('LimitSendingEmailing', getDolGlobalInt('MAILING_LIMIT_SENDBYWEB'));
1087  } else {
1088  $text .= $langs->trans('SendingFromWebInterfaceIsNotAllowed');
1089  }
1090  }
1091  if (empty($nbemail)) {
1092  $nbemail .= ' '.img_warning('').' <span class="warning">'.$langs->trans("NoTargetYet").'</span>';
1093  }
1094  if ($text) {
1095  print $form->textwithpicto($nbemail, $text, 1, 'warning');
1096  } else {
1097  print $nbemail;
1098  }
1099  }
1100  print '</td></tr>';
1101 
1102  print '<tr><td>';
1103  print $langs->trans("MAIN_MAIL_SENDMODE");
1104  print '</td><td>';
1105  if ($object->messtype != 'sms') {
1106  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') && getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
1107  $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING')];
1108  } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE')) {
1109  $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE')];
1110  } else {
1111  $text = $listofmethods['mail'];
1112  }
1113  print $text;
1114  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
1115  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'mail') {
1116  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER_EMAILING', getDolGlobalString('MAIN_MAIL_SMTP_SERVER')).')</span>';
1117  }
1118  } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE') != 'mail' && getDolGlobalString('MAIN_MAIL_SMTP_SERVER')) {
1119  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER').')</span>';
1120  }
1121  } else {
1122  print 'SMS ';
1123  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER').')</span>';
1124  }
1125  print '</td></tr>';
1126 
1127  // Other attributes. Fields from hook formObjectOptions and Extrafields.
1128  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1129 
1130  print '</table>';
1131  print '</div>';
1132  print '</div>';
1133 
1134  print '<div class="clearboth"></div>';
1135 
1136  print dol_get_fiche_end();
1137 
1138 
1139  // Clone confirmation
1140  if ($action == 'clone') {
1141  // Create an array for form
1142  $formquestion = array(
1143  'text' => $langs->trans("ConfirmClone"),
1144  0 => array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneContent"), 'value' => 1),
1145  1 => array('type' => 'checkbox', 'name' => 'clone_receivers', 'label' => $langs->trans("CloneReceivers"), 'value' => 0)
1146  );
1147  // Incomplete payment. On demande si motif = escompte ou autre
1148  print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneEMailing', $object->ref), 'confirm_clone', $formquestion, 'yes', 2, 240);
1149  }
1150 
1151  // Actions Buttons
1152  if (GETPOST('cancel', 'alpha') || $confirm == 'no' || $action == '' || in_array($action, array('settodraft', 'valid', 'delete', 'sendall', 'clone', 'test', 'editevenunsubscribe'))) {
1153  print "\n\n<div class=\"tabsAction\">\n";
1154 
1155  if (($object->status == 1) && ($user->hasRight('mailing', 'valider') || $object->user_validation_id == $user->id)) {
1156  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=settodraft&token='.newToken().'&id='.$object->id.'">'.$langs->trans("SetToDraft").'</a>';
1157  }
1158 
1159  if (($object->status == 0 || $object->status == 1 || $object->status == 2) && $user->hasRight('mailing', 'creer')) {
1160  if (isModEnabled('fckeditor') && getDolGlobalString('FCKEDITOR_ENABLE_MAILING') && $object->messtype != 'sms') {
1161  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans("EditHTML").'</a>';
1162  } else {
1163  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edittxt&token='.newToken().'&id='.$object->id.'">'.$langs->trans("EditWithTextEditor").'</a>';
1164  }
1165 
1166  if (!getDolGlobalInt('EMAILINGS_SUPPORT_ALSO_SMS')) {
1167  if (!empty($conf->use_javascript_ajax)) {
1168  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edithtml&token='.newToken().'&id='.$object->id.'">'.$langs->trans("EditHTMLSource").'</a>';
1169  }
1170  }
1171  }
1172 
1173  //print '<a class="butAction" href="card.php?action=test&amp;id='.$object->id.'">'.$langs->trans("PreviewMailing").'</a>';
1174 
1175  if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('mailing', 'mailing_advance', 'send')) {
1176  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("TestMailing").'</a>';
1177  } else {
1178  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=test&token='.newToken().'&id='.$object->id.'">'.$langs->trans("TestMailing").'</a>';
1179  }
1180 
1181  if ($object->status == 0) {
1182  if ($object->nbemail <= 0) {
1183  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NoTargetYet")).'">'.$langs->trans("Validate").'</a>';
1184  } elseif (!$user->hasRight('mailing', 'valider')) {
1185  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("Validate").'</a>';
1186  } else {
1187  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=valid&amp;id='.$object->id.'">'.$langs->trans("Validate").'</a>';
1188  }
1189  }
1190 
1191  if (($object->status == 1 || $object->status == 2) && $object->nbemail > 0 && $user->hasRight('mailing', 'valider')) {
1192  if (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') < 0) {
1193  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("SendingFromWebInterfaceIsNotAllowed")).'">'.$langs->trans("SendMailing").'</a>';
1194  } elseif (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('mailing', 'mailing_advance', 'send')) {
1195  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("SendMailing").'</a>';
1196  } else {
1197  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=sendall&amp;id='.$object->id.'">'.$langs->trans("SendMailing").'</a>';
1198  }
1199  }
1200 
1201  if ($user->hasRight('mailing', 'creer')) {
1202  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=clone&amp;object=emailing&amp;id='.$object->id.'">'.$langs->trans("ToClone").'</a>';
1203  }
1204 
1205  if (($object->status == 2 || $object->status == 3) && $user->hasRight('mailing', 'valider')) {
1206  if (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('mailing', 'mailing_advance', 'send')) {
1207  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("ResetMailing").'</a>';
1208  } else {
1209  print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=reset&amp;id='.$object->id.'">'.$langs->trans("ResetMailing").'</a>';
1210  }
1211  }
1212 
1213  if (($object->status <= 1 && $user->hasRight('mailing', 'creer')) || $user->hasRight('mailing', 'supprimer')) {
1214  if ($object->status > 0 && (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('mailing', 'mailing_advance', 'delete'))) {
1215  print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("Delete").'</a>';
1216  } else {
1217  print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&id='.$object->id.(!empty($urlfrom) ? '&urlfrom='.$urlfrom : '').'">'.$langs->trans("Delete").'</a>';
1218  }
1219  }
1220 
1221  print '</div>';
1222  }
1223 
1224  // Display of the TEST form
1225  if ($action == 'test') {
1226  print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>';
1227  print load_fiche_titre($langs->trans("TestMailing"));
1228 
1229  print dol_get_fiche_head(null, '', '', -1);
1230 
1231  // Create mail form object
1232  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
1233  $formmail = new FormMail($db);
1234  $formmail->fromname = $object->email_from;
1235  $formmail->frommail = $object->email_from;
1236  $formmail->withsubstit = 0;
1237  $formmail->withfrom = 0;
1238  $formmail->withto = $user->email ? $user->email : 1;
1239  $formmail->withtocc = 0;
1240  $formmail->withtoccc = getDolGlobalString('MAIN_EMAIL_USECCC');
1241  $formmail->withtopic = 0;
1242  $formmail->withtopicreadonly = 1;
1243  $formmail->withfile = 0;
1244  $formmail->withlayout = 0;
1245  $formmail->withaiprompt = '';
1246  $formmail->withbody = 0;
1247  $formmail->withbodyreadonly = 1;
1248  $formmail->withcancel = 1;
1249  $formmail->withdeliveryreceipt = 0;
1250  // Table of substitutions
1251  $formmail->substit = $object->substitutionarrayfortest;
1252  // Table of post's complementary params
1253  $formmail->param["action"] = "send";
1254  $formmail->param["models"] = 'none';
1255  $formmail->param["mailid"] = $object->id;
1256  $formmail->param["returnurl"] = $_SERVER['PHP_SELF']."?id=".$object->id;
1257 
1258  print $formmail->get_form();
1259 
1260  print '<br>';
1261 
1262  print dol_get_fiche_end();
1263 
1264  dol_set_focus('#sendto');
1265  }
1266 
1267 
1268  $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br><br><span class="small">';
1269  foreach ($object->substitutionarray as $key => $val) {
1270  $htmltext .= $key.' = '.$langs->trans($val).'<br>';
1271  }
1272  $htmltext .= '</span></i>';
1273 
1274  // Print mail content
1275  print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto('<span class="opacitymedium hideonsmartphone">'.$langs->trans("AvailableVariables").'</span>', $htmltext, 1, 'helpclickable', '', 0, 3, 'emailsubstitionhelp'), 'generic');
1276 
1277  print dol_get_fiche_head('', '', '', -1);
1278 
1279  print '<table class="bordernooddeven tableforfield centpercent">';
1280 
1281  // Subject
1282  if ($object->messtype != 'sms') {
1283  print '<tr><td class="titlefield">'.$langs->trans("MailTopic").'</td><td colspan="3">'.$object->sujet.'</td></tr>';
1284  }
1285 
1286  // Joined files
1287  if ($object->messtype != 'sms') {
1288  print '<tr><td>'.$langs->trans("MailFile").'</td><td colspan="3">';
1289  // List of files
1290  $listofpaths = dol_dir_list($upload_dir, 'all', 0, '', '', 'name', SORT_ASC, 0);
1291  if (count($listofpaths)) {
1292  foreach ($listofpaths as $key => $val) {
1293  print img_mime($listofpaths[$key]['name']).' '.$listofpaths[$key]['name'];
1294  print '<br>';
1295  }
1296  } else {
1297  print '<span class="opacitymedium">'.$langs->trans("NoAttachedFiles").'</span><br>';
1298  }
1299  print '</td></tr>';
1300  }
1301 
1302  // Background color
1303  /*print '<tr><td width="15%">'.$langs->trans("BackgroundColorByDefault").'</td><td colspan="3">';
1304  print $htmlother->selectColor($object->bgcolor,'bgcolor','',0);
1305  print '</td></tr>';*/
1306 
1307  print '</table>';
1308 
1309  // Message
1310  print '<div style="padding-top: 10px; background: '.($object->bgcolor ? (preg_match('/^#/', $object->bgcolor) ? '' : '#').$object->bgcolor : 'white').'">';
1311  if (empty($object->bgcolor) || strtolower($object->bgcolor) == 'ffffff') { // CKEditor does not apply the color of the div into its content area
1312  $readonly = 1;
1313  // wysiwyg editor
1314  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1315  $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, true, !getDolGlobalString('FCKEDITOR_ENABLE_MAILING') ? 0 : 1, 20, '90%', $readonly);
1316  $doleditor->Create();
1317  } else {
1318  print dol_htmlentitiesbr($object->body);
1319  }
1320  print '</div>';
1321 
1322  print dol_get_fiche_end();
1323  } else {
1324  /*
1325  * Edition mode mailing (CKeditor or HTML source)
1326  */
1327 
1328  print dol_get_fiche_head($head, 'card', $langs->trans("Mailing"), -1, 'email');
1329 
1330  $linkback = '<a href="'.DOL_URL_ROOT.'/comm/mailing/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1331 
1332  $morehtmlref = '<div class="refidno">';
1333  // Ref customer
1334  $morehtmlref .= $form->editfieldkey("", 'title', $object->title, $object, $user->hasRight('mailing', 'creer'), 'string', '', 0, 1);
1335  $morehtmlref .= $form->editfieldval("", 'title', $object->title, $object, $user->hasRight('mailing', 'creer'), 'string', '', null, null, '', 1);
1336  $morehtmlref .= '</div>';
1337 
1338  $morehtmlstatus = '';
1339  $nbtry = $nbok = 0;
1340  if ($object->status == 2 || $object->status == 3) {
1341  $nbtry = $object->countNbOfTargets('alreadysent');
1342  $nbko = $object->countNbOfTargets('alreadysentko');
1343 
1344  $morehtmlstatus .= ' ('.$nbtry.'/'.$object->nbemail;
1345  if ($nbko) {
1346  $morehtmlstatus .= ' - '.$nbko.' '.$langs->trans("Error");
1347  }
1348  $morehtmlstatus .= ') &nbsp; ';
1349  }
1350 
1351  dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
1352 
1353  print '<div class="fichecenter">';
1354  print '<div class="fichehalfleft">';
1355  print '<div class="underbanner clearboth"></div>';
1356 
1357  print '<table class="border centpercent tableforfield">';
1358 
1359  /*
1360  print '<tr><td class="titlefield">'.$langs->trans("Ref").'</td>';
1361  print '<td colspan="3">';
1362  print $form->showrefnav($object,'id', $linkback);
1363  print '</td></tr>';
1364  */
1365 
1366  // From
1367  print '<tr><td class="titlefield">';
1368  print $langs->trans("MailFrom");
1369  print '</td><td>'.dol_print_email($object->email_from, 0, 0, 0, 0, 1).'</td></tr>';
1370  // To
1371  if ($object->messtype != 'sms') {
1372  print '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>'.dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1).'</td></tr>';
1373  }
1374 
1375  print '</table>';
1376  print '</div>';
1377 
1378 
1379  print '<div class="fichehalfright">';
1380  print '<div class="underbanner clearboth"></div>';
1381 
1382  print '<table class="border centpercent tableforfield">';
1383 
1384  // Number of distinct emails
1385  print '<tr><td>';
1386  print $langs->trans("TotalNbOfDistinctRecipients");
1387  print '</td><td>';
1388  $nbemail = ($object->nbemail ? $object->nbemail : 0);
1389  if (is_numeric($nbemail)) {
1390  $text = '';
1391  if ((getDolGlobalString('MAILING_LIMIT_SENDBYWEB') && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail) && ($object->status == 1 || $object->status == 2)) {
1392  if (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') > 0) {
1393  $text .= $langs->trans('LimitSendingEmailing', getDolGlobalString('MAILING_LIMIT_SENDBYWEB'));
1394  } else {
1395  $text .= $langs->trans('SendingFromWebInterfaceIsNotAllowed');
1396  }
1397  }
1398  if (empty($nbemail)) {
1399  $nbemail .= ' '.img_warning('').' <span class="warning">'.$langs->trans("NoTargetYet").'</span>';
1400  }
1401  if ($text) {
1402  print $form->textwithpicto($nbemail, $text, 1, 'warning');
1403  } else {
1404  print $nbemail;
1405  }
1406  }
1407  print '</td></tr>';
1408 
1409  print '<tr><td>';
1410  print $langs->trans("MAIN_MAIL_SENDMODE");
1411  print '</td><td>';
1412  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') && getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
1413  $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING')];
1414  } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE')) {
1415  $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE')];
1416  } else {
1417  $text = $listofmethods['mail'];
1418  }
1419  print $text;
1420  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
1421  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'mail') {
1422  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER_EMAILING').')</span>';
1423  }
1424  } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE') != 'mail' && getDolGlobalString('MAIN_MAIL_SMTP_SERVER')) {
1425  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER').')</span>';
1426  }
1427  print '</td></tr>';
1428 
1429 
1430  // Other attributes
1431  $parameters = array();
1432  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1433  print $hookmanager->resPrint;
1434  if (empty($reshook)) {
1435  print $object->showOptionals($extrafields, 'edit', $parameters);
1436  }
1437 
1438  print '</table>';
1439  print '</div>';
1440  print '</div>';
1441 
1442  print '<div class="clearboth"></div>';
1443 
1444  print dol_get_fiche_end();
1445 
1446 
1447  print "<br><br>\n";
1448 
1449  print '<form name="edit_mailing" action="card.php" method="post" enctype="multipart/form-data">'."\n";
1450  print '<input type="hidden" name="token" value="'.newToken().'">';
1451  print '<input type="hidden" name="action" value="update">';
1452  print '<input type="hidden" name="id" value="'.$object->id.'">';
1453 
1454  $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br><br><span class="small">';
1455  foreach ($object->substitutionarray as $key => $val) {
1456  $htmltext .= $key.' = '.$langs->trans($val).'<br>';
1457  }
1458  $htmltext .= '</span></i>';
1459 
1460  // Print mail content
1461  print load_fiche_titre($langs->trans("EMail"), '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("AvailableVariables").'</span>', $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'generic');
1462 
1463  print dol_get_fiche_head(null, '', '', -1);
1464 
1465  print '<table class="bordernooddeven centpercent">';
1466 
1467  // Subject
1468  if ($object->messtype != 'sms') {
1469  print '<tr><td class="fieldrequired titlefield">';
1470  print $langs->trans("MailTopic");
1471  print '</td><td colspan="3"><input class="flat quatrevingtpercent" type="text" name="sujet" value="'.$object->sujet.'"></td></tr>';
1472  }
1473 
1474  $trackid = ''; // TODO To avoid conflicts with 2 mass emailing, we should set a trackid here, even if we use another one into email header.
1475  dol_init_file_process($upload_dir, $trackid);
1476 
1477  // Joined files
1478  if ($object->messtype != 'sms') {
1479  $addfileaction = 'addfile';
1480  print '<tr><td>'.$langs->trans("MailFile").'</td>';
1481  print '<td colspan="3">';
1482  // List of files
1483  $listofpaths = dol_dir_list($upload_dir, 'all', 0, '', '', 'name', SORT_ASC, 0);
1484  $out = '';
1485 
1486  // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
1487  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
1488  $out .= '<script type="text/javascript">';
1489  $out .= 'jQuery(document).ready(function () {';
1490  $out .= ' jQuery(".removedfile").click(function() {';
1491  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
1492  $out .= ' });';
1493  $out .= '})';
1494  $out .= '</script>'."\n";
1495  if (count($listofpaths)) {
1496  foreach ($listofpaths as $key => $val) {
1497  $out .= '<div id="attachfile_'.$key.'">';
1498  $out .= img_mime($listofpaths[$key]['name']).' '.$listofpaths[$key]['name'];
1499  $out .= ' <input type="image" style="border: 0px;" src="'.img_picto($langs->trans("Search"), 'delete.png', '', '', 1).'" value="'.($key + 1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
1500  $out .= '<br></div>';
1501  }
1502  } else {
1503  //$out .= '<span class="opacitymedium">'.$langs->trans("NoAttachedFiles").'</span><br>';
1504  }
1505 
1506  // Add link to add file
1507  $maxfilesizearray = getMaxFileSizeArray();
1508  $maxmin = $maxfilesizearray['maxmin'];
1509  if ($maxmin > 0) {
1510  $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
1511  }
1512  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
1513  $out .= ' ';
1514  $out .= '<input type="submit" class="button smallpaddingimp" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
1515  print $out;
1516  print '</td></tr>';
1517 
1518  // Background color
1519  print '<tr><td>'.$langs->trans("BackgroundColorByDefault").'</td><td colspan="3">';
1520  print $htmlother->selectColor($object->bgcolor, 'bgcolor', '', 0);
1521  print '</td></tr>';
1522  }
1523 
1524  print '</table>';
1525 
1526 
1527  // Message
1528  print '<div style="padding-top: 10px">';
1529 
1530  if ($action == 'edit') {
1531  // wysiwyg editor
1532  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1533  $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%');
1534  $doleditor->Create();
1535  }
1536  if ($action == 'edittxt') {
1537  // wysiwyg editor
1538  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1539  $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, 0, 20, '90%');
1540  $doleditor->Create();
1541  }
1542  if ($action == 'edithtml') {
1543  // HTML source editor
1544  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1545  $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, 'ace', 20, '90%');
1546  $doleditor->Create(0, '', false, 'HTML Source', 'php');
1547  }
1548 
1549  print '</div>';
1550 
1551 
1552  print dol_get_fiche_end();
1553 
1554  print '<div class="center">';
1555  print '<input type="submit" class="button buttonforacesave button-save" value="'.$langs->trans("Save").'" name="save">';
1556  print '&nbsp; &nbsp; &nbsp;';
1557  print '<input type="submit" class="button button-cancel" value="'.$langs->trans("Cancel").'" name="cancel">';
1558  print '</div>';
1559 
1560  print '</form>';
1561  print '<br>';
1562  }
1563  } else {
1564  dol_print_error($db, $object->error);
1565  }
1566 }
1567 
1568 // End of page
1569 llxFooter();
1570 $db->close();
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
static getValidAddress($address, $format, $encode=0, $maxnumberofemail=0)
Return a formatted address string for SMTP protocol.
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new Form...
static getAvailableSubstitKey($mode='formemail', $object=null)
Get list of substitution keys available for emails.
Class permettant la generation de composants html autre Only common components are here.
Class to manage emailings module.
Class to manage third parties objects (customers, suppliers, prospects...)
$parameters
Actions.
Definition: card.php:84
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:744
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
emailing_prepare_head(Mailing $object)
Prepare array with list of tabs.
dol_init_file_process($pathtoscan='', $trackid='')
Scan a directory and init $_SESSION to manage uploaded files with list of all found files.
Definition: files.lib.php:1804
dol_remove_file_process($filenb, $donotupdatesession=0, $donotdeletefile=1, $trackid='')
Remove an uploaded file (for example after submitting a new file a mail form).
Definition: files.lib.php:2023
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:63
dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1, $object=null)
Get and save an upload file (for example after submitting a new file a mail form).
Definition: files.lib.php:1842
isValidMailDomain($mail)
Return true if email has a domain name that can be resolved to MX type.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_print_email($email, $cid=0, $socid=0, $addlink=0, $max=64, $showinvalid=1, $withpicto=0)
Show EMail link formatted for HTML output.
dol_now($mode='auto')
Return date for now.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getMaxFileSizeArray()
Return the max allowed for file upload.
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.