dolibarr  13.0.2
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-2019 Frédéric France <frederic.france@netlogic.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  */
22 
28 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
29 
30 
37 class FormMail extends Form
38 {
42  public $db;
43 
49  public $withform;
50 
54  public $fromname;
55 
59  public $frommail;
60 
64  public $fromtype;
65 
69  public $fromid;
70 
74  public $fromalsorobot;
75 
79  public $totype;
80 
84  public $toid;
85 
89  public $replytoname;
90 
94  public $replytomail;
95 
99  public $toname;
100 
104  public $tomail;
105 
109  public $trackid;
110 
111  public $withsubstit; // Show substitution array
112  public $withfrom;
113 
117  public $withto; // Show recipient emails
118 
119  public $withtofree; // Show free text for recipient emails
120  public $withtocc;
121  public $withtoccc;
122  public $withtopic;
123  public $withfile; // 0=No attaches files, 1=Show attached files, 2=Can add new attached files
124  public $withmaindocfile; // 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
125  public $withbody;
126 
127  public $withfromreadonly;
128  public $withreplytoreadonly;
129  public $withtoreadonly;
130  public $withtoccreadonly;
131  public $withtocccreadonly;
132  public $withtopicreadonly;
133  public $withfilereadonly;
134  public $withdeliveryreceipt;
135  public $withcancel;
136  public $withfckeditor;
137 
138  public $substit = array();
139  public $substit_lines = array();
140  public $param = array();
141 
142  public $withtouser = array();
143  public $withtoccuser = array();
144 
145  public $lines_model;
146 
147 
153  public function __construct($db)
154  {
155  $this->db = $db;
156 
157  $this->withform = 1;
158 
159  $this->withfrom = 1;
160  $this->withto = 1;
161  $this->withtofree = 1;
162  $this->withtocc = 1;
163  $this->withtoccc = 0;
164  $this->witherrorsto = 0;
165  $this->withtopic = 1;
166  $this->withfile = 0; // 1=Add section "Attached files". 2=Can add files.
167  $this->withmaindocfile = 0; // 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
168  $this->withbody = 1;
169 
170  $this->withfromreadonly = 1;
171  $this->withreplytoreadonly = 1;
172  $this->withtoreadonly = 0;
173  $this->withtoccreadonly = 0;
174  $this->withtocccreadonly = 0;
175  $this->witherrorstoreadonly = 0;
176  $this->withtopicreadonly = 0;
177  $this->withfilereadonly = 0;
178  $this->withbodyreadonly = 0;
179  $this->withdeliveryreceiptreadonly = 0;
180  $this->withfckeditor = -1; // -1 = Auto
181  }
182 
183  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
189  public function clear_attached_files()
190  {
191  // phpcs:enable
192  global $conf, $user;
193  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
194 
195  // Set tmp user directory
196  $vardir = $conf->user->dir_output."/".$user->id;
197  $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
198  if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir);
199 
200  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
201  unset($_SESSION["listofpaths".$keytoavoidconflict]);
202  unset($_SESSION["listofnames".$keytoavoidconflict]);
203  unset($_SESSION["listofmimes".$keytoavoidconflict]);
204  }
205 
206  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
215  public function add_attached_files($path, $file = '', $type = '')
216  {
217  // phpcs:enable
218  $listofpaths = array();
219  $listofnames = array();
220  $listofmimes = array();
221 
222  if (empty($file)) $file = basename($path);
223  if (empty($type)) $type = dol_mimetype($file);
224 
225  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
226  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
227  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
228  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
229  if (!in_array($file, $listofnames))
230  {
231  $listofpaths[] = $path;
232  $listofnames[] = $file;
233  $listofmimes[] = $type;
234  $_SESSION["listofpaths".$keytoavoidconflict] = join(';', $listofpaths);
235  $_SESSION["listofnames".$keytoavoidconflict] = join(';', $listofnames);
236  $_SESSION["listofmimes".$keytoavoidconflict] = join(';', $listofmimes);
237  }
238  }
239 
240  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
247  public function remove_attached_files($keytodelete)
248  {
249  // phpcs:enable
250  $listofpaths = array();
251  $listofnames = array();
252  $listofmimes = array();
253 
254  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
255  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
256  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
257  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
258  if ($keytodelete >= 0)
259  {
260  unset($listofpaths[$keytodelete]);
261  unset($listofnames[$keytodelete]);
262  unset($listofmimes[$keytodelete]);
263  $_SESSION["listofpaths".$keytoavoidconflict] = join(';', $listofpaths);
264  $_SESSION["listofnames".$keytoavoidconflict] = join(';', $listofnames);
265  $_SESSION["listofmimes".$keytoavoidconflict] = join(';', $listofmimes);
266  //var_dump($_SESSION['listofpaths']);
267  }
268  }
269 
270  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
276  public function get_attached_files()
277  {
278  // phpcs:enable
279  $listofpaths = array();
280  $listofnames = array();
281  $listofmimes = array();
282 
283  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
284  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
285  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
286  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
287  return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
288  }
289 
290  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
301  public function show_form($addfileaction = 'addfile', $removefileaction = 'removefile')
302  {
303  // phpcs:enable
304  print $this->get_form($addfileaction, $removefileaction);
305  }
306 
307  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
318  public function get_form($addfileaction = 'addfile', $removefileaction = 'removefile')
319  {
320  // phpcs:enable
321  global $conf, $langs, $user, $hookmanager, $form;
322 
323  // Required to show preview of mail attachments
324  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
325  $formfile = new Formfile($this->db);
326 
327  if (!is_object($form)) $form = new Form($this->db);
328 
329  // Load translation files required by the page
330  $langs->loadLangs(array('other', 'mails'));
331 
332  // Clear temp files. Must be done before call of triggers, at beginning (mode = init), or when we select a new template
333  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
334  $this->clear_attached_files();
335  }
336 
337  // Call hook getFormMail
338  $hookmanager->initHooks(array('formmail'));
339 
340  $parameters = array(
341  'addfileaction' => $addfileaction,
342  'removefileaction'=> $removefileaction,
343  'trackid'=> $this->trackid
344  );
345  $reshook = $hookmanager->executeHooks('getFormMail', $parameters, $this);
346 
347  if (!empty($reshook))
348  {
349  return $hookmanager->resPrint;
350  } else {
351  $out = '';
352 
353  $disablebademails = 1;
354 
355  // Define output language
356  $outputlangs = $langs;
357  $newlang = '';
358  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $this->param['langsmodels'];
359  if (!empty($newlang))
360  {
361  $outputlangs = new Translate("", $conf);
362  $outputlangs->setDefaultLang($newlang);
363  $outputlangs->load('other');
364  }
365 
366  // Get message template for $this->param["models"] into c_email_templates
367  $arraydefaultmessage = -1;
368  if ($this->param['models'] != 'none')
369  {
370  $model_id = 0;
371  if (array_key_exists('models_id', $this->param))
372  {
373  $model_id = $this->param["models_id"];
374  }
375 
376  $arraydefaultmessage = $this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one
377  }
378 
379  // Define list of attached files
380  $listofpaths = array();
381  $listofnames = array();
382  $listofmimes = array();
383  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
384 
385  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1'))
386  {
387  if (!empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit']))
388  {
389  foreach ($this->param['fileinit'] as $file)
390  {
391  $this->add_attached_files($file, basename($file), dol_mimetype($file));
392  }
393  }
394  }
395 
396  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
397  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
398  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
399 
400 
401  $out .= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
402  if ($this->withform == 1)
403  {
404  $out .= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
405 
406  $out .= '<a id="formmail" name="formmail"></a>';
407  $out .= '<input style="display:none" type="submit" id="sendmail" name="sendmail">';
408  $out .= '<input type="hidden" name="token" value="'.newToken().'" />';
409  $out .= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
410  }
411  if (!empty($this->withfrom))
412  {
413  if (!empty($this->withfromreadonly))
414  {
415  $out .= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
416  $out .= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
417  }
418  }
419  foreach ($this->param as $key=>$value)
420  {
421  if (is_array($value)) {
422  $out .= "<!-- param key=".$key." is array, we do not output input filed for it -->\n";
423  } else {
424  $out .= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
425  }
426  }
427 
428  $modelmail_array = array();
429  if ($this->param['models'] != 'none')
430  {
431  $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
432 
433  if ($result < 0)
434  {
435  setEventMessages($this->error, $this->errors, 'errors');
436  }
437  $langs->trans("members");
438  foreach ($this->lines_model as $line)
439  {
440  $reg = array();
441  if (preg_match('/\((.*)\)/', $line->label, $reg)) {
442  $labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__
443  } else {
444  $labeltouse = $line->label;
445  }
446 
447  // We escape the $labeltouse to store it into $modelmail_array.
448  $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse);
449  if ($line->lang) $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang);
450  if ($line->private) $modelmail_array[$line->id] .= ' - <span class="opacitymedium">'.dol_escape_htmltag($langs->trans("Private")).'</span>';
451  }
452  }
453 
454  // Zone to select email template
455  if (count($modelmail_array) > 0)
456  {
457  $model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOST('modelmailselected', 'int') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0);
458 
459  // If list of template is filled
460  $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
461 
462  $out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
463  $out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1);
464  if ($user->admin) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
465  $out .= ' &nbsp; ';
466  $out .= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
467  $out .= ' &nbsp; ';
468  $out .= '</div>';
469  } elseif (!empty($this->param['models']) && in_array($this->param['models'], array(
470  'propal_send', 'order_send', 'facture_send',
471  'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send',
472  'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'all'
473  )))
474  {
475  // If list of template is empty
476  $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
477  $out .= $langs->trans('SelectMailModel').': <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.
478  if ($user->admin) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
479  $out .= ' &nbsp; ';
480  $out .= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
481  $out .= ' &nbsp; ';
482  $out .= '</div>';
483  } else {
484  $out .= '<!-- No template available for $this->param["models"] = '.$this->param['models'].' -->';
485  }
486 
487 
488  $out .= '<table class="tableforemailform boxtablenotop" width="100%">'."\n";
489 
490  // Substitution array/string
491  $helpforsubstitution = '';
492  if (is_array($this->substit) && count($this->substit)) $helpforsubstitution .= $langs->trans('AvailableVariables').' :<br>'."\n";
493  foreach ($this->substit as $key => $val)
494  {
495  $helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))).'<br>';
496  }
497  if (!empty($this->withsubstit)) // Unset or set ->withsubstit=0 to disable this.
498  {
499  $out .= '<tr><td colspan="2" class="right">';
500  //$out.='<div class="floatright">';
501  if (is_numeric($this->withsubstit)) $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
502  else $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
503  $out .= "</td></tr>\n";
504  //$out.='</div>';
505  }
506 
507  /*var_dump(! empty($this->withfromreadonly));
508  var_dump($this->withfrom);
509  var_dump($this->fromtype);
510  var_dump($this->fromname);*/
511 
512  // From
513  if (!empty($this->withfrom))
514  {
515  if (!empty($this->withfromreadonly))
516  {
517  $out .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
518 
519  // $this->fromtype is the default value to use to select sender
520  if (!($this->fromtype === 'user' && $this->fromid > 0)
521  && !($this->fromtype === 'company')
522  && !($this->fromtype === 'robot')
523  && !preg_match('/user_aliases/', $this->fromtype)
524  && !preg_match('/global_aliases/', $this->fromtype)
525  && !preg_match('/senderprofile/', $this->fromtype)
526  )
527  {
528  // Use this->fromname and this->frommail or error if not defined
529  $out .= $this->fromname;
530  if ($this->frommail)
531  {
532  $out .= ' &lt;'.$this->frommail.'&gt;';
533  } else {
534  if ($this->fromtype)
535  {
536  $langs->load('errors');
537  $out .= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
538  }
539  }
540  } else {
541  $liste = array();
542 
543  // Add user email
544  if (empty($user->email))
545  {
546  $langs->load('errors');
547  $liste['user'] = $user->getFullName($langs).' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
548  } else {
549  $liste['user'] = $user->getFullName($langs).' &lt;'.$user->email.'&gt;';
550  }
551 
552  // Add also company main email
553  $liste['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM.' &lt;'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'&gt;';
554 
555  // Add also email aliases if there is some
556  $listaliases = array('user_aliases'=>$user->email_aliases, 'global_aliases'=>$conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
557 
558  // Also add robot email
559  if (!empty($this->fromalsorobot))
560  {
561  if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && $conf->global->MAIN_MAIL_EMAIL_FROM != $conf->global->MAIN_INFO_SOCIETE_MAIL)
562  {
563  $liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM;
564  if ($this->frommail)
565  {
566  $liste['robot'] .= ' &lt;'.$conf->global->MAIN_MAIL_EMAIL_FROM.'&gt;';
567  }
568  }
569  }
570 
571  // Add also email aliases from the c_email_senderprofile table
572  $sql = 'SELECT rowid, label, email FROM '.MAIN_DB_PREFIX.'c_email_senderprofile';
573  $sql .= ' WHERE active = 1 AND (private = 0 OR private = '.$user->id.')';
574  $sql .= ' ORDER BY position';
575  $resql = $this->db->query($sql);
576  if ($resql)
577  {
578  $num = $this->db->num_rows($resql);
579  $i = 0;
580  while ($i < $num)
581  {
582  $obj = $this->db->fetch_object($resql);
583  if ($obj)
584  {
585  $listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
586  }
587  $i++;
588  }
589  } else dol_print_error($this->db);
590 
591  foreach ($listaliases as $typealias => $listalias)
592  {
593  $posalias = 0;
594  $listaliasarray = explode(',', $listalias);
595  foreach ($listaliasarray as $listaliasval)
596  {
597  $posalias++;
598  $listaliasval = trim($listaliasval);
599  if ($listaliasval)
600  {
601  $listaliasval = preg_replace('/</', '&lt;', $listaliasval);
602  $listaliasval = preg_replace('/>/', '&gt;', $listaliasval);
603  if (!preg_match('/&lt;/', $listaliasval)) $listaliasval = '&lt;'.$listaliasval.'&gt;';
604  $liste[$typealias.'_'.$posalias] = $listaliasval;
605  }
606  }
607  }
608 
609  // Set the default "From"
610  $defaultfrom = '';
611  $reshook = $hookmanager->executeHooks('getDefaultFromEmail', $parameters, $this);
612  if (empty($reshook))
613  {
614  $defaultfrom = $this->fromtype;
615  }
616  if (!empty($hookmanager->resArray['defaultfrom'])) $defaultfrom = $hookmanager->resArray['defaultfrom'];
617 
618  // Using combo here make the '<email>' no more visible on list.
619  //$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
620  $out .= ' '.$form->selectarray('fromtype', $liste, $defaultfrom, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 0, '', $disablebademails);
621  }
622 
623  $out .= "</td></tr>\n";
624  } else {
625  $out .= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
626  $out .= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
627  $out .= '&nbsp; &nbsp; ';
628  $out .= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
629  $out .= "</td></tr>\n";
630  }
631  }
632 
633  // To
634  if (!empty($this->withto) || is_array($this->withto))
635  {
636  $out .= '<tr><td class="fieldrequired">';
637  if ($this->withtofree) $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
638  else $out .= $langs->trans("MailTo");
639  $out .= '</td><td>';
640  if ($this->withtoreadonly)
641  {
642  if (!empty($this->toname) && !empty($this->tomail))
643  {
644  $out .= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
645  $out .= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
646  if ($this->totype == 'thirdparty')
647  {
648  $soc = new Societe($this->db);
649  $soc->fetch($this->toid);
650  $out .= $soc->getNomUrl(1);
651  } elseif ($this->totype == 'contact')
652  {
653  $contact = new Contact($this->db);
654  $contact->fetch($this->toid);
655  $out .= $contact->getNomUrl(1);
656  } else {
657  $out .= $this->toname;
658  }
659  $out .= ' &lt;'.$this->tomail.'&gt;';
660  if ($this->withtofree)
661  {
662  $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) : "").'" />';
663  }
664  } else {
665  // Note withto may be a text like 'AllRecipientSelected'
666  $out .= (!is_array($this->withto) && !is_numeric($this->withto)) ? $this->withto : "";
667  }
668  } else {
669  // The free input of email
670  if (!empty($this->withtofree))
671  {
672  $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) : "")).'" />';
673  }
674  // The select combo
675  if (!empty($this->withto) && is_array($this->withto))
676  {
677  if (!empty($this->withtofree)) $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
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->withto;
680  foreach ($tmparray as $key => $val)
681  {
682  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
683  }
684 
685  $withtoselected = GETPOST("receiver", 'array'); // Array of selected value
686 
687  if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend')
688  {
689  $withtoselected = array_keys($tmparray);
690  }
691  $out .= $form->multiselectarray("receiver", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
692  }
693  }
694  $out .= "</td></tr>\n";
695  }
696 
697  // To User
698  if (!empty($this->withtouser) && is_array($this->withtouser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT))
699  {
700  $out .= '<tr><td>';
701  $out .= $langs->trans("MailToUsers");
702  $out .= '</td><td>';
703 
704  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
705  $tmparray = $this->withtouser;
706  foreach ($tmparray as $key => $val)
707  {
708  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
709  }
710  $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value
711  if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend')
712  {
713  $withtoselected = array_keys($tmparray);
714  }
715  $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
716  $out .= "</td></tr>\n";
717  }
718 
719  // With option one email per recipient
720  if (!empty($this->withoptiononeemailperrecipient))
721  {
722  $out .= '<tr><td class="minwidth200">';
723  $out .= $langs->trans("GroupEmails");
724  $out .= '</td><td>';
725  $out .= ' <input type="checkbox" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> ';
726  $out .= $langs->trans("OneEmailPerRecipient");
727  $out .= '<span class="hideonsmartphone">';
728  $out .= ' - ';
729  $out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
730  $out .= '</span>';
731  $out .= '</td></tr>';
732  }
733 
734  // CC
735  if (!empty($this->withtocc) || is_array($this->withtocc))
736  {
737  $out .= '<tr><td>';
738  $out .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
739  $out .= '</td><td>';
740  if ($this->withtoccreadonly)
741  {
742  $out .= (!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : "";
743  } else {
744  $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 : '')).'" />';
745  if (!empty($this->withtocc) && is_array($this->withtocc))
746  {
747  $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
748  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
749  $tmparray = $this->withtocc;
750  foreach ($tmparray as $key => $val)
751  {
752  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
753  }
754  $withtoccselected = GETPOST("receivercc", 'array'); // Array of selected value
755  $out .= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, null, null, 'inline-block minwidth500', null, "");
756  }
757  }
758  $out .= "</td></tr>\n";
759  }
760 
761  // To User cc
762  if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT))
763  {
764  $out .= '<tr><td>';
765  $out .= $langs->trans("MailToCCUsers");
766  $out .= '</td><td>';
767 
768  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
769  $tmparray = $this->withtoccuser;
770  foreach ($tmparray as $key => $val)
771  {
772  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
773  }
774  $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value
775  if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend')
776  {
777  $withtoselected = array_keys($tmparray);
778  }
779  $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
780  $out .= "</td></tr>\n";
781  }
782 
783  // CCC
784  if (!empty($this->withtoccc) || is_array($this->withtoccc)) {
785  $out .= $this->getHtmlForWithCcc();
786  }
787 
788  // Replyto
789  if (!empty($this->withreplyto))
790  {
791  if ($this->withreplytoreadonly)
792  {
793  $out .= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
794  $out .= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
795  $out .= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail ? (" &lt;".$this->replytomail."&gt;") : "");
796  $out .= "</td></tr>\n";
797  }
798  }
799 
800  // Errorsto
801  if (!empty($this->witherrorsto)) {
802  $out .= $this->getHtmlForWithErrorsTo();
803  }
804 
805  // Ask delivery receipt
806  if (!empty($this->withdeliveryreceipt)) {
807  $out .= $this->getHtmlForDeliveryReceipt();
808  }
809 
810  // Topic
811  if (!empty($this->withtopic)) {
812  $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution);
813  }
814 
815  // Attached files
816  if (!empty($this->withfile))
817  {
818  $out .= '<tr>';
819  $out .= '<td>'.$langs->trans("MailFile").'</td>';
820 
821  $out .= '<td>';
822 
823  if ($this->withmaindocfile) // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
824  {
825  if (GETPOSTISSET('sendmail'))
826  {
827  $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
828  }
829  // If a template was selected, we use setup of template to define if join file checkbox is selected or not.
830  elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0)
831  {
832  $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
833  }
834  }
835 
836  if (!empty($this->withmaindocfile))
837  {
838  if ($this->withmaindocfile == 1)
839  {
840  $out .= '<input type="checkbox" name="addmaindocfile" value="1" />';
841  }
842  if ($this->withmaindocfile == -1)
843  {
844  $out .= '<input type="checkbox" name="addmaindocfile" value="1" checked="checked" />';
845  }
846  $out .= ' '.$langs->trans("JoinMainDoc").'.<br>';
847  }
848 
849  if (is_numeric($this->withfile))
850  {
851  // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
852  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
853  $out .= '<script type="text/javascript" language="javascript">';
854  $out .= 'jQuery(document).ready(function () {';
855  $out .= ' jQuery(".removedfile").click(function() {';
856  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
857  $out .= ' });';
858  $out .= '})';
859  $out .= '</script>'."\n";
860  if (count($listofpaths))
861  {
862  foreach ($listofpaths as $key => $val)
863  {
864  $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val)));
865  if ($conf->entity > 1) {
866  $relativepathtofile = str_replace($conf->entity.'/', '', $relativepathtofile);
867  }
868  // Try to extract data from full path
869  $formfile_params = array();
870  preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params);
871 
872  $out .= '<div id="attachfile_'.$key.'">';
873  // Preview of attachment
874  $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
875  $out .= $formfile->showPreview(array(), $formfile_params[2], $formfile_params[4]);
876  if (!$this->withfilereadonly)
877  {
878  $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.'" />';
879  //$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
880  }
881  $out .= '<br></div>';
882  }
883  } elseif (empty($this->withmaindocfile)) // Do not show message if we asked to show the checkbox
884  {
885  $out .= $langs->trans("NoAttachedFiles").'<br>';
886  }
887  if ($this->withfile == 2) // Can add other files
888  {
889  if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) $out .= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
890  else $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
891  $out .= ' ';
892  $out .= '<input class="button" type="submit" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
893  }
894  } else {
895  $out .= $this->withfile;
896  }
897 
898  $out .= "</td></tr>\n";
899  }
900 
901  // Message
902  if (!empty($this->withbody))
903  {
904  $defaultmessage = GETPOST('message', 'restricthtml');
905  if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1')
906  {
907  if ($arraydefaultmessage && $arraydefaultmessage->content) {
908  $defaultmessage = $arraydefaultmessage->content;
909  } elseif (!is_numeric($this->withbody)) {
910  $defaultmessage = $this->withbody;
911  }
912  }
913 
914  // Complete substitution array with the url to make online payment
915  $paymenturl = ''; $validpaymentmethod = array();
916  if (empty($this->substit['__REF__']))
917  {
918  $paymenturl = '';
919  } else {
920  // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
921  require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
922  $langs->loadLangs(array('paypal', 'other'));
923  $typeforonlinepayment = 'free';
924  if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') $typeforonlinepayment = 'order'; // TODO use detection on something else than template
925  if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template
926  if ($this->param["models"] == 'member') $typeforonlinepayment = 'member'; // TODO use detection on something else than template
927  $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
928  $paymenturl = $url;
929 
930  $validpaymentmethod = getValidOnlinePaymentMethods('');
931  }
932 
933  if (count($validpaymentmethod) > 0 && $paymenturl)
934  {
935  $langs->load('other');
936  $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
937  $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
938  } else {
939  $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
940  $this->substit['__ONLINE_PAYMENT_URL__'] = '';
941  }
942 
943  $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = '';
944 
945  // Add lines substitution key from each line
946  $lines = '';
947  $defaultlines = $arraydefaultmessage->content_lines;
948  if (isset($defaultlines))
949  {
950  foreach ($this->substit_lines as $substit_line)
951  {
952  $lines .= make_substitutions($defaultlines, $substit_line)."\n";
953  }
954  }
955  $this->substit['__LINES__'] = $lines;
956 
957  $defaultmessage = str_replace('\n', "\n", $defaultmessage);
958 
959  // Deal with format differences between message and some substitution variables (text / HTML)
960  $atleastonecomponentishtml = 0;
961  if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
962  $atleastonecomponentishtml++;
963  }
964  if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
965  $atleastonecomponentishtml++;
966  }
967  if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) {
968  $atleastonecomponentishtml++;
969  }
970  if (dol_textishtml($defaultmessage)) {
971  $atleastonecomponentishtml++;
972  }
973  if ($atleastonecomponentishtml) {
974  if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
975  $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
976  }
977  if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
978  $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']);
979  }
980  if (!dol_textishtml($defaultmessage)) {
981  $defaultmessage = dol_nl2br($defaultmessage);
982  }
983  }
984 
985  if (GETPOSTISSET("message") && !$_POST['modelselected']) $defaultmessage = $_POST["message"];
986  else {
987  $defaultmessage = make_substitutions($defaultmessage, $this->substit);
988  // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
989  $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
990  $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
991  }
992 
993  $out .= '<tr>';
994  $out .= '<td class="tdtop">';
995  $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
996  $out .= '</td>';
997  $out .= '<td>';
998  if ($this->withbodyreadonly)
999  {
1000  $out .= nl2br($defaultmessage);
1001  $out .= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
1002  } else {
1003  if (!isset($this->ckeditortoolbar)) $this->ckeditortoolbar = 'dolibarr_notes';
1004 
1005  // Editor wysiwyg
1006  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1007  if ($this->withfckeditor == -1)
1008  {
1009  if (!empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor = 1;
1010  else $this->withfckeditor = 0;
1011  }
1012 
1013  $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%');
1014  $out .= $doleditor->Create(1);
1015  }
1016  $out .= "</td></tr>\n";
1017  }
1018 
1019  $out .= '</table>'."\n";
1020 
1021  if ($this->withform == 1 || $this->withform == -1)
1022  {
1023  $out .= '<br><div class="center">';
1024  $out .= '<input class="button" type="submit" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
1025  // Add a javascript test to avoid to forget to submit file before sending email
1026  if ($this->withfile == 2 && $conf->use_javascript_ajax)
1027  {
1028  $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
1029  }
1030  $out .= ' />';
1031  if ($this->withcancel)
1032  {
1033  $out .= ' &nbsp; &nbsp; ';
1034  $out .= '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
1035  }
1036  $out .= '</div>'."\n";
1037  }
1038 
1039  if ($this->withform == 1) $out .= '</form>'."\n";
1040 
1041  // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1042  if (!empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY))
1043  {
1044  $out .= '<script type="text/javascript" language="javascript">';
1045  $out .= 'jQuery(document).ready(function () {';
1046  $out .= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is called at every key pressed ! */
1047  var code = e.keyCode || e.which;
1048  if (code == 13) {
1049  console.log("Enter was intercepted and blocked");
1050  e.preventDefault();
1051  return false;
1052  }
1053  });';
1054  $out .= ' })';
1055  $out .= '</script>';
1056  }
1057 
1058  $out .= "<!-- End form mail -->\n";
1059 
1060  return $out;
1061  }
1062  }
1063 
1069  public function getHtmlForWithCcc()
1070  {
1071  global $conf, $langs, $form;
1072  $out = '<tr><td>';
1073  $out .= $form->textwithpicto($langs->trans("MailCCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1074  $out .= '</td><td>';
1075  if (!empty($this->withtocccreadonly)) {
1076  $out .= (!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : "";
1077  } else {
1078  $out .= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.(GETPOSTISSET("sendtoccc") ? GETPOST("sendtoccc", "alpha") : ((!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />';
1079  if (!empty($this->withtoccc) && is_array($this->withtoccc)) {
1080  $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1081  // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1082  $tmparray = $this->withtoccc;
1083  foreach ($tmparray as $key => $val) {
1084  $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
1085  }
1086  $withtocccselected = GETPOST("receiverccc", 'array'); // Array of selected value
1087  $out .= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, null, null, null, null, "90%");
1088  }
1089  }
1090 
1091  $showinfobcc = '';
1092  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO;
1093  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) && !empty($this->param['models']) && $this->param['models'] == 'order_send') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO;
1094  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO;
1095  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO;
1096  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO;
1097  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) && !empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO;
1098  if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO) && !empty($this->param['models']) && $this->param['models'] == 'project') $showinfobcc = $conf->global->MAIN_MAIL_AUTOCOPY_PROJECT_TO;
1099  if ($showinfobcc) $out .= ' + '.$showinfobcc;
1100  $out .= "</td></tr>\n";
1101  return $out;
1102  }
1103 
1109  public function getHtmlForWithErrorsTo()
1110  {
1111  global $conf, $langs;
1112  //if (! $this->errorstomail) $this->errorstomail=$this->frommail;
1113  $errorstomail = (!empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : $this->errorstomail);
1114  if ($this->witherrorstoreadonly) {
1115  $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1116  $out .= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1117  $out .= $errorstomail;
1118  $out .= "</td></tr>\n";
1119  } else {
1120  $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1121  $out .= '<input size="30" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1122  $out .= "</td></tr>\n";
1123  }
1124  return $out;
1125  }
1126 
1132  public function getHtmlForDeliveryreceipt()
1133  {
1134  global $conf, $langs, $form;
1135  $out = '<tr><td>'.$langs->trans("DeliveryReceipt").'</td><td>';
1136 
1137  if (!empty($this->withdeliveryreceiptreadonly)) {
1138  $out .= yn($this->withdeliveryreceipt);
1139  } else {
1140  $defaultvaluefordeliveryreceipt = 0;
1141  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && !empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt = 1;
1142  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt = 1;
1143  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && !empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt = 1;
1144  if (!empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && !empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt = 1;
1145  $out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1);
1146  }
1147  $out .= "</td></tr>\n";
1148  return $out;
1149  }
1150 
1158  public function getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
1159  {
1160  global $conf, $langs, $form;
1161 
1162  $defaulttopic = GETPOST('subject', 'restricthtml');
1163  if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
1164  if ($arraydefaultmessage && $arraydefaultmessage->topic) {
1165  $defaulttopic = $arraydefaultmessage->topic;
1166  } elseif (!is_numeric($this->withtopic)) {
1167  $defaulttopic = $this->withtopic;
1168  }
1169  }
1170 
1171  $defaulttopic = make_substitutions($defaulttopic, $this->substit);
1172 
1173  $out = '<tr>';
1174  $out .= '<td class="fieldrequired">';
1175  $out .= $form->textwithpicto($langs->trans('MailTopic'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
1176  $out .= '</td>';
1177  $out .= '<td>';
1178  if ($this->withtopicreadonly) {
1179  $out .= $defaulttopic;
1180  $out .= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
1181  } else {
1182  $out .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'.((GETPOSTISSET("subject") && !GETPOST('modelselected')) ? GETPOST("subject") : ($defaulttopic ? $defaulttopic : '')).'" />';
1183  }
1184  $out .= "</td></tr>\n";
1185  return $out;
1186  }
1187 
1201  public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '')
1202  {
1203  global $conf;
1204 
1205  $ret = new ModelMail();
1206 
1207  if ($id == -2 && empty($label)) {
1208  $this->error = 'LabelIsMandatoryWhenIdIs-2';
1209  return -1;
1210  }
1211 
1212  $languagetosearch = (is_object($outputlangs) ? $outputlangs->defaultlang : '');
1213  // Define $languagetosearchmain to fall back on main language (for example to get 'es_ES' for 'es_MX')
1214  $tmparray = explode('_', $languagetosearch);
1215  $languagetosearchmain = $tmparray[0].'_'.strtoupper($tmparray[0]);
1216  if ($languagetosearchmain == $languagetosearch) $languagetosearchmain = '';
1217 
1218  $sql = "SELECT rowid, module, label, type_template, topic, joinfiles, content, content_lines, lang";
1219  $sql .= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1220  $sql .= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')";
1221  $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1222  $sql .= " AND (private = 0 OR fk_user = ".$user->id.")"; // Get all public or private owned
1223  if ($active >= 0) $sql .= " AND active = ".$active;
1224  if ($label) $sql .= " AND label ='".$db->escape($label)."'";
1225  if (!($id > 0) && $languagetosearch) $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
1226  if ($id > 0) $sql .= " AND rowid=".$id;
1227  if ($id == -1) $sql .= " AND position=0";
1228  if ($languagetosearch) $sql .= $db->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or ''
1229  else $sql .= $db->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined
1230  //$sql .= $db->plimit(1);
1231  //print $sql;
1232 
1233  $resql = $db->query($sql);
1234  if (!$resql)
1235  {
1236  dol_print_error($db);
1237  return -1;
1238  }
1239 
1240  // Get first found
1241  while (1) {
1242  $obj = $db->fetch_object($resql);
1243 
1244  if ($obj) {
1245  // If template is for a module, check module is enabled; if not, take next template
1246  if ($obj->module) {
1247  $tempmodulekey = $obj->module;
1248  if (empty($conf->$tempmodulekey) || empty($conf->$tempmodulekey->enabled)) {
1249  continue;
1250  }
1251  }
1252 
1253  // If a record was found
1254  $ret->id = $obj->rowid;
1255  $ret->module = $obj->module;
1256  $ret->label = $obj->label;
1257  $ret->lang = $obj->lang;
1258  $ret->topic = $obj->topic;
1259  $ret->content = $obj->content;
1260  $ret->content_lines = $obj->content_lines;
1261  $ret->joinfiles = $obj->joinfiles;
1262 
1263  break;
1264  } else {
1265  // If no record found
1266  if ($id == -2) {
1267  // Not found with the provided label
1268  return -1;
1269  } else {
1270  // If there is no template at all
1271  $defaultmessage = '';
1272 
1273  if ($type_template == 'body') {
1274  // Special case to use this->withbody as content
1275  $defaultmessage = $this->withbody;
1276  } elseif ($type_template == 'facture_send') {
1277  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoice");
1278  } elseif ($type_template == 'facture_relance') {
1279  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder");
1280  } elseif ($type_template == 'propal_send') {
1281  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendProposal");
1282  } elseif ($type_template == 'supplier_proposal_send') {
1283  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal");
1284  } elseif ($type_template == 'order_send') {
1285  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendOrder");
1286  } elseif ($type_template == 'order_supplier_send') {
1287  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder");
1288  } elseif ($type_template == 'invoice_supplier_send') {
1289  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice");
1290  } elseif ($type_template == 'shipping_send') {
1291  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendShipping");
1292  } elseif ($type_template == 'fichinter_send') {
1293  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendFichInter");
1294  } elseif ($type_template == 'actioncomm_send') {
1295  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm");
1296  } elseif ($type_template == 'thirdparty') {
1297  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentThirdparty");
1298  } elseif (!empty($type_template)) {
1299  $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric");
1300  }
1301 
1302  $ret->label = 'default';
1303  $ret->lang = $outputlangs->defaultlang;
1304  $ret->topic = '';
1305  $ret->joinfiles = 1;
1306  $ret->content = $defaultmessage;
1307  $ret->content_lines = '';
1308 
1309  break;
1310  }
1311  }
1312  }
1313 
1314  $db->free($resql);
1315  return $ret;
1316  }
1317 
1327  public function isEMailTemplate($type_template, $user, $outputlangs)
1328  {
1329  $sql = "SELECT label, topic, content, lang";
1330  $sql .= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1331  $sql .= " WHERE type_template='".$this->db->escape($type_template)."'";
1332  $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1333  $sql .= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
1334  if (is_object($outputlangs)) $sql .= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
1335  $sql .= $this->db->order("lang,label", "ASC");
1336  //print $sql;
1337 
1338  $resql = $this->db->query($sql);
1339  if ($resql)
1340  {
1341  $num = $this->db->num_rows($resql);
1342  $this->db->free($resql);
1343  return $num;
1344  } else {
1345  $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1346  return -1;
1347  }
1348  }
1349 
1360  public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active = 1)
1361  {
1362  global $conf;
1363 
1364  $sql = "SELECT rowid, module, label, topic, content, content_lines, lang, fk_user, private, position";
1365  $sql .= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1366  $sql .= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1367  $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1368  $sql .= " AND (private = 0 OR fk_user = ".$user->id.")"; // See all public templates or templates I own.
1369  if ($active >= 0) $sql .= " AND active = ".$active;
1370  //if (is_object($outputlangs)) $sql.= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')"; // Return all languages
1371  $sql .= $this->db->order("position,lang,label", "ASC");
1372  //print $sql;
1373 
1374  $resql = $this->db->query($sql);
1375  if ($resql)
1376  {
1377  $num = $this->db->num_rows($resql);
1378  $this->lines_model = array();
1379  while ($obj = $this->db->fetch_object($resql))
1380  {
1381  // If template is for a module, check module is enabled.
1382  if ($obj->module) {
1383  $tempmodulekey = $obj->module;
1384  if (empty($conf->$tempmodulekey) || empty($conf->$tempmodulekey->enabled)) {
1385  continue;
1386  }
1387  }
1388 
1389  $line = new ModelMail();
1390  $line->id = $obj->rowid;
1391  $line->label = $obj->label;
1392  $line->lang = $obj->lang;
1393  $line->fk_user = $obj->fk_user;
1394  $line->private = $obj->private;
1395  $line->position = $obj->position;
1396  $line->topic = $obj->topic;
1397  $line->content = $obj->content;
1398  $line->content_lines = $obj->content_lines;
1399 
1400  $this->lines_model[] = $line;
1401  }
1402  $this->db->free($resql);
1403  return $num;
1404  } else {
1405  $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1406  return -1;
1407  }
1408  }
1409 
1410 
1411 
1420  public function setSubstitFromObject($object, $outputlangs)
1421  {
1422  global $conf, $user, $extrafields;
1423 
1424  $parameters = array();
1425  $tmparray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
1426  complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
1427 
1428  $this->substit = $tmparray;
1429 
1430  // Fill substit_lines with each object lines content
1431  if (is_array($object->lines))
1432  {
1433  foreach ($object->lines as $line)
1434  {
1435  $substit_line = array(
1436  '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1437  '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1438  '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1439  '__LABEL__' => isset($line->label) ? $line->label : '',
1440  '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1441  '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
1442  '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
1443  '__QUANTITY__' => $line->qty,
1444  '__SUBPRICE__' => price($line->subprice),
1445  '__AMOUNT__' => price($line->total_ttc),
1446  '__AMOUNT_EXCL_TAX__' => price($line->total_ht)
1447  );
1448 
1449  // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1450  if (!empty($line->fk_product))
1451  {
1452  if (!is_object($extrafields)) $extrafields = new ExtraFields($this->db);
1453  $extrafields->fetch_name_optionals_label('product', true);
1454  $product = new Product($this->db);
1455  $product->fetch($line->fk_product, '', '', 1);
1456  $product->fetch_optionals();
1457  if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
1458  {
1459  foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
1460  $substit_line['__PRODUCT_EXTRAFIELD_'.strtoupper($key).'__'] = $product->array_options['options_'.$key];
1461  }
1462  }
1463  }
1464  $this->substit_lines[] = $substit_line;
1465  }
1466  }
1467  }
1468 
1477  public static function getAvailableSubstitKey($mode = 'formemail', $object = null)
1478  {
1479  global $conf, $langs;
1480 
1481  $tmparray = array();
1482  if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines')
1483  {
1484  $parameters = array('mode'=>$mode);
1485  $tmparray = getCommonSubstitutionArray($langs, 2, null, $object); // Note: On email templated edition, this is null because it is related to all type of objects
1486  complete_substitutions_array($tmparray, $langs, null, $parameters);
1487 
1488  if ($mode == 'formwithlines')
1489  {
1490  $tmparray['__LINES__'] = '__LINES__'; // Will be set by the get_form function
1491  }
1492  if ($mode == 'formforlines')
1493  {
1494  $tmparray['__QUANTITY__'] = '__QUANTITY__'; // Will be set by the get_form function
1495  }
1496  }
1497 
1498  if ($mode == 'emailing')
1499  {
1500  $parameters = array('mode'=>$mode);
1501  $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
1502  complete_substitutions_array($tmparray, $langs, null, $parameters);
1503 
1504  // For mass emailing, we have different keys
1505  $tmparray['__ID__'] = 'IdRecord';
1506  $tmparray['__EMAIL__'] = 'EMailRecipient';
1507  $tmparray['__LASTNAME__'] = 'Lastname';
1508  $tmparray['__FIRSTNAME__'] = 'Firstname';
1509  $tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
1510  $tmparray['__OTHER1__'] = 'Other1';
1511  $tmparray['__OTHER2__'] = 'Other2';
1512  $tmparray['__OTHER3__'] = 'Other3';
1513  $tmparray['__OTHER4__'] = 'Other4';
1514  $tmparray['__OTHER5__'] = 'Other5';
1515  $tmparray['__USER_SIGNATURE__'] = 'TagSignature';
1516  $tmparray['__CHECK_READ__'] = 'TagCheckMail';
1517  $tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe';
1518  //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing
1519 
1520  $onlinepaymentenabled = 0;
1521  if (!empty($conf->paypal->enabled)) $onlinepaymentenabled++;
1522  if (!empty($conf->paybox->enabled)) $onlinepaymentenabled++;
1523  if (!empty($conf->stripe->enabled)) $onlinepaymentenabled++;
1524  if ($onlinepaymentenabled && !empty($conf->global->PAYMENT_SECURITY_TOKEN))
1525  {
1526  $tmparray['__SECUREKEYPAYMENT__'] = $conf->global->PAYMENT_SECURITY_TOKEN;
1527  if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE))
1528  {
1529  if ($conf->adherent->enabled) $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
1530  if ($conf->facture->enabled) $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
1531  if ($conf->commande->enabled) $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
1532  if ($conf->contrat->enabled) $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
1533  }
1534  } else {
1535  /* No need to show into tooltip help, option is not enabled
1536  $vars['__SECUREKEYPAYMENT__']='';
1537  $vars['__SECUREKEYPAYMENT_MEMBER__']='';
1538  $vars['__SECUREKEYPAYMENT_INVOICE__']='';
1539  $vars['__SECUREKEYPAYMENT_ORDER__']='';
1540  $vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
1541  */
1542  }
1543  }
1544 
1545  foreach ($tmparray as $key => $val)
1546  {
1547  if (empty($val)) $tmparray[$key] = $key;
1548  }
1549 
1550  return $tmparray;
1551  }
1552 }
1553 
1554 
1558 class ModelMail
1559 {
1563  public $id;
1564 
1568  public $label;
1569 
1570  public $topic;
1571  public $content;
1572  public $content_lines;
1573  public $lang;
1574  public $joinfiles;
1575 }
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto= 'UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
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= '', $addjscombo=0, $moreparamonempty= '', $disablebademail=0, $nohtmlescape=0)
Return a HTML select string, built from an array of key+value.
getHtmlForWithCcc()
get html For WithCCC
Classe permettant la generation du formulaire html d&#39;envoi de mail unitaire Usage: $formail = new For...
show_form($addfileaction= 'addfile', $removefileaction= 'removefile')
Show the form to input an email this-&gt;withfile: 0=No attaches files, 1=Show attached files...
__construct($db)
Constructor.
getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1, $label= '')
Return templates of email with type = $type_template or type = &#39;all&#39;.
Class to manage contact/addresses.
</td >< tdcolspan="3">< spanclass="opacitymedium"></span ></td ></tr >< trclass="liste_total"> CREANCES DETTES< tdcolspan="3"class="right"></td >< tdcolspan="3"class="right"></td ></tr > CREANCES DETTES RECETTES DEPENSES trips CREANCES DETTES Y m expensereport p date_valid Y m expensereport pe datep $db idate($date_start)."' AND $column < p rowid
dol_htmlentities($string, $flags=null, $encoding= 'UTF-8', $double_encode=false)
Replace htmlentities functions.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
img_mime($file, $titlealt= '', $morecss= '')
Show MIME img of a file.
$conf db
API class for accounts.
Definition: inc.php:54
add_attached_files($path, $file= '', $type= '')
Add a file into the list of attached files (stored in SECTION array)
get_form($addfileaction= 'addfile', $removefileaction= 'removefile')
Get the form to input an email this-&gt;withfile: 0=No attaches files, 1=Show attached files...
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname.
getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
get Html For Topic of message
Class to manage third parties objects (customers, suppliers, prospects...)
dol_mimetype($file, $default= 'application/octet-stream', $mode=0)
Return mime type of a file.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories) ...
Definition: files.lib.php:1286
fetchAllEMailTemplate($type_template, $user, $outputlangs, $active=1)
Find if template exists and are available for current user, then set them into $this-&gt;lines_module.
getHtmlForWithErrorsTo()
get Html For WithErrorsTo
Class to manage translations.
remove_attached_files($keytodelete)
Remove a file from the list of attached files (stored in SECTION array)
get_attached_files()
Return list of attached files (stored in SECTION array)
dolGetFirstLineOfText($text, $nboflines=1, $charset= 'UTF-8')
Return first line of text.
print
Draft customers invoices.
Definition: index.php:89
clear_attached_files()
Clear list of attached files in send mail form (also stored in session)
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
print $_SERVER["PHP_SELF"] n
Edit parameters.
Definition: categories.php:101
Class to manage a WYSIWYG editor.
make_substitutions($text, $substitutionarray, $outputlangs=null)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=&gt;newva...
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin= '1', $morecss= '', $textfordropdown= '')
Show information for admin users or standard users.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $keepmoretags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dol_textishtml($msg, $option=0)
Return if a text is a html content.