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