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