html.formmail.class.php 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  1. <?php
  2. /* Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
  4. * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
  5. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * \file htdocs/core/class/html.formmail.class.php
  22. * \ingroup core
  23. * \brief Fichier de la classe permettant la generation du formulaire html d'envoi de mail unitaire
  24. */
  25. require_once DOL_DOCUMENT_ROOT .'/core/class/html.form.class.php';
  26. /**
  27. * Classe permettant la generation du formulaire html d'envoi de mail unitaire
  28. * Usage: $formail = new FormMail($db)
  29. * $formmail->proprietes=1 ou chaine ou tableau de valeurs
  30. * $formmail->show_form() affiche le formulaire
  31. */
  32. class FormMail extends Form
  33. {
  34. var $db;
  35. var $withform; // 1=Include HTML form tag and show submit button, 0=Do not include form tag and submit button, -1=Do not include form tag but include submit button
  36. var $fromname;
  37. var $frommail;
  38. var $replytoname;
  39. var $replytomail;
  40. var $toname;
  41. var $tomail;
  42. var $trackid;
  43. var $withsubstit; // Show substitution array
  44. var $withfrom;
  45. /**
  46. * @var int
  47. * @deprecated Fill withto with array before calling method.
  48. * @see withto
  49. */
  50. public $withtosocid;
  51. /**
  52. * @var int|int[]
  53. */
  54. public $withto; // Show recipient emails
  55. var $withtofree; // Show free text for recipient emails
  56. var $withtocc;
  57. var $withtoccc;
  58. var $withtopic;
  59. var $withfile; // 0=No attaches files, 1=Show attached files, 2=Can add new attached files
  60. var $withbody;
  61. var $withfromreadonly;
  62. var $withreplytoreadonly;
  63. var $withtoreadonly;
  64. var $withtoccreadonly;
  65. var $withtocccreadonly;
  66. var $withtopicreadonly;
  67. var $withfilereadonly;
  68. var $withdeliveryreceipt;
  69. var $withcancel;
  70. var $withfckeditor;
  71. var $substit=array();
  72. var $substit_lines=array();
  73. var $param=array();
  74. var $error;
  75. public $lines_model;
  76. /**
  77. * Constructor
  78. *
  79. * @param DoliDB $db Database handler
  80. */
  81. function __construct($db)
  82. {
  83. $this->db = $db;
  84. $this->withform=1;
  85. $this->withfrom=1;
  86. $this->withto=1;
  87. $this->withtofree=1;
  88. $this->withtocc=1;
  89. $this->withtoccc=0;
  90. $this->witherrorsto=0;
  91. $this->withtopic=1;
  92. $this->withfile=0;
  93. $this->withbody=1;
  94. $this->withfromreadonly=1;
  95. $this->withreplytoreadonly=1;
  96. $this->withtoreadonly=0;
  97. $this->withtoccreadonly=0;
  98. $this->withtocccreadonly=0;
  99. $this->witherrorstoreadonly=0;
  100. $this->withtopicreadonly=0;
  101. $this->withfilereadonly=0;
  102. $this->withbodyreadonly=0;
  103. $this->withdeliveryreceiptreadonly=0;
  104. $this->withfckeditor=-1; // -1 = Auto
  105. return 1;
  106. }
  107. /**
  108. * Clear list of attached files in send mail form (also stored in session)
  109. *
  110. * @return void
  111. */
  112. function clear_attached_files()
  113. {
  114. global $conf,$user;
  115. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  116. // Set tmp user directory
  117. $vardir=$conf->user->dir_output."/".$user->id;
  118. $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
  119. if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir);
  120. $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined
  121. unset($_SESSION["listofpaths".$keytoavoidconflict]);
  122. unset($_SESSION["listofnames".$keytoavoidconflict]);
  123. unset($_SESSION["listofmimes".$keytoavoidconflict]);
  124. }
  125. /**
  126. * Add a file into the list of attached files (stored in SECTION array)
  127. *
  128. * @param string $path Full absolute path on filesystem of file, including file name
  129. * @param string $file Only filename
  130. * @param string $type Mime type
  131. * @return void
  132. */
  133. function add_attached_files($path,$file,$type)
  134. {
  135. $listofpaths=array();
  136. $listofnames=array();
  137. $listofmimes=array();
  138. $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined
  139. if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
  140. if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
  141. if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
  142. if (! in_array($file,$listofnames))
  143. {
  144. $listofpaths[]=$path;
  145. $listofnames[]=$file;
  146. $listofmimes[]=$type;
  147. $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
  148. $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
  149. $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
  150. }
  151. }
  152. /**
  153. * Remove a file from the list of attached files (stored in SECTION array)
  154. *
  155. * @param string $keytodelete Key in file array (0, 1, 2, ...)
  156. * @return void
  157. */
  158. function remove_attached_files($keytodelete)
  159. {
  160. $listofpaths=array();
  161. $listofnames=array();
  162. $listofmimes=array();
  163. $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined
  164. if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
  165. if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
  166. if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
  167. if ($keytodelete >= 0)
  168. {
  169. unset ($listofpaths[$keytodelete]);
  170. unset ($listofnames[$keytodelete]);
  171. unset ($listofmimes[$keytodelete]);
  172. $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
  173. $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
  174. $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
  175. //var_dump($_SESSION['listofpaths']);
  176. }
  177. }
  178. /**
  179. * Return list of attached files (stored in SECTION array)
  180. *
  181. * @return array array('paths'=> ,'names'=>, 'mimes'=> )
  182. */
  183. function get_attached_files()
  184. {
  185. $listofpaths=array();
  186. $listofnames=array();
  187. $listofmimes=array();
  188. $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined
  189. if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
  190. if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
  191. if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
  192. return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
  193. }
  194. /**
  195. * Show the form to input an email
  196. * this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
  197. *
  198. * @param string $addfileaction Name of action when posting file attachments
  199. * @param string $removefileaction Name of action when removing file attachments
  200. * @return void
  201. */
  202. function show_form($addfileaction='addfile',$removefileaction='removefile')
  203. {
  204. print $this->get_form($addfileaction,$removefileaction);
  205. }
  206. /**
  207. * Get the form to input an email
  208. * this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
  209. * this->param: Contains more parameteres like email templates info
  210. *
  211. * @param string $addfileaction Name of action when posting file attachments
  212. * @param string $removefileaction Name of action when removing file attachments
  213. * @return string Form to show
  214. */
  215. function get_form($addfileaction='addfile',$removefileaction='removefile')
  216. {
  217. global $conf, $langs, $user, $hookmanager, $form;
  218. if (! is_object($form)) $form=new Form($this->db);
  219. $langs->load("other");
  220. $langs->load("mails");
  221. $hookmanager->initHooks(array('formmail'));
  222. $parameters=array(
  223. 'addfileaction' => $addfileaction,
  224. 'removefileaction'=> $removefileaction,
  225. 'trackid'=> $this->trackid
  226. );
  227. $reshook=$hookmanager->executeHooks('getFormMail', $parameters, $this);
  228. if (!empty($reshook))
  229. {
  230. return $hookmanager->resPrint;
  231. }
  232. else
  233. {
  234. $out='';
  235. $disablebademails=1;
  236. // Define list of attached files
  237. $listofpaths=array();
  238. $listofnames=array();
  239. $listofmimes=array();
  240. $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined
  241. if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
  242. if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
  243. if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
  244. // Define output language
  245. $outputlangs = $langs;
  246. $newlang = '';
  247. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $this->param['langsmodels'];
  248. if (! empty($newlang))
  249. {
  250. $outputlangs = new Translate("", $conf);
  251. $outputlangs->setDefaultLang($newlang);
  252. $outputlangs->load('other');
  253. }
  254. // Get message template
  255. $model_id=0;
  256. if (array_key_exists('models_id',$this->param))
  257. {
  258. $model_id=$this->param["models_id"];
  259. }
  260. $arraydefaultmessage=$this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);
  261. //var_dump($arraydefaultmessage);
  262. $out.= "\n".'<!-- Begin form mail --><div id="mailformdiv"></div>'."\n";
  263. if ($this->withform == 1)
  264. {
  265. $out.= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
  266. $out.= '<input style="display:none" type="submit" id="sendmail" name="sendmail">';
  267. $out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
  268. $out.= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
  269. $out.= '<a id="formmail" name="formmail"></a>';
  270. }
  271. foreach ($this->param as $key=>$value)
  272. {
  273. $out.= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
  274. }
  275. $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
  276. if ($result<0)
  277. {
  278. setEventMessages($this->error, $this->errors, 'errors');
  279. }
  280. $modelmail_array=array();
  281. foreach($this->lines_model as $line)
  282. {
  283. $modelmail_array[$line->id]=$line->label;
  284. }
  285. // Zone to select its email template
  286. if (count($modelmail_array)>0)
  287. {
  288. $out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
  289. $out.= $langs->trans('SelectMailModel').': '.$this->selectarray('modelmailselected', $modelmail_array, 0, 1);
  290. if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
  291. $out.= ' &nbsp; ';
  292. $out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
  293. $out.= ' &nbsp; ';
  294. $out.= '</div>';
  295. }
  296. elseif (! empty($this->param['models']) && in_array($this->param['models'], array(
  297. 'propal_send','order_send','facture_send',
  298. 'shipping_send','fichinter_send','supplier_proposal_send','order_supplier_send',
  299. 'invoice_supplier_send','thirdparty'
  300. )))
  301. {
  302. $out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
  303. $out.= $langs->trans('SelectMailModel').': <select name="modelmailselected" disabled="disabled"><option value="none">'.$langs->trans("NoTemplateDefined").'</option></select>'; // Do not put disabled on option, it is already on select and it makes chrome crazy.
  304. if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
  305. $out.= ' &nbsp; ';
  306. $out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
  307. $out.= ' &nbsp; ';
  308. $out.= '</div>';
  309. }
  310. $out.= '<table class="border" width="100%">'."\n";
  311. // Substitution array
  312. if (! empty($this->withsubstit))
  313. {
  314. $out.= '<tr><td colspan="2">';
  315. $help="";
  316. foreach($this->substit as $key => $val)
  317. {
  318. $help.=$key.' -> '.$langs->trans($val).'<br>';
  319. }
  320. $out.= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $help);
  321. $out.= "</td></tr>\n";
  322. }
  323. // From
  324. if (! empty($this->withfrom))
  325. {
  326. if (! empty($this->withfromreadonly))
  327. {
  328. $out.= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
  329. $out.= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
  330. $out.= '<tr><td width="180">'.$langs->trans("MailFrom").'</td><td>';
  331. if (! ($this->fromtype === 'user' && $this->fromid > 0)
  332. && ! ($this->fromtype === 'company')
  333. && ! preg_match('/user_aliases/', $this->fromtype)
  334. && ! preg_match('/global_aliases/', $this->fromtype))
  335. {
  336. // Use this->fromname and this->frommail or error if not defined
  337. $out.= $this->fromname;
  338. if ($this->frommail)
  339. {
  340. $out.= ' &lt;'.$this->frommail.'&gt;';
  341. }
  342. else
  343. {
  344. if ($this->fromtype)
  345. {
  346. $langs->load('errors');
  347. $out.= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
  348. }
  349. }
  350. } else {
  351. $liste = array();
  352. if (empty($user->email))
  353. {
  354. $langs->load('errors');
  355. $liste['user'] = $user->getFullName($langs) . ' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
  356. }
  357. else
  358. {
  359. $liste['user'] = $user->getFullName($langs) .' &lt;'.$user->email.'&gt;';
  360. }
  361. $liste['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM .' &lt;'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'&gt;';
  362. // Add also email aliases if there is one
  363. $listaliases=array('user_aliases'=>$user->email_aliases, 'global_aliases'=>$conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
  364. foreach($listaliases as $typealias => $listalias)
  365. {
  366. $posalias=0;
  367. $listaliasarray=explode(',', $listalias);
  368. foreach ($listaliasarray as $listaliasval)
  369. {
  370. $posalias++;
  371. $listaliasval=trim($listaliasval);
  372. if ($listaliasval)
  373. {
  374. $listaliasval=preg_replace('/</', '&lt;', $listaliasval);
  375. $listaliasval=preg_replace('/>/', '&gt;', $listaliasval);
  376. if (! preg_match('/&lt;/', $listaliasval)) $listaliasval='&lt;'.$listaliasval.'&gt;';
  377. $liste[$typealias.'_'.$posalias]=$listaliasval;
  378. }
  379. }
  380. }
  381. $out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', '', 0, '', $disablebademails);
  382. }
  383. $out.= "</td></tr>\n";
  384. $out.= "</td></tr>\n";
  385. }
  386. else
  387. {
  388. $out.= "<tr><td>".$langs->trans("MailFrom")."</td><td>";
  389. $out.= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" size="32" value="'.$this->fromname.'" />';
  390. $out.= '&nbsp; &nbsp; ';
  391. $out.= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" size="32" value="'.$this->frommail.'" />&gt;';
  392. $out.= "</td></tr>\n";
  393. }
  394. }
  395. // Replyto
  396. if (! empty($this->withreplyto))
  397. {
  398. if ($this->withreplytoreadonly)
  399. {
  400. $out.= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
  401. $out.= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
  402. $out.= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail?(" &lt;".$this->replytomail."&gt;"):"");
  403. $out.= "</td></tr>\n";
  404. }
  405. }
  406. // Errorsto
  407. if (! empty($this->witherrorsto))
  408. {
  409. //if (! $this->errorstomail) $this->errorstomail=$this->frommail;
  410. $errorstomail = (! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : $this->errorstomail);
  411. if ($this->witherrorstoreadonly)
  412. {
  413. $out.= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
  414. $out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
  415. $out.= $errorstomail;
  416. $out.= "</td></tr>\n";
  417. }
  418. else
  419. {
  420. $out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
  421. $out.= '<input size="30" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
  422. $out.= "</td></tr>\n";
  423. }
  424. }
  425. // To
  426. if (! empty($this->withto) || is_array($this->withto))
  427. {
  428. $out.= '<tr><td width="180">';
  429. if ($this->withtofree) $out.= $form->textwithpicto($langs->trans("MailTo"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
  430. else $out.= $langs->trans("MailTo");
  431. $out.= '</td><td>';
  432. if ($this->withtoreadonly)
  433. {
  434. if (! empty($this->toname) && ! empty($this->tomail))
  435. {
  436. $out.= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
  437. $out.= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
  438. if ($this->totype == 'thirdparty')
  439. {
  440. $soc=new Societe($this->db);
  441. $soc->fetch($this->toid);
  442. $out.= $soc->getNomUrl(1);
  443. }
  444. else if ($this->totype == 'contact')
  445. {
  446. $contact=new Contact($this->db);
  447. $contact->fetch($this->toid);
  448. $out.= $contact->getNomUrl(1);
  449. }
  450. else
  451. {
  452. $out.= $this->toname;
  453. }
  454. $out.= ' &lt;'.$this->tomail.'&gt;';
  455. if ($this->withtofree)
  456. {
  457. $out.= '<br>'.$langs->trans("or").' <input size="'.(is_array($this->withto)?"30":"60").'" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
  458. }
  459. }
  460. else
  461. {
  462. $out.= (! is_array($this->withto) && ! is_numeric($this->withto))?$this->withto:"";
  463. }
  464. }
  465. else
  466. {
  467. if (! empty($this->withtofree))
  468. {
  469. $out.= '<input size="'.(is_array($this->withto)?"30":"60").'" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
  470. }
  471. if (! empty($this->withto) && is_array($this->withto))
  472. {
  473. if (! empty($this->withtofree)) $out.= " ".$langs->trans("or")." ";
  474. // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
  475. $tmparray = $this->withto;
  476. foreach($tmparray as $key => $val)
  477. {
  478. $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
  479. }
  480. $out.= $form->multiselectarray("receiver", $tmparray, GETPOST("receiver"), null, null, 'inline-block minwidth500', null, "");
  481. }
  482. }
  483. $out.= "</td></tr>\n";
  484. }
  485. // CC
  486. if (! empty($this->withtocc) || is_array($this->withtocc))
  487. {
  488. $out.= '<tr><td width="180">';
  489. $out.= $form->textwithpicto($langs->trans("MailCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
  490. $out.= '</td><td>';
  491. if ($this->withtoccreadonly)
  492. {
  493. $out.= (! is_array($this->withtocc) && ! is_numeric($this->withtocc))?$this->withtocc:"";
  494. }
  495. else
  496. {
  497. $out.= '<input size="'.(is_array($this->withtocc)?"30":"60").'" id="sendtocc" name="sendtocc" value="'.((! is_array($this->withtocc) && ! is_numeric($this->withtocc))? (isset($_POST["sendtocc"])?$_POST["sendtocc"]:$this->withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />';
  498. if (! empty($this->withtocc) && is_array($this->withtocc))
  499. {
  500. $out.= " ".$langs->trans("or")." ";
  501. // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
  502. $tmparray = $this->withtocc;
  503. foreach($tmparray as $key => $val)
  504. {
  505. $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
  506. }
  507. $out.= $form->multiselectarray("receivercc", $tmparray, GETPOST("receivercc"), null, null, 'inline-block minwidth500',null, "");
  508. }
  509. }
  510. $out.= "</td></tr>\n";
  511. }
  512. // CCC
  513. if (! empty($this->withtoccc) || is_array($this->withtoccc))
  514. {
  515. $out.= '<tr><td width="180">';
  516. $out.= $form->textwithpicto($langs->trans("MailCCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
  517. $out.= '</td><td>';
  518. if (! empty($this->withtocccreadonly))
  519. {
  520. $out.= (! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))?$this->withtoccc:"";
  521. }
  522. else
  523. {
  524. $out.= '<input size="'.(is_array($this->withtoccc)?"30":"60").'" id="sendtoccc" name="sendtoccc" value="'.((! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))? (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:$this->withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />';
  525. if (! empty($this->withtoccc) && is_array($this->withtoccc))
  526. {
  527. $out.= " ".$langs->trans("or")." ";
  528. // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
  529. $tmparray = $this->withtoccc;
  530. foreach($tmparray as $key => $val)
  531. {
  532. $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
  533. }
  534. //$out.= $form->selectarray("receiverccc", $this->withtoccc, GETPOST("receiverccc"), 1);
  535. $out.= $form->multiselectarray("receiverccc", $tmparray, GETPOST("receiverccc"), null, null, null,null, "90%");
  536. }
  537. }
  538. $showinfobcc='';
  539. 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;
  540. 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;
  541. 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;
  542. 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;
  543. if ($showinfobcc) $out.=' + '.$showinfobcc;
  544. $out.= "</td></tr>\n";
  545. }
  546. // Ask delivery receipt
  547. if (! empty($this->withdeliveryreceipt))
  548. {
  549. $out.= '<tr><td width="180">'.$langs->trans("DeliveryReceipt").'</td><td>';
  550. if (! empty($this->withdeliveryreceiptreadonly))
  551. {
  552. $out.= yn($this->withdeliveryreceipt);
  553. }
  554. else
  555. {
  556. $defaultvaluefordeliveryreceipt=0;
  557. if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt=1;
  558. if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt=1;
  559. if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt=1;
  560. if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt=1;
  561. $out.= $form->selectyesno('deliveryreceipt', (isset($_POST["deliveryreceipt"])?$_POST["deliveryreceipt"]:$defaultvaluefordeliveryreceipt), 1);
  562. }
  563. $out.= "</td></tr>\n";
  564. }
  565. // Topic
  566. if (! empty($this->withtopic))
  567. {
  568. $defaulttopic="";
  569. if (count($arraydefaultmessage) > 0 && $arraydefaultmessage['topic']) $defaulttopic=$arraydefaultmessage['topic'];
  570. elseif (! is_numeric($this->withtopic)) $defaulttopic=$this->withtopic;
  571. $defaulttopic=make_substitutions($defaulttopic,$this->substit);
  572. $out.= '<tr>';
  573. $out.= '<td width="180">'.$langs->trans("MailTopic").'</td>';
  574. $out.= '<td>';
  575. if ($this->withtopicreadonly)
  576. {
  577. $out.= $defaulttopic;
  578. $out.= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
  579. }
  580. else
  581. {
  582. $out.= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'. ((isset($_POST["subject"]) && ! $_POST['modelselected'])?$_POST["subject"]:($defaulttopic?$defaulttopic:'')) .'" />';
  583. }
  584. $out.= "</td></tr>\n";
  585. }
  586. // Attached files
  587. if (! empty($this->withfile))
  588. {
  589. $out.= '<tr>';
  590. $out.= '<td width="180">'.$langs->trans("MailFile").'</td>';
  591. $out.= '<td>';
  592. if (is_numeric($this->withfile))
  593. {
  594. // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
  595. $out.= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
  596. $out.= '<script type="text/javascript" language="javascript">';
  597. $out.= 'jQuery(document).ready(function () {';
  598. $out.= ' jQuery(".removedfile").click(function() {';
  599. $out.= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
  600. $out.= ' });';
  601. $out.= '})';
  602. $out.= '</script>'."\n";
  603. if (count($listofpaths))
  604. {
  605. foreach($listofpaths as $key => $val)
  606. {
  607. $out.= '<div id="attachfile_'.$key.'">';
  608. $out.= img_mime($listofnames[$key]).' '.$listofnames[$key];
  609. if (! $this->withfilereadonly)
  610. {
  611. $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.'" />';
  612. //$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
  613. }
  614. $out.= '<br></div>';
  615. }
  616. }
  617. else
  618. {
  619. $out.= $langs->trans("NoAttachedFiles").'<br>';
  620. }
  621. if ($this->withfile == 2) // Can add other files
  622. {
  623. 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 />';
  624. else $out.= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
  625. $out.= ' ';
  626. $out.= '<input class="button" type="submit" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
  627. }
  628. }
  629. else
  630. {
  631. $out.=$this->withfile;
  632. }
  633. $out.= "</td></tr>\n";
  634. }
  635. // Message
  636. if (! empty($this->withbody))
  637. {
  638. $defaultmessage="";
  639. if (count($arraydefaultmessage) > 0 && $arraydefaultmessage['content']) $defaultmessage=$arraydefaultmessage['content'];
  640. elseif (! is_numeric($this->withbody)) $defaultmessage=$this->withbody;
  641. // Complete substitution array
  642. if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_ADD_PAYMENT_URL))
  643. {
  644. require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php';
  645. $langs->load('paypal');
  646. // Set the paypal message and url link into __PERSONALIZED__ key
  647. if ($this->param["models"]=='order_send')
  648. {
  649. $url=getPaypalPaymentUrl(0,'order',$this->substit['__ORDERREF__']?$this->substit['__ORDERREF__']:$this->substit['__REF__']);
  650. $this->substit['__PERSONALIZED__']=str_replace('\n',"\n",$langs->transnoentitiesnoconv("PredefinedMailContentLink",$url));
  651. }
  652. if ($this->param["models"]=='facture_send')
  653. {
  654. $url=getPaypalPaymentUrl(0,'invoice',$this->substit['__REF__']);
  655. $this->substit['__PERSONALIZED__']=str_replace('\n',"\n",$langs->transnoentitiesnoconv("PredefinedMailContentLink",$url));
  656. }
  657. }
  658. //Add lines substitution key from each line
  659. $lines = '';
  660. $defaultlines = $arraydefaultmessage['content_lines'];
  661. if (isset($defaultlines))
  662. {
  663. foreach ($this->substit_lines as $substit_line)
  664. {
  665. $lines .= make_substitutions($defaultlines,$substit_line)."\n";
  666. }
  667. }
  668. $this->substit['__LINES__']=$lines;
  669. $defaultmessage=str_replace('\n',"\n",$defaultmessage);
  670. // Deal with format differences between message and signature (text / HTML)
  671. if(dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__SIGNATURE__'])) {
  672. $this->substit['__SIGNATURE__'] = dol_nl2br($this->substit['__SIGNATURE__']);
  673. } else if(!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__SIGNATURE__'])) {
  674. $defaultmessage = dol_nl2br($defaultmessage);
  675. }
  676. if (isset($_POST["message"]) && ! $_POST['modelselected']) $defaultmessage=$_POST["message"];
  677. else
  678. {
  679. $defaultmessage=make_substitutions($defaultmessage,$this->substit);
  680. // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
  681. $defaultmessage=preg_replace("/^(<br>)+/","",$defaultmessage);
  682. $defaultmessage=preg_replace("/^\n+/","",$defaultmessage);
  683. }
  684. $out.= '<tr>';
  685. $out.= '<td width="180" valign="top">'.$langs->trans("MailText").'</td>';
  686. $out.= '<td>';
  687. if ($this->withbodyreadonly)
  688. {
  689. $out.= nl2br($defaultmessage);
  690. $out.= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
  691. }
  692. else
  693. {
  694. if (! isset($this->ckeditortoolbar)) $this->ckeditortoolbar = 'dolibarr_notes';
  695. // Editor wysiwyg
  696. require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
  697. if ($this->withfckeditor == -1)
  698. {
  699. if (! empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor=1;
  700. else $this->withfckeditor=0;
  701. }
  702. $doleditor=new DolEditor('message',$defaultmessage,'',280,$this->ckeditortoolbar,'In',true,true,$this->withfckeditor,8,'95%');
  703. $out.= $doleditor->Create(1);
  704. }
  705. $out.= "</td></tr>\n";
  706. }
  707. $out.= '</table>'."\n";
  708. if ($this->withform == 1 || $this->withform == -1)
  709. {
  710. $out.= '<br><div class="center">';
  711. $out.= '<input class="button" type="submit" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
  712. // Add a javascript test to avoid to forget to submit file before sending email
  713. if ($this->withfile == 2 && $conf->use_javascript_ajax)
  714. {
  715. $out.= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
  716. }
  717. $out.= ' />';
  718. if ($this->withcancel)
  719. {
  720. $out.= ' &nbsp; &nbsp; ';
  721. $out.= '<input class="button" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
  722. }
  723. $out.= '</div>'."\n";
  724. }
  725. if ($this->withform == 1) $out.= '</form>'."\n";
  726. // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
  727. if (! empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY))
  728. {
  729. $out.= '<script type="text/javascript" language="javascript">';
  730. $out.= 'jQuery(document).ready(function () {';
  731. $out.= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is calle at every key pressed ! */
  732. var code = e.keyCode || e.which;
  733. if (code == 13) {
  734. e.preventDefault();
  735. return false;
  736. }
  737. });';
  738. $out.=' })';
  739. $out.= '</script>';
  740. }
  741. $out.= "<!-- End form mail -->\n";
  742. return $out;
  743. }
  744. }
  745. /**
  746. * Return template of email
  747. * Search into table c_email_templates
  748. *
  749. * @param DoliDB $db Database handler
  750. * @param string $type_template Get message for key module
  751. * @param string $user Use template public or limited to this user
  752. * @param Translate $outputlangs Output lang object
  753. * @param int $id Id template to find
  754. * @param int $active 1=Only active template, 0=Only disabled, -1=All
  755. * @return array array('topic'=>,'content'=>,..)
  756. */
  757. private function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1)
  758. {
  759. $ret=array();
  760. $sql = "SELECT label, topic, content, content_lines, lang";
  761. $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
  762. $sql.= " WHERE type_template='".$db->escape($type_template)."'";
  763. $sql.= " AND entity IN (".getEntity("c_email_templates").")";
  764. $sql.= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
  765. if ($active >= 0) $sql.=" AND active = ".$active;
  766. if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
  767. if (!empty($id)) $sql.= " AND rowid=".$id;
  768. $sql.= $db->order("position,lang,label","ASC");
  769. //print $sql;
  770. $resql = $db->query($sql);
  771. if ($resql)
  772. {
  773. $obj = $db->fetch_object($resql); // Get first found
  774. if ($obj)
  775. {
  776. $ret['label']=$obj->label;
  777. $ret['topic']=$obj->topic;
  778. $ret['content']=$obj->content;
  779. $ret['content_lines']=$obj->content_lines;
  780. $ret['lang']=$obj->lang;
  781. }
  782. else
  783. {
  784. $defaultmessage='';
  785. if ($type_template=='facture_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoice"); }
  786. elseif ($type_template=='facture_relance') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder"); }
  787. elseif ($type_template=='propal_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendProposal"); }
  788. elseif ($type_template=='supplier_proposal_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal"); }
  789. elseif ($type_template=='order_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendOrder"); }
  790. elseif ($type_template=='order_supplier_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder"); }
  791. elseif ($type_template=='invoice_supplier_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice"); }
  792. elseif ($type_template=='shipping_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendShipping"); }
  793. elseif ($type_template=='fichinter_send') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendFichInter"); }
  794. elseif ($type_template=='thirdparty') { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentThirdparty"); }
  795. $ret['label']='default';
  796. $ret['topic']='';
  797. $ret['content']=$defaultmessage;
  798. $ret['content_lines']='';
  799. $ret['lang']=$outputlangs->defaultlang;
  800. }
  801. $db->free($resql);
  802. return $ret;
  803. }
  804. else
  805. {
  806. dol_print_error($db);
  807. return -1;
  808. }
  809. }
  810. /**
  811. * Find if template exists
  812. * Search into table c_email_templates
  813. *
  814. * @param string $type_template Get message for key module
  815. * @param string $user Use template public or limited to this user
  816. * @param Translate $outputlangs Output lang object
  817. * @return int <0 if KO,
  818. */
  819. public function isEMailTemplate($type_template, $user, $outputlangs)
  820. {
  821. $ret=array();
  822. $sql = "SELECT label, topic, content, lang";
  823. $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
  824. $sql.= " WHERE type_template='".$this->db->escape($type_template)."'";
  825. $sql.= " AND entity IN (".getEntity("c_email_templates").")";
  826. $sql.= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
  827. if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
  828. $sql.= $this->db->order("lang,label","ASC");
  829. //print $sql;
  830. $resql = $this->db->query($sql);
  831. if ($resql)
  832. {
  833. $num= $this->db->num_rows($resql);
  834. $this->db->free($resql);
  835. return $num;
  836. }
  837. else
  838. {
  839. $this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
  840. return -1;
  841. }
  842. }
  843. /**
  844. * Find if template exists
  845. * Search into table c_email_templates
  846. *
  847. * @param string $type_template Get message for key module
  848. * @param string $user Use template public or limited to this user
  849. * @param Translate $outputlangs Output lang object
  850. * @param int $active 1=Only active template, 0=Only disabled, -1=All
  851. * @return int <0 if KO, nb of records found if OK
  852. */
  853. public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active=1)
  854. {
  855. $ret=array();
  856. $sql = "SELECT rowid, label, topic, content, content_lines, lang, position";
  857. $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
  858. $sql.= " WHERE type_template='".$this->db->escape($type_template)."'";
  859. $sql.= " AND entity IN (".getEntity("c_email_templates").")";
  860. $sql.= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
  861. if ($active >= 0) $sql.=" AND active = ".$active;
  862. if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
  863. $sql.= $this->db->order("position,lang,label","ASC");
  864. //print $sql;
  865. $resql = $this->db->query($sql);
  866. if ($resql)
  867. {
  868. $num=$this->db->num_rows($resql);
  869. $this->lines_model=array();
  870. while ($obj = $this->db->fetch_object($resql))
  871. {
  872. $line = new ModelMail();
  873. $line->id=$obj->rowid;
  874. $line->label=$obj->label;
  875. $line->topic=$obj->topic;
  876. $line->content=$obj->content;
  877. $line->content_lines=$obj->content_lines;
  878. $line->lang=$obj->lang;
  879. $this->lines_model[]=$line;
  880. }
  881. $this->db->free($resql);
  882. return $num;
  883. }
  884. else
  885. {
  886. $this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
  887. return -1;
  888. }
  889. }
  890. /**
  891. * Set substit array from object
  892. *
  893. * @param CommonObject $object Object to use
  894. * @param Translate $outputlangs Object lang
  895. * @return void
  896. */
  897. function setSubstitFromObject($object, $outputlangs=null)
  898. {
  899. global $conf, $user;
  900. $this->substit['__REF__'] = $object->ref;
  901. $this->substit['__REFCLIENT__'] = isset($object->ref_client) ? $object->ref_client : '';
  902. $this->substit['__REFSUPPLIER__'] = isset($object->ref_supplier) ? $object->ref_supplier : '';
  903. $this->substit['__DATE_YMD__'] = isset($object->date) ? dol_print_date($object->date, 'day', 0, $outputlangs) : '';
  904. $this->substit['__DATE_DUE_YMD__'] = isset($object->date_lim_reglement)? dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) : '';
  905. $this->substit['__AMOUNT__'] = price($object->total_ttc);
  906. $this->substit['__AMOUNT_WO_TAX__'] = price($object->total_ht);
  907. $this->substit['__AMOUNT_VAT__'] = price($object->total_tva);
  908. $this->substit['__THIRDPARTY_ID__'] = (is_object($object->thirdparty)?$object->thirdparty->id:'');
  909. $this->substit['__THIRDPARTY_NAME__'] = (is_object($object->thirdparty)?$object->thirdparty->name:'');
  910. $this->substit['__PROJECT_ID__'] = (is_object($object->projet)?$object->projet->id:'');
  911. $this->substit['__PROJECT_REF__'] = (is_object($object->projet)?$object->projet->ref:'');
  912. $this->substit['__PROJECT_NAME__'] = (is_object($object->projet)?$object->projet->title:'');
  913. $this->substit['__SIGNATURE__'] = $user->signature;
  914. $this->substit['__PERSONALIZED__'] = '';
  915. $this->substit['__CONTACTCIVNAME__'] = ''; // Will be replace just before sending
  916. // Create dinamic tags for __EXTRAFIELD_FIELD__
  917. $extrafields = new ExtraFields($this->db);
  918. $extralabels = $extrafields->fetch_name_optionals_label($object->table_element, true);
  919. $object->fetch_optionals($object->id, $extralabels);
  920. foreach ($extrafields->attribute_label as $key => $label) {
  921. $this->substit['__EXTRAFIELD_' . strtoupper($key) . '__'] = $object->array_options['options_' . $key];
  922. }
  923. //Fill substit_lines with each object lines content
  924. if (is_array($object->lines))
  925. {
  926. foreach ($object->lines as $line)
  927. {
  928. $substit_line = array(
  929. '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
  930. '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
  931. '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
  932. '__LABEL__' => isset($line->label) ? $line->label : '',
  933. '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
  934. '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
  935. '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
  936. '__QUANTITY__' => $line->qty,
  937. '__SUBPRICE__' => price($line->subprice),
  938. '__AMOUNT__' => price($line->total_ttc),
  939. '__AMOUNT_WO_TAX__' => price($line->total_ht),
  940. //'__PRODUCT_EXTRAFIELD_FIELD__' Done dinamically just after
  941. );
  942. // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
  943. if (!empty($line->fk_product))
  944. {
  945. $extrafields = new ExtraFields($this->db);
  946. $extralabels = $extrafields->fetch_name_optionals_label('product', true);
  947. $product = new Product($this->db);
  948. $product->fetch($line->fk_product, '', '', 1);
  949. $product->fetch_optionals($product->id, $extralabels);
  950. foreach ($extrafields->attribute_label as $key => $label) {
  951. $substit_line['__PRODUCT_EXTRAFIELD_' . strtoupper($key) . '__'] = $product->array_options['options_' . $key];
  952. }
  953. }
  954. $this->substit_lines[] = $substit_line;
  955. }
  956. }
  957. }
  958. /**
  959. * Get list of substition keys available.
  960. *
  961. * @param string $mode 'formemail', 'formemailwithlines', 'formemailforlines', 'emailing', ...
  962. * @return void
  963. */
  964. static function getAvailableSubstitKey($mode='formemail')
  965. {
  966. global $conf, $langs;
  967. $vars=array();
  968. if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines')
  969. {
  970. $vars=array(
  971. '__REF__',
  972. '__REFCLIENT__',
  973. '__REFSUPPLIER__',
  974. '__THIRDPARTY_ID__',
  975. '__THIRDPARTY_NAME__',
  976. '__PROJECT_ID__',
  977. '__PROJECT_REF__',
  978. '__PROJECT_NAME__',
  979. '__CONTACTCIVNAME__',
  980. '__AMOUNT__',
  981. '__AMOUNT_WO_TAX__',
  982. '__AMOUNT_VAT__',
  983. '__PERSONALIZED__', // Paypal link will be added here in form mode
  984. '__SIGNATURE__',
  985. );
  986. if ($mode == 'formwithlines')
  987. {
  988. $vars[] = '__LINES__'; // Will be set by the get_form function
  989. }
  990. if ($mode == 'formforlines')
  991. {
  992. $vars[] = '__QUANTITY__'; // Will be set by the get_form function
  993. }
  994. }
  995. if ($mode == 'emailing')
  996. {
  997. // For mass emailing, we have different keys
  998. $vars=array(
  999. '__ID__' => 'IdRecord',
  1000. '__EMAIL__' => 'EMailRecipient',
  1001. '__LASTNAME__' => 'Lastname',
  1002. '__FIRSTNAME__' => 'Firstname',
  1003. '__MAILTOEMAIL__' => 'TagMailtoEmail',
  1004. '__OTHER1__' => 'Other1',
  1005. '__OTHER2__' => 'Other2',
  1006. '__OTHER3__' => 'Other3',
  1007. '__OTHER4__' => 'Other4',
  1008. '__OTHER5__' => 'Other5',
  1009. '__SIGNATURE__' => 'TagSignature',
  1010. '__CHECK_READ__' => 'TagCheckMail',
  1011. '__UNSUBSCRIBE__' => 'TagUnsubscribe'
  1012. //,'__PERSONALIZED__' => 'Personalized' // Hidden because not used yet in mass emailing
  1013. );
  1014. if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN))
  1015. {
  1016. $vars['__SECUREKEYPAYPAL__']='SecureKeyPaypal';
  1017. if (! empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE))
  1018. {
  1019. if ($conf->adherent->enabled) $vars['__SECUREKEYPAYPAL_MEMBER__']='SecureKeyPaypalUniquePerMember';
  1020. if ($conf->facture->enabled) $vars['__SECUREKEYPAYPAL_INVOICE__']='SecureKeyPaypalUniquePerInvoice';
  1021. if ($conf->commande->enabled) $vars['__SECUREKEYPAYPAL_ORDER__']='SecureKeyPaypalUniquePerOrder';
  1022. if ($conf->contrat->enabled) $vars['__SECUREKEYPAYPAL_CONTRACTLINE__']='SecureKeyPaypalUniquePerContractLine';
  1023. }
  1024. }
  1025. else
  1026. {
  1027. $vars['__SECUREKEYPAYPAL__']='';
  1028. $vars['__SECUREKEYPAYPAL_MEMBER__']='';
  1029. }
  1030. }
  1031. $tmparray=array();
  1032. $parameters=array('mode'=>$mode);
  1033. complete_substitutions_array($tmparray, $langs, null, $parameters);
  1034. foreach($tmparray as $key => $val)
  1035. {
  1036. $vars[$key]=$key;
  1037. }
  1038. return $vars;
  1039. }
  1040. }
  1041. /**
  1042. * ModelMail
  1043. */
  1044. class ModelMail
  1045. {
  1046. public $id;
  1047. public $label;
  1048. public $topic;
  1049. public $content;
  1050. public $content_lines;
  1051. public $lang;
  1052. }