dolibarr 20.0.2
cibles.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2024 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
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 */
21
28// Load Dolibarr environment
29require '../../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
31require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmailing.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/emailing.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
37
38// Load translation files required by the page
39$langs->loadLangs(array("mails", "admin"));
40
41// Load variable for pagination
42$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
43$sortfield = GETPOST('sortfield', 'aZ09comma');
44$sortorder = GETPOST('sortorder', 'aZ09comma');
45$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
46if (empty($page) || $page == -1) {
47 $page = 0;
48} // If $page is not defined, or '' or -1
49$offset = $limit * $page;
50$pageprev = $page - 1;
51$pagenext = $page + 1;
52if (!$sortfield) {
53 $sortfield = "mc.statut,email";
54}
55if (!$sortorder) {
56 $sortorder = "DESC,ASC";
57}
58
59$id = GETPOSTINT('id');
60$rowid = GETPOSTINT('rowid');
61$action = GETPOST('action', 'aZ09');
62$search_lastname = GETPOST("search_lastname", 'alphanohtml');
63$search_firstname = GETPOST("search_firstname", 'alphanohtml');
64$search_email = GETPOST("search_email", 'alphanohtml');
65$search_other = GETPOST("search_other", 'alphanohtml');
66$search_dest_status = GETPOST('search_dest_status', 'int');
67
68// Search modules dirs
69$modulesdir = dolGetModulesDirs('/mailings');
70
71$object = new Mailing($db);
72$result = $object->fetch($id);
73
74// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
75$hookmanager->initHooks(array('ciblescard', 'globalcard'));
76
77$sqlmessage = '';
78
79// List of sending methods
80$listofmethods = array();
81//$listofmethods['default'] = $langs->trans('DefaultOutgoingEmailSetup');
82$listofmethods['mail'] = 'PHP mail function';
83//$listofmethods['simplemail']='Simplemail class';
84$listofmethods['smtps'] = 'SMTP/SMTPS socket library';
85if (version_compare(phpversion(), '7.0', '>=')) {
86 $listofmethods['swiftmailer'] = 'Swift Mailer socket library';
87}
88
89// Security check
90if (!$user->hasRight('mailing', 'lire') || (!getDolGlobalString('EXTERNAL_USERS_ARE_AUTHORIZED') && $user->socid > 0)) {
92}
93if (empty($action) && empty($object->id)) {
94 accessforbidden('Object not found');
95}
96
97$permissiontoread = $user->hasRight('maling', 'lire');
98$permissiontocreate = $user->hasRight('mailing', 'creer');
99$permissiontovalidatesend = $user->hasRight('mailing', 'valider');
100$permissiontodelete = $user->hasRight('mailing', 'supprimer');
101
102
103/*
104 * Actions
105 */
106
107if ($action == 'add' && $permissiontocreate) { // Add recipients
108 $module = GETPOST("module", 'alpha');
109 $result = -1;
110
111 foreach ($modulesdir as $dir) {
112 // Load modules attributes in arrays (name, numero, orders) from dir directory
113 //print $dir."\n<br>";
114 dol_syslog("Scan directory ".$dir." for modules");
115
116 // Loading Class
117 $file = $dir."/".$module.".modules.php";
118 $classname = "mailing_".$module;
119
120 if (file_exists($file)) {
121 include_once $file;
122
123 // Add targets into database
124 dol_syslog("Call add_to_target() on class ".$classname." evenunsubscribe=".$object->evenunsubscribe);
125
126 if (class_exists($classname)) {
127 $obj = new $classname($db);
128 $obj->evenunsubscribe = $object->evenunsubscribe;
129
130 $result = $obj->add_to_target($id);
131
132 $sqlmessage = $obj->sql;
133 } else {
134 $result = -1;
135 break;
136 }
137 }
138 }
139 if ($result > 0) {
140 // If status of emailing is sent completely, change to to send partially
141 if ($object->status == $object::STATUS_SENTCOMPLETELY) {
142 $object->setStatut($object::STATUS_SENTPARTIALY);
143 }
144
145 setEventMessages($langs->trans("XTargetsAdded", $result), null, 'mesgs');
146 $action = '';
147 }
148 if ($result == 0) {
149 setEventMessages($langs->trans("WarningNoEMailsAdded"), null, 'warnings');
150 }
151 if ($result < 0) {
152 setEventMessages($langs->trans("Error").($obj->error ? ' '.$obj->error : ''), null, 'errors');
153 }
154}
155
156if (GETPOSTINT('clearlist') && $permissiontocreate) {
157 // Loading Class
158 $obj = new MailingTargets($db);
159 $obj->clear_target($id);
160 /* Avoid this to allow reposition
161 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
162 exit;
163 */
164}
165
166if (GETPOSTINT('exportcsv') && $permissiontoread) {
167 $completefilename = 'targets_emailing'.$object->id.'_'.dol_print_date(dol_now(), 'dayhourlog').'.csv';
168 header('Content-Type: text/csv');
169 header('Content-Disposition: attachment;filename='.$completefilename);
170
171 // List of selected targets
172 $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut as status, mc.date_envoi, mc.tms,";
173 $sql .= " mc.source_id, mc.source_type, mc.error_text";
174 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
175 $sql .= " WHERE mc.fk_mailing = ".((int) $object->id);
176 $sql .= $db->order($sortfield, $sortorder);
177
178 $resql = $db->query($sql);
179 if ($resql) {
180 $num = $db->num_rows($resql);
181 $sep = ',';
182
183 while ($obj = $db->fetch_object($resql)) {
184 print $obj->rowid.$sep;
185 print '"'.$obj->lastname.'"'.$sep;
186 print '"'.$obj->firstname.'"'.$sep;
187 print $obj->email.$sep;
188 print $obj->other.$sep;
189 print $obj->tms.$sep;
190 print $obj->source_type.$sep;
191 print $obj->source_id.$sep;
192 print $obj->date_envoi.$sep;
193 print $obj->status.$sep;
194 print '"'.$obj->error_text.'"'.$sep;
195 print "\n";
196 }
197
198 exit;
199 } else {
200 dol_print_error($db);
201 }
202 exit;
203}
204
205if ($action == 'delete' && $permissiontocreate) {
206 // Ici, rowid indique le destinataire et id le mailing
207 $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid = ".((int) $rowid);
208 $resql = $db->query($sql);
209 if ($resql) {
210 if (!empty($id)) {
211 $obj = new MailingTargets($db);
212 $obj->update_nb($id);
213
214 setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
215 } else {
216 header("Location: list.php");
217 exit;
218 }
219 } else {
220 dol_print_error($db);
221 }
222}
223
224// Purge search criteria
225if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
226 $search_lastname = '';
227 $search_firstname = '';
228 $search_email = '';
229 $search_other = '';
230 $search_dest_status = '';
231}
232
233// Action update description of emailing
234if (($action == 'settitle' || $action == 'setemail_from' || $action == 'setreplyto' || $action == 'setemail_errorsto' || $action == 'setevenunsubscribe') && $permissiontocreate) {
235 $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
236
237 if ($action == 'settitle') { // Test on permission already done
238 $object->title = trim(GETPOST('title', 'alpha'));
239 } elseif ($action == 'setemail_from') { // Test on permission already done
240 $object->email_from = trim(GETPOST('email_from', 'alphawithlgt')); // Must allow 'name <email>'
241 } elseif ($action == 'setemail_replyto') { // Test on permission already done
242 $object->email_replyto = trim(GETPOST('email_replyto', 'alphawithlgt')); // Must allow 'name <email>'
243 } elseif ($action == 'setemail_errorsto') { // Test on permission already done
244 $object->email_errorsto = trim(GETPOST('email_errorsto', 'alphawithlgt')); // Must allow 'name <email>'
245 } elseif ($action == 'settitle' && empty($object->title)) { // Test on permission already done
246 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTitle"));
247 } elseif ($action == 'setfrom' && empty($object->email_from)) { // Test on permission already done
248 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailFrom"));
249 } elseif ($action == 'setevenunsubscribe') { // Test on permission already done
250 $object->evenunsubscribe = (GETPOST('evenunsubscribe') ? 1 : 0);
251 }
252
253 if (!$mesg) {
254 $result = $object->update($user);
255 if ($result >= 0) {
256 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
257 exit;
258 }
259 $mesg = $object->error;
260 }
261
262 setEventMessages($mesg, $mesgs, 'errors');
263 $action = "";
264}
265
266
267/*
268 * View
269 */
270
271llxHeader('', $langs->trans("Mailing"), 'EN:Module_EMailing|FR:Module_Mailing|ES:M&oacute;dulo_Mailing');
272
273$form = new Form($db);
274$formmailing = new FormMailing($db);
275
276if ($object->fetch($id) >= 0) {
277 $head = emailing_prepare_head($object);
278
279 print dol_get_fiche_head($head, 'targets', $langs->trans("Mailing"), -1, 'email');
280
281 $linkback = '<a href="'.DOL_URL_ROOT.'/comm/mailing/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
282
283 $morehtmlref = '<div class="refidno">';
284 // Ref customer
285 $morehtmlref .= $form->editfieldkey("", 'title', $object->title, $object, 0, 'string', '', 0, 1);
286 $morehtmlref .= $form->editfieldval("", 'title', $object->title, $object, 0, 'string', '', null, null, '', 1);
287 $morehtmlref .= '</div>';
288
289 $morehtmlstatus = '';
290 $nbtry = $nbok = 0;
291 if ($object->status == $object::STATUS_SENTPARTIALY || $object->status == $object::STATUS_SENTCOMPLETELY) {
292 $nbtry = $object->countNbOfTargets('alreadysent');
293 $nbko = $object->countNbOfTargets('alreadysentko');
294 $nbok = ($nbtry - $nbko);
295
296 $morehtmlstatus .= ' ('.$nbtry.'/'.$object->nbemail;
297 if ($nbko) {
298 $morehtmlstatus .= ' - '.$nbko.' '.$langs->trans("Error");
299 }
300 $morehtmlstatus .= ') &nbsp; ';
301 }
302
303 dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
304
305 print '<div class="fichecenter">';
306 print '<div class="fichehalfleft">';
307 print '<div class="underbanner clearboth"></div>';
308
309 print '<table class="border centpercent tableforfield">';
310
311 // From
312 print '<tr><td class="titlefield">'.$langs->trans("MailFrom").'</td><td>';
313 $emailarray = CMailFile::getArrayAddress($object->email_from);
314 foreach ($emailarray as $email => $name) {
315 if ($name && $name != $email) {
316 print dol_escape_htmltag($name).' &lt;'.$email;
317 print '&gt;';
318 if (!isValidEmail($email)) {
319 $langs->load("errors");
320 print img_warning($langs->trans("ErrorBadEMail", $email));
321 }
322 } else {
323 print dol_print_email($object->email_from, 0, 0, 0, 0, 1);
324 }
325 }
326 //print dol_print_email($object->email_from, 0, 0, 0, 0, 1);
327 //var_dump($object->email_from);
328 print '</td></tr>';
329
330 // Errors to
331 if ($object->messtype != 'sms') {
332 print '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
333 $emailarray = CMailFile::getArrayAddress($object->email_errorsto);
334 foreach ($emailarray as $email => $name) {
335 if ($name != $email) {
336 print dol_escape_htmltag($name).' &lt;'.$email;
337 print '&gt;';
338 if ($email && !isValidEmail($email)) {
339 $langs->load("errors");
340 print img_warning($langs->trans("ErrorBadEMail", $email));
341 } elseif ($email && !isValidMailDomain($email)) {
342 $langs->load("errors");
343 print img_warning($langs->trans("ErrorBadMXDomain", $email));
344 }
345 } else {
346 print dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1);
347 }
348 }
349 print '</td></tr>';
350 }
351
352 // Reply to
353 if ($object->messtype != 'sms') {
354 print '<tr><td>';
355 print $form->editfieldkey("MailReply", 'email_replyto', $object->email_replyto, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
356 print '</td><td>';
357 print $form->editfieldval("MailReply", 'email_replyto', $object->email_replyto, $object, $user->hasRight('mailing', 'creer') && $object->status < $object::STATUS_SENTCOMPLETELY, 'string');
358 $email = CMailFile::getValidAddress($object->email_replyto, 2);
359 if ($action != 'editemail_replyto') {
360 if ($email && !isValidEmail($email)) {
361 $langs->load("errors");
362 print img_warning($langs->trans("ErrorBadEMail", $email));
363 } elseif ($email && !isValidMailDomain($email)) {
364 $langs->load("errors");
365 print img_warning($langs->trans("ErrorBadMXDomain", $email));
366 }
367 }
368 print '</td></tr>';
369 }
370
371 print '</table>';
372 print '</div>';
373
374
375 print '<div class="fichehalfright">';
376 print '<div class="underbanner clearboth"></div>';
377
378 print '<table class="border centpercent tableforfield">';
379
380 // Number of distinct emails
381 print '<tr><td>';
382 print $langs->trans("TotalNbOfDistinctRecipients");
383 print '</td><td>';
384 $nbemail = ($object->nbemail ? $object->nbemail : 0);
385 if (is_numeric($nbemail)) {
386 $text = '';
387 if ((getDolGlobalString('MAILING_LIMIT_SENDBYWEB') && getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') < $nbemail) && ($object->status == 1 || ($object->status == 2 && $nbtry < $nbemail))) {
388 if (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') > 0) {
389 $text .= $langs->trans('LimitSendingEmailing', getDolGlobalString('MAILING_LIMIT_SENDBYWEB'));
390 } else {
391 $text .= $langs->trans('SendingFromWebInterfaceIsNotAllowed');
392 }
393 }
394 if (empty($nbemail)) {
395 $nbemail .= ' '.img_warning($langs->trans('ToAddRecipientsChooseHere'));//.' <span class="warning">'.$langs->trans("NoTargetYet").'</span>';
396 }
397 if ($text) {
398 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
399 print $form->textwithpicto($nbemail, $text, 1, 'warning');
400 } else {
401 print $nbemail;
402 }
403 }
404 print '</td></tr>';
405
406 print '<tr><td>';
407 print $langs->trans("MAIN_MAIL_SENDMODE");
408 print '</td><td>';
409 if ($object->messtype != 'sms') {
410 if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') && getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
411 $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING')];
412 } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE')) {
413 $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE')];
414 } else {
415 $text = $listofmethods['mail'];
416 }
417 print $text;
418 if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
419 if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'mail') {
420 print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER_EMAILING', getDolGlobalString('MAIN_MAIL_SMTP_SERVER')).')</span>';
421 }
422 } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE') != 'mail' && getDolGlobalString('MAIN_MAIL_SMTP_SERVER')) {
423 print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER').')</span>';
424 }
425 } else {
426 print 'SMS ';
427 print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER').')</span>';
428 }
429 print '</td></tr>';
430
431 // Other attributes. Fields from hook formObjectOptions and Extrafields.
432 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
433
434 print '</table>';
435 print '</div>';
436 print '</div>';
437
438 print '<div class="clearboth"></div>';
439
440 print dol_get_fiche_end();
441
442 print '<br>';
443
444
445 $newcardbutton = '';
446 $allowaddtarget = ($object->status == $object::STATUS_DRAFT);
447 if (GETPOST('allowaddtarget')) {
448 $allowaddtarget = 1;
449 }
450 if (!$allowaddtarget) {
451 $newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?id='.$object->id.'&allowaddtarget=1', '', $user->hasRight('mailing', 'creer'));
452 }
453
454 // Show email selectors
455 if ($allowaddtarget && $user->hasRight('mailing', 'creer')) {
456 print load_fiche_titre($langs->trans("ToAddRecipientsChooseHere"), ($user->admin ? info_admin($langs->trans("YouCanAddYourOwnPredefindedListHere"), 1) : ''), 'generic');
457
458 print '<div class="div-table-responsive">';
459 print '<div class="tagtable centpercentwithout1imp liste_titre_bydiv borderbottom" id="tablelines">';
460
461 print '<div class="tagtr liste_titre">';
462 print '<div class="tagtd"></div>';
463 print '<div class="tagtd">'.$langs->trans("RecipientSelectionModules").'</div>';
464 print '<div class="tagtd center maxwidth150">';
465 if ($object->messtype != 'sms') {
466 print $langs->trans("NbOfUniqueEMails");
467 } else {
468 print $langs->trans("NbOfUniquePhones");
469 }
470 print '</div>';
471 print '<div class="tagtd left"><div class="inline-block">'.$langs->trans("Filters").'</div>';
472 if ($object->messtype != 'sms') {
473 print ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div class=" inline-block">'.$langs->trans("EvenUnsubscribe").' ';
474 print ajax_object_onoff($object, 'evenunsubscribe', 'evenunsubscribe', 'EvenUnsubscribe:switch_on:warning', 'EvenUnsubscribe', array(), 'small valignmiddle', '', 1);
475 print '</div>';
476 }
477 print '</div>';
478 print '<div class="tagtd">&nbsp;</div>';
479 print '</div>'; // End tr
480
481 clearstatcache();
482
483 foreach ($modulesdir as $dir) {
484 $modulenames = array();
485
486 // Load modules attributes in arrays (name, numero, orders) from dir directory
487 //print $dir."\n<br>";
488 dol_syslog("Scan directory ".$dir." for modules");
489 $handle = @opendir($dir);
490 if (is_resource($handle)) {
491 while (($file = readdir($handle)) !== false) {
492 if (substr($file, 0, 1) != '.' && substr($file, 0, 3) != 'CVS') {
493 $reg = array();
494 if (preg_match("/(.*)\.modules\.php$/i", $file, $reg)) {
495 if ($reg[1] == 'example') {
496 continue;
497 }
498 $modulenames[] = $reg[1];
499 }
500 }
501 }
502 closedir($handle);
503 }
504
505 // Sort $modulenames
506 sort($modulenames);
507
508 $var = true;
509
510 // Loop on each submodule
511 foreach ($modulenames as $modulename) {
512 // Loading Class
513 $file = $dir.$modulename.".modules.php";
514 $classname = "mailing_".$modulename;
515 require_once $file;
516
517 $obj = new $classname($db);
518
519 // Check if qualified
520 $qualified = (is_null($obj->enabled) ? 1 : (int) dol_eval($obj->enabled, 1));
521
522 // Check dependencies
523 foreach ($obj->require_module as $key) {
524 if (empty($conf->$key->enabled) || (empty($user->admin) && $obj->require_admin)) {
525 $qualified = 0;
526 //print "Les prerequis d'activation du module mailing ne sont pas respectes. Il ne sera pas actif";
527 break;
528 }
529 }
530
531 // If module is qualified
532 if ($qualified) {
533 $var = !$var;
534
535 if ($allowaddtarget) {
536 print '<form '.$bctag[$var].' name="'.$modulename.'" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&module='.$modulename.'" method="POST" enctype="multipart/form-data">';
537 print '<input type="hidden" name="token" value="'.newToken().'">';
538 print '<input type="hidden" name="action" value="add">';
539 print '<input type="hidden" name="page_y" value="'.newToken().'">';
540 } else {
541 print '<div '.$bctag[$var].'>';
542 }
543
544 print '<div class="tagtd paddingleftimp marginleftonly paddingrightimp marginrightonly valignmiddle center">';
545 if (empty($obj->picto)) {
546 $obj->picto = 'generic';
547 }
548 print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj), $obj->picto, 'class="valignmiddle width25 size15x"');
549 print '</div>';
550 print '<div class="tagtd valignmiddle">'; // style="height: 4em"
551 print $obj->getDesc();
552 print '</div>';
553
554 try {
555 $obj->evenunsubscribe = $object->evenunsubscribe; // Set flag to include/exclude email that has opt-out.
556
557 $nbofrecipient = $obj->getNbOfRecipients('');
558 } catch (Exception $e) {
559 dol_syslog($e->getMessage(), LOG_ERR);
560 }
561
562 print '<div class="tagtd center valignmiddle">';
563 if ($nbofrecipient === '' || $nbofrecipient >= 0) {
564 print $nbofrecipient;
565 } else {
566 print $langs->trans("Error").' '.img_error($obj->error);
567 }
568 print '</div>';
569
570 print '<div class="tagtd left valignmiddle">';
571 if ($allowaddtarget) {
572 try {
573 $filter = $obj->formFilter();
574 } catch (Exception $e) {
575 dol_syslog($e->getMessage(), LOG_ERR);
576 }
577 if ($filter) {
578 print $filter;
579 } else {
580 print $langs->trans("None");
581 }
582 }
583 print '</div>';
584
585 print '<div class="tagtd right valignmiddle">';
586 if ($allowaddtarget) {
587 print '<input type="submit" class="button button-add small reposition" name="button_'.$modulename.'" value="'.$langs->trans("Add").'">';
588 } else {
589 print '<input type="submit" class="button small disabled" disabled="disabled" name="button_'.$modulename.'" value="'.$langs->trans("Add").'">';
590 //print $langs->trans("MailNoChangePossible");
591 print "&nbsp;";
592 }
593 print '</div>';
594
595 if ($allowaddtarget) {
596 print '</form>';
597 } else {
598 print '</div>';
599 }
600 }
601 }
602 } // End foreach dir
603
604 $parameters = array();
605 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
606 print $hookmanager->resPrint;
607
608 print '</div>'; // End table
609 print '</div>';
610
611 print '<br>';
612
613 if ($sqlmessage && $user->admin) {
614 print info_admin($langs->trans("SQLUsedForExport").':<br> '.$sqlmessage, 0, 0, 1, '', 'TechnicalInformation');
615 print '<br>';
616 }
617
618 print '<br>';
619 }
620
621 // List of selected targets
622 $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut as status, mc.date_envoi, mc.tms,";
623 $sql .= " mc.source_url, mc.source_id, mc.source_type, mc.error_text,";
624 $sql .= " COUNT(mu.rowid) as nb";
625 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
626 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."mailing_unsubscribe as mu ON mu.email = mc.email";
627 $sql .= " WHERE mc.fk_mailing=".((int) $object->id);
628 $asearchcriteriahasbeenset = 0;
629 if ($search_lastname) {
630 $sql .= natural_search("mc.lastname", $search_lastname);
631 $asearchcriteriahasbeenset++;
632 }
633 if ($search_firstname) {
634 $sql .= natural_search("mc.firstname", $search_firstname);
635 $asearchcriteriahasbeenset++;
636 }
637 if ($search_email) {
638 $sql .= natural_search("mc.email", $search_email);
639 $asearchcriteriahasbeenset++;
640 }
641 if ($search_other) {
642 $sql .= natural_search("mc.other", $search_other);
643 $asearchcriteriahasbeenset++;
644 }
645 if ($search_dest_status != '' && (int) $search_dest_status >= -1) {
646 $sql .= " AND mc.statut = ".((int) $search_dest_status);
647 $asearchcriteriahasbeenset++;
648 }
649 $sql .= ' GROUP BY mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut, mc.date_envoi, mc.tms, mc.source_url, mc.source_id, mc.source_type, mc.error_text';
650 $sql .= $db->order($sortfield, $sortorder);
651
652
653 // Count total nb of records
654 $nbtotalofrecords = '';
655 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
656 $result = $db->query($sql);
657 $nbtotalofrecords = $db->num_rows($result);
658 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
659 $page = 0;
660 $offset = 0;
661 }
662
663 // Fix/update nbemail on emailing record if it differs (may happen if user edit lines from database directly)
664 if (empty($asearchcriteriahasbeenset)) {
665 if ($nbtotalofrecords != $object->nbemail) {
666 dol_syslog("We found a difference in nb of record in target table and the property ->nbemail, we fix ->nbemail");
667 //print "nbemail=".$object->nbemail." nbtotalofrecords=".$nbtotalofrecords;
668 $resultrefresh = $object->refreshNbOfTargets();
669 if ($resultrefresh < 0) {
670 dol_print_error($db, $object->error, $object->errors);
671 }
672 }
673 }
674 }
675
676 //$nbtotalofrecords=$object->nbemail; // nbemail is a denormalized field storing nb of targets
677 $sql .= $db->plimit($limit + 1, $offset);
678
679 $resql = $db->query($sql);
680 if ($resql) {
681 $num = $db->num_rows($resql);
682
683 $param = "&id=".$object->id;
684 //if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
685 if ($limit > 0 && $limit != $conf->liste_limit) {
686 $param .= '&limit='.((int) $limit);
687 }
688 if ($search_lastname) {
689 $param .= "&search_lastname=".urlencode($search_lastname);
690 }
691 if ($search_firstname) {
692 $param .= "&search_firstname=".urlencode($search_firstname);
693 }
694 if ($search_email) {
695 $param .= "&search_email=".urlencode($search_email);
696 }
697 if ($search_other) {
698 $param .= "&search_other=".urlencode($search_other);
699 }
700
701 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
702 print '<input type="hidden" name="token" value="'.newToken().'">';
703 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
704 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
705 print '<input type="hidden" name="page" value="'.$page.'">';
706 print '<input type="hidden" name="id" value="'.$object->id.'">';
707 print '<input type="hidden" name="page_y" value="">';
708
709 $morehtmlcenter = '';
710 if ($object->status == $object::STATUS_DRAFT) {
711 $morehtmlcenter = '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ToClearAllRecipientsClickHere").'</span> <a href="'.$_SERVER["PHP_SELF"].'?clearlist=1&id='.$object->id.'" class="button reposition smallpaddingimp">'.$langs->trans("TargetsReset").'</a>';
712 }
713 $morehtmlcenter .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=exportcsv&token='.newToken().'&exportcsv=1&id='.$object->id.'">'.img_picto('', 'download', 'class="pictofixedwidth"').$langs->trans("Download").'</a>';
714
715 $massactionbutton = '';
716
717 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
718 print_barre_liste($langs->trans("MailSelectedRecipients"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $morehtmlcenter, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit, 0, 0, 1);
719
720 print '</form>';
721
722 print "\n<!-- Liste destinataires selectionnes -->\n";
723 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
724 print '<input type="hidden" name="token" value="'.newToken().'">';
725 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
726 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
727 print '<input type="hidden" name="page" value="'.$page.'">';
728 print '<input type="hidden" name="id" value="'.$object->id.'">';
729 print '<input type="hidden" name="limit" value="'.$limit.'">';
730 print '<input type="hidden" name="page_y" value="">';
731
732 print '<div class="div-table-responsive">';
733 print '<table class="noborder centpercent">';
734
735 // Ligne des champs de filtres
736 print '<tr class="liste_titre_filter">';
737
738 // Action column
739 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
740 print '<td class="liste_titre maxwidthsearch">';
741 $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
742 print $searchpicto;
743 print '</td>';
744 }
745 // EMail
746 print '<td class="liste_titre">';
747 print '<input class="flat maxwidth75" type="text" name="search_email" value="'.dol_escape_htmltag($search_email).'">';
748 print '</td>';
749 // Name
750 print '<td class="liste_titre">';
751 print '<input class="flat maxwidth50" type="text" name="search_lastname" value="'.dol_escape_htmltag($search_lastname).'">';
752 print '</td>';
753 // Firstname
754 print '<td class="liste_titre">';
755 print '<input class="flat maxwidth50" type="text" name="search_firstname" value="'.dol_escape_htmltag($search_firstname).'">';
756 print '</td>';
757 // Other
758 print '<td class="liste_titre">';
759 print '<input class="flat maxwidth100" type="text" name="search_other" value="'.dol_escape_htmltag($search_other).'">';
760 print '</td>';
761 // Source
762 print '<td class="liste_titre">';
763 print '&nbsp;';
764 print '</td>';
765
766 // Date last update
767 print '<td class="liste_titre">';
768 print '&nbsp;';
769 print '</td>';
770
771 // Date sending
772 print '<td class="liste_titre">';
773 print '&nbsp;';
774 print '</td>';
775
776 // Status
777 print '<td class="liste_titre center parentonrightofpage">';
778 print $formmailing->selectDestinariesStatus($search_dest_status, 'search_dest_status', 1, 'width100 onrightofpage');
779 print '</td>';
780
781 // Action column
782 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
783 print '<td class="liste_titre maxwidthsearch">';
784 $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
785 print $searchpicto;
786 print '</td>';
787 }
788
789 print '</tr>';
790
791 if ($page) {
792 $param .= "&page=".urlencode((string) ($page));
793 }
794
795 print '<tr class="liste_titre">';
796 // Action column
797 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
798 print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch ');
799 }
800 print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "mc.email", $param, "", "", $sortfield, $sortorder);
801 print_liste_field_titre("Lastname", $_SERVER["PHP_SELF"], "mc.lastname", $param, "", "", $sortfield, $sortorder);
802 print_liste_field_titre("Firstname", $_SERVER["PHP_SELF"], "mc.firstname", $param, "", "", $sortfield, $sortorder);
803 print_liste_field_titre("OtherInformations", $_SERVER["PHP_SELF"], "", $param, "", "", $sortfield, $sortorder);
804 print_liste_field_titre("Source", $_SERVER["PHP_SELF"], "", $param, "", '', $sortfield, $sortorder, 'center ');
805 // Date last update
806 print_liste_field_titre("DateLastModification", $_SERVER["PHP_SELF"], "mc.tms", $param, "", '', $sortfield, $sortorder, 'center ');
807 // Date sending
808 print_liste_field_titre("DateSending", $_SERVER["PHP_SELF"], "mc.date_envoi", $param, '', '', $sortfield, $sortorder, 'center ');
809 print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "mc.statut", $param, '', '', $sortfield, $sortorder, 'center ');
810 // Action column
811 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
812 print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch ');
813 }
814 print '</tr>';
815
816 $i = 0;
817
818 if ($num) {
819 include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
820 include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
821 include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
822 include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
823 include_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
824
825 $objectstaticmember = new Adherent($db);
826 $objectstaticuser = new User($db);
827 $objectstaticcompany = new Societe($db);
828 $objectstaticcontact = new Contact($db);
829 $objectstaticeventorganization = new ConferenceOrBoothAttendee($db);
830
831 while ($i < min($num, $limit)) {
832 $obj = $db->fetch_object($resql);
833
834 print '<tr class="oddeven">';
835
836 // Action column
837 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
838 print '<td class="center">';
839 print '<!-- ID mailing_cibles = '.$obj->rowid.' -->';
840 if ($obj->status == $object::STATUS_DRAFT) { // Not sent yet
841 if ($user->hasRight('mailing', 'creer')) {
842 print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&rowid='.((int) $obj->rowid).$param.'">'.img_delete($langs->trans("RemoveRecipient")).'</a>';
843 }
844 }
845 /*if ($obj->status == -1) // Sent with error
846 {
847 print '<a href="'.$_SERVER['PHP_SELF'].'?action=retry&rowid='.$obj->rowid.$param.'">'.$langs->trans("Retry").'</a>';
848 }*/
849 print '</td>';
850 }
851
852 print '<td class="tdoverflowmax150">';
853 print img_picto($obj->email, 'email', 'class="paddingright"');
854 if ($obj->nb > 0) {
855 print img_warning($langs->trans("EmailOptedOut"), 'warning', 'pictofixedwidth');
856 }
857 print dol_escape_htmltag($obj->email);
858 print '</td>';
859
860 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->lastname).'</td>';
861
862 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->firstname).'">'.dol_escape_htmltag($obj->firstname).'</td>';
863
864 print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($obj->other).'"><span class="small">'.dol_escape_htmltag($obj->other).'</small></td>';
865
866 print '<td class="center tdoverflowmax150">';
867 if (empty($obj->source_id) || empty($obj->source_type)) {
868 print empty($obj->source_url) ? '' : $obj->source_url; // For backward compatibility
869 } else {
870 if ($obj->source_type == 'member') {
871 $objectstaticmember->fetch($obj->source_id);
872 print $objectstaticmember->getNomUrl(1);
873 } elseif ($obj->source_type == 'user') {
874 $objectstaticuser->fetch($obj->source_id);
875 print $objectstaticuser->getNomUrl(1);
876 } elseif ($obj->source_type == 'thirdparty') {
877 $objectstaticcompany->fetch($obj->source_id);
878 print $objectstaticcompany->getNomUrl(1);
879 } elseif ($obj->source_type == 'contact') {
880 $objectstaticcontact->fetch($obj->source_id);
881 print $objectstaticcontact->getNomUrl(1);
882 } elseif ($obj->source_type == 'eventorganizationattendee') {
883 $objectstaticeventorganization->fetch($obj->source_id);
884 print $objectstaticeventorganization->getNomUrl(1);
885 } else {
886 print $obj->source_url;
887 }
888 }
889 print '</td>';
890
891 // Date last update
892 print '<td class="center nowraponall">';
893 print dol_print_date(dol_stringtotime($obj->tms), 'dayhour');
894 print '</td>';
895
896 // Date sent
897 print '<td class="center nowraponall">';
898 if ($obj->status != $object::STATUS_DRAFT) { // If status of target line is not draft
899 // Date sent
900 print $obj->date_envoi; // @TODO Must store date in date format
901 }
902 print '</td>';
903
904 // Status of recipient sending email (Warning != status of emailing)
905 print '<td class="nowrap center">';
906 if ($obj->status == $object::STATUS_DRAFT) { // If status of target line is not draft
907 print $object::libStatutDest((int) $obj->status, 2, '');
908 } else {
909 print $object::libStatutDest((int) $obj->status, 2, $obj->error_text);
910 }
911 print '</td>';
912
913 // Action column
914 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
915 print '<td class="center">';
916 print '<!-- ID mailing_cibles = '.$obj->rowid.' -->';
917 if ($obj->status == $object::STATUS_DRAFT) { // If status of target line is not sent yet
918 if ($user->hasRight('mailing', 'creer')) {
919 print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&rowid='.((int) $obj->rowid).$param.'">'.img_delete($langs->trans("RemoveRecipient")).'</a>';
920 }
921 }
922 /*if ($obj->status == -1) // Sent with error
923 {
924 print '<a href="'.$_SERVER['PHP_SELF'].'?action=retry&rowid='.$obj->rowid.$param.'">'.$langs->trans("Retry").'</a>';
925 }*/
926 print '</td>';
927 }
928 print '</tr>';
929
930 $i++;
931 }
932 } else {
933 if ($object->status < $object::STATUS_SENTPARTIALY) {
934 print '<tr><td colspan="9">';
935 print '<span class="opacitymedium">'.$langs->trans("NoTargetYet").'</span>';
936 print '</td></tr>';
937 } else {
938 print '<tr><td colspan="9">';
939 print '<span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span>';
940 print '</td></tr>';
941 }
942 }
943 print "</table><br>";
944 print '</div>';
945
946 print '</form>';
947
948 $db->free($resql);
949 } else {
950 dol_print_error($db);
951 }
952
953 print "\n<!-- Fin liste destinataires selectionnes -->\n";
954}
955
956// End of page
957llxFooter();
958$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input=array(), $morecss='', $htmlname='', $forcenojs=0, $moreparam='')
On/off button to change a property status of an object This uses the ajax service objectonoff....
Definition ajax.lib.php:725
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to manage members of a foundation.
static getValidAddress($address, $format, $encode=0, $maxnumberofemail=0)
Return a formatted address string for SMTP protocol.
static getArrayAddress($address)
Return a formatted array of address string for SMTP protocol.
Class for ConferenceOrBoothAttendee.
Class to manage contact/addresses.
Class to manage generation of HTML components Only common components must be here.
Class to offer components to list and upload files.
Class to manage emailings module.
Parent class of emailing target selectors modules.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:427
emailing_prepare_head(Mailing $object)
Prepare array with list of tabs.
dolGetModulesDirs($subdir='')
Return list of directories that contain modules.
isValidMailDomain($mail)
Return true if email has a domain name that can be resolved to MX type.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_print_email($email, $cid=0, $socid=0, $addlink=0, $max=64, $showinvalid=1, $withpicto=0)
Show EMail link formatted for HTML output.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
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.
img_error($titlealt='default')
Show error logo.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart='')
Return a path to have a the directory according to object where files are stored.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.