dolibarr  17.0.4
interface_50_modTicket_TicketEmail.class.php
Go to the documentation of this file.
1 <?php
2 /*
3  * Copyright (C) 2014-2016 Jean-François Ferry <hello@librethic.io>
4  * 2016 Christophe Battarel <christophe@altairis.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
25 require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
26 
27 
32 {
38  public function __construct($db)
39  {
40  $this->db = $db;
41 
42  $this->name = preg_replace('/^Interface/i', '', get_class($this));
43  $this->family = "ticket";
44  $this->description = "Triggers of the module ticket to send notifications to internal users and to third-parties";
45  $this->version = self::VERSION_DOLIBARR; // 'development', 'experimental', 'dolibarr' or version
46  $this->picto = 'ticket';
47  }
48 
60  public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
61  {
62  $ok = 0;
63 
64  if (empty($conf->ticket) || !isModEnabled('ticket')) {
65  return 0; // Module not active, we do nothing
66  }
67 
68  switch ($action) {
69  case 'TICKET_ASSIGNED':
70  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
71 
72  if ($object->fk_user_assign > 0 && $object->fk_user_assign != $user->id) {
73  $userstat = new User($this->db);
74  $res = $userstat->fetch($object->fk_user_assign);
75  if ($res > 0) {
76  // Send email to notification email
77 
78  if (empty($conf->global->TICKET_DISABLE_ALL_MAILS)) {
79  // Init to avoid errors
80  $filepath = array();
81  $filename = array();
82  $mimetype = array();
83 
84  // Send email to assigned user
85  $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketAssignedToYou');
86  $message = '<p>'.$langs->transnoentities('TicketAssignedEmailBody', $object->track_id, dolGetFirstLastname($user->firstname, $user->lastname))."</p>";
87  $message .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
88  $message .= '<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
89  $message .= '<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
90  $message .= '<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
91  // Extrafields
92  if (is_array($object->array_options) && count($object->array_options) > 0) {
93  foreach ($object->array_options as $key => $value) {
94  $message .= '<li>'.$langs->trans($key).' : '.$value.'</li>';
95  }
96  }
97 
98  $message .= '</ul>';
99  $message .= '<p>'.$langs->trans('Message').' : <br>'.$object->message.'</p>';
100  $message .= '<p><a href="'.dol_buildpath('/ticket/card.php', 2).'?track_id='.$object->track_id.'">'.$langs->trans('SeeThisTicketIntomanagementInterface').'</a></p>';
101 
102  $sendto = $userstat->email;
103  $from = dolGetFirstLastname($user->firstname, $user->lastname).'<'.$user->email.'>';
104 
105  $message = dol_nl2br($message);
106 
107  if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
108  $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
109  $conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
110  }
111  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
112  $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1);
113  if ($mailfile->error) {
114  setEventMessages($mailfile->error, $mailfile->errors, 'errors');
115  } else {
116  $result = $mailfile->sendfile();
117  }
118  if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
119  $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
120  }
121  }
122 
123  $ok = 1;
124  } else {
125  $this->error = $userstat->error;
126  $this->errors = $userstat->errors;
127  }
128  }
129  break;
130 
131  case 'TICKET_CREATE':
132  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
133 
134  $langs->load('ticket');
135 
136  $subject_admin = 'TicketNewEmailSubjectAdmin';
137  $body_admin = 'TicketNewEmailBodyAdmin';
138  $subject_customer = 'TicketNewEmailSubjectCustomer';
139  $body_customer = 'TicketNewEmailBodyCustomer';
140  $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer';
141 
142  // Send email to notification email
143  if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) {
144  $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
145  if ($sendto) {
146  $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs);
147  }
148  }
149 
150  // Send email to customer
151  if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) {
152  $sendto = '';
153 
154  //if contact selected send to email's contact else send to email's thirdparty
155 
156  $contactid = GETPOST('contactid', 'alpha');
157  $res = 0;
158 
159  if (!empty($contactid)) {
160  $contact = new Contact($this->db);
161  $res = $contact->fetch($contactid);
162  }
163 
164  if ($res > 0 && !empty($contact->email) && !empty($contact->statut)) {
165  $sendto = $contact->email;
166  } elseif (!empty($object->fk_soc)) {
167  $object->fetch_thirdparty();
168  $sendto = $object->thirdparty->email;
169  }
170 
171  if ($sendto) {
172  $this->composeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs);
173  }
174  }
175 
176  $ok = 1;
177  break;
178 
179  case 'TICKET_DELETE':
180  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
181  break;
182 
183  case 'TICKET_MODIFY':
184  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
185  break;
186 
187  case 'TICKET_CLOSE':
188  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
189  $langs->load('ticket');
190 
191  $subject_admin = 'TicketCloseEmailSubjectAdmin';
192  $body_admin = 'TicketCloseEmailBodyAdmin';
193  $subject_customer = 'TicketCloseEmailSubjectCustomer';
194  $body_customer = 'TicketCloseEmailBodyCustomer';
195  $see_ticket_customer = 'TicketCloseEmailBodyInfosTrackUrlCustomer';
196 
197  // Send email to notification email
198  if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) {
199  $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
200  if ($sendto) {
201  $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs);
202  }
203  }
204 
205  // Send email to customer.
206  if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail'])) {
207  $linked_contacts = $object->listeContact(-1, 'thirdparty');
208  $linked_contacts = array_merge($linked_contacts, $object->listeContact(-1, 'internal'));
209  if (empty($linked_contacts) && !empty($conf->global->TICKET_NOTIFY_AT_CLOSING) && !empty($object->fk_soc)) {
210  $object->fetch_thirdparty();
211  $linked_contacts[] = $object->thirdparty->email;
212  }
213 
214  $contactid = GETPOST('contactid', 'int');
215  $res = 0;
216 
217  if ($contactid > 0) {
218  $contact = new Contact($this->db);
219  $res = $contact->fetch($contactid);
220  if (! in_array($contact, $linked_contacts)) {
221  $error_msg = $langs->trans('Error'). ': ';
222  $error_msg .= $langs->transnoentities('TicketWrongContact');
223  setEventMessages($error_msg, [], 'errors');
224  $ok = 0;
225  break;
226  }
227  }
228 
229  $sendto = '';
230  if ($res > 0 && !empty($contact->email) && !empty($contact->statut)) {
231  $sendto = $contact->email;
232  } elseif ( !empty($linked_contacts) && ($contactid == -2 || (GETPOST('massaction', 'alpha') == 'close' && GETPOST('confirm', 'alpha') == 'yes'))) {
233  // if sending to all contacts or sending to contacts while mass closing
234  $temp_emails = [];
235  foreach ($linked_contacts as $contact) {
236  $temp_emails[] = $contact['email'];
237  }
238  $sendto = implode(", ", $temp_emails);
239  unset($temp_emails);
240  unset($linked_contacts);
241  }
242  if ($sendto) {
243  $this->composeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs);
244  }
245  }
246  $ok = 1;
247  break;
248  }
249 
250  return $ok;
251  }
252 
263  private function composeAndSendAdminMessage($sendto, $base_subject, $body, Ticket $object, Translate $langs)
264  {
265  global $conf;
266 
267  // Init to avoid errors
268  $filepath = array();
269  $filename = array();
270  $mimetype = array();
271 
272  /* Send email to admin */
273  $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject, $object->ref, $object->track_id);
274  $message_admin = $langs->transnoentities($body, $object->track_id).'<br>';
275  $message_admin .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
276  $message_admin .= '<li>'.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'</li>';
277  $message_admin .= '<li>'.$langs->trans('TicketCategory').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'</li>';
278  $message_admin .= '<li>'.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'</li>';
279  $message_admin .= '<li>'.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'</li>';
280  // Extrafields
281  $extraFields = new ExtraFields($this->db);
282  $extraFields->fetch_name_optionals_label($object->table_element);
283  if (is_array($object->array_options) && count($object->array_options) > 0) {
284  foreach ($object->array_options as $key => $value) {
285  $key = substr($key, 8); // remove "options_"
286  $message_admin .= '<li>'.$langs->trans($extraFields->attributes[$object->element]['label'][$key]).' : '.$extraFields->showOutputField($key, $value, '', $object->table_element).'</li>';
287  }
288  }
289  if ($object->fk_soc > 0) {
290  $object->fetch_thirdparty();
291  $message_admin .= '<li>'.$langs->trans('Company').' : '.$object->thirdparty->name.'</li>';
292  }
293  $message_admin .= '</ul>';
294 
295  $message = $object->message;
296  if (!dol_textishtml($message)) {
297  $message = dol_nl2br($message);
298  }
299  $message_admin .= '<p>'.$langs->trans('Message').' : <br><br>'.$message.'</p><br>';
300  $message_admin .= '<p><a href="'.dol_buildpath('/ticket/card.php', 2).'?track_id='.$object->track_id.'">'.$langs->trans('SeeThisTicketIntomanagementInterface').'</a></p>';
301 
302  $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>';
303 
304  $trackid = 'tic'.$object->id;
305 
306  if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
307  $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
308  $conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
309  }
310  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
311  $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket');
312  if ($mailfile->error) {
313  dol_syslog($mailfile->error, LOG_DEBUG);
314  } else {
315  $result = $mailfile->sendfile();
316  }
317  if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
318  $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
319  }
320  }
321 
333  private function composeAndSendCustomerMessage($sendto, $base_subject, $body, $see_ticket, Ticket $object, Translate $langs)
334  {
335  global $conf, $user;
336 
337  // Init to avoid errors
338  $filepath = array();
339  $filename = array();
340  $mimetype = array();
341 
342  $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject);
343  $message_customer = $langs->transnoentities($body, $object->track_id).'<br>';
344  $message_customer .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
345  $message_customer .= '<li>'.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'</li>';
346  $message_customer .= '<li>'.$langs->trans('TicketCategory').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'</li>';
347  $message_customer .= '<li>'.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'</li>';
348 
349  // Extrafields
350  if (is_array($this->attributes[$object->table_element]['label'])) {
351  foreach ($this->attributes[$object->table_element]['label'] as $key => $value) {
352  $enabled = 1;
353  if ($enabled && isset($this->attributes[$object->table_element]['list'][$key])) {
354  $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1);
355  }
356  $perms = 1;
357  if ($perms && isset($this->attributes[$object->table_element]['perms'][$key])) {
358  $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1);
359  }
360 
361  $qualified = true;
362  if (empty($enabled)) {
363  $qualified = false;
364  }
365  if (empty($perms)) {
366  $qualified = false;
367  }
368 
369  if ($qualified) {
370  $message_customer .= '<li>' . $langs->trans($key) . ' : ' . $value . '</li>';
371  }
372  }
373  }
374 
375  $message_customer .= '</ul>';
376 
377  $message = $object->message;
378  if (!dol_textishtml($message)) {
379  $message = dol_nl2br($message);
380  }
381  $message_customer .= '<p>'.$langs->trans('Message').' : <br><br>'.$message.'</p><br>';
382  $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/view.php' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id;
383  $message_customer .= '<p>'.$langs->trans($see_ticket).' : <a href="'.$url_public_ticket.'">'.$url_public_ticket.'</a></p>';
384  $message_customer .= '<p>'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'</p>';
385 
386  $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>';
387 
388  $trackid = 'tic'.$object->id;
389 
390  $old_MAIN_MAIL_AUTOCOPY_TO = getDolGlobalString('MAIN_MAIL_AUTOCOPY_TO');
391 
392  if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
393  $conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
394  }
395 
396  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
397  $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket');
398  if ($mailfile->error) {
399  dol_syslog($mailfile->error, LOG_DEBUG);
400  } else {
401  $result = $mailfile->sendfile();
402  if ($result) {
403  // update last_msg_sent date
404  $object->fetch($object->id);
405  $object->date_last_msg_sent = dol_now();
406  $object->update($user);
407  }
408  }
409  if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
410  $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
411  }
412  }
413 }
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class to stock current configuration.
Definition: conf.class.php:34
Class to manage contact/addresses.
Class that all the triggers must extend.
Class to manage standard extra fields.
Class of triggers for ticket module.
composeAndSendCustomerMessage($sendto, $base_subject, $body, $see_ticket, Ticket $object, Translate $langs)
Composes and sends a message concerning a ticket, to be sent to customer addresses.
runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
Function called when a Dolibarrr business event is done.
composeAndSendAdminMessage($sendto, $base_subject, $body, Ticket $object, Translate $langs)
Composes and sends a message concerning a ticket, to be sent to admin address.
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:47
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_now($mode='auto')
Return date for now.
dol_eval($s, $returnvalue=0, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_textishtml($msg, $option=0)
Return if a text is a html content.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Class to generate the form for creating a new ticket.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:122
$conf db
API class for accounts.
Definition: inc.php:41