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