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