dolibarr 21.0.0-alpha
modules_mailings.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
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 * or see https://www.gnu.org/
20 */
21
27require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
28
29
33class MailingTargets // This can't be abstract as it is used for some method
34{
38 public $db;
39
43 public $error = '';
44
48 public $errors;
49
53 public $enabled;
54
58 public $name;
59
63 public $desc;
64
68 public $tooltip = '';
69
73 public $sql;
74
75
76 public $evenunsubscribe = 0; // Set this to 1 if you want to flag you also want to include email in target that has opt-out.
77
78
84 public function __construct($db)
85 {
86 $this->db = $db;
87 }
88
94 public function getDesc()
95 {
96 global $langs, $form;
97
98 $langs->load("mails");
99 $transstring = "MailingModuleDesc".$this->name;
100 $s = '';
101
102 if ($langs->trans($this->name) != $this->name) {
103 $s = $langs->trans($this->name);
104 } elseif ($langs->trans($transstring) != $transstring) {
105 $s = $langs->trans($transstring);
106 } else {
107 $s = $this->desc;
108 }
109
110 if ($this->tooltip && is_object($form)) {
111 $s .= ' '.$form->textwithpicto('', $langs->trans($this->tooltip), 1, 1);
112 }
113 return $s;
114 }
115
121 public function getNbOfRecords()
122 {
123 return 0;
124 }
125
132 public function getNbOfRecipients($sql)
133 {
134 $result = $this->db->query($sql);
135 if ($result) {
136 $total = 0;
137 while ($obj = $this->db->fetch_object($result)) {
138 $total += $obj->nb;
139 }
140 return $total;
141 } else {
142 $this->error = $this->db->lasterror();
143 return -1;
144 }
145 }
146
153 public function formFilter()
154 {
155 return '';
156 }
157
158 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
165 public function update_nb($mailing_id)
166 {
167 // phpcs:enable
168 // Mise a jour nombre de destinataire dans table des mailings
169 $sql = "SELECT COUNT(*) nb FROM ".MAIN_DB_PREFIX."mailing_cibles";
170 $sql .= " WHERE fk_mailing = ".((int) $mailing_id);
171 $result = $this->db->query($sql);
172 if ($result) {
173 $obj = $this->db->fetch_object($result);
174 $nb = $obj->nb;
175
176 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing";
177 $sql .= " SET nbemail = ".((int) $nb)." WHERE rowid = ".((int) $mailing_id);
178 if (!$this->db->query($sql)) {
179 dol_syslog($this->db->error());
180 $this->error = $this->db->error();
181 return -1;
182 }
183 } else {
184 return -1;
185 }
186 return $nb;
187 }
188
196 public function addTargetsToDatabase($mailing_id, $cibles)
197 {
198 global $conf;
199
200 $this->db->begin();
201
202 // Insert emailing targets from array into database
203 $j = 0;
204 $num = count($cibles);
205 foreach ($cibles as $targetarray) {
206 if (!empty($targetarray['email'])) { // avoid empty email address
207 $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_cibles";
208 $sql .= " (fk_mailing,";
209 $sql .= " fk_contact,";
210 $sql .= " lastname, firstname, email, other, source_url, source_id,";
211 $sql .= " tag,";
212 $sql .= " source_type)";
213 $sql .= " VALUES (".((int) $mailing_id).",";
214 $sql .= (empty($targetarray['fk_contact']) ? '0' : (int) $targetarray['fk_contact']).",";
215 $sql .= "'".$this->db->escape($targetarray['lastname'])."',";
216 $sql .= "'".$this->db->escape($targetarray['firstname'])."',";
217 $sql .= "'".$this->db->escape($targetarray['email'])."',";
218 $sql .= "'".$this->db->escape($targetarray['other'])."',";
219 $sql .= "'".$this->db->escape($targetarray['source_url'])."',";
220 $sql .= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").",";
221 $sql .= "'".$this->db->escape(dol_hash($conf->file->instance_unique_id.";".$targetarray['email'].";".$targetarray['lastname'].";".((int) $mailing_id).";".getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY'), 'md5'))."',";
222 $sql .= "'".$this->db->escape($targetarray['source_type'])."')";
223 dol_syslog(__METHOD__, LOG_DEBUG);
224 $result = $this->db->query($sql);
225 if ($result) {
226 $j++;
227 } else {
228 if ($this->db->errno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') {
229 // Si erreur autre que doublon
230 dol_syslog($this->db->error().' : '.$targetarray['email']);
231 $this->error = $this->db->error().' : '.$targetarray['email'];
232 $this->db->rollback();
233 return -1;
234 }
235 }
236 }
237 }
238
239 dol_syslog(__METHOD__.": mailing ".$j." targets added");
240
241 /*
242 //Update the status to show thirdparty mail that don't want to be contacted anymore'
243 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
244 $sql .= " SET statut=3";
245 $sql .= " WHERE fk_mailing = ".((int) $mailing_id)." AND email in (SELECT email FROM ".MAIN_DB_PREFIX."societe where fk_stcomm=-1)";
246 $sql .= " AND source_type='thirdparty'";
247 dol_syslog(__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted");
248 $result=$this->db->query($sql);
249
250 //Update the status to show contact mail that don't want to be contacted anymore'
251 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
252 $sql .= " SET statut=3";
253 $sql .= " WHERE fk_mailing = ".((int) $mailing_id)." AND source_type='contact' AND (email in (SELECT sc.email FROM ".MAIN_DB_PREFIX."socpeople AS sc ";
254 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid=sc.fk_soc WHERE s.fk_stcomm=-1 OR no_email=1))";
255 dol_syslog(__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG);
256 $result=$this->db->query($sql);
257 */
258
259 if (empty($this->evenunsubscribe)) {
260 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles as mc";
261 $sql .= " SET mc.statut = 3";
262 $sql .= " WHERE mc.fk_mailing = ".((int) $mailing_id);
263 $sql .= " AND EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = mc.email and mu.entity = ".((int) $conf->entity).")";
264
265 dol_syslog(__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG);
266 $result = $this->db->query($sql);
267 if (!$result) {
268 dol_print_error($this->db);
269 }
270 }
271
272 // Update nb of recipient into emailing record
273 $this->update_nb($mailing_id);
274
275 $this->db->commit();
276
277 return $j;
278 }
279
280 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
287 public function clear_target($mailing_id)
288 {
289 // phpcs:enable
290 $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
291 $sql .= " WHERE fk_mailing = ".((int) $mailing_id);
292
293 if (!$this->db->query($sql)) {
294 dol_syslog($this->db->error());
295 }
296
297 $this->update_nb($mailing_id);
298 }
299
300
308 public static function getEmailingSelectorsList($forcedir = null)
309 {
310 global $langs, $db;
311
312 $files = array();
313 $fullpath = array();
314 $relpath = array();
315 $iscoreorexternal = array();
316 $modules = array();
317 $orders = array();
318 $i = 0;
319
320 $diremailselector = array('/core/modules/mailings/'); // $conf->modules_parts['emailings'] is not required
321 if (is_array($forcedir)) {
322 $diremailselector = $forcedir;
323 }
324
325 foreach ($diremailselector as $reldir) {
326 $dir = dol_buildpath($reldir, 0);
327 $newdir = dol_osencode($dir);
328
329 // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
330 if (!is_dir($newdir)) {
331 continue;
332 }
333
334 $handle = opendir($newdir);
335 if (is_resource($handle)) {
336 while (($file = readdir($handle)) !== false) {
337 $reg = array();
338 if (is_readable($newdir.'/'.$file) && preg_match('/^(.+)\.modules.php/', $file, $reg)) {
339 if (preg_match('/\.back$/', $file) || preg_match('/^(.+)\.disabled\.php/', $file)) {
340 continue;
341 }
342
343 $part1 = $reg[1];
344
345 //$modName = ucfirst($reg[1]);
346 $modName = 'mailing_'.$reg[1]; // name of selector submodule
347 //print "file=$file modName=$modName"; exit;
348 if (in_array($modName, $modules)) {
349 $langs->load("errors");
350 print '<div class="error">'.$langs->trans("Error").' : '.$langs->trans("ErrorDuplicateEmalingSelector", $modName, "").'</div>';
351 } else {
352 try {
353 //print $newdir.'/'.$file;
354 include_once $newdir.'/'.$file;
355 } catch (Exception $e) {
356 print $e->getMessage();
357 }
358 }
359
360 $files[$i] = $file;
361 $fullpath[$i] = $dir.'/'.$file;
362 $relpath[$i] = preg_replace('/^\//', '', $reldir).'/'.$file;
363 $iscoreorexternal[$i] = ($reldir == '/core/modules/mailings/' ? 'internal' : 'external');
364 $modules[$i] = $modName;
365 $orders[$i] = $part1; // Set sort criteria value
366
367 $i++;
368 }
369 }
370 closedir($handle);
371 }
372 }
373 //echo "<pre>";print_r($modules);echo "</pre>";
374
375 asort($orders);
376
377 $widget = array();
378 $j = 0;
379
380 // Loop on each emailing selector
381 foreach ($orders as $key => $value) {
382 $modName = $modules[$key];
383 if (empty($modName)) {
384 continue;
385 }
386
387 if (!class_exists($modName)) {
388 print 'Error: An emailing selector file was found but its class "'.$modName.'" was not found.'."<br>\n";
389 continue;
390 }
391
392 $objMod = new $modName($db);
393 if (is_object($objMod)) {
394 '@phan-var-force ModeleBoxes $objMod';
395 // Define disabledbyname and disabledbymodule
396 $disabledbyname = 0;
397 $disabledbymodule = 0; // TODO Set to 2 if module is not enabled
398 $module = '';
399
400 // Check if widget file is disabled by name
401 if (preg_match('/NORUN$/i', $files[$key])) {
402 $disabledbyname = 1;
403 }
404
405 // We set info of modules @phan-suppress-next-line PhanUndeclaredProperty
406 $widget[$j]['picto'] = (empty($objMod->picto) ? (empty($objMod->boximg) ? img_object('', 'generic') : $objMod->boximg) : img_object('', $objMod->picto));
407 $widget[$j]['file'] = $files[$key];
408 $widget[$j]['fullpath'] = $fullpath[$key];
409 $widget[$j]['relpath'] = $relpath[$key];
410 $widget[$j]['iscoreorexternal'] = $iscoreorexternal[$key];
411 $widget[$j]['version'] = empty($objMod->version) ? '' : $objMod->version;
412 $widget[$j]['status'] = img_picto($langs->trans("Active"), 'tick');
413 if ($disabledbyname > 0 || $disabledbymodule > 1) {
414 $widget[$j]['status'] = '';
415 }
416
417 $text = '<b>'.$langs->trans("Description").':</b><br>';
418 $text .= $objMod->boxlabel.'<br>';
419 $text .= '<br><b>'.$langs->trans("Status").':</b><br>';
420 if ($disabledbymodule == 2) {
421 $text .= $langs->trans("WidgetDisabledAsModuleDisabled", $module).'<br>';
422 }
423
424 $widget[$j]['info'] = $text;
425 }
426 $j++;
427 }
428
429 return $widget;
430 }
431
432
441 public function getSqlArrayForStats()
442 {
443 // Needs to be implemented in child class
444 $msg = get_class($this)."::".__FUNCTION__." not implemented";
445 dol_syslog($msg, LOG_ERR);
446 return array();
447 }
448}
Parent class of emailing target selectors modules.
__construct($db)
Constructor.
static getEmailingSelectorsList($forcedir=null)
Return list of widget.
addTargetsToDatabase($mailing_id, $cibles)
Add a list of targets into the database.
getDesc()
Return description of email selector.
getNbOfRecipients($sql)
Retourne nombre de destinataires.
clear_target($mailing_id)
Supprime tous les destinataires de la table des cibles.
update_nb($mailing_id)
Met a jour nombre de destinataires.
formFilter()
Affiche formulaire de filtre qui apparait dans page de selection des destinataires de mailings.
getNbOfRecords()
Return number of records for email selector.
getSqlArrayForStats()
On the main mailing area, there is a box with statistics.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.