dolibarr  x.y.z
html.formmail.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
5  * Copyright (C) 2015-2017 Marcos García <marcosgdf@gmail.com>
6  * Copyright (C) 2015-2017 Nicolas ZABOURI <info@inovea-conseil.com>
7  * Copyright (C) 2018-2022 Frédéric France <frederic.france@netlogic.fr>
8  * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
29 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
30 
31 
38 class FormMail extends Form
39 {
43  public $db;
44 
50  public $withform;
51 
55  public $fromname;
56 
60  public $frommail;
61 
65  public $fromtype;
66 
70  public $fromid;
71 
75  public $fromalsorobot;
76 
80  public $totype;
81 
85  public $toid;
86 
90  public $replytoname;
91 
95  public $replytomail;
96 
100  public $toname;
101 
105  public $tomail;
106 
110  public $trackid;
111 
115  public $inreplyto;
116 
117  public $withsubstit; // Show substitution array
118  public $withfrom;
119 
123  public $withto; // Show recipient emails
124  public $withreplyto;
125 
131  public $withtofree;
132  public $withtocc;
133  public $withtoccc;
134  public $withtopic;
135 
139  public $withfile;
140 
144  public $withmaindocfile;
145  public $withbody;
146 
147  public $withfromreadonly;
148  public $withreplytoreadonly;
149  public $withtoreadonly;
150  public $withtoccreadonly;
151  public $withtocccreadonly;
152  public $withtopicreadonly;
153  public $withfilereadonly;
154  public $withdeliveryreceipt;
155  public $withcancel;
156  public $withfckeditor;
157 
158  public $substit = array();
159  public $substit_lines = array();
160  public $param = array();
161 
162  public $withtouser = array();
163  public $withtoccuser = array();
164 
165  public $lines_model;
166 
167  // -1 suggest the checkbox 'one email per recipient' not checked, 0 = no suggestion, 1 = suggest and checked
168  public $withoptiononeemailperrecipient;
169 
170 
176  public function __construct($db)
177  {
178  $this->db = $db;
179 
180  $this->withform = 1;
181 
182  $this->withfrom = 1;
183  $this->withto = 1;
184  $this->withtofree = 1;
185  $this->withtocc = 1;
186  $this->withtoccc = 0;
187  $this->witherrorsto = 0;
188  $this->withtopic = 1;
189  $this->withfile = 0; // 1=Add section "Attached files". 2=Can add files.
190  $this->withmaindocfile = 0; // 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
191  $this->withbody = 1;
192 
193  $this->withfromreadonly = 1;
194  $this->withreplytoreadonly = 1;
195  $this->withtoreadonly = 0;
196  $this->withtoccreadonly = 0;
197  $this->withtocccreadonly = 0;
198  $this->witherrorstoreadonly = 0;
199  $this->withtopicreadonly = 0;
200  $this->withfilereadonly = 0;
201  $this->withbodyreadonly = 0;
202  $this->withdeliveryreceiptreadonly = 0;
203  $this->withfckeditor = -1; // -1 = Auto
204  }
205 
206  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
212  public function clear_attached_files()
213  {
214  // phpcs:enable
215  global $conf, $user;
216  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
217 
218  // Set tmp user directory
219  $vardir = $conf->user->dir_output."/".$user->id;
220  $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
221  if (is_dir($upload_dir)) {
222  dol_delete_dir_recursive($upload_dir);
223  }
224 
225  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
226  unset($_SESSION["listofpaths".$keytoavoidconflict]);
227  unset($_SESSION["listofnames".$keytoavoidconflict]);
228  unset($_SESSION["listofmimes".$keytoavoidconflict]);
229  }
230 
231  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
240  public function add_attached_files($path, $file = '', $type = '')
241  {
242  // phpcs:enable
243  $listofpaths = array();
244  $listofnames = array();
245  $listofmimes = array();
246 
247  if (empty($file)) {
248  $file = basename($path);
249  }
250  if (empty($type)) {
251  $type = dol_mimetype($file);
252  }
253 
254  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
255  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
256  $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
257  }
258  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
259  $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
260  }
261  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
262  $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
263  }
264  if (!in_array($file, $listofnames)) {
265  $listofpaths[] = $path;
266  $listofnames[] = $file;
267  $listofmimes[] = $type;
268  $_SESSION["listofpaths".$keytoavoidconflict] = join(';', $listofpaths);
269  $_SESSION["listofnames".$keytoavoidconflict] = join(';', $listofnames);
270  $_SESSION["listofmimes".$keytoavoidconflict] = join(';', $listofmimes);
271  }
272  }
273 
274  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
281  public function remove_attached_files($keytodelete)
282  {
283  // phpcs:enable
284  $listofpaths = array();
285  $listofnames = array();
286  $listofmimes = array();
287 
288  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
289  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
290  $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
291  }
292  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
293  $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
294  }
295  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
296  $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
297  }
298  if ($keytodelete >= 0) {
299  unset($listofpaths[$keytodelete]);
300  unset($listofnames[$keytodelete]);
301  unset($listofmimes[$keytodelete]);
302  $_SESSION["listofpaths".$keytoavoidconflict] = join(';', $listofpaths);
303  $_SESSION["listofnames".$keytoavoidconflict] = join(';', $listofnames);
304  $_SESSION["listofmimes".$keytoavoidconflict] = join(';', $listofmimes);
305  //var_dump($_SESSION['listofpaths']);
306  }
307  }
308 
309  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
315  public function get_attached_files()
316  {
317  // phpcs:enable
318  $listofpaths = array();
319  $listofnames = array();
320  $listofmimes = array();
321 
322  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
323  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
324  $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
325  }
326  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
327  $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
328  }
329  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
330  $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
331  }
332  return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
333  }
334 
335  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
346  public function show_form($addfileaction = 'addfile', $removefileaction = 'removefile')
347  {
348  // phpcs:enable
349  print $this->get_form($addfileaction, $removefileaction);
350  }
351 
352  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
363  public function get_form($addfileaction = 'addfile', $removefileaction = 'removefile')
364  {
365  // phpcs:enable
366  global $conf, $langs, $user, $hookmanager, $form;
367 
368  // Required to show preview wof mail attachments
369  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
370  $formfile = new Formfile($this->db);
371 
372  if (!is_object($form)) {
373  $form = new Form($this->db);
374  }
375 
376  // Load translation files required by the page
377  $langs->loadLangs(array('other', 'mails', 'members'));
378 
379  // Clear temp files. Must be done before call of triggers, at beginning (mode = init), or when we select a new template
380  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
381  $this->clear_attached_files();
382  }
383 
384  // Call hook getFormMail
385  $hookmanager->initHooks(array('formmail'));
386 
387  $parameters = array(
388  'addfileaction' => $addfileaction,
389  'removefileaction'=> $removefileaction,
390  'trackid'=> $this->trackid
391  );
392  $reshook = $hookmanager->executeHooks('getFormMail', $parameters, $this);
393 
394  if (!empty($reshook)) {
395  return $hookmanager->resPrint;
396  } else {
397  $out = '';
398 
399  $disablebademails = 1;
400 
401  // Define output language
402  $outputlangs = $langs;
403  $newlang = '';
404  if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($this->param['langsmodels'])) {
405  $newlang = $this->param['langsmodels'];
406  }
407  if (!empty($newlang)) {
408  $outputlangs = new Translate("", $conf);
409  $outputlangs->setDefaultLang($newlang);
410  $outputlangs->load('other');
411  }
412 
413  // Get message template for $this->param["models"] into c_email_templates
414  $arraydefaultmessage = -1;
415  if ($this->param['models'] != 'none') {
416  $model_id = 0;
417  if (array_key_exists('models_id', $this->param)) {
418  $model_id = $this->param["models_id"];
419  }
420 
421  $arraydefaultmessage = $this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one
422  }
423 
424  // Define list of attached files
425  $listofpaths = array();
426  $listofnames = array();
427  $listofmimes = array();
428  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
429 
430  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
431  if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
432  foreach ($this->param['fileinit'] as $file) {
433  $this->add_attached_files($file, basename($file), dol_mimetype($file));
434  }
435  }
436  }
437 
438  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
439  $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
440  }
441  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
442  $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
443  }
444  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
445  $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
446  }
447 
448 
449  $out .= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
450  if ($this->withform == 1) {
451  $out .= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
452 
453  $out .= '<a id="formmail" name="formmail"></a>';
454  $out .= '<input style="display:none" type="submit" id="sendmailhidden" name="sendmail">';
455  $out .= '<input type="hidden" name="token" value="'.newToken().'" />';
456  $out .= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
457  $out .= '<input type="hidden" name="inreplyto" value="'.$this->inreplyto.'" />';
458  }
459  if (!empty($this->withfrom)) {
460  if (!empty($this->withfromreadonly)) {
461  $out .= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
462  $out .= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
463  }
464  }
465  foreach ($this->param as $key => $value) {
466  if (is_array($value)) {
467  $out .= "<!-- param key=".$key." is array, we do not output input field for it -->\n";
468  } else {
469  $out .= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
470  }
471  }
472 
473  $modelmail_array = array();
474  if ($this->param['models'] != 'none') {
475  $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
476  if ($result < 0) {
477  setEventMessages($this->error, $this->errors, 'errors');
478  }
479 
480  foreach ($this->lines_model as $line) {
481  $reg = array();
482  if (preg_match('/\‍((.*)\‍)/', $line->label, $reg)) {
483  $labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__
484  } else {
485  $labeltouse = $line->label;
486  }
487 
488  // We escape the $labeltouse to store it into $modelmail_array.
489  $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse);
490  if ($line->lang) {
491  $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang);
492  }
493  if ($line->private) {
494  $modelmail_array[$line->id] .= ' - <span class="opacitymedium">'.dol_escape_htmltag($langs->trans("Private")).'</span>';
495  }
496  }
497  }
498 
499  // Zone to select email template
500  if (count($modelmail_array) > 0) {
501  $model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOST('modelmailselected', 'int') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0);
502 
503  // If list of template is filled
504  $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
505 
506  $out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
507 
508  $out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1);
509  if ($user->admin) {
510  $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
511  }
512 
513  $out .= ' &nbsp; ';
514  $out .= '<input type="submit" class="button reposition smallpaddingimp" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
515  $out .= ' &nbsp; ';
516  $out .= '</div>';
517  } elseif (!empty($this->param['models']) && in_array($this->param['models'], array(
518  'propal_send', 'order_send', 'facture_send',
519  'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send',
520  'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'all'
521  ))) {
522  // If list of template is empty
523  $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
524  $out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
525  $out .= '<select name="modelmailselected" disabled="disabled"><option value="none">'.$langs->trans("NoTemplateDefined").'</option></select>'; // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy.
526  if ($user->admin) {
527  $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
528  }
529  $out .= ' &nbsp; ';
530  $out .= '<input type="submit" class="button" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
531  $out .= ' &nbsp; ';
532  $out .= '</div>';
533  } else {
534  $out .= '<!-- No template available for $this->param["models"] = '.$this->param['models'].' -->';
535  }
536 
537 
538  $out .= '<table class="tableforemailform boxtablenotop centpercent">'."\n";
539 
540  // Substitution array/string
541  $helpforsubstitution = '';
542  if (is_array($this->substit) && count($this->substit)) {
543  $helpforsubstitution .= $langs->trans('AvailableVariables').' :<br>'."\n";
544  }
545  foreach ($this->substit as $key => $val) {
546  $helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))).'<br>';
547  }
548  if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this.
549  $out .= '<tr><td colspan="2" class="right">';
550  //$out.='<div class="floatright">';
551  if (is_numeric($this->withsubstit)) {
552  $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
553  } else {
554  $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
555  }
556  $out .= "</td></tr>\n";
557  //$out.='</div>';
558  }
559 
560  // From
561  if (!empty($this->withfrom)) {
562  if (!empty($this->withfromreadonly)) {
563  $out .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
564 
565  // $this->fromtype is the default value to use to select sender
566  if (!($this->fromtype === 'user' && $this->fromid > 0)
567  && !($this->fromtype === 'company')
568  && !($this->fromtype === 'robot')
569  && !preg_match('/user_aliases/', $this->fromtype)
570  && !preg_match('/global_aliases/', $this->fromtype)
571  && !preg_match('/senderprofile/', $this->fromtype)
572  ) {
573  // Use this->fromname and this->frommail or error if not defined
574  $out .= $this->fromname;
575  if ($this->frommail) {
576  $out .= ' &lt;'.$this->frommail.'&gt;';
577  } else {
578  if ($this->fromtype) {
579  $langs->load('errors');
580  $out .= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
581  }
582  }
583  } else {
584  $liste = array();
585 
586  // Add user email
587  if (empty($user->email)) {
588  $langs->load('errors');
589  $liste['user'] = $user->getFullName($langs).' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
590  } else {
591  $liste['user'] = $user->getFullName($langs).' &lt;'.$user->email.'&gt;';
592  }
593 
594  // Add also company main email
595  if (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) {
596  $liste['company'] = !empty($conf->global->MAIN_INFO_SOCIETE_NOM)?$conf->global->MAIN_INFO_SOCIETE_NOM:$conf->global->MAIN_INFO_SOCIETE_MAIL;
597  $liste['company'].=' &lt;'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'&gt;';
598  }
599 
600  // Add also email aliases if there is some
601  $listaliases = array(
602  'user_aliases' => (empty($user->email_aliases) ? '' : $user->email_aliases),
603  'global_aliases' => getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'),
604  );
605 
606  // Also add robot email
607  if (!empty($this->fromalsorobot)) {
608  if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
609  $liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM;
610  if ($this->frommail) {
611  $liste['robot'] .= ' &lt;'.$conf->global->MAIN_MAIL_EMAIL_FROM.'&gt;';
612  }
613  }
614  }
615 
616  // Add also email aliases from the c_email_senderprofile table
617  $sql = "SELECT rowid, label, email FROM ".$this->db->prefix()."c_email_senderprofile";
618  $sql .= " WHERE active = 1 AND (private = 0 OR private = ".((int) $user->id).")";
619  $sql .= " ORDER BY position";
620  $resql = $this->db->query($sql);
621  if ($resql) {
622  $num = $this->db->num_rows($resql);
623  $i = 0;
624  while ($i < $num) {
625  $obj = $this->db->fetch_object($resql);
626  if ($obj) {
627  $listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
628  }
629  $i++;
630  }
631  } else {
632  dol_print_error($this->db);
633  }
634 
635  foreach ($listaliases as $typealias => $listalias) {
636  $posalias = 0;
637  $listaliasarray = explode(',', $listalias);
638  foreach ($listaliasarray as $listaliasval) {
639  $posalias++;
640  $listaliasval = trim($listaliasval);
641  if ($listaliasval) {
642  $listaliasval = preg_replace('/</', '&lt;', $listaliasval);
643  $listaliasval = preg_replace('/>/', '&gt;', $listaliasval);
644  if (!preg_match('/&lt;/', $listaliasval)) {
645  $listaliasval = '&lt;'.$listaliasval.'&gt;';
646  }
647  $liste[$typealias.'_'.$posalias] = $listaliasval;
648  }
649  }
650  }
651 
652  // Using combo here make the '<email>' no more visible on list.
653  //$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
654  $out .= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 0, '', $disablebademails);
655  }
656 
657  $out .= "</td></tr>\n";
658  } else {
659  $out .= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
660  $out .= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
661  $out .= '&nbsp; &nbsp; ';
662  $out .= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
663  $out .= "</td></tr>\n";
664  }
665  }
666 
667  // To
668  if (!empty($this->withto) || is_array($this->withto)) {
669  $out .= $this->getHtmlForTo();
670  }
671 
672  // To User
673  if (!empty($this->withtouser) && is_array($this->withtouser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) {
674  $out .= '<tr><td>';
675  $out .= $langs->trans("MailToUsers");
676  $out .= '</td><td>';
677 
678  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
679  $tmparray = $this->withtouser;
680  foreach ($tmparray as $key => $val) {
681  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
682  }
683  $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value
684  if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
685  $withtoselected = array_keys($tmparray);
686  }
687  $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
688  $out .= "</td></tr>\n";
689  }
690 
691  // With option one email per recipient
692  if (!empty($this->withoptiononeemailperrecipient)) {
693  if (abs($this->withoptiononeemailperrecipient) == 1) {
694  $out .= '<tr><td class="minwidth200">';
695  $out .= $langs->trans("GroupEmails");
696  $out .= '</td><td>';
697  $out .= ' <input type="checkbox" id="oneemailperrecipient" value="1" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> ';
698  $out .= '<label for="oneemailperrecipient">'.$langs->trans("OneEmailPerRecipient").'</label>';
699  $out .= '<span class="hideonsmartphone opacitymedium">';
700  $out .= ' - ';
701  $out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
702  $out .= '</span>';
703  $out .= '</td></tr>';
704  } else {
705  $out .= '<tr><td><input type="hidden" name="oneemailperrecipient" value="1"></td><td></td></tr>';
706  }
707  }
708 
709  // CC
710  if (!empty($this->withtocc) || is_array($this->withtocc)) {
711  $out .= $this->getHtmlForCc();
712  }
713 
714  // To User cc
715  if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) {
716  $out .= '<tr><td>';
717  $out .= $langs->trans("MailToCCUsers");
718  $out .= '</td><td>';
719 
720  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
721  $tmparray = $this->withtoccuser;
722  foreach ($tmparray as $key => $val) {
723  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
724  }
725  $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value
726  if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
727  $withtoselected = array_keys($tmparray);
728  }
729  $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
730  $out .= "</td></tr>\n";
731  }
732 
733  // CCC
734  if (!empty($this->withtoccc) || is_array($this->withtoccc)) {
735  $out .= $this->getHtmlForWithCcc();
736  }
737 
738  // Replyto
739  if (!empty($this->withreplyto)) {
740  if ($this->withreplytoreadonly) {
741  $out .= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
742  $out .= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
743  $out .= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail ? (" &lt;".$this->replytomail."&gt;") : "");
744  $out .= "</td></tr>\n";
745  }
746  }
747 
748  // Errorsto
749  if (!empty($this->witherrorsto)) {
750  $out .= $this->getHtmlForWithErrorsTo();
751  }
752 
753  // Ask delivery receipt
754  if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) {
755  $out .= $this->getHtmlForDeliveryReceipt();
756  }
757 
758  // Topic
759  if (!empty($this->withtopic)) {
760  $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution);
761  }
762 
763  // Attached files
764  if (!empty($this->withfile)) {
765  $out .= '<tr>';
766  $out .= '<td>'.$langs->trans("MailFile").'</td>';
767 
768  $out .= '<td>';
769 
770  if ($this->withmaindocfile) {
771  // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
772  if (GETPOSTISSET('sendmail')) {
773  $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
774  } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
775  // If a template was selected, we use setup of template to define if join file checkbox is selected or not.
776  $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
777  }
778  }
779 
780  if (!empty($this->withmaindocfile)) {
781  if ($this->withmaindocfile == 1) {
782  $out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" />';
783  } elseif ($this->withmaindocfile == -1) {
784  $out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" checked="checked" />';
785  }
786  if (!empty($conf->global->MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND)) {
787  $out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDocOrLastGenerated").'.</label><br>';
788  } else {
789  $out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDoc").'.</label><br>';
790  }
791  }
792 
793  if (is_numeric($this->withfile)) {
794  // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
795  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
796  $out .= '<script type="text/javascript">';
797  $out .= 'jQuery(document).ready(function () {';
798  $out .= ' jQuery(".removedfile").click(function() {';
799  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
800  $out .= ' });';
801  $out .= '})';
802  $out .= '</script>'."\n";
803  if (count($listofpaths)) {
804  foreach ($listofpaths as $key => $val) {
805  $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val)));
806 
807  if ($conf->entity > 1) {
808  $relativepathtofile = str_replace($conf->entity.'/', '', $relativepathtofile);
809  }
810  // Try to extract data from full path
811  $formfile_params = array();
812  preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params);
813 
814  $out .= '<div id="attachfile_'.$key.'">';
815  // Preview of attachment
816  $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
817 
818  $out .= $formfile->showPreview(array(), $formfile_params[2], $formfile_params[4]);
819  if (!$this->withfilereadonly) {
820  $out .= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key + 1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
821  //$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
822  }
823  $out .= '<br></div>';
824  }
825  } elseif (empty($this->withmaindocfile)) {
826  //$out .= '<span class="opacitymedium">'.$langs->trans("NoAttachedFiles").'</span><br>';
827  }
828  if ($this->withfile == 2) {
829  $maxfilesizearray = getMaxFileSizeArray();
830  $maxmin = $maxfilesizearray['maxmin'];
831  if ($maxmin > 0) {
832  $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
833  }
834  // Can add other files
835  if (empty($conf->global->FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE)) {
836  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
837  } else {
838  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
839  }
840  $out .= ' ';
841  $out .= '<input type="submit" class="button smallpaddingimp" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
842  }
843  } else {
844  $out .= $this->withfile;
845  }
846 
847  $out .= "</td></tr>\n";
848  }
849 
850  // Message
851  if (!empty($this->withbody)) {
852  $defaultmessage = GETPOST('message', 'restricthtml');
853  if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
854  if ($arraydefaultmessage && $arraydefaultmessage->content) {
855  $defaultmessage = $arraydefaultmessage->content;
856  } elseif (!is_numeric($this->withbody)) {
857  $defaultmessage = $this->withbody;
858  }
859  }
860 
861  // Complete substitution array with the url to make online payment
862  $paymenturl = '';
863  $validpaymentmethod = array();
864  if (empty($this->substit['__REF__'])) {
865  $paymenturl = '';
866  } else {
867  // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
868  require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
869  $langs->loadLangs(array('paypal', 'other'));
870  $typeforonlinepayment = 'free';
871  if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') {
872  $typeforonlinepayment = 'order'; // TODO use detection on something else than template
873  }
874  if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') {
875  $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template
876  }
877  if ($this->param["models"] == 'member') {
878  $typeforonlinepayment = 'member'; // TODO use detection on something else than template
879  }
880  $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
881  $paymenturl = $url;
882 
883  $validpaymentmethod = getValidOnlinePaymentMethods('');
884  }
885 
886  if (count($validpaymentmethod) > 0 && $paymenturl) {
887  $langs->load('other');
888  $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
889  $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
890  } else {
891  $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
892  $this->substit['__ONLINE_PAYMENT_URL__'] = '';
893  }
894 
895  $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = '';
896 
897  // Add lines substitution key from each line
898  $lines = '';
899  $defaultlines = $arraydefaultmessage->content_lines;
900  if (isset($defaultlines)) {
901  foreach ($this->substit_lines as $substit_line) {
902  $lines .= make_substitutions($defaultlines, $substit_line)."\n";
903  }
904  }
905  $this->substit['__LINES__'] = $lines;
906 
907  $defaultmessage = str_replace('\n', "\n", $defaultmessage);
908 
909  // Deal with format differences between message and some substitution variables (text / HTML)
910  $atleastonecomponentishtml = 0;
911  if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
912  $atleastonecomponentishtml++;
913  }
914  if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
915  $atleastonecomponentishtml++;
916  }
917  if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
918  $atleastonecomponentishtml++;
919  }
920  if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) {
921  $atleastonecomponentishtml++;
922  }
923  if (dol_textishtml($defaultmessage)) {
924  $atleastonecomponentishtml++;
925  }
926  if ($atleastonecomponentishtml) {
927  if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
928  $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
929  }
930  if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
931  $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']);
932  }
933  if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
934  $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']);
935  }
936  if (!dol_textishtml($defaultmessage)) {
937  $defaultmessage = dol_nl2br($defaultmessage);
938  }
939  }
940 
941  if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
942  $defaultmessage = GETPOST("message", "restricthtml");
943  } else {
944  $defaultmessage = make_substitutions($defaultmessage, $this->substit);
945  // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
946  $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
947  $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
948  }
949 
950  $out .= '<tr>';
951  $out .= '<td colspan="2">';
952  $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
953  $out .= '</td>';
954  $out .= '</tr>';
955 
956  $out .= '<tr>';
957  $out .= '<td colspan="2">';
958  if ($this->withbodyreadonly) {
959  $out .= nl2br($defaultmessage);
960  $out .= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
961  } else {
962  if (!isset($this->ckeditortoolbar)) {
963  $this->ckeditortoolbar = 'dolibarr_mailings';
964  }
965 
966  // Editor wysiwyg
967  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
968  if ($this->withfckeditor == -1) {
969  if (!empty($conf->global->FCKEDITOR_ENABLE_MAIL)) {
970  $this->withfckeditor = 1;
971  } else {
972  $this->withfckeditor = 0;
973  }
974  }
975 
976  $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%');
977  $out .= $doleditor->Create(1);
978  }
979  $out .= "</td></tr>\n";
980  }
981 
982  $out .= '</table>'."\n";
983 
984  if ($this->withform == 1 || $this->withform == -1) {
985  $out .= '<div class="center">';
986  $out .= '<input type="submit" class="button button-add" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
987  // Add a javascript test to avoid to forget to submit file before sending email
988  if ($this->withfile == 2 && $conf->use_javascript_ajax) {
989  $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
990  }
991  $out .= ' />';
992  if ($this->withcancel) {
993  $out .= '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
994  }
995  $out .= '</div>'."\n";
996  }
997 
998  if ($this->withform == 1) {
999  $out .= '</form>'."\n";
1000  }
1001 
1002  // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1003  if (!empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY)) {
1004  $out .= '<script type="text/javascript">';
1005  $out .= 'jQuery(document).ready(function () {';
1006  $out .= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is called at every key pressed ! */
1007  var code = e.keyCode || e.which;
1008  if (code == 13) {
1009  console.log("Enter was intercepted and blocked");
1010  e.preventDefault();
1011  return false;
1012  }
1013  });';
1014  $out .= ' })';
1015  $out .= '</script>';
1016  }
1017 
1018  $out .= "<!-- End form mail -->\n";
1019 
1020  return $out;
1021  }
1022  }
1023 
1029  public function getHtmlForTo()
1030  {
1031  global $langs, $form;
1032  $out = '<tr><td class="fieldrequired">';
1033  if ($this->withtofree) {
1034  $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1035  } else {
1036  $out .= $langs->trans("MailTo");
1037  }
1038  $out .= '</td><td>';
1039  if ($this->withtoreadonly) {
1040  if (!empty($this->toname) && !empty($this->tomail)) {
1041  $out .= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
1042  $out .= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
1043  if ($this->totype == 'thirdparty') {
1044  $soc = new Societe($this->db);
1045  $soc->fetch($this->toid);
1046  $out .= $soc->getNomUrl(1);
1047  } elseif ($this->totype == 'contact') {
1048  $contact = new Contact($this->db);
1049  $contact->fetch($this->toid);
1050  $out .= $contact->getNomUrl(1);
1051  } else {
1052  $out .= $this->toname;
1053  }
1054  $out .= ' &lt;'.$this->tomail.'&gt;';
1055  if ($this->withtofree) {
1056  $out .= '<br>'.$langs->trans("and").' <input class="minwidth200" id="sendto" name="sendto" value="'.(!is_array($this->withto) && !is_numeric($this->withto) ? (GETPOSTISSET("sendto") ? GETPOST("sendto") : $this->withto) : "").'" />';
1057  }
1058  } else {
1059  // Note withto may be a text like 'AllRecipientSelected'
1060  $out .= (!is_array($this->withto) && !is_numeric($this->withto)) ? $this->withto : "";
1061  }
1062  } else {
1063  // The free input of email
1064  if (!empty($this->withtofree)) {
1065  $out .= '<input class="minwidth200" id="sendto" name="sendto" value="'.(($this->withtofree && !is_numeric($this->withtofree)) ? $this->withtofree : (!is_array($this->withto) && !is_numeric($this->withto) ? (GETPOSTISSET("sendto") ? GETPOST("sendto") : $this->withto) : "")).'" />';
1066  }
1067  // The select combo
1068  if (!empty($this->withto) && is_array($this->withto)) {
1069  if (!empty($this->withtofree)) {
1070  $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1071  }
1072  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1073  $tmparray = $this->withto;
1074  foreach ($tmparray as $key => $val) {
1075  $tmparray[$key] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]);
1076  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
1077  }
1078 
1079  $withtoselected = GETPOST("receiver", 'array'); // Array of selected value
1080 
1081  if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
1082  $withtoselected = array_keys($tmparray);
1083  }
1084 
1085  $out .= $form->multiselectarray("receiver", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
1086  }
1087  }
1088  $out .= "</td></tr>\n";
1089  return $out;
1090  }
1091 
1097  public function getHtmlForCc()
1098  {
1099  global $langs, $form;
1100  $out = '<tr><td>';
1101  $out .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1102  $out .= '</td><td>';
1103  if ($this->withtoccreadonly) {
1104  $out .= (!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : "";
1105  } else {
1106  $out .= '<input class="minwidth200" id="sendtocc" name="sendtocc" value="'.(GETPOST("sendtocc", "alpha") ? GETPOST("sendtocc", "alpha") : ((!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : '')).'" />';
1107  if (!empty($this->withtocc) && is_array($this->withtocc)) {
1108  $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1109  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1110  $tmparray = $this->withtocc;
1111  foreach ($tmparray as $key => $val) {
1112  $tmparray[$key] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]);
1113  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
1114  }
1115  $withtoccselected = GETPOST("receivercc", 'array'); // Array of selected value
1116  $out .= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, null, null, 'inline-block minwidth500', null, "");
1117  }
1118  }
1119  $out .= "</td></tr>\n";
1120  return $out;
1121  }
1122 
1128  public function getHtmlForWithCcc()
1129  {
1130  global $conf, $langs, $form;
1131  $out = '<tr><td>';
1132  $out .= $form->textwithpicto($langs->trans("MailCCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1133  $out .= '</td><td>';
1134  if (!empty($this->withtocccreadonly)) {
1135  $out .= (!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : "";
1136  } else {
1137  $out .= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.(GETPOSTISSET("sendtoccc") ? GETPOST("sendtoccc", "alpha") : ((!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />';
1138  if (!empty($this->withtoccc) && is_array($this->withtoccc)) {
1139  $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1140  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1141  $tmparray = $this->withtoccc;
1142  foreach ($tmparray as $key => $val) {
1143  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
1144  }
1145  $withtocccselected = GETPOST("receiverccc", 'array'); // Array of selected value
1146  $out .= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, null, null, null, null, "90%");
1147  }
1148  }
1149 
1150  $showinfobcc = '';
1151  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
1152  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO;
1153  }
1154  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
1155  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO;
1156  }
1157  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
1158  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO;
1159  }
1160  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
1161  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO;
1162  }
1163  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
1164  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO;
1165  }
1166  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) && !empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') {
1167  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO;
1168  }
1169  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO) && !empty($this->param['models']) && $this->param['models'] == 'project') {
1170  $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO;
1171  }
1172  if ($showinfobcc) {
1173  $out .= ' + '.$showinfobcc;
1174  }
1175  $out .= "</td></tr>\n";
1176  return $out;
1177  }
1178 
1184  public function getHtmlForWithErrorsTo()
1185  {
1186  global $conf, $langs;
1187  //if (! $this->errorstomail) $this->errorstomail=$this->frommail;
1188  $errorstomail = getDolGlobalString('MAIN_MAIL_ERRORS_TO', (!empty($this->errorstomail) ? $this->errorstomail : ''));
1189  if ($this->witherrorstoreadonly) {
1190  $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1191  $out .= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1192  $out .= $errorstomail;
1193  $out .= "</td></tr>\n";
1194  } else {
1195  $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1196  $out .= '<input class="minwidth200" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1197  $out .= "</td></tr>\n";
1198  }
1199  return $out;
1200  }
1201 
1207  public function getHtmlForDeliveryreceipt()
1208  {
1209  global $conf, $langs;
1210  $out = '<tr><td><label for="deliveryreceipt">'.$langs->trans("DeliveryReceipt").'</label></td><td>';
1211 
1212  if (!empty($this->withdeliveryreceiptreadonly)) {
1213  $out .= yn($this->withdeliveryreceipt);
1214  } else {
1215  $defaultvaluefordeliveryreceipt = 0;
1216  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
1217  $defaultvaluefordeliveryreceipt = 1;
1218  }
1219  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
1220  $defaultvaluefordeliveryreceipt = 1;
1221  }
1222  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
1223  $defaultvaluefordeliveryreceipt = 1;
1224  }
1225  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
1226  $defaultvaluefordeliveryreceipt = 1;
1227  }
1228  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
1229  $defaultvaluefordeliveryreceipt = 1;
1230  }
1231  //$out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1);
1232  $out .= '<input type="checkbox" id="deliveryreceipt" name="deliveryreceipt" value="1"'.((GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt) ? ' checked="checked"' : '').'>';
1233  }
1234  $out .= "</td></tr>\n";
1235  return $out;
1236  }
1237 
1245  public function getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
1246  {
1247  global $conf, $langs, $form;
1248 
1249  $defaulttopic = GETPOST('subject', 'restricthtml');
1250 
1251  if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
1252  if ($arraydefaultmessage && $arraydefaultmessage->topic) {
1253  $defaulttopic = $arraydefaultmessage->topic;
1254  } elseif (!is_numeric($this->withtopic)) {
1255  $defaulttopic = $this->withtopic;
1256  }
1257  }
1258 
1259  $defaulttopic = make_substitutions($defaulttopic, $this->substit);
1260 
1261  $out = '<tr>';
1262  $out .= '<td class="fieldrequired">';
1263  $out .= $form->textwithpicto($langs->trans('MailTopic'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
1264  $out .= '</td>';
1265  $out .= '<td>';
1266  if ($this->withtopicreadonly) {
1267  $out .= $defaulttopic;
1268  $out .= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
1269  } else {
1270  $out .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'.((GETPOSTISSET("subject") && !GETPOST('modelselected')) ? GETPOST("subject") : ($defaulttopic ? $defaulttopic : '')).'" />';
1271  }
1272  $out .= "</td></tr>\n";
1273  return $out;
1274  }
1275 
1289  public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '')
1290  {
1291  global $conf, $langs;
1292 
1293  $ret = new ModelMail();
1294 
1295  if ($id == -2 && empty($label)) {
1296  $this->error = 'LabelIsMandatoryWhenIdIs-2';
1297  return -1;
1298  }
1299 
1300  $languagetosearch = (is_object($outputlangs) ? $outputlangs->defaultlang : '');
1301  // Define $languagetosearchmain to fall back on main language (for example to get 'es_ES' for 'es_MX')
1302  $tmparray = explode('_', $languagetosearch);
1303  $languagetosearchmain = $tmparray[0].'_'.strtoupper($tmparray[0]);
1304  if ($languagetosearchmain == $languagetosearch) {
1305  $languagetosearchmain = '';
1306  }
1307 
1308  $sql = "SELECT rowid, module, label, type_template, topic, joinfiles, content, content_lines, lang, email_from, email_to, email_tocc, email_tobcc";
1309  $sql .= " FROM ".$dbs->prefix().'c_email_templates';
1310  $sql .= " WHERE (type_template = '".$dbs->escape($type_template)."' OR type_template = 'all')";
1311  $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1312  $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // Get all public or private owned
1313  if ($active >= 0) {
1314  $sql .= " AND active = ".((int) $active);
1315  }
1316  if ($label) {
1317  $sql .= " AND label = '".$dbs->escape($label)."'";
1318  }
1319  if (!($id > 0) && $languagetosearch) {
1320  $sql .= " AND (lang = '".$dbs->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$dbs->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
1321  }
1322  if ($id > 0) {
1323  $sql .= " AND rowid=".(int) $id;
1324  }
1325  if ($id == -1) {
1326  $sql .= " AND position=0";
1327  }
1328  if ($languagetosearch) {
1329  $sql .= $dbs->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or ''
1330  } else {
1331  $sql .= $dbs->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined
1332  }
1333  //$sql .= $dbs->plimit(1);
1334  //print $sql;
1335 
1336  $resql = $dbs->query($sql);
1337  if (!$resql) {
1338  dol_print_error($dbs);
1339  return -1;
1340  }
1341 
1342  // Get first found
1343  while (1) {
1344  $obj = $dbs->fetch_object($resql);
1345 
1346  if ($obj) {
1347  // If template is for a module, check module is enabled; if not, take next template
1348  if ($obj->module) {
1349  $tempmodulekey = $obj->module;
1350  if (empty($conf->$tempmodulekey) || empty($conf->$tempmodulekey->enabled)) {
1351  continue;
1352  }
1353  }
1354 
1355  // If a record was found
1356  $ret->id = $obj->rowid;
1357  $ret->module = $obj->module;
1358  $ret->label = $obj->label;
1359  $ret->lang = $obj->lang;
1360  $ret->topic = $obj->topic;
1361  $ret->content = $obj->content;
1362  $ret->content_lines = $obj->content_lines;
1363  $ret->joinfiles = $obj->joinfiles;
1364 
1365  break;
1366  } else {
1367  // If no record found
1368  if ($id == -2) {
1369  // Not found with the provided label
1370  return -1;
1371  } else {
1372  // If there is no template at all
1373  $defaultmessage = '';
1374 
1375  if ($type_template == 'body') {
1376  // Special case to use this->withbody as content
1377  $defaultmessage = $this->withbody;
1378  } elseif ($type_template == 'facture_send') {
1379  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoice");
1380  } elseif ($type_template == 'facture_relance') {
1381  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder");
1382  } elseif ($type_template == 'propal_send') {
1383  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendProposal");
1384  } elseif ($type_template == 'supplier_proposal_send') {
1385  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal");
1386  } elseif ($type_template == 'order_send') {
1387  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendOrder");
1388  } elseif ($type_template == 'order_supplier_send') {
1389  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder");
1390  } elseif ($type_template == 'invoice_supplier_send') {
1391  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice");
1392  } elseif ($type_template == 'shipping_send') {
1393  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendShipping");
1394  } elseif ($type_template == 'fichinter_send') {
1395  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendFichInter");
1396  } elseif ($type_template == 'actioncomm_send') {
1397  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm");
1398  } elseif (!empty($type_template)) {
1399  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric");
1400  }
1401 
1402  $ret->label = 'default';
1403  $ret->lang = $outputlangs->defaultlang;
1404  $ret->topic = '';
1405  $ret->joinfiles = 1;
1406  $ret->content = $defaultmessage;
1407  $ret->content_lines = '';
1408 
1409  break;
1410  }
1411  }
1412  }
1413 
1414  $dbs->free($resql);
1415 
1416  return $ret;
1417  }
1418 
1428  public function isEMailTemplate($type_template, $user, $outputlangs)
1429  {
1430  $sql = "SELECT label, topic, content, lang";
1431  $sql .= " FROM ".$this->db->prefix().'c_email_templates';
1432  $sql .= " WHERE type_template='".$this->db->escape($type_template)."'";
1433  $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1434  $sql .= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".((int) $user->id).")";
1435  if (is_object($outputlangs)) {
1436  $sql .= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
1437  }
1438  $sql .= $this->db->order("lang,label", "ASC");
1439  //print $sql;
1440 
1441  $resql = $this->db->query($sql);
1442  if ($resql) {
1443  $num = $this->db->num_rows($resql);
1444  $this->db->free($resql);
1445  return $num;
1446  } else {
1447  $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1448  return -1;
1449  }
1450  }
1451 
1462  public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active = 1)
1463  {
1464  global $conf;
1465 
1466  $sql = "SELECT rowid, module, label, topic, content, content_lines, lang, fk_user, private, position";
1467  $sql .= " FROM ".$this->db->prefix().'c_email_templates';
1468  $sql .= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1469  $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1470  $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // See all public templates or templates I own.
1471  if ($active >= 0) {
1472  $sql .= " AND active = ".((int) $active);
1473  }
1474  //if (is_object($outputlangs)) $sql.= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')"; // Return all languages
1475  $sql .= $this->db->order("position,lang,label", "ASC");
1476  //print $sql;
1477 
1478  $resql = $this->db->query($sql);
1479  if ($resql) {
1480  $num = $this->db->num_rows($resql);
1481  $this->lines_model = array();
1482  while ($obj = $this->db->fetch_object($resql)) {
1483  // If template is for a module, check module is enabled.
1484  if ($obj->module) {
1485  $tempmodulekey = $obj->module;
1486  if (empty($conf->$tempmodulekey) || empty($conf->$tempmodulekey->enabled)) {
1487  continue;
1488  }
1489  }
1490 
1491  $line = new ModelMail();
1492  $line->id = $obj->rowid;
1493  $line->label = $obj->label;
1494  $line->lang = $obj->lang;
1495  $line->fk_user = $obj->fk_user;
1496  $line->private = $obj->private;
1497  $line->position = $obj->position;
1498  $line->topic = $obj->topic;
1499  $line->content = $obj->content;
1500  $line->content_lines = $obj->content_lines;
1501 
1502  $this->lines_model[] = $line;
1503  }
1504  $this->db->free($resql);
1505  return $num;
1506  } else {
1507  $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1508  return -1;
1509  }
1510  }
1511 
1512 
1513 
1522  public function setSubstitFromObject($object, $outputlangs)
1523  {
1524  global $conf, $user, $extrafields;
1525 
1526  $parameters = array();
1527  $tmparray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
1528  complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
1529 
1530  $this->substit = $tmparray;
1531 
1532  // Fill substit_lines with each object lines content
1533  if (is_array($object->lines)) {
1534  foreach ($object->lines as $line) {
1535  $substit_line = array(
1536  '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1537  '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1538  '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1539  '__LABEL__' => isset($line->label) ? $line->label : '',
1540  '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1541  '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
1542  '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
1543  '__QUANTITY__' => $line->qty,
1544  '__SUBPRICE__' => price($line->subprice),
1545  '__AMOUNT__' => price($line->total_ttc),
1546  '__AMOUNT_EXCL_TAX__' => price($line->total_ht)
1547  );
1548 
1549  // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1550  if (!empty($line->fk_product)) {
1551  if (!is_object($extrafields)) {
1552  $extrafields = new ExtraFields($this->db);
1553  }
1554  $product = new Product($this->db);
1555  $product->fetch($line->fk_product, '', '', 1);
1556  $product->fetch_optionals();
1557 
1558  $extrafields->fetch_name_optionals_label($product->table_element, true);
1559 
1560  if (!empty($extrafields->attributes[$product->table_element]['label']) && is_array($extrafields->attributes[$product->table_element]['label']) && count($extrafields->attributes[$product->table_element]['label']) > 0) {
1561  foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
1562  $substit_line['__PRODUCT_EXTRAFIELD_'.strtoupper($key).'__'] = isset($product->array_options['options_'.$key]) ? $product->array_options['options_'.$key] : '';
1563  }
1564  }
1565  }
1566  $this->substit_lines[] = $substit_line;
1567  }
1568  }
1569  }
1570 
1579  public static function getAvailableSubstitKey($mode = 'formemail', $object = null)
1580  {
1581  global $conf, $langs;
1582 
1583  $tmparray = array();
1584  if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines') {
1585  $parameters = array('mode'=>$mode);
1586  $tmparray = getCommonSubstitutionArray($langs, 2, null, $object); // Note: On email templated edition, this is null because it is related to all type of objects
1587  complete_substitutions_array($tmparray, $langs, null, $parameters);
1588 
1589  if ($mode == 'formwithlines') {
1590  $tmparray['__LINES__'] = '__LINES__'; // Will be set by the get_form function
1591  }
1592  if ($mode == 'formforlines') {
1593  $tmparray['__QUANTITY__'] = '__QUANTITY__'; // Will be set by the get_form function
1594  }
1595  }
1596 
1597  if ($mode == 'emailing') {
1598  $parameters = array('mode'=>$mode);
1599  $tmparray = getCommonSubstitutionArray($langs, 2, array('object', 'objectamount'), $object); // Note: On email templated edition, this is null because it is related to all type of objects
1600  complete_substitutions_array($tmparray, $langs, null, $parameters);
1601 
1602  // For mass emailing, we have different keys
1603  $tmparray['__ID__'] = 'IdRecord';
1604  $tmparray['__THIRDPARTY_CUSTOMER_CODE__'] = 'CustomerCode';
1605  $tmparray['__EMAIL__'] = 'EMailRecipient';
1606  $tmparray['__LASTNAME__'] = 'Lastname';
1607  $tmparray['__FIRSTNAME__'] = 'Firstname';
1608  $tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
1609  $tmparray['__OTHER1__'] = 'Other1';
1610  $tmparray['__OTHER2__'] = 'Other2';
1611  $tmparray['__OTHER3__'] = 'Other3';
1612  $tmparray['__OTHER4__'] = 'Other4';
1613  $tmparray['__OTHER5__'] = 'Other5';
1614  $tmparray['__USER_SIGNATURE__'] = 'TagUserSignature';
1615  $tmparray['__SENDEREMAIL_SIGNATURE__'] = 'TagEmailSenderSignature';
1616  $tmparray['__CHECK_READ__'] = 'TagCheckMail';
1617  $tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe';
1618  //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing
1619 
1620  $onlinepaymentenabled = 0;
1621  if (isModEnabled('paypal')) {
1622  $onlinepaymentenabled++;
1623  }
1624  if (isModEnabled('paybox')) {
1625  $onlinepaymentenabled++;
1626  }
1627  if (isModEnabled('stripe')) {
1628  $onlinepaymentenabled++;
1629  }
1630  if ($onlinepaymentenabled && !empty($conf->global->PAYMENT_SECURITY_TOKEN)) {
1631  $tmparray['__SECUREKEYPAYMENT__'] = $conf->global->PAYMENT_SECURITY_TOKEN;
1632  if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) {
1633  if (isModEnabled('adherent')) {
1634  $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
1635  }
1636  if (isModEnabled('don')) {
1637  $tmparray['__SECUREKEYPAYMENT_DONATION__'] = 'SecureKeyPAYMENTUniquePerDonation';
1638  }
1639  if (isModEnabled('facture')) {
1640  $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
1641  }
1642  if (isModEnabled('commande')) {
1643  $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
1644  }
1645  if (isModEnabled('contrat')) {
1646  $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
1647  }
1648 
1649  //Online payement link
1650  if (isModEnabled('adherent')) {
1651  $tmparray['__ONLINEPAYMENTLINK_MEMBER__'] = 'OnlinePaymentLinkUniquePerMember';
1652  }
1653  if (isModEnabled('don')) {
1654  $tmparray['__ONLINEPAYMENTLINK_DONATION__'] = 'OnlinePaymentLinkUniquePerDonation';
1655  }
1656  if (isModEnabled('facture')) {
1657  $tmparray['__ONLINEPAYMENTLINK_INVOICE__'] = 'OnlinePaymentLinkUniquePerInvoice';
1658  }
1659  if (isModEnabled('commande')) {
1660  $tmparray['__ONLINEPAYMENTLINK_ORDER__'] = 'OnlinePaymentLinkUniquePerOrder';
1661  }
1662  if (isModEnabled('contrat')) {
1663  $tmparray['__ONLINEPAYMENTLINK_CONTRACTLINE__'] = 'OnlinePaymentLinkUniquePerContractLine';
1664  }
1665  }
1666  } else {
1667  /* No need to show into tooltip help, option is not enabled
1668  $vars['__SECUREKEYPAYMENT__']='';
1669  $vars['__SECUREKEYPAYMENT_MEMBER__']='';
1670  $vars['__SECUREKEYPAYMENT_INVOICE__']='';
1671  $vars['__SECUREKEYPAYMENT_ORDER__']='';
1672  $vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
1673  */
1674  }
1675  if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
1676  $substitutionarray['__PUBLICLINK_NEWMEMBERFORM__'] = 'BlankSubscriptionForm';
1677  }
1678  }
1679 
1680  foreach ($tmparray as $key => $val) {
1681  if (empty($val)) {
1682  $tmparray[$key] = $key;
1683  }
1684  }
1685 
1686  return $tmparray;
1687  }
1688 }
1689 
1690 
1696 class ModelMail
1697 {
1701  public $id;
1702 
1706  public $label;
1707 
1711  public $fk_user;
1712 
1716  public $private;
1717 
1721  public $topic;
1722 
1726  public $content;
1727  public $content_lines;
1728  public $lang;
1729  public $joinfiles;
1730 
1731  public $email_from;
1732  public $email_to;
1733  public $email_tocc;
1734  public $email_tobcc;
1735 
1739  public $module;
1740 
1744  public $position;
1745 }
Class to manage a WYSIWYG editor.
Class to manage generation of HTML components Only common components must be here.
static selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='minwidth75', $addjscombo=1, $moreparamonempty='', $disablebademail=0, $nohtmlescape=0)
Return a HTML select string, built from an array of key+value.
Classe permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new For...
get_attached_files()
Return list of attached files (stored in SECTION array)
getHtmlForWithErrorsTo()
get Html For WithErrorsTo
getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
get Html For Topic of message
clear_attached_files()
Clear list of attached files in send mail form (also stored in session)
fetchAllEMailTemplate($type_template, $user, $outputlangs, $active=1)
Find if template exists and are available for current user, then set them into $this->lines_module.
getHtmlForCc()
get html For CC
getHtmlForTo()
get html For To
add_attached_files($path, $file='', $type='')
Add a file into the list of attached files (stored in SECTION array)
getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id=0, $active=1, $label='')
Return templates of email with type = $type_template or type = 'all'.
getHtmlForWithCcc()
get html For WithCCC
remove_attached_files($keytodelete)
Remove a file from the list of attached files (stored in SECTION array)
__construct($db)
Constructor.
show_form($addfileaction='addfile', $removefileaction='removefile')
Show the form to input an email this->withfile: 0=No attaches files, 1=Show attached files,...
get_form($addfileaction='addfile', $removefileaction='removefile')
Get the form to input an email this->withfile: 0=No attaches files, 1=Show attached files,...
Class to manage translations.
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
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
Definition: files.lib.php:1401
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.
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
dol_htmlentities($string, $flags=ENT_QUOTES|ENT_SUBSTITUTE, $encoding='UTF-8', $double_encode=false)
Replace htmlentities functions.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information for admin users or standard users.
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
table tableforfield button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
Definition: style.css.php:843
getMaxFileSizeArray()
Return the max allowed for file upload.
$conf db
API class for accounts.
Definition: inc.php:41