dolibarr 19.0.4
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 * Copyright (C) 2023 Anthony Berton <anthony.berton@bb2a.fr>
10 *
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
32
33
40class FormMail extends Form
41{
45 public $db;
46
52 public $withform;
53
57 public $fromname;
58
62 public $frommail;
63
67 public $fromtype;
68
72 public $fromid;
73
77 public $fromalsorobot;
78
82 public $totype;
83
87 public $toid;
88
92 public $replytoname;
93
97 public $replytomail;
98
102 public $toname;
103
107 public $tomail;
108
112 public $trackid;
113
117 public $inreplyto;
118
119 public $withsubstit; // Show substitution array
120 public $withfrom;
121
125 public $withto; // Show recipient emails
126 public $withreplyto;
127
133 public $withtofree;
134 public $withtocc;
135 public $withtoccc;
136 public $withtopic;
137 public $witherrorsto;
138
142 public $withfile;
143
147 public $withmaindocfile;
148 public $withbody;
149
150 public $withfromreadonly;
151 public $withreplytoreadonly;
152 public $withtoreadonly;
153 public $withtoccreadonly;
154 public $witherrorstoreadonly;
155 public $withtocccreadonly;
156 public $withtopicreadonly;
157 public $withbodyreadonly;
158 public $withfilereadonly;
159 public $withdeliveryreceipt;
160 public $withcancel;
161 public $withdeliveryreceiptreadonly;
162 public $withfckeditor;
163
167 public $ckeditortoolbar;
168
169 public $substit = array();
170 public $substit_lines = array();
171 public $param = array();
172
173 public $withtouser = array();
174 public $withtoccuser = array();
175
176 public $lines_model;
177
178 // -1 suggest the checkbox 'one email per recipient' not checked, 0 = no suggestion, 1 = suggest and checked
179 public $withoptiononeemailperrecipient;
180
181
187 public function __construct($db)
188 {
189 $this->db = $db;
190
191 $this->withform = 1;
192
193 $this->withfrom = 1;
194 $this->withto = 1;
195 $this->withtofree = 1;
196 $this->withtocc = 1;
197 $this->withtoccc = 0;
198 $this->witherrorsto = 0;
199 $this->withtopic = 1;
200 $this->withfile = 0; // 1=Add section "Attached files". 2=Can add files.
201 $this->withmaindocfile = 0; // 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
202 $this->withbody = 1;
203
204 $this->withfromreadonly = 1;
205 $this->withreplytoreadonly = 1;
206 $this->withtoreadonly = 0;
207 $this->withtoccreadonly = 0;
208 $this->withtocccreadonly = 0;
209 $this->witherrorstoreadonly = 0;
210 $this->withtopicreadonly = 0;
211 $this->withfilereadonly = 0;
212 $this->withbodyreadonly = 0;
213 $this->withdeliveryreceiptreadonly = 0;
214 $this->withfckeditor = -1; // -1 = Auto
215 }
216
217 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
223 public function clear_attached_files()
224 {
225 // phpcs:enable
226 global $conf, $user;
227 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
228
229 // Set tmp user directory
230 $vardir = $conf->user->dir_output."/".$user->id;
231 $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
232 if (is_dir($upload_dir)) {
233 dol_delete_dir_recursive($upload_dir);
234 }
235
236 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
237 unset($_SESSION["listofpaths".$keytoavoidconflict]);
238 unset($_SESSION["listofnames".$keytoavoidconflict]);
239 unset($_SESSION["listofmimes".$keytoavoidconflict]);
240 }
241
242 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
251 public function add_attached_files($path, $file = '', $type = '')
252 {
253 // phpcs:enable
254 $listofpaths = array();
255 $listofnames = array();
256 $listofmimes = array();
257
258 if (empty($file)) {
259 $file = basename($path);
260 }
261 if (empty($type)) {
262 $type = dol_mimetype($file);
263 }
264
265 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
266 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
267 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
268 }
269 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
270 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
271 }
272 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
273 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
274 }
275 if (!in_array($file, $listofnames)) {
276 $listofpaths[] = $path;
277 $listofnames[] = $file;
278 $listofmimes[] = $type;
279 $_SESSION["listofpaths".$keytoavoidconflict] = join(';', $listofpaths);
280 $_SESSION["listofnames".$keytoavoidconflict] = join(';', $listofnames);
281 $_SESSION["listofmimes".$keytoavoidconflict] = join(';', $listofmimes);
282 }
283 }
284
285 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
292 public function remove_attached_files($keytodelete)
293 {
294 // phpcs:enable
295 $listofpaths = array();
296 $listofnames = array();
297 $listofmimes = array();
298
299 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
300 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
301 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
302 }
303 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
304 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
305 }
306 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
307 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
308 }
309 if ($keytodelete >= 0) {
310 unset($listofpaths[$keytodelete]);
311 unset($listofnames[$keytodelete]);
312 unset($listofmimes[$keytodelete]);
313 $_SESSION["listofpaths".$keytoavoidconflict] = join(';', $listofpaths);
314 $_SESSION["listofnames".$keytoavoidconflict] = join(';', $listofnames);
315 $_SESSION["listofmimes".$keytoavoidconflict] = join(';', $listofmimes);
316 //var_dump($_SESSION['listofpaths']);
317 }
318 }
319
320 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
326 public function get_attached_files()
327 {
328 // phpcs:enable
329 $listofpaths = array();
330 $listofnames = array();
331 $listofmimes = array();
332
333 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
334 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
335 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
336 }
337 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
338 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
339 }
340 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
341 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
342 }
343 return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
344 }
345
346 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
357 public function show_form($addfileaction = 'addfile', $removefileaction = 'removefile')
358 {
359 // phpcs:enable
360 print $this->get_form($addfileaction, $removefileaction);
361 }
362
363 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
374 public function get_form($addfileaction = 'addfile', $removefileaction = 'removefile')
375 {
376 // phpcs:enable
377 global $conf, $langs, $user, $hookmanager, $form;
378
379 // Required to show preview wof mail attachments
380 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
381 $formfile = new FormFile($this->db);
382
383 if (!is_object($form)) {
384 $form = new Form($this->db);
385 }
386
387 // Load translation files required by the page
388 $langs->loadLangs(array('other', 'mails', 'members'));
389
390 // Clear temp files. Must be done before call of triggers, at beginning (mode = init), or when we select a new template
391 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
392 $this->clear_attached_files();
393 }
394
395 // Call hook getFormMail
396 $hookmanager->initHooks(array('formmail'));
397
398 $parameters = array(
399 'addfileaction' => $addfileaction,
400 'removefileaction'=> $removefileaction,
401 'trackid'=> $this->trackid
402 );
403 $reshook = $hookmanager->executeHooks('getFormMail', $parameters, $this);
404
405 if (!empty($reshook)) {
406 return $hookmanager->resPrint;
407 } else {
408 $out = '';
409
410 $disablebademails = 1;
411
412 // Define output language
413 $outputlangs = $langs;
414 $newlang = '';
415 if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($this->param['langsmodels'])) {
416 $newlang = $this->param['langsmodels'];
417 }
418 if (!empty($newlang)) {
419 $outputlangs = new Translate("", $conf);
420 $outputlangs->setDefaultLang($newlang);
421 $outputlangs->load('other');
422 }
423
424 // Get message template for $this->param["models"] into c_email_templates
425 $arraydefaultmessage = -1;
426 if ($this->param['models'] != 'none') {
427 $model_id = 0;
428 if (array_key_exists('models_id', $this->param)) {
429 $model_id = $this->param["models_id"];
430 }
431
432 $arraydefaultmessage = $this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id, 1, '', ($model_id > 0 ? -1 : 1)); // If $model_id is empty, preselect the first one
433 }
434
435 // Define list of attached files
436 $listofpaths = array();
437 $listofnames = array();
438 $listofmimes = array();
439 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
440
441 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
442 if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
443 foreach ($this->param['fileinit'] as $path) {
444 if (!empty($path)) {
445 $this->add_attached_files($path);
446 }
447 }
448 }
449 }
450
451 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
452 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
453 }
454 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
455 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
456 }
457 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
458 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
459 }
460
461
462 $out .= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
463 if ($this->withform == 1) {
464 $out .= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
465
466 $out .= '<a id="formmail" name="formmail"></a>';
467 $out .= '<input style="display:none" type="submit" id="sendmailhidden" name="sendmail">';
468 $out .= '<input type="hidden" name="token" value="'.newToken().'" />';
469 $out .= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
470 $out .= '<input type="hidden" name="inreplyto" value="'.$this->inreplyto.'" />';
471 }
472 if (!empty($this->withfrom)) {
473 if (!empty($this->withfromreadonly)) {
474 $out .= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
475 $out .= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
476 }
477 }
478 foreach ($this->param as $key => $value) {
479 if (is_array($value)) {
480 $out .= "<!-- param key=".$key." is array, we do not output input field for it -->\n";
481 } else {
482 $out .= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
483 }
484 }
485
486 $modelmail_array = array();
487 if ($this->param['models'] != 'none') {
488 $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
489 if ($result < 0) {
490 setEventMessages($this->error, $this->errors, 'errors');
491 }
492
493 foreach ($this->lines_model as $line) {
494 $reg = array();
495 if (preg_match('/\‍((.*)\‍)/', $line->label, $reg)) {
496 $labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__
497 } else {
498 $labeltouse = $line->label;
499 }
500
501 // We escape the $labeltouse to store it into $modelmail_array.
502 $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse);
503 if ($line->lang) {
504 $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang);
505 }
506 if ($line->private) {
507 $modelmail_array[$line->id] .= ' - <span class="opacitymedium">'.dol_escape_htmltag($langs->trans("Private")).'</span>';
508 }
509 }
510 }
511
512 // Zone to select email template
513 if (count($modelmail_array) > 0) {
514 $model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOST('modelmailselected', 'int') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0);
515
516 // If list of template is filled
517 $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
518
519 $out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
520
521 $out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1);
522 if ($user->admin) {
523 $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
524 }
525
526 $out .= ' &nbsp; ';
527 $out .= '<input type="submit" class="button reposition smallpaddingimp" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
528 $out .= ' &nbsp; ';
529 $out .= '</div>';
530 } elseif (!empty($this->param['models']) && in_array($this->param['models'], array(
531 'propal_send', 'order_send', 'facture_send',
532 'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send',
533 'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'all'
534 ))) {
535 // If list of template is empty
536 $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
537 $out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
538 $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.
539 if ($user->admin) {
540 $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
541 }
542 $out .= ' &nbsp; ';
543 $out .= '<input type="submit" class="button" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
544 $out .= ' &nbsp; ';
545 $out .= '</div>';
546 } else {
547 $out .= '<!-- No template available for $this->param["models"] = '.$this->param['models'].' -->';
548 }
549
550
551 $out .= '<table class="tableforemailform boxtablenotop centpercent">'."\n";
552
553 // Substitution array/string
554 $helpforsubstitution = '';
555 if (is_array($this->substit) && count($this->substit)) {
556 $helpforsubstitution .= $langs->trans('AvailableVariables').' :<br><br><span class="small">'."\n";
557 }
558 foreach ($this->substit as $key => $val) {
559 // Do not show deprecated variables into the tooltip help of substitution variables
560 if (in_array($key, array('__NEWREF__', '__REFCLIENT__', '__REFSUPPLIER__', '__SUPPLIER_ORDER_DATE_DELIVERY__', '__SUPPLIER_ORDER_DELAY_DELIVERY__'))) {
561 continue;
562 }
563 $helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText($val))).'<br>';
564 }
565 if (is_array($this->substit) && count($this->substit)) {
566 $helpforsubstitution .= '</span>';
567 }
568
569 if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this.
570 $out .= '<tr><td colspan="2" class="right">';
571 if (is_numeric($this->withsubstit)) {
572 $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
573 } else {
574 $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
575 }
576 $out .= "</td></tr>\n";
577 }
578
579 // From
580 if (!empty($this->withfrom)) {
581 if (!empty($this->withfromreadonly)) {
582 $out .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
583
584 // $this->fromtype is the default value to use to select sender
585 if (!($this->fromtype === 'user' && $this->fromid > 0)
586 && !($this->fromtype === 'company')
587 && !($this->fromtype === 'robot')
588 && !preg_match('/user_aliases/', $this->fromtype)
589 && !preg_match('/global_aliases/', $this->fromtype)
590 && !preg_match('/senderprofile/', $this->fromtype)
591 ) {
592 // Use this->fromname and this->frommail or error if not defined
593 $out .= $this->fromname;
594 if ($this->frommail) {
595 $out .= ' &lt;'.$this->frommail.'&gt;';
596 } else {
597 if ($this->fromtype) {
598 $langs->load('errors');
599 $out .= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
600 }
601 }
602 } else {
603 $liste = array();
604
605 // Add user email
606 if (empty($user->email)) {
607 $langs->load('errors');
608 $s = $user->getFullName($langs).' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
609 } else {
610 $s = $user->getFullName($langs).' &lt;'.$user->email.'&gt;';
611 }
612 $liste['user'] = array('label' => $s, 'data-html' => $s);
613
614 // Add also company main email
615 if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
616 $s = (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? $conf->global->MAIN_INFO_SOCIETE_EMAIL : $conf->global->MAIN_INFO_SOCIETE_NOM).' &lt;' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL').'&gt;';
617 $liste['company'] = array('label' => $s, 'data-html' => $s);
618 }
619
620 // Add also email aliases if there is some
621 $listaliases = array(
622 'user_aliases' => (empty($user->email_aliases) ? '' : $user->email_aliases),
623 'global_aliases' => getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'),
624 );
625
626 if (!empty($arraydefaultmessage->email_from)) {
627 $templatemailfrom = ' &lt;'.$arraydefaultmessage->email_from.'&gt;';
628 $liste['from_template_'.GETPOST('modelmailselected')] = array('label' => $templatemailfrom, 'data-html' => $templatemailfrom);
629 }
630
631 // Also add robot email
632 if (!empty($this->fromalsorobot)) {
633 if (getDolGlobalString('MAIN_MAIL_EMAIL_FROM') && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
634 $s = $conf->global->MAIN_MAIL_EMAIL_FROM;
635 if ($this->frommail) {
636 $s .= ' &lt;' . getDolGlobalString('MAIN_MAIL_EMAIL_FROM').'&gt;';
637 }
638 array('label' => $s, 'data-html' => $s);
639 }
640 }
641
642 // Add also email aliases from the c_email_senderprofile table
643 $sql = "SELECT rowid, label, email FROM ".$this->db->prefix()."c_email_senderprofile";
644 $sql .= " WHERE active = 1 AND (private = 0 OR private = ".((int) $user->id).")";
645 $sql .= " ORDER BY position";
646 $resql = $this->db->query($sql);
647 if ($resql) {
648 $num = $this->db->num_rows($resql);
649 $i = 0;
650 while ($i < $num) {
651 $obj = $this->db->fetch_object($resql);
652 if ($obj) {
653 $listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
654 }
655 $i++;
656 }
657 } else {
658 dol_print_error($this->db);
659 }
660
661 foreach ($listaliases as $typealias => $listalias) {
662 $posalias = 0;
663 $listaliasarray = explode(',', $listalias);
664 foreach ($listaliasarray as $listaliasval) {
665 $posalias++;
666 $listaliasval = trim($listaliasval);
667 if ($listaliasval) {
668 $listaliasval = preg_replace('/</', '&lt;', $listaliasval);
669 $listaliasval = preg_replace('/>/', '&gt;', $listaliasval);
670 if (!preg_match('/&lt;/', $listaliasval)) {
671 $listaliasval = '&lt;'.$listaliasval.'&gt;';
672 }
673 $liste[$typealias.'_'.$posalias] = array('label' => $listaliasval, 'data-html' => $listaliasval);
674 }
675 }
676 }
677
678 // Using ajaxcombo here make the '<email>' no more visible on list because <emailofuser> is not a valid html tag,
679 // so we transform before each record into $liste to be printable with ajaxcombo by replacing <> into ()
680 // $liste['senderprofile_0_0'] = array('label'=>'rrr', 'data-html'=>'rrr &lt;aaaa&gt;');
681 foreach ($liste as $key => $val) {
682 if (!empty($liste[$key]['data-html'])) {
683 $liste[$key]['data-html'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $liste[$key]['data-html']);
684 $liste[$key]['data-html'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $liste[$key]['data-html']);
685 }
686 }
687 $out .= ' '.$form->selectarray('fromtype', $liste, empty($arraydefaultmessage->email_from) ? $this->fromtype : 'from_template_'.GETPOST('modelmailselected'), 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
688 }
689
690 $out .= "</td></tr>\n";
691 } else {
692 $out .= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
693 $out .= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
694 $out .= '&nbsp; &nbsp; ';
695 $out .= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
696 $out .= "</td></tr>\n";
697 }
698 }
699
700 // To
701 if (!empty($this->withto) || is_array($this->withto)) {
702 $out .= $this->getHtmlForTo();
703 }
704
705 // To User
706 if (!empty($this->withtouser) && is_array($this->withtouser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) {
707 $out .= '<tr><td>';
708 $out .= $langs->trans("MailToUsers");
709 $out .= '</td><td>';
710
711 // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
712 $tmparray = $this->withtouser;
713 foreach ($tmparray as $key => $val) {
714 $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
715 }
716 $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value
717 if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
718 $withtoselected = array_keys($tmparray);
719 }
720 $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
721 $out .= "</td></tr>\n";
722 }
723
724 // With option for one email per recipient
725 if (!empty($this->withoptiononeemailperrecipient)) {
726 if (abs($this->withoptiononeemailperrecipient) == 1) {
727 $out .= '<tr><td class="minwidth200">';
728 $out .= $langs->trans("GroupEmails");
729 $out .= '</td><td>';
730 $out .= ' <input type="checkbox" id="oneemailperrecipient" value="1" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> ';
731 $out .= '<label for="oneemailperrecipient">';
732 $out .= $form->textwithpicto($langs->trans("OneEmailPerRecipient"), $langs->trans("WarningIfYouCheckOneRecipientPerEmail"), 1, 'help');
733 $out .= '</label>';
734 //$out .= '<span class="hideonsmartphone opacitymedium">';
735 //$out .= ' - ';
736 //$out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
737 //$out .= '</span>';
738 if (getDolGlobalString('MASS_ACTION_EMAIL_ON_DIFFERENT_THIRPARTIES_ADD_CUSTOM_EMAIL')) {
739 if (!empty($this->withto) && !is_array($this->withto)) {
740 $out .= ' '.$langs->trans("or").' <input type="email" name="emailto" value="">';
741 }
742 }
743 $out .= '</td></tr>';
744 } else {
745 $out .= '<tr><td><input type="hidden" name="oneemailperrecipient" value="1"></td><td></td></tr>';
746 }
747 }
748
749 // CC
750 if (!empty($this->withtocc) || is_array($this->withtocc)) {
751 $out .= $this->getHtmlForCc();
752 }
753
754 // To User cc
755 if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) {
756 $out .= '<tr><td>';
757 $out .= $langs->trans("MailToCCUsers");
758 $out .= '</td><td>';
759
760 // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
761 $tmparray = $this->withtoccuser;
762 foreach ($tmparray as $key => $val) {
763 $tmparray[$key] = dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
764 }
765 $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value
766 if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
767 $withtoselected = array_keys($tmparray);
768 }
769 $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
770 $out .= "</td></tr>\n";
771 }
772
773 // CCC
774 if (!empty($this->withtoccc) || is_array($this->withtoccc)) {
775 $out .= $this->getHtmlForWithCcc();
776 }
777
778 // Replyto
779 if (!empty($this->withreplyto)) {
780 if ($this->withreplytoreadonly) {
781 $out .= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
782 $out .= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
783 $out .= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail ? (" &lt;".$this->replytomail."&gt;") : "");
784 $out .= "</td></tr>\n";
785 }
786 }
787
788 // Errorsto
789 if (!empty($this->witherrorsto)) {
790 $out .= $this->getHtmlForWithErrorsTo();
791 }
792
793 // Ask delivery receipt
794 if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) {
795 $out .= $this->getHtmlForDeliveryReceipt();
796 }
797
798 // Topic
799 if (!empty($this->withtopic)) {
800 $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution);
801 }
802
803 // Attached files
804 if (!empty($this->withfile)) {
805 $out .= '<tr>';
806 $out .= '<td>'.$langs->trans("MailFile").'</td>';
807
808 $out .= '<td>';
809
810 if ($this->withmaindocfile) {
811 // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
812 if (GETPOSTISSET('sendmail')) {
813 $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
814 } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
815 // If a template was selected, we use setup of template to define if join file checkbox is selected or not.
816 $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
817 }
818 }
819
820 if (!empty($this->withmaindocfile)) {
821 if ($this->withmaindocfile == 1) {
822 $out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" />';
823 } elseif ($this->withmaindocfile == -1) {
824 $out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" checked="checked" />';
825 }
826 if (getDolGlobalString('MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND')) {
827 $out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDocOrLastGenerated").'.</label><br>';
828 } else {
829 $out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDoc").'.</label><br>';
830 }
831 }
832
833 if (is_numeric($this->withfile)) {
834 // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
835 $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
836 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
837 $out .= 'jQuery(document).ready(function () {';
838 $out .= ' jQuery(".removedfile").click(function() {';
839 $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
840 $out .= ' });';
841 $out .= '})';
842 $out .= '</script>'."\n";
843 if (count($listofpaths)) {
844 foreach ($listofpaths as $key => $val) {
845 $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val)));
846
847 $entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity);
848 if ($entity > 1) {
849 $relativepathtofile = str_replace('/'.$entity.'/', '/', $relativepathtofile);
850 }
851 // Try to extract data from full path
852 $formfile_params = array();
853 preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params);
854
855 $out .= '<div id="attachfile_'.$key.'">';
856 // Preview of attachment
857 $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
858
859 $out .= $formfile->showPreview(array(), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity='.((int) $entity)));
860 if (!$this->withfilereadonly) {
861 $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.'" />';
862 //$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
863 }
864 $out .= '<br></div>';
865 }
866 } elseif (empty($this->withmaindocfile)) {
867 //$out .= '<span class="opacitymedium">'.$langs->trans("NoAttachedFiles").'</span><br>';
868 }
869 if ($this->withfile == 2) {
870 $maxfilesizearray = getMaxFileSizeArray();
871 $maxmin = $maxfilesizearray['maxmin'];
872 if ($maxmin > 0) {
873 $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
874 }
875 // Can add other files
876 if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) {
877 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
878 } else {
879 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
880 }
881 $out .= ' ';
882 $out .= '<input type="submit" class="button smallpaddingimp" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
883 }
884 } else {
885 $out .= $this->withfile;
886 }
887
888 $out .= "</td></tr>\n";
889 }
890
891 // Message
892 if (!empty($this->withbody)) {
893 $defaultmessage = GETPOST('message', 'restricthtml');
894 if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
895 if ($arraydefaultmessage && $arraydefaultmessage->content) {
896 $defaultmessage = $arraydefaultmessage->content;
897 } elseif (!is_numeric($this->withbody)) {
898 $defaultmessage = $this->withbody;
899 }
900 }
901
902 // Complete substitution array with the url to make online payment
903 $paymenturl = '';
904 // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
905 require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
906 $validpaymentmethod = getValidOnlinePaymentMethods('');
907 if (empty($this->substit['__REF__'])) {
908 $paymenturl = '';
909 } else {
910 $langs->loadLangs(array('paypal', 'other'));
911 $typeforonlinepayment = 'free';
912 if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') {
913 $typeforonlinepayment = 'order'; // TODO use detection on something else than template
914 }
915 if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') {
916 $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template
917 }
918 if ($this->param["models"] == 'member') {
919 $typeforonlinepayment = 'member'; // TODO use detection on something else than template
920 }
921 $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
922 $paymenturl = $url;
923 }
924
925 if (count($validpaymentmethod) > 0 && $paymenturl) {
926 $langs->load('other');
927 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
928 $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
929 } elseif (count($validpaymentmethod) > 0) {
930 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__';
931 $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__';
932 } else {
933 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
934 $this->substit['__ONLINE_PAYMENT_URL__'] = '';
935 }
936
937 $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = '';
938
939 // Add lines substitution key from each line
940 $lines = '';
941 $defaultlines = $arraydefaultmessage->content_lines;
942 if (isset($defaultlines)) {
943 foreach ($this->substit_lines as $substit_line) {
944 $lines .= make_substitutions($defaultlines, $substit_line)."\n";
945 }
946 }
947 $this->substit['__LINES__'] = $lines;
948
949 $defaultmessage = str_replace('\n', "\n", $defaultmessage);
950
951 // Deal with format differences between message and some substitution variables (text / HTML)
952 $atleastonecomponentishtml = 0;
953 if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
954 $atleastonecomponentishtml++;
955 }
956 if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
957 $atleastonecomponentishtml++;
958 }
959 if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
960 $atleastonecomponentishtml++;
961 }
962 if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) {
963 $atleastonecomponentishtml++;
964 }
965 if (dol_textishtml($defaultmessage)) {
966 $atleastonecomponentishtml++;
967 }
968 if ($atleastonecomponentishtml) {
969 if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
970 $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
971 }
972 if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
973 $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']);
974 }
975 if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
976 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']);
977 }
978 if (!dol_textishtml($defaultmessage)) {
979 $defaultmessage = dol_nl2br($defaultmessage);
980 }
981 }
982
983 if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
984 $defaultmessage = GETPOST("message", "restricthtml");
985 } else {
986 $defaultmessage = make_substitutions($defaultmessage, $this->substit);
987 // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
988 $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
989 $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
990 }
991
992 $out .= '<tr>';
993 $out .= '<td colspan="2">';
994 $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
995 $out .= '</td>';
996 $out .= '</tr>';
997
998 $out .= '<tr>';
999 $out .= '<td colspan="2">';
1000 if ($this->withbodyreadonly) {
1001 $out .= nl2br($defaultmessage);
1002 $out .= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
1003 } else {
1004 if (!isset($this->ckeditortoolbar)) {
1005 $this->ckeditortoolbar = 'dolibarr_mailings';
1006 }
1007
1008 // Editor wysiwyg
1009 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1010 if ($this->withfckeditor == -1) {
1011 if (getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) {
1012 $this->withfckeditor = 1;
1013 } else {
1014 $this->withfckeditor = 0;
1015 }
1016 }
1017
1018 $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%');
1019 $out .= $doleditor->Create(1);
1020 }
1021 $out .= "</td></tr>\n";
1022 }
1023
1024 $out .= '</table>'."\n";
1025
1026 if ($this->withform == 1 || $this->withform == -1) {
1027 $out .= '<div class="center">';
1028 $out .= '<input type="submit" class="button button-add" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
1029 // Add a javascript test to avoid to forget to submit file before sending email
1030 if ($this->withfile == 2 && $conf->use_javascript_ajax) {
1031 $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
1032 }
1033 $out .= ' />';
1034 if ($this->withcancel) {
1035 $out .= '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
1036 }
1037 $out .= '</div>'."\n";
1038 }
1039
1040 if ($this->withform == 1) {
1041 $out .= '</form>'."\n";
1042 }
1043
1044 // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1045 if (getDolGlobalString('MAIN_MAILFORM_DISABLE_ENTERKEY')) {
1046 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
1047 $out .= 'jQuery(document).ready(function () {';
1048 $out .= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is called at every key pressed ! */
1049 var code = e.keyCode || e.which;
1050 if (code == 13) {
1051 console.log("Enter was intercepted and blocked");
1052 e.preventDefault();
1053 return false;
1054 }
1055 });';
1056 $out .= ' })';
1057 $out .= '</script>';
1058 }
1059
1060 $out .= "<!-- End form mail -->\n";
1061
1062 return $out;
1063 }
1064 }
1065
1071 public function getHtmlForTo()
1072 {
1073 global $langs, $form;
1074 $out = '<tr><td class="fieldrequired">';
1075 if ($this->withtofree) {
1076 $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1077 } else {
1078 $out .= $langs->trans("MailTo");
1079 }
1080 $out .= '</td><td>';
1081 if ($this->withtoreadonly) {
1082 if (!empty($this->toname) && !empty($this->tomail)) {
1083 $out .= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
1084 $out .= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
1085 if ($this->totype == 'thirdparty') {
1086 $soc = new Societe($this->db);
1087 $soc->fetch($this->toid);
1088 $out .= $soc->getNomUrl(1);
1089 } elseif ($this->totype == 'contact') {
1090 $contact = new Contact($this->db);
1091 $contact->fetch($this->toid);
1092 $out .= $contact->getNomUrl(1);
1093 } else {
1094 $out .= $this->toname;
1095 }
1096 $out .= ' &lt;'.$this->tomail.'&gt;';
1097 if ($this->withtofree) {
1098 $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) : "").'" />';
1099 }
1100 } else {
1101 // Note withto may be a text like 'AllRecipientSelected'
1102 $out .= (!is_array($this->withto) && !is_numeric($this->withto)) ? $this->withto : "";
1103 }
1104 } else {
1105 // The free input of email
1106 if (!empty($this->withtofree)) {
1107 $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) : "")).'" />';
1108 }
1109 // The select combo
1110 if (!empty($this->withto) && is_array($this->withto)) {
1111 if (!empty($this->withtofree)) {
1112 $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1113 }
1114
1115 $tmparray = $this->withto;
1116 foreach ($tmparray as $key => $val) {
1117 if (is_array($val)) {
1118 $label = $val['label'];
1119 } else {
1120 $label = $val;
1121 }
1122
1123 $tmparray[$key] = array();
1124 $tmparray[$key]['id'] = $key;
1125
1126 $tmparray[$key]['label'] = $label;
1127 $tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
1128 // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1129 $tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8', true);
1130
1131 $tmparray[$key]['labelhtml'] = $label;
1132 $tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
1133 $tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
1134 }
1135
1136 $withtoselected = GETPOST("receiver", 'array'); // Array of selected value
1137 if (!getDolGlobalInt('MAIN_MAIL_NO_WITH_TO_SELECTED')) {
1138 if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
1139 $withtoselected = array_keys($tmparray);
1140 }
1141 }
1142
1143 $out .= $form->multiselectarray("receiver", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', 0, 0);
1144 }
1145 }
1146 $out .= "</td></tr>\n";
1147 return $out;
1148 }
1149
1155 public function getHtmlForCc()
1156 {
1157 global $langs, $form;
1158 $out = '<tr><td>';
1159 $out .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1160 $out .= '</td><td>';
1161 if ($this->withtoccreadonly) {
1162 $out .= (!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : "";
1163 } else {
1164 $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 : '')).'" />';
1165 if (!empty($this->withtocc) && is_array($this->withtocc)) {
1166 $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1167
1168 $tmparray = $this->withtocc;
1169 foreach ($tmparray as $key => $val) {
1170 if (is_array($val)) {
1171 $label = $val['label'];
1172 } else {
1173 $label = $val;
1174 }
1175
1176 $tmparray[$key] = array();
1177 $tmparray[$key]['id'] = $key;
1178
1179 $tmparray[$key]['label'] = $label;
1180 $tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
1181 // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1182 $tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8', true);
1183
1184 $tmparray[$key]['labelhtml'] = $label;
1185 $tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
1186 $tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
1187 }
1188
1189 $withtoccselected = GETPOST("receivercc", 'array'); // Array of selected value
1190
1191 $out .= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, null, null, 'inline-block minwidth500', 0, 0);
1192 }
1193 }
1194 $out .= "</td></tr>\n";
1195 return $out;
1196 }
1197
1203 public function getHtmlForWithCcc()
1204 {
1205 global $conf, $langs, $form;
1206
1207 $out = '<tr><td>';
1208 $out .= $form->textwithpicto($langs->trans("MailCCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1209 $out .= '</td><td>';
1210 if (!empty($this->withtocccreadonly)) {
1211 $out .= (!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : "";
1212 } else {
1213 $out .= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.(GETPOSTISSET("sendtoccc") ? GETPOST("sendtoccc", "alpha") : ((!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />';
1214 if (!empty($this->withtoccc) && is_array($this->withtoccc)) {
1215 $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1216
1217 $tmparray = $this->withtoccc;
1218 foreach ($tmparray as $key => $val) {
1219 if (is_array($val)) {
1220 $label = $val['label'];
1221 } else {
1222 $label = $val;
1223 }
1224 $tmparray[$key] = array();
1225 $tmparray[$key]['id'] = $key;
1226
1227 $tmparray[$key]['label'] = $label;
1228 $tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
1229 // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1230 $tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8', true);
1231
1232 $tmparray[$key]['labelhtml'] = $label;
1233 $tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
1234 $tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
1235 }
1236
1237 $withtocccselected = GETPOST("receiverccc", 'array'); // Array of selected value
1238
1239 $out .= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, null, null, 'inline-block minwidth500', 0, 0);
1240 }
1241 }
1242
1243 $showinfobcc = '';
1244 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROPOSAL_TO') && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
1245 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROPOSAL_TO');
1246 }
1247 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_ORDER_TO') && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
1248 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_ORDER_TO');
1249 }
1250 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_INVOICE_TO') && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
1251 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_INVOICE_TO');
1252 }
1253 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO') && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
1254 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO');
1255 }
1256 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO') && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
1257 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO');
1258 }
1259 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO') && !empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') {
1260 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO');
1261 }
1262 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROJECT_TO') && !empty($this->param['models']) && $this->param['models'] == 'project') {
1263 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROJECT_TO');
1264 }
1265 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SHIPMENT_TO') && !empty($this->param['models']) && $this->param['models'] == 'shipping_send') {
1266 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SHIPMENT_TO');
1267 }
1268 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_RECEPTION_TO') && !empty($this->param['models']) && $this->param['models'] == 'reception_send') {
1269 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_RECEPTION_TO');
1270 }
1271 if ($showinfobcc) {
1272 $out .= ' + '.$showinfobcc;
1273 }
1274 $out .= "</td></tr>\n";
1275 return $out;
1276 }
1277
1283 public function getHtmlForWithErrorsTo()
1284 {
1285 global $conf, $langs;
1286 //if (! $this->errorstomail) $this->errorstomail=$this->frommail;
1287 $errorstomail = getDolGlobalString('MAIN_MAIL_ERRORS_TO', (!empty($this->errorstomail) ? $this->errorstomail : ''));
1288 if ($this->witherrorstoreadonly) {
1289 $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1290 $out .= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1291 $out .= $errorstomail;
1292 $out .= "</td></tr>\n";
1293 } else {
1294 $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1295 $out .= '<input class="minwidth200" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1296 $out .= "</td></tr>\n";
1297 }
1298 return $out;
1299 }
1300
1306 public function getHtmlForDeliveryreceipt()
1307 {
1308 global $conf, $langs;
1309 $out = '<tr><td><label for="deliveryreceipt">'.$langs->trans("DeliveryReceipt").'</label></td><td>';
1310
1311 if (!empty($this->withdeliveryreceiptreadonly)) {
1312 $out .= yn($this->withdeliveryreceipt);
1313 } else {
1314 $defaultvaluefordeliveryreceipt = 0;
1315 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_PROPAL') && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
1316 $defaultvaluefordeliveryreceipt = 1;
1317 }
1318 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL') && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
1319 $defaultvaluefordeliveryreceipt = 1;
1320 }
1321 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_ORDER') && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
1322 $defaultvaluefordeliveryreceipt = 1;
1323 }
1324 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_INVOICE') && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
1325 $defaultvaluefordeliveryreceipt = 1;
1326 }
1327 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_ORDER') && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
1328 $defaultvaluefordeliveryreceipt = 1;
1329 }
1330 //$out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1);
1331 $out .= '<input type="checkbox" id="deliveryreceipt" name="deliveryreceipt" value="1"'.((GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt) ? ' checked="checked"' : '').'>';
1332 }
1333 $out .= "</td></tr>\n";
1334 return $out;
1335 }
1336
1344 public function getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
1345 {
1346 global $conf, $langs, $form;
1347
1348 $defaulttopic = GETPOST('subject', 'restricthtml');
1349
1350 if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
1351 if ($arraydefaultmessage && $arraydefaultmessage->topic) {
1352 $defaulttopic = $arraydefaultmessage->topic;
1353 } elseif (!is_numeric($this->withtopic)) {
1354 $defaulttopic = $this->withtopic;
1355 }
1356 }
1357
1358 $defaulttopic = make_substitutions($defaulttopic, $this->substit);
1359
1360 $out = '<tr>';
1361 $out .= '<td class="fieldrequired">';
1362 $out .= $form->textwithpicto($langs->trans('MailTopic'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
1363 $out .= '</td>';
1364 $out .= '<td>';
1365 if ($this->withtopicreadonly) {
1366 $out .= $defaulttopic;
1367 $out .= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
1368 } else {
1369 $out .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'.((GETPOSTISSET("subject") && !GETPOST('modelselected')) ? GETPOST("subject") : ($defaulttopic ? $defaulttopic : '')).'" />';
1370 }
1371 $out .= "</td></tr>\n";
1372 return $out;
1373 }
1374
1392 public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '', $defaultfortype = -1)
1393 {
1394 global $conf;
1395
1396 if ($id == -2 && empty($label)) {
1397 $this->error = 'LabelIsMandatoryWhenIdIs-2or-3';
1398 return -1;
1399 }
1400
1401 $ret = new ModelMail();
1402
1403 $languagetosearch = (is_object($outputlangs) ? $outputlangs->defaultlang : '');
1404 // Define $languagetosearchmain to fall back on main language (for example to get 'es_ES' for 'es_MX')
1405 $tmparray = explode('_', $languagetosearch);
1406 $languagetosearchmain = $tmparray[0].'_'.strtoupper($tmparray[0]);
1407 if ($languagetosearchmain == $languagetosearch) {
1408 $languagetosearchmain = '';
1409 }
1410
1411 $sql = "SELECT rowid, module, label, type_template, topic, email_from, joinfiles, content, content_lines, lang, email_from, email_to, email_tocc, email_tobcc";
1412 $sql .= " FROM ".$dbs->prefix().'c_email_templates';
1413 $sql .= " WHERE (type_template = '".$dbs->escape($type_template)."' OR type_template = 'all')";
1414 $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1415 $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // Get all public or private owned
1416 if ($active >= 0) {
1417 $sql .= " AND active = ".((int) $active);
1418 }
1419 if ($defaultfortype >= 0) {
1420 $sql .= " AND defaultfortype = ".((int) $defaultfortype);
1421 }
1422 if ($label) {
1423 $sql .= " AND label = '".$dbs->escape($label)."'";
1424 }
1425 if (!($id > 0) && $languagetosearch) {
1426 $sql .= " AND (lang = '".$dbs->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$dbs->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
1427 }
1428 if ($id > 0) {
1429 $sql .= " AND rowid = ".(int) $id;
1430 }
1431 if ($id == -1) {
1432 $sql .= " AND position = 0";
1433 }
1434 if ($languagetosearch) {
1435 $sql .= $dbs->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or ''
1436 } else {
1437 $sql .= $dbs->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined
1438 }
1439 //$sql .= $dbs->plimit(1);
1440 //print $sql;
1441
1442 $resql = $dbs->query($sql);
1443 if (!$resql) {
1444 dol_print_error($dbs);
1445 return -1;
1446 }
1447
1448 // Get first found
1449 while (1) {
1450 $obj = $dbs->fetch_object($resql);
1451
1452 if ($obj) {
1453 // If template is for a module, check module is enabled; if not, take next template
1454 if ($obj->module) {
1455 $tempmodulekey = $obj->module;
1456 if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
1457 continue;
1458 }
1459 }
1460
1461 // If a record was found
1462 $ret->id = $obj->rowid;
1463 $ret->module = $obj->module;
1464 $ret->label = $obj->label;
1465 $ret->lang = $obj->lang;
1466 $ret->topic = $obj->topic;
1467 $ret->content = $obj->content;
1468 $ret->content_lines = $obj->content_lines;
1469 $ret->joinfiles = $obj->joinfiles;
1470 $ret->email_from = $obj->email_from;
1471
1472 break;
1473 } else {
1474 // If no record found
1475 if ($id == -2) {
1476 // Not found with the provided label
1477 return -1;
1478 } else {
1479 // If there is no template at all
1480 $defaultmessage = '';
1481
1482 if ($type_template == 'body') {
1483 // Special case to use this->withbody as content
1484 $defaultmessage = $this->withbody;
1485 } elseif ($type_template == 'facture_send') {
1486 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoice");
1487 } elseif ($type_template == 'facture_relance') {
1488 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder");
1489 } elseif ($type_template == 'propal_send') {
1490 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendProposal");
1491 } elseif ($type_template == 'supplier_proposal_send') {
1492 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal");
1493 } elseif ($type_template == 'order_send') {
1494 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendOrder");
1495 } elseif ($type_template == 'order_supplier_send') {
1496 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder");
1497 } elseif ($type_template == 'invoice_supplier_send') {
1498 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice");
1499 } elseif ($type_template == 'shipping_send') {
1500 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendShipping");
1501 } elseif ($type_template == 'fichinter_send') {
1502 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendFichInter");
1503 } elseif ($type_template == 'actioncomm_send') {
1504 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm");
1505 } elseif (!empty($type_template)) {
1506 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric");
1507 }
1508
1509 $ret->label = 'default';
1510 $ret->lang = $outputlangs->defaultlang;
1511 $ret->topic = '';
1512 $ret->joinfiles = 1;
1513 $ret->content = $defaultmessage;
1514 $ret->content_lines = '';
1515
1516 break;
1517 }
1518 }
1519 }
1520
1521 $dbs->free($resql);
1522
1523 return $ret;
1524 }
1525
1535 public function isEMailTemplate($type_template, $user, $outputlangs)
1536 {
1537 $sql = "SELECT label, topic, content, lang";
1538 $sql .= " FROM ".$this->db->prefix().'c_email_templates';
1539 $sql .= " WHERE type_template='".$this->db->escape($type_template)."'";
1540 $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1541 $sql .= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".((int) $user->id).")";
1542 if (is_object($outputlangs)) {
1543 $sql .= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
1544 }
1545 $sql .= $this->db->order("lang,label", "ASC");
1546 //print $sql;
1547
1548 $resql = $this->db->query($sql);
1549 if ($resql) {
1550 $num = $this->db->num_rows($resql);
1551 $this->db->free($resql);
1552 return $num;
1553 } else {
1554 $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1555 return -1;
1556 }
1557 }
1558
1569 public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active = 1)
1570 {
1571 global $conf;
1572
1573 $sql = "SELECT rowid, module, label, topic, content, content_lines, lang, fk_user, private, position";
1574 $sql .= " FROM ".$this->db->prefix().'c_email_templates';
1575 $sql .= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1576 $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1577 $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // See all public templates or templates I own.
1578 if ($active >= 0) {
1579 $sql .= " AND active = ".((int) $active);
1580 }
1581 //if (is_object($outputlangs)) $sql.= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')"; // Return all languages
1582 $sql .= $this->db->order("position,lang,label", "ASC");
1583 //print $sql;
1584
1585 $resql = $this->db->query($sql);
1586 if ($resql) {
1587 $num = $this->db->num_rows($resql);
1588 $this->lines_model = array();
1589 while ($obj = $this->db->fetch_object($resql)) {
1590 // If template is for a module, check module is enabled.
1591 if ($obj->module) {
1592 $tempmodulekey = $obj->module;
1593 if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
1594 continue;
1595 }
1596 }
1597
1598 $line = new ModelMail();
1599 $line->id = $obj->rowid;
1600 $line->label = $obj->label;
1601 $line->lang = $obj->lang;
1602 $line->fk_user = $obj->fk_user;
1603 $line->private = $obj->private;
1604 $line->position = $obj->position;
1605 $line->topic = $obj->topic;
1606 $line->content = $obj->content;
1607 $line->content_lines = $obj->content_lines;
1608
1609 $this->lines_model[] = $line;
1610 }
1611 $this->db->free($resql);
1612 return $num;
1613 } else {
1614 $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1615 return -1;
1616 }
1617 }
1618
1619
1620
1629 public function setSubstitFromObject($object, $outputlangs)
1630 {
1631 global $conf, $user, $extrafields;
1632
1633 $parameters = array();
1634 $tmparray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
1635 complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
1636
1637 $this->substit = $tmparray;
1638
1639 // Fill substit_lines with each object lines content
1640 if (is_array($object->lines)) {
1641 foreach ($object->lines as $line) {
1642 $substit_line = array(
1643 '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1644 '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1645 '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1646 '__LABEL__' => isset($line->label) ? $line->label : '',
1647 '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1648 '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
1649 '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
1650 '__QUANTITY__' => $line->qty,
1651 '__SUBPRICE__' => price($line->subprice),
1652 '__AMOUNT__' => price($line->total_ttc),
1653 '__AMOUNT_EXCL_TAX__' => price($line->total_ht)
1654 );
1655
1656 // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1657 if (!empty($line->fk_product)) {
1658 if (!is_object($extrafields)) {
1659 $extrafields = new ExtraFields($this->db);
1660 }
1661 $product = new Product($this->db);
1662 $product->fetch($line->fk_product, '', '', 1);
1663 $product->fetch_optionals();
1664
1665 $extrafields->fetch_name_optionals_label($product->table_element, true);
1666
1667 if (!empty($extrafields->attributes[$product->table_element]['label']) && is_array($extrafields->attributes[$product->table_element]['label']) && count($extrafields->attributes[$product->table_element]['label']) > 0) {
1668 foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
1669 $substit_line['__PRODUCT_EXTRAFIELD_'.strtoupper($key).'__'] = isset($product->array_options['options_'.$key]) ? $product->array_options['options_'.$key] : '';
1670 }
1671 }
1672 }
1673 $this->substit_lines[] = $substit_line;
1674 }
1675 }
1676 }
1677
1686 public static function getAvailableSubstitKey($mode = 'formemail', $object = null)
1687 {
1688 global $conf, $langs;
1689
1690 $tmparray = array();
1691 if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines') {
1692 $parameters = array('mode'=>$mode);
1693 $tmparray = getCommonSubstitutionArray($langs, 2, null, $object); // Note: On email templated edition, this is null because it is related to all type of objects
1694 complete_substitutions_array($tmparray, $langs, null, $parameters);
1695
1696 if ($mode == 'formwithlines') {
1697 $tmparray['__LINES__'] = '__LINES__'; // Will be set by the get_form function
1698 }
1699 if ($mode == 'formforlines') {
1700 $tmparray['__QUANTITY__'] = '__QUANTITY__'; // Will be set by the get_form function
1701 }
1702 }
1703
1704 if ($mode == 'emailing') {
1705 $parameters = array('mode'=>$mode);
1706 $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
1707 complete_substitutions_array($tmparray, $langs, null, $parameters);
1708
1709 // For mass emailing, we have different keys specific to the data into tagerts list
1710 $tmparray['__ID__'] = 'IdRecord';
1711 $tmparray['__THIRDPARTY_CUSTOMER_CODE__'] = 'CustomerCode';
1712 $tmparray['__EMAIL__'] = 'EMailRecipient';
1713 $tmparray['__LASTNAME__'] = 'Lastname';
1714 $tmparray['__FIRSTNAME__'] = 'Firstname';
1715 $tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
1716 $tmparray['__OTHER1__'] = 'Other1';
1717 $tmparray['__OTHER2__'] = 'Other2';
1718 $tmparray['__OTHER3__'] = 'Other3';
1719 $tmparray['__OTHER4__'] = 'Other4';
1720 $tmparray['__OTHER5__'] = 'Other5';
1721 $tmparray['__CHECK_READ__'] = $langs->trans('TagCheckMail');
1722 $tmparray['__UNSUBSCRIBE__'] = $langs->trans('TagUnsubscribe');
1723 $tmparray['__UNSUBSCRIBE_URL__'] = $langs->trans('TagUnsubscribe').' (URL)';
1724
1725 $onlinepaymentenabled = 0;
1726 if (isModEnabled('paypal')) {
1727 $onlinepaymentenabled++;
1728 }
1729 if (isModEnabled('paybox')) {
1730 $onlinepaymentenabled++;
1731 }
1732 if (isModEnabled('stripe')) {
1733 $onlinepaymentenabled++;
1734 }
1735 if ($onlinepaymentenabled && getDolGlobalString('PAYMENT_SECURITY_TOKEN')) {
1736 $tmparray['__SECUREKEYPAYMENT__'] = $conf->global->PAYMENT_SECURITY_TOKEN;
1737 if (getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')) {
1738 if (isModEnabled('adherent')) {
1739 $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
1740 }
1741 if (isModEnabled('don')) {
1742 $tmparray['__SECUREKEYPAYMENT_DONATION__'] = 'SecureKeyPAYMENTUniquePerDonation';
1743 }
1744 if (isModEnabled('facture')) {
1745 $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
1746 }
1747 if (isModEnabled('commande')) {
1748 $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
1749 }
1750 if (isModEnabled('contrat')) {
1751 $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
1752 }
1753
1754 //Online payment link
1755 if (isModEnabled('adherent')) {
1756 $tmparray['__ONLINEPAYMENTLINK_MEMBER__'] = 'OnlinePaymentLinkUniquePerMember';
1757 }
1758 if (isModEnabled('don')) {
1759 $tmparray['__ONLINEPAYMENTLINK_DONATION__'] = 'OnlinePaymentLinkUniquePerDonation';
1760 }
1761 if (isModEnabled('facture')) {
1762 $tmparray['__ONLINEPAYMENTLINK_INVOICE__'] = 'OnlinePaymentLinkUniquePerInvoice';
1763 }
1764 if (isModEnabled('commande')) {
1765 $tmparray['__ONLINEPAYMENTLINK_ORDER__'] = 'OnlinePaymentLinkUniquePerOrder';
1766 }
1767 if (isModEnabled('contrat')) {
1768 $tmparray['__ONLINEPAYMENTLINK_CONTRACTLINE__'] = 'OnlinePaymentLinkUniquePerContractLine';
1769 }
1770 }
1771 } else {
1772 /* No need to show into tooltip help, option is not enabled
1773 $vars['__SECUREKEYPAYMENT__']='';
1774 $vars['__SECUREKEYPAYMENT_MEMBER__']='';
1775 $vars['__SECUREKEYPAYMENT_INVOICE__']='';
1776 $vars['__SECUREKEYPAYMENT_ORDER__']='';
1777 $vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
1778 */
1779 }
1780 if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
1781 $tmparray['__PUBLICLINK_NEWMEMBERFORM__'] = 'BlankSubscriptionForm';
1782 }
1783 }
1784
1785 foreach ($tmparray as $key => $val) {
1786 if (empty($val)) {
1787 $tmparray[$key] = $key;
1788 }
1789 }
1790
1791 return $tmparray;
1792 }
1793}
1794
1795
1801class ModelMail
1802{
1806 public $id;
1807
1811 public $label;
1812
1816 public $fk_user;
1817
1821 public $private;
1822
1826 public $topic;
1827
1831 public $content;
1832 public $content_lines;
1833 public $lang;
1834 public $joinfiles;
1835
1836 public $email_from;
1837 public $email_to;
1838 public $email_tocc;
1839 public $email_tobcc;
1840
1844 public $module;
1845
1849 public $position;
1850}
Class to manage a WYSIWYG editor.
Class to offer components to list and upload files.
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)
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.
getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id=0, $active=1, $label='', $defaultfortype=-1)
Return templates of email with type = $type_template or type = 'all'.
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.
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)
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
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.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return a 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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
rtl background position
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
Definition invoice.php:1926
ui dialog ui datepicker calendar ui widget content ui state ui datepicker calendar ui widget header ui state ui datepicker calendar ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
getMaxFileSizeArray()
Return the max allowed for file upload.