dolibarr  13.0.2
html.formticket.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2013-2015 Jean-François FERRY <hello@librethic.io>
3  * Copyright (C) 2016 Christophe Battarel <christophe@altairis.fr>
4  * Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
5  * Copyright (C) 2021 Juanjo Menent <jmenent@2byte.es>
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 2 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 
26 require_once DOL_DOCUMENT_ROOT."/core/class/html.form.class.php";
27 require_once DOL_DOCUMENT_ROOT."/core/class/html.formmail.class.php";
28 require_once DOL_DOCUMENT_ROOT."/core/class/html.formprojet.class.php";
29 
30 if (!class_exists('FormCompany')) {
31  include DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
32 }
33 
43 {
47  public $db;
48 
49  public $track_id;
50 
54  public $fk_user_create;
55 
56  public $message;
57  public $topic_title;
58 
59  public $action;
60 
61  public $withtopic;
62  public $withemail;
67  public $withsubstit;
68 
69  public $withfile;
70  public $withfilereadonly;
71 
72  public $ispublic; // To show information or not into public form
73 
74  public $withtitletopic;
75  public $withcompany; // affiche liste déroulante company
76  public $withfromsocid;
77  public $withfromcontactid;
78  public $withnotifytiersatcreate;
79  public $withusercreate; // Show name of creating user in form
80  public $withcreatereadonly;
81 
82  public $withref; // Show ref field
83 
84  public $withcancel;
85 
90  public $substit = array();
91  public $param = array();
92 
96  public $error;
97 
98 
104  public function __construct($db)
105  {
106  $this->db = $db;
107 
108  $this->action = 'add';
109 
110  $this->withcompany = 1;
111  $this->withfromsocid = 0;
112  $this->withfromcontactid = 0;
113  //$this->withthreadid=0;
114  //$this->withtitletopic='';
115  $this->withnotifytiersatcreate = 0;
116  $this->withusercreate = 1;
117  $this->withcreatereadonly = 1;
118  $this->withemail = 0;
119  $this->withref = 0;
120  $this->withextrafields = 0; // Show extrafields or not
121  //$this->withtopicreadonly=0;
122  }
123 
131  public function showForm($withdolfichehead = 0, $mode = 'edit')
132  {
133  global $conf, $langs, $user, $hookmanager;
134 
135  // Load translation files required by the page
136  $langs->loadLangs(array('other', 'mails', 'ticket'));
137 
138  $form = new Form($this->db);
139  $formcompany = new FormCompany($this->db);
140  $ticketstatic = new Ticket($this->db);
141 
142  $soc = new Societe($this->db);
143  if (!empty($this->withfromsocid) && $this->withfromsocid > 0) {
144  $soc->fetch($this->withfromsocid);
145  }
146 
147  $ticketstat = new Ticket($this->db);
148 
149  $extrafields = new ExtraFields($this->db);
150  $extrafields->fetch_name_optionals_label($ticketstat->table_element);
151 
152  print "\n<!-- Begin form TICKET -->\n";
153 
154  if ($withdolfichehead) print dol_get_fiche_head(null, 'card', '', 0, '');
155 
156  print '<form method="POST" '.($withdolfichehead ? '' : 'style="margin-bottom: 30px;" ').'name="ticket" id="form_create_ticket" enctype="multipart/form-data" action="'.$this->param["returnurl"].'">';
157  print '<input type="hidden" name="token" value="'.newToken().'">';
158  print '<input type="hidden" name="action" value="'.$this->action.'">';
159  foreach ($this->param as $key => $value) {
160  print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
161  }
162  print '<input type="hidden" name="fk_user_create" value="'.$this->fk_user_create.'">';
163 
164  print '<table class="border centpercent">';
165 
166  if ($this->withref) {
167  // Ref
168  $defaultref = $ticketstat->getDefaultRef();
169  print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td><input size="18" type="text" name="ref" value="'.(GETPOST("ref", 'alpha') ? GETPOST("ref", 'alpha') : $defaultref).'"></td></tr>';
170  }
171 
172  // TITLE
173  if ($this->withemail) {
174  print '<tr><td class="titlefield"><label for="email"><span class="fieldrequired">'.$langs->trans("Email").'</span></label></td><td>';
175  print '<input class="text minwidth200" id="email" name="email" value="'.(GETPOST('email', 'alpha') ? GETPOST('email', 'alpha') : $subject).'" />';
176  print '</td></tr>';
177  }
178 
179  // If ticket created from another object
180  if (isset($this->param['origin']) && $this->param['originid'] > 0) {
181  // Parse element/subelement (ex: project_task)
182  $element = $subelement = $this->param['origin'];
183  if (preg_match('/^([^_]+)_([^_]+)/i', $this->param['origin'], $regs)) {
184  $element = $regs[1];
185  $subelement = $regs[2];
186  }
187 
188  dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
189  $classname = ucfirst($subelement);
190  $objectsrc = new $classname($this->db);
191  $objectsrc->fetch(GETPOST('originid', 'int'));
192 
193  if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
194  $objectsrc->fetch_lines();
195  }
196 
197  $objectsrc->fetch_thirdparty();
198  $newclassname = $classname;
199  print '<tr><td>'.$langs->trans($newclassname).'</td><td colspan="2"><input name="'.$subelement.'id" value="'.GETPOST('originid').'" type="hidden" />'.$objectsrc->getNomUrl(1).'</td></tr>';
200  }
201 
202  // Type
203  print '<tr><td class="titlefield"><span class="fieldrequired"><label for="selecttype_code">'.$langs->trans("TicketTypeRequest").'</span></label></td><td>';
204  $this->selectTypesTickets((GETPOST('type_code', 'alpha') ? GETPOST('type_code', 'alpha') : $this->type_code), 'type_code', '', 2, 0, 0, 0, 'minwidth200');
205  print '</td></tr>';
206 
207  // Group
208  print '<tr><td><span class="fieldrequired"><label for="selectcategory_code">'.$langs->trans("TicketCategory").'</span></label></td><td>';
209  $this->selectGroupTickets((GETPOST('category_code') ? GETPOST('category_code') : $this->category_code), 'category_code', '', 2, 0, 0, 0, 'minwidth200');
210  print '</td></tr>';
211 
212  // Severity
213  print '<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans("TicketSeverity").'</span></label></td><td>';
214  $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 0);
215  print '</td></tr>';
216 
217  // Subject
218  if ($this->withtitletopic) {
219  print '<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans("Subject").'</span></label></td><td>';
220 
221  // Réponse à un ticket : affichage du titre du thread en readonly
222  if ($this->withtopicreadonly) {
223  print $langs->trans('SubjectAnswerToTicket').' '.$this->topic_title;
224  print '</td></tr>';
225  } else {
226  if ($this->withthreadid > 0) {
227  $subject = $langs->trans('SubjectAnswerToTicket').' '.$this->withthreadid.' : '.$this->topic_title.'';
228  }
229  print '<input class="text minwidth500" id="subject" name="subject" value="'.(GETPOST('subject', 'alpha') ? GETPOST('subject', 'alpha') : $subject).'" autofocus />';
230  print '</td></tr>';
231  }
232  }
233 
234  // MESSAGE
235  $msg = GETPOSTISSET('message') ? GETPOST('message', 'restricthtml') : '';
236  print '<tr><td><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span></label></td><td>';
237 
238  // If public form, display more information
239  $toolbarname = 'dolibarr_notes';
240  if ($this->ispublic)
241  {
242  $toolbarname = 'dolibarr_details';
243  print '<div class="warning">'.($conf->global->TICKET_PUBLIC_TEXT_HELP_MESSAGE ? $conf->global->TICKET_PUBLIC_TEXT_HELP_MESSAGE : $langs->trans('TicketPublicPleaseBeAccuratelyDescribe')).'</div>';
244  }
245  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
246  $uselocalbrowser = true;
247  $doleditor = new DolEditor('message', $msg, '100%', 230, $toolbarname, 'In', true, $uselocalbrowser, $conf->global->FCKEDITOR_ENABLE_TICKET, ROWS_8, '90%');
248  $doleditor->Create();
249  print '</td></tr>';
250 
251 
252  // Attached files
253  if (!empty($this->withfile)) {
254  // Define list of attached files
255  $listofpaths = array();
256  $listofnames = array();
257  $listofmimes = array();
258  if (!empty($_SESSION["listofpaths"])) {
259  $listofpaths = explode(';', $_SESSION["listofpaths"]);
260  }
261 
262  if (!empty($_SESSION["listofnames"])) {
263  $listofnames = explode(';', $_SESSION["listofnames"]);
264  }
265 
266  if (!empty($_SESSION["listofmimes"])) {
267  $listofmimes = explode(';', $_SESSION["listofmimes"]);
268  }
269 
270  $out = '<tr>';
271  $out .= '<td>'.$langs->trans("MailFile").'</td>';
272  $out .= '<td>';
273  // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
274  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
275  $out .= '<script type="text/javascript" language="javascript">';
276  $out .= 'jQuery(document).ready(function () {';
277  $out .= ' jQuery(".removedfile").click(function() {';
278  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
279  $out .= ' });';
280  $out .= '})';
281  $out .= '</script>'."\n";
282  if (count($listofpaths)) {
283  foreach ($listofpaths as $key => $val) {
284  $out .= '<div id="attachfile_'.$key.'">';
285  $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
286  if (!$this->withfilereadonly) {
287  $out .= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key + 1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
288  }
289  $out .= '<br></div>';
290  }
291  } else {
292  $out .= $langs->trans("NoAttachedFiles").'<br>';
293  }
294  if ($this->withfile == 2) { // Can add other files
295  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
296  $out .= ' ';
297  $out .= '<input type="submit" class="button" id="addfile" name="addfile" value="'.$langs->trans("MailingAddFile").'" />';
298  }
299  $out .= "</td></tr>\n";
300 
301  print $out;
302  }
303 
304  // User of creation
305  if ($this->withusercreate > 0 && $this->fk_user_create) {
306  print '<tr><td class="titlefield">'.$langs->trans("CreatedBy").'</td><td>';
307  $langs->load("users");
308  $fuser = new User($this->db);
309 
310  if ($this->withcreatereadonly) {
311  if ($res = $fuser->fetch($this->fk_user_create)) {
312  print $fuser->getNomUrl(1);
313  }
314  }
315  print ' &nbsp; ';
316  print "</td></tr>\n";
317  }
318 
319  // Customer or supplier
320  if ($this->withcompany) {
321  // altairis: force company and contact id for external user
322  if (empty($user->socid)) {
323  // Company
324  print '<tr><td class="titlefield">'.$langs->trans("ThirdParty").'</td><td>';
325  $events = array();
326  $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php', 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
327  print img_picto('', 'company', 'class="paddingright"');
328  print $form->select_company($this->withfromsocid, 'socid', '', 1, 1, '', $events, 0, 'minwidth200');
329  print '</td></tr>';
330  if (!empty($conf->use_javascript_ajax) && !empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) {
331  $htmlname = 'socid';
332  print '<script type="text/javascript">
333  $(document).ready(function () {
334  jQuery("#'.$htmlname.'").change(function () {
335  var obj = '.json_encode($events).';
336  $.each(obj, function(key,values) {
337  if (values.method.length) {
338  runJsCodeForEvent'.$htmlname.'(values);
339  }
340  });
341  });
342 
343  function runJsCodeForEvent'.$htmlname.'(obj) {
344  console.log("Run runJsCodeForEvent'.$htmlname.'");
345  var id = $("#'.$htmlname.'").val();
346  var method = obj.method;
347  var url = obj.url;
348  var htmlname = obj.htmlname;
349  var showempty = obj.showempty;
350  $.getJSON(url,
351  {
352  action: method,
353  id: id,
354  htmlname: htmlname,
355  showempty: showempty
356  },
357  function(response) {
358  $.each(obj.params, function(key,action) {
359  if (key.length) {
360  var num = response.num;
361  if (num > 0) {
362  $("#" + key).removeAttr(action);
363  } else {
364  $("#" + key).attr(action, action);
365  }
366  }
367  });
368  $("select#" + htmlname).html(response.value);
369  if (response.num) {
370  var selecthtml_str = response.value;
371  var selecthtml_dom=$.parseHTML(selecthtml_str);
372  $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
373  } else {
374  $("#inputautocomplete"+htmlname).val("");
375  }
376  $("select#" + htmlname).change(); /* Trigger event change */
377  }
378  );
379  }
380  });
381  </script>';
382  }
383 
384  // Contact and type
385  print '<tr><td>'.$langs->trans("Contact").'</td><td>';
386  // If no socid, set to -1 to avoid full contacts list
387  $selectedCompany = ($this->withfromsocid > 0) ? $this->withfromsocid : -1;
388  print img_picto('', 'contact', 'class="paddingright"');
389  print $form->selectcontacts($selectedCompany, $this->withfromcontactid, 'contactid', 3, '', '', 0, 'minwidth200');
390  print ' ';
391  $formcompany->selectTypeContact($ticketstatic, '', 'type', 'external', '', 0, 'maginleftonly');
392  print '</td></tr>';
393  } else {
394  print '<tr><td class="titlefield"><input type="hidden" name="socid" value="'.$user->socid.'"/></td>';
395  print '<td><input type="hidden" name="contactid" value="'.$user->contact_id.'"/></td>';
396  print '<td><input type="hidden" name="type" value="Z"/></td></tr>';
397  }
398 
399  // Notify thirdparty at creation
400  if (empty($this->ispublic))
401  {
402  print '<tr><td><label for="notify_tiers_at_create">'.$langs->trans("TicketNotifyTiersAtCreation").'</label></td><td>';
403  print '<input type="checkbox" id="notify_tiers_at_create" name="notify_tiers_at_create"'.($this->withnotifytiersatcreate ? ' checked="checked"' : '').'>';
404  print '</td></tr>';
405  }
406  }
407 
408  if (!empty($conf->projet->enabled) && !$this->ispublic)
409  {
410  $formproject = new FormProjets($this->db);
411  print '<tr><td><label for="project"><span class="">'.$langs->trans("Project").'</span></label></td><td>';
412  print img_picto('', 'project').$formproject->select_projects(-1, GETPOST('projectid', 'int'), 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
413  print '</td></tr>';
414  }
415 
416  // Other attributes
417  $parameters = array();
418  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $ticketstat, $this->action); // Note that $action and $object may have been modified by hook
419  if (empty($reshook))
420  {
421  print $ticketstat->showOptionals($extrafields, 'create');
422  }
423 
424  print '</table>';
425 
426  if ($withdolfichehead) print dol_get_fiche_end();
427 
428  print '<div class="center">';
429  print '<input class="button" type="submit" name="add" value="'.$langs->trans(($this->withthreadid > 0 ? "SendResponse" : "NewTicket")).'" />';
430  if ($this->withcancel) {
431  print " &nbsp; &nbsp; &nbsp;";
432  print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
433  }
434  print '</div>';
435 
436  print "</form>\n";
437  print "<!-- End form TICKET -->\n";
438  }
439 
453  public function selectTypesTickets($selected = '', $htmlname = 'tickettype', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '')
454  {
455  global $langs, $user;
456 
457  $ticketstat = new Ticket($this->db);
458 
459  dol_syslog(get_class($this)."::select_types_tickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
460 
461  $filterarray = array();
462 
463  if ($filtertype != '' && $filtertype != '-1') {
464  $filterarray = explode(',', $filtertype);
465  }
466 
467  $ticketstat->loadCacheTypesTickets();
468 
469  print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
470  if ($empty) {
471  print '<option value="">&nbsp;</option>';
472  }
473 
474  if (is_array($ticketstat->cache_types_tickets) && count($ticketstat->cache_types_tickets)) {
475  foreach ($ticketstat->cache_types_tickets as $id => $arraytypes) {
476  // On passe si on a demande de filtrer sur des modes de paiments particuliers
477  if (count($filterarray) && !in_array($arraytypes['type'], $filterarray)) {
478  continue;
479  }
480 
481  // We discard empty line if showempty is on because an empty line has already been output.
482  if ($empty && empty($arraytypes['code'])) {
483  continue;
484  }
485 
486  if ($format == 0) {
487  print '<option value="'.$id.'"';
488  }
489 
490  if ($format == 1) {
491  print '<option value="'.$arraytypes['code'].'"';
492  }
493 
494  if ($format == 2) {
495  print '<option value="'.$arraytypes['code'].'"';
496  }
497 
498  if ($format == 3) {
499  print '<option value="'.$id.'"';
500  }
501 
502  // Si selected est text, on compare avec code, sinon avec id
503  if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code']) {
504  print ' selected="selected"';
505  } elseif ($selected == $id) {
506  print ' selected="selected"';
507  } elseif ($arraytypes['use_default'] == "1" && !$selected && !$empty) {
508  print ' selected="selected"';
509  }
510 
511  print '>';
512  $value = '&nbsp;';
513  if ($format == 0) {
514  $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
515  } elseif ($format == 1) {
516  $value = $arraytypes['code'];
517  } elseif ($format == 2) {
518  $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
519  } elseif ($format == 3) {
520  $value = $arraytypes['code'];
521  }
522 
523  print $value;
524  print '</option>';
525  }
526  }
527  print '</select>';
528  if ($user->admin && !$noadmininfo) {
529  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
530  }
531 
532  print ajax_combobox('select'.$htmlname);
533  }
534 
548  public function selectGroupTickets($selected = '', $htmlname = 'ticketcategory', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '')
549  {
550  global $langs, $user;
551 
552  $ticketstat = new Ticket($this->db);
553 
554  dol_syslog(get_class($this)."::selectCategoryTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
555 
556  $filterarray = array();
557 
558  if ($filtertype != '' && $filtertype != '-1') {
559  $filterarray = explode(',', $filtertype);
560  }
561 
562  $ticketstat->loadCacheCategoriesTickets();
563 
564  print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
565  if ($empty) {
566  print '<option value="">&nbsp;</option>';
567  }
568 
569  if (is_array($ticketstat->cache_category_tickets) && count($ticketstat->cache_category_tickets)) {
570  foreach ($ticketstat->cache_category_tickets as $id => $arraycategories) {
571  // On passe si on a demande de filtrer sur des modes de paiments particuliers
572  if (count($filterarray) && !in_array($arraycategories['type'], $filterarray)) {
573  continue;
574  }
575 
576  // We discard empty line if showempty is on because an empty line has already been output.
577  if ($empty && empty($arraycategories['code'])) {
578  continue;
579  }
580 
581  if ($format == 0) {
582  print '<option value="'.$id.'"';
583  }
584 
585  if ($format == 1) {
586  print '<option value="'.$arraycategories['code'].'"';
587  }
588 
589  if ($format == 2) {
590  print '<option value="'.$arraycategories['code'].'"';
591  }
592 
593  if ($format == 3) {
594  print '<option value="'.$id.'"';
595  }
596 
597  // Si selected est text, on compare avec code, sinon avec id
598  if (preg_match('/[a-z]/i', $selected) && $selected == $arraycategories['code']) {
599  print ' selected="selected"';
600  } elseif ($selected == $id) {
601  print ' selected="selected"';
602  } elseif ($arraycategories['use_default'] == "1" && !$selected && !$empty) {
603  print ' selected="selected"';
604  }
605 
606  print '>';
607 
608  if ($format == 0) {
609  $value = ($maxlength ? dol_trunc($arraycategories['label'], $maxlength) : $arraycategories['label']);
610  }
611 
612  if ($format == 1) {
613  $value = $arraycategories['code'];
614  }
615 
616  if ($format == 2) {
617  $value = ($maxlength ? dol_trunc($arraycategories['label'], $maxlength) : $arraycategories['label']);
618  }
619 
620  if ($format == 3) {
621  $value = $arraycategories['code'];
622  }
623 
624  print $value ? $value : '&nbsp;';
625  print '</option>';
626  }
627  }
628  print '</select>';
629  if ($user->admin && !$noadmininfo) {
630  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
631  }
632 
633  print ajax_combobox('select'.$htmlname);
634  }
635 
649  public function selectSeveritiesTickets($selected = '', $htmlname = 'ticketseverity', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '')
650  {
651  global $langs, $user;
652 
653  $ticketstat = new Ticket($this->db);
654 
655  dol_syslog(get_class($this)."::selectSeveritiesTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
656 
657  $filterarray = array();
658 
659  if ($filtertype != '' && $filtertype != '-1') {
660  $filterarray = explode(',', $filtertype);
661  }
662 
663  $ticketstat->loadCacheSeveritiesTickets();
664 
665  print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
666  if ($empty) {
667  print '<option value="">&nbsp;</option>';
668  }
669 
670  if (is_array($ticketstat->cache_severity_tickets) && count($ticketstat->cache_severity_tickets)) {
671  foreach ($ticketstat->cache_severity_tickets as $id => $arrayseverities) {
672  // On passe si on a demande de filtrer sur des modes de paiments particuliers
673  if (count($filterarray) && !in_array($arrayseverities['type'], $filterarray)) {
674  continue;
675  }
676 
677  // We discard empty line if showempty is on because an empty line has already been output.
678  if ($empty && empty($arrayseverities['code'])) {
679  continue;
680  }
681 
682  if ($format == 0) {
683  print '<option value="'.$id.'"';
684  }
685 
686  if ($format == 1) {
687  print '<option value="'.$arrayseverities['code'].'"';
688  }
689 
690  if ($format == 2) {
691  print '<option value="'.$arrayseverities['code'].'"';
692  }
693 
694  if ($format == 3) {
695  print '<option value="'.$id.'"';
696  }
697 
698  // Si selected est text, on compare avec code, sinon avec id
699  if (preg_match('/[a-z]/i', $selected) && $selected == $arrayseverities['code']) {
700  print ' selected="selected"';
701  } elseif ($selected == $id) {
702  print ' selected="selected"';
703  } elseif ($arrayseverities['use_default'] == "1" && !$selected && !$empty) {
704  print ' selected="selected"';
705  }
706 
707  print '>';
708  if ($format == 0) {
709  $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
710  }
711 
712  if ($format == 1) {
713  $value = $arrayseverities['code'];
714  }
715 
716  if ($format == 2) {
717  $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
718  }
719 
720  if ($format == 3) {
721  $value = $arrayseverities['code'];
722  }
723 
724  print $value ? $value : '&nbsp;';
725  print '</option>';
726  }
727  }
728  print '</select>';
729  if ($user->admin && !$noadmininfo) {
730  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
731  }
732 
733  print ajax_combobox('select'.$htmlname);
734  }
735 
736  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
742  public function clear_attached_files()
743  {
744  // phpcs:enable
745  global $conf, $user;
746  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
747 
748  // Set tmp user directory
749  $vardir = $conf->user->dir_output."/".$user->id;
750  $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
751  if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir);
752 
753  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
754  unset($_SESSION["listofpaths".$keytoavoidconflict]);
755  unset($_SESSION["listofnames".$keytoavoidconflict]);
756  unset($_SESSION["listofmimes".$keytoavoidconflict]);
757  }
758 
765  public function showMessageForm($width = '40%')
766  {
767  global $conf, $langs, $user, $hookmanager, $form, $mysoc;
768 
769  $formmail = new FormMail($this->db);
770  $addfileaction = 'addfile';
771 
772  if (!is_object($form)) $form = new Form($this->db);
773 
774  // Load translation files required by the page
775  $langs->loadLangs(array('other', 'mails'));
776 
777  // Clear temp files. Must be done at beginning, before call of triggers
778  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1'))
779  {
780  $this->clear_attached_files();
781  }
782 
783  // Define output language
784  $outputlangs = $langs;
785  $newlang = '';
786  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $this->param['langsmodels'];
787  if (!empty($newlang))
788  {
789  $outputlangs = new Translate("", $conf);
790  $outputlangs->setDefaultLang($newlang);
791  $outputlangs->load('other');
792  }
793 
794  // Get message template for $this->param["models"] into c_email_templates
795  $arraydefaultmessage = -1;
796  if ($this->param['models'] != 'none')
797  {
798  $model_id = 0;
799  if (array_key_exists('models_id', $this->param))
800  {
801  $model_id = $this->param["models_id"];
802  }
803 
804  $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one
805  }
806 
807  // Define list of attached files
808  $listofpaths = array();
809  $listofnames = array();
810  $listofmimes = array();
811  $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
812 
813  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1'))
814  {
815  if (!empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit']))
816  {
817  foreach ($this->param['fileinit'] as $file)
818  {
819  $this->add_attached_files($file, basename($file), dol_mimetype($file));
820  }
821  }
822  }
823 
824  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
825  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
826  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
827 
828  // Define output language
829  $outputlangs = $langs;
830  $newlang = '';
831  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
832  $newlang = $this->param['langsmodels'];
833  }
834  if (!empty($newlang)) {
835  $outputlangs = new Translate("", $conf);
836  $outputlangs->setDefaultLang($newlang);
837  $outputlangs->load('other');
838  }
839 
840  print "\n<!-- Begin message_form TICKET -->\n";
841 
842  $send_email = GETPOST('send_email', 'int') ? GETPOST('send_email', 'int') : 0;
843 
844  // Example 1 : Adding jquery code
845  print '<script type="text/javascript" language="javascript">
846  jQuery(document).ready(function() {
847  send_email=' . $send_email.';
848  if (send_email) {
849  jQuery(".email_line").show();
850  } else {
851  jQuery(".email_line").hide();
852  }
853 
854  jQuery("#send_msg_email").click(function() {
855  if(jQuery(this).is(":checked")) {
856  jQuery(".email_line").show();
857  }
858  else {
859  jQuery(".email_line").hide();
860  }
861  });';
862  print '});
863  </script>';
864 
865  print '<form method="post" name="ticket" enctype="multipart/form-data" action="'.$this->param["returnurl"].'">';
866  print '<input type="hidden" name="token" value="'.newToken().'">';
867  print '<input type="hidden" name="action" value="'.$this->action.'">';
868  print '<input type="hidden" name="actionbis" value="add_message">';
869  foreach ($this->param as $key => $value) {
870  print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
871  }
872 
873  // Get message template
874  $model_id = 0;
875  if (array_key_exists('models_id', $this->param)) {
876  $model_id = $this->param["models_id"];
877  $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);
878  }
879 
880  $result = $formmail->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
881  if ($result < 0) {
882  setEventMessages($this->error, $this->errors, 'errors');
883  }
884  $modelmail_array = array();
885  foreach ($formmail->lines_model as $line) {
886  $modelmail_array[$line->id] = $line->label;
887  }
888 
889  print '<table class="border" width="'.$width.'">';
890 
891  // External users can't send message email
892  if ($user->rights->ticket->write && !$user->socid)
893  {
894  print '<tr><td></td><td>';
895  $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : '');
896  print '<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.'/> ';
897  print '<label for="send_msg_email">'.$langs->trans('SendMessageByEmail').'</label>';
898  print '</td></tr>';
899 
900  // Zone to select its email template
901  if (count($modelmail_array) > 0) {
902  print '<tr class="email_line"><td></td><td colspan="2"><div style="padding: 3px 0 3px 0">'."\n";
903  print $langs->trans('SelectMailModel').': '.$formmail->selectarray('modelmailselected', $modelmail_array, $this->param['models_id'], 1);
904  if ($user->admin) {
905  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
906  }
907  print ' &nbsp; ';
908  print '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
909  print '</div></td>';
910  }
911 
912  // Private message (not visible by customer/external user)
913  if (!$user->socid) {
914  print '<tr><td></td><td>';
915  $checkbox_selected = (GETPOST('private_message', 'alpha') == "1" ? ' checked' : '');
916  print '<input type="checkbox" name="private_message" value="1" id="private_message" '.$checkbox_selected.'/> ';
917  print '<label for="private_message">'.$langs->trans('MarkMessageAsPrivate').'</label>';
918  print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
919  print '</td></tr>';
920  }
921 
922  // Subject
923  print '<tr class="email_line"><td class="titlefieldcreate">'.$langs->trans('Subject').'</td>';
924  print '<td><input type="text" class="text minwidth500" name="subject" value="['.$conf->global->MAIN_INFO_SOCIETE_NOM.' - '.$langs->trans("Ticket").' '.$this->ref.'] '.$langs->trans('TicketNewMessage').'" />';
925  print '</td></tr>';
926 
927  // Destinataires
928  print '<tr class="email_line"><td>'.$langs->trans('MailRecipients').'</td><td>';
929  $ticketstat = new Ticket($this->db);
930  $res = $ticketstat->fetch('', '', $this->track_id);
931  if ($res) {
932  // Retrieve email of all contacts (internal and external)
933  $contacts = $ticketstat->getInfosTicketInternalContact();
934  $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact());
935 
936  // Build array to display recipient list
937  if (is_array($contacts) && count($contacts) > 0) {
938  foreach ($contacts as $key => $info_sendto) {
939  if ($info_sendto['email'] != '') {
940  $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">").' <small class="opacitymedium">('.dol_escape_htmltag($info_sendto['libelle']).")</small>";
941  }
942  }
943  }
944 
945  if ($ticketstat->origin_email && !in_array($this->dao->origin_email, $sendto)) {
946  $sendto[] = dol_escape_htmltag($ticketstat->origin_email).' <small class="opacitymedium">('.$langs->trans("TicketEmailOriginIssuer").")</small>";
947  }
948 
949  if ($ticketstat->fk_soc > 0) {
950  $ticketstat->socid = $ticketstat->fk_soc;
951  $ticketstat->fetch_thirdparty();
952 
953  if (is_array($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) {
954  $sendto[] = $ticketstat->thirdparty->email.' <small class="opacitymedium">('.$langs->trans('Customer').')</small>';
955  }
956  }
957 
958  if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) {
959  $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' <small class="opacitymedium">(generic email)</small>';
960  }
961 
962  // Print recipient list
963  if (is_array($sendto) && count($sendto) > 0) {
964  print implode(', ', $sendto);
965  } else {
966  print '<div class="warning">'.$langs->trans('WarningNoEMailsAdded').' '.$langs->trans('TicketGoIntoContactTab').'</div>';
967  }
968  }
969  print '</td></tr>';
970  }
971 
972  // Intro
973  // External users can't send message email
974  if ($user->rights->ticket->write && !$user->socid) {
975  $mail_intro = GETPOST('mail_intro') ? GETPOST('mail_intro') : $conf->global->TICKET_MESSAGE_MAIL_INTRO;
976  print '<tr class="email_line"><td><label for="mail_intro">';
977  print $form->textwithpicto($langs->trans("TicketMessageMailIntro"), $langs->trans("TicketMessageMailIntroHelp"), 1, 'help');
978  print '</label>';
979 
980  print '</td><td>';
981  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
982  $uselocalbrowser = true;
983 
984  $doleditor = new DolEditor('mail_intro', $mail_intro, '100%', 90, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_2, 70);
985 
986  $doleditor->Create();
987  print '</td></tr>';
988  }
989 
990  // MESSAGE
991  $defaultmessage = "";
992  if (is_object($arraydefaultmessage) && $arraydefaultmessage->content) {
993  $defaultmessage = $arraydefaultmessage->content;
994  }
995  $defaultmessage = str_replace('\n', "\n", $defaultmessage);
996 
997  // Deal with format differences between message and signature (text / HTML)
998  if (dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
999  $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
1000  } elseif (!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1001  $defaultmessage = dol_nl2br($defaultmessage);
1002  }
1003  if (GETPOSTISSET("message") && !$_POST['modelselected']) {
1004  $defaultmessage = GETPOST('message', 'restricthtml');
1005  } else {
1006  $defaultmessage = make_substitutions($defaultmessage, $this->substit);
1007  // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
1008  $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
1009  $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
1010  }
1011 
1012  print '<tr><td class="tdtop"><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span>';
1013  if ($user->rights->ticket->write && !$user->socid) {
1014  print $form->textwithpicto('', $langs->trans("TicketMessageHelp"), 1, 'help');
1015  }
1016  print '</label></td><td>';
1017  //$toolbarname = 'dolibarr_details';
1018  $toolbarname = 'dolibarr_notes';
1019  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1020  $doleditor = new DolEditor('message', $defaultmessage, '100%', 200, $toolbarname, '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, 70);
1021  $doleditor->Create();
1022  print '</td></tr>';
1023 
1024  // Signature
1025  // External users can't send message email
1026  if ($user->rights->ticket->write && !$user->socid) {
1027  $mail_signature = GETPOST('mail_signature') ? GETPOST('mail_signature') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE;
1028  print '<tr class="email_line"><td><label for="mail_intro">'.$langs->trans("TicketMessageMailSignature").'</label>';
1029  print $form->textwithpicto('', $langs->trans("TicketMessageMailSignatureHelp"), 1, 'help');
1030  print '</td><td>';
1031  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1032  $doleditor = new DolEditor('mail_signature', $mail_signature, '100%', 150, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_2, 70);
1033  $doleditor->Create();
1034  print '</td></tr>';
1035  }
1036 
1037  // Attached files
1038  if (!empty($this->withfile)) {
1039  $out = '<tr>';
1040  $out .= '<td width="180">'.$langs->trans("MailFile").'</td>';
1041  $out .= '<td>';
1042  // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
1043  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
1044  $out .= '<script type="text/javascript" language="javascript">';
1045  $out .= 'jQuery(document).ready(function () {';
1046  $out .= ' jQuery(".removedfile").click(function() {';
1047  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
1048  $out .= ' });';
1049  $out .= '})';
1050  $out .= '</script>'."\n";
1051  if (count($listofpaths)) {
1052  foreach ($listofpaths as $key => $val) {
1053  $out .= '<div id="attachfile_'.$key.'">';
1054  $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
1055  if (!$this->withfilereadonly) {
1056  $out .= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key + 1).'" class="removedfile reposition" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
1057  }
1058  $out .= '<br></div>';
1059  }
1060  } else {
1061  $out .= $langs->trans("NoAttachedFiles").'<br>';
1062  }
1063  if ($this->withfile == 2) { // Can add other files
1064  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
1065  $out .= ' ';
1066  $out .= '<input type="submit" class="button" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
1067  }
1068  $out .= "</td></tr>\n";
1069 
1070  print $out;
1071  }
1072 
1073  print '</table>';
1074 
1075  print '<center><br>';
1076  print '<input class="button" type="submit" name="btn_add_message" value="'.$langs->trans("AddMessage").'" />';
1077  if ($this->withcancel) {
1078  print " &nbsp; &nbsp; ";
1079  print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
1080  }
1081  print "</center>\n";
1082 
1083  print "</form>\n";
1084  print "<!-- End form TICKET -->\n";
1085  }
1086 }
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname= '')
Make an include_once using default root and alternate root if it fails.
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Classe permettant la generation du formulaire html d&#39;envoi de mail unitaire Usage: $formail = new For...
selectSeveritiesTickets($selected= '', $htmlname= 'ticketseverity', $filtertype= '', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $morecss= '')
Return html list of ticket severitys.
Class to manage Dolibarr users.
Definition: user.class.php:44
showForm($withdolfichehead=0, $mode= 'edit')
Show the form to input ticket.
showMessageForm($width= '40%')
Show the form to add message on ticket.
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete= 'resolve')
Convert a html select field into an ajax combobox.
Definition: ajax.lib.php:391
clear_attached_files()
Clear list of attached files in send mail form (also stored in session)
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
__construct($db)
Constructor.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
img_mime($file, $titlealt= '', $morecss= '')
Show MIME img of a file.
$conf db
API class for accounts.
Definition: inc.php:54
Class to manage ticket.
selectGroupTickets($selected= '', $htmlname= 'ticketcategory', $filtertype= '', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $morecss= '')
Return html list of ticket anaytic codes.
Class to build HTML component for third parties management Only common components are here...
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname.
Class to manage third parties objects (customers, suppliers, prospects...)
dol_mimetype($file, $default= 'application/octet-stream', $mode=0)
Return mime type of a file.
Class to manage building of HTML components.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories) ...
Definition: files.lib.php:1286
selectTypesTickets($selected= '', $htmlname= 'tickettype', $filtertype= '', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $morecss= '')
Return html list of tickets type.
Class to manage translations.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
print
Draft customers invoices.
Definition: index.php:89
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Class to manage a WYSIWYG editor.
dol_trunc($string, $size=40, $trunc= 'right', $stringencoding= 'UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding &#39;...&#39; if string larger than length.
make_substitutions($text, $substitutionarray, $outputlangs=null)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=&gt;newva...
if(!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN'
Draft customers invoices.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin= '1', $morecss= '', $textfordropdown= '')
Show information for admin users or standard users.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $keepmoretags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dol_textishtml($msg, $option=0)
Return if a text is a html content.