PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/core/actions_sendmails.inc.php

http://github.com/Dolibarr/dolibarr
PHP | 459 lines | 333 code | 55 blank | 71 comment | 102 complexity | b42b5e404227c467095e1192c93e9b13 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-3.0, LGPL-2.0, CC-BY-SA-4.0, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, MIT
  1. <?php
  2. /* Copyright (C) 2013 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. * or see https://www.gnu.org/
  18. */
  19. /**
  20. * \file htdocs/core/actions_sendmails.inc.php
  21. * \brief Code for actions on sending mails from object page
  22. */
  23. // $mysoc must be defined
  24. // $id must be defined
  25. // $paramname may be defined
  26. // $autocopy may be defined (used to know the automatic BCC to add)
  27. // $triggersendname must be set (can be '')
  28. // $actiontypecode can be set
  29. // $object and $uobject may be defined
  30. /*
  31. * Add file in email form
  32. */
  33. if (GETPOST('addfile', 'alpha')) {
  34. $trackid = GETPOST('trackid', 'aZ09');
  35. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  36. // Set tmp user directory
  37. $vardir = $conf->user->dir_output."/".$user->id;
  38. $upload_dir_tmp = $vardir.'/temp'; // TODO Add $keytoavoidconflict in upload_dir path
  39. dol_add_file_process($upload_dir_tmp, 1, 0, 'addedfile', '', null, $trackid, 0);
  40. $action = 'presend';
  41. }
  42. /*
  43. * Remove file in email form
  44. */
  45. if (!empty($_POST['removedfile']) && empty($_POST['removAll'])) {
  46. $trackid = GETPOST('trackid', 'aZ09');
  47. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  48. // Set tmp user directory
  49. $vardir = $conf->user->dir_output."/".$user->id;
  50. $upload_dir_tmp = $vardir.'/temp'; // TODO Add $keytoavoidconflict in upload_dir path
  51. // TODO Delete only files that was uploaded from email form. This can be addressed by adding the trackid into the temp path then changing donotdeletefile to 2 instead of 1 to say "delete only if into temp dir"
  52. // GETPOST('removedfile','alpha') is position of file into $_SESSION["listofpaths"...] array.
  53. dol_remove_file_process(GETPOST('removedfile', 'alpha'), 0, 1, $trackid); // We do not delete because if file is the official PDF of doc, we don't want to remove it physically
  54. $action = 'presend';
  55. }
  56. /*
  57. * Remove all files in email form
  58. */
  59. if (GETPOST('removAll', 'alpha')) {
  60. $trackid = GETPOST('trackid', 'aZ09');
  61. $listofpaths = array();
  62. $listofnames = array();
  63. $listofmimes = array();
  64. $keytoavoidconflict = empty($trackid) ? '' : '-'.$trackid;
  65. if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
  66. $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
  67. }
  68. if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
  69. $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
  70. }
  71. if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
  72. $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
  73. }
  74. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
  75. $formmail = new FormMail($db);
  76. $formmail->trackid = $trackid;
  77. foreach ($listofpaths as $key => $value) {
  78. $pathtodelete = $value;
  79. $filetodelete = $listofnames[$key];
  80. $result = dol_delete_file($pathtodelete, 1); // Delete uploded Files
  81. $langs->load("other");
  82. setEventMessages($langs->trans("FileWasRemoved", $filetodelete), null, 'mesgs');
  83. $formmail->remove_attached_files($key); // Update Session
  84. }
  85. }
  86. /*
  87. * Send mail
  88. */
  89. if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST['removAll'] && !$_POST['removedfile'] && !$_POST['cancel'] && !$_POST['modelselected']) {
  90. if (empty($trackid)) {
  91. $trackid = GETPOST('trackid', 'aZ09');
  92. }
  93. $subject = '';
  94. $actionmsg = '';
  95. $actionmsg2 = '';
  96. $langs->load('mails');
  97. if (is_object($object)) {
  98. $result = $object->fetch($id);
  99. $sendtosocid = 0; // Id of related thirdparty
  100. if (method_exists($object, "fetch_thirdparty") && !in_array($object->element, array('member', 'user', 'expensereport', 'societe', 'contact'))) {
  101. $resultthirdparty = $object->fetch_thirdparty();
  102. $thirdparty = $object->thirdparty;
  103. if (is_object($thirdparty)) {
  104. $sendtosocid = $thirdparty->id;
  105. }
  106. } elseif ($object->element == 'member' || $object->element == 'user') {
  107. $thirdparty = $object;
  108. if ($object->socid > 0) {
  109. $sendtosocid = $object->socid;
  110. }
  111. } elseif ($object->element == 'expensereport') {
  112. $tmpuser = new User($db);
  113. $tmpuser->fetch($object->fk_user_author);
  114. $thirdparty = $tmpuser;
  115. if ($object->socid > 0) {
  116. $sendtosocid = $object->socid;
  117. }
  118. } elseif ($object->element == 'societe') {
  119. $thirdparty = $object;
  120. if (is_object($thirdparty) && $thirdparty->id > 0) {
  121. $sendtosocid = $thirdparty->id;
  122. }
  123. } elseif ($object->element == 'contact') {
  124. $contact = $object;
  125. if ($contact->id > 0) {
  126. $contact->fetch_thirdparty();
  127. $thirdparty = $contact->thirdparty;
  128. if (is_object($thirdparty) && $thirdparty->id > 0) {
  129. $sendtosocid = $thirdparty->id;
  130. }
  131. }
  132. } else {
  133. dol_print_error('', "Use actions_sendmails.in.php for an element/object '".$object->element."' that is not supported");
  134. }
  135. if (is_object($hookmanager)) {
  136. $parameters = array();
  137. $reshook = $hookmanager->executeHooks('initSendToSocid', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  138. }
  139. } else {
  140. $thirdparty = $mysoc;
  141. }
  142. if ($result > 0) {
  143. $sendto = '';
  144. $sendtocc = '';
  145. $sendtobcc = '';
  146. $sendtoid = array();
  147. $sendtouserid = array();
  148. $sendtoccuserid = array();
  149. // Define $sendto
  150. $receiver = $_POST['receiver'];
  151. if (!is_array($receiver)) {
  152. if ($receiver == '-1') {
  153. $receiver = array();
  154. } else {
  155. $receiver = array($receiver);
  156. }
  157. }
  158. $tmparray = array();
  159. if (trim($_POST['sendto'])) {
  160. // Recipients are provided into free text field
  161. $tmparray[] = trim($_POST['sendto']);
  162. }
  163. if (trim($_POST['tomail'])) {
  164. // Recipients are provided into free hidden text field
  165. $tmparray[] = trim($_POST['tomail']);
  166. }
  167. if (count($receiver) > 0) {
  168. // Recipient was provided from combo list
  169. foreach ($receiver as $key => $val) {
  170. if ($val == 'thirdparty') { // Key selected means current third party ('thirdparty' may be used for current member or current user too)
  171. $tmparray[] = dol_string_nospecial($thirdparty->getFullName($langs), ' ', array(",")).' <'.$thirdparty->email.'>';
  172. } elseif ($val == 'contact') { // Key selected means current contact
  173. $tmparray[] = dol_string_nospecial($contact->getFullName($langs), ' ', array(",")).' <'.$contact->email.'>';
  174. $sendtoid[] = $contact->id;
  175. } elseif ($val) { // $val is the Id of a contact
  176. $tmparray[] = $thirdparty->contact_get_property((int) $val, 'email');
  177. $sendtoid[] = ((int) $val);
  178. }
  179. }
  180. }
  181. if (!empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) {
  182. $receiveruser = $_POST['receiveruser'];
  183. if (is_array($receiveruser) && count($receiveruser) > 0) {
  184. $fuserdest = new User($db);
  185. foreach ($receiveruser as $key => $val) {
  186. $tmparray[] = $fuserdest->user_get_property($val, 'email');
  187. $sendtouserid[] = $val;
  188. }
  189. }
  190. }
  191. $sendto = implode(',', $tmparray);
  192. // Define $sendtocc
  193. $receivercc = $_POST['receivercc'];
  194. if (!is_array($receivercc)) {
  195. if ($receivercc == '-1') {
  196. $receivercc = array();
  197. } else {
  198. $receivercc = array($receivercc);
  199. }
  200. }
  201. $tmparray = array();
  202. if (trim($_POST['sendtocc'])) {
  203. $tmparray[] = trim($_POST['sendtocc']);
  204. }
  205. if (count($receivercc) > 0) {
  206. foreach ($receivercc as $key => $val) {
  207. if ($val == 'thirdparty') { // Key selected means current thirdparty (may be usd for current member or current user too)
  208. // Recipient was provided from combo list
  209. $tmparray[] = dol_string_nospecial($thirdparty->name, ' ', array(",")).' <'.$thirdparty->email.'>';
  210. } elseif ($val == 'contact') { // Key selected means current contact
  211. // Recipient was provided from combo list
  212. $tmparray[] = dol_string_nospecial($contact->name, ' ', array(",")).' <'.$contact->email.'>';
  213. //$sendtoid[] = $contact->id; TODO Add also id of contact in CC ?
  214. } elseif ($val) { // $val is the Id of a contact
  215. $tmparray[] = $thirdparty->contact_get_property((int) $val, 'email');
  216. //$sendtoid[] = ((int) $val); TODO Add also id of contact in CC ?
  217. }
  218. }
  219. }
  220. if (!empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) {
  221. $receiverccuser = $_POST['receiverccuser'];
  222. if (is_array($receiverccuser) && count($receiverccuser) > 0) {
  223. $fuserdest = new User($db);
  224. foreach ($receiverccuser as $key => $val) {
  225. $tmparray[] = $fuserdest->user_get_property($val, 'email');
  226. $sendtoccuserid[] = $val;
  227. }
  228. }
  229. }
  230. $sendtocc = implode(',', $tmparray);
  231. if (dol_strlen($sendto)) {
  232. // Define $urlwithroot
  233. $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
  234. $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  235. //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  236. require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  237. $langs->load("commercial");
  238. $reg = array();
  239. $fromtype = GETPOST('fromtype', 'alpha');
  240. if ($fromtype === 'robot') {
  241. $from = dol_string_nospecial($conf->global->MAIN_MAIL_EMAIL_FROM, ' ', array(",")).' <'.$conf->global->MAIN_MAIL_EMAIL_FROM.'>';
  242. } elseif ($fromtype === 'user') {
  243. $from = dol_string_nospecial($user->getFullName($langs), ' ', array(",")).' <'.$user->email.'>';
  244. } elseif ($fromtype === 'company') {
  245. $from = dol_string_nospecial($conf->global->MAIN_INFO_SOCIETE_NOM, ' ', array(",")).' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>';
  246. } elseif (preg_match('/user_aliases_(\d+)/', $fromtype, $reg)) {
  247. $tmp = explode(',', $user->email_aliases);
  248. $from = trim($tmp[($reg[1] - 1)]);
  249. } elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) {
  250. $tmp = explode(',', $conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
  251. $from = trim($tmp[($reg[1] - 1)]);
  252. } elseif (preg_match('/senderprofile_(\d+)_(\d+)/', $fromtype, $reg)) {
  253. $sql = 'SELECT rowid, label, email FROM '.MAIN_DB_PREFIX.'c_email_senderprofile';
  254. $sql .= ' WHERE rowid = '.(int) $reg[1];
  255. $resql = $db->query($sql);
  256. $obj = $db->fetch_object($resql);
  257. if ($obj) {
  258. $from = dol_string_nospecial($obj->label, ' ', array(",")).' <'.$obj->email.'>';
  259. }
  260. } else {
  261. $from = dol_string_nospecial($_POST['fromname'], ' ', array(",")).' <'.$_POST['frommail'].'>';
  262. }
  263. $replyto = dol_string_nospecial($_POST['replytoname'], ' ', array(",")).' <'.$_POST['replytomail'].'>';
  264. $message = GETPOST('message', 'restricthtml');
  265. $subject = GETPOST('subject', 'restricthtml');
  266. // Make a change into HTML code to allow to include images from medias directory with an external reabable URL.
  267. // <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
  268. // become
  269. // <img alt="" src="'.$urlwithroot.'viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
  270. $message = preg_replace('/(<img.*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^\/]*\/>)/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $message);
  271. $sendtobcc = GETPOST('sendtoccc');
  272. // Autocomplete the $sendtobcc
  273. // $autocopy can be MAIN_MAIL_AUTOCOPY_PROPOSAL_TO, MAIN_MAIL_AUTOCOPY_ORDER_TO, MAIN_MAIL_AUTOCOPY_INVOICE_TO, MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO...
  274. if (!empty($autocopy)) {
  275. $sendtobcc .= (empty($conf->global->$autocopy) ? '' : (($sendtobcc ? ", " : "").$conf->global->$autocopy));
  276. }
  277. $deliveryreceipt = $_POST['deliveryreceipt'];
  278. if ($action == 'send' || $action == 'relance') {
  279. $actionmsg2 = $langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto, 4, 0, 1);
  280. if ($message) {
  281. $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
  282. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
  283. if ($sendtocc) {
  284. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
  285. }
  286. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
  287. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
  288. $actionmsg = dol_concatdesc($actionmsg, $message);
  289. }
  290. }
  291. // Create form object
  292. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
  293. $formmail = new FormMail($db);
  294. $formmail->trackid = $trackid; // $trackid must be defined
  295. $attachedfiles = $formmail->get_attached_files();
  296. $filepath = $attachedfiles['paths'];
  297. $filename = $attachedfiles['names'];
  298. $mimetype = $attachedfiles['mimes'];
  299. // Make substitution in email content
  300. $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $object);
  301. $substitutionarray['__EMAIL__'] = $sendto;
  302. $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty)) ? '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.urlencode($object->thirdparty->tag).'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>' : '';
  303. $parameters = array('mode'=>'formemail');
  304. complete_substitutions_array($substitutionarray, $langs, $object, $parameters);
  305. $subject = make_substitutions($subject, $substitutionarray);
  306. $message = make_substitutions($message, $substitutionarray);
  307. if (is_object($object) && method_exists($object, 'makeSubstitution')) {
  308. $subject = $object->makeSubstitution($subject);
  309. $message = $object->makeSubstitution($message);
  310. }
  311. // Send mail (substitutionarray must be done just before this)
  312. if (empty($sendcontext)) {
  313. $sendcontext = 'standard';
  314. }
  315. $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', $trackid, '', $sendcontext);
  316. if ($mailfile->error) {
  317. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  318. $action = 'presend';
  319. } else {
  320. $result = $mailfile->sendfile();
  321. if ($result) {
  322. // Initialisation of datas of object to call trigger
  323. if (is_object($object)) {
  324. if (empty($actiontypecode)) {
  325. $actiontypecode = 'AC_OTH_AUTO'; // Event insert into agenda automatically
  326. }
  327. $object->socid = $sendtosocid; // To link to a company
  328. $object->sendtoid = $sendtoid; // To link to contact-addresses. This is an array.
  329. $object->actiontypecode = $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
  330. $object->actionmsg = $actionmsg; // Long text (@todo Replace this with $message, we already have details of email in dedicated properties)
  331. $object->actionmsg2 = $actionmsg2; // Short text ($langs->transnoentities('MailSentBy')...);
  332. $object->trackid = $trackid;
  333. $object->fk_element = $object->id;
  334. $object->elementtype = $object->element;
  335. if (is_array($attachedfiles) && count($attachedfiles) > 0) {
  336. $object->attachedfiles = $attachedfiles;
  337. }
  338. if (is_array($sendtouserid) && count($sendtouserid) > 0 && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) {
  339. $object->sendtouserid = $sendtouserid;
  340. }
  341. $object->email_msgid = $mailfile->msgid; // @todo Set msgid into $mailfile after sending
  342. $object->email_from = $from;
  343. $object->email_subject = $subject;
  344. $object->email_to = $sendto;
  345. $object->email_tocc = $sendtocc;
  346. $object->email_tobcc = $sendtobcc;
  347. $object->email_subject = $subject;
  348. $object->email_msgid = $mailfile->msgid;
  349. // Call of triggers (you should have set $triggersendname to execute trigger. $trigger_name is deprecated)
  350. if (!empty($triggersendname) || !empty($trigger_name)) {
  351. // Call trigger
  352. $result = $object->call_trigger(empty($triggersendname) ? $trigger_name : $triggersendname, $user);
  353. if ($result < 0) {
  354. $error++;
  355. }
  356. // End call triggers
  357. if ($error) {
  358. setEventMessages($object->error, $object->errors, 'errors');
  359. }
  360. }
  361. // End call of triggers
  362. }
  363. // Redirect here
  364. // This avoid sending mail twice if going out and then back to page
  365. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2));
  366. setEventMessages($mesg, null, 'mesgs');
  367. $moreparam = '';
  368. if (isset($paramname2) || isset($paramval2)) {
  369. $moreparam .= '&'.($paramname2 ? $paramname2 : 'mid').'='.$paramval2;
  370. }
  371. header('Location: '.$_SERVER["PHP_SELF"].'?'.($paramname ? $paramname : 'id').'='.(is_object($object) ? $object->id : '').$moreparam);
  372. exit;
  373. } else {
  374. $langs->load("other");
  375. $mesg = '<div class="error">';
  376. if ($mailfile->error) {
  377. $mesg .= $langs->transnoentities('ErrorFailedToSendMail', dol_escape_htmltag($from), dol_escape_htmltag($sendto));
  378. $mesg .= '<br>'.$mailfile->error;
  379. } else {
  380. $mesg .= $langs->transnoentities('ErrorFailedToSendMail', dol_escape_htmltag($from), dol_escape_htmltag($sendto));
  381. if (!empty($conf->global->MAIN_DISABLE_ALL_MAILS)) {
  382. $mesg .= '<br>Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
  383. } else {
  384. $mesg .= '<br>Unkown Error, please refers to your administrator';
  385. }
  386. }
  387. $mesg .= '</div>';
  388. setEventMessages($mesg, null, 'warnings');
  389. $action = 'presend';
  390. }
  391. }
  392. } else {
  393. $langs->load("errors");
  394. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("MailTo")), null, 'warnings');
  395. dol_syslog('Try to send email with no recipient defined', LOG_WARNING);
  396. $action = 'presend';
  397. }
  398. } else {
  399. $langs->load("errors");
  400. setEventMessages($langs->trans('ErrorFailedToReadObject', $object->element), null, 'errors');
  401. dol_syslog('Failed to read data of object id='.$object->id.' element='.$object->element);
  402. $action = 'presend';
  403. }
  404. }