dolibarr 25.0.0-alpha
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-2025 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 * or see https://www.gnu.org/
22 */
23
30// $massaction must be defined
31// $objectclass and $objectlabel must be defined
32// $parameters, $object, $action must be defined for the hook.
33
34// $permissiontoread, $permissiontoadd, $permissiontodelete, $permissiontoclose may be defined
35// $uploaddir may be defined (example to $conf->project->dir_output."/";)
36// $toselect may be defined
37// $diroutputmassaction may be defined
54// Protection
55if (empty($objectclass) || empty($uploaddir)) {
56 dol_print_error(null, 'include of actions_massactions.inc.php is done but var $objectclass or $uploaddir was not defined');
57 exit;
58}
59
60'
61@phan-var-force string $massaction
62@phan-var-force string $objectclass
63@phan-var-force ?string $diroutputmassaction
64@phan-var-force ?string $uploaddir
65@phan-var-force string[] $toselect
66@phan-var-force array<string,mixed> $parameters
67';
68
69$error = 0;
70
71// Mass actions. Controls on number of lines checked.
72$maxformassaction = getDolGlobalInt('MAIN_LIMIT_FOR_MASS_ACTIONS', 1000);
73if (!empty($massaction) && is_array($toselect) && count($toselect) < 1) {
74 $error++;
75 setEventMessages($langs->trans("NoRecordSelected"), null, "warnings");
76}
77if (!$error && is_array($toselect) && count($toselect) > $maxformassaction) {
78 setEventMessages($langs->trans('TooManyRecordForMassAction', (string) $maxformassaction), null, 'errors');
79 $error++;
80}
81
82if (!$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
83 $massaction = 'presend_attendees';
84}
85
86if (!$error && $massaction == 'confirm_presend_attendees') {
87 $resaction = '';
88 $nbsent = 0;
89 $nbignored = 0;
90 $langs->load("mails");
91 include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
92
93 $listofobjectid = array();
94
95 $listofobjectref = array();
96 $oneemailperrecipient = (GETPOSTINT('oneemailperrecipient') ? 1 : 0);
97
98 $listofselectedid = array();
99 $listofselectedref = array();
100 require_once DOL_DOCUMENT_ROOT . '/eventorganization/class/conferenceorboothattendee.class.php';
101 $objecttmp = new $objectclass($db);
102 '@phan-var-force CommonObject $objecttmp';
103
104 foreach ($toselect as $toselectid) {
105 $result = $objecttmp->fetch($toselectid);
106 if ($result > 0 && $objecttmp instanceof ConferenceOrBoothAttendee && !empty($objecttmp->email)) {
107 $attendee = clone $objecttmp;
108 $attendee->fetch_thirdparty();
109 $listofselectedid[$attendee->email] = $attendee;
110 $listofselectedref[$attendee->email] = $attendee;
111 }
112 }
113 '@phan-var-force CommonObject $objecttmp';
114 '@phan-var-force array<string,ConferenceOrBoothAttendee> $listofselectedid';
115 '@phan-var-force array<string,ConferenceOrBoothAttendee> $listofselectedref';
116
117 // Check mandatory parameters
118 if (GETPOST('fromtype', 'alpha') === 'user' && empty($user->email)) {
119 $error++;
120 setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings');
121 $massaction = 'presend_attendees';
122 }
123
124 $receiver = GETPOST('receiver', 'alphawithlgt');
125 if (!is_array($receiver)) {
126 if (empty($receiver) || $receiver == '-1') {
127 $receiver = array();
128 } else {
129 $receiver = array($receiver);
130 }
131 }
132 if (!trim(GETPOST('sendto', 'alphawithlgt')) && count($receiver) == 0 && count($listofselectedid) == 0) { // if only one recipient, receiver is mandatory
133 $error++;
134 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings');
135 $massaction = 'presend_attendees';
136 }
137
138 if (!GETPOST('subject', 'restricthtml')) {
139 $error++;
140 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailTopic")), null, 'warnings');
141 $massaction = 'presend_attendees';
142 }
143
144 if (!$error && !empty($listofselectedid)) {
145 $objecttmp->fetch_thirdparty();
146 foreach ($listofselectedid as $email => $attendees) {
147 $sendto = '';
148 $sendtocc = '';
149 $sendtobcc = '';
150 $sendtoid = array();
151
152 // Define $sendto
153 $sendto = $attendees->thirdparty->name . '<' . trim($attendees->email) . '>';
154
155 // Define $sendtocc
156 $receivercc = GETPOST('receivercc', 'alphawithlgt');
157 if (!is_array($receivercc)) {
158 if ($receivercc == '-1') {
159 $receivercc = array();
160 } else {
161 $receivercc = array($receivercc);
162 }
163 }
164 $tmparray = array();
165 if (trim(GETPOST('sendtocc', 'alphawithlgt'))) {
166 $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt'));
167 }
168 $sendtocc = implode(',', $tmparray);
169
170
171 $langs->load("commercial");
172
173 $reg = array();
174 $fromtype = GETPOST('fromtype');
175 if ($fromtype === 'user') {
176 $email_from = $user->getFullName($langs) . ' <' . $user->email . '>';
177 } elseif ($fromtype === 'company') {
178 $email_from = getDolGlobalString('MAIN_INFO_SOCIETE_NOM') . ' <' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL') . '>';
179 } elseif (preg_match('/global_aliases_(\d+)/', $fromtype, $reg)) {
180 $tmp = explode(',', getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'));
181 $email_from = trim($tmp[((int) $reg[1] - 1)]);
182 } elseif (preg_match('/senderprofile_(\d+)_(\d+)/', $fromtype, $reg)) {
183 $sql = "SELECT rowid, label, email FROM " . MAIN_DB_PREFIX . "c_email_senderprofile WHERE rowid = " . (int) $reg[1];
184 $resql = $db->query($sql);
185 $obj = $db->fetch_object($resql);
186 if ($obj) {
187 $email_from = dol_string_nospecial($obj->label, ' ', array(",")) . ' <' . $obj->email . '>';
188 } else {
189 $email_from = '';
190 }
191 } else {
192 $email_from = dol_string_nospecial(GETPOST('fromname'), ' ', array(",")) . ' <' . GETPOST('frommail') . '>';
193 }
194
195 $replyto = $email_from;
196 $subject = GETPOST('subject', 'restricthtml');
197 $message = GETPOST('message', 'restricthtml');
198
199 $sendtobcc = GETPOST('sendtoccc', 'alphawithlgt');
200
201 // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per object
202 // Make substitution in email content
203 $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $attendees);
204 $url_link = null;
205 $html_link = null;
206
207 if (getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY')) {
208 $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root));
209 $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT;
210 $url_link = $urlwithroot . '/public/agenda/agendaexport.php?format=ical' . ($conf->entity > 1 ? "&entity=" . $conf->entity : "");
211 $url_link .= '&exportkey=' . urlencode(getDolGlobalString('MAIN_AGENDA_XCAL_EXPORTKEY', '...'));
212 $url_link .= "&project=" . $listofselectedref[$email]->fk_project . '&module=' . urlencode('@eventorganization') . '&status=' . ConferenceOrBooth::STATUS_CONFIRMED;
213 $html_link = '<a href="' . $url_link . '">' . $langs->trans('DownloadICSLink') . '</a>';
214 }
215 $substitutionarray['__EVENTORGANIZATION_ICS_LINK__'] = $html_link;
216 $substitutionarray['__EVENTORGANIZATION_URL_LINK__'] = $url_link;
217
218 $parameters = array('mode' => 'formemail');
219
220 if (!empty($listofobjectref)) {
221 $parameters['listofobjectref'] = $listofobjectref;
222 }
223
224 complete_substitutions_array($substitutionarray, $langs, $attendees, $parameters);
225
226 $subjectreplaced = make_substitutions($subject, $substitutionarray);
227 $messagereplaced = make_substitutions($message, $substitutionarray);
228
229
230 if (empty($sendcontext)) {
231 $sendcontext = 'standard';
232 }
233
234 // Send mail (substitutionarray must be done just before this)
235 require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
236 $mailfile = new CMailFile($subjectreplaced, $sendto, $email_from, $messagereplaced, array(), array(), array(), $sendtocc, $sendtobcc, 0, -1, '', '', "attendees_".$attendees->id, '', $sendcontext);
237 if ($mailfile->error) {
238 $resaction .= '<div class="error">' . $mailfile->error . '</div>';
239 } else {
240 $result = $mailfile->sendfile();
241 if ($result) {
242 $resaction .= $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($email_from, 2), $mailfile->getValidAddress($sendto, 2)) . '<br>'; // Must not contain "
243 $error = 0;
244
245 dol_syslog("Try to insert email event into agenda for objid=" . $attendees->id . " => objectobj=" . get_class($attendees));
246
247 $actionmsg = $langs->transnoentities('MailSentByTo', $email_from, $sendto);
248 if ($message) {
249 if ($sendtocc) {
250 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
251 }
252 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subjectreplaced);
253 $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
254 $actionmsg = dol_concatdesc($actionmsg, $messagereplaced);
255 }
256 $actionmsg2 = '';
257
258 $objectobj2 = $listofselectedref[$email];
259 // Initialisation donnees
260 $objectobj2->actionmsg = $actionmsg; // Long text
261 $objectobj2->actionmsg2 = $actionmsg2; // Short text
262 $objectobj2->fk_element = $objectobj2->id;
263 $objectobj2->elementtype = $objectobj2->element;
264
265 $triggername = 'CONFERENCEORBOOTHATTENDEE_SENTBYMAIL';
266 // Call trigger
267 $result = $objectobj2->call_trigger($triggername, $user);
268 if ($result < 0) {
269 $error++;
270 }
271 // End call triggers
272
273 if ($error) {
274 setEventMessages($db->lasterror(), $objectobj2->errors, 'errors');
275 dol_syslog("Error in trigger " . $triggername . ' ' . $db->lasterror(), LOG_ERR);
276 }
277
278 $nbsent++; // Nb of object sent
279 } else {
280 $langs->load("other");
281 if ($mailfile->error) { // @phpstan-ignore-line
282 $resaction .= $langs->trans('ErrorFailedToSendMail', $email_from, $sendto);
283 $resaction .= '<br><div class="error">' . $mailfile->error . '</div>';
284 } elseif (getDolGlobalString('MAIN_DISABLE_ALL_MAILS')) {
285 $resaction .= '<div class="warning">No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS</div>';
286 } else {
287 $resaction .= $langs->trans('ErrorFailedToSendMail', $email_from, $sendto) . '<br><div class="error">(unhandled error)</div>';
288 }
289 $nbignored++;
290 }
291 }
292 } // foreach ($listofselectedid as $email => $attendees)
293 }
294 $resaction .= ($resaction ? '<br>' : $resaction);
295 $resaction .= '<strong>' . $langs->trans("ResultOfMailSending") . ':</strong><br>' . "\n";
296 $resaction .= $langs->trans("NbSelected") . ': ' . count($toselect) . "\n<br>";
297 $resaction .= $langs->trans("NbIgnored") . ': ' . ($nbignored ? $nbignored : 0) . "\n<br>";
298 $resaction .= $langs->trans("NbSent") . ': ' . ($nbsent ? $nbsent : 0) . "\n<br>";
299
300 if ($nbsent) {
301 $action = ''; // Do not show form post if there was at least one successful sent
302 //setEventMessages($langs->trans("EMailSentToNRecipients", $nbsent.'/'.count($toselect)), null, 'mesgs');
303 setEventMessages($langs->trans("EMailSentForNElements", $nbsent . '/' . count($toselect)), null, 'mesgs');
304 setEventMessages($resaction, null, 'mesgs');
305 } else {
306 //setEventMessages($langs->trans("EMailSentToNRecipients", 0), null, 'warnings'); // May be object has no generated PDF file
307 setEventMessages($resaction, null, 'warnings');
308 }
309
310 $action = 'list';
311 $massaction = '';
312}
313
314
315
316$parameters['toselect'] = $toselect;
317$parameters['uploaddir'] = $uploaddir;
318$parameters['massaction'] = $massaction;
319$parameters['diroutputmassaction'] = isset($diroutputmassaction) ? $diroutputmassaction : null;
320
321$reshook = $hookmanager->executeHooks('doMassActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
322if ($reshook < 0) {
323 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
324}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
global $dolibarr_main_url_root
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class for ConferenceOrBoothAttendee.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_string_nospecial($str, $newstr='_', $badcharstoreplace='', $badcharstoremove='', $keepspaces=0)
Clean a string from all punctuation characters to use it as a ref or login.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
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...
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.