dolibarr 18.0.6
actions_massactions_mail.inc.php
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
29// $massaction must be defined
30// $objectclass and $objectlabel must be defined
31// $parameters, $object, $action must be defined for the hook.
32
33// $permissiontoread, $permissiontoadd, $permissiontodelete, $permissiontoclose may be defined
34// $uploaddir may be defined (example to $conf->project->dir_output."/";)
35// $toselect may be defined
36// $diroutputmassaction may be defined
37
38
39// Protection
40if (empty($objectclass) || empty($uploaddir)) {
41 dol_print_error(null, 'include of actions_massactions.inc.php is done but var $objectclass or $uploaddir was not defined');
42 exit;
43}
44
45// Mass actions. Controls on number of lines checked.
46$maxformassaction = (empty($conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS) ? 1000 : $conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS);
47if (!empty($massaction) && is_array($toselect) && count($toselect) < 1) {
48 $error++;
49 setEventMessages($langs->trans("NoRecordSelected"), null, "warnings");
50}
51if (!$error && is_array($toselect) && count($toselect) > $maxformassaction) {
52 setEventMessages($langs->trans('TooManyRecordForMassAction', $maxformassaction), null, 'errors');
53 $error++;
54}
55
56if (!$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
57 $massaction = 'presend_attendees';
58}
59if (!$error && $massaction == 'confirm_presend_attendees') {
60 $resaction = '';
61 $nbsent = 0;
62 $nbignored = 0;
63 $langs->load("mails");
64 include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
65
66 $listofobjectid = array();
67
68 $listofobjectref = array();
69 $oneemailperrecipient = (GETPOST('oneemailperrecipient', 'int') ? 1 : 0);
70
71 if (!$error) {
72 require_once DOL_DOCUMENT_ROOT . '/eventorganization/class/conferenceorboothattendee.class.php';
73 $attendee = new ConferenceOrBoothAttendee($db);
74 $listofselectedid = array();
75 $listofselectedref = array();
76 $objecttmp = new $objectclass($db);
77
78 foreach ($toselect as $toselectid) {
79 $result = $objecttmp->fetch($toselectid);
80 if ($result > 0) {
81 $attendees = $attendee->fetchAll();
82 if (is_array($attendees) && count($attendees) > 0) {
83 foreach ($attendees as $attmail) {
84 if (!empty($attmail->email)) {
85 $attmail->fetch_thirdparty();
86 $listofselectedid[$attmail->email] = $attmail;
87 $listofselectedref[$attmail->email] = $objecttmp;
88 }
89 }
90 }
91 }
92 }
93 }
94
95 // Check mandatory parameters
96 if (GETPOST('fromtype', 'alpha') === 'user' && empty($user->email)) {
97 $error++;
98 setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings');
99 $massaction = 'presend_attendees';
100 }
101
102 $receiver = GETPOST('receiver', 'alphawithlgt');
103 if (!is_array($receiver)) {
104 if (empty($receiver) || $receiver == '-1') {
105 $receiver = array();
106 } else {
107 $receiver = array($receiver);
108 }
109 }
110 if (!trim($_POST['sendto']) && count($receiver) == 0 && count($listofselectedid) == 0) { // if only one recipient, receiver is mandatory
111 $error++;
112 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings');
113 $massaction = 'presend_attendees';
114 }
115
116 if (!GETPOST('subject', 'restricthtml')) {
117 $error++;
118 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailTopic")), null, 'warnings');
119 $massaction = 'presend_attendees';
120 }
121
122 if (!$error) {
123 $objecttmp->fetch_thirdparty();
124 foreach ($listofselectedid as $email => $attendees) {
125 $sendto = '';
126 $sendtocc = '';
127 $sendtobcc = '';
128 $sendtoid = array();
129
130 // Define $sendto
131 $sendto = $attendees->thirdparty->name . '<' . trim($attendees->email) . '>';
132
133 // Define $sendtocc
134 $receivercc = GETPOST('receivercc', 'alphawithlgt');
135 if (!is_array($receivercc)) {
136 if ($receivercc == '-1') {
137 $receivercc = array();
138 } else {
139 $receivercc = array($receivercc);
140 }
141 }
142 $tmparray = array();
143 if (trim($_POST['sendtocc'])) {
144 $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt'));
145 }
146 $sendtocc = implode(',', $tmparray);
147
148
149 $langs->load("commercial");
150
151 $reg = array();
152 $fromtype = GETPOST('fromtype');
153 if ($fromtype === 'user') {
154 $from = $user->getFullName($langs) . ' <' . $user->email . '>';
155 } elseif ($fromtype === 'company') {
156 $from = $conf->global->MAIN_INFO_SOCIETE_NOM . ' <' . $conf->global->MAIN_INFO_SOCIETE_MAIL . '>';
157 } elseif (preg_match('/user_aliases_(\d+)/', $fromtype, $reg)) {
158 $tmp = explode(',', $user->email_aliases);
159 $from = trim($tmp[($reg[1] - 1)]);
160 } elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) {
161 $tmp = explode(',', $conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
162 $from = trim($tmp[($reg[1] - 1)]);
163 } elseif (preg_match('/senderprofile_(\d+)_(\d+)/', $fromtype, $reg)) {
164 $sql = "SELECT rowid, label, email FROM " . MAIN_DB_PREFIX . "c_email_senderprofile WHERE rowid = " . (int) $reg[1];
165 $resql = $db->query($sql);
166 $obj = $db->fetch_object($resql);
167 if ($obj) {
168 $from = dol_string_nospecial($obj->label, ' ', array(",")) . ' <' . $obj->email . '>';
169 }
170 } else {
171 $from = dol_string_nospecial(GETPOST('fromname'), ' ', array(",")) . ' <' . GETPOST('frommail') . '>';
172 }
173
174 $replyto = $from;
175 $subject = GETPOST('subject', 'restricthtml');
176 $message = GETPOST('message', 'restricthtml');
177
178 $sendtobcc = GETPOST('sendtoccc', 'alphawithlgt');
179
180 // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per object
181 // Make substitution in email content
182 $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $attendees);
183
184 if (!empty($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY)) {
185 $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root));
186 $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT;
187 $url_link = $urlwithroot . '/public/agenda/agendaexport.php?format=ical' . ($conf->entity > 1 ? "&entity=" . $conf->entity : "");
188 $url_link .= '&exportkey=' . ($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ? urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...');
189 $url_link .= "&project=" . $listofselectedref[$email]->fk_project . '&module=' . urlencode('@eventorganization') . '&status=' . ConferenceOrBooth::STATUS_CONFIRMED;
190 $html_link = '<a href="' . $url_link . '">' . $langs->trans('DownloadICSLink') . '</a>';
191 }
192 $substitutionarray['__EVENTORGANIZATION_ICS_LINK__'] = $html_link;
193 $substitutionarray['__EVENTORGANIZATION_URL_LINK__'] = $url_link;
194
195 $parameters = array('mode' => 'formemail');
196
197 if (!empty($listofobjectref)) {
198 $parameters['listofobjectref'] = $listofobjectref;
199 }
200
201 complete_substitutions_array($substitutionarray, $langs, $attendees, $parameters);
202
203 $subjectreplaced = make_substitutions($subject, $substitutionarray);
204 $messagereplaced = make_substitutions($message, $substitutionarray);
205
206
207 if (empty($sendcontext)) {
208 $sendcontext = 'standard';
209 }
210
211 // Send mail (substitutionarray must be done just before this)
212 require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
213 $mailfile = new CMailFile($subjectreplaced, $sendto, $from, $messagereplaced, array(), array(), array(), $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', "attendees_".$attendees->id, '', $sendcontext);
214 if ($mailfile->error) {
215 $resaction .= '<div class="error">' . $mailfile->error . '</div>';
216 } else {
217 $result = $mailfile->sendfile();
218 if ($result) {
219 $resaction .= $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($sendto, 2)) . '<br>'; // Must not contain "
220 $error = 0;
221
222 dol_syslog("Try to insert email event into agenda for objid=" . $attendees->id . " => objectobj=" . get_class($attendees));
223
224 $actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto;
225 if ($message) {
226 if ($sendtocc) {
227 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
228 }
229 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subjectreplaced);
230 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
231 $actionmsg = dol_concatdesc($actionmsg, $messagereplaced);
232 }
233 $actionmsg2 = '';
234
235 $objectobj2 = $listofselectedref[$email];
236 // Initialisation donnees
237 $objectobj2->actionmsg = $actionmsg; // Long text
238 $objectobj2->actionmsg2 = $actionmsg2; // Short text
239 $objectobj2->fk_element = $objectobj2->id;
240 $objectobj2->elementtype = $objectobj2->element;
241
242 $triggername = 'CONFERENCEORBOOTHATTENDEE_SENTBYMAIL';
243 if (!empty($triggername)) {
244 // Call trigger
245 $result = $objectobj2->call_trigger($triggername, $user);
246 if ($result < 0) {
247 $error++;
248 }
249 // End call triggers
250
251 if ($error) {
252 setEventMessages($db->lasterror(), $objectobj2->errors, 'errors');
253 dol_syslog("Error in trigger " . $triggername . ' ' . $db->lasterror(), LOG_ERR);
254 }
255 }
256
257 $nbsent++; // Nb of object sent
258 } else {
259 $langs->load("other");
260 if ($mailfile->error) {
261 $resaction .= $langs->trans('ErrorFailedToSendMail', $from, $sendto);
262 $resaction .= '<br><div class="error">' . $mailfile->error . '</div>';
263 } elseif (!empty($conf->global->MAIN_DISABLE_ALL_MAILS)) {
264 $resaction .= '<div class="warning">No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS</div>';
265 } else {
266 $resaction .= $langs->trans('ErrorFailedToSendMail', $from, $sendto) . '<br><div class="error">(unhandled error)</div>';
267 }
268 }
269 }
270 }
271 }
272 $resaction .= ($resaction ? '<br>' : $resaction);
273 $resaction .= '<strong>' . $langs->trans("ResultOfMailSending") . ':</strong><br>' . "\n";
274 $resaction .= $langs->trans("NbSelected") . ': ' . count($toselect) . "\n<br>";
275 $resaction .= $langs->trans("NbIgnored") . ': ' . ($nbignored ? $nbignored : 0) . "\n<br>";
276 $resaction .= $langs->trans("NbSent") . ': ' . ($nbsent ? $nbsent : 0) . "\n<br>";
277
278 if ($nbsent) {
279 $action = ''; // Do not show form post if there was at least one successfull sent
280 //setEventMessages($langs->trans("EMailSentToNRecipients", $nbsent.'/'.count($toselect)), null, 'mesgs');
281 setEventMessages($langs->trans("EMailSentForNElements", $nbsent . '/' . count($toselect)), null, 'mesgs');
282 setEventMessages($resaction, null, 'mesgs');
283 } else {
284 //setEventMessages($langs->trans("EMailSentToNRecipients", 0), null, 'warnings'); // May be object has no generated PDF file
285 setEventMessages($resaction, null, 'warnings');
286 }
287
288 $action = 'list';
289 $massaction = '';
290}
291
292
293
294$parameters['toselect'] = $toselect;
295$parameters['uploaddir'] = $uploaddir;
296$parameters['massaction'] = $massaction;
297$parameters['diroutputmassaction'] = isset($diroutputmassaction) ? $diroutputmassaction : null;
298
299$reshook = $hookmanager->executeHooks('doMassActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
300if ($reshook < 0) {
301 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
302}
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class for ConferenceOrBoothAttendee.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_string_nospecial($str, $newstr='_', $badcharstoreplace='', $badcharstoremove='', $keepspaces=0)
Clean a string from all punctuation characters to use it as a ref or login.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.