dolibarr 18.0.6
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
28require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
29require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
30require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
31
32if (!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 $selected = (GETPOST('category_code') ? GETPOST('category_code') : $this->category_code);
345 $this->selectGroupTickets($selected, 'category_code', $filter, 2, 1, 0, 0, 'minwidth200');
346 print '</td></tr>';
347
348 // Severity => Priority
349 print '<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans("TicketSeverity").'</span></label></td><td>';
350 $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 1);
351 print '</td></tr>';
352
353 if (!empty($conf->knowledgemanagement->enabled)) {
354 // KM Articles
355 print '<tr id="KWwithajax" class="hidden"><td></td></tr>';
356 print '<!-- Script to manage change of ticket group -->
357 <script nonce="'.getNonce().'">
358 jQuery(document).ready(function() {
359 function groupticketchange() {
360 console.log("We called groupticketchange, so we try to load list KM linked to event");
361 $("#KWwithajax").html("");
362 idgroupticket = $("#selectcategory_code").val();
363
364 console.log("We have selected id="+idgroupticket);
365
366 if (idgroupticket != "") {
367 $.ajax({ url: \''.DOL_URL_ROOT.'/core/ajax/fetchKnowledgeRecord.php\',
368 data: { action: \'getKnowledgeRecord\', idticketgroup: idgroupticket, token: \''.newToken().'\', lang:\''.$langs->defaultlang.'\', public:'.($public).' },
369 type: \'GET\',
370 success: function(response) {
371 var urllist = \'\';
372 console.log("We received response "+response);
373 if (typeof response == "object") {
374 console.log("response is already type object, no need to parse it");
375 } else {
376 console.log("response is type "+(typeof response));
377 response = JSON.parse(response);
378 }
379 for (key in response) {
380 answer = response[key].answer;
381 urllist += \'<li><a href="#" title="\'+response[key].title+\'" class="button_KMpopup" data-html="\'+answer+\'">\' +response[key].title+\'</a></li>\';
382 }
383 if (urllist != "") {
384 $("#KWwithajax").html(\'<td>'.$langs->trans("KMFoundForTicketGroup").'</td><td><ul>\'+urllist+\'</ul></td>\');
385 $("#KWwithajax").show();
386 $(".button_KMpopup").on("click",function(){
387 console.log("Open popup with jQuery(...).dialog() with KM article")
388 var $dialog = $("<div></div>").html($(this).attr("data-html"))
389 .dialog({
390 autoOpen: false,
391 modal: true,
392 height: (window.innerHeight - 150),
393 width: "80%",
394 title: $(this).attr("title"),
395 });
396 $dialog.dialog("open");
397 console.log($dialog);
398 })
399 }
400 },
401 error : function(output) {
402 console.error("Error on Fetch of KM articles");
403 },
404 });
405 }
406 };
407 $("#selectcategory_code").on("change",function() { groupticketchange(); });
408 if ($("#selectcategory_code").val() != "") {
409 groupticketchange();
410 }
411 });
412 </script>'."\n";
413 }
414
415 // Subject
416 if ($this->withtitletopic) {
417 print '<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans("Subject").'</span></label></td><td>';
418 // Answer to a ticket : display of the thread title in readonly
419 if ($this->withtopicreadonly) {
420 print $langs->trans('SubjectAnswerToTicket').' '.$this->topic_title;
421 } else {
422 if (isset($this->withreadid) && $this->withreadid > 0) {
423 $subject = $langs->trans('SubjectAnswerToTicket').' '.$this->withreadid.' : '.$this->topic_title;
424 } else {
425 $subject = GETPOST('subject', 'alpha');
426 }
427 print '<input class="text minwidth500" id="subject" name="subject" value="'.$subject.'"'.(empty($this->withemail)?' autofocus':'').' />';
428 }
429 print '</td></tr>';
430 }
431
432 // MESSAGE
433 $msg = GETPOSTISSET('message') ? GETPOST('message', 'restricthtml') : '';
434 print '<tr><td><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span></label></td><td>';
435
436 // If public form, display more information
437 $toolbarname = 'dolibarr_notes';
438 if ($this->ispublic) {
439 $toolbarname = 'dolibarr_details';
440 print '<div class="warning hideonsmartphone">'.(getDolGlobalString("TICKET_PUBLIC_TEXT_HELP_MESSAGE", $langs->trans('TicketPublicPleaseBeAccuratelyDescribe'))).'</div>';
441 }
442 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
443 $uselocalbrowser = true;
444 $doleditor = new DolEditor('message', $msg, '100%', 230, $toolbarname, 'In', true, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_TICKET'), ROWS_8, '90%');
445 $doleditor->Create();
446 print '</td></tr>';
447
448 if ($public && !empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA_TICKET)) {
449 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
450 print '<tr><td class="titlefield"><label for="email"><span class="fieldrequired">'.$langs->trans("SecurityCode").'</span></label></td><td>';
451 print '<span class="span-icon-security inline-block">';
452 print '<input id="securitycode" placeholder="'.$langs->trans("SecurityCode").'" class="flat input-icon-security width125" type="text" maxlength="5" name="code" tabindex="3" />';
453 print '</span>';
454 print '<span class="nowrap inline-block">';
455 print '<img class="inline-block valignmiddle" src="'.DOL_URL_ROOT.'/core/antispamimage.php" border="0" width="80" height="32" id="img_securitycode" />';
456 print '<a class="inline-block valignmiddle" href="" tabindex="4" data-role="button">'.img_picto($langs->trans("Refresh"), 'refresh', 'id="captcha_refresh_img"').'</a>';
457 print '</span>';
458 print '</td></tr>';
459 }
460
461 // Categories
462 if (isModEnabled('categorie')) {
463 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
464 $cate_arbo = $form->select_all_categories(Categorie::TYPE_TICKET, '', 'parent', 64, 0, 1);
465
466 if (count($cate_arbo)) {
467 // Categories
468 print '<tr><td class="wordbreak">'.$langs->trans("Categories").'</td><td>';
469 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
470 print "</td></tr>";
471 }
472 }
473
474 // Attached files
475 if (!empty($this->withfile)) {
476 // Define list of attached files
477 $listofpaths = array();
478 $listofnames = array();
479 $listofmimes = array();
480 if (!empty($_SESSION["listofpaths"])) {
481 $listofpaths = explode(';', $_SESSION["listofpaths"]);
482 }
483
484 if (!empty($_SESSION["listofnames"])) {
485 $listofnames = explode(';', $_SESSION["listofnames"]);
486 }
487
488 if (!empty($_SESSION["listofmimes"])) {
489 $listofmimes = explode(';', $_SESSION["listofmimes"]);
490 }
491
492 $out = '<tr>';
493 $out .= '<td>'.$langs->trans("MailFile").'</td>';
494 $out .= '<td>';
495 // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
496 $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
497 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
498 $out .= 'jQuery(document).ready(function () {';
499 $out .= ' jQuery(".removedfile").click(function() {';
500 $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
501 $out .= ' });';
502 $out .= '})';
503 $out .= '</script>'."\n";
504 if (count($listofpaths)) {
505 foreach ($listofpaths as $key => $val) {
506 $out .= '<div id="attachfile_'.$key.'">';
507 $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
508 if (!$this->withfilereadonly) {
509 $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.'" />';
510 }
511 $out .= '<br></div>';
512 }
513 } else {
514 $out .= $langs->trans("NoAttachedFiles").'<br>';
515 }
516 if ($this->withfile == 2) { // Can add other files
517 $maxfilesizearray = getMaxFileSizeArray();
518 $maxmin = $maxfilesizearray['maxmin'];
519 if ($maxmin > 0) {
520 $out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
521 }
522 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
523 $out .= ' ';
524 $out .= '<input type="submit" class="button smallpaddingimp reposition" id="addfile" name="addfile" value="'.$langs->trans("MailingAddFile").'" />';
525 }
526 $out .= "</td></tr>\n";
527
528 print $out;
529 }
530
531 // User of creation
532 if ($this->withusercreate > 0 && $this->fk_user_create) {
533 print '<tr><td class="titlefield">'.$langs->trans("CreatedBy").'</td><td>';
534 $langs->load("users");
535 $fuser = new User($this->db);
536
537 if ($this->withcreatereadonly) {
538 if ($res = $fuser->fetch($this->fk_user_create)) {
539 print $fuser->getNomUrl(1);
540 }
541 }
542 print ' &nbsp; ';
543 print "</td></tr>\n";
544 }
545
546 // Customer or supplier
547 if ($this->withcompany) {
548 // altairis: force company and contact id for external user
549 if (empty($user->socid)) {
550 // Company
551 print '<tr><td class="titlefield">'.$langs->trans("ThirdParty").'</td><td>';
552 $events = array();
553 $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php', 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
554 print img_picto('', 'company', 'class="paddingright"');
555 print $form->select_company($this->withfromsocid, 'socid', '', 1, 1, '', $events, 0, 'minwidth200');
556 print '</td></tr>';
557 if (!empty($conf->use_javascript_ajax) && !empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) {
558 $htmlname = 'socid';
559 print '<script nonce="'.getNonce().'" type="text/javascript">
560 $(document).ready(function () {
561 jQuery("#'.$htmlname.'").change(function () {
562 var obj = '.json_encode($events).';
563 $.each(obj, function(key,values) {
564 if (values.method.length) {
565 runJsCodeForEvent'.$htmlname.'(values);
566 }
567 });
568 });
569
570 function runJsCodeForEvent'.$htmlname.'(obj) {
571 console.log("Run runJsCodeForEvent'.$htmlname.'");
572 var id = $("#'.$htmlname.'").val();
573 var method = obj.method;
574 var url = obj.url;
575 var htmlname = obj.htmlname;
576 var showempty = obj.showempty;
577 $.getJSON(url,
578 {
579 action: method,
580 id: id,
581 htmlname: htmlname,
582 showempty: showempty
583 },
584 function(response) {
585 $.each(obj.params, function(key,action) {
586 if (key.length) {
587 var num = response.num;
588 if (num > 0) {
589 $("#" + key).removeAttr(action);
590 } else {
591 $("#" + key).attr(action, action);
592 }
593 }
594 });
595 $("select#" + htmlname).html(response.value);
596 if (response.num) {
597 var selecthtml_str = response.value;
598 var selecthtml_dom=$.parseHTML(selecthtml_str);
599 if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
600 $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
601 }
602 } else {
603 $("#inputautocomplete"+htmlname).val("");
604 }
605 $("select#" + htmlname).change(); /* Trigger event change */
606 }
607 );
608 }
609 });
610 </script>';
611 }
612
613 // Contact and type
614 print '<tr><td>'.$langs->trans("Contact").'</td><td>';
615 // If no socid, set to -1 to avoid full contacts list
616 $selectedCompany = ($this->withfromsocid > 0) ? $this->withfromsocid : -1;
617 print img_picto('', 'contact', 'class="paddingright"');
618 print $form->selectcontacts($selectedCompany, $this->withfromcontactid, 'contactid', 3, '', '', 0, 'minwidth200');
619 print ' ';
620 $formcompany->selectTypeContact($ticketstatic, '', 'type', 'external', '', 0, 'maginleftonly');
621 print '</td></tr>';
622 } else {
623 print '<tr><td class="titlefield"><input type="hidden" name="socid" value="'.$user->socid.'"/></td>';
624 print '<td><input type="hidden" name="contactid" value="'.$user->contact_id.'"/></td>';
625 print '<td><input type="hidden" name="type" value="Z"/></td></tr>';
626 }
627
628 // Notify thirdparty at creation
629 if (empty($this->ispublic)) {
630 print '<tr><td><label for="notify_tiers_at_create">'.$langs->trans("TicketNotifyTiersAtCreation").'</label></td><td>';
631 print '<input type="checkbox" id="notify_tiers_at_create" name="notify_tiers_at_create"'.($this->withnotifytiersatcreate ? ' checked="checked"' : '').'>';
632 print '</td></tr>';
633 }
634
635 // User assigned
636 print '<tr><td>';
637 print $langs->trans("AssignedTo");
638 print '</td><td>';
639 print img_picto('', 'user', 'class="pictofixedwidth"');
640 print $form->select_dolusers(GETPOST('fk_user_assign', 'int'), 'fk_user_assign', 1);
641 print '</td>';
642 print '</tr>';
643 }
644
645 if ($subelement != 'project') {
646 if (isModEnabled('project') && !$this->ispublic) {
647 $formproject = new FormProjets($this->db);
648 print '<tr><td><label for="project"><span class="">'.$langs->trans("Project").'</span></label></td><td>';
649 print img_picto('', 'project').$formproject->select_projects(-1, GETPOST('projectid', 'int'), 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
650 print '</td></tr>';
651 }
652 }
653
654 // Other attributes
655 $parameters = array();
656 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $ticketstat, $action); // Note that $action and $object may have been modified by hook
657 if (empty($reshook)) {
658 print $ticketstat->showOptionals($extrafields, 'create');
659 }
660
661 print '</table>';
662
663 if ($withdolfichehead) {
664 print dol_get_fiche_end();
665 }
666
667 print '<br><br>';
668
669 print $form->buttonsSaveCancel(((isset($this->withreadid) && $this->withreadid > 0) ? "SendResponse" : "CreateTicket"), ($this->withcancel ? "Cancel" : ""));
670
671 /*
672 print '<div class="center">';
673 print '<input type="submit" class="button" name="add" value="'.$langs->trans(($this->withreadid > 0 ? "SendResponse" : "CreateTicket")).'" />';
674 if ($this->withcancel) {
675 print " &nbsp; &nbsp; &nbsp;";
676 print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
677 }
678 print '</div>';
679 */
680
681 print '<input type="hidden" name="page_y">'."\n";
682
683 print "</form>\n";
684 print "<!-- End form TICKET -->\n";
685 }
686
701 public function selectTypesTickets($selected = '', $htmlname = 'tickettype', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '', $multiselect = 0)
702 {
703 global $langs, $user;
704
705 $selected = is_array($selected) ? $selected : (!empty($selected) ? explode(',', $selected) : array());
706 $ticketstat = new Ticket($this->db);
707
708 dol_syslog(get_class($this) . "::select_types_tickets " . implode(';', $selected) . ", " . $htmlname . ", " . $filtertype . ", " . $format . ", " . $multiselect, LOG_DEBUG);
709
710 $filterarray = array();
711
712 if ($filtertype != '' && $filtertype != '-1') {
713 $filterarray = explode(',', $filtertype);
714 }
715
716 $ticketstat->loadCacheTypesTickets();
717
718 print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.($multiselect?'[]':'').'"'.($multiselect?' multiple':'').'>';
719 if ($empty) {
720 print '<option value="">&nbsp;</option>';
721 }
722
723 if (is_array($ticketstat->cache_types_tickets) && count($ticketstat->cache_types_tickets)) {
724 foreach ($ticketstat->cache_types_tickets as $id => $arraytypes) {
725 // On passe si on a demande de filtrer sur des modes de paiments particuliers
726 if (count($filterarray) && !in_array($arraytypes['type'], $filterarray)) {
727 continue;
728 }
729
730 // If 'showempty' is enabled we discard empty line because an empty line has already been output.
731 if ($empty && empty($arraytypes['code'])) {
732 continue;
733 }
734
735 if ($format == 0) {
736 print '<option value="'.$id.'"';
737 }
738
739 if ($format == 1) {
740 print '<option value="'.$arraytypes['code'].'"';
741 }
742
743 if ($format == 2) {
744 print '<option value="'.$arraytypes['code'].'"';
745 }
746
747 if ($format == 3) {
748 print '<option value="'.$id.'"';
749 }
750
751 // If text is selected, we compare with code, otherwise with id
752 if (in_array($arraytypes['code'], $selected)) {
753 print ' selected="selected"';
754 } elseif (in_array($id, $selected)) {
755 print ' selected="selected"';
756 } elseif ($arraytypes['use_default'] == "1" && !$selected && !$empty) {
757 print ' selected="selected"';
758 }
759
760 print '>';
761
762 $value = '&nbsp;';
763 if ($format == 0) {
764 $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
765 } elseif ($format == 1) {
766 $value = $arraytypes['code'];
767 } elseif ($format == 2) {
768 $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
769 } elseif ($format == 3) {
770 $value = $arraytypes['code'];
771 }
772
773 print $value ? $value : '&nbsp;';
774 print '</option>';
775 }
776 }
777 print '</select>';
778 if (isset($user->admin) && $user->admin && !$noadmininfo) {
779 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
780 }
781
782 print ajax_combobox('select'.$htmlname);
783 }
784
800 public function selectGroupTickets($selected = '', $htmlname = 'ticketcategory', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '', $use_multilevel = 0, $outputlangs = null)
801 {
802 global $conf, $langs, $user;
803
804 dol_syslog(get_class($this)."::selectCategoryTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
805
806 if (is_null($outputlangs) || !is_object($outputlangs)) {
807 $outputlangs = $langs;
808 }
809 $outputlangs->load("ticket");
810
811 $publicgroups = ($filtertype == 'public=1' || $filtertype == '(public:=:1)');
812
813 $ticketstat = new Ticket($this->db);
814 $ticketstat->loadCacheCategoriesTickets($publicgroups ? 1 : -1); // get list of active ticket groups
815
816 if ($use_multilevel <= 0) {
817 print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
818 if ($empty) {
819 print '<option value="">&nbsp;</option>';
820 }
821
822 if (is_array($ticketstat->cache_category_tickets) && count($ticketstat->cache_category_tickets)) {
823 foreach ($ticketstat->cache_category_tickets as $id => $arraycategories) {
824 // Exclude some record
825 if ($publicgroups) {
826 if (empty($arraycategories['public'])) {
827 continue;
828 }
829 }
830
831 // We discard empty line if showempty is on because an empty line has already been output.
832 if ($empty && empty($arraycategories['code'])) {
833 continue;
834 }
835
836 $label = ($arraycategories['label'] != '-' ? $arraycategories['label'] : '');
837 if ($outputlangs->trans("TicketCategoryShort".$arraycategories['code']) != ("TicketCategoryShort".$arraycategories['code'])) {
838 $label = $outputlangs->trans("TicketCategoryShort".$arraycategories['code']);
839 } elseif ($outputlangs->trans($arraycategories['code']) != $arraycategories['code']) {
840 $label = $outputlangs->trans($arraycategories['code']);
841 }
842
843 if ($format == 0) {
844 print '<option value="'.$id.'"';
845 }
846
847 if ($format == 1) {
848 print '<option value="'.$arraycategories['code'].'"';
849 }
850
851 if ($format == 2) {
852 print '<option value="'.$arraycategories['code'].'"';
853 }
854
855 if ($format == 3) {
856 print '<option value="'.$id.'"';
857 }
858
859 // If selected is text, we compare with code, otherwise with id
860 if (isset($selected) && preg_match('/[a-z]/i', $selected) && $selected == $arraycategories['code']) {
861 print ' selected="selected"';
862 } elseif (isset($selected) && $selected == $id) {
863 print ' selected="selected"';
864 } elseif ($arraycategories['use_default'] == "1" && !$selected && !$empty) {
865 print ' selected="selected"';
866 } elseif (count($ticketstat->cache_category_tickets) == 1) {
867 print ' selected="selected"';
868 }
869
870 print '>';
871
872 $value = '';
873 if ($format == 0) {
874 $value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
875 }
876
877 if ($format == 1) {
878 $value = $arraycategories['code'];
879 }
880
881 if ($format == 2) {
882 $value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
883 }
884
885 if ($format == 3) {
886 $value = $arraycategories['code'];
887 }
888
889 print $value ? $value : '&nbsp;';
890 print '</option>';
891 }
892 }
893 print '</select>';
894 if (isset($user->admin) && $user->admin && !$noadmininfo) {
895 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
896 }
897
898 print ajax_combobox('select'.$htmlname);
899 } elseif ($htmlname!='') {
900 $selectedgroups = array();
901 $groupvalue = "";
902 $groupticket=GETPOST($htmlname, 'aZ09');
903 $child_id=GETPOST($htmlname.'_child_id', 'aZ09')?GETPOST($htmlname.'_child_id', 'aZ09'):0;
904 if (!empty($groupticket)) {
905 $tmpgroupticket = $groupticket;
906 $sql = "SELECT ctc.rowid, ctc.fk_parent, ctc.code";
907 $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc WHERE ctc.code = '".$this->db->escape($tmpgroupticket)."'";
908 $resql = $this->db->query($sql);
909 if ($resql) {
910 $obj = $this->db->fetch_object($resql);
911 $selectedgroups[] = $obj->code;
912 while ($obj->fk_parent > 0) {
913 $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)."'";
914 $resql = $this->db->query($sql);
915 if ($resql) {
916 $obj = $this->db->fetch_object($resql);
917 $selectedgroups[] = $obj->code;
918 }
919 }
920 }
921 }
922
923 $arrayidused = array();
924 $arrayidusedconcat = array();
925 $arraycodenotparent = array();
926 $arraycodenotparent[] = "";
927
928 $stringtoprint = '<span class="supportemailfield bold">'.$langs->trans("GroupOfTicket").'</span> ';
929 $stringtoprint .= '<select id ="'.$htmlname.'" class="minwidth500" child_id="0">';
930 $stringtoprint .= '<option value="">&nbsp;</option>';
931
932 $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ";
933 $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";
934 $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc";
935 $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
936 if ($filtertype == 'public=1') {
937 $sql .= " AND ctc.public = 1";
938 }
939 $sql .= " AND ctc.fk_parent = 0";
940 $sql .= $this->db->order('ctc.pos', 'ASC');
941
942 $resql = $this->db->query($sql);
943 if ($resql) {
944 $num_rows_level0 = $this->db->num_rows($resql);
945 $i = 0;
946 while ($i < $num_rows_level0) {
947 $obj = $this->db->fetch_object($resql);
948 if ($obj) {
949 $label = ($obj->label != '-' ? $obj->label : '');
950 if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) {
951 $label = $outputlangs->trans("TicketCategoryShort".$obj->code);
952 } elseif ($outputlangs->trans($obj->code) != $obj->code) {
953 $label = $outputlangs->trans($obj->code);
954 }
955
956 $grouprowid = $obj->rowid;
957 $groupvalue = $obj->code;
958 $grouplabel = $label;
959
960 $isparent = $obj->isparent;
961 if (is_array($selectedgroups)) {
962 $iselected = in_array($obj->code, $selectedgroups) ?'selected':'';
963 } else {
964 $iselected = $groupticket == $obj->code ?'selected':'';
965 }
966 $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>';
967 if ($isparent == 'NOTPARENT') {
968 $arraycodenotparent[] = $groupvalue;
969 }
970 $arrayidused[] = $grouprowid;
971 $arrayidusedconcat[] = $grouprowid;
972 }
973 $i++;
974 }
975 } else {
976 dol_print_error($this->db);
977 }
978 if (count($arrayidused) == 1) {
979 return '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.dol_escape_htmltag($groupvalue).'">';
980 } else {
981 $stringtoprint .= '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'_select" class="maxwidth500 minwidth400">';
982 $stringtoprint .= '<input type="hidden" name="'.$htmlname.'_child_id" id="'.$htmlname.'_select_child_id" class="maxwidth500 minwidth400">';
983 }
984 $stringtoprint .= '</select>&nbsp;';
985
986 $levelid = 1; // The first combobox
987 while ($levelid <= $use_multilevel) { // Loop to take the child of the combo
988 $tabscript = array();
989 $stringtoprint .= '<select id ="'.$htmlname.'_child_'.$levelid.'" class="maxwidth500 minwidth400 groupticketchild" child_id="'.$levelid.'">';
990 $stringtoprint .= '<option value="">&nbsp;</option>';
991
992 $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ctcjoin.code as codefather";
993 $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc";
994 $sql .= " JOIN ".$this->db->prefix()."c_ticket_category as ctcjoin ON ctc.fk_parent = ctcjoin.rowid";
995 $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
996 $sql .= " AND ctc.rowid NOT IN (".$this->db->sanitize(join(',', $arrayidusedconcat)).")";
997
998 if ($filtertype == 'public=1') {
999 $sql .= " AND ctc.public = 1";
1000 }
1001 // Add a test to take only record that are direct child
1002 if (!empty($arrayidused)) {
1003 $sql .= " AND ctc.fk_parent IN ( ";
1004 foreach ($arrayidused as $idused) {
1005 $sql .= $idused.", ";
1006 }
1007 $sql = substr($sql, 0, -2);
1008 $sql .= ")";
1009 }
1010 $sql .= $this->db->order('ctc.pos', 'ASC');
1011
1012 $resql = $this->db->query($sql);
1013 if ($resql) {
1014 $num_rows = $this->db->num_rows($resql);
1015 $i = 0;
1016 $arrayidused=array();
1017 while ($i < $num_rows) {
1018 $obj = $this->db->fetch_object($resql);
1019 if ($obj) {
1020 $label = ($obj->label != '-' ? $obj->label : '');
1021 if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) {
1022 $label = $outputlangs->trans("TicketCategoryShort".$obj->code);
1023 } elseif ($outputlangs->trans($obj->code) != $obj->code) {
1024 $label = $outputlangs->trans($obj->code);
1025 }
1026
1027 $grouprowid = $obj->rowid;
1028 $groupvalue = $obj->code;
1029 $grouplabel = $label;
1030 $isparent = $obj->isparent;
1031 $fatherid = $obj->fk_parent;
1032 $arrayidused[] = $grouprowid;
1033 $arrayidusedconcat[] = $grouprowid;
1034 $groupcodefather = $obj->codefather;
1035 if ($isparent == 'NOTPARENT') {
1036 $arraycodenotparent[] = $groupvalue;
1037 }
1038 if (is_array($selectedgroups)) {
1039 $iselected = in_array($obj->code, $selectedgroups) ?'selected':'';
1040 } else {
1041 $iselected = $groupticket == $obj->code ?'selected':'';
1042 }
1043 $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>';
1044 if (empty($tabscript[$groupcodefather])) {
1045 $tabscript[$groupcodefather] = 'if ($("#'.$htmlname.($levelid > 1 ?'_child_'.($levelid-1):'').'").val() == "'.dol_escape_js($groupcodefather).'"){
1046 $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").show()
1047 console.log("We show childs tickets of '.$groupcodefather.' group ticket")
1048 }else{
1049 $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").hide()
1050 console.log("We hide childs tickets of '.$groupcodefather.' group ticket")
1051 }';
1052 }
1053 }
1054 $i++;
1055 }
1056 } else {
1057 dol_print_error($this->db);
1058 }
1059 $stringtoprint .='</select>';
1060
1061 $stringtoprint .='<script nonce="'.getNonce().'">';
1062 $stringtoprint .='arraynotparents = '.json_encode($arraycodenotparent).';'; // when the last visible combo list is number x, this is the array of group
1063 $stringtoprint .='if (arraynotparents.includes($("#'.$htmlname.($levelid > 1 ?'_child_'.($levelid-1):'').'").val())){
1064 console.log("'.$htmlname.'_child_'.$levelid.'")
1065 if($("#'.$htmlname.'_child_'.$levelid.'").val() == "" && ($("#'.$htmlname.'_child_'.$levelid.'").attr("child_id")>'.$child_id.')){
1066 $("#'.$htmlname.'_child_'.$levelid.'").hide();
1067 console.log("We hide '.$htmlname.'_child_'.$levelid.' input")
1068 }
1069 if(arraynotparents.includes("'.$groupticket.'") && '.$child_id.' == 0){
1070 $("#ticketcategory_select_child_id").val($("#'.$htmlname.'").attr("child_id"))
1071 $("#ticketcategory_select").val($("#'.$htmlname.'").val()) ;
1072 console.log("We choose '.$htmlname.' input and reload hidden input");
1073 }
1074 }
1075 $("#'.$htmlname.($levelid > 1 ?'_child_'.($levelid-1):'').'").change(function() {
1076 child_id = $("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid:'').'").attr("child_id");
1077
1078 /* Change of value to select this value*/
1079 if (arraynotparents.includes($(this).val()) || $(this).attr("child_id") == '.$use_multilevel.') {
1080 $("#ticketcategory_select").val($(this).val());
1081 $("#ticketcategory_select_child_id").val($(this).attr("child_id")) ;
1082 console.log("We choose to select "+ $(this).val());
1083 }else{
1084 if ($("#'.$htmlname.'_child_'.$levelid.' option").length <= 1) {
1085 $("#ticketcategory_select").val($(this).val());
1086 $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1087 console.log("We choose to select "+ $(this).val() + " and next combo has no item, so we keep this selection");
1088 } else {
1089 console.log("We choose to select "+ $(this).val() + " but next combo has some item, so we clean selected item");
1090 $("#ticketcategory_select").val("");
1091 $("#ticketcategory_select_child_id").val("");
1092 }
1093 }
1094
1095 console.log("We select a new value into combo child_id="+child_id);
1096
1097 // Hide all selected box that are child of the one modified
1098 $(".groupticketchild").each(function(){
1099 if ($(this).attr("child_id") > child_id) {
1100 console.log("hide child_id="+$(this).attr("child_id"));
1101 $(this).val("");
1102 $(this).hide();
1103 }
1104 })
1105
1106 // Now we enable the next combo
1107 $("#'.$htmlname.'_child_'.$levelid.'").val("");
1108 if (!arraynotparents.includes($(this).val()) && $("#'.$htmlname.'_child_'.$levelid.' option").length > 1) {
1109 console.log($("#'.$htmlname.'_child_'.$levelid.' option").length);
1110 $("#'.$htmlname.'_child_'.$levelid.'").show()
1111 } else {
1112 $("#'.$htmlname.'_child_'.$levelid.'").hide()
1113 }
1114 ';
1115 $levelid++;
1116 foreach ($tabscript as $script) {
1117 $stringtoprint .= $script;
1118 }
1119 $stringtoprint .='})';
1120 $stringtoprint .='</script>';
1121 }
1122 $stringtoprint .='<script nonce="'.getNonce().'">';
1123 $stringtoprint .='$("#'.$htmlname.'_child_'.$use_multilevel.'").change(function() {
1124 $("#ticketcategory_select").val($(this).val());
1125 $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1126 console.log($("#ticketcategory_select").val());
1127 })';
1128 $stringtoprint .='</script>';
1129 $stringtoprint .= ajax_combobox($htmlname);
1130
1131 return $stringtoprint;
1132 }
1133 }
1134
1148 public function selectSeveritiesTickets($selected = '', $htmlname = 'ticketseverity', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '')
1149 {
1150 global $langs, $user;
1151
1152 $ticketstat = new Ticket($this->db);
1153
1154 dol_syslog(get_class($this)."::selectSeveritiesTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
1155
1156 $filterarray = array();
1157
1158 if ($filtertype != '' && $filtertype != '-1') {
1159 $filterarray = explode(',', $filtertype);
1160 }
1161
1162 $ticketstat->loadCacheSeveritiesTickets();
1163
1164 print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
1165 if ($empty) {
1166 print '<option value="">&nbsp;</option>';
1167 }
1168
1169 if (is_array($ticketstat->cache_severity_tickets) && count($ticketstat->cache_severity_tickets)) {
1170 foreach ($ticketstat->cache_severity_tickets as $id => $arrayseverities) {
1171 // On passe si on a demande de filtrer sur des modes de paiments particuliers
1172 if (count($filterarray) && !in_array($arrayseverities['type'], $filterarray)) {
1173 continue;
1174 }
1175
1176 // We discard empty line if showempty is on because an empty line has already been output.
1177 if ($empty && empty($arrayseverities['code'])) {
1178 continue;
1179 }
1180
1181 if ($format == 0) {
1182 print '<option value="'.$id.'"';
1183 }
1184
1185 if ($format == 1) {
1186 print '<option value="'.$arrayseverities['code'].'"';
1187 }
1188
1189 if ($format == 2) {
1190 print '<option value="'.$arrayseverities['code'].'"';
1191 }
1192
1193 if ($format == 3) {
1194 print '<option value="'.$id.'"';
1195 }
1196
1197 // If text is selected, we compare with code, otherwise with id
1198 if (isset($selected) && preg_match('/[a-z]/i', $selected) && $selected == $arrayseverities['code']) {
1199 print ' selected="selected"';
1200 } elseif (isset($selected) && $selected == $id) {
1201 print ' selected="selected"';
1202 } elseif ($arrayseverities['use_default'] == "1" && !$selected && !$empty) {
1203 print ' selected="selected"';
1204 }
1205
1206 print '>';
1207
1208 $value = '';
1209 if ($format == 0) {
1210 $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
1211 }
1212
1213 if ($format == 1) {
1214 $value = $arrayseverities['code'];
1215 }
1216
1217 if ($format == 2) {
1218 $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
1219 }
1220
1221 if ($format == 3) {
1222 $value = $arrayseverities['code'];
1223 }
1224
1225 print $value ? $value : '&nbsp;';
1226 print '</option>';
1227 }
1228 }
1229 print '</select>';
1230 if (isset($user->admin) && $user->admin && !$noadmininfo) {
1231 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1232 }
1233
1234 print ajax_combobox('select'.$htmlname);
1235 }
1236
1237 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1243 public function clear_attached_files()
1244 {
1245 // phpcs:enable
1246 global $conf, $user;
1247 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1248
1249 // Set tmp user directory
1250 $vardir = $conf->user->dir_output."/".$user->id;
1251 $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
1252 if (is_dir($upload_dir)) {
1253 dol_delete_dir_recursive($upload_dir);
1254 }
1255
1256 if (!empty($this->trackid)) { // TODO Always use trackid (ticXXX) instead of track_id (abcd123)
1257 $keytoavoidconflict = '-'.$this->trackid;
1258 } else {
1259 $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id;
1260 }
1261 unset($_SESSION["listofpaths".$keytoavoidconflict]);
1262 unset($_SESSION["listofnames".$keytoavoidconflict]);
1263 unset($_SESSION["listofmimes".$keytoavoidconflict]);
1264 }
1265
1272 public function showMessageForm($width = '40%')
1273 {
1274 global $conf, $langs, $user, $hookmanager, $form, $mysoc;
1275
1276 $formmail = new FormMail($this->db);
1277 $addfileaction = 'addfile';
1278
1279 if (!is_object($form)) {
1280 $form = new Form($this->db);
1281 }
1282
1283 // Load translation files required by the page
1284 $langs->loadLangs(array('other', 'mails', 'ticket'));
1285
1286 // Clear temp files. Must be done at beginning, before call of triggers
1287 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
1288 $this->clear_attached_files();
1289 }
1290
1291 // Define output language
1292 $outputlangs = $langs;
1293 $newlang = '';
1294 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->param['langsmodels'])) {
1295 $newlang = $this->param['langsmodels'];
1296 }
1297 if (!empty($newlang)) {
1298 $outputlangs = new Translate("", $conf);
1299 $outputlangs->setDefaultLang($newlang);
1300 $outputlangs->load('other');
1301 }
1302
1303 // Get message template for $this->param["models"] into c_email_templates
1304 $arraydefaultmessage = -1;
1305 if (isset($this->param['models']) && $this->param['models'] != 'none') {
1306 $model_id = 0;
1307 if (array_key_exists('models_id', $this->param)) {
1308 $model_id = (int) $this->param["models_id"];
1309 }
1310
1311 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one
1312 }
1313
1314 // Define list of attached files
1315 $listofpaths = array();
1316 $listofnames = array();
1317 $listofmimes = array();
1318
1319 if (!empty($this->trackid)) {
1320 $keytoavoidconflict = '-'.$this->trackid;
1321 } else {
1322 $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
1323 }
1324 //var_dump($keytoavoidconflict);
1325 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
1326 if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
1327 foreach ($this->param['fileinit'] as $file) {
1328 $formmail->add_attached_files($file, basename($file), dol_mimetype($file));
1329 }
1330 }
1331 }
1332 //var_dump($_SESSION);
1333 //var_dump($_SESSION["listofpaths".$keytoavoidconflict]);
1334 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
1335 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
1336 }
1337 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
1338 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
1339 }
1340 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
1341 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
1342 }
1343
1344 // Define output language
1345 $outputlangs = $langs;
1346 $newlang = '';
1347 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->param['langsmodels'])) {
1348 $newlang = $this->param['langsmodels'];
1349 }
1350 if (!empty($newlang)) {
1351 $outputlangs = new Translate("", $conf);
1352 $outputlangs->setDefaultLang($newlang);
1353 $outputlangs->load('other');
1354 }
1355
1356 print "\n<!-- Begin message_form TICKET -->\n";
1357
1358 $send_email = GETPOST('send_email', 'int') ? GETPOST('send_email', 'int') : 0;
1359
1360 // Example 1 : Adding jquery code
1361 print '<script nonce="'.getNonce().'" type="text/javascript">
1362 jQuery(document).ready(function() {
1363 send_email=' . $send_email.';
1364 if (send_email) {
1365 if (!jQuery("#send_msg_email").is(":checked")) {
1366 jQuery("#send_msg_email").prop("checked", true).trigger("change");
1367 }
1368 jQuery(".email_line").show();
1369 } else {
1370 if (!jQuery("#private_message").is(":checked")) {
1371 jQuery("#private_message").prop("checked", true).trigger("change");
1372 }
1373 jQuery(".email_line").hide();
1374 }
1375 ';
1376
1377 // If constant set, allow to send private messages as email
1378 if (empty($conf->global->TICKET_SEND_PRIVATE_EMAIL)) {
1379 print 'jQuery("#send_msg_email").click(function() {
1380 console.log("Click send_msg_email");
1381 if(jQuery(this).is(":checked")) {
1382 if (jQuery("#private_message").is(":checked")) {
1383 jQuery("#private_message").prop("checked", false).trigger("change");
1384 }
1385 jQuery(".email_line").show();
1386 }
1387 else {
1388 jQuery(".email_line").hide();
1389 }
1390 });
1391
1392 jQuery("#private_message").click(function() {
1393 console.log("Click private_message");
1394 if (jQuery(this).is(":checked")) {
1395 if (jQuery("#send_msg_email").is(":checked")) {
1396 jQuery("#send_msg_email").prop("checked", false).trigger("change");
1397 }
1398 jQuery(".email_line").hide();
1399 }
1400 });';
1401 }
1402
1403 print '});
1404 </script>';
1405
1406
1407 print '<form method="post" name="ticket" id="ticket" enctype="multipart/form-data" action="'.$this->param["returnurl"].'">';
1408 print '<input type="hidden" name="token" value="'.newToken().'">';
1409 print '<input type="hidden" name="action" value="'.$this->action.'">';
1410 print '<input type="hidden" name="actionbis" value="add_message">';
1411 print '<input type="hidden" name="backtopage" value="'.$this->backtopage.'">';
1412 if (!empty($this->trackid)) {
1413 print '<input type="hidden" name="trackid" value="'.$this->trackid.'">';
1414 } else {
1415 print '<input type="hidden" name="trackid" value="'.(empty($this->track_id) ? '' : $this->track_id).'">';
1416 $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
1417 }
1418 foreach ($this->param as $key => $value) {
1419 print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
1420 }
1421
1422 // Get message template
1423 $model_id = 0;
1424 if (array_key_exists('models_id', $this->param)) {
1425 $model_id = $this->param["models_id"];
1426 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);
1427 }
1428
1429 $result = $formmail->fetchAllEMailTemplate(!empty($this->param["models"]) ? $this->param["models"] : "", $user, $outputlangs);
1430 if ($result < 0) {
1431 setEventMessages($this->error, $this->errors, 'errors');
1432 }
1433 $modelmail_array = array();
1434 foreach ($formmail->lines_model as $line) {
1435 $modelmail_array[$line->id] = $line->label;
1436 }
1437
1438 print '<table class="border" width="'.$width.'">';
1439
1440 // External users can't send message email
1441 if ($user->hasRight("ticket", "write") && !$user->socid) {
1442 $ticketstat = new Ticket($this->db);
1443 $res = $ticketstat->fetch('', '', $this->track_id);
1444
1445 print '<tr><td></td><td>';
1446 $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : (getDolGlobalInt('TICKETS_MESSAGE_FORCE_MAIL')?'checked':''));
1447 print '<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.'/> ';
1448 print '<label for="send_msg_email">'.$langs->trans('SendMessageByEmail').'</label>';
1449 $texttooltip = $langs->trans("TicketMessageSendEmailHelp");
1450 if (empty($conf->global->TICKET_SEND_PRIVATE_EMAIL)) {
1451 $texttooltip .= ' '.$langs->trans("TicketMessageSendEmailHelp2b");
1452 } else {
1453 $texttooltip .= ' '.$langs->trans("TicketMessageSendEmailHelp2a", '{s1}');
1454 }
1455 $texttooltip = str_replace('{s1}', $langs->trans('MarkMessageAsPrivate'), $texttooltip);
1456 print ' '.$form->textwithpicto('', $texttooltip, 1, 'help');
1457 print '</td></tr>';
1458
1459 // Private message (not visible by customer/external user)
1460 if (!$user->socid) {
1461 print '<tr><td></td><td>';
1462 $checkbox_selected = (GETPOST('private_message', 'alpha') == "1" ? ' checked' : '');
1463 print '<input type="checkbox" name="private_message" value="1" id="private_message" '.$checkbox_selected.'/> ';
1464 print '<label for="private_message">'.$langs->trans('MarkMessageAsPrivate').'</label>';
1465 print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
1466 print '</td></tr>';
1467 }
1468
1469 // Zone to select its email template
1470 if (count($modelmail_array) > 0) {
1471 print '<tr class="email_line"><td></td><td colspan="2"><div style="padding: 3px 0 3px 0">'."\n";
1472 print $langs->trans('SelectMailModel').': '.$formmail->selectarray('modelmailselected', $modelmail_array, $this->param['models_id'], 1, 0, "", "", 0, 0, 0, '', 'minwidth200');
1473 if ($user->admin) {
1474 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1475 }
1476 print ' &nbsp; ';
1477 print '<input type="submit" class="button" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
1478 print '</div></td>';
1479 }
1480
1481 // Subject
1482 print '<tr class="email_line"><td>'.$langs->trans('Subject').'</td>';
1483 print '<td><input type="text" class="text minwidth500" name="subject" value="['.getDolGlobalString('MAIN_INFO_SOCIETE_NOM').' - '.$langs->trans("Ticket").' '.$ticketstat->ref.'] '.$langs->trans('TicketNewMessage').'" />';
1484 print '</td></tr>';
1485
1486 // Recipients / adressed-to
1487 print '<tr class="email_line"><td>'.$langs->trans('MailRecipients');
1488 print ' '.$form->textwithpicto('', $langs->trans("TicketMessageRecipientsHelp"), 1, 'help');
1489 print '</td><td>';
1490 if ($res) {
1491 // Retrieve email of all contacts (internal and external)
1492 $contacts = $ticketstat->getInfosTicketInternalContact(1);
1493 $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact(1));
1494
1495 $sendto = array();
1496
1497 // Build array to display recipient list
1498 if (is_array($contacts) && count($contacts) > 0) {
1499 foreach ($contacts as $key => $info_sendto) {
1500 if ($info_sendto['email'] != '') {
1501 $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">").' <small class="opacitymedium">('.dol_escape_htmltag($info_sendto['libelle']).")</small>";
1502 }
1503 }
1504 }
1505
1506 if ($ticketstat->origin_email && !in_array($ticketstat->origin_email, $sendto)) {
1507 $sendto[] = dol_escape_htmltag($ticketstat->origin_email).' <small class="opacitymedium">('.$langs->trans("TicketEmailOriginIssuer").")</small>";
1508 }
1509
1510 if ($ticketstat->fk_soc > 0) {
1511 $ticketstat->socid = $ticketstat->fk_soc;
1512 $ticketstat->fetch_thirdparty();
1513
1514 if (is_array($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) {
1515 $sendto[] = $ticketstat->thirdparty->email.' <small class="opacitymedium">('.$langs->trans('Customer').')</small>';
1516 }
1517 }
1518
1519 if (getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')) {
1520 $sendto[] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO').' <small class="opacitymedium">(generic email)</small>';
1521 }
1522
1523 // Print recipient list
1524 if (is_array($sendto) && count($sendto) > 0) {
1525 print img_picto('', 'email', 'class="pictofixedwidth"');
1526 print implode(', ', $sendto);
1527 } else {
1528 print '<div class="warning">'.$langs->trans('WarningNoEMailsAdded').' '.$langs->trans('TicketGoIntoContactTab').'</div>';
1529 }
1530 }
1531 print '</td></tr>';
1532 }
1533
1534 $uselocalbrowser = false;
1535
1536 // Intro
1537 // External users can't send message email
1538 /*
1539 if ($user->rights->ticket->write && !$user->socid && !empty($conf->global->TICKET_MESSAGE_MAIL_INTRO)) {
1540 $mail_intro = GETPOST('mail_intro') ? GETPOST('mail_intro') : $conf->global->TICKET_MESSAGE_MAIL_INTRO;
1541 print '<tr class="email_line"><td><label for="mail_intro">';
1542 print $form->textwithpicto($langs->trans("TicketMessageMailIntro"), $langs->trans("TicketMessageMailIntroHelp"), 1, 'help');
1543 print '</label>';
1544
1545 print '</td><td>';
1546 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1547
1548 $doleditor = new DolEditor('mail_intro', $mail_intro, '100%', 90, 'dolibarr_details', '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_TICKET'), ROWS_2, 70);
1549
1550 $doleditor->Create();
1551 print '</td></tr>';
1552 }
1553 */
1554
1555 // Attached files
1556 if (!empty($this->withfile)) {
1557 $out = '<tr>';
1558 $out .= '<td width="180">'.$langs->trans("MailFile").'</td>';
1559 $out .= '<td>';
1560 // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
1561 $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
1562 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
1563 $out .= 'jQuery(document).ready(function () {';
1564 $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", true);';
1565 $out .= ' jQuery("#addedfile").on("change", function() {';
1566 $out .= ' if (jQuery(this).val().length) {';
1567 $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", false);';
1568 $out .= ' } else {';
1569 $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", true);';
1570 $out .= ' }';
1571 $out .= ' });';
1572 $out .= ' jQuery(".removedfile").click(function() {';
1573 $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
1574 $out .= ' });';
1575 $out .= '})';
1576 $out .= '</script>'."\n";
1577
1578 if (count($listofpaths)) {
1579 foreach ($listofpaths as $key => $val) {
1580 $out .= '<div id="attachfile_'.$key.'">';
1581 $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
1582 if (!$this->withfilereadonly) {
1583 $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.'" />';
1584 }
1585 $out .= '<br></div>';
1586 }
1587 } else {
1588 //$out .= $langs->trans("NoAttachedFiles").'<br>';
1589 }
1590 if ($this->withfile == 2) { // Can add other files
1591 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
1592 $out .= ' ';
1593 $out .= '<input type="submit" class="button smallpaddingimp reposition" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
1594 }
1595 $out .= "</td></tr>\n";
1596
1597 print $out;
1598 }
1599
1600 // MESSAGE
1601
1602 $defaultmessage = "";
1603 if (is_object($arraydefaultmessage) && $arraydefaultmessage->content) {
1604 $defaultmessage = $arraydefaultmessage->content;
1605 }
1606 $defaultmessage = str_replace('\n', "\n", $defaultmessage);
1607
1608 // Deal with format differences between message and signature (text / HTML)
1609 if (dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1610 $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
1611 } elseif (!dol_textishtml($defaultmessage) && isset($this->substit['__USER_SIGNATURE__']) && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1612 $defaultmessage = dol_nl2br($defaultmessage);
1613 }
1614 if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
1615 $defaultmessage = GETPOST('message', 'restricthtml');
1616 } else {
1617 $defaultmessage = make_substitutions($defaultmessage, $this->substit);
1618 // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
1619 $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
1620 $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
1621 }
1622
1623 print '<tr><td colspan="2"><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span>';
1624 if ($user->hasRight("ticket", "write") && !$user->socid) {
1625 $texttooltip = $langs->trans("TicketMessageHelp");
1626 if (getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO') || getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE')) {
1627 $texttooltip .= '<br><br>'.$langs->trans("ForEmailMessageWillBeCompletedWith").'...';
1628 }
1629 if (getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO')) {
1630 $texttooltip .= '<br><u>'.$langs->trans("TicketMessageMailIntro").'</u><br>'.getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO');
1631 }
1632 if (getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE')) {
1633 $texttooltip .= '<br><br><u>'.$langs->trans("TicketMessageMailFooter").'</u><br>'.getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE');
1634 }
1635 print $form->textwithpicto('', $texttooltip, 1, 'help');
1636 }
1637 print '</label></td></tr>';
1638
1639
1640 print '<tr><td colspan="2">';
1641 //$toolbarname = 'dolibarr_details';
1642 $toolbarname = 'dolibarr_notes';
1643 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1644 $doleditor = new DolEditor('message', $defaultmessage, '100%', 200, $toolbarname, '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_5, 70);
1645 $doleditor->Create();
1646 print '</td></tr>';
1647
1648 // Footer
1649 // External users can't send message email
1650 /*if ($user->rights->ticket->write && !$user->socid && !empty($conf->global->TICKET_MESSAGE_MAIL_SIGNATURE)) {
1651 $mail_signature = GETPOST('mail_signature') ? GETPOST('mail_signature') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE;
1652 print '<tr class="email_line"><td><label for="mail_intro">'.$langs->trans("TicketMessageMailFooter").'</label>';
1653 print $form->textwithpicto('', $langs->trans("TicketMessageMailFooterHelp"), 1, 'help');
1654 print '</td><td>';
1655 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1656 $doleditor = new DolEditor('mail_signature', $mail_signature, '100%', 90, 'dolibarr_details', '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_2, 70);
1657 $doleditor->Create();
1658 print '</td></tr>';
1659 }
1660 */
1661
1662 print '</table>';
1663
1664 print '<center><br>';
1665 print '<input type="submit" class="button" name="btn_add_message" value="'.$langs->trans("Add").'"';
1666 // Add a javascript test to avoid to forget to submit file before sending email
1667 if ($this->withfile == 2 && !empty($conf->use_javascript_ajax)) {
1668 print ' onClick="if (document.ticket.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
1669 }
1670 print ' />';
1671 if (!empty($this->withcancel)) {
1672 print " &nbsp; &nbsp; ";
1673 print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
1674 }
1675 print "</center>\n";
1676
1677 print '<input type="hidden" name="page_y">'."\n";
1678
1679 print "</form>\n";
1680
1681 // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1682 if (!empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY)) {
1683 print '<script type="text/javascript">';
1684 print 'jQuery(document).ready(function () {';
1685 print ' $(document).on("keypress", \'#ticket\', function (e) { /* Note this is called at every key pressed ! */
1686 var code = e.keyCode || e.which;
1687 if (code == 13) {
1688 console.log("Enter was intercepted and blocked");
1689 e.preventDefault();
1690 return false;
1691 }
1692 });';
1693 print '})';
1694 print '</script>';
1695 }
1696
1697 print "<!-- End form TICKET -->\n";
1698 }
1699}
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:464
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.
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)
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
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.
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.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
ui dialog ui datepicker calendar ui widget content ui state ui datepicker calendar ui widget header ui state ui datepicker calendar ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
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:120
getMaxFileSizeArray()
Return the max allowed for file upload.