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