dolibarr  20.0.0-beta
cibles.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2005-2023 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
29 require '../../main.inc.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
31 require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmailing.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/lib/emailing.lib.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
36 require_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");
46 if (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;
52 if (!$sortfield) {
53  $sortfield = "mc.statut,email";
54 }
55 if (!$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';
85 if (version_compare(phpversion(), '7.0', '>=')) {
86  $listofmethods['swiftmailer'] = 'Swift Mailer socket library';
87 }
88 
89 // Security check
90 if (!$user->hasRight('mailing', 'lire') || (!getDolGlobalString('EXTERNAL_USERS_ARE_AUTHORIZED') && $user->socid > 0)) {
92 }
93 //$result = restrictedArea($user, 'mailing');
94 
95 
96 /*
97  * Actions
98  */
99 
100 if ($action == 'add' && $user->hasRight('mailing', 'creer')) { // Add recipients
101  $module = GETPOST("module", 'alpha');
102  $result = -1;
103 
104  foreach ($modulesdir as $dir) {
105  // Load modules attributes in arrays (name, numero, orders) from dir directory
106  //print $dir."\n<br>";
107  dol_syslog("Scan directory ".$dir." for modules");
108 
109  // Loading Class
110  $file = $dir."/".$module.".modules.php";
111  $classname = "mailing_".$module;
112 
113  if (file_exists($file)) {
114  include_once $file;
115 
116  // Add targets into database
117  dol_syslog("Call add_to_target() on class ".$classname." evenunsubscribe=".$object->evenunsubscribe);
118 
119  if (class_exists($classname)) {
120  $obj = new $classname($db);
121  $obj->evenunsubscribe = $object->evenunsubscribe;
122 
123  $result = $obj->add_to_target($id);
124 
125  $sqlmessage = $obj->sql;
126  } else {
127  $result = -1;
128  break;
129  }
130  }
131  }
132  if ($result > 0) {
133  // If status of emailing is sent completely, change to to send partially
134  if ($object->status == $object::STATUS_SENTCOMPLETELY) {
135  $object->setStatut($object::STATUS_SENTPARTIALY);
136  }
137 
138  setEventMessages($langs->trans("XTargetsAdded", $result), null, 'mesgs');
139  $action = '';
140  }
141  if ($result == 0) {
142  setEventMessages($langs->trans("WarningNoEMailsAdded"), null, 'warnings');
143  }
144  if ($result < 0) {
145  setEventMessages($langs->trans("Error").($obj->error ? ' '.$obj->error : ''), null, 'errors');
146  }
147 }
148 
149 if (GETPOSTINT('clearlist') && $user->hasRight('mailing', 'creer')) {
150  // Loading Class
151  $obj = new MailingTargets($db);
152  $obj->clear_target($id);
153  /* Avoid this to allow reposition
154  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
155  exit;
156  */
157 }
158 
159 if (GETPOSTINT('exportcsv') && $user->hasRight('mailing', 'lire')) {
160  $completefilename = 'targets_emailing'.$object->id.'_'.dol_print_date(dol_now(), 'dayhourlog').'.csv';
161  header('Content-Type: text/csv');
162  header('Content-Disposition: attachment;filename='.$completefilename);
163 
164  // List of selected targets
165  $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut as status, mc.date_envoi, mc.tms,";
166  $sql .= " mc.source_id, mc.source_type, mc.error_text";
167  $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
168  $sql .= " WHERE mc.fk_mailing = ".((int) $object->id);
169  $sql .= $db->order($sortfield, $sortorder);
170 
171  $resql = $db->query($sql);
172  if ($resql) {
173  $num = $db->num_rows($resql);
174  $sep = ',';
175 
176  while ($obj = $db->fetch_object($resql)) {
177  print $obj->rowid.$sep;
178  print '"'.$obj->lastname.'"'.$sep;
179  print '"'.$obj->firstname.'"'.$sep;
180  print $obj->email.$sep;
181  print $obj->other.$sep;
182  print $obj->tms.$sep;
183  print $obj->source_type.$sep;
184  print $obj->source_id.$sep;
185  print $obj->date_envoi.$sep;
186  print $obj->status.$sep;
187  print '"'.$obj->error_text.'"'.$sep;
188  print "\n";
189  }
190 
191  exit;
192  } else {
193  dol_print_error($db);
194  }
195  exit;
196 }
197 
198 if ($action == 'delete' && $user->hasRight('mailing', 'creer')) {
199  // Ici, rowid indique le destinataire et id le mailing
200  $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid = ".((int) $rowid);
201  $resql = $db->query($sql);
202  if ($resql) {
203  if (!empty($id)) {
204  $obj = new MailingTargets($db);
205  $obj->update_nb($id);
206 
207  setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
208  } else {
209  header("Location: list.php");
210  exit;
211  }
212  } else {
213  dol_print_error($db);
214  }
215 }
216 
217 // Purge search criteria
218 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
219  $search_lastname = '';
220  $search_firstname = '';
221  $search_email = '';
222  $search_other = '';
223  $search_dest_status = '';
224 }
225 
226 // Action update description of emailing
227 if ($action == 'settitle' || $action == 'setemail_from' || $action == 'setreplyto' || $action == 'setemail_errorsto' || $action == 'setevenunsubscribe') {
228  $upload_dir = $conf->mailing->dir_output."/".get_exdir($object->id, 2, 0, 1, $object, 'mailing');
229 
230  if ($action == 'settitle') {
231  $object->title = trim(GETPOST('title', 'alpha'));
232  } elseif ($action == 'setemail_from') {
233  $object->email_from = trim(GETPOST('email_from', 'alphawithlgt')); // Must allow 'name <email>'
234  } elseif ($action == 'setemail_replyto') {
235  $object->email_replyto = trim(GETPOST('email_replyto', 'alphawithlgt')); // Must allow 'name <email>'
236  } elseif ($action == 'setemail_errorsto') {
237  $object->email_errorsto = trim(GETPOST('email_errorsto', 'alphawithlgt')); // Must allow 'name <email>'
238  } elseif ($action == 'settitle' && empty($object->title)) {
239  $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailTitle"));
240  } elseif ($action == 'setfrom' && empty($object->email_from)) {
241  $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("MailFrom"));
242  } elseif ($action == 'setevenunsubscribe') {
243  $object->evenunsubscribe = (GETPOST('evenunsubscribe') ? 1 : 0);
244  }
245 
246  if (!$mesg) {
247  $result = $object->update($user);
248  if ($result >= 0) {
249  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
250  exit;
251  }
252  $mesg = $object->error;
253  }
254 
255  setEventMessages($mesg, null, 'errors');
256  $action = "";
257 }
258 
259 
260 /*
261  * View
262  */
263 
264 llxHeader('', $langs->trans("Mailing"), 'EN:Module_EMailing|FR:Module_Mailing|ES:M&oacute;dulo_Mailing');
265 
266 $form = new Form($db);
267 $formmailing = new FormMailing($db);
268 
269 if ($object->fetch($id) >= 0) {
271 
272  print dol_get_fiche_head($head, 'targets', $langs->trans("Mailing"), -1, 'email');
273 
274  $linkback = '<a href="'.DOL_URL_ROOT.'/comm/mailing/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
275 
276  $morehtmlref = '<div class="refidno">';
277  // Ref customer
278  $morehtmlref .= $form->editfieldkey("", 'title', $object->title, $object, 0, 'string', '', 0, 1);
279  $morehtmlref .= $form->editfieldval("", 'title', $object->title, $object, 0, 'string', '', null, null, '', 1);
280  $morehtmlref .= '</div>';
281 
282  $morehtmlstatus = '';
283  $nbtry = $nbok = 0;
284  if ($object->status == $object::STATUS_SENTPARTIALY || $object->status == $object::STATUS_SENTCOMPLETELY) {
285  $nbtry = $object->countNbOfTargets('alreadysent');
286  $nbko = $object->countNbOfTargets('alreadysentko');
287  $nbok = ($nbtry - $nbko);
288 
289  $morehtmlstatus .= ' ('.$nbtry.'/'.$object->nbemail;
290  if ($nbko) {
291  $morehtmlstatus .= ' - '.$nbko.' '.$langs->trans("Error");
292  }
293  $morehtmlstatus .= ') &nbsp; ';
294  }
295 
296  dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
297 
298  print '<div class="fichecenter">';
299  print '<div class="fichehalfleft">';
300  print '<div class="underbanner clearboth"></div>';
301 
302  print '<table class="border centpercent tableforfield">';
303 
304  print '<tr><td class="titlefield">'.$langs->trans("MailFrom").'</td><td>';
305  $emailarray = CMailFile::getArrayAddress($object->email_from);
306  foreach ($emailarray as $email => $name) {
307  if ($name && $name != $email) {
308  print dol_escape_htmltag($name).' &lt;'.$email;
309  print '&gt;';
310  if (!isValidEmail($email)) {
311  $langs->load("errors");
312  print img_warning($langs->trans("ErrorBadEMail", $email));
313  }
314  } else {
315  print dol_print_email($object->email_from, 0, 0, 0, 0, 1);
316  }
317  }
318  //print dol_print_email($object->email_from, 0, 0, 0, 0, 1);
319  //var_dump($object->email_from);
320  print '</td></tr>';
321 
322  // Errors to
323  if ($object->messtype != 'sms') {
324  print '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
325  $emailarray = CMailFile::getArrayAddress($object->email_errorsto);
326  foreach ($emailarray as $email => $name) {
327  if ($name != $email) {
328  print dol_escape_htmltag($name).' &lt;'.$email;
329  print '&gt;';
330  if (!isValidEmail($email)) {
331  $langs->load("errors");
332  print img_warning($langs->trans("ErrorBadEMail", $email));
333  }
334  } else {
335  print dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1);
336  }
337  }
338  print '</td></tr>';
339  }
340 
341  print '</table>';
342  print '</div>';
343 
344 
345  print '<div class="fichehalfright">';
346  print '<div class="underbanner clearboth"></div>';
347 
348  print '<table class="border centpercent tableforfield">';
349 
350  // Number of distinct emails
351  print '<tr><td>';
352  print $langs->trans("TotalNbOfDistinctRecipients");
353  print '</td><td>';
354  $nbemail = ($object->nbemail ? $object->nbemail : 0);
355  if (is_numeric($nbemail)) {
356  $text = '';
357  if ((getDolGlobalString('MAILING_LIMIT_SENDBYWEB') && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail) && ($object->status == 1 || ($object->status == 2 && $nbtry < $nbemail))) {
358  if (getDolGlobalInt('MAILING_LIMIT_SENDBYWEB') > 0) {
359  $text .= $langs->trans('LimitSendingEmailing', getDolGlobalString('MAILING_LIMIT_SENDBYWEB'));
360  } else {
361  $text .= $langs->trans('SendingFromWebInterfaceIsNotAllowed');
362  }
363  }
364  if (empty($nbemail)) {
365  $nbemail .= ' '.img_warning($langs->trans('ToAddRecipientsChooseHere'));//.' <span class="warning">'.$langs->trans("NoTargetYet").'</span>';
366  }
367  if ($text) {
368  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
369  print $form->textwithpicto($nbemail, $text, 1, 'warning');
370  } else {
371  print $nbemail;
372  }
373  }
374  print '</td></tr>';
375 
376  print '<tr><td>';
377  print $langs->trans("MAIN_MAIL_SENDMODE");
378  print '</td><td>';
379  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') && getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
380  $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING')];
381  } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE')) {
382  $text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE')];
383  } else {
384  $text = $listofmethods['mail'];
385  }
386  print $text;
387  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'default') {
388  if (getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING') != 'mail') {
389  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER_EMAILING').')</span>';
390  }
391  } elseif (getDolGlobalString('MAIN_MAIL_SENDMODE') != 'mail' && getDolGlobalString('MAIN_MAIL_SMTP_SERVER')) {
392  print ' <span class="opacitymedium">('.getDolGlobalString('MAIN_MAIL_SMTP_SERVER').')</span>';
393  }
394  print '</td></tr>';
395 
396  // Other attributes. Fields from hook formObjectOptions and Extrafields.
397  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
398 
399  print '</table>';
400  print '</div>';
401  print '</div>';
402 
403  print '<div class="clearboth"></div>';
404 
405  print dol_get_fiche_end();
406 
407  print '<br>';
408 
409 
410  $newcardbutton = '';
411  $allowaddtarget = ($object->status == $object::STATUS_DRAFT);
412  if (GETPOST('allowaddtarget')) {
413  $allowaddtarget = 1;
414  }
415  if (!$allowaddtarget) {
416  $newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?id='.$object->id.'&allowaddtarget=1', '', $user->hasRight('mailing', 'creer'));
417  }
418 
419  // Show email selectors
420  if ($allowaddtarget && $user->hasRight('mailing', 'creer')) {
421  print load_fiche_titre($langs->trans("ToAddRecipientsChooseHere"), ($user->admin ? info_admin($langs->trans("YouCanAddYourOwnPredefindedListHere"), 1) : ''), 'generic');
422 
423  print '<div class="div-table-responsive">';
424  print '<div class="tagtable centpercentwithout1imp liste_titre_bydiv borderbottom" id="tablelines">';
425 
426  print '<div class="tagtr liste_titre">';
427  print '<div class="tagtd"></div>';
428  print '<div class="tagtd">'.$langs->trans("RecipientSelectionModules").'</div>';
429  print '<div class="tagtd center maxwidth150">';
430  if ($object->messtype != 'sms') {
431  print $langs->trans("NbOfUniqueEMails");
432  } else {
433  print $langs->trans("NbOfUniquePhones");
434  }
435  print '</div>';
436  print '<div class="tagtd left"><div class="inline-block">'.$langs->trans("Filters").'</div>';
437  if ($object->messtype != 'sms') {
438  print ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div class=" inline-block">'.$langs->trans("EvenUnsubscribe").' ';
439  print ajax_object_onoff($object, 'evenunsubscribe', 'evenunsubscribe', 'EvenUnsubscribe:switch_on:warning', 'EvenUnsubscribe', array(), 'small valignmiddle', '', 1);
440  print '</div>';
441  }
442  print '</div>';
443  print '<div class="tagtd">&nbsp;</div>';
444  print '</div>'; // End tr
445 
446  clearstatcache();
447 
448  foreach ($modulesdir as $dir) {
449  $modulenames = array();
450 
451  // Load modules attributes in arrays (name, numero, orders) from dir directory
452  //print $dir."\n<br>";
453  dol_syslog("Scan directory ".$dir." for modules");
454  $handle = @opendir($dir);
455  if (is_resource($handle)) {
456  while (($file = readdir($handle)) !== false) {
457  if (substr($file, 0, 1) != '.' && substr($file, 0, 3) != 'CVS') {
458  $reg = array();
459  if (preg_match("/(.*)\.modules\.php$/i", $file, $reg)) {
460  if ($reg[1] == 'example') {
461  continue;
462  }
463  $modulenames[] = $reg[1];
464  }
465  }
466  }
467  closedir($handle);
468  }
469 
470  // Sort $modulenames
471  sort($modulenames);
472 
473  $var = true;
474 
475  // Loop on each submodule
476  foreach ($modulenames as $modulename) {
477  // Loading Class
478  $file = $dir.$modulename.".modules.php";
479  $classname = "mailing_".$modulename;
480  require_once $file;
481 
482  $obj = new $classname($db);
483 
484  // Check if qualified
485  $qualified = (is_null($obj->enabled) ? 1 : (int) dol_eval($obj->enabled, 1));
486 
487  // Check dependencies
488  foreach ($obj->require_module as $key) {
489  if (empty($conf->$key->enabled) || (empty($user->admin) && $obj->require_admin)) {
490  $qualified = 0;
491  //print "Les prerequis d'activation du module mailing ne sont pas respectes. Il ne sera pas actif";
492  break;
493  }
494  }
495 
496  // If module is qualified
497  if ($qualified) {
498  $var = !$var;
499 
500  if ($allowaddtarget) {
501  print '<form '.$bctag[$var].' name="'.$modulename.'" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&module='.$modulename.'" method="POST" enctype="multipart/form-data">';
502  print '<input type="hidden" name="token" value="'.newToken().'">';
503  print '<input type="hidden" name="action" value="add">';
504  print '<input type="hidden" name="page_y" value="'.newToken().'">';
505  } else {
506  print '<div '.$bctag[$var].'>';
507  }
508 
509  print '<div class="tagtd paddingleftimp marginleftonly paddingrightimp marginrightonly valignmiddle center">';
510  if (empty($obj->picto)) {
511  $obj->picto = 'generic';
512  }
513  print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj), $obj->picto, 'class="valignmiddle width25 size15x"');
514  print '</div>';
515  print '<div class="tagtd valignmiddle">'; // style="height: 4em"
516  print $obj->getDesc();
517  print '</div>';
518 
519  try {
520  $obj->evenunsubscribe = $object->evenunsubscribe; // Set flag to include/exclude email that has opt-out.
521 
522  $nbofrecipient = $obj->getNbOfRecipients('');
523  } catch (Exception $e) {
524  dol_syslog($e->getMessage(), LOG_ERR);
525  }
526 
527  print '<div class="tagtd center valignmiddle">';
528  if ($nbofrecipient === '' || $nbofrecipient >= 0) {
529  print $nbofrecipient;
530  } else {
531  print $langs->trans("Error").' '.img_error($obj->error);
532  }
533  print '</div>';
534 
535  print '<div class="tagtd left valignmiddle">';
536  if ($allowaddtarget) {
537  try {
538  $filter = $obj->formFilter();
539  } catch (Exception $e) {
540  dol_syslog($e->getMessage(), LOG_ERR);
541  }
542  if ($filter) {
543  print $filter;
544  } else {
545  print $langs->trans("None");
546  }
547  }
548  print '</div>';
549 
550  print '<div class="tagtd right valignmiddle">';
551  if ($allowaddtarget) {
552  print '<input type="submit" class="button button-add small reposition" name="button_'.$modulename.'" value="'.$langs->trans("Add").'">';
553  } else {
554  print '<input type="submit" class="button small disabled" disabled="disabled" name="button_'.$modulename.'" value="'.$langs->trans("Add").'">';
555  //print $langs->trans("MailNoChangePossible");
556  print "&nbsp;";
557  }
558  print '</div>';
559 
560  if ($allowaddtarget) {
561  print '</form>';
562  } else {
563  print '</div>';
564  }
565  }
566  }
567  } // End foreach dir
568 
569  $parameters = array();
570  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
571  print $hookmanager->resPrint;
572 
573  print '</div>'; // End table
574  print '</div>';
575 
576  print '<br>';
577 
578  if ($sqlmessage && $user->admin) {
579  print info_admin($langs->trans("SQLUsedForExport").':<br> '.$sqlmessage, 0, 0, 1, '', 'TechnicalInformation');
580  print '<br>';
581  }
582 
583  print '<br>';
584  }
585 
586  // List of selected targets
587  $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut as status, mc.date_envoi, mc.tms,";
588  $sql .= " mc.source_url, mc.source_id, mc.source_type, mc.error_text,";
589  $sql .= " COUNT(mu.rowid) as nb";
590  $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
591  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."mailing_unsubscribe as mu ON mu.email = mc.email";
592  $sql .= " WHERE mc.fk_mailing=".((int) $object->id);
593  $asearchcriteriahasbeenset = 0;
594  if ($search_lastname) {
595  $sql .= natural_search("mc.lastname", $search_lastname);
596  $asearchcriteriahasbeenset++;
597  }
598  if ($search_firstname) {
599  $sql .= natural_search("mc.firstname", $search_firstname);
600  $asearchcriteriahasbeenset++;
601  }
602  if ($search_email) {
603  $sql .= natural_search("mc.email", $search_email);
604  $asearchcriteriahasbeenset++;
605  }
606  if ($search_other) {
607  $sql .= natural_search("mc.other", $search_other);
608  $asearchcriteriahasbeenset++;
609  }
610  if ($search_dest_status != '' && (int) $search_dest_status >= -1) {
611  $sql .= " AND mc.statut = ".((int) $search_dest_status);
612  $asearchcriteriahasbeenset++;
613  }
614  $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';
615  $sql .= $db->order($sortfield, $sortorder);
616 
617 
618  // Count total nb of records
619  $nbtotalofrecords = '';
620  if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
621  $result = $db->query($sql);
622  $nbtotalofrecords = $db->num_rows($result);
623  if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
624  $page = 0;
625  $offset = 0;
626  }
627 
628  // Fix/update nbemail on emailing record if it differs (may happen if user edit lines from database directly)
629  if (empty($asearchcriteriahasbeenset)) {
630  if ($nbtotalofrecords != $object->nbemail) {
631  dol_syslog("We found a difference in nb of record in target table and the property ->nbemail, we fix ->nbemail");
632  //print "nbemail=".$object->nbemail." nbtotalofrecords=".$nbtotalofrecords;
633  $resultrefresh = $object->refreshNbOfTargets();
634  if ($resultrefresh < 0) {
635  dol_print_error($db, $object->error, $object->errors);
636  }
637  }
638  }
639  }
640 
641  //$nbtotalofrecords=$object->nbemail; // nbemail is a denormalized field storing nb of targets
642  $sql .= $db->plimit($limit + 1, $offset);
643 
644  $resql = $db->query($sql);
645  if ($resql) {
646  $num = $db->num_rows($resql);
647 
648  $param = "&id=".$object->id;
649  //if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
650  if ($limit > 0 && $limit != $conf->liste_limit) {
651  $param .= '&limit='.((int) $limit);
652  }
653  if ($search_lastname) {
654  $param .= "&search_lastname=".urlencode($search_lastname);
655  }
656  if ($search_firstname) {
657  $param .= "&search_firstname=".urlencode($search_firstname);
658  }
659  if ($search_email) {
660  $param .= "&search_email=".urlencode($search_email);
661  }
662  if ($search_other) {
663  $param .= "&search_other=".urlencode($search_other);
664  }
665 
666  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
667  print '<input type="hidden" name="token" value="'.newToken().'">';
668  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
669  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
670  print '<input type="hidden" name="page" value="'.$page.'">';
671  print '<input type="hidden" name="id" value="'.$object->id.'">';
672  print '<input type="hidden" name="page_y" value="">';
673 
674  $morehtmlcenter = '';
675  if ($object->status == $object::STATUS_DRAFT) {
676  $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>';
677  }
678  $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>';
679 
680  $massactionbutton = '';
681 
682  // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
683  print_barre_liste($langs->trans("MailSelectedRecipients"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $morehtmlcenter, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit, 0, 0, 1);
684 
685  print '</form>';
686 
687  print "\n<!-- Liste destinataires selectionnes -->\n";
688  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
689  print '<input type="hidden" name="token" value="'.newToken().'">';
690  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
691  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
692  print '<input type="hidden" name="page" value="'.$page.'">';
693  print '<input type="hidden" name="id" value="'.$object->id.'">';
694  print '<input type="hidden" name="limit" value="'.$limit.'">';
695  print '<input type="hidden" name="page_y" value="">';
696 
697  print '<div class="div-table-responsive">';
698  print '<table class="noborder centpercent">';
699 
700  // Ligne des champs de filtres
701  print '<tr class="liste_titre_filter">';
702 
703  // Action column
704  if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
705  print '<td class="liste_titre maxwidthsearch">';
706  $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
707  print $searchpicto;
708  print '</td>';
709  }
710  // EMail
711  print '<td class="liste_titre">';
712  print '<input class="flat maxwidth75" type="text" name="search_email" value="'.dol_escape_htmltag($search_email).'">';
713  print '</td>';
714  // Name
715  print '<td class="liste_titre">';
716  print '<input class="flat maxwidth50" type="text" name="search_lastname" value="'.dol_escape_htmltag($search_lastname).'">';
717  print '</td>';
718  // Firstname
719  print '<td class="liste_titre">';
720  print '<input class="flat maxwidth50" type="text" name="search_firstname" value="'.dol_escape_htmltag($search_firstname).'">';
721  print '</td>';
722  // Other
723  print '<td class="liste_titre">';
724  print '<input class="flat maxwidth100" type="text" name="search_other" value="'.dol_escape_htmltag($search_other).'">';
725  print '</td>';
726  // Source
727  print '<td class="liste_titre">';
728  print '&nbsp;';
729  print '</td>';
730 
731  // Date last update
732  print '<td class="liste_titre">';
733  print '&nbsp;';
734  print '</td>';
735 
736  // Date sending
737  print '<td class="liste_titre">';
738  print '&nbsp;';
739  print '</td>';
740 
741  // Status
742  print '<td class="liste_titre center parentonrightofpage">';
743  print $formmailing->selectDestinariesStatus($search_dest_status, 'search_dest_status', 1, 'width100 onrightofpage');
744  print '</td>';
745 
746  // Action column
747  if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
748  print '<td class="liste_titre maxwidthsearch">';
749  $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
750  print $searchpicto;
751  print '</td>';
752  }
753 
754  print '</tr>';
755 
756  if ($page) {
757  $param .= "&page=".urlencode((string) ($page));
758  }
759 
760  print '<tr class="liste_titre">';
761  // Action column
762  if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
763  print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch ');
764  }
765  print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "mc.email", $param, "", "", $sortfield, $sortorder);
766  print_liste_field_titre("Lastname", $_SERVER["PHP_SELF"], "mc.lastname", $param, "", "", $sortfield, $sortorder);
767  print_liste_field_titre("Firstname", $_SERVER["PHP_SELF"], "mc.firstname", $param, "", "", $sortfield, $sortorder);
768  print_liste_field_titre("OtherInformations", $_SERVER["PHP_SELF"], "", $param, "", "", $sortfield, $sortorder);
769  print_liste_field_titre("Source", $_SERVER["PHP_SELF"], "", $param, "", '', $sortfield, $sortorder, 'center ');
770  // Date last update
771  print_liste_field_titre("DateLastModification", $_SERVER["PHP_SELF"], "mc.tms", $param, "", '', $sortfield, $sortorder, 'center ');
772  // Date sending
773  print_liste_field_titre("DateSending", $_SERVER["PHP_SELF"], "mc.date_envoi", $param, '', '', $sortfield, $sortorder, 'center ');
774  print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "mc.statut", $param, '', '', $sortfield, $sortorder, 'center ');
775  // Action column
776  if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
777  print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch ');
778  }
779  print '</tr>';
780 
781  $i = 0;
782 
783  if ($num) {
784  include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
785  include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
786  include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
787  include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
788  include_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
789 
790  $objectstaticmember = new Adherent($db);
791  $objectstaticuser = new User($db);
792  $objectstaticcompany = new Societe($db);
793  $objectstaticcontact = new Contact($db);
794  $objectstaticeventorganization = new ConferenceOrBoothAttendee($db);
795 
796  while ($i < min($num, $limit)) {
797  $obj = $db->fetch_object($resql);
798 
799  print '<tr class="oddeven">';
800 
801  // Action column
802  if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
803  print '<td class="center">';
804  print '<!-- ID mailing_cibles = '.$obj->rowid.' -->';
805  if ($obj->status == $object::STATUS_DRAFT) { // Not sent yet
806  if ($user->hasRight('mailing', 'creer')) {
807  print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&rowid='.((int) $obj->rowid).$param.'">'.img_delete($langs->trans("RemoveRecipient")).'</a>';
808  }
809  }
810  /*if ($obj->status == -1) // Sent with error
811  {
812  print '<a href="'.$_SERVER['PHP_SELF'].'?action=retry&rowid='.$obj->rowid.$param.'">'.$langs->trans("Retry").'</a>';
813  }*/
814  print '</td>';
815  }
816 
817  print '<td class="tdoverflowmax150">';
818  print img_picto($obj->email, 'email', 'class="paddingright"');
819  if ($obj->nb > 0) {
820  print img_warning($langs->trans("EmailOptedOut"), 'warning', 'pictofixedwidth');
821  }
822  print dol_escape_htmltag($obj->email);
823  print '</td>';
824 
825  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->lastname).'">'.dol_escape_htmltag($obj->lastname).'</td>';
826 
827  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->firstname).'">'.dol_escape_htmltag($obj->firstname).'</td>';
828 
829  print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($obj->other).'"><span class="small">'.dol_escape_htmltag($obj->other).'</small></td>';
830 
831  print '<td class="center tdoverflowmax150">';
832  if (empty($obj->source_id) || empty($obj->source_type)) {
833  print empty($obj->source_url) ? '' : $obj->source_url; // For backward compatibility
834  } else {
835  if ($obj->source_type == 'member') {
836  $objectstaticmember->fetch($obj->source_id);
837  print $objectstaticmember->getNomUrl(1);
838  } elseif ($obj->source_type == 'user') {
839  $objectstaticuser->fetch($obj->source_id);
840  print $objectstaticuser->getNomUrl(1);
841  } elseif ($obj->source_type == 'thirdparty') {
842  $objectstaticcompany->fetch($obj->source_id);
843  print $objectstaticcompany->getNomUrl(1);
844  } elseif ($obj->source_type == 'contact') {
845  $objectstaticcontact->fetch($obj->source_id);
846  print $objectstaticcontact->getNomUrl(1);
847  } elseif ($obj->source_type == 'eventorganizationattendee') {
848  $objectstaticeventorganization->fetch($obj->source_id);
849  print $objectstaticeventorganization->getNomUrl(1);
850  } else {
851  print $obj->source_url;
852  }
853  }
854  print '</td>';
855 
856  // Date last update
857  print '<td class="center nowraponall">';
858  print dol_print_date(dol_stringtotime($obj->tms), 'dayhour');
859  print '</td>';
860 
861  // Date sent
862  print '<td class="center nowraponall">';
863  if ($obj->status != $object::STATUS_DRAFT) {
864  // Date sent
865  print $obj->date_envoi;
866  }
867  print '</td>';
868 
869  // Status of recipient sending email (Warning != status of emailing)
870  print '<td class="nowrap center">';
871  if ($obj->status == $object::STATUS_DRAFT) {
872  print $object::libStatutDest($obj->status, 2, '');
873  } else {
874  print $object::libStatutDest($obj->status, 2, $obj->error_text);
875  }
876  print '</td>';
877 
878  // Action column
879  if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
880  print '<td class="center">';
881  print '<!-- ID mailing_cibles = '.$obj->rowid.' -->';
882  if ($obj->status == $object::STATUS_DRAFT) { // Not sent yet
883  if ($user->hasRight('mailing', 'creer')) {
884  print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&rowid='.((int) $obj->rowid).$param.'">'.img_delete($langs->trans("RemoveRecipient")).'</a>';
885  }
886  }
887  /*if ($obj->status == -1) // Sent with error
888  {
889  print '<a href="'.$_SERVER['PHP_SELF'].'?action=retry&rowid='.$obj->rowid.$param.'">'.$langs->trans("Retry").'</a>';
890  }*/
891  print '</td>';
892  }
893  print '</tr>';
894 
895  $i++;
896  }
897  } else {
898  if ($object->status < $object::STATUS_SENTPARTIALY) {
899  print '<tr><td colspan="9">';
900  print '<span class="opacitymedium">'.$langs->trans("NoTargetYet").'</span>';
901  print '</td></tr>';
902  } else {
903  print '<tr><td colspan="9">';
904  print '<span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span>';
905  print '</td></tr>';
906  }
907  }
908  print "</table><br>";
909  print '</div>';
910 
911  print '</form>';
912 
913  $db->free($resql);
914  } else {
915  dol_print_error($db);
916  }
917 
918  print "\n<!-- Fin liste destinataires selectionnes -->\n";
919 }
920 
921 // End of page
922 llxFooter();
923 $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)
On/off button to change a property status of an object This uses the ajax service objectonoff....
Definition: ajax.lib.php:722
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 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.
Definition: user.class.php:50
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
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.
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.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information in HTML for admin users or standard users.
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...
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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.