dolibarr 22.0.5
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-2024 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
9 * Copyright (C) 2023 Anthony Berton <anthony.berton@bb2a.fr>
10 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
32require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
33
34
41class FormMail extends Form
42{
46 public $db;
47
53 public $withform;
54
58 public $fromname;
59
63 public $frommail;
64
68 public $fromtype;
69
73 public $fromid;
74
78 public $fromalsorobot;
79
83 public $totype;
84
88 public $toid;
89
93 public $replytoname;
94
98 public $replytomail;
99
103 public $toname;
104
108 public $tomail;
109
113 public $trackid;
114
118 public $inreplyto;
119
123 public $withsubstit; // Show substitution array
127 public $withfrom;
128
132 public $withto; // Show recipient emails
136 public $withreplyto;
137
143 public $withtofree;
147 public $withtocc;
151 public $withtoccc;
155 public $withtopic;
159 public $witherrorsto;
160
164 public $withfile;
165
169 public $withlayout;
170
174 public $withaiprompt;
175
179 public $withmaindocfile;
183 public $withbody;
184
188 public $withfromreadonly;
192 public $withreplytoreadonly;
196 public $withtoreadonly;
200 public $withtoccreadonly;
204 public $witherrorstoreadonly;
208 public $withtocccreadonly;
212 public $withtopicreadonly;
216 public $withbodyreadonly;
220 public $withfilereadonly;
224 public $withdeliveryreceipt;
228 public $withcancel;
232 public $withdeliveryreceiptreadonly;
236 public $withfckeditor;
237
241 public $ckeditortoolbar;
242
246 public $substit = array();
247
251 public $substit_lines = array();
252
256 public $param = array();
257
261 public $withtouser = array();
265 public $withtoccuser = array();
266
270 public $lines_model;
271
275 public $withoptiononeemailperrecipient;
276
277
283 public function __construct($db)
284 {
285 $this->db = $db;
286
287 $this->withform = 1;
288
289 $this->withfrom = 1;
290 $this->withto = 1;
291 $this->withtofree = 1;
292 $this->withtocc = 1;
293 $this->withtoccc = '0';
294 $this->witherrorsto = 0;
295 $this->withtopic = 1;
296 $this->withfile = 0; // 1=Add section "Attached files". 2=Can add files.
297 $this->withmaindocfile = 0; // 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
298 $this->withbody = 1;
299
300 $this->withfromreadonly = 1;
301 $this->withreplytoreadonly = 1;
302 $this->withtoreadonly = 0;
303 $this->withtoccreadonly = 0;
304 $this->withtocccreadonly = 0;
305 $this->witherrorstoreadonly = 0;
306 $this->withtopicreadonly = 0;
307 $this->withfilereadonly = 0;
308 $this->withbodyreadonly = 0;
309 $this->withdeliveryreceiptreadonly = 0;
310 $this->withfckeditor = -1; // -1 = Auto
311 }
312
313 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
319 public function clear_attached_files()
320 {
321 // phpcs:enable
322 global $conf, $user;
323 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
324
325 // Set tmp user directory
326 $vardir = $conf->user->dir_output."/".$user->id;
327 $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
328 if (is_dir($upload_dir)) {
329 dol_delete_dir_recursive($upload_dir);
330 }
331
332 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
333 unset($_SESSION["listofpaths".$keytoavoidconflict]);
334 unset($_SESSION["listofnames".$keytoavoidconflict]);
335 unset($_SESSION["listofmimes".$keytoavoidconflict]);
336 }
337
338 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
347 public function add_attached_files($path, $file = '', $type = '')
348 {
349 // phpcs:enable
350 $listofpaths = array();
351 $listofnames = array();
352 $listofmimes = array();
353
354 if (empty($file)) {
355 $file = basename($path);
356 }
357 if (empty($type)) {
358 $type = dol_mimetype($file);
359 }
360
361 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
362 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
363 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
364 }
365 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
366 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
367 }
368 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
369 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
370 }
371 if (!in_array($file, $listofnames)) {
372 $listofpaths[] = $path;
373 $listofnames[] = $file;
374 $listofmimes[] = $type;
375 $_SESSION["listofpaths".$keytoavoidconflict] = implode(';', $listofpaths);
376 $_SESSION["listofnames".$keytoavoidconflict] = implode(';', $listofnames);
377 $_SESSION["listofmimes".$keytoavoidconflict] = implode(';', $listofmimes);
378 }
379 }
380
381 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
388 public function remove_attached_files($keytodelete)
389 {
390 // phpcs:enable
391 $listofpaths = array();
392 $listofnames = array();
393 $listofmimes = array();
394
395 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
396 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
397 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
398 }
399 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
400 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
401 }
402 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
403 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
404 }
405 if ($keytodelete >= 0) {
406 unset($listofpaths[$keytodelete]);
407 unset($listofnames[$keytodelete]);
408 unset($listofmimes[$keytodelete]);
409 $_SESSION["listofpaths".$keytoavoidconflict] = implode(';', $listofpaths);
410 $_SESSION["listofnames".$keytoavoidconflict] = implode(';', $listofnames);
411 $_SESSION["listofmimes".$keytoavoidconflict] = implode(';', $listofmimes);
412 //var_dump($_SESSION['listofpaths']);
413 }
414 }
415
416 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
422 public function get_attached_files()
423 {
424 // phpcs:enable
425 $listofpaths = array();
426 $listofnames = array();
427 $listofmimes = array();
428
429 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
430 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
431 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
432 }
433 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
434 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
435 }
436 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
437 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
438 }
439 return array('paths' => $listofpaths, 'names' => $listofnames, 'mimes' => $listofmimes);
440 }
441
442 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
453 public function show_form($addfileaction = 'addfile', $removefileaction = 'removefile')
454 {
455 // phpcs:enable
456 print $this->get_form($addfileaction, $removefileaction);
457 }
458
459 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
470 public function get_form($addfileaction = 'addfile', $removefileaction = 'removefile')
471 {
472 // phpcs:enable
473 global $conf, $langs, $user, $hookmanager, $form;
474
475 if (!is_object($form)) {
476 $form = new Form($this->db);
477 }
478
479 // Required to show editor assistants
480 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
481 $formfile = new FormFile($this->db);
482
483 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formai.class.php';
484 $formai = new FormAI($this->db);
485
486 // Load translation files required by the page
487 $langs->loadLangs(array('other', 'mails', 'members'));
488
489 // Clear temp files. Must be done before call of triggers, at beginning (mode = init), or when we select a new template
490 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
491 $this->clear_attached_files();
492 }
493
494 // Call hook getFormMail
495 $hookmanager->initHooks(array('formmail'));
496
497 $parameters = array(
498 'addfileaction' => $addfileaction,
499 'removefileaction' => $removefileaction,
500 'trackid' => $this->trackid
501 );
502 $reshook = $hookmanager->executeHooks('getFormMail', $parameters, $this);
503
504 if (!empty($reshook)) {
505 return $hookmanager->resPrint;
506 } else {
507 $out = '';
508
509 $disablebademails = 1;
510
511 // Define output language
512 $outputlangs = $langs;
513 $newlang = '';
514 if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($this->param['langsmodels'])) {
515 $newlang = $this->param['langsmodels'];
516 }
517 if (!empty($newlang)) {
518 $outputlangs = new Translate("", $conf);
519 $outputlangs->setDefaultLang($newlang);
520 $outputlangs->load('other');
521 }
522
523 // Get message template for $this->param["models"] into c_email_templates
524 $arraydefaultmessage = -1;
525 if ($this->param['models'] != 'none') {
526 $model_id = 0;
527 if (array_key_exists('models_id', $this->param)) {
528 $model_id = $this->param["models_id"];
529 }
530
531 $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
532 }
533
534 // Define list of attached files
535 $listofpaths = array();
536 $listofnames = array();
537 $listofmimes = array();
538 $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
539
540 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
541 if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
542 foreach ($this->param['fileinit'] as $path) {
543 if (!empty($path)) {
544 $this->add_attached_files($path);
545 }
546 }
547 }
548 }
549
550 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
551 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
552 }
553 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
554 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
555 }
556 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
557 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
558 }
559
560
561 $out .= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
562 if ($this->withform == 1) {
563 $out .= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
564
565 $out .= '<a id="formmail" name="formmail"></a>';
566 $out .= '<input style="display:none" type="submit" id="sendmailhidden" name="sendmail">';
567 $out .= '<input type="hidden" name="token" value="'.newToken().'" />';
568 $out .= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
569 $out .= '<input type="hidden" name="inreplyto" value="'.$this->inreplyto.'" />';
570 }
571 if (!empty($this->withfrom)) {
572 if (!empty($this->withfromreadonly)) {
573 $out .= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
574 $out .= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
575 }
576 }
577 foreach ($this->param as $key => $value) {
578 if (is_array($value)) {
579 $out .= "<!-- param key=".$key." is array, we do not output input field for it -->\n";
580 } else {
581 $out .= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
582 }
583 }
584
585 $modelmail_array = array();
586 if ($this->param['models'] != 'none') {
587 $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
588 if ($result < 0) {
589 setEventMessages($this->error, $this->errors, 'errors');
590 }
591
592 foreach ($this->lines_model as $line) {
593 $reg = array();
594 if (preg_match('/\‍((.*)\‍)/', $line->label, $reg)) {
595 $labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__
596 } else {
597 $labeltouse = $line->label;
598 }
599
600 // We escape the $labeltouse to store it into $modelmail_array.
601 $modelmail_array[$line->id] = dol_escape_htmltag($labeltouse);
602 if ($line->lang) {
603 $modelmail_array[$line->id] .= ' '.picto_from_langcode($line->lang);
604 }
605 if ($line->private) {
606 $modelmail_array[$line->id] .= ' - <span class="opacitymedium">'.dol_escape_htmltag($langs->trans("Private")).'</span>';
607 }
608 }
609 }
610
611 // Zone to select email template
612 if (count($modelmail_array) > 0) {
613 $model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOSTINT('modelmailselected') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0);
614
615 // If list of template is filled
616 $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
617
618 $out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, $langs->trans('SelectMailModel'), 0, 0, '', 0, 0, 0, '', 'minwidth100', 1, '', 0, 1);
619 if ($user->admin) {
620 $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
621 }
622
623 $out .= ' &nbsp; ';
624 $out .= '<input type="submit" class="button reposition smallpaddingimp" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
625 $out .= ' &nbsp; ';
626 $out .= '</div>';
627 } elseif (!empty($this->param['models']) && in_array($this->param['models'], array(
628 'propal_send', 'order_send', 'facture_send',
629 'shipping_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send',
630 'invoice_supplier_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'product_send', 'all'
631 ))) {
632 // If list of template is empty
633 $out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
634 $out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
635 $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.
636 if ($user->admin) {
637 $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
638 }
639 $out .= ' &nbsp; ';
640 $out .= '<input type="submit" class="button reposition smallpaddingimp" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
641 $out .= ' &nbsp; ';
642 $out .= '</div>';
643 } else {
644 $out .= '<!-- No template available for $this->param["models"] = '.$this->param['models'].' -->';
645 }
646
647
648 $out .= '<table class="tableforemailform boxtablenotop centpercent">'."\n";
649
650 // Substitution array/string
651 $helpforsubstitution = '';
652 if (is_array($this->substit) && count($this->substit)) {
653 $helpforsubstitution .= $langs->trans('AvailableVariables').' :<br><br><span class="small">'."\n";
654 }
655 foreach ($this->substit as $key => $val) {
656 // Do not show deprecated variables into the tooltip help of substitution variables
657 if (in_array($key, array('__NEWREF__', '__REFCLIENT__', '__REFSUPPLIER__', '__SUPPLIER_ORDER_DATE_DELIVERY__', '__SUPPLIER_ORDER_DELAY_DELIVERY__'))) {
658 continue;
659 }
660 $helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText((string) $val))).'<br>';
661 }
662 if (is_array($this->substit) && count($this->substit)) {
663 $helpforsubstitution .= '</span>';
664 }
665
666 /*
667 if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this.
668 $out .= '<tr><td colspan="2" class="right">';
669 if (is_numeric($this->withsubstit)) {
670 $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
671 } else {
672 $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
673 }
674 $out .= "</td></tr>\n";
675 }*/
676
677 // From
678 if (!empty($this->withfrom)) {
679 if (!empty($this->withfromreadonly)) {
680 $out .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
681
682 // $this->fromtype is the default value to use to select sender
683 if (!($this->fromtype === 'user' && $this->fromid > 0)
684 && !($this->fromtype === 'company')
685 && !($this->fromtype === 'robot')
686 && !preg_match('/user_aliases/', $this->fromtype)
687 && !preg_match('/global_aliases/', $this->fromtype)
688 && !preg_match('/senderprofile/', $this->fromtype)
689 ) {
690 // Use this->fromname and this->frommail or error if not defined
691 $out .= $this->fromname;
692 if ($this->frommail) {
693 $out .= ' &lt;'.$this->frommail.'&gt;';
694 } else {
695 if ($this->fromtype) {
696 $langs->load('errors');
697 $out .= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
698 }
699 }
700 } else {
701 $liste = array();
702
703 // Add user email
704 if (empty($user->email)) {
705 $langs->load('errors');
706 $s = $user->getFullName($langs).' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
707 } else {
708 $s = $user->getFullName($langs).' &lt;'.$user->email.'&gt;';
709 }
710 $liste['user'] = array('label' => $s, 'data-html' => $s);
711
712 // Add also company main email
713 if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
714 $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;';
715 $liste['company'] = array('label' => $s, 'data-html' => $s);
716 }
717
718 // Add also email aliases if there is some
719 $listaliases = array(
720 'user_aliases' => (empty($user->email_aliases) ? '' : $user->email_aliases),
721 'global_aliases' => getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'),
722 );
723
724 if (!empty($arraydefaultmessage->email_from)) {
725 $templatemailfrom = ' &lt;'.$arraydefaultmessage->email_from.'&gt;';
726 $liste['from_template_'.$arraydefaultmessage->id] = array('label' => $templatemailfrom, 'data-html' => $templatemailfrom);
727 }
728
729 // Also add robot email
730 if (!empty($this->fromalsorobot)) {
731 if (getDolGlobalString('MAIN_MAIL_EMAIL_FROM') && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
732 $s = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
733 if ($this->frommail) {
734 $s .= ' &lt;' . getDolGlobalString('MAIN_MAIL_EMAIL_FROM').'&gt;';
735 }
736 $liste['main_from'] = array('label' => $s, 'data-html' => $s);
737 }
738 }
739
740 // Add also email aliases from the c_email_senderprofile table
741 $sql = "SELECT rowid, label, email FROM ".$this->db->prefix()."c_email_senderprofile";
742 $sql .= " WHERE active = 1 AND (private = 0 OR private = ".((int) $user->id).") AND entity IN (".getEntity('c_email_senderprofile').")";
743 $sql .= " ORDER BY position";
744 $resql = $this->db->query($sql);
745 if ($resql) {
746 $num = $this->db->num_rows($resql);
747 $i = 0;
748 while ($i < $num) {
749 $obj = $this->db->fetch_object($resql);
750 if ($obj) {
751 $listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
752 }
753 $i++;
754 }
755 } else {
756 dol_print_error($this->db);
757 }
758
759 foreach ($listaliases as $typealias => $listalias) {
760 $posalias = 0;
761 $listaliasarray = explode(',', $listalias);
762 foreach ($listaliasarray as $listaliasval) {
763 $posalias++;
764 $listaliasval = trim($listaliasval);
765 if ($listaliasval) {
766 $listaliasval = preg_replace('/</', '&lt;', $listaliasval);
767 $listaliasval = preg_replace('/>/', '&gt;', $listaliasval);
768 if (!preg_match('/&lt;/', $listaliasval)) {
769 $listaliasval = '&lt;'.$listaliasval.'&gt;';
770 }
771 $liste[$typealias.'_'.$posalias] = array('label' => $listaliasval, 'data-html' => $listaliasval);
772 }
773 }
774 }
775
776 // Using ajaxcombo here make the '<email>' no more visible on list because <emailofuser> is not a valid html tag,
777 // so we transform before each record into $liste to be printable with ajaxcombo by replacing <> into ()
778 // $liste['senderprofile_0_0'] = array('label'=>'rrr', 'data-html'=>'rrr &lt;aaaa&gt;');
779 foreach ($liste as $key => $val) {
780 if (!empty($liste[$key]['data-html'])) {
781 $liste[$key]['data-html'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $liste[$key]['data-html']);
782 $liste[$key]['data-html'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $liste[$key]['data-html']);
783 }
784 }
785 $out .= ' '.$form->selectarray('fromtype', $liste, empty($arraydefaultmessage->email_from) ? $this->fromtype : 'from_template_'.$arraydefaultmessage->id, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
786 }
787
788 $out .= "</td></tr>\n";
789 } else {
790 $out .= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
791 $out .= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
792 $out .= '&nbsp; &nbsp; ';
793 $out .= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
794 $out .= "</td></tr>\n";
795 }
796 }
797
798 // To
799 if (!empty($this->withto) || is_array($this->withto)) {
800 $out .= $this->getHtmlForTo();
801 }
802
803 // To User
804 if (!empty($this->withtouser) && is_array($this->withtouser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) {
805 $out .= '<tr><td>';
806 $out .= $langs->trans("MailToUsers");
807 $out .= '</td><td>';
808
809 // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
810 $tmparray = $this->withtouser;
811 foreach ($tmparray as $key => $val) {
812 $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true);
813 }
814 $withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value
815 if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
816 $withtoselected = array_keys($tmparray);
817 }
818 $out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, "");
819 $out .= "</td></tr>\n";
820 }
821
822 // With option for one email per recipient
823 if (!empty($this->withoptiononeemailperrecipient)) {
824 if (abs($this->withoptiononeemailperrecipient) == 1) {
825 $out .= '<tr><td class="minwidth200">';
826 $out .= $langs->trans("GroupEmails");
827 $out .= '</td><td>';
828 $out .= ' <input type="checkbox" id="oneemailperrecipient" value="1" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> ';
829 $out .= '<label for="oneemailperrecipient">';
830 $out .= $form->textwithpicto($langs->trans("OneEmailPerRecipient"), $langs->trans("WarningIfYouCheckOneRecipientPerEmail"), 1, 'help');
831 $out .= '</label>';
832 //$out .= '<span class="hideonsmartphone opacitymedium">';
833 //$out .= ' - ';
834 //$out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
835 //$out .= '</span>';
836 if (getDolGlobalString('MASS_ACTION_EMAIL_ON_DIFFERENT_THIRPARTIES_ADD_CUSTOM_EMAIL')) {
837 if (!empty($this->withto) && !is_array($this->withto)) {
838 $out .= ' '.$langs->trans("or").' <input type="email" name="emailto" value="">';
839 }
840 }
841 $out .= '</td></tr>';
842 } else {
843 $out .= '<tr><td><input type="hidden" name="oneemailperrecipient" value="1"></td><td></td></tr>';
844 }
845 }
846
847 // CC
848 if (!empty($this->withtocc) || is_array($this->withtocc)) {
849 $out .= $this->getHtmlForCc();
850 }
851
852 // To User cc
853 if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) {
854 $out .= '<tr><td>';
855 $out .= $langs->trans("MailToCCUsers");
856 $out .= '</td><td>';
857
858 // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
859 $tmparray = $this->withtoccuser;
860 foreach ($tmparray as $key => $val) {
861 $tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true);
862 }
863 $withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value
864 if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
865 $withtoselected = array_keys($tmparray);
866 }
867 $out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, "");
868 $out .= "</td></tr>\n";
869 }
870
871 // CCC
872 if (!empty($this->withtoccc) || is_array($this->withtoccc)) {
873 $out .= $this->getHtmlForWithCcc();
874 }
875
876 // Replyto
877 if (!empty($this->withreplyto)) {
878 if ($this->withreplytoreadonly) {
879 $out .= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
880 $out .= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
881 $out .= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail ? (" &lt;".$this->replytomail."&gt;") : "");
882 $out .= "</td></tr>\n";
883 }
884 }
885
886 // Errorsto
887 if (!empty($this->witherrorsto)) {
888 $out .= $this->getHtmlForWithErrorsTo();
889 }
890
891 // Ask delivery receipt
892 if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) {
893 $out .= $this->getHtmlForDeliveryreceipt();
894 }
895
896 // Topic
897 if (!empty($this->withtopic)) {
898 $out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution);
899 }
900
901 // Attached files
902 if (!empty($this->withfile)) {
903 $out .= '<tr>';
904 $out .= '<td class="tdtop">'.$langs->trans("MailFile").'</td>';
905
906 $out .= '<td>';
907
908 if ($this->withmaindocfile) {
909 // withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
910 if (GETPOSTISSET('sendmail')) {
911 $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
912 } elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
913 // If a template was selected, we use setup of template to define if join file checkbox is selected or not.
914 $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
915 }
916 }
917
918 if (!empty($this->withmaindocfile)) {
919 if ($this->withmaindocfile == 1) {
920 $out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" />';
921 } elseif ($this->withmaindocfile == -1) {
922 $out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" checked="checked" />';
923 }
924 if (getDolGlobalString('MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND')) {
925 $out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDocOrLastGenerated").'.</label><br>';
926 } else {
927 $out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDoc").'.</label><br>';
928 }
929 }
930
931 if (is_numeric($this->withfile)) {
932 // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
933 $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
934 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
935 $out .= 'jQuery(document).ready(function () {';
936 $out .= ' jQuery(".removedfile").click(function() {';
937 $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
938 $out .= ' });';
939 $out .= '})';
940 $out .= '</script>'."\n";
941 if (count($listofpaths)) {
942 foreach ($listofpaths as $key => $val) {
943 $relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val)));
944
945 $entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity);
946 if ($entity > 1) {
947 $relativepathtofile = str_replace('/'.$entity.'/', '/', $relativepathtofile);
948 }
949 // Try to extract data from full path
950 $formfile_params = array();
951 preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params);
952
953 $out .= '<div id="attachfile_'.$key.'">';
954 // Preview of attachment
955 $out .= img_mime($listofnames[$key]).$listofnames[$key];
956
957 $out .= ' '.$formfile->showPreview(array(), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity='.((int) $entity)));
958
959 if (!$this->withfilereadonly) {
960 $out .= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key + 1).'" class="removedfile input-nobottom" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
961 //$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).'&id=removedfile_'.$key.'">'.img_delete($langs->trans("Remove"), 'id="removedfile_'.$key.'" name="removedfile_'.$key.'"', 'removedfile input-nobottom').'</a>';
962 }
963 $out .= '<br></div>';
964 }
965 } /*elseif (empty($this->withmaindocfile)) {
966 //$out .= '<span class="opacitymedium">'.$langs->trans("NoAttachedFiles").'</span><br>';
967 }*/
968 if ($this->withfile == 2) {
969 $maxfilesizearray = getMaxFileSizeArray();
970 $maxmin = $maxfilesizearray['maxmin'];
971 if ($maxmin > 0) {
972 $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
973 }
974 // Can add other files
975 if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) {
976 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
977 } else {
978 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
979 }
980 $out .= ' ';
981 $out .= '<input type="submit" class="button smallpaddingimp" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
982 }
983 } else {
984 $out .= $this->withfile;
985 }
986
987 $out .= "</td></tr>\n";
988 }
989
990 // Message (+ Links to choose layout or ai prompt)
991 if (!empty($this->withbody)) {
992 $defaultmessage = GETPOST('message', 'restricthtml');
993 if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
994 if ($arraydefaultmessage && $arraydefaultmessage->content) {
995 $defaultmessage = (string) $arraydefaultmessage->content;
996 } elseif (!is_numeric($this->withbody)) {
997 $defaultmessage = $this->withbody;
998 }
999 }
1000
1001 // Complete substitution array with the url to make online payment
1002 $paymenturl = '';
1003 // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
1004 require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
1005 $validpaymentmethod = getValidOnlinePaymentMethods('');
1006
1007 if (empty($this->substit['__REF__'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
1008 $paymenturl = '';
1009 } else {
1010 $langs->loadLangs(array('paypal', 'other'));
1011 $typeforonlinepayment = 'free';
1012 if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') {
1013 $typeforonlinepayment = 'order'; // TODO use detection on something else than template
1014 }
1015 if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') {
1016 $typeforonlinepayment = 'invoice'; // TODO use detection on something else than template
1017 }
1018 if ($this->param["models"] == 'member') {
1019 $typeforonlinepayment = 'member'; // TODO use detection on something else than template
1020 }
1021 $url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
1022 $paymenturl = $url;
1023 }
1024
1025 if (count($validpaymentmethod) > 0 && $paymenturl) {
1026 $langs->load('other');
1027 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
1028 $this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
1029 } elseif (count($validpaymentmethod) > 0) {
1030 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__';
1031 $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__';
1032 } else {
1033 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
1034 $this->substit['__ONLINE_PAYMENT_URL__'] = '';
1035 }
1036
1037 $this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = '';
1038
1039 // Generate the string with the template for lines repeated and filled for each line
1040 $lines = '';
1041 $defaultlines = $arraydefaultmessage->content_lines;
1042 if (isset($defaultlines)) {
1043 foreach ($this->substit_lines as $lineid => $substit_line) {
1044 $lines .= make_substitutions($defaultlines, $substit_line, $outputlangs)."\n";
1045 }
1046 }
1047 $this->substit['__LINES__'] = $lines;
1048
1049 $defaultmessage = str_replace('\n', "\n", $defaultmessage);
1050
1051 // Deal with format differences between message and some substitution variables (text / HTML)
1052 $atleastonecomponentishtml = 0;
1053 if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1054 $atleastonecomponentishtml++;
1055 }
1056 if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
1057 $atleastonecomponentishtml++;
1058 }
1059 if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
1060 $atleastonecomponentishtml++;
1061 }
1062 if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) {
1063 $atleastonecomponentishtml++;
1064 }
1065 if (dol_textishtml($defaultmessage)) {
1066 $atleastonecomponentishtml++;
1067 }
1068 if ($atleastonecomponentishtml) {
1069 if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1070 $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
1071 }
1072 if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
1073 $this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']);
1074 }
1075 if (!dol_textishtml($this->substit['__LINES__'])) {
1076 $this->substit['__LINES__'] = dol_nl2br($this->substit['__LINES__']);
1077 }
1078 if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
1079 $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']);
1080 }
1081 if (!dol_textishtml($defaultmessage)) {
1082 $defaultmessage = dol_nl2br($defaultmessage);
1083 }
1084 }
1085
1086 if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
1087 $defaultmessage = GETPOST("message", "restricthtml");
1088 } else {
1089 // Pass $outputlangs so __(TranslationKey)__ in the template body is resolved
1090 // in the language of the selected email template, not the operator's language
1091 // (see issue #34540).
1092 $defaultmessage = make_substitutions($defaultmessage, $this->substit, $outputlangs);
1093 // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
1094 $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
1095 $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
1096 }
1097
1098 $out .= '<tr>';
1099 $out .= '<td class="tdtop">';
1100 $out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
1101 $out .= '</td>';
1102 $out .= '<td class="tdtop">';
1103
1104 $formmail = $this;
1105 $showlinktolayout = ($formmail->withfckeditor && getDolGlobalInt('MAIN_EMAIL_USE_LAYOUT')) ? $formmail->withlayout : '';
1106 $showlinktolayoutlabel = $langs->trans("FillMessageWithALayout");
1107 $showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationemail' : '';
1108 $showlinktoailabel = $langs->trans("AIEnhancements");
1109 $formatforouput = '';
1110 $htmlname = 'message';
1111
1112 $formai->substit = $this->substit;
1113 $formai->substit_lines = $this->substit_lines;
1114
1115 // Fill $out
1116 $db = $this->db;
1117 include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
1118
1119 $out .= '</td>';
1120 $out .= '</tr>';
1121
1122 $out .= '<tr>';
1123 $out .= '<td colspan="2">';
1124 if ($this->withbodyreadonly) {
1125 $out .= nl2br($defaultmessage);
1126 $out .= '<input type="hidden" id="message" name="message" disabled value="'.$defaultmessage.'" />';
1127 } else {
1128 if (!isset($this->ckeditortoolbar)) {
1129 $this->ckeditortoolbar = 'dolibarr_mailings';
1130 }
1131
1132 // Editor wysiwyg
1133 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1134 if ($this->withfckeditor == -1) {
1135 if (getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) {
1136 $this->withfckeditor = 1;
1137 } else {
1138 $this->withfckeditor = 0;
1139 }
1140 }
1141
1142 $doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, true, $this->withfckeditor, 8, '95%');
1143 $out .= $doleditor->Create(1);
1144 }
1145 $out .= "</td></tr>\n";
1146 }
1147
1148 $out .= '</table>'."\n";
1149
1150 if ($this->withform == 1 || $this->withform == -1) {
1151 $out .= '<div class="center">';
1152 $out .= '<input type="submit" class="button button-add" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
1153 // Add a javascript test to avoid to forget to submit file before sending email
1154 if ($this->withfile == 2 && $conf->use_javascript_ajax) {
1155 $out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
1156 }
1157 $out .= ' />';
1158 if ($this->withcancel) {
1159 $out .= '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
1160 }
1161 $out .= '</div>'."\n";
1162 }
1163
1164 if ($this->withform == 1) {
1165 $out .= '</form>'."\n";
1166 }
1167
1168 // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1169 if (getDolGlobalString('MAIN_MAILFORM_DISABLE_ENTERKEY')) {
1170 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
1171 $out .= 'jQuery(document).ready(function () {';
1172 $out .= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is called at every key pressed ! */
1173 var code = e.keyCode || e.which;
1174 if (code == 13) {
1175 console.log("Enter was intercepted and blocked");
1176 e.preventDefault();
1177 return false;
1178 }
1179 });';
1180 $out .= ' })';
1181 $out .= '</script>';
1182 }
1183
1184 $out .= "<!-- End form mail -->\n";
1185
1186 return $out;
1187 }
1188 }
1189
1195 public function getHtmlForTo()
1196 {
1197 global $langs, $form;
1198 $out = '<tr><td class="fieldrequired">';
1199 if ($this->withtofree) {
1200 $out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1201 } else {
1202 $out .= $langs->trans("MailTo");
1203 }
1204 $out .= '</td><td>';
1205 if ($this->withtoreadonly) {
1206 if (!empty($this->toname) && !empty($this->tomail)) {
1207 $out .= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
1208 $out .= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
1209 if ($this->totype == 'thirdparty') {
1210 $soc = new Societe($this->db);
1211 $soc->fetch($this->toid);
1212 $out .= $soc->getNomUrl(1);
1213 } elseif ($this->totype == 'contact') {
1214 $contact = new Contact($this->db);
1215 $contact->fetch($this->toid);
1216 $out .= $contact->getNomUrl(1);
1217 } else {
1218 $out .= $this->toname;
1219 }
1220 $out .= ' &lt;'.$this->tomail.'&gt;';
1221 if ($this->withtofree) {
1222 $out .= '<br>'.$langs->trans("and").' <input class="minwidth200" id="sendto" name="sendto" spellcheck="false" value="'.(!is_array($this->withto) && !is_numeric($this->withto) ? (GETPOSTISSET("sendto") ? GETPOST("sendto") : $this->withto) : "").'" />';
1223 }
1224 } else {
1225 // Note withto may be a text like 'AllRecipientSelected'
1226 $out .= (!is_array($this->withto) && !is_numeric($this->withto)) ? $this->withto : "";
1227 }
1228 } else {
1229 // The free input of email
1230 if (!empty($this->withtofree)) {
1231 $out .= '<input class="minwidth200" id="sendto" name="sendto" spellcheck="false" value="'.(($this->withtofree && !is_numeric($this->withtofree)) ? $this->withtofree : (!is_array($this->withto) && !is_numeric($this->withto) ? (GETPOSTISSET("sendto") ? GETPOST("sendto") : $this->withto) : "")).'" />';
1232 }
1233 // The select combo
1234 if (!empty($this->withto) && is_array($this->withto)) {
1235 if (!empty($this->withtofree)) {
1236 $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1237 }
1238
1239 $tmparray = $this->withto;
1240 foreach ($tmparray as $key => $val) {
1241 if (is_array($val)) {
1242 $label = $val['label'];
1243 } else {
1244 $label = $val;
1245 }
1246
1247 $tmparray[$key] = array();
1248 $tmparray[$key]['id'] = $key;
1249
1250 $tmparray[$key]['label'] = $label;
1251 $tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
1252 // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
1253 $tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true);
1254
1255 $tmparray[$key]['labelhtml'] = $label;
1256 $tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
1257 $tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
1258 }
1259
1260 $withtoselected = GETPOST("receiver", 'array'); // Array of selected value
1261 if (!getDolGlobalInt('MAIN_MAIL_NO_WITH_TO_SELECTED')) {
1262 if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
1263 $withtoselected = array_keys($tmparray);
1264 }
1265 }
1266
1267 $out .= $form->multiselectarray("receiver", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, 0);
1268 }
1269 }
1270 $out .= "</td></tr>\n";
1271 return $out;
1272 }
1273
1279 public function getHtmlForCc()
1280 {
1281 global $langs, $form;
1282 $out = '<tr><td>';
1283 $out .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1284 $out .= '</td><td>';
1285 if ($this->withtoccreadonly) {
1286 $out .= (!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : "";
1287 } else {
1288 $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 : '')).'" />';
1289 if (!empty($this->withtocc) && is_array($this->withtocc)) {
1290 $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1291
1292 $tmparray = $this->withtocc;
1293 foreach ($tmparray as $key => $val) {
1294 if (is_array($val)) {
1295 $label = $val['label'];
1296 } else {
1297 $label = $val;
1298 }
1299
1300 $tmparray[$key] = array();
1301 $tmparray[$key]['id'] = $key;
1302
1303 $tmparray[$key]['label'] = $label;
1304 $tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
1305 // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
1306 $tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true);
1307
1308 $tmparray[$key]['labelhtml'] = $label;
1309 $tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
1310 $tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
1311 }
1312
1313 $withtoccselected = GETPOST("receivercc", 'array'); // Array of selected value
1314
1315 $out .= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, 0, 0, 'inline-block minwidth500', 0, 0);
1316 }
1317 }
1318 $out .= "</td></tr>\n";
1319 return $out;
1320 }
1321
1328 public function getHtmlForWithCcc()
1329 {
1330 global $langs, $form;
1331
1332 $out = '<tr><td>';
1333 $out .= $form->textwithpicto($langs->trans("MailCCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1334 $out .= '</td><td>';
1335 if (!empty($this->withtocccreadonly)) {
1336 $out .= (!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : "";
1337 } else {
1338 $out .= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.(GETPOSTISSET("sendtoccc") ? GETPOST("sendtoccc", "alpha") : ((!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />';
1339 if (!empty($this->withtoccc) && is_array($this->withtoccc)) {
1340 $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1341
1342 $tmparray = $this->withtoccc;
1343 foreach ($tmparray as $key => $val) {
1344 if (is_array($val)) {
1345 $label = $val['label'];
1346 } else {
1347 $label = $val;
1348 }
1349 $tmparray[$key] = array();
1350 $tmparray[$key]['id'] = $key;
1351
1352 $tmparray[$key]['label'] = $label;
1353 $tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
1354 // multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
1355 $tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true);
1356
1357 $tmparray[$key]['labelhtml'] = $label;
1358 $tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
1359 $tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
1360 }
1361
1362 $withtocccselected = GETPOST("receiverccc", 'array'); // Array of selected value
1363
1364 $out .= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, 0, 0, 'inline-block minwidth500', 0, 0);
1365 }
1366 }
1367
1368 $showinfobcc = '';
1369 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROPOSAL_TO') && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
1370 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROPOSAL_TO');
1371 }
1372 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_ORDER_TO') && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
1373 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_ORDER_TO');
1374 }
1375 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_INVOICE_TO') && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
1376 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_INVOICE_TO');
1377 }
1378 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO') && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
1379 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO');
1380 }
1381 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO') && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
1382 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO');
1383 }
1384 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO') && !empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') {
1385 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO');
1386 }
1387 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROJECT_TO') && !empty($this->param['models']) && $this->param['models'] == 'project') { // don't know why there is not '_send' at end of this models name.
1388 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROJECT_TO');
1389 }
1390 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SHIPMENT_TO') && !empty($this->param['models']) && $this->param['models'] == 'shipping_send') {
1391 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SHIPMENT_TO');
1392 }
1393 if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_RECEPTION_TO') && !empty($this->param['models']) && $this->param['models'] == 'reception_send') {
1394 $showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_RECEPTION_TO');
1395 }
1396 if ($showinfobcc) {
1397 $out .= ' + '.$showinfobcc;
1398 }
1399 $out .= "</td></tr>\n";
1400 return $out;
1401 }
1402
1408 public function getHtmlForWithErrorsTo()
1409 {
1410 global $langs;
1411
1412 //if (! $this->errorstomail) $this->errorstomail=$this->frommail;
1413 $errorstomail = getDolGlobalString('MAIN_MAIL_ERRORS_TO', (!empty($this->errorstomail) ? $this->errorstomail : ''));
1414 if ($this->witherrorstoreadonly) {
1415 $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1416 $out .= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1417 $out .= $errorstomail;
1418 $out .= "</td></tr>\n";
1419 } else {
1420 $out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1421 $out .= '<input class="minwidth200" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1422 $out .= "</td></tr>\n";
1423 }
1424 return $out;
1425 }
1426
1432 public function getHtmlForDeliveryreceipt()
1433 {
1434 global $langs;
1435
1436 $out = '<tr><td><label for="deliveryreceipt">'.$langs->trans("DeliveryReceipt").'</label></td><td>';
1437
1438 if (!empty($this->withdeliveryreceiptreadonly)) {
1439 $out .= yn($this->withdeliveryreceipt);
1440 } else {
1441 $defaultvaluefordeliveryreceipt = 0;
1442 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_PROPAL') && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
1443 $defaultvaluefordeliveryreceipt = 1;
1444 }
1445 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL') && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
1446 $defaultvaluefordeliveryreceipt = 1;
1447 }
1448 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_ORDER') && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
1449 $defaultvaluefordeliveryreceipt = 1;
1450 }
1451 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_INVOICE') && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
1452 $defaultvaluefordeliveryreceipt = 1;
1453 }
1454 if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_ORDER') && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
1455 $defaultvaluefordeliveryreceipt = 1;
1456 }
1457 //$out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1);
1458 $out .= '<input type="checkbox" id="deliveryreceipt" name="deliveryreceipt" value="1"'.((GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt) ? ' checked="checked"' : '').'>';
1459 }
1460 $out .= "</td></tr>\n";
1461 return $out;
1462 }
1463
1471 public function getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
1472 {
1473 global $conf, $langs, $form;
1474
1475 $defaulttopic = GETPOST('subject', 'restricthtml');
1476
1477 if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
1478 if ($arraydefaultmessage && $arraydefaultmessage->topic) {
1479 $defaulttopic = $arraydefaultmessage->topic;
1480 } elseif (!is_numeric($this->withtopic)) {
1481 $defaulttopic = $this->withtopic;
1482 }
1483 }
1484
1485 // Resolve __(TranslationKey)__ in the language of the selected template
1486 // (see issue #34540). Falls back to the caller's language when the template
1487 // has no explicit language pinned.
1488 $outputlangs = $langs;
1489 if (is_object($arraydefaultmessage) && !empty($arraydefaultmessage->lang)) {
1490 $outputlangs = new Translate("", $conf);
1491 $outputlangs->setDefaultLang($arraydefaultmessage->lang);
1492 $outputlangs->load('other');
1493 }
1494
1495 $defaulttopic = make_substitutions($defaulttopic, $this->substit, $outputlangs);
1496
1497 $out = '<tr>';
1498 $out .= '<td class="fieldrequired">';
1499 $out .= $form->textwithpicto($langs->trans('MailTopic'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
1500 $out .= '</td>';
1501 $out .= '<td>';
1502 if ($this->withtopicreadonly) {
1503 $out .= $defaulttopic;
1504 $out .= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
1505 } else {
1506 $out .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'.((GETPOSTISSET("subject") && !GETPOST('modelselected')) ? GETPOST("subject") : ($defaulttopic ? $defaulttopic : '')).'" />';
1507 }
1508 $out .= "</td></tr>\n";
1509 return $out;
1510 }
1511
1519 public function getEmailLayoutSelector($htmlContent = 'message', $showlinktolayout = 'email')
1520 {
1521 global $conf, $db, $websitepage, $langs;
1522
1523 require_once DOL_DOCUMENT_ROOT.'/core/lib/emaillayout.lib.php';
1524 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1525 require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
1526 require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
1527
1528 $out = '<div id="template-selector" class="template-selector email-layout-container hidden" style="display:none;">';
1529
1530 // Define list of email layouts to use
1531 $layouts = array(
1532 'empty' => 'empty',
1533 );
1534
1535 // Search available layouts on disk
1536 $arrayoflayoutemplates = dol_dir_list(DOL_DOCUMENT_ROOT.'/install/doctemplates/maillayout/', 'files', 0, '\.html$');
1537 foreach ($arrayoflayoutemplates as $layouttemplatefile) {
1538 $layoutname = preg_replace('/\.html$/i', '', $layouttemplatefile['name']);
1539
1540 // Exclude some layouts for some use cases
1541 if ($layoutname == 'news' && (!in_array($showlinktolayout, array('emailing', 'websitepage')) || !isModEnabled('website'))) {
1542 continue;
1543 }
1544 if ($layoutname == 'products' && (!in_array($showlinktolayout, array('emailing', 'websitepage')) || (!isModEnabled('product') && !isModEnabled('service')))) {
1545 continue;
1546 }
1547
1548 $layouts[$layoutname] = ucfirst($layoutname);
1549 }
1550 //}
1551 // TODO Add a hook to allow to complete the list
1552
1553 foreach ($layouts as $layout => $templateFunction) {
1554 $contentHtml = getHtmlOfLayout($layout);
1555
1556 $out .= '<div class="template-option" data-template="'.$layout.'" data-content="'.htmlentities($contentHtml).'">';
1557 $out .= '<img class="maillayout" alt="'.$layout.'" src="'.DOL_URL_ROOT.'/theme/common/maillayout/'.$layout.'.png" />';
1558 $out .= '<span class="template-option-text">'.$langs->trans($templateFunction).'</span>';
1559 $out .= '</div>';
1560 }
1561 $out .= '</div>';
1562
1563 // Prepare the array for multiselect
1564
1565 // Fetch blogs
1566 $blogArray = array();
1567 if (isModEnabled('website')) {
1568 $websitepage = new WebsitePage($this->db);
1569 $arrayofblogs = $websitepage->fetchAll('', 'ASC,DESC', 'fk_website,date_creation', 0, 0, array('type_container' => 'blogpost'));
1570
1571 if (empty($conf->cache['websiteurl'])) {
1572 $conf->cache['websiteurl'] = array();
1573 }
1574
1575 if (!empty($arrayofblogs)) {
1576 foreach ($arrayofblogs as $blog) {
1577 if (!isset($conf->cache['websiteurl'][$blog->id])) {
1578 $tmpwebsite = new Website($db);
1579 $tmpwebsite->fetch($blog->fk_website);
1580 $conf->cache['websiteurl'][$blog->fk_website] = (empty($tmpwebsite->virtualhost) ? $tmpwebsite->ref : $tmpwebsite->virtualhost);
1581 }
1582
1583 $labelwebsite = $conf->cache['websiteurl'][$blog->fk_website];
1584 //$blog->fk_website
1585
1586 $blogArray[$blog->id] = array(
1587 'id' => $blog->id,
1588 'label' => '['.$labelwebsite.' '.$blog->type_container.' '.$blog->id.'] '.dol_trunc($blog->title, 40),
1589 'labelhtml' => '<span class="opacitymedium">['.$labelwebsite.' '.$blog->type_container.' '.$blog->id.']</span> '.dol_trunc($blog->title, 40),
1590 );
1591 }
1592 }
1593 }
1594
1595 // Use the multiselect array function to create the dropdown
1596 $out .= '<div id="post-dropdown-container" class="email-layout-container hidden" style="display:none;">';
1597 $out .= '<label for="blogpost-select">Select Posts: </label>';
1598 $out .= '<!-- select component for selection of products -->'."\n";
1599 $out .= self::multiselectarray('blogpost-select', $blogArray, array(), 0, 0, 'minwidth200');
1600 $out .= '</div>';
1601
1602 $out .= '<!-- Js code to manage choice of an email layout -->'."\n";
1603 $out .= '<script type="text/javascript">
1604 $(document).ready(function() {
1605 $(".template-option").click(function() {
1606 var template = $(this).data("template");
1607 var subject = jQuery("#subject").val();
1608 var fromtype = jQuery("#fromtype").val();
1609 var sendto = jQuery("#sendto").val();
1610 var sendtocc = jQuery("#sendtocc").val();
1611 var sendtoccc = jQuery("#sendtoccc").val();
1612
1613 console.log("We choose a layout for email template=" + template + ", subject="+subject);
1614
1615 $(".template-option").removeClass("selected");
1616 $(this).addClass("selected");
1617
1618 if (template === "news") {
1619 $("#post-dropdown-container").show();
1620 console.log("Displaying dropdown for news template");
1621 } else {
1622 $("#post-dropdown-container").hide();
1623
1624 var csrfToken = "' .newToken().'";
1625 $.ajax({
1626 type: "POST",
1627 url: "'.DOL_URL_ROOT.'/core/ajax/mailtemplate.php",
1628 data: {
1629 token: csrfToken,
1630 template: template,
1631 subject: subject,
1632 fromtype: fromtype,
1633 sendto: sendto,
1634 sendtocc: sendtocc,
1635 sendtoccc: sendtoccc,
1636 selectedPosts: "[]"
1637 },
1638 success: function(response) {
1639 jQuery("#'.$htmlContent.'").val(response);
1640 var editorInstance = CKEDITOR.instances["'.$htmlContent.'"];
1641 if (editorInstance) {
1642 editorInstance.setData(response);
1643 }
1644 },
1645 error: function(xhr, status, error) {
1646 console.error("An error occurred: " + xhr.responseText);
1647 }
1648 });
1649 }
1650 });
1651
1652 $("#blogpost-select").change(function() {
1653 var selectedIds = $(this).val();
1654 var contentHtml = $(".template-option.selected").data("content");
1655
1656 updateSelectedPostsContent(contentHtml, selectedIds);
1657 });
1658
1659 function updateSelectedPostsContent(contentHtml, selectedIds) {
1660 var csrfToken = "' .newToken().'";
1661 $.ajax({
1662 type: "POST",
1663 url: "/core/ajax/getnews.php",
1664 data: {
1665 selectedIds: JSON.stringify(selectedIds),
1666 token : csrfToken
1667 },
1668 success: function(response) {
1669 var selectedPosts = JSON.parse(response);
1670 var subject = $("#subject").val();
1671
1672 contentHtml = contentHtml.replace(/__SUBJECT__/g, subject);
1673
1674 $.ajax({
1675 type: "POST",
1676 url: "/core/ajax/mailtemplate.php",
1677 data: {
1678 token: csrfToken,
1679 template: template,
1680 subject: subject,
1681 fromtype: fromtype,
1682 sendto: sendto,
1683 sendtocc: sendtocc,
1684 sendtoccc: sendtoccc,
1685 selectedPosts: selectedIds.join(",")
1686 },
1687 success: function(response) {
1688 jQuery("#'.$htmlContent.'").val(response);
1689 var editorInstance = CKEDITOR.instances["'.$htmlContent.'"];
1690 if (editorInstance) {
1691 editorInstance.setData(response);
1692 }
1693 },
1694 error: function(xhr, status, error) {
1695 console.error("An error occurred: " + xhr.responseText);
1696 }
1697 });
1698 },
1699 error: function(xhr, status, error) {
1700 console.error("An error occurred: " + xhr.responseText);
1701 }
1702 });
1703 }
1704 });
1705 </script>';
1706
1707 return $out;
1708 }
1709
1727 public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '', $defaultfortype = -1)
1728 {
1729 global $conf;
1730
1731 if ($id == -2 && empty($label)) {
1732 $this->error = 'LabelIsMandatoryWhenIdIs-2or-3';
1733 return -1;
1734 }
1735
1736 $ret = new ModelMail($dbs);
1737
1738 $languagetosearch = (is_object($outputlangs) ? $outputlangs->defaultlang : '');
1739 // Define $languagetosearchmain to fall back on main language (for example to get 'es_ES' for 'es_MX')
1740 $tmparray = explode('_', $languagetosearch);
1741 $languagetosearchmain = $tmparray[0].'_'.strtoupper($tmparray[0]);
1742 if ($languagetosearchmain == $languagetosearch) {
1743 $languagetosearchmain = '';
1744 }
1745
1746 $sql = "SELECT rowid, entity, module, label, type_template, topic, email_from, joinfiles, content, content_lines, lang, email_from, email_to, email_tocc, email_tobcc";
1747 $sql .= " FROM ".$dbs->prefix().'c_email_templates';
1748 $sql .= " WHERE (type_template = '".$dbs->escape($type_template)."' OR type_template = '".$dbs->escape($type_template)."_send' OR type_template = 'all')";
1749 $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1750 $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // Get all public or private owned
1751 if ($active >= 0) {
1752 $sql .= " AND active = ".((int) $active);
1753 }
1754 if ($defaultfortype >= 0) {
1755 $sql .= " AND defaultfortype = ".((int) $defaultfortype);
1756 }
1757 if ($label) {
1758 $sql .= " AND label = '".$dbs->escape($label)."'";
1759 }
1760 if (!($id > 0) && $languagetosearch) {
1761 $sql .= " AND (lang = '".$dbs->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$dbs->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
1762 }
1763 if ($id > 0) {
1764 $sql .= " AND rowid = ".(int) $id;
1765 }
1766 if ($id == -1) {
1767 $sql .= " AND position = 0";
1768 }
1769 $sql .= " AND entity IN(".getEntity('c_email_templates', 1).")";
1770 if ($languagetosearch) {
1771 $sql .= $dbs->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or ''
1772 } else {
1773 $sql .= $dbs->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined
1774 }
1775 //$sql .= $dbs->plimit(1);
1776 //print $sql;
1777
1778 $resql = $dbs->query($sql);
1779 if (!$resql) {
1780 dol_print_error($dbs);
1781 return -1;
1782 }
1783
1784 // Get first found
1785 while (1) {
1786 $obj = $dbs->fetch_object($resql);
1787
1788 if ($obj) {
1789 // If template is for a module, check module is enabled; if not, take next template
1790 if ($obj->module) {
1791 $tempmodulekey = $obj->module;
1792 if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
1793 continue;
1794 }
1795 }
1796
1797 // If a record was found
1798 $ret->id = (int) $obj->rowid;
1799 $ret->module = (string) $obj->module;
1800 $ret->label = (string) $obj->label;
1801 $ret->lang = $obj->lang;
1802 $ret->topic = $obj->topic;
1803 $ret->content = (string) $obj->content;
1804 $ret->content_lines = (string) $obj->content_lines;
1805 $ret->joinfiles = $obj->joinfiles;
1806 $ret->email_from = (string) $obj->email_from;
1807
1808 break;
1809 } else {
1810 // If no record found
1811 if ($id == -2) {
1812 // Not found with the provided label
1813 return -1;
1814 } else {
1815 // If there is no template at all
1816 $defaultmessage = '';
1817
1818 if ($type_template == 'body') {
1819 // Special case to use this->withbody as content
1820 $defaultmessage = (string) $this->withbody;
1821 } elseif ($type_template == 'facture_send' || $type_template == 'facture' || $type_template == 'facture_relance') {
1822 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoice");
1823 } elseif ($type_template == 'propal_send' || $type_template == 'propal') {
1824 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendProposal");
1825 } elseif ($type_template == 'supplier_proposal_send' || $type_template == 'supplier_proposal') {
1826 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal");
1827 } elseif ($type_template == 'order_send' || $type_template == 'order') {
1828 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendOrder");
1829 } elseif ($type_template == 'order_supplier_send' || $type_template == 'order_supplier') {
1830 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder");
1831 } elseif ($type_template == 'invoice_supplier_send' || $type_template == 'invoice_supplier') {
1832 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice");
1833 } elseif ($type_template == 'shipping_send' || $type_template == 'shipping') {
1834 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendShipping");
1835 } elseif ($type_template == 'fichinter_send' || $type_template == 'fichinter') {
1836 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendFichInter");
1837 } elseif ($type_template == 'actioncomm_send' || $type_template == 'actioncomm') {
1838 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm");
1839 } elseif (!empty($type_template)) {
1840 $defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric");
1841 }
1842
1843 $ret->label = 'default';
1844 $ret->lang = $outputlangs->defaultlang;
1845 $ret->topic = '';
1846 $ret->joinfiles = 1;
1847 $ret->content = $defaultmessage;
1848 $ret->content_lines = '';
1849
1850 break;
1851 }
1852 }
1853 }
1854
1855 $dbs->free($resql);
1856
1857 return $ret;
1858 }
1859
1869 public function isEMailTemplate($type_template, $user, $outputlangs)
1870 {
1871 $sql = "SELECT label, topic, content, lang";
1872 $sql .= " FROM ".$this->db->prefix().'c_email_templates';
1873 $sql .= " WHERE type_template='".$this->db->escape($type_template)."'";
1874 $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1875 $sql .= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".((int) $user->id).")";
1876 if (is_object($outputlangs)) {
1877 $sql .= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
1878 }
1879 $sql .= $this->db->order("lang,label", "ASC");
1880 //print $sql;
1881
1882 $resql = $this->db->query($sql);
1883 if ($resql) {
1884 $num = $this->db->num_rows($resql);
1885 $this->db->free($resql);
1886 return $num;
1887 } else {
1888 $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1889 return -1;
1890 }
1891 }
1892
1903 public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active = 1)
1904 {
1905 global $db, $conf;
1906
1907 $sql = "SELECT rowid, module, label, topic, content, content_lines, lang, fk_user, private, position";
1908 $sql .= " FROM ".$this->db->prefix().'c_email_templates';
1909 $sql .= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1910 $sql .= " AND entity IN (".getEntity('c_email_templates').")";
1911 $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // See all public templates or templates I own.
1912 if ($active >= 0) {
1913 $sql .= " AND active = ".((int) $active);
1914 }
1915 //if (is_object($outputlangs)) $sql.= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')"; // Return all languages
1916 $sql .= $this->db->order("position,lang,label", "ASC");
1917 //print $sql;
1918
1919 $resql = $this->db->query($sql);
1920 if ($resql) {
1921 $num = $this->db->num_rows($resql);
1922 $this->lines_model = array();
1923 while ($obj = $this->db->fetch_object($resql)) {
1924 // If template is for a module, check module is enabled.
1925 if ($obj->module) {
1926 $tempmodulekey = $obj->module;
1927 if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
1928 continue;
1929 }
1930 }
1931
1932 $line = new ModelMail($db);
1933 $line->id = (int) $obj->rowid;
1934 $line->label = (string) $obj->label;
1935 $line->lang = $obj->lang;
1936 $line->fk_user = $obj->fk_user;
1937 $line->private = $obj->private;
1938 $line->position = $obj->position;
1939 $line->topic = $obj->topic;
1940 $line->content = $obj->content;
1941 $line->content_lines = $obj->content_lines;
1942
1943 $this->lines_model[] = $line;
1944 }
1945 $this->db->free($resql);
1946 return $num;
1947 } else {
1948 $this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1949 return -1;
1950 }
1951 }
1952
1953
1954
1963 public function setSubstitFromObject($object, $outputlangs)
1964 {
1965 global $extrafields;
1966
1967 $parameters = array();
1968 $tmparray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
1969 complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
1970
1971 $this->substit = $tmparray;
1972
1973 // Fill substit_lines with each object lines content
1974 if (is_array($object->lines)) {
1975 foreach ($object->lines as $line) {
1976 $substit_line = array(
1977 '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1978 '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1979 '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1980 '__LABEL__' => isset($line->label) ? $line->label : '',
1981 '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1982 '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', false, $outputlangs),
1983 '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', false, $outputlangs),
1984 '__QUANTITY__' => $line->qty,
1985 '__SUBPRICE__' => price($line->subprice),
1986 '__AMOUNT__' => price($line->total_ttc),
1987 '__AMOUNT_EXCL_TAX__' => price($line->total_ht)
1988 );
1989
1990 // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1991 if (!empty($line->fk_product)) {
1992 if (!is_object($extrafields)) {
1993 $extrafields = new ExtraFields($this->db);
1994 }
1995 $product = new Product($this->db);
1996 $product->fetch($line->fk_product, '', '', '1');
1997 $product->fetch_optionals();
1998
1999 $extrafields->fetch_name_optionals_label($product->table_element, true);
2000
2001 if (!empty($extrafields->attributes[$product->table_element]['label']) && is_array($extrafields->attributes[$product->table_element]['label']) && count($extrafields->attributes[$product->table_element]['label']) > 0) {
2002 foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
2003 $substit_line['__PRODUCT_EXTRAFIELD_'.strtoupper($key).'__'] = isset($product->array_options['options_'.$key]) ? $product->array_options['options_'.$key] : '';
2004 }
2005 }
2006 }
2007
2008 $this->substit_lines[$line->id] = $substit_line; // @phan-suppress-current-line PhanTypeMismatchProperty
2009 }
2010 }
2011 }
2012
2021 public static function getAvailableSubstitKey($mode = 'formemail', $object = null)
2022 {
2023 global $langs;
2024
2025 $tmparray = array();
2026 if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines') {
2027 $parameters = array('mode' => $mode);
2028 $tmparray = getCommonSubstitutionArray($langs, 2, null, $object); // Note: On email templated edition, this is null because it is related to all type of objects
2029 complete_substitutions_array($tmparray, $langs, null, $parameters);
2030
2031 if ($mode == 'formwithlines') {
2032 $tmparray['__LINES__'] = '__LINES__'; // Will be set by the get_form function
2033 }
2034 if ($mode == 'formforlines') {
2035 $tmparray['__QUANTITY__'] = '__QUANTITY__'; // Will be set by the get_form function
2036 }
2037 }
2038
2039 if ($mode == 'emailing') {
2040 $parameters = array('mode' => $mode);
2041 $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
2042 complete_substitutions_array($tmparray, $langs, null, $parameters);
2043
2044 // For mass emailing, we have different keys specific to the data into tagerts list
2045 $tmparray['__ID__'] = 'IdRecord';
2046 $tmparray['__EMAIL__'] = 'EMailRecipient';
2047 $tmparray['__LASTNAME__'] = 'Lastname';
2048 $tmparray['__FIRSTNAME__'] = 'Firstname';
2049 $tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
2050 $tmparray['__OTHER1__'] = 'Other1';
2051 $tmparray['__OTHER2__'] = 'Other2';
2052 $tmparray['__OTHER3__'] = 'Other3';
2053 $tmparray['__OTHER4__'] = 'Other4';
2054 $tmparray['__OTHER5__'] = 'Other5';
2055
2056 $tmparray['__THIRDPARTY_CUSTOMER_CODE__'] = 'CustomerCode'; // If source is a thirdparty
2057
2058 $tmparray['__CHECK_READ__'] = $langs->trans('TagCheckMail');
2059 $tmparray['__UNSUBSCRIBE__'] = $langs->trans('TagUnsubscribe');
2060 $tmparray['__UNSUBSCRIBE_URL__'] = $langs->trans('TagUnsubscribe').' (URL)';
2061
2062 $onlinepaymentenabled = 0;
2063 if (isModEnabled('paypal')) {
2064 $onlinepaymentenabled++;
2065 }
2066 if (isModEnabled('paybox')) {
2067 $onlinepaymentenabled++;
2068 }
2069 if (isModEnabled('stripe')) {
2070 $onlinepaymentenabled++;
2071 }
2072 if ($onlinepaymentenabled && getDolGlobalString('PAYMENT_SECURITY_TOKEN')) {
2073 $tmparray['__SECUREKEYPAYMENT__'] = getDolGlobalString('PAYMENT_SECURITY_TOKEN');
2074 if (getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')) {
2075 if (isModEnabled('member')) {
2076 $tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
2077 }
2078 if (isModEnabled('don')) {
2079 $tmparray['__SECUREKEYPAYMENT_DONATION__'] = 'SecureKeyPAYMENTUniquePerDonation';
2080 }
2081 if (isModEnabled('invoice')) {
2082 $tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
2083 }
2084 if (isModEnabled('order')) {
2085 $tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
2086 }
2087 if (isModEnabled('contract')) {
2088 $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
2089 }
2090
2091 //Online payment link
2092 if (isModEnabled('member')) {
2093 $tmparray['__ONLINEPAYMENTLINK_MEMBER__'] = 'OnlinePaymentLinkUniquePerMember';
2094 }
2095 if (isModEnabled('don')) {
2096 $tmparray['__ONLINEPAYMENTLINK_DONATION__'] = 'OnlinePaymentLinkUniquePerDonation';
2097 }
2098 if (isModEnabled('invoice')) {
2099 $tmparray['__ONLINEPAYMENTLINK_INVOICE__'] = 'OnlinePaymentLinkUniquePerInvoice';
2100 }
2101 if (isModEnabled('order')) {
2102 $tmparray['__ONLINEPAYMENTLINK_ORDER__'] = 'OnlinePaymentLinkUniquePerOrder';
2103 }
2104 if (isModEnabled('contract')) {
2105 $tmparray['__ONLINEPAYMENTLINK_CONTRACTLINE__'] = 'OnlinePaymentLinkUniquePerContractLine';
2106 }
2107 }
2108 } else {
2109 /* No need to show into tooltip help, option is not enabled
2110 $vars['__SECUREKEYPAYMENT__']='';
2111 $vars['__SECUREKEYPAYMENT_MEMBER__']='';
2112 $vars['__SECUREKEYPAYMENT_INVOICE__']='';
2113 $vars['__SECUREKEYPAYMENT_ORDER__']='';
2114 $vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
2115 */
2116 }
2117 if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
2118 $tmparray['__PUBLICLINK_NEWMEMBERFORM__'] = 'BlankSubscriptionForm';
2119 }
2120 }
2121
2122 foreach ($tmparray as $key => $val) {
2123 if (empty($val)) {
2124 $tmparray[$key] = $key;
2125 }
2126 }
2127
2128 return $tmparray;
2129 }
2130}
2131
2132
2133require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
2134
2140class ModelMail extends CommonObject
2141{
2145 public $element = 'email_template';
2146
2150 public $table_element = 'c_email_templates';
2151
2152
2153 // BEGIN MODULEBUILDER PROPERTIES
2157 public $fields = array(
2158 "rowid" => array("type" => "integer", "label" => "TechnicalID", 'enabled' => 1, 'position' => 10, 'notnull' => 1, 'visible' => -1,),
2159 "module" => array("type" => "varchar(32)", "label" => "Module", 'enabled' => 1, 'position' => 20, 'notnull' => 0, 'visible' => -1,),
2160 "type_template" => array("type" => "varchar(32)", "label" => "Typetemplate", 'enabled' => 1, 'position' => 25, 'notnull' => 0, 'visible' => -1,),
2161 "lang" => array("type" => "varchar(6)", "label" => "Lang", 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => -1,),
2162 "private" => array("type" => "smallint(6)", "label" => "Private", 'enabled' => 1, 'position' => 35, 'notnull' => 1, 'visible' => -1,),
2163 "fk_user" => array("type" => "integer:User:user/class/user.class.php", "label" => "Fkuser", 'enabled' => 1, 'position' => 40, 'notnull' => 0, 'visible' => -1, "css" => "maxwidth500 widthcentpercentminusxx", "csslist" => "tdoverflowmax150",),
2164 "datec" => array("type" => "datetime", "label" => "DateCreation", 'enabled' => 1, 'position' => 45, 'notnull' => 0, 'visible' => -1,),
2165 "tms" => array("type" => "timestamp", "label" => "DateModification", 'enabled' => 1, 'position' => 50, 'notnull' => 1, 'visible' => -1,),
2166 "label" => array("type" => "varchar(255)", "label" => "Label", 'enabled' => 1, 'position' => 55, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1, "css" => "minwidth300", "cssview" => "wordbreak", "csslist" => "tdoverflowmax150",),
2167 "position" => array("type" => "smallint(6)", "label" => "Position", 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2168 "active" => array("type" => "integer", "label" => "Active", 'enabled' => 1, 'position' => 65, 'notnull' => 1, 'visible' => -1, 'alwayseditable' => 1,),
2169 "topic" => array("type" => "text", "label" => "Topic", 'enabled' => 1, 'position' => 70, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2170 "content" => array("type" => "mediumtext", "label" => "Content", 'enabled' => 1, 'position' => 75, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2171 "content_lines" => array("type" => "text", "label" => "Contentlines", "enabled" => "getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')", 'position' => 80, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2172 "enabled" => array("type" => "varchar(255)", "label" => "Enabled", 'enabled' => 1, 'position' => 85, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2173 "joinfiles" => array("type" => "varchar(255)", "label" => "Joinfiles", 'enabled' => 1, 'position' => 90, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2174 "email_from" => array("type" => "varchar(255)", "label" => "Emailfrom", 'enabled' => 1, 'position' => 95, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2175 "email_to" => array("type" => "varchar(255)", "label" => "Emailto", 'enabled' => 1, 'position' => 100, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2176 "email_tocc" => array("type" => "varchar(255)", "label" => "Emailtocc", 'enabled' => 1, 'position' => 105, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2177 "email_tobcc" => array("type" => "varchar(255)", "label" => "Emailtobcc", 'enabled' => 1, 'position' => 110, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2178 "defaultfortype" => array("type" => "smallint(6)", "label" => "Defaultfortype", 'enabled' => 1, 'position' => 115, 'notnull' => 0, 'visible' => -1, 'alwayseditable' => 1,),
2179 );
2183 public $rowid;
2187 public $type_template;
2191 public $datec;
2195 public $tms;
2199 public $active;
2203 public $enabled;
2207 public $defaultfortype;
2208
2212 public $id;
2213
2217 public $label;
2218
2222 public $fk_user;
2223
2227 public $private;
2228
2232 public $topic;
2233
2237 public $content;
2241 public $content_lines;
2242
2246 public $lang;
2250 public $joinfiles;
2251
2255 public $email_from;
2259 public $email_to;
2263 public $email_tocc;
2267 public $email_tobcc;
2268
2272 public $module;
2273
2277 public $position;
2278 // END MODULEBUILDER PROPERTIES
2279
2280
2281
2287 public function __construct(DoliDB $db)
2288 {
2289 global $langs;
2290
2291 $this->db = $db;
2292 $this->ismultientitymanaged = 0;
2293 $this->isextrafieldmanaged = 1;
2294
2295 // @phan-suppress-next-line PhanTypeMismatchProperty
2296 if (!getDolGlobalInt('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
2297 $this->fields['rowid']['visible'] = 0;
2298 }
2299 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
2300 $this->fields['entity']['enabled'] = 0;
2301 }
2302
2303 // Example to show how to set values of fields definition dynamically
2304 /*if ($user->hasRight('test', 'mailtemplate', 'read')) {
2305 $this->fields['myfield']['visible'] = 1;
2306 $this->fields['myfield']['noteditable'] = 0;
2307 }*/
2308
2309 // Unset fields that are disabled
2310 foreach ($this->fields as $key => $val) {
2311 if (isset($val['enabled']) && empty($val['enabled'])) {
2312 unset($this->fields[$key]);
2313 }
2314 }
2315
2316 // Translate some data of arrayofkeyval
2317 if (is_object($langs)) {
2318 foreach ($this->fields as $key => $val) {
2319 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
2320 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
2321 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
2322 }
2323 }
2324 }
2325 }
2326 }
2327
2328
2338 public function fetch($id, $ref = null, $noextrafields = 0, $nolines = 0)
2339 {
2340 // The table llx_c_email_templates has no field ref. The field ref was named "label" instead. So we change the call to fetchCommon.
2341 //$result = $this->fetchCommon($id, $ref, '', $noextrafields);
2342 $result = $this->fetchCommon($id, '', (empty($ref) ? '' : " AND t.label = '".$this->db->escape($ref)."'"), $noextrafields);
2343
2344 if ($result > 0 && !empty($this->table_element_line) && empty($nolines)) {
2345 $this->fetchLines($noextrafields);
2346 }
2347 return $result;
2348 }
2349}
print $object position
Definition edit.php:206
Class to manage a WYSIWYG editor.
Class permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new Form...
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.
Class permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new Form...
get_attached_files()
Return list of attached files (stored in SECTION array)
getHtmlForWithErrorsTo()
get Html For WithErrorsTo
getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
Return Html section for the 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_model.
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 This information is show when MAIN_EMAIL_USECCC is set.
remove_attached_files($keytodelete)
Remove a file from the list of attached files (stored in SECTION array)
__construct($db)
Constructor.
getHtmlForDeliveryreceipt()
get Html For Asking for Delivery Receipt
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 for Position.
Class to manage translations.
Class to manage Dolibarr users.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as p label as s rowid as s nom as s email
Sender: Who sends the email ("Sender" has sent emails on behalf of "From").
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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_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.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
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...
ui state ui widget content ui state ui widget header ui state a ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:162
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
getMaxFileSizeArray()
Return the max allowed for file upload.