dolibarr 24.0.0-beta
mailing.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7 * Copyright (C) 2025 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
29require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
30require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing_targets.class.php';
31
35class Mailing extends CommonObject
36{
40 public $element = 'mailing';
41
45 public $table_element = 'mailing';
46
50 public $picto = 'mail-bulk';
51
55 public $messtype = 'email';
56
60 public $title;
61
65 public $sujet;
66
70 public $body;
71
75 public $evenunsubscribe;
76
80 public $note_public;
81
85 public $note_private;
86
90 public $nbemail;
91
95 public $bgcolor;
96
100 public $bgimage;
101
106 public $statut; // Status 0=Draft, 1=Validated, 2=Sent partially, 3=Sent completely
107
111 public $status; // Status 0=Draft, 1=Validated, 2=Sent partially, 3=Sent completely
112
116 public $email_from;
117
121 public $sendto;
122
126 public $email_replyto;
127
131 public $email_errorsto;
132
136 public $joined_file1;
137
141 public $joined_file2;
142
146 public $joined_file3;
147
151 public $joined_file4;
152
156 public $date_envoi;
157
161 public $extraparams = array();
162
166 public $statut_dest = array();
167
171 public $substitutionarray;
172
176 public $substitutionarrayfortest;
177
181 public $targets = array();
182
187 public $fk_project;
188
189 public $fields = array(
190 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id'),
191 'fk_project' => array('type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label' => 'Fk project', 'enabled' => "isModEnabled('project')", 'visible' => -1, 'position' => 10),
192 );
193
194 const STATUS_DRAFT = 0;
195 const STATUS_VALIDATED = 1;
196 const STATUS_SENTPARTIALY = 2;
197 const STATUS_SENTCOMPLETELY = 3;
198
199
205 public function __construct($db)
206 {
207 $this->db = $db;
208
209 // List of language codes for status
210 $this->labelStatus[0] = 'MailingStatusDraft';
211 $this->labelStatus[1] = 'MailingStatusValidated';
212 $this->labelStatus[2] = 'MailingStatusSentPartialy';
213 $this->labelStatus[3] = 'MailingStatusSentCompletely';
214
215 $this->statut_dest[0] = 'MailingStatusNotSent';
216 $this->statut_dest[1] = 'MailingStatusSent';
217 $this->statut_dest[2] = 'MailingStatusRead';
218 $this->statut_dest[3] = 'MailingStatusReadAndUnsubscribe'; // Read but ask to not be contacted anymore
219 $this->statut_dest[-1] = 'MailingStatusError';
220 }
221
229 public function create($user, $notrigger = 0)
230 {
231 global $conf, $langs;
232
233 // Check properties
234 if (preg_match('/^InvalidHTMLStringCantBeCleaned/', $this->body)) {
235 $this->error = 'InvalidHTMLStringCantBeCleaned';
236 return -1;
237 }
238
239 $this->title = trim($this->title);
240 $this->email_from = trim($this->email_from);
241 if (empty($this->messtype)) {
242 $this->messtype = 'email';
243 }
244 if (!$this->email_from) {
245 if ($this->messtype !== 'sms') {
246 $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailFrom"));
247 } else {
248 $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PhoneFrom"));
249 }
250 return -1;
251 }
252
253 $error = 0;
254 $now = dol_now();
255
256 $this->db->begin();
257
258 $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing";
259 $sql .= " (messtype, date_creat, fk_user_creat, entity)";
260 $sql .= " VALUES ('".$this->db->escape($this->messtype)."', '".$this->db->idate($now)."', ".((int) $user->id).", ".((int) $conf->entity).")";
261
262 if (!$this->title) {
263 $this->title = $langs->trans("NoTitle");
264 }
265
266 dol_syslog(__METHOD__, LOG_DEBUG);
267
268 $resql = $this->db->query($sql);
269 if ($resql) {
270 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."mailing");
271
272 $result = $this->update($user, 1);
273 if ($result < 0) {
274 $error++;
275 }
276
277 if (!$error && !$notrigger) {
278 // Call trigger
279 $result = $this->call_trigger('MAILING_CREATE', $user);
280 if ($result < 0) {
281 $error++;
282 }
283 // End call triggers
284 }
285
286 if (!$error) {
287 $this->db->commit();
288 return $this->id;
289 } else {
290 $this->db->rollback();
291 dol_syslog(__METHOD__ . ' ' . $this->error, LOG_ERR);
292 return -2;
293 }
294 } else {
295 $this->error = $this->db->lasterror();
296 $this->db->rollback();
297 return -1;
298 }
299 }
300
308 public function update($user, $notrigger = 0)
309 {
310 global $langs;
311
312 // Check properties
313 if (preg_match('/^InvalidHTMLStringCantBeCleaned/', $this->body)) {
314 $this->error = 'InvalidHTMLStringCantBeCleaned';
315 return -1;
316 }
317
318 if (empty($this->messtype)) {
319 $this->messtype = 'email';
320 }
321
322 $error = 0;
323 $this->db->begin();
324
325 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing";
326 $sql .= " SET titre = '".$this->db->escape($this->title)."'";
327 $sql .= ", messtype = '".$this->db->escape($this->messtype)."'";
328 $sql .= ", sujet = '".$this->db->escape($this->sujet)."'";
329 $sql .= ", body = '".$this->db->escape($this->body)."'";
330 $sql .= ", email_from = '".$this->db->escape($this->email_from)."'";
331 $sql .= ", email_replyto = '".$this->db->escape($this->email_replyto)."'";
332 $sql .= ", email_errorsto = '".$this->db->escape($this->email_errorsto)."'";
333 $sql .= ", bgcolor = '".($this->bgcolor ? $this->db->escape($this->bgcolor) : null)."'";
334 $sql .= ", bgimage = '".($this->bgimage ? $this->db->escape($this->bgimage) : null)."'";
335 $sql .= ", evenunsubscribe = ".((int) $this->evenunsubscribe);
336 $sql .= ", note_public = '".$this->db->escape($this->note_public)."'";
337 $sql .= ", note_private = '".$this->db->escape($this->note_private)."'";
338 $sql .= ", fk_project = '".((int) $this->fk_project)."'";
339 $sql .= " WHERE rowid = ".(int) $this->id;
340
341 dol_syslog(__METHOD__, LOG_DEBUG);
342 $resql = $this->db->query($sql);
343 if ($resql) {
344 if (!$error && !$notrigger) {
345 // Call trigger
346 $result = $this->call_trigger('MAILING_MODIFY', $user);
347 if ($result < 0) {
348 $error++;
349 }
350 // End call triggers
351 }
352
353 if (!$error) {
354 dol_syslog(__METHOD__ . ' success');
355 $this->db->commit();
356 return 1;
357 } else {
358 $this->db->rollback();
359 dol_syslog(__METHOD__ . ' ' . $this->error, LOG_ERR);
360 return -2;
361 }
362 } else {
363 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
364 $this->error = $langs->trans("ErrorTitleAlreadyExists", $this->title);
365 } else {
366 $this->error = $this->db->lasterror();
367 }
368 $this->db->rollback();
369 return -1;
370 }
371 }
372
380 public function fetch($rowid, $ref = '')
381 {
382 $sql = "SELECT m.rowid, m.messtype, m.titre as title, m.entity, m.sujet, m.body, m.bgcolor, m.bgimage, m.evenunsubscribe";
383 $sql .= ", m.note_public, m.note_private";
384 $sql .= ", m.email_from, m.email_replyto, m.email_errorsto";
385 $sql .= ", m.statut as status, m.nbemail";
386 $sql .= ", m.fk_user_creat, m.fk_user_valid";
387 $sql .= ", m.tms as date_modification";
388 $sql .= ", m.date_creat";
389 $sql .= ", m.date_valid";
390 $sql .= ", m.date_envoi";
391 $sql .= ", m.extraparams";
392 $sql .= ", m.tag";
393 $sql .= ", m.name_from";
394 $sql .= ", m.fk_user_modif";
395 $sql .= ", m.fk_user_appro";
396 $sql .= ", m.date_appro";
397 $sql .= ", m.cible";
398 $sql .= ", m.joined_file1";
399 $sql .= ", m.joined_file2";
400 $sql .= ", m.joined_file3";
401 $sql .= ", m.joined_file4";
402 $sql .= ", m.fk_project";
403 $sql .= " FROM ".MAIN_DB_PREFIX."mailing as m";
404 $sql .= " WHERE entity IN (".getEntity('mailing').")";
405 if ($ref) {
406 $sql .= " AND m.titre = '".$this->db->escape($ref)."'";
407 } else {
408 $sql .= " AND m.rowid = ".(int) $rowid;
409 }
410
411 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
412 $result = $this->db->query($sql);
413 if ($result) {
414 if ($this->db->num_rows($result)) {
415 $obj = $this->db->fetch_object($result);
416
417 $this->id = $obj->rowid;
418 $this->entity = $obj->entity;
419 $this->ref = $obj->rowid;
420 $this->title = $obj->title;
421 $this->messtype = $obj->messtype;
422
423 $this->statut = $obj->status; // deprecated
424 $this->status = $obj->status;
425
426 $this->nbemail = $obj->nbemail;
427
428 $this->sujet = $obj->sujet;
429 if (getDolGlobalString('FCKEDITOR_ENABLE_MAILING') && dol_textishtml(dol_html_entity_decode($obj->body, ENT_COMPAT | ENT_HTML5))) {
430 $this->body = dol_html_entity_decode($obj->body, ENT_COMPAT | ENT_HTML5);
431 } else {
432 $this->body = $obj->body;
433 }
434
435 $this->bgcolor = $obj->bgcolor;
436 $this->bgimage = $obj->bgimage;
437 $this->evenunsubscribe = $obj->evenunsubscribe;
438 $this->note_public = $obj->note_public;
439 $this->note_private = $obj->note_private;
440
441 $this->email_from = $obj->email_from;
442 $this->email_replyto = $obj->email_replyto;
443 $this->email_errorsto = $obj->email_errorsto;
444
445 $this->user_creation_id = $obj->fk_user_creat;
446 $this->user_validation_id = $obj->fk_user_valid;
447
448 $this->date_creation = $this->db->jdate($obj->date_creat);
449 $this->date_validation = $this->db->jdate($obj->date_valid);
450 $this->date_envoi = $this->db->jdate($obj->date_envoi);
451 $this->date_modification = $this->db->jdate($obj->date_modification); // tms
452
453 $this->extraparams = (array) json_decode($obj->extraparams, true);
454
455 $this->tag = $obj->tag;
456 $this->name_from = $obj->name_from;
457 $this->fk_user_modif = $obj->fk_user_modif;
458 $this->fk_user_appro = $obj->fk_user_appro;
459 $this->date_appro = $obj->date_appro;
460 $this->cible = $obj->cible;
461 $this->joined_file1 = $obj->joined_file1;
462 $this->joined_file2 = $obj->joined_file2;
463 $this->joined_file3 = $obj->joined_file3;
464 $this->joined_file4 = $obj->joined_file4;
465 $this->fk_project = $obj->fk_project;
466
467 if ($this->messtype == 'sms') {
468 $this->picto = 'phone';
469 }
470
471 return 1;
472 } else {
473 dol_syslog(get_class($this)."::fetch Erreur -1");
474 return -1;
475 }
476 } else {
477 dol_syslog(get_class($this)."::fetch Erreur -2");
478 return -2;
479 }
480 }
481
495 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
496 {
497 dol_syslog(__METHOD__, LOG_DEBUG);
498
499 $records = array();
500
501 $sql = 'SELECT ';
502 $sql .= $this->getFieldList('t');
503 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
504 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
505 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
506 } else {
507 $sql .= ' WHERE 1 = 1';
508 }
509
510 // Manage filter
511 if (is_array($filter)) { // deprecated, use $filter = USF syntax
512 dol_syslog("You are using a deprecated use of fetchAll. filter parameter must be an USF string now.", LOG_WARNING);
513 $sqlwhere = array();
514 if (count($filter) > 0) {
515 foreach ($filter as $key => $value) {
516 if ($key == 't.rowid' || $key == 't.fk_soc' || $key == 't.fk_project') {
517 $sqlwhere[] = $this->db->sanitize($key).' = '.((int) $value);
518 } elseif (!empty($this->fields[$key]) && in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
519 $sqlwhere[] = $this->db->sanitize($key)." = '".$this->db->idate((int) $value)."'";
520 } elseif ($key == 'customsql') {
521 $sqlwhere[] = $value;
522 } elseif (strpos($value, '%') === false) {
523 $sqlwhere[] = $this->db->sanitize($key).' IN ('.$this->db->sanitize($this->db->escape($value)).')';
524 } else {
525 $sqlwhere[] = $this->db->sanitize($key)." LIKE '%".$this->db->escape($value)."%'";
526 }
527 }
528 }
529 if (count($sqlwhere) > 0) {
530 $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
531 }
532
533 $filter = '';
534 }
535
536 // Manage filter
537 $errormessage = '';
538 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
539 if ($errormessage) {
540 $this->errors[] = $errormessage;
541 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
542 return -1;
543 }
544
545 if (!empty($sortfield)) {
546 $sql .= $this->db->order($sortfield, $sortorder);
547 }
548 if (!empty($limit)) {
549 $sql .= $this->db->plimit($limit, $offset);
550 }
551
552 $resql = $this->db->query($sql);
553 if ($resql) {
554 $num = $this->db->num_rows($resql);
555 $i = 0;
556 while ($i < ($limit ? min($limit, $num) : $num)) {
557 $obj = $this->db->fetch_object($resql);
558
559 $record = new self($this->db);
560 $record->setVarsFromFetchObj($obj);
561
562 $records[$record->id] = $record;
563
564 $i++;
565 }
566 $this->db->free($resql);
567
568 return $records;
569 } else {
570 $this->errors[] = 'Error '.$this->db->lasterror();
571 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
572
573 return -1;
574 }
575 }
576
587 public function createFromClone(User $user, $fromid, $option1, $option2, $notrigger = 0)
588 {
589 global $langs;
590
591 $error = 0;
592
593 $object = new Mailing($this->db);
594
595 $this->db->begin();
596
597 // Load source object
598 $object->fetch($fromid);
599 $object->id = 0;
600 $object->status = 0;
601 $object->statut = 0;
602
603 // Clear fields
604 $object->title = $langs->trans("CopyOf").' '.$object->title.' '.dol_print_date(dol_now());
605
606 // If no option copy content
607 if (empty($option1)) {
608 // Clear values
609 $object->nbemail = 0;
610 $object->sujet = '';
611 $object->body = '';
612 $object->bgcolor = '';
613 $object->bgimage = '';
614 $object->evenunsubscribe = 0;
615 $object->note_public = '';
616 $object->note_private = '';
617
618 //$object->email_from = ''; // We do not reset from email because it is a mandatory value
619 $object->email_replyto = '';
620 $object->email_errorsto = '';
621
622 $object->user_creation_id = $user->id;
623 $object->user_validation_id = null;
624
625 $object->date_envoi = null;
626 }
627
628 // Create clone
629 $object->context['createfromclone'] = 'createfromclone';
630 $result = $object->create($user, $notrigger);
631
632 // Other options
633 if ($result < 0) {
635 $error++;
636 }
637
638 if (!$error) {
639 // Clone recipient targets
640 if (!empty($option2)) {
641 require_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
642
643 $mailing_target = new MailingTargets($this->db);
644
645 $target_array = array();
646
647 $sql = "SELECT fk_contact,";
648 $sql .= " lastname,";
649 $sql .= " firstname,";
650 $sql .= " email,";
651 $sql .= " other,";
652 $sql .= " source_url,";
653 $sql .= " source_id ,";
654 $sql .= " source_type";
655 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles";
656 $sql .= " WHERE fk_mailing = ".((int) $fromid);
657
658 $result = $this->db->query($sql);
659 if ($result) {
660 if ($this->db->num_rows($result)) {
661 while ($obj = $this->db->fetch_object($result)) {
662 $target_array[] = array(
663 'fk_contact' => $obj->fk_contact,
664 'lastname' => $obj->lastname,
665 'firstname' => $obj->firstname,
666 'email' => $obj->email,
667 'other' => $obj->other,
668 'source_url' => $obj->source_url,
669 'source_id' => $obj->source_id,
670 'source_type' => $obj->source_type
671 );
672 }
673 }
674 } else {
675 $this->error = $this->db->lasterror();
676 return -1;
677 }
678
679 $mailing_target->addTargetsToDatabase($object->id, $target_array);
680 }
681 }
682
683 unset($object->context['createfromclone']);
684
685 // End
686 if (!$error) {
687 $this->db->commit();
688 return $object->id;
689 } else {
690 $this->db->rollback();
691 return -1;
692 }
693 }
694
701 public function valid($user)
702 {
703 $now = dol_now();
704
705 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing ";
706 $sql .= " SET statut = 1, date_valid = '".$this->db->idate($now)."', fk_user_valid=".$user->id;
707 $sql .= " WHERE rowid = ".((int) $this->id);
708
709 dol_syslog("Mailing::valid", LOG_DEBUG);
710 if ($this->db->query($sql)) {
711 return 1;
712 } else {
713 $this->error = $this->db->lasterror();
714 return -1;
715 }
716 }
717
724 public function setDraft($user)
725 {
726 $now = dol_now();
727
728 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing ";
729 $sql .= " SET statut = 0, tms = '".$this->db->idate($now)."', fk_user_modif=".$user->id;
730 $sql .= " WHERE rowid = ".((int) $this->id);
731
732 dol_syslog("Mailing::valid", LOG_DEBUG);
733 if ($this->db->query($sql)) {
734 return 1;
735 } else {
736 $this->error = $this->db->lasterror();
737 return -1;
738 }
739 }
740
748 public function delete($user, $notrigger = 0)
749 {
750 $error = 0;
751
752 $this->db->begin();
753
754 if (!$notrigger) {
755 $result = $this->call_trigger('MAILING_DELETE', $user);
756 if ($result < 0) {
757 $error++;
758 }
759 }
760
761 if (!$error) {
762 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "mailing";
763 $sql .= " WHERE rowid = " . ((int) $this->id);
764
765 dol_syslog(__METHOD__, LOG_DEBUG);
766 $resql = $this->db->query($sql);
767 if ($resql) {
768 $res = $this->delete_targets();
769 if ($res <= 0) {
770 $error++;
771 }
772
773 if (!$error) {
774 dol_syslog(__METHOD__ . ' success');
775 $this->db->commit();
776 return 1;
777 } else {
778 $this->db->rollback();
779 dol_syslog(__METHOD__ . ' ' . $this->error, LOG_ERR);
780 return -2;
781 }
782 } else {
783 $this->db->rollback();
784 $this->error = $this->db->lasterror();
785 return -1;
786 }
787 } else {
788 $this->db->rollback();
789 return -1;
790 }
791 }
792
793 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
799 public function delete_targets()
800 {
801 // phpcs:enable
802 $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
803 $sql .= " WHERE fk_mailing = ".((int) $this->id);
804
805 dol_syslog("Mailing::delete_targets", LOG_DEBUG);
806 $resql = $this->db->query($sql);
807 if ($resql) {
808 $this->refreshNbOfTargets();
809
810 return 1;
811 } else {
812 $this->error = $this->db->lasterror();
813 return 0;
814 }
815 }
816
817
818 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
825 public function reset_targets_status($user)
826 {
827 // phpcs:enable
828 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
829 $sql .= " SET statut = 0";
830 $sql .= " WHERE fk_mailing = ".((int) $this->id);
831
832 dol_syslog("Mailing::reset_targets_status", LOG_DEBUG);
833 $resql = $this->db->query($sql);
834 if ($resql) {
835 return 1;
836 } else {
837 $this->error = $this->db->lasterror();
838 return -1;
839 }
840 }
841
849 public function resetTargetErrorStatus($user, $id)
850 {
851 // phpcs:enable
852 global $langs;
853
854 $sql = "SELECT email, statut FROM ".MAIN_DB_PREFIX."mailing_cibles";
855 $sql .= " WHERE fk_mailing = ".((int) $this->id);
856 $sql .= " AND rowid = ".((int) $id);
857 $resql = $this->db->query($sql);
858 if ($resql) {
859 $nb = $this->db->num_rows($resql);
860 $obj = $this->db->fetch_object($resql);
861 if ($obj->statut != -1) {
862 $langs->load("errors");
863 $this->error = $langs->trans('ErrorIsNotInError', $obj->email);
864 return 0;
865 }
866 } else {
867 $this->error = $this->db->lasterror();
868 }
869
870 $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
871 $sql .= " SET statut = 0";
872 $sql .= " WHERE fk_mailing = ".((int) $this->id);
873 $sql .= " AND rowid = ".((int) $id);
874 $sql .= " AND statut = -1";
875
876 dol_syslog("Mailing::reset_targets_status", LOG_DEBUG);
877 $resql = $this->db->query($sql);
878 if ($resql) {
879 return 1;
880 } else {
881 $this->error = $this->db->lasterror();
882 return -1;
883 }
884 }
885
892 public function countNbOfTargets($mode)
893 {
894 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_cibles";
895 $sql .= " WHERE fk_mailing = ".((int) $this->id);
896 if ($mode == 'alreadysent') {
897 $sql .= " AND statut <> 0";
898 } elseif ($mode == 'alreadysentok') {
899 $sql .= " AND statut > 0";
900 } elseif ($mode == 'alreadysentko') {
901 $sql .= " AND statut = -1";
902 } elseif ($mode == 'all') {
903 // just want to return all possible recipients
904 } else {
905 $this->error = 'BadValueForParameterMode';
906 return -2;
907 }
908
909 $resql = $this->db->query($sql);
910 if ($resql) {
911 $obj = $this->db->fetch_object($resql);
912 if ($obj) {
913 return $obj->nb;
914 }
915 } else {
916 $this->error = $this->db->lasterror();
917 return -1;
918 }
919 return 0;
920 }
921
928 public function refreshNbOfTargets()
929 {
930 $sql = "SELECT COUNT(rowid) as nb";
931 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles";
932 $sql .= " WHERE fk_mailing = ".((int) $this->id);
933
934 $resql = $this->db->query($sql);
935 if ($resql) {
936 $obj = $this->db->fetch_object($resql);
937 if ($obj) {
938 $nbforupdate = $obj->nb;
939
940 $sql = 'UPDATE '.MAIN_DB_PREFIX.'mailing SET nbemail = '.((int) $nbforupdate);
941 $sql .= ' WHERE rowid = '.((int) $this->id);
942
943 $resqlupdate = $this->db->query($sql);
944 if (! $resqlupdate) {
945 $this->error = $this->db->lasterror();
946 return -1;
947 } else {
948 $this->nbemail = (int) $nbforupdate;
949 }
950 }
951 } else {
952 $this->error = $this->db->lasterror();
953 return -1;
954 }
955
956 return 1;
957 }
958
965 public function getTooltipContentArray($params)
966 {
967 global $langs;
968
969 //$nofetch = !empty($params['nofetch']);
970 $langs->load('mails');
971
972 $datas = array();
973 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ShowEMailing").'</u>';
974 if (isset($this->status)) {
975 $datas['picto'] .= ' '.$this->getLibStatut(5);
976 }
977 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
978 if (isset($this->title)) {
979 $datas['title'] = '<br><b>'.$langs->trans('MailTitle').':</b> '.$this->title;
980 }
981 if (isset($this->sujet)) {
982 $datas['subject'] = '<br><b>'.$langs->trans('MailTopic').':</b> '.$this->sujet;
983 }
984
985 return $datas;
986 }
987
998 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
999 {
1000 global $conf, $langs, $hookmanager;
1001
1002 if (!empty($conf->dol_no_mouse_hover)) {
1003 $notooltip = 1; // Force disable tooltips
1004 }
1005
1006 $result = '';
1007 $params = [
1008 'id' => $this->id,
1009 'objecttype' => $this->element,
1010 'option' => $option,
1011 'nofetch' => 1,
1012 ];
1013 $classfortooltip = 'classfortooltip';
1014 $dataparams = '';
1015 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1016 $classfortooltip = 'classforajaxtooltip';
1017 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1018 $label = '';
1019 } else {
1020 $label = implode($this->getTooltipContentArray($params));
1021 }
1022
1023 $url = DOL_URL_ROOT.'/comm/mailing/card.php?id='.$this->id;
1024
1025 if ($option != 'nolink') {
1026 // Add param to save lastsearch_values or not
1027 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1028 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1029 $add_save_lastsearch_values = 1;
1030 }
1031 if ($add_save_lastsearch_values) {
1032 $url .= '&save_lastsearch_values=1';
1033 }
1034 }
1035
1036 $linkclose = '';
1037 if (empty($notooltip)) {
1038 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1039 $label = $langs->trans("ShowEMailing");
1040 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1041 }
1042 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1043 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1044 } else {
1045 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1046 }
1047
1048 $linkstart = '<a href="'.$url.'"';
1049 $linkstart .= $linkclose.'>';
1050 $linkend = '</a>';
1051
1052 $result .= $linkstart;
1053 if ($withpicto) {
1054 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
1055 }
1056 if ($withpicto != 2) {
1057 $result .= $this->ref;
1058 }
1059 $result .= $linkend;
1060 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1061
1062 global $action;
1063 $hookmanager->initHooks(array('emailingdao'));
1064 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1065 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1066 if ($reshook > 0) {
1067 $result = $hookmanager->resPrint;
1068 } else {
1069 $result .= $hookmanager->resPrint;
1070 }
1071
1072 return $result;
1073 }
1074
1081 public function getLibStatut($mode = 0)
1082 {
1083 return $this->LibStatut($this->status, $mode);
1084 }
1085
1086 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1094 public function LibStatut($status, $mode = 0)
1095 {
1096 // phpcs:enable
1097 global $langs;
1098 $langs->load("mailing");
1099
1100 $labelStatus = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
1101 $labelStatusShort = $langs->transnoentitiesnoconv($this->labelStatus[$status]);
1102
1103 $statusType = 'status'.$status;
1104 if ($status == 2) {
1105 $statusType = 'status3';
1106 }
1107 if ($status == 3) {
1108 $statusType = 'status6';
1109 }
1110
1111 return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1112 }
1113
1114
1124 public static function libStatutDest($status, $mode = 0, $desc = '')
1125 {
1126 global $langs;
1127 $langs->load("mails");
1128
1129 $labelStatus = array();
1130 $labelStatusShort = array();
1131
1132 $labelStatus[-1] = $langs->transnoentitiesnoconv('MailingStatusError');
1133 $labelStatus[0] = $langs->transnoentitiesnoconv('MailingStatusNotSent');
1134 $labelStatus[1] = $langs->transnoentitiesnoconv('MailingStatusSent');
1135 $labelStatus[2] = $langs->transnoentitiesnoconv('MailingStatusRead');
1136 $labelStatus[3] = $langs->transnoentitiesnoconv('MailingStatusNotContact');
1137 $labelStatusShort[-1] = $langs->transnoentitiesnoconv('MailingStatusError');
1138 $labelStatusShort[0] = $langs->transnoentitiesnoconv('MailingStatusNotSent');
1139 $labelStatusShort[1] = $langs->transnoentitiesnoconv('MailingStatusSent');
1140 $labelStatusShort[2] = $langs->transnoentitiesnoconv('MailingStatusRead');
1141 $labelStatusShort[3] = $langs->transnoentitiesnoconv('MailingStatusNotContact');
1142
1143 $statusType = 'status'.$status;
1144 if ($status == -1) {
1145 $statusType = 'status8';
1146 }
1147 if ($status == 1) {
1148 $statusType = 'status6';
1149 }
1150 if ($status == 2) {
1151 $statusType = 'status4';
1152 }
1153
1154 $param = array();
1155 if ($status == -1) {
1156 $param = array('badgeParams' => array('attr' => array('title' => $desc)));
1157 }
1158
1159 return dolGetStatus($labelStatus[$status], $labelStatusShort[$status], '', $statusType, $mode, '', $param);
1160 }
1161}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$object ref
Definition info.php:90
Parent class of all other business classes (invoices, contracts, proposals, orders,...
setErrorsFromObject($object)
setErrorsFromObject
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
Class to manage emailings module.
static libStatutDest($status, $mode=0, $desc='')
Return the label of a given status of a recipient TODO Add class mailin_target.class....
getLibStatut($mode=0)
Return label of status of emailing (draft, validated, ...)
delete_targets()
Delete targets emailing.
valid($user)
Validate emailing.
countNbOfTargets($mode)
Count number of target with status.
create($user, $notrigger=0)
Create an EMailing.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
setDraft($user)
SetDraft emailing.
fetch($rowid, $ref='')
Get object from database.
getTooltipContentArray($params)
getTooltipContentArray
__construct($db)
Constructor.
update($user, $notrigger=0)
Update emailing record.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
refreshNbOfTargets()
Refresh denormalized value ->nbemail into emailing record Note: There is also the method update_nb in...
reset_targets_status($user)
Change status of each recipient.
resetTargetErrorStatus($user, $id)
Reset status of a specific recipient in error.
createFromClone(User $user, $fromid, $option1, $option2, $notrigger=0)
Load an object from its id and create a new one in database.
LibStatut($status, $mode=0)
Return the label of a given status.
Parent class of emailing target selectors modules.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:168
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_html_entity_decode($a, $b, $c='UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
dol_now($mode='gmt')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_textishtml($msg, $option=0)
Return if a text is a html content.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.