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