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