dolibarr 21.0.0-beta
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
79 public $evenunsubscribe = 0;
80
81
87 public function __construct($db)
88 {
89 $this->db = $db;
90 }
91
97 public function getDesc()
98 {
99 global $langs, $form;
100
101 $langs->load("mails");
102 $transstring = "MailingModuleDesc".$this->name;
103 $s = '';
104
105 if ($langs->trans($this->name) != $this->name) {
106 $s = $langs->trans($this->name);
107 } elseif ($langs->trans($transstring) != $transstring) {
108 $s = $langs->trans($transstring);
109 } else {
110 $s = $this->desc;
111 }
112
113 if ($this->tooltip && is_object($form)) {
114 $s .= ' '.$form->textwithpicto('', $langs->trans($this->tooltip), 1, 1);
115 }
116 return $s;
117 }
118
124 public function getNbOfRecords()
125 {
126 return 0;
127 }
128
135 public function getNbOfRecipients($sql)
136 {
137 $result = $this->db->query($sql);
138 if ($result) {
139 $total = 0;
140 while ($obj = $this->db->fetch_object($result)) {
141 $total += $obj->nb;
142 }
143 return $total;
144 } else {
145 $this->error = $this->db->lasterror();
146 return -1;
147 }
148 }
149
156 public function formFilter()
157 {
158 return '';
159 }
160
161 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
168 public function update_nb($mailing_id)
169 {
170 // phpcs:enable
171 // Mise a jour nombre de destinataire dans table des mailings
172 $sql = "SELECT COUNT(*) nb FROM ".MAIN_DB_PREFIX."mailing_cibles";
173 $sql .= " WHERE fk_mailing = ".((int) $mailing_id);
174 $result = $this->db->query($sql);
175 if ($result) {
176 $obj = $this->db->fetch_object($result);
177 $nb = $obj->nb;
178
179 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing";
180 $sql .= " SET nbemail = ".((int) $nb)." WHERE rowid = ".((int) $mailing_id);
181 if (!$this->db->query($sql)) {
182 dol_syslog($this->db->error());
183 $this->error = $this->db->error();
184 return -1;
185 }
186 } else {
187 return -1;
188 }
189 return $nb;
190 }
191
199 public function addTargetsToDatabase($mailing_id, $cibles)
200 {
201 global $conf;
202
203 $this->db->begin();
204
205
206 // Insert emailing targets from array into database
207 $j = 0;
208 $num = count($cibles);
209 foreach ($cibles as $targetarray) {
210 if (!empty($targetarray['email'])) { // avoid empty email address
211 $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_cibles";
212 $sql .= " (fk_mailing,";
213 $sql .= " fk_contact,";
214 $sql .= " lastname, firstname, email, other, source_url, source_id,";
215 $sql .= " tag,";
216 $sql .= " source_type)";
217 $sql .= " VALUES (".((int) $mailing_id).",";
218 $sql .= (empty($targetarray['fk_contact']) ? '0' : (int) $targetarray['fk_contact']).",";
219 $sql .= "'".$this->db->escape($targetarray['lastname'])."',";
220 $sql .= "'".$this->db->escape($targetarray['firstname'])."',";
221 $sql .= "'".$this->db->escape($targetarray['email'])."',";
222 $sql .= "'".$this->db->escape($targetarray['other'])."',";
223 $sql .= "'".$this->db->escape($targetarray['source_url'])."',";
224 $sql .= (empty($targetarray['source_id']) ? 'null' : (int) $targetarray['source_id']).",";
225 $sql .= "'".$this->db->escape(dol_hash($conf->file->instance_unique_id.";".$targetarray['email'].";".$targetarray['lastname'].";".((int) $mailing_id).";".getDolGlobalString('MAILING_EMAIL_UNSUBSCRIBE_KEY'), 'md5'))."',";
226 $sql .= "'".$this->db->escape($targetarray['source_type'])."')";
227 dol_syslog(__METHOD__, LOG_DEBUG);
228 $result = $this->db->query($sql);
229 if ($result) {
230 $j++;
231 } else {
232 if ($this->db->errno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') {
233 // Si erreur autre que doublon
234 dol_syslog($this->db->error().' : '.$targetarray['email']);
235 $this->error = $this->db->error().' : '.$targetarray['email'];
236 $this->db->rollback();
237 return -1;
238 }
239 }
240 }
241 }
242
243 dol_syslog(__METHOD__.": mailing ".$j." targets added");
244
245 /*
246 //Update the status to show thirdparty mail that don't want to be contacted anymore'
247 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
248 $sql .= " SET statut=3";
249 $sql .= " WHERE fk_mailing = ".((int) $mailing_id)." AND email in (SELECT email FROM ".MAIN_DB_PREFIX."societe where fk_stcomm=-1)";
250 $sql .= " AND source_type='thirdparty'";
251 dol_syslog(__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted");
252 $result=$this->db->query($sql);
253
254 //Update the status to show contact mail that don't want to be contacted anymore'
255 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
256 $sql .= " SET statut=3";
257 $sql .= " WHERE fk_mailing = ".((int) $mailing_id)." AND source_type='contact' AND (email in (SELECT sc.email FROM ".MAIN_DB_PREFIX."socpeople AS sc ";
258 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid=sc.fk_soc WHERE s.fk_stcomm=-1 OR no_email=1))";
259 dol_syslog(__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG);
260 $result=$this->db->query($sql);
261 */
262
263 if (empty($this->evenunsubscribe)) {
264 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles as mc";
265 $sql .= " SET mc.statut = 3";
266 $sql .= " WHERE mc.fk_mailing = ".((int) $mailing_id);
267 $sql .= " AND EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = mc.email and mu.entity = ".((int) $conf->entity).")";
268
269 dol_syslog(__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG);
270 $result = $this->db->query($sql);
271 if (!$result) {
272 dol_print_error($this->db);
273 }
274 }
275
276 // Update nb of recipient into emailing record
277 $this->update_nb($mailing_id);
278
279 $this->db->commit();
280
281 return $j;
282 }
283
284 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
291 public function clear_target($mailing_id)
292 {
293 // phpcs:enable
294 $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
295 $sql .= " WHERE fk_mailing = ".((int) $mailing_id);
296
297 if (!$this->db->query($sql)) {
298 dol_syslog($this->db->error());
299 }
300
301 $this->update_nb($mailing_id);
302 }
303
304
312 public static function getEmailingSelectorsList($forcedir = null)
313 {
314 global $langs, $db;
315
316 $files = array();
317 $fullpath = array();
318 $relpath = array();
319 $iscoreorexternal = array();
320 $modules = array();
321 $orders = array();
322 $i = 0;
323
324 $diremailselector = array('/core/modules/mailings/'); // $conf->modules_parts['emailings'] is not required
325 if (is_array($forcedir)) {
326 $diremailselector = $forcedir;
327 }
328
329 foreach ($diremailselector as $reldir) {
330 $dir = dol_buildpath($reldir, 0);
331 $newdir = dol_osencode($dir);
332
333 // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
334 if (!is_dir($newdir)) {
335 continue;
336 }
337
338 $handle = opendir($newdir);
339 if (is_resource($handle)) {
340 while (($file = readdir($handle)) !== false) {
341 $reg = array();
342 if (is_readable($newdir.'/'.$file) && preg_match('/^(.+)\.modules.php/', $file, $reg)) {
343 if (preg_match('/\.back$/', $file) || preg_match('/^(.+)\.disabled\.php/', $file)) {
344 continue;
345 }
346
347 $part1 = $reg[1];
348
349 //$modName = ucfirst($reg[1]);
350 $modName = 'mailing_'.$reg[1]; // name of selector submodule
351 //print "file=$file modName=$modName"; exit;
352 if (in_array($modName, $modules)) {
353 $langs->load("errors");
354 print '<div class="error">'.$langs->trans("Error").' : '.$langs->trans("ErrorDuplicateEmalingSelector", $modName, "").'</div>';
355 } else {
356 try {
357 //print $newdir.'/'.$file;
358 include_once $newdir.'/'.$file;
359 } catch (Exception $e) {
360 print $e->getMessage();
361 }
362 }
363
364 $files[$i] = $file;
365 $fullpath[$i] = $dir.'/'.$file;
366 $relpath[$i] = preg_replace('/^\//', '', $reldir).'/'.$file;
367 $iscoreorexternal[$i] = ($reldir == '/core/modules/mailings/' ? 'internal' : 'external');
368 $modules[$i] = $modName;
369 $orders[$i] = $part1; // Set sort criteria value
370
371 $i++;
372 }
373 }
374 closedir($handle);
375 }
376 }
377 //echo "<pre>";print_r($modules);echo "</pre>";
378
379 asort($orders);
380
381 $widget = array();
382 $j = 0;
383
384 // Loop on each emailing selector
385 foreach ($orders as $key => $value) {
386 $modName = $modules[$key];
387 if (empty($modName)) {
388 continue;
389 }
390
391 if (!class_exists($modName)) {
392 print 'Error: An emailing selector file was found but its class "'.$modName.'" was not found.'."<br>\n";
393 continue;
394 }
395
396 $objMod = new $modName($db);
397 if (is_object($objMod)) {
398 '@phan-var-force ModeleBoxes $objMod';
399 // Define disabledbyname and disabledbymodule
400 $disabledbyname = 0;
401 $disabledbymodule = 0; // TODO Set to 2 if module is not enabled
402 $module = '';
403
404 // Check if widget file is disabled by name
405 if (preg_match('/NORUN$/i', $files[$key])) {
406 $disabledbyname = 1;
407 }
408
409 // We set info of modules @phan-suppress-next-line PhanUndeclaredProperty
410 $widget[$j]['picto'] = (empty($objMod->picto) ? (empty($objMod->boximg) ? img_object('', 'generic') : $objMod->boximg) : img_object('', $objMod->picto));
411 $widget[$j]['file'] = $files[$key];
412 $widget[$j]['fullpath'] = $fullpath[$key];
413 $widget[$j]['relpath'] = $relpath[$key];
414 $widget[$j]['iscoreorexternal'] = $iscoreorexternal[$key];
415 $widget[$j]['version'] = empty($objMod->version) ? '' : $objMod->version;
416 $widget[$j]['status'] = img_picto($langs->trans("Active"), 'tick');
417 if ($disabledbyname > 0 || $disabledbymodule > 1) {
418 $widget[$j]['status'] = '';
419 }
420
421 $text = '<b>'.$langs->trans("Description").':</b><br>';
422 $text .= $objMod->boxlabel.'<br>';
423 $text .= '<br><b>'.$langs->trans("Status").':</b><br>';
424 if ($disabledbymodule == 2) {
425 $text .= $langs->trans("WidgetDisabledAsModuleDisabled", $module).'<br>';
426 }
427
428 $widget[$j]['info'] = $text;
429 }
430 $j++;
431 }
432
433 return $widget;
434 }
435
436
445 public function getSqlArrayForStats()
446 {
447 // Needs to be implemented in child class
448 $msg = get_class($this)."::".__FUNCTION__." not implemented";
449 dol_syslog($msg, LOG_ERR);
450 return array();
451 }
452
453 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
460 public function add_to_target($mailing_id)
461 {
462 // phpcs:enable
463 // Needs to be implemented in child class
464 $msg = get_class($this)."::".__FUNCTION__." not implemented";
465 dol_syslog($msg, LOG_ERR);
466 return -1;
467 }
468}
Parent class of emailing target selectors modules.
__construct($db)
Constructor.
add_to_target($mailing_id)
Add destinations in the targets table.
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:152
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.