dolibarr  17.0.4
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  * Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
29 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
30 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
31 
32 if (!class_exists('FormCompany')) {
33  include DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
34 }
35 
45 {
49  public $db;
50 
54  public $track_id;
55 
59  public $fk_user_create;
60 
61  public $message;
62  public $topic_title;
63 
64  public $action;
65 
66  public $withtopic;
67  public $withemail;
68 
72  public $withsubstit;
73 
74  public $withfile;
75  public $withfilereadonly;
76 
77  public $backtopage;
78 
79  public $ispublic; // to show information or not into public form
80 
81  public $withtitletopic;
82  public $withtopicreadonly;
83  public $withreadid;
84 
85  public $withcompany; // to show company drop-down list
86  public $withfromsocid;
87  public $withfromcontactid;
88  public $withnotifytiersatcreate;
89  public $withusercreate; // to show name of creating user in form
90  public $withcreatereadonly;
91 
92  public $withref; // to show ref field
93 
94  public $withcancel;
95 
96  public $type_code;
97  public $category_code;
98  public $severity_code;
99 
100 
105  public $substit = array();
106  public $param = array();
107 
111  public $error;
112  public $errors = array();
113 
114 
120  public function __construct($db)
121  {
122  global $conf;
123 
124  $this->db = $db;
125 
126  $this->action = 'add';
127 
128  $this->withcompany = isModEnabled("societe");
129  $this->withfromsocid = 0;
130  $this->withfromcontactid = 0;
131  $this->withreadid=0;
132  //$this->withtitletopic='';
133  $this->withnotifytiersatcreate = 0;
134  $this->withusercreate = 1;
135  $this->withcreatereadonly = 1;
136  $this->withemail = 0;
137  $this->withref = 0;
138  $this->withextrafields = 0; // to show extrafields or not
139  //$this->withtopicreadonly=0;
140  }
141 
152  public function showForm($withdolfichehead = 0, $mode = 'edit', $public = 0, Contact $with_contact = null, $action = '')
153  {
154  global $conf, $langs, $user, $hookmanager;
155 
156  // Load translation files required by the page
157  $langs->loadLangs(array('other', 'mails', 'ticket'));
158 
159  $form = new Form($this->db);
160  $formcompany = new FormCompany($this->db);
161  $ticketstatic = new Ticket($this->db);
162 
163  $soc = new Societe($this->db);
164  if (!empty($this->withfromsocid) && $this->withfromsocid > 0) {
165  $soc->fetch($this->withfromsocid);
166  }
167 
168  $ticketstat = new Ticket($this->db);
169 
170  $extrafields = new ExtraFields($this->db);
171  $extrafields->fetch_name_optionals_label($ticketstat->table_element);
172 
173  print "\n<!-- Begin form TICKET -->\n";
174 
175  if ($withdolfichehead) {
176  print dol_get_fiche_head(null, 'card', '', 0, '');
177  }
178 
179  print '<form method="POST" '.($withdolfichehead ? '' : 'style="margin-bottom: 30px;" ').'name="ticket" id="form_create_ticket" enctype="multipart/form-data" action="'.(!empty($this->param["returnurl"]) ? $this->param["returnurl"] : $_SERVER['PHP_SELF']).'">';
180  print '<input type="hidden" name="token" value="'.newToken().'">';
181  print '<input type="hidden" name="action" value="'.$this->action.'">';
182  print '<input type="hidden" name="trackid" value="'.$this->trackid.'">';
183  foreach ($this->param as $key => $value) {
184  print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
185  }
186  print '<input type="hidden" name="fk_user_create" value="'.$this->fk_user_create.'">';
187 
188  print '<table class="border centpercent">';
189 
190  if ($this->withref) {
191  // Ref
192  $defaultref = $ticketstat->getDefaultRef();
193  print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td>';
194  print '<input type="text" name="ref" value="'.dol_escape_htmltag(GETPOST("ref", 'alpha') ? GETPOST("ref", 'alpha') : $defaultref).'">';
195  print '</td></tr>';
196  }
197 
198  // TITLE
199  $email = GETPOSTISSET('email') ? GETPOST('email', 'alphanohtml') : '';
200  if ($this->withemail) {
201  print '<tr><td class="titlefield"><label for="email"><span class="fieldrequired">'.$langs->trans("Email").'</span></label></td><td>';
202  print '<input class="text minwidth200" id="email" name="email" value="'.$email.'" autofocus>';
203  print '</td></tr>';
204 
205  if ($with_contact) {
206  // contact search and result
207  $html_contact_search = '';
208  $html_contact_search .= '<tr id="contact_search_line">';
209  $html_contact_search .= '<td class="titlefield">';
210  $html_contact_search .= '<label for="contact"><span class="fieldrequired">' . $langs->trans('Contact') . '</span></label>';
211  $html_contact_search .= '<input type="hidden" id="contact_id" name="contact_id" value="" />';
212  $html_contact_search .= '</td>';
213  $html_contact_search .= '<td id="contact_search_result"></td>';
214  $html_contact_search .= '</tr>';
215  print $html_contact_search;
216  // contact lastname
217  $html_contact_lastname = '';
218  $html_contact_lastname .= '<tr id="contact_lastname_line" class="contact_field"><td class="titlefield"><label for="contact_lastname"><span class="fieldrequired">' . $langs->trans('Lastname') . '</span></label></td><td>';
219  $html_contact_lastname .= '<input type="text" id="contact_lastname" name="contact_lastname" value="' . dol_escape_htmltag(GETPOSTISSET('contact_lastname') ? GETPOST('contact_lastname', 'alphanohtml') : '') . '" />';
220  $html_contact_lastname .= '</td></tr>';
221  print $html_contact_lastname;
222  // contact firstname
223  $html_contact_firstname = '';
224  $html_contact_firstname .= '<tr id="contact_firstname_line" class="contact_field"><td class="titlefield"><label for="contact_firstname"><span class="fieldrequired">' . $langs->trans('Firstname') . '</span></label></td><td>';
225  $html_contact_firstname .= '<input type="text" id="contact_firstname" name="contact_firstname" value="' . dol_escape_htmltag(GETPOSTISSET('contact_firstname') ? GETPOST('contact_firstname', 'alphanohtml') : '') . '" />';
226  $html_contact_firstname .= '</td></tr>';
227  print $html_contact_firstname;
228  // company name
229  $html_company_name = '';
230  $html_company_name .= '<tr id="contact_company_name_line" class="contact_field"><td><label for="company_name"><span>' . $langs->trans('Company') . '</span></label></td><td>';
231  $html_company_name .= '<input type="text" id="company_name" name="company_name" value="' . dol_escape_htmltag(GETPOSTISSET('company_name') ? GETPOST('company_name', 'alphanohtml') : '') . '" />';
232  $html_company_name .= '</td></tr>';
233  print $html_company_name;
234  // contact phone
235  $html_contact_phone = '';
236  $html_contact_phone .= '<tr id="contact_phone_line" class="contact_field"><td><label for="contact_phone"><span>' . $langs->trans('Phone') . '</span></label></td><td>';
237  $html_contact_phone .= '<input type="text" id="contact_phone" name="contact_phone" value="' . dol_escape_htmltag(GETPOSTISSET('contact_phone') ? GETPOST('contact_phone', 'alphanohtml') : '') . '" />';
238  $html_contact_phone .= '</td></tr>';
239  print $html_contact_phone;
240 
241  // search contact form email
242  $langs->load('errors');
243  print '<script type="text/javascript">
244  jQuery(document).ready(function() {
245  var contact = jQuery.parseJSON("'.dol_escape_js(json_encode($with_contact), 2).'");
246  jQuery("#contact_search_line").hide();
247  if (contact) {
248  if (contact.id > 0) {
249  jQuery("#contact_search_line").show();
250  jQuery("#contact_id").val(contact.id);
251  jQuery("#contact_search_result").html(contact.firstname+" "+contact.lastname);
252  jQuery(".contact_field").hide();
253  } else {
254  jQuery(".contact_field").show();
255  }
256  }
257 
258  jQuery("#email").change(function() {
259  jQuery("#contact_search_line").show();
260  jQuery("#contact_search_result").html("'.dol_escape_js($langs->trans('Select2SearchInProgress')).'");
261  jQuery("#contact_id").val("");
262  jQuery("#contact_lastname").val("");
263  jQuery("#contact_firstname").val("");
264  jQuery("#company_name").val("");
265  jQuery("#contact_phone").val("");
266 
267  jQuery.getJSON(
268  "'.dol_escape_js(dol_buildpath('/public/ticket/ajax/ajax.php', 1)).'",
269  {
270  action: "getContacts",
271  email: jQuery("#email").val()
272  },
273  function(response) {
274  if (response.error) {
275  jQuery("#contact_search_result").html("<span class=\"error\">"+response.error+"</span>");
276  } else {
277  var contact_list = response.contacts;
278  if (contact_list.length == 1) {
279  var contact = contact_list[0];
280  jQuery("#contact_id").val(contact.id);
281  jQuery("#contact_search_result").html(contact.firstname+" "+contact.lastname);
282  jQuery(".contact_field").hide();
283  } else if (contact_list.length <= 0) {
284  jQuery("#contact_search_line").hide();
285  jQuery(".contact_field").show();
286  }
287  }
288  }
289  ).fail(function(jqxhr, textStatus, error) {
290  var error_msg = "'.dol_escape_js($langs->trans('ErrorAjaxRequestFailed')).'"+" ["+textStatus+"] : "+error;
291  jQuery("#contact_search_result").html("<span class=\"error\">"+error_msg+"</span>");
292  });
293  });
294  });
295  </script>';
296  }
297  }
298 
299  // If ticket created from another object
300  $subelement = '';
301  if (isset($this->param['origin']) && $this->param['originid'] > 0) {
302  // Parse element/subelement (ex: project_task)
303  $element = $subelement = $this->param['origin'];
304  $regs = array();
305  if (preg_match('/^([^_]+)_([^_]+)/i', $this->param['origin'], $regs)) {
306  $element = $regs[1];
307  $subelement = $regs[2];
308  }
309 
310  dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
311  $classname = ucfirst($subelement);
312  $objectsrc = new $classname($this->db);
313  $objectsrc->fetch(GETPOST('originid', 'int'));
314 
315  if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
316  $objectsrc->fetch_lines();
317  }
318 
319  $objectsrc->fetch_thirdparty();
320  $newclassname = $classname;
321  print '<tr><td>'.$langs->trans($newclassname).'</td><td colspan="2"><input name="'.$subelement.'id" value="'.GETPOST('originid').'" type="hidden" />'.$objectsrc->getNomUrl(1).'</td></tr>';
322  }
323 
324  // Type of Ticket
325  print '<tr><td class="titlefield"><span class="fieldrequired"><label for="selecttype_code">'.$langs->trans("TicketTypeRequest").'</span></label></td><td>';
326  $this->selectTypesTickets((GETPOST('type_code', 'alpha') ? GETPOST('type_code', 'alpha') : $this->type_code), 'type_code', '', 2, 1, 0, 0, 'minwidth200');
327  print '</td></tr>';
328 
329  // Group => Category
330  print '<tr><td><span class="fieldrequired"><label for="selectcategory_code">'.$langs->trans("TicketCategory").'</span></label></td><td>';
331  $filter = '';
332  if ($public) {
333  $filter = 'public=1';
334  }
335  $selected = (GETPOST('category_code') ? GETPOST('category_code') : $this->category_code);
336  $this->selectGroupTickets($selected, 'category_code', $filter, 2, 1, 0, 0, 'minwidth200');
337  print '</td></tr>';
338 
339  // Severity => Priority
340  print '<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans("TicketSeverity").'</span></label></td><td>';
341  $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 1);
342  print '</td></tr>';
343 
344  if (!empty($conf->knowledgemanagement->enabled)) {
345  // KM Articles
346  print '<tr id="KWwithajax" class="hidden"><td></td></tr>';
347  print '<!-- Script to manage change of ticket group -->
348  <script>
349  jQuery(document).ready(function() {
350  function groupticketchange(){
351  console.log("We called groupticketchange, so we try to load list KM linked to event");
352  $("#KWwithajax").html("");
353  idgroupticket = $("#selectcategory_code").val();
354 
355  console.log("We have selected id="+idgroupticket);
356 
357  if (idgroupticket != "") {
358  $.ajax({ url: \''.DOL_URL_ROOT.'/core/ajax/fetchKnowledgeRecord.php\',
359  data: { action: \'getKnowledgeRecord\', idticketgroup: idgroupticket, token: \''.newToken().'\', lang:\''.$langs->defaultlang.'\', public:'.($public).' },
360  type: \'GET\',
361  success: function(response) {
362  var urllist = \'\';
363  console.log("We received response "+response);
364  if (typeof response == "object") {
365  console.log("response is already type object, no need to parse it");
366  } else {
367  console.log("response is type "+(typeof response));
368  response = JSON.parse(response);
369  }
370  for (key in response) {
371  answer = response[key].answer;
372  urllist += \'<li><a href="#" title="\'+response[key].title+\'" class="button_KMpopup" data-html="\'+answer+\'">\' +response[key].title+\'</a></li>\';
373  }
374  if (urllist != "") {
375  $("#KWwithajax").html(\'<td>'.$langs->trans("KMFoundForTicketGroup").'</td><td><ul>\'+urllist+\'</ul></td>\');
376  $("#KWwithajax").show();
377  $(".button_KMpopup").on("click",function(){
378  console.log("Open popup with jQuery(...).dialog() with KM article")
379  var $dialog = $("<div></div>").html($(this).attr("data-html"))
380  .dialog({
381  autoOpen: false,
382  modal: true,
383  height: (window.innerHeight - 150),
384  width: "80%",
385  title: $(this).attr("title"),
386  });
387  $dialog.dialog("open");
388  console.log($dialog);
389  })
390  }
391  },
392  error : function(output) {
393  console.error("Error on Fetch of KM articles");
394  },
395  });
396  }
397  };
398  $("#selectcategory_code").on("change",function() { groupticketchange(); });
399  if ($("#selectcategory_code").val() != "") {
400  groupticketchange();
401  }
402  });
403  </script>'."\n";
404  }
405 
406  // Subject
407  if ($this->withtitletopic) {
408  print '<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans("Subject").'</span></label></td><td>';
409  // Answer to a ticket : display of the thread title in readonly
410  if ($this->withtopicreadonly) {
411  print $langs->trans('SubjectAnswerToTicket').' '.$this->topic_title;
412  } else {
413  if (isset($this->withreadid) && $this->withreadid > 0) {
414  $subject = $langs->trans('SubjectAnswerToTicket').' '.$this->withreadid.' : '.$this->topic_title;
415  } else {
416  $subject = GETPOST('subject', 'alpha');
417  }
418  print '<input class="text minwidth500" id="subject" name="subject" value="'.$subject.'"'.(empty($this->withemail)?' autofocus':'').' />';
419  }
420  print '</td></tr>';
421  }
422 
423  // MESSAGE
424  $msg = GETPOSTISSET('message') ? GETPOST('message', 'restricthtml') : '';
425  print '<tr><td><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span></label></td><td>';
426 
427  // If public form, display more information
428  $toolbarname = 'dolibarr_notes';
429  if ($this->ispublic) {
430  $toolbarname = 'dolibarr_details';
431  print '<div class="warning hideonsmartphone">'.(getDolGlobalString("TICKET_PUBLIC_TEXT_HELP_MESSAGE", $langs->trans('TicketPublicPleaseBeAccuratelyDescribe'))).'</div>';
432  }
433  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
434  $uselocalbrowser = true;
435  $doleditor = new DolEditor('message', $msg, '100%', 230, $toolbarname, 'In', true, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_TICKET'), ROWS_8, '90%');
436  $doleditor->Create();
437  print '</td></tr>';
438 
439  if ($public && !empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA_TICKET)) {
440  require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
441  print '<tr><td class="titlefield"><label for="email"><span class="fieldrequired">'.$langs->trans("SecurityCode").'</span></label></td><td>';
442  print '<span class="span-icon-security inline-block">';
443  print '<input id="securitycode" placeholder="'.$langs->trans("SecurityCode").'" class="flat input-icon-security width125" type="text" maxlength="5" name="code" tabindex="3" />';
444  print '</span>';
445  print '<span class="nowrap inline-block">';
446  print '<img class="inline-block valignmiddle" src="'.DOL_URL_ROOT.'/core/antispamimage.php" border="0" width="80" height="32" id="img_securitycode" />';
447  print '<a class="inline-block valignmiddle" href="" tabindex="4" data-role="button">'.img_picto($langs->trans("Refresh"), 'refresh', 'id="captcha_refresh_img"').'</a>';
448  print '</span>';
449  print '</td></tr>';
450  }
451 
452  // Categories
453  if (isModEnabled('categorie')) {
454  include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
455  $cate_arbo = $form->select_all_categories(Categorie::TYPE_TICKET, '', 'parent', 64, 0, 1);
456 
457  if (count($cate_arbo)) {
458  // Categories
459  print '<tr><td class="wordbreak">'.$langs->trans("Categories").'</td><td>';
460  print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
461  print "</td></tr>";
462  }
463  }
464 
465  // Attached files
466  if (!empty($this->withfile)) {
467  // Define list of attached files
468  $listofpaths = array();
469  $listofnames = array();
470  $listofmimes = array();
471  if (!empty($_SESSION["listofpaths"])) {
472  $listofpaths = explode(';', $_SESSION["listofpaths"]);
473  }
474 
475  if (!empty($_SESSION["listofnames"])) {
476  $listofnames = explode(';', $_SESSION["listofnames"]);
477  }
478 
479  if (!empty($_SESSION["listofmimes"])) {
480  $listofmimes = explode(';', $_SESSION["listofmimes"]);
481  }
482 
483  $out = '<tr>';
484  $out .= '<td>'.$langs->trans("MailFile").'</td>';
485  $out .= '<td>';
486  // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
487  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
488  $out .= '<script type="text/javascript">';
489  $out .= 'jQuery(document).ready(function () {';
490  $out .= ' jQuery(".removedfile").click(function() {';
491  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
492  $out .= ' });';
493  $out .= '})';
494  $out .= '</script>'."\n";
495  if (count($listofpaths)) {
496  foreach ($listofpaths as $key => $val) {
497  $out .= '<div id="attachfile_'.$key.'">';
498  $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
499  if (!$this->withfilereadonly) {
500  $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.'" />';
501  }
502  $out .= '<br></div>';
503  }
504  } else {
505  $out .= $langs->trans("NoAttachedFiles").'<br>';
506  }
507  if ($this->withfile == 2) { // Can add other files
508  $maxfilesizearray = getMaxFileSizeArray();
509  $maxmin = $maxfilesizearray['maxmin'];
510  if ($maxmin > 0) {
511  $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
512  }
513  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
514  $out .= ' ';
515  $out .= '<input type="submit" class="button smallpaddingimp reposition" id="addfile" name="addfile" value="'.$langs->trans("MailingAddFile").'" />';
516  }
517  $out .= "</td></tr>\n";
518 
519  print $out;
520  }
521 
522  // User of creation
523  if ($this->withusercreate > 0 && $this->fk_user_create) {
524  print '<tr><td class="titlefield">'.$langs->trans("CreatedBy").'</td><td>';
525  $langs->load("users");
526  $fuser = new User($this->db);
527 
528  if ($this->withcreatereadonly) {
529  if ($res = $fuser->fetch($this->fk_user_create)) {
530  print $fuser->getNomUrl(1);
531  }
532  }
533  print ' &nbsp; ';
534  print "</td></tr>\n";
535  }
536 
537  // Customer or supplier
538  if ($this->withcompany) {
539  // altairis: force company and contact id for external user
540  if (empty($user->socid)) {
541  // Company
542  print '<tr><td class="titlefield">'.$langs->trans("ThirdParty").'</td><td>';
543  $events = array();
544  $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php', 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
545  print img_picto('', 'company', 'class="paddingright"');
546  print $form->select_company($this->withfromsocid, 'socid', '', 1, 1, '', $events, 0, 'minwidth200');
547  print '</td></tr>';
548  if (!empty($conf->use_javascript_ajax) && !empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) {
549  $htmlname = 'socid';
550  print '<script type="text/javascript">
551  $(document).ready(function () {
552  jQuery("#'.$htmlname.'").change(function () {
553  var obj = '.json_encode($events).';
554  $.each(obj, function(key,values) {
555  if (values.method.length) {
556  runJsCodeForEvent'.$htmlname.'(values);
557  }
558  });
559  });
560 
561  function runJsCodeForEvent'.$htmlname.'(obj) {
562  console.log("Run runJsCodeForEvent'.$htmlname.'");
563  var id = $("#'.$htmlname.'").val();
564  var method = obj.method;
565  var url = obj.url;
566  var htmlname = obj.htmlname;
567  var showempty = obj.showempty;
568  $.getJSON(url,
569  {
570  action: method,
571  id: id,
572  htmlname: htmlname,
573  showempty: showempty
574  },
575  function(response) {
576  $.each(obj.params, function(key,action) {
577  if (key.length) {
578  var num = response.num;
579  if (num > 0) {
580  $("#" + key).removeAttr(action);
581  } else {
582  $("#" + key).attr(action, action);
583  }
584  }
585  });
586  $("select#" + htmlname).html(response.value);
587  if (response.num) {
588  var selecthtml_str = response.value;
589  var selecthtml_dom=$.parseHTML(selecthtml_str);
590  if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
591  $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
592  }
593  } else {
594  $("#inputautocomplete"+htmlname).val("");
595  }
596  $("select#" + htmlname).change(); /* Trigger event change */
597  }
598  );
599  }
600  });
601  </script>';
602  }
603 
604  // Contact and type
605  print '<tr><td>'.$langs->trans("Contact").'</td><td>';
606  // If no socid, set to -1 to avoid full contacts list
607  $selectedCompany = ($this->withfromsocid > 0) ? $this->withfromsocid : -1;
608  print img_picto('', 'contact', 'class="paddingright"');
609  print $form->selectcontacts($selectedCompany, $this->withfromcontactid, 'contactid', 3, '', '', 0, 'minwidth200');
610  print ' ';
611  $formcompany->selectTypeContact($ticketstatic, '', 'type', 'external', '', 0, 'maginleftonly');
612  print '</td></tr>';
613  } else {
614  print '<tr><td class="titlefield"><input type="hidden" name="socid" value="'.$user->socid.'"/></td>';
615  print '<td><input type="hidden" name="contactid" value="'.$user->contact_id.'"/></td>';
616  print '<td><input type="hidden" name="type" value="Z"/></td></tr>';
617  }
618 
619  // Notify thirdparty at creation
620  if (empty($this->ispublic)) {
621  print '<tr><td><label for="notify_tiers_at_create">'.$langs->trans("TicketNotifyTiersAtCreation").'</label></td><td>';
622  print '<input type="checkbox" id="notify_tiers_at_create" name="notify_tiers_at_create"'.($this->withnotifytiersatcreate ? ' checked="checked"' : '').'>';
623  print '</td></tr>';
624  }
625 
626  // User assigned
627  print '<tr><td>';
628  print $langs->trans("AssignedTo");
629  print '</td><td>';
630  print img_picto('', 'user', 'class="pictofixedwidth"');
631  print $form->select_dolusers(GETPOST('fk_user_assign', 'int'), 'fk_user_assign', 1);
632  print '</td>';
633  print '</tr>';
634  }
635 
636  if ($subelement != 'project') {
637  if (isModEnabled('project') && !$this->ispublic) {
638  $formproject = new FormProjets($this->db);
639  print '<tr><td><label for="project"><span class="">'.$langs->trans("Project").'</span></label></td><td>';
640  print img_picto('', 'project').$formproject->select_projects(-1, GETPOST('projectid', 'int'), 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
641  print '</td></tr>';
642  }
643  }
644 
645  // Other attributes
646  $parameters = array();
647  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $ticketstat, $action); // Note that $action and $object may have been modified by hook
648  if (empty($reshook)) {
649  print $ticketstat->showOptionals($extrafields, 'create');
650  }
651 
652  print '</table>';
653 
654  if ($withdolfichehead) {
655  print dol_get_fiche_end();
656  }
657 
658  print '<br><br>';
659 
660  print $form->buttonsSaveCancel(((isset($this->withreadid) && $this->withreadid > 0) ? "SendResponse" : "CreateTicket"), ($this->withcancel ? "Cancel" : ""));
661 
662  /*
663  print '<div class="center">';
664  print '<input type="submit" class="button" name="add" value="'.$langs->trans(($this->withreadid > 0 ? "SendResponse" : "CreateTicket")).'" />';
665  if ($this->withcancel) {
666  print " &nbsp; &nbsp; &nbsp;";
667  print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
668  }
669  print '</div>';
670  */
671 
672  print '<input type="hidden" name="page_y">'."\n";
673 
674  print "</form>\n";
675  print "<!-- End form TICKET -->\n";
676  }
677 
692  public function selectTypesTickets($selected = '', $htmlname = 'tickettype', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '', $multiselect = 0)
693  {
694  global $langs, $user;
695 
696  $selected = is_array($selected) ? $selected : (!empty($selected) ? explode(',', $selected) : array());
697  $ticketstat = new Ticket($this->db);
698 
699  dol_syslog(get_class($this) . "::select_types_tickets " . implode(';', $selected) . ", " . $htmlname . ", " . $filtertype . ", " . $format . ", " . $multiselect, LOG_DEBUG);
700 
701  $filterarray = array();
702 
703  if ($filtertype != '' && $filtertype != '-1') {
704  $filterarray = explode(',', $filtertype);
705  }
706 
707  $ticketstat->loadCacheTypesTickets();
708 
709  print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.($multiselect?'[]':'').'"'.($multiselect?' multiple':'').'>';
710  if ($empty) {
711  print '<option value="">&nbsp;</option>';
712  }
713 
714  if (is_array($ticketstat->cache_types_tickets) && count($ticketstat->cache_types_tickets)) {
715  foreach ($ticketstat->cache_types_tickets as $id => $arraytypes) {
716  // On passe si on a demande de filtrer sur des modes de paiments particuliers
717  if (count($filterarray) && !in_array($arraytypes['type'], $filterarray)) {
718  continue;
719  }
720 
721  // If 'showempty' is enabled we discard empty line because an empty line has already been output.
722  if ($empty && empty($arraytypes['code'])) {
723  continue;
724  }
725 
726  if ($format == 0) {
727  print '<option value="'.$id.'"';
728  }
729 
730  if ($format == 1) {
731  print '<option value="'.$arraytypes['code'].'"';
732  }
733 
734  if ($format == 2) {
735  print '<option value="'.$arraytypes['code'].'"';
736  }
737 
738  if ($format == 3) {
739  print '<option value="'.$id.'"';
740  }
741 
742  // If text is selected, we compare with code, otherwise with id
743  if (in_array($arraytypes['code'], $selected)) {
744  print ' selected="selected"';
745  } elseif (in_array($id, $selected)) {
746  print ' selected="selected"';
747  } elseif ($arraytypes['use_default'] == "1" && !$selected && !$empty) {
748  print ' selected="selected"';
749  }
750 
751  print '>';
752 
753  $value = '&nbsp;';
754  if ($format == 0) {
755  $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
756  } elseif ($format == 1) {
757  $value = $arraytypes['code'];
758  } elseif ($format == 2) {
759  $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
760  } elseif ($format == 3) {
761  $value = $arraytypes['code'];
762  }
763 
764  print $value ? $value : '&nbsp;';
765  print '</option>';
766  }
767  }
768  print '</select>';
769  if (isset($user->admin) && $user->admin && !$noadmininfo) {
770  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
771  }
772 
773  print ajax_combobox('select'.$htmlname);
774  }
775 
791  public function selectGroupTickets($selected = '', $htmlname = 'ticketcategory', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '', $use_multilevel = 0, $outputlangs = null)
792  {
793  global $conf, $langs, $user;
794 
795  dol_syslog(get_class($this)."::selectCategoryTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
796 
797  if (is_null($outputlangs) || !is_object($outputlangs)) {
798  $outputlangs = $langs;
799  }
800  $outputlangs->load("ticket");
801 
802  $publicgroups = ($filtertype == 'public=1' || $filtertype == '(public:=:1)');
803 
804  $ticketstat = new Ticket($this->db);
805  $ticketstat->loadCacheCategoriesTickets($publicgroups ? 1 : -1); // get list of active ticket groups
806 
807  if ($use_multilevel <= 0) {
808  print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
809  if ($empty) {
810  print '<option value="">&nbsp;</option>';
811  }
812 
813  if (is_array($ticketstat->cache_category_tickets) && count($ticketstat->cache_category_tickets)) {
814  foreach ($ticketstat->cache_category_tickets as $id => $arraycategories) {
815  // Exclude some record
816  if ($publicgroups) {
817  if (empty($arraycategories['public'])) {
818  continue;
819  }
820  }
821 
822  // We discard empty line if showempty is on because an empty line has already been output.
823  if ($empty && empty($arraycategories['code'])) {
824  continue;
825  }
826 
827  $label = ($arraycategories['label'] != '-' ? $arraycategories['label'] : '');
828  if ($outputlangs->trans("TicketCategoryShort".$arraycategories['code']) != ("TicketCategoryShort".$arraycategories['code'])) {
829  $label = $outputlangs->trans("TicketCategoryShort".$arraycategories['code']);
830  } elseif ($outputlangs->trans($arraycategories['code']) != $arraycategories['code']) {
831  $label = $outputlangs->trans($arraycategories['code']);
832  }
833 
834  if ($format == 0) {
835  print '<option value="'.$id.'"';
836  }
837 
838  if ($format == 1) {
839  print '<option value="'.$arraycategories['code'].'"';
840  }
841 
842  if ($format == 2) {
843  print '<option value="'.$arraycategories['code'].'"';
844  }
845 
846  if ($format == 3) {
847  print '<option value="'.$id.'"';
848  }
849 
850  // If selected is text, we compare with code, otherwise with id
851  if (preg_match('/[a-z]/i', $selected) && $selected == $arraycategories['code']) {
852  print ' selected="selected"';
853  } elseif ($selected == $id) {
854  print ' selected="selected"';
855  } elseif ($arraycategories['use_default'] == "1" && !$selected && !$empty) {
856  print ' selected="selected"';
857  } elseif (count($ticketstat->cache_category_tickets) == 1) {
858  print ' selected="selected"';
859  }
860 
861  print '>';
862 
863  $value = '';
864  if ($format == 0) {
865  $value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
866  }
867 
868  if ($format == 1) {
869  $value = $arraycategories['code'];
870  }
871 
872  if ($format == 2) {
873  $value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
874  }
875 
876  if ($format == 3) {
877  $value = $arraycategories['code'];
878  }
879 
880  print $value ? $value : '&nbsp;';
881  print '</option>';
882  }
883  }
884  print '</select>';
885  if (isset($user->admin) && $user->admin && !$noadmininfo) {
886  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
887  }
888 
889  print ajax_combobox('select'.$htmlname);
890  } elseif ($htmlname!='') {
891  $selectedgroups = array();
892  $groupvalue = "";
893  $groupticket=GETPOST($htmlname, 'aZ09');
894  $child_id=GETPOST($htmlname.'_child_id', 'aZ09')?GETPOST($htmlname.'_child_id', 'aZ09'):0;
895  if (!empty($groupticket)) {
896  $tmpgroupticket = $groupticket;
897  $sql = "SELECT ctc.rowid, ctc.fk_parent, ctc.code FROM ".$this->db->prefix()."c_ticket_category as ctc WHERE ctc.code = '".$this->db->escape($tmpgroupticket)."'";
898  $resql = $this->db->query($sql);
899  if ($resql) {
900  $obj = $this->db->fetch_object($resql);
901  $selectedgroups[] = $obj->code;
902  while ($obj->fk_parent > 0) {
903  $sql = "SELECT ctc.rowid, ctc.fk_parent, ctc.code FROM ".$this->db->prefix()."c_ticket_category as ctc WHERE ctc.rowid ='".$this->db->escape($obj->fk_parent)."'";
904  $resql = $this->db->query($sql);
905  if ($resql) {
906  $obj = $this->db->fetch_object($resql);
907  $selectedgroups[] = $obj->code;
908  }
909  }
910  }
911  }
912 
913  $arrayidused = array();
914  $arrayidusedconcat = array();
915  $arraycodenotparent = array();
916  $arraycodenotparent[] = "";
917 
918  $stringtoprint = '<span class="supportemailfield bold">'.$langs->trans("GroupOfTicket").'</span> ';
919  $stringtoprint .= '<select id ="'.$htmlname.'" class="minwidth500" child_id="0">';
920  $stringtoprint .= '<option value="">&nbsp;</option>';
921 
922  $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ";
923  $sql .= $this->db->ifsql("ctc.rowid NOT IN (SELECT ctcfather.rowid FROM llx_c_ticket_category as ctcfather JOIN llx_c_ticket_category as ctcjoin ON ctcfather.rowid = ctcjoin.fk_parent)", "'NOTPARENT'", "'PARENT'")." as isparent";
924  $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc";
925  $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
926  if ($filtertype == 'public=1') {
927  $sql .= " AND ctc.public = 1";
928  }
929  $sql .= " AND ctc.fk_parent = 0";
930  $sql .= $this->db->order('ctc.pos', 'ASC');
931 
932  $resql = $this->db->query($sql);
933  if ($resql) {
934  $num_rows_level0 = $this->db->num_rows($resql);
935  $i = 0;
936  while ($i < $num_rows_level0) {
937  $obj = $this->db->fetch_object($resql);
938  if ($obj) {
939  $label = ($obj->label != '-' ? $obj->label : '');
940  if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) {
941  $label = $outputlangs->trans("TicketCategoryShort".$obj->code);
942  } elseif ($outputlangs->trans($obj->code) != $obj->code) {
943  $label = $outputlangs->trans($obj->code);
944  }
945 
946  $grouprowid = $obj->rowid;
947  $groupvalue = $obj->code;
948  $grouplabel = $label;
949 
950  $isparent = $obj->isparent;
951  if (is_array($selectedgroups)) {
952  $iselected = in_array($obj->code, $selectedgroups) ?'selected':'';
953  } else {
954  $iselected = $groupticket == $obj->code ?'selected':'';
955  }
956  $stringtoprint .= '<option '.$iselected.' class="'.$htmlname.dol_escape_htmltag($grouprowid).'" value="'.dol_escape_htmltag($groupvalue).'" data-html="'.dol_escape_htmltag($grouplabel).'">'.dol_escape_htmltag($grouplabel).'</option>';
957  if ($isparent == 'NOTPARENT') {
958  $arraycodenotparent[] = $groupvalue;
959  }
960  $arrayidused[] = $grouprowid;
961  $arrayidusedconcat[] = $grouprowid;
962  }
963  $i++;
964  }
965  } else {
966  dol_print_error($this->db);
967  }
968  if (count($arrayidused) == 1) {
969  return '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.dol_escape_htmltag($groupvalue).'">';
970  } else {
971  $stringtoprint .= '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'_select" class="maxwidth500 minwidth400">';
972  $stringtoprint .= '<input type="hidden" name="'.$htmlname.'_child_id" id="'.$htmlname.'_select_child_id" class="maxwidth500 minwidth400">';
973  }
974  $stringtoprint .= '</select>&nbsp;';
975 
976  $levelid = 1; // The first combobox
977  while ($levelid <= $use_multilevel) { // Loop to take the child of the combo
978  $tabscript = array();
979  $stringtoprint .= '<select id ="'.$htmlname.'_child_'.$levelid.'" class="maxwidth500 minwidth400 groupticketchild" child_id="'.$levelid.'">';
980  $stringtoprint .= '<option value="">&nbsp;</option>';
981 
982  $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ctcjoin.code as codefather";
983  $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc";
984  $sql .= " JOIN ".$this->db->prefix()."c_ticket_category as ctcjoin ON ctc.fk_parent = ctcjoin.rowid";
985  $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
986  $sql .= " AND ctc.rowid NOT IN (".$this->db->sanitize(join(',', $arrayidusedconcat)).")";
987 
988  if ($filtertype == 'public=1') {
989  $sql .= " AND ctc.public = 1";
990  }
991  // Add a test to take only record that are direct child
992  if (!empty($arrayidused)) {
993  $sql .= " AND ctc.fk_parent IN ( ";
994  foreach ($arrayidused as $idused) {
995  $sql .= $idused.", ";
996  }
997  $sql = substr($sql, 0, -2);
998  $sql .= ")";
999  } else {
1000  }
1001  $sql .= $this->db->order('ctc.pos', 'ASC');
1002 
1003  $resql = $this->db->query($sql);
1004  if ($resql) {
1005  $num_rows = $this->db->num_rows($resql);
1006  $i = 0;
1007  $arrayidused=array();
1008  while ($i < $num_rows) {
1009  $obj = $this->db->fetch_object($resql);
1010  if ($obj) {
1011  $label = ($obj->label != '-' ? $obj->label : '');
1012  if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) {
1013  $label = $outputlangs->trans("TicketCategoryShort".$obj->code);
1014  } elseif ($outputlangs->trans($obj->code) != $obj->code) {
1015  $label = $outputlangs->trans($obj->code);
1016  }
1017 
1018  $grouprowid = $obj->rowid;
1019  $groupvalue = $obj->code;
1020  $grouplabel = $label;
1021  $isparent = $obj->isparent;
1022  $fatherid = $obj->fk_parent;
1023  $arrayidused[] = $grouprowid;
1024  $arrayidusedconcat[] = $grouprowid;
1025  $groupcodefather = $obj->codefather;
1026  if ($isparent == 'NOTPARENT') {
1027  $arraycodenotparent[] = $groupvalue;
1028  }
1029  if (is_array($selectedgroups)) {
1030  $iselected = in_array($obj->code, $selectedgroups) ?'selected':'';
1031  } else {
1032  $iselected = $groupticket == $obj->code ?'selected':'';
1033  }
1034  $stringtoprint .= '<option '.$iselected.' class="'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'" value="'.dol_escape_htmltag($groupvalue).'" data-html="'.dol_escape_htmltag($grouplabel).'">'.dol_escape_htmltag($grouplabel).'</option>';
1035  if (empty($tabscript[$groupcodefather])) {
1036  $tabscript[$groupcodefather] = 'if ($("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid-1:'').'").val() == "'.dol_escape_js($groupcodefather).'"){
1037  $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").show()
1038  console.log("We show childs tickets of '.$groupcodefather.' group ticket")
1039  }else{
1040  $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").hide()
1041  console.log("We hide childs tickets of '.$groupcodefather.' group ticket")
1042  }';
1043  }
1044  }
1045  $i++;
1046  }
1047  } else {
1048  dol_print_error($this->db);
1049  }
1050  $stringtoprint .='</select>';
1051 
1052  $stringtoprint .='<script>';
1053  $stringtoprint .='arraynotparents = '.json_encode($arraycodenotparent).';'; // when the last visible combo list is number x, this is the array of group
1054  $stringtoprint .='if (arraynotparents.includes($("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid-1:'').'").val())){
1055  console.log("'.$htmlname.'_child_'.$levelid.'")
1056  if($("#'.$htmlname.'_child_'.$levelid.'").val() == "" && ($("#'.$htmlname.'_child_'.$levelid.'").attr("child_id")>'.$child_id.')){
1057  $("#'.$htmlname.'_child_'.$levelid.'").hide();
1058  console.log("We hide '.$htmlname.'_child_'.$levelid.' input")
1059  }
1060  if(arraynotparents.includes("'.$groupticket.'") && '.$child_id.' == 0){
1061  $("#ticketcategory_select_child_id").val($("#'.$htmlname.'").attr("child_id"))
1062  $("#ticketcategory_select").val($("#'.$htmlname.'").val()) ;
1063  console.log("We choose '.$htmlname.' input and reload hidden input");
1064  }
1065  }
1066  $("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid-1:'').'").change(function() {
1067  child_id = $("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid:'').'").attr("child_id");
1068 
1069  /* Change of value to select this value*/
1070  if (arraynotparents.includes($(this).val()) || $(this).attr("child_id") == '.$use_multilevel.') {
1071  $("#ticketcategory_select").val($(this).val());
1072  $("#ticketcategory_select_child_id").val($(this).attr("child_id")) ;
1073  console.log("We choose to select "+ $(this).val());
1074  }else{
1075  if ($("#'.$htmlname.'_child_'.$levelid.' option").length <= 1) {
1076  $("#ticketcategory_select").val($(this).val());
1077  $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1078  console.log("We choose to select "+ $(this).val() + " and next combo has no item, so we keep this selection");
1079  } else {
1080  console.log("We choose to select "+ $(this).val() + " but next combo has some item, so we clean selected item");
1081  $("#ticketcategory_select").val("");
1082  $("#ticketcategory_select_child_id").val("");
1083  }
1084  }
1085 
1086  console.log("We select a new value into combo child_id="+child_id);
1087 
1088  // Hide all selected box that are child of the one modified
1089  $(".groupticketchild").each(function(){
1090  if ($(this).attr("child_id") > child_id) {
1091  console.log("hide child_id="+$(this).attr("child_id"));
1092  $(this).val("");
1093  $(this).hide();
1094  }
1095  })
1096 
1097  // Now we enable the next combo
1098  $("#'.$htmlname.'_child_'.$levelid.'").val("");
1099  if (!arraynotparents.includes($(this).val()) && $("#'.$htmlname.'_child_'.$levelid.' option").length > 1) {
1100  console.log($("#'.$htmlname.'_child_'.$levelid.' option").length);
1101  $("#'.$htmlname.'_child_'.$levelid.'").show()
1102  } else {
1103  $("#'.$htmlname.'_child_'.$levelid.'").hide()
1104  }
1105  ';
1106  $levelid++;
1107  foreach ($tabscript as $script) {
1108  $stringtoprint .= $script;
1109  };
1110  $stringtoprint .='})';
1111  $stringtoprint .='</script>';
1112  }
1113  $stringtoprint .='<script>';
1114  $stringtoprint .='$("#'.$htmlname.'_child_'.$use_multilevel.'").change(function() {
1115  $("#ticketcategory_select").val($(this).val());
1116  $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1117  console.log($("#ticketcategory_select").val());
1118  })';
1119  $stringtoprint .='</script>';
1120  $stringtoprint .= ajax_combobox($htmlname);
1121 
1122  return $stringtoprint;
1123  }
1124  }
1125 
1139  public function selectSeveritiesTickets($selected = '', $htmlname = 'ticketseverity', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '')
1140  {
1141  global $langs, $user;
1142 
1143  $ticketstat = new Ticket($this->db);
1144 
1145  dol_syslog(get_class($this)."::selectSeveritiesTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
1146 
1147  $filterarray = array();
1148 
1149  if ($filtertype != '' && $filtertype != '-1') {
1150  $filterarray = explode(',', $filtertype);
1151  }
1152 
1153  $ticketstat->loadCacheSeveritiesTickets();
1154 
1155  print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
1156  if ($empty) {
1157  print '<option value="">&nbsp;</option>';
1158  }
1159 
1160  if (is_array($ticketstat->cache_severity_tickets) && count($ticketstat->cache_severity_tickets)) {
1161  foreach ($ticketstat->cache_severity_tickets as $id => $arrayseverities) {
1162  // On passe si on a demande de filtrer sur des modes de paiments particuliers
1163  if (count($filterarray) && !in_array($arrayseverities['type'], $filterarray)) {
1164  continue;
1165  }
1166 
1167  // We discard empty line if showempty is on because an empty line has already been output.
1168  if ($empty && empty($arrayseverities['code'])) {
1169  continue;
1170  }
1171 
1172  if ($format == 0) {
1173  print '<option value="'.$id.'"';
1174  }
1175 
1176  if ($format == 1) {
1177  print '<option value="'.$arrayseverities['code'].'"';
1178  }
1179 
1180  if ($format == 2) {
1181  print '<option value="'.$arrayseverities['code'].'"';
1182  }
1183 
1184  if ($format == 3) {
1185  print '<option value="'.$id.'"';
1186  }
1187 
1188  // If text is selected, we compare with code, otherwise with id
1189  if (preg_match('/[a-z]/i', $selected) && $selected == $arrayseverities['code']) {
1190  print ' selected="selected"';
1191  } elseif ($selected == $id) {
1192  print ' selected="selected"';
1193  } elseif ($arrayseverities['use_default'] == "1" && !$selected && !$empty) {
1194  print ' selected="selected"';
1195  }
1196 
1197  print '>';
1198 
1199  $value = '';
1200  if ($format == 0) {
1201  $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
1202  }
1203 
1204  if ($format == 1) {
1205  $value = $arrayseverities['code'];
1206  }
1207 
1208  if ($format == 2) {
1209  $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
1210  }
1211 
1212  if ($format == 3) {
1213  $value = $arrayseverities['code'];
1214  }
1215 
1216  print $value ? $value : '&nbsp;';
1217  print '</option>';
1218  }
1219  }
1220  print '</select>';
1221  if (isset($user->admin) && $user->admin && !$noadmininfo) {
1222  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1223  }
1224 
1225  print ajax_combobox('select'.$htmlname);
1226  }
1227 
1228  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1234  public function clear_attached_files()
1235  {
1236  // phpcs:enable
1237  global $conf, $user;
1238  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1239 
1240  // Set tmp user directory
1241  $vardir = $conf->user->dir_output."/".$user->id;
1242  $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
1243  if (is_dir($upload_dir)) {
1244  dol_delete_dir_recursive($upload_dir);
1245  }
1246 
1247  if (!empty($this->trackid)) { // TODO Always use trackid (ticXXX) instead of track_id (abcd123)
1248  $keytoavoidconflict = '-'.$this->trackid;
1249  } else {
1250  $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id;
1251  }
1252  unset($_SESSION["listofpaths".$keytoavoidconflict]);
1253  unset($_SESSION["listofnames".$keytoavoidconflict]);
1254  unset($_SESSION["listofmimes".$keytoavoidconflict]);
1255  }
1256 
1263  public function showMessageForm($width = '40%')
1264  {
1265  global $conf, $langs, $user, $hookmanager, $form, $mysoc;
1266 
1267  $formmail = new FormMail($this->db);
1268  $addfileaction = 'addfile';
1269 
1270  if (!is_object($form)) {
1271  $form = new Form($this->db);
1272  }
1273 
1274  // Load translation files required by the page
1275  $langs->loadLangs(array('other', 'mails'));
1276 
1277  // Clear temp files. Must be done at beginning, before call of triggers
1278  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
1279  $this->clear_attached_files();
1280  }
1281 
1282  // Define output language
1283  $outputlangs = $langs;
1284  $newlang = '';
1285  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->param['langsmodels'])) {
1286  $newlang = $this->param['langsmodels'];
1287  }
1288  if (!empty($newlang)) {
1289  $outputlangs = new Translate("", $conf);
1290  $outputlangs->setDefaultLang($newlang);
1291  $outputlangs->load('other');
1292  }
1293 
1294  // Get message template for $this->param["models"] into c_email_templates
1295  $arraydefaultmessage = -1;
1296  if (isset($this->param['models']) && $this->param['models'] != 'none') {
1297  $model_id = 0;
1298  if (array_key_exists('models_id', $this->param)) {
1299  $model_id = (int) $this->param["models_id"];
1300  }
1301 
1302  $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one
1303  }
1304 
1305  // Define list of attached files
1306  $listofpaths = array();
1307  $listofnames = array();
1308  $listofmimes = array();
1309 
1310  if (!empty($this->trackid)) {
1311  $keytoavoidconflict = '-'.$this->trackid;
1312  } else {
1313  $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
1314  }
1315  //var_dump($keytoavoidconflict);
1316  if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
1317  if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
1318  foreach ($this->param['fileinit'] as $file) {
1319  $formmail->add_attached_files($file, basename($file), dol_mimetype($file));
1320  }
1321  }
1322  }
1323  //var_dump($_SESSION);
1324  //var_dump($_SESSION["listofpaths".$keytoavoidconflict]);
1325  if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
1326  $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
1327  }
1328  if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
1329  $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
1330  }
1331  if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
1332  $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
1333  }
1334 
1335  // Define output language
1336  $outputlangs = $langs;
1337  $newlang = '';
1338  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->param['langsmodels'])) {
1339  $newlang = $this->param['langsmodels'];
1340  }
1341  if (!empty($newlang)) {
1342  $outputlangs = new Translate("", $conf);
1343  $outputlangs->setDefaultLang($newlang);
1344  $outputlangs->load('other');
1345  }
1346 
1347  print "\n<!-- Begin message_form TICKET -->\n";
1348 
1349  $send_email = GETPOST('send_email', 'int') ? GETPOST('send_email', 'int') : 0;
1350 
1351 
1352  // Example 1 : Adding jquery code
1353  print '<script type="text/javascript">
1354  jQuery(document).ready(function() {
1355  send_email=' . $send_email.';
1356  if (send_email) {
1357  if (!jQuery("#send_msg_email").is(":checked")) {
1358  jQuery("#send_msg_email").prop("checked", true).trigger("change");
1359  }
1360  jQuery(".email_line").show();
1361  } else {
1362  if (!jQuery("#private_message").is(":checked")) {
1363  jQuery("#private_message").prop("checked", true).trigger("change");
1364  }
1365  jQuery(".email_line").hide();
1366  }';
1367 
1368  // If constant set, allow to send private messages as email
1369  if (empty($conf->global->TICKET_SEND_PRIVATE_EMAIL)) {
1370  print 'jQuery("#send_msg_email").click(function() {
1371  if(jQuery(this).is(":checked")) {
1372  if (jQuery("#private_message").is(":checked")) {
1373  jQuery("#private_message").prop("checked", false).trigger("change");
1374  }
1375  jQuery(".email_line").show();
1376  }
1377  else {
1378  jQuery(".email_line").hide();
1379  }
1380  });
1381 
1382  jQuery("#private_message").click(function() {
1383  if (jQuery(this).is(":checked")) {
1384  if (jQuery("#send_msg_email").is(":checked")) {
1385  jQuery("#send_msg_email").prop("checked", false).trigger("change");
1386  }
1387  jQuery(".email_line").hide();
1388  }
1389  });';
1390  }
1391 
1392  print '});
1393  </script>';
1394 
1395 
1396 
1397  print '<form method="post" name="ticket" id="ticket" enctype="multipart/form-data" action="'.$this->param["returnurl"].'">';
1398  print '<input type="hidden" name="token" value="'.newToken().'">';
1399  print '<input type="hidden" name="action" value="'.$this->action.'">';
1400  print '<input type="hidden" name="actionbis" value="add_message">';
1401  print '<input type="hidden" name="backtopage" value="'.$this->backtopage.'">';
1402  if (!empty($this->trackid)) {
1403  print '<input type="hidden" name="trackid" value="'.$this->trackid.'">';
1404  } else {
1405  print '<input type="hidden" name="trackid" value="'.(empty($this->track_id) ? '' : $this->track_id).'">';
1406  $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
1407  }
1408  foreach ($this->param as $key => $value) {
1409  print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
1410  }
1411 
1412  // Get message template
1413  $model_id = 0;
1414  if (array_key_exists('models_id', $this->param)) {
1415  $model_id = $this->param["models_id"];
1416  $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);
1417  }
1418 
1419  $result = $formmail->fetchAllEMailTemplate(!empty($this->param["models"]) ? $this->param["models"] : "", $user, $outputlangs);
1420  if ($result < 0) {
1421  setEventMessages($this->error, $this->errors, 'errors');
1422  }
1423  $modelmail_array = array();
1424  foreach ($formmail->lines_model as $line) {
1425  $modelmail_array[$line->id] = $line->label;
1426  }
1427 
1428  print '<table class="border" width="'.$width.'">';
1429 
1430  // External users can't send message email
1431  if ($user->hasRight("ticket", "write") && !$user->socid) {
1432  $ticketstat = new Ticket($this->db);
1433  $res = $ticketstat->fetch('', '', $this->track_id);
1434 
1435  print '<tr><td></td><td>';
1436  $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : (getDolGlobalInt('TICKETS_MESSAGE_FORCE_MAIL')?'checked':''));
1437  print '<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.'/> ';
1438  print '<label for="send_msg_email">'.$langs->trans('SendMessageByEmail').'</label>';
1439  $texttooltip = $langs->trans("TicketMessageSendEmailHelp", '{s1}');
1440  $texttooltip = str_replace('{s1}', $langs->trans('MarkMessageAsPrivate'), $texttooltip);
1441  print ' '.$form->textwithpicto('', $texttooltip, 1, 'help');
1442  print '</td></tr>';
1443 
1444  // Private message (not visible by customer/external user)
1445  if (!$user->socid) {
1446  print '<tr><td></td><td>';
1447  $checkbox_selected = (GETPOST('private_message', 'alpha') == "1" ? ' checked' : '');
1448  print '<input type="checkbox" name="private_message" value="1" id="private_message" '.$checkbox_selected.'/> ';
1449  print '<label for="private_message">'.$langs->trans('MarkMessageAsPrivate').'</label>';
1450  print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
1451  print '</td></tr>';
1452  }
1453 
1454  // Zone to select its email template
1455  if (count($modelmail_array) > 0) {
1456  print '<tr class="email_line"><td></td><td colspan="2"><div style="padding: 3px 0 3px 0">'."\n";
1457  print $langs->trans('SelectMailModel').': '.$formmail->selectarray('modelmailselected', $modelmail_array, $this->param['models_id'], 1, 0, "", "", 0, 0, 0, '', 'minwidth200');
1458  if ($user->admin) {
1459  print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1460  }
1461  print ' &nbsp; ';
1462  print '<input type="submit" class="button" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
1463  print '</div></td>';
1464  }
1465 
1466  // Subject
1467  print '<tr class="email_line"><td>'.$langs->trans('Subject').'</td>';
1468  print '<td><input type="text" class="text minwidth500" name="subject" value="['.getDolGlobalString('MAIN_INFO_SOCIETE_NOM').' - '.$langs->trans("Ticket").' '.$ticketstat->ref.'] '.$langs->trans('TicketNewMessage').'" />';
1469  print '</td></tr>';
1470 
1471  // Recipients / adressed-to
1472  print '<tr class="email_line"><td>'.$langs->trans('MailRecipients').'</td><td>';
1473  if ($res) {
1474  // Retrieve email of all contacts (internal and external)
1475  $contacts = $ticketstat->getInfosTicketInternalContact();
1476  $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact());
1477 
1478  $sendto = array();
1479 
1480  // Build array to display recipient list
1481  if (is_array($contacts) && count($contacts) > 0) {
1482  foreach ($contacts as $key => $info_sendto) {
1483  if ($info_sendto['email'] != '') {
1484  $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">").' <small class="opacitymedium">('.dol_escape_htmltag($info_sendto['libelle']).")</small>";
1485  }
1486  }
1487  }
1488 
1489  if ($ticketstat->origin_email && !in_array($ticketstat->origin_email, $sendto)) {
1490  $sendto[] = dol_escape_htmltag($ticketstat->origin_email).' <small class="opacitymedium">('.$langs->trans("TicketEmailOriginIssuer").")</small>";
1491  }
1492 
1493  if ($ticketstat->fk_soc > 0) {
1494  $ticketstat->socid = $ticketstat->fk_soc;
1495  $ticketstat->fetch_thirdparty();
1496 
1497  if (is_array($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) {
1498  $sendto[] = $ticketstat->thirdparty->email.' <small class="opacitymedium">('.$langs->trans('Customer').')</small>';
1499  }
1500  }
1501 
1502  if (getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')) {
1503  $sendto[] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO').' <small class="opacitymedium">(generic email)</small>';
1504  }
1505 
1506  // Print recipient list
1507  if (is_array($sendto) && count($sendto) > 0) {
1508  print img_picto('', 'email', 'class="pictofixedwidth"');
1509  print implode(', ', $sendto);
1510  } else {
1511  print '<div class="warning">'.$langs->trans('WarningNoEMailsAdded').' '.$langs->trans('TicketGoIntoContactTab').'</div>';
1512  }
1513  }
1514  print '</td></tr>';
1515  }
1516 
1517  $uselocalbrowser = false;
1518 
1519  // Intro
1520  // External users can't send message email
1521  /*
1522  if ($user->rights->ticket->write && !$user->socid && !empty($conf->global->TICKET_MESSAGE_MAIL_INTRO)) {
1523  $mail_intro = GETPOST('mail_intro') ? GETPOST('mail_intro') : $conf->global->TICKET_MESSAGE_MAIL_INTRO;
1524  print '<tr class="email_line"><td><label for="mail_intro">';
1525  print $form->textwithpicto($langs->trans("TicketMessageMailIntro"), $langs->trans("TicketMessageMailIntroHelp"), 1, 'help');
1526  print '</label>';
1527 
1528  print '</td><td>';
1529  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1530 
1531  $doleditor = new DolEditor('mail_intro', $mail_intro, '100%', 90, 'dolibarr_details', '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_TICKET'), ROWS_2, 70);
1532 
1533  $doleditor->Create();
1534  print '</td></tr>';
1535  }
1536  */
1537 
1538  // Attached files
1539  if (!empty($this->withfile)) {
1540  $out = '<tr>';
1541  $out .= '<td width="180">'.$langs->trans("MailFile").'</td>';
1542  $out .= '<td>';
1543  // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
1544  $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
1545  $out .= '<script type="text/javascript">';
1546  $out .= 'jQuery(document).ready(function () {';
1547  $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", true);';
1548  $out .= ' jQuery("#addedfile").on("change", function() {';
1549  $out .= ' if (jQuery(this).val().length) {';
1550  $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", false);';
1551  $out .= ' } else {';
1552  $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", true);';
1553  $out .= ' }';
1554  $out .= ' });';
1555  $out .= ' jQuery(".removedfile").click(function() {';
1556  $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
1557  $out .= ' });';
1558  $out .= '})';
1559  $out .= '</script>'."\n";
1560 
1561  if (count($listofpaths)) {
1562  foreach ($listofpaths as $key => $val) {
1563  $out .= '<div id="attachfile_'.$key.'">';
1564  $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
1565  if (!$this->withfilereadonly) {
1566  $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.'" />';
1567  }
1568  $out .= '<br></div>';
1569  }
1570  } else {
1571  //$out .= $langs->trans("NoAttachedFiles").'<br>';
1572  }
1573  if ($this->withfile == 2) { // Can add other files
1574  $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
1575  $out .= ' ';
1576  $out .= '<input type="submit" class="button smallpaddingimp reposition" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
1577  }
1578  $out .= "</td></tr>\n";
1579 
1580  print $out;
1581  }
1582 
1583  // MESSAGE
1584 
1585  $defaultmessage = "";
1586  if (is_object($arraydefaultmessage) && $arraydefaultmessage->content) {
1587  $defaultmessage = $arraydefaultmessage->content;
1588  }
1589  $defaultmessage = str_replace('\n', "\n", $defaultmessage);
1590 
1591  // Deal with format differences between message and signature (text / HTML)
1592  if (dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1593  $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
1594  } elseif (!dol_textishtml($defaultmessage) && isset($this->substit['__USER_SIGNATURE__']) && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1595  $defaultmessage = dol_nl2br($defaultmessage);
1596  }
1597  if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
1598  $defaultmessage = GETPOST('message', 'restricthtml');
1599  } else {
1600  $defaultmessage = make_substitutions($defaultmessage, $this->substit);
1601  // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
1602  $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
1603  $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
1604  }
1605 
1606  print '<tr><td colspan="2"><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span>';
1607  if ($user->hasRight("ticket", "write") && !$user->socid) {
1608  $texttooltip = $langs->trans("TicketMessageHelp");
1609  if (getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO') || getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE')) {
1610  $texttooltip .= '<br><br>'.$langs->trans("ForEmailMessageWillBeCompletedWith").'...';
1611  }
1612  if (getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO')) {
1613  $texttooltip .= '<br><u>'.$langs->trans("TicketMessageMailIntro").'</u><br>'.getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO');
1614  }
1615  if (getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE')) {
1616  $texttooltip .= '<br><br><u>'.$langs->trans("TicketMessageMailFooter").'</u><br>'.getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE');
1617  }
1618  print $form->textwithpicto('', $texttooltip, 1, 'help');
1619  }
1620  print '</label></td></tr>';
1621 
1622 
1623  print '<tr><td colspan="2">';
1624  //$toolbarname = 'dolibarr_details';
1625  $toolbarname = 'dolibarr_notes';
1626  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1627  $doleditor = new DolEditor('message', $defaultmessage, '100%', 200, $toolbarname, '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_5, 70);
1628  $doleditor->Create();
1629  print '</td></tr>';
1630 
1631  // Footer
1632  // External users can't send message email
1633  /*if ($user->rights->ticket->write && !$user->socid && !empty($conf->global->TICKET_MESSAGE_MAIL_SIGNATURE)) {
1634  $mail_signature = GETPOST('mail_signature') ? GETPOST('mail_signature') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE;
1635  print '<tr class="email_line"><td><label for="mail_intro">'.$langs->trans("TicketMessageMailFooter").'</label>';
1636  print $form->textwithpicto('', $langs->trans("TicketMessageMailFooterHelp"), 1, 'help');
1637  print '</td><td>';
1638  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1639  $doleditor = new DolEditor('mail_signature', $mail_signature, '100%', 90, 'dolibarr_details', '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_2, 70);
1640  $doleditor->Create();
1641  print '</td></tr>';
1642  }
1643  */
1644 
1645  print '</table>';
1646 
1647  print '<center><br>';
1648  print '<input type="submit" class="button" name="btn_add_message" value="'.$langs->trans("Add").'"';
1649  // Add a javascript test to avoid to forget to submit file before sending email
1650  if ($this->withfile == 2 && !empty($conf->use_javascript_ajax)) {
1651  print ' onClick="if (document.ticket.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
1652  }
1653  print ' />';
1654  if (!empty($this->withcancel)) {
1655  print " &nbsp; &nbsp; ";
1656  print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
1657  }
1658  print "</center>\n";
1659 
1660  print '<input type="hidden" name="page_y">'."\n";
1661 
1662  print "</form>\n";
1663 
1664  // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1665  if (!empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY)) {
1666  print '<script type="text/javascript">';
1667  print 'jQuery(document).ready(function () {';
1668  print ' $(document).on("keypress", \'#ticket\', function (e) { /* Note this is called at every key pressed ! */
1669  var code = e.keyCode || e.which;
1670  if (code == 13) {
1671  console.log("Enter was intercepted and blocked");
1672  e.preventDefault();
1673  return false;
1674  }
1675  });';
1676  print '})';
1677  print '</script>';
1678  }
1679 
1680  print "<!-- End form TICKET -->\n";
1681  }
1682 }
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition: ajax.lib.php:449
Class to manage contact/addresses.
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new For...
Class to manage building of HTML components.
selectGroupTickets($selected='', $htmlname='ticketcategory', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $morecss='', $use_multilevel=0, $outputlangs=null)
Return html list of ticket anaytic codes.
selectSeveritiesTickets($selected='', $htmlname='ticketseverity', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $morecss='')
Return html list of ticket severitys (priorities)
showMessageForm($width='40%')
Show the form to add message on ticket.
selectTypesTickets($selected='', $htmlname='tickettype', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $morecss='', $multiselect=0)
Return html list of tickets type.
__construct($db)
Constructor.
showForm($withdolfichehead=0, $mode='edit', $public=0, Contact $with_contact=null, $action='')
Show the form to input ticket.
clear_attached_files()
Clear list of attached files in send mail form (also stored in session)
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:47
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
Definition: files.lib.php:1402
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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.
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
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.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information for admin users or standard users.
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.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
table tableforfield button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
Definition: style.css.php:843
Class to generate the form for creating a new ticket.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
getMaxFileSizeArray()
Return the max allowed for file upload.
$conf db
API class for accounts.
Definition: inc.php:41