PageRenderTime 31ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/eventorganization/core/actions_massactions_mail.inc.php

http://github.com/Dolibarr/dolibarr
PHP | 315 lines | 224 code | 46 blank | 45 comment | 67 complexity | b56a42784be044d4cdf6cc0b5adeb7b1 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) 2015-2017 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2018-2021 Nicolas ZABOURI <info@inovea-conseil.com>
  4. * Copyright (C) 2018 Juanjo Menent <jmenent@2byte.es>
  5. * Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
  6. * Copyright (C) 2019-2021 Frédéric France <frederic.france@netlogic.fr>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. * or see https://www.gnu.org/
  21. */
  22. /**
  23. * \file htdocs/core/actions_massactions.inc.php
  24. * \brief Code for actions done with massaction button (send by email, merge pdf, delete, ...)
  25. */
  26. // $massaction must be defined
  27. // $objectclass and $objectlabel must be defined
  28. // $parameters, $object, $action must be defined for the hook.
  29. // $permissiontoread, $permissiontoadd, $permissiontodelete, $permissiontoclose may be defined
  30. // $uploaddir may be defined (example to $conf->projet->dir_output."/";)
  31. // $toselect may be defined
  32. // $diroutputmassaction may be defined
  33. // Protection
  34. if (empty($objectclass) || empty($uploaddir)) {
  35. dol_print_error(null, 'include of actions_massactions.inc.php is done but var $objectclass or $uploaddir was not defined');
  36. exit;
  37. }
  38. // For backward compatibility
  39. if (!empty($permtoread) && empty($permissiontoread)) {
  40. $permissiontoread = $permtoread;
  41. }
  42. if (!empty($permtocreate) && empty($permissiontoadd)) {
  43. $permissiontoadd = $permtocreate;
  44. }
  45. if (!empty($permtodelete) && empty($permissiontodelete)) {
  46. $permissiontodelete = $permtodelete;
  47. }
  48. // Mass actions. Controls on number of lines checked.
  49. $maxformassaction = (empty($conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS) ? 1000 : $conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS);
  50. if (!empty($massaction) && is_array($toselect) && count($toselect) < 1) {
  51. $error++;
  52. setEventMessages($langs->trans("NoRecordSelected"), null, "warnings");
  53. }
  54. if (!$error && is_array($toselect) && count($toselect) > $maxformassaction) {
  55. setEventMessages($langs->trans('TooManyRecordForMassAction', $maxformassaction), null, 'errors');
  56. $error++;
  57. }
  58. if (!$error && $massaction == 'confirm_presend_attendees' && !GETPOST('sendmail')) { // If we do not choose button send (for example when we change template or limit), we must not send email, but keep on send email form
  59. $massaction = 'presend_attendees';
  60. }
  61. if (!$error && $massaction == 'confirm_presend_attendees') {
  62. $resaction = '';
  63. $nbsent = 0;
  64. $nbignored = 0;
  65. $langs->load("mails");
  66. include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
  67. $listofobjectid = array();
  68. $listofobjectref = array();
  69. $oneemailperrecipient = (GETPOST('oneemailperrecipient') == 'on' ? 1 : 0);
  70. if (!$error) {
  71. require_once DOL_DOCUMENT_ROOT . '/eventorganization/class/conferenceorboothattendee.class.php';
  72. $attendee = new ConferenceOrBoothAttendee($db);
  73. $listofselectedid = array();
  74. $listofselectedref = array();
  75. $objecttmp = new $objectclass($db);
  76. foreach ($toselect as $toselectid) {
  77. $result = $objecttmp->fetch($toselectid);
  78. if ($result > 0) {
  79. $attendees = $attendee->fetchAll();
  80. if (is_array($attendees) && count($attendees) > 0) {
  81. foreach ($attendees as $attmail) {
  82. if (!empty($attmail->email)) {
  83. $attmail->fetch_thirdparty();
  84. $listofselectedid[$attmail->email] = $attmail;
  85. $listofselectedref[$attmail->email] = $objecttmp;
  86. }
  87. }
  88. }
  89. }
  90. }
  91. }
  92. // Check mandatory parameters
  93. if (GETPOST('fromtype', 'alpha') === 'user' && empty($user->email)) {
  94. $error++;
  95. setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings');
  96. $massaction = 'presend_attendees';
  97. }
  98. $receiver = $_POST['receiver'];
  99. if (!is_array($receiver)) {
  100. if (empty($receiver) || $receiver == '-1') {
  101. $receiver = array();
  102. } else {
  103. $receiver = array($receiver);
  104. }
  105. }
  106. if (!trim($_POST['sendto']) && count($receiver) == 0 && count($listofselectedid) == 0) { // if only one recipient, receiver is mandatory
  107. $error++;
  108. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings');
  109. $massaction = 'presend_attendees';
  110. }
  111. if (!GETPOST('subject', 'restricthtml')) {
  112. $error++;
  113. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailTopic")), null, 'warnings');
  114. $massaction = 'presend_attendees';
  115. }
  116. if (!$error) {
  117. $objecttmp->fetch_thirdparty();
  118. foreach ($listofselectedid as $email => $attendees) {
  119. $sendto = '';
  120. $sendtocc = '';
  121. $sendtobcc = '';
  122. $sendtoid = array();
  123. // Define $sendto
  124. $sendto = $attendees->thirdparty->name . '<' . trim($attendees->email) . '>';
  125. // Define $sendtocc
  126. $receivercc = $_POST['receivercc'];
  127. if (!is_array($receivercc)) {
  128. if ($receivercc == '-1') {
  129. $receivercc = array();
  130. } else {
  131. $receivercc = array($receivercc);
  132. }
  133. }
  134. $tmparray = array();
  135. if (trim($_POST['sendtocc'])) {
  136. $tmparray[] = trim($_POST['sendtocc']);
  137. }
  138. $sendtocc = implode(',', $tmparray);
  139. $langs->load("commercial");
  140. $reg = array();
  141. $fromtype = GETPOST('fromtype');
  142. if ($fromtype === 'user') {
  143. $from = $user->getFullName($langs) . ' <' . $user->email . '>';
  144. } elseif ($fromtype === 'company') {
  145. $from = $conf->global->MAIN_INFO_SOCIETE_NOM . ' <' . $conf->global->MAIN_INFO_SOCIETE_MAIL . '>';
  146. } elseif (preg_match('/user_aliases_(\d+)/', $fromtype, $reg)) {
  147. $tmp = explode(',', $user->email_aliases);
  148. $from = trim($tmp[($reg[1] - 1)]);
  149. } elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) {
  150. $tmp = explode(',', $conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
  151. $from = trim($tmp[($reg[1] - 1)]);
  152. } elseif (preg_match('/senderprofile_(\d+)_(\d+)/', $fromtype, $reg)) {
  153. $sql = "SELECT rowid, label, email FROM " . MAIN_DB_PREFIX . "c_email_senderprofile WHERE rowid = " . (int) $reg[1];
  154. $resql = $db->query($sql);
  155. $obj = $db->fetch_object($resql);
  156. if ($obj) {
  157. $from = $obj->label . ' <' . $obj->email . '>';
  158. }
  159. } else {
  160. $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>';
  161. }
  162. $replyto = $from;
  163. $subject = GETPOST('subject', 'restricthtml');
  164. $message = GETPOST('message', 'restricthtml');
  165. $sendtobcc = GETPOST('sendtoccc');
  166. // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per object
  167. // Make substitution in email content
  168. $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $attendees);
  169. if (!empty($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY)) {
  170. $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root));
  171. $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT;
  172. $url_link = $urlwithroot . '/public/agenda/agendaexport.php?format=ical' . ($conf->entity > 1 ? "&entity=" . $conf->entity : "");
  173. $url_link .= '&exportkey=' . ($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ? urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...');
  174. $url_link .= "&project=" . $listofselectedref[$email]->fk_project . '&module=' . urlencode('@eventorganization') . '&status=' . ConferenceOrBooth::STATUS_CONFIRMED;
  175. $html_link = '<a href="' . $url_link . '">' . $langs->trans('DownloadICSLink') . '</a>';
  176. }
  177. $substitutionarray['__EVENTORGANIZATION_ICS_LINK__'] = $html_link;
  178. $substitutionarray['__EVENTORGANIZATION_URL_LINK__'] = $url_link;
  179. $substitutionarray['__CHECK_READ__'] = '<img src="' . DOL_MAIN_URL_ROOT . '/public/emailing/mailing-read.php?tag=' . urlencode($attendees->thirdparty->tag) . '&securitykey=' . urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY) . '" width="1" height="1" style="width:1px;height:1px" border="0"/>';
  180. $parameters = array('mode' => 'formemail');
  181. if (!empty($listofobjectref)) {
  182. $parameters['listofobjectref'] = $listofobjectref;
  183. }
  184. complete_substitutions_array($substitutionarray, $langs, $attendees, $parameters);
  185. $subjectreplaced = make_substitutions($subject, $substitutionarray);
  186. $messagereplaced = make_substitutions($message, $substitutionarray);
  187. if (empty($sendcontext)) {
  188. $sendcontext = 'standard';
  189. }
  190. // Send mail (substitutionarray must be done just before this)
  191. require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
  192. $mailfile = new CMailFile($subjectreplaced, $sendto, $from, $messagereplaced, array(), array(), array(), $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', "attendees_".$attendees->id, '', $sendcontext);
  193. if ($mailfile->error) {
  194. $resaction .= '<div class="error">' . $mailfile->error . '</div>';
  195. } else {
  196. $result = $mailfile->sendfile();
  197. if ($result) {
  198. $resaction .= $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)) . '<br>'; // Must not contain "
  199. $error = 0;
  200. dol_syslog("Try to insert email event into agenda for objid=" . $attendees->id . " => objectobj=" . get_class($attendees));
  201. $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto;
  202. if ($message) {
  203. if ($sendtocc) {
  204. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
  205. }
  206. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subjectreplaced);
  207. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
  208. $actionmsg = dol_concatdesc($actionmsg, $messagereplaced);
  209. }
  210. $actionmsg2 = '';
  211. $objectobj2 = $listofselectedref[$email];
  212. // Initialisation donnees
  213. $objectobj2->actionmsg = $actionmsg; // Long text
  214. $objectobj2->actionmsg2 = $actionmsg2; // Short text
  215. $objectobj2->fk_element = $objectobj2->id;
  216. $objectobj2->elementtype = $objectobj2->element;
  217. $triggername = 'CONFERENCEORBOOTHATTENDEE_SENTBYMAIL';
  218. if (!empty($triggername)) {
  219. // Call trigger
  220. $result = $objectobj2->call_trigger($triggername, $user);
  221. if ($result < 0) {
  222. $error++;
  223. }
  224. // End call triggers
  225. if ($error) {
  226. setEventMessages($db->lasterror(), $objectobj2->errors, 'errors');
  227. dol_syslog("Error in trigger " . $triggername . ' ' . $db->lasterror(), LOG_ERR);
  228. }
  229. }
  230. $nbsent++; // Nb of object sent
  231. } else {
  232. $langs->load("other");
  233. if ($mailfile->error) {
  234. $resaction .= $langs->trans('ErrorFailedToSendMail', $from, $sendto);
  235. $resaction .= '<br><div class="error">' . $mailfile->error . '</div>';
  236. } elseif (!empty($conf->global->MAIN_DISABLE_ALL_MAILS)) {
  237. $resaction .= '<div class="warning">No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS</div>';
  238. } else {
  239. $resaction .= $langs->trans('ErrorFailedToSendMail', $from, $sendto) . '<br><div class="error">(unhandled error)</div>';
  240. }
  241. }
  242. }
  243. }
  244. }
  245. $resaction .= ($resaction ? '<br>' : $resaction);
  246. $resaction .= '<strong>' . $langs->trans("ResultOfMailSending") . ':</strong><br>' . "\n";
  247. $resaction .= $langs->trans("NbSelected") . ': ' . count($toselect) . "\n<br>";
  248. $resaction .= $langs->trans("NbIgnored") . ': ' . ($nbignored ? $nbignored : 0) . "\n<br>";
  249. $resaction .= $langs->trans("NbSent") . ': ' . ($nbsent ? $nbsent : 0) . "\n<br>";
  250. if ($nbsent) {
  251. $action = ''; // Do not show form post if there was at least one successfull sent
  252. //setEventMessages($langs->trans("EMailSentToNRecipients", $nbsent.'/'.count($toselect)), null, 'mesgs');
  253. setEventMessages($langs->trans("EMailSentForNElements", $nbsent . '/' . count($toselect)), null, 'mesgs');
  254. setEventMessages($resaction, null, 'mesgs');
  255. } else {
  256. //setEventMessages($langs->trans("EMailSentToNRecipients", 0), null, 'warnings'); // May be object has no generated PDF file
  257. setEventMessages($resaction, null, 'warnings');
  258. }
  259. $action = 'list';
  260. $massaction = '';
  261. }
  262. $parameters['toselect'] = $toselect;
  263. $parameters['uploaddir'] = $uploaddir;
  264. $parameters['massaction'] = $massaction;
  265. $parameters['diroutputmassaction'] = isset($diroutputmassaction) ? $diroutputmassaction : null;
  266. $reshook = $hookmanager->executeHooks('doMassActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  267. if ($reshook < 0) {
  268. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  269. }