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