dolibarr  19.0.0-dev
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();
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.
Classe permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new For...
static getAvailableSubstitKey($mode='formemail', $object=null)
Get list of substitution keys available for emails.
Classe 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:83
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
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:1699
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
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
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
isValidMailDomain($mail)
Return true if email has a domain name that can be resolved to MX type.
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.
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.
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_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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 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_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')
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.