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, 'ifone', 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, 'ifone', 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, 'ifone');
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="">'.((is_numeric($empty) || $empty == 'ifone') ? '&nbsp;' : $empty).'</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" && empty($selected) && !$multiselect) {
757 print ' selected="selected"';
758 } elseif (count($ticketstat->cache_types_tickets) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it
759 print ' selected="selected"';
760 }
761
762 print '>';
763
764 $value = '&nbsp;';
765 if ($format == 0) {
766 $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
767 } elseif ($format == 1) {
768 $value = $arraytypes['code'];
769 } elseif ($format == 2) {
770 $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
771 } elseif ($format == 3) {
772 $value = $arraytypes['code'];
773 }
774
775 print $value ? $value : '&nbsp;';
776 print '</option>';
777 }
778 }
779 print '</select>';
780 if (isset($user->admin) && $user->admin && !$noadmininfo) {
781 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
782 }
783
784 print ajax_combobox('select'.$htmlname);
785 }
786
802 public function selectGroupTickets($selected = '', $htmlname = 'ticketcategory', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '', $use_multilevel = 0, $outputlangs = null)
803 {
804 global $conf, $langs, $user;
805
806 dol_syslog(get_class($this)."::selectCategoryTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
807
808 if (is_null($outputlangs) || !is_object($outputlangs)) {
809 $outputlangs = $langs;
810 }
811 $outputlangs->load("ticket");
812
813 $publicgroups = ($filtertype == 'public=1' || $filtertype == '(public:=:1)');
814
815 $ticketstat = new Ticket($this->db);
816 $ticketstat->loadCacheCategoriesTickets($publicgroups ? 1 : -1); // get list of active ticket groups
817
818 if ($use_multilevel <= 0) { // Only one combo list to select the group of ticket (default)
819 print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
820 if ($empty) {
821 print '<option value="">'.((is_numeric($empty) || $empty == 'ifone') ? '&nbsp;' : $empty).'</option>';
822 }
823
824 if (is_array($ticketstat->cache_category_tickets) && count($ticketstat->cache_category_tickets)) {
825 foreach ($ticketstat->cache_category_tickets as $id => $arraycategories) {
826 // Exclude some record
827 if ($publicgroups) {
828 if (empty($arraycategories['public'])) {
829 continue;
830 }
831 }
832
833 // We discard empty line if showempty is on because an empty line has already been output.
834 if ($empty && empty($arraycategories['code'])) {
835 continue;
836 }
837
838 $label = ($arraycategories['label'] != '-' ? $arraycategories['label'] : '');
839 if ($outputlangs->trans("TicketCategoryShort".$arraycategories['code']) != ("TicketCategoryShort".$arraycategories['code'])) {
840 $label = $outputlangs->trans("TicketCategoryShort".$arraycategories['code']);
841 } elseif ($outputlangs->trans($arraycategories['code']) != $arraycategories['code']) {
842 $label = $outputlangs->trans($arraycategories['code']);
843 }
844
845 if ($format == 0) {
846 print '<option value="'.$id.'"';
847 }
848
849 if ($format == 1) {
850 print '<option value="'.$arraycategories['code'].'"';
851 }
852
853 if ($format == 2) {
854 print '<option value="'.$arraycategories['code'].'"';
855 }
856
857 if ($format == 3) {
858 print '<option value="'.$id.'"';
859 }
860
861 // If selected is text, we compare with code, otherwise with id
862 if (isset($selected) && preg_match('/[a-z]/i', $selected) && $selected == $arraycategories['code']) {
863 print ' selected="selected"';
864 } elseif (isset($selected) && $selected == $id) {
865 print ' selected="selected"';
866 } elseif ($arraycategories['use_default'] == "1" && !$selected && (!$empty || $empty == 'ifone')) {
867 print ' selected="selected"';
868 } elseif (count($ticketstat->cache_category_tickets) == 1 && (!$empty || $empty == 'ifone')) {
869 print ' selected="selected"';
870 }
871
872 print '>';
873
874 $value = '';
875 if ($format == 0) {
876 $value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
877 }
878
879 if ($format == 1) {
880 $value = $arraycategories['code'];
881 }
882
883 if ($format == 2) {
884 $value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
885 }
886
887 if ($format == 3) {
888 $value = $arraycategories['code'];
889 }
890
891 print $value ? $value : '&nbsp;';
892 print '</option>';
893 }
894 }
895 print '</select>';
896 if (isset($user->admin) && $user->admin && !$noadmininfo) {
897 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
898 }
899
900 print ajax_combobox('select'.$htmlname);
901 } elseif ($htmlname!='') {
902 $selectedgroups = array();
903 $groupvalue = "";
904 $groupticket=GETPOST($htmlname, 'aZ09');
905 $child_id=GETPOST($htmlname.'_child_id', 'aZ09')?GETPOST($htmlname.'_child_id', 'aZ09'):0;
906 if (!empty($groupticket)) {
907 $tmpgroupticket = $groupticket;
908 $sql = "SELECT ctc.rowid, ctc.fk_parent, ctc.code";
909 $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc WHERE ctc.code = '".$this->db->escape($tmpgroupticket)."'";
910 $resql = $this->db->query($sql);
911 if ($resql) {
912 $obj = $this->db->fetch_object($resql);
913 $selectedgroups[] = $obj->code;
914 while ($obj->fk_parent > 0) {
915 $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)."'";
916 $resql = $this->db->query($sql);
917 if ($resql) {
918 $obj = $this->db->fetch_object($resql);
919 $selectedgroups[] = $obj->code;
920 }
921 }
922 }
923 }
924
925 $arrayidused = array();
926 $arrayidusedconcat = array();
927 $arraycodenotparent = array();
928 $arraycodenotparent[] = "";
929
930 $stringtoprint = '<span class="supportemailfield bold">'.$langs->trans("GroupOfTicket").'</span> ';
931 $stringtoprint .= '<select id ="'.$htmlname.'" class="minwidth500" child_id="0">';
932 $stringtoprint .= '<option value="">&nbsp;</option>';
933
934 $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ";
935 $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";
936 $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc";
937 $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
938 if ($filtertype == 'public=1') {
939 $sql .= " AND ctc.public = 1";
940 }
941 $sql .= " AND ctc.fk_parent = 0";
942 $sql .= $this->db->order('ctc.pos', 'ASC');
943
944 $resql = $this->db->query($sql);
945 if ($resql) {
946 $num_rows_level0 = $this->db->num_rows($resql);
947 $i = 0;
948 while ($i < $num_rows_level0) {
949 $obj = $this->db->fetch_object($resql);
950 if ($obj) {
951 $label = ($obj->label != '-' ? $obj->label : '');
952 if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) {
953 $label = $outputlangs->trans("TicketCategoryShort".$obj->code);
954 } elseif ($outputlangs->trans($obj->code) != $obj->code) {
955 $label = $outputlangs->trans($obj->code);
956 }
957
958 $grouprowid = $obj->rowid;
959 $groupvalue = $obj->code;
960 $grouplabel = $label;
961
962 $isparent = $obj->isparent;
963 if (is_array($selectedgroups)) {
964 $iselected = in_array($obj->code, $selectedgroups) ?'selected':'';
965 } else {
966 $iselected = $groupticket == $obj->code ?'selected':'';
967 }
968 $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>';
969 if ($isparent == 'NOTPARENT') {
970 $arraycodenotparent[] = $groupvalue;
971 }
972 $arrayidused[] = $grouprowid;
973 $arrayidusedconcat[] = $grouprowid;
974 }
975 $i++;
976 }
977 } else {
978 dol_print_error($this->db);
979 }
980 if (count($arrayidused) == 1) {
981 return '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.dol_escape_htmltag($groupvalue).'">';
982 } else {
983 $stringtoprint .= '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'_select" class="maxwidth500 minwidth400">';
984 $stringtoprint .= '<input type="hidden" name="'.$htmlname.'_child_id" id="'.$htmlname.'_select_child_id" class="maxwidth500 minwidth400">';
985 }
986 $stringtoprint .= '</select>&nbsp;';
987
988 $levelid = 1; // The first combobox
989 while ($levelid <= $use_multilevel) { // Loop to take the child of the combo
990 $tabscript = array();
991 $stringtoprint .= '<select id ="'.$htmlname.'_child_'.$levelid.'" class="maxwidth500 minwidth400 groupticketchild" child_id="'.$levelid.'">';
992 $stringtoprint .= '<option value="">&nbsp;</option>';
993
994 $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ctcjoin.code as codefather";
995 $sql .= " FROM ".$this->db->prefix()."c_ticket_category as ctc";
996 $sql .= " JOIN ".$this->db->prefix()."c_ticket_category as ctcjoin ON ctc.fk_parent = ctcjoin.rowid";
997 $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
998 $sql .= " AND ctc.rowid NOT IN (".$this->db->sanitize(join(',', $arrayidusedconcat)).")";
999
1000 if ($filtertype == 'public=1') {
1001 $sql .= " AND ctc.public = 1";
1002 }
1003 // Add a test to take only record that are direct child
1004 if (!empty($arrayidused)) {
1005 $sql .= " AND ctc.fk_parent IN ( ";
1006 foreach ($arrayidused as $idused) {
1007 $sql .= $idused.", ";
1008 }
1009 $sql = substr($sql, 0, -2);
1010 $sql .= ")";
1011 }
1012 $sql .= $this->db->order('ctc.pos', 'ASC');
1013
1014 $resql = $this->db->query($sql);
1015 if ($resql) {
1016 $num_rows = $this->db->num_rows($resql);
1017 $i = 0;
1018 $arrayidused=array();
1019 while ($i < $num_rows) {
1020 $obj = $this->db->fetch_object($resql);
1021 if ($obj) {
1022 $label = ($obj->label != '-' ? $obj->label : '');
1023 if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) {
1024 $label = $outputlangs->trans("TicketCategoryShort".$obj->code);
1025 } elseif ($outputlangs->trans($obj->code) != $obj->code) {
1026 $label = $outputlangs->trans($obj->code);
1027 }
1028
1029 $grouprowid = $obj->rowid;
1030 $groupvalue = $obj->code;
1031 $grouplabel = $label;
1032 $isparent = $obj->isparent;
1033 $fatherid = $obj->fk_parent;
1034 $arrayidused[] = $grouprowid;
1035 $arrayidusedconcat[] = $grouprowid;
1036 $groupcodefather = $obj->codefather;
1037 if ($isparent == 'NOTPARENT') {
1038 $arraycodenotparent[] = $groupvalue;
1039 }
1040 if (is_array($selectedgroups)) {
1041 $iselected = in_array($obj->code, $selectedgroups) ?'selected':'';
1042 } else {
1043 $iselected = $groupticket == $obj->code ?'selected':'';
1044 }
1045 $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>';
1046 if (empty($tabscript[$groupcodefather])) {
1047 $tabscript[$groupcodefather] = 'if ($("#'.$htmlname.($levelid > 1 ?'_child_'.($levelid-1):'').'").val() == "'.dol_escape_js($groupcodefather).'"){
1048 $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").show()
1049 console.log("We show childs tickets of '.$groupcodefather.' group ticket")
1050 }else{
1051 $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").hide()
1052 console.log("We hide childs tickets of '.$groupcodefather.' group ticket")
1053 }';
1054 }
1055 }
1056 $i++;
1057 }
1058 } else {
1059 dol_print_error($this->db);
1060 }
1061 $stringtoprint .='</select>';
1062
1063 $stringtoprint .='<script nonce="'.getNonce().'">';
1064 $stringtoprint .='arraynotparents = '.json_encode($arraycodenotparent).';'; // when the last visible combo list is number x, this is the array of group
1065 $stringtoprint .='if (arraynotparents.includes($("#'.$htmlname.($levelid > 1 ?'_child_'.($levelid-1):'').'").val())){
1066 console.log("'.$htmlname.'_child_'.$levelid.'")
1067 if($("#'.$htmlname.'_child_'.$levelid.'").val() == "" && ($("#'.$htmlname.'_child_'.$levelid.'").attr("child_id")>'.$child_id.')){
1068 $("#'.$htmlname.'_child_'.$levelid.'").hide();
1069 console.log("We hide '.$htmlname.'_child_'.$levelid.' input")
1070 }
1071 if(arraynotparents.includes("'.$groupticket.'") && '.$child_id.' == 0){
1072 $("#ticketcategory_select_child_id").val($("#'.$htmlname.'").attr("child_id"))
1073 $("#ticketcategory_select").val($("#'.$htmlname.'").val()) ;
1074 console.log("We choose '.$htmlname.' input and reload hidden input");
1075 }
1076 }
1077 $("#'.$htmlname.($levelid > 1 ?'_child_'.($levelid-1):'').'").change(function() {
1078 child_id = $("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid:'').'").attr("child_id");
1079
1080 /* Change of value to select this value*/
1081 if (arraynotparents.includes($(this).val()) || $(this).attr("child_id") == '.$use_multilevel.') {
1082 $("#ticketcategory_select").val($(this).val());
1083 $("#ticketcategory_select_child_id").val($(this).attr("child_id")) ;
1084 console.log("We choose to select "+ $(this).val());
1085 }else{
1086 if ($("#'.$htmlname.'_child_'.$levelid.' option").length <= 1) {
1087 $("#ticketcategory_select").val($(this).val());
1088 $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1089 console.log("We choose to select "+ $(this).val() + " and next combo has no item, so we keep this selection");
1090 } else {
1091 console.log("We choose to select "+ $(this).val() + " but next combo has some item, so we clean selected item");
1092 $("#ticketcategory_select").val("");
1093 $("#ticketcategory_select_child_id").val("");
1094 }
1095 }
1096
1097 console.log("We select a new value into combo child_id="+child_id);
1098
1099 // Hide all selected box that are child of the one modified
1100 $(".groupticketchild").each(function(){
1101 if ($(this).attr("child_id") > child_id) {
1102 console.log("hide child_id="+$(this).attr("child_id"));
1103 $(this).val("");
1104 $(this).hide();
1105 }
1106 })
1107
1108 // Now we enable the next combo
1109 $("#'.$htmlname.'_child_'.$levelid.'").val("");
1110 if (!arraynotparents.includes($(this).val()) && $("#'.$htmlname.'_child_'.$levelid.' option").length > 1) {
1111 console.log($("#'.$htmlname.'_child_'.$levelid.' option").length);
1112 $("#'.$htmlname.'_child_'.$levelid.'").show()
1113 } else {
1114 $("#'.$htmlname.'_child_'.$levelid.'").hide()
1115 }
1116 ';
1117 $levelid++;
1118 foreach ($tabscript as $script) {
1119 $stringtoprint .= $script;
1120 }
1121 $stringtoprint .='})';
1122 $stringtoprint .='</script>';
1123 }
1124 $stringtoprint .='<script nonce="'.getNonce().'">';
1125 $stringtoprint .='$("#'.$htmlname.'_child_'.$use_multilevel.'").change(function() {
1126 $("#ticketcategory_select").val($(this).val());
1127 $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1128 console.log($("#ticketcategory_select").val());
1129 })';
1130 $stringtoprint .='</script>';
1131 $stringtoprint .= ajax_combobox($htmlname);
1132
1133 return $stringtoprint;
1134 }
1135 }
1136
1150 public function selectSeveritiesTickets($selected = '', $htmlname = 'ticketseverity', $filtertype = '', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss = '')
1151 {
1152 global $langs, $user;
1153
1154 $ticketstat = new Ticket($this->db);
1155
1156 dol_syslog(get_class($this)."::selectSeveritiesTickets ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
1157
1158 $filterarray = array();
1159
1160 if ($filtertype != '' && $filtertype != '-1') {
1161 $filterarray = explode(',', $filtertype);
1162 }
1163
1164 $ticketstat->loadCacheSeveritiesTickets();
1165
1166 print '<select id="select'.$htmlname.'" class="flat minwidth100'.($morecss ? ' '.$morecss : '').'" name="'.$htmlname.'">';
1167 if ($empty) {
1168 print '<option value="">'.((is_numeric($empty) || $empty == 'ifone') ? '&nbsp;' : $empty).'</option>';
1169 }
1170
1171 if (is_array($ticketstat->cache_severity_tickets) && count($ticketstat->cache_severity_tickets)) {
1172 foreach ($ticketstat->cache_severity_tickets as $id => $arrayseverities) {
1173 // On passe si on a demande de filtrer sur des modes de paiments particuliers
1174 if (count($filterarray) && !in_array($arrayseverities['type'], $filterarray)) {
1175 continue;
1176 }
1177
1178 // We discard empty line if showempty is on because an empty line has already been output.
1179 if ($empty && empty($arrayseverities['code'])) {
1180 continue;
1181 }
1182
1183 if ($format == 0) {
1184 print '<option value="'.$id.'"';
1185 }
1186
1187 if ($format == 1) {
1188 print '<option value="'.$arrayseverities['code'].'"';
1189 }
1190
1191 if ($format == 2) {
1192 print '<option value="'.$arrayseverities['code'].'"';
1193 }
1194
1195 if ($format == 3) {
1196 print '<option value="'.$id.'"';
1197 }
1198
1199 // If text is selected, we compare with code, otherwise with id
1200 if (isset($selected) && preg_match('/[a-z]/i', $selected) && $selected == $arrayseverities['code']) {
1201 print ' selected="selected"';
1202 } elseif (isset($selected) && $selected == $id) {
1203 print ' selected="selected"';
1204 } elseif ($arrayseverities['use_default'] == "1" && empty($selected) && (!$empty || $empty == 'ifone')) {
1205 print ' selected="selected"';
1206 } elseif (count($ticketstat->cache_severity_tickets) == 1 && (!$empty || $empty == 'ifone')) { // If only 1 choice, we autoselect it
1207 print ' selected="selected"';
1208 }
1209
1210 print '>';
1211
1212 $value = '';
1213 if ($format == 0) {
1214 $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
1215 }
1216
1217 if ($format == 1) {
1218 $value = $arrayseverities['code'];
1219 }
1220
1221 if ($format == 2) {
1222 $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
1223 }
1224
1225 if ($format == 3) {
1226 $value = $arrayseverities['code'];
1227 }
1228
1229 print $value ? $value : '&nbsp;';
1230 print '</option>';
1231 }
1232 }
1233 print '</select>';
1234 if (isset($user->admin) && $user->admin && !$noadmininfo) {
1235 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1236 }
1237
1238 print ajax_combobox('select'.$htmlname);
1239 }
1240
1241 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1247 public function clear_attached_files()
1248 {
1249 // phpcs:enable
1250 global $conf, $user;
1251 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1252
1253 // Set tmp user directory
1254 $vardir = $conf->user->dir_output."/".$user->id;
1255 $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
1256 if (is_dir($upload_dir)) {
1257 dol_delete_dir_recursive($upload_dir);
1258 }
1259
1260 if (!empty($this->trackid)) { // TODO Always use trackid (ticXXX) instead of track_id (abcd123)
1261 $keytoavoidconflict = '-'.$this->trackid;
1262 } else {
1263 $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id;
1264 }
1265 unset($_SESSION["listofpaths".$keytoavoidconflict]);
1266 unset($_SESSION["listofnames".$keytoavoidconflict]);
1267 unset($_SESSION["listofmimes".$keytoavoidconflict]);
1268 }
1269
1276 public function showMessageForm($width = '40%')
1277 {
1278 global $conf, $langs, $user, $hookmanager, $form, $mysoc;
1279
1280 $formmail = new FormMail($this->db);
1281 $addfileaction = 'addfile';
1282
1283 if (!is_object($form)) {
1284 $form = new Form($this->db);
1285 }
1286
1287 // Load translation files required by the page
1288 $langs->loadLangs(array('other', 'mails', 'ticket'));
1289
1290 // Clear temp files. Must be done at beginning, before call of triggers
1291 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
1292 $this->clear_attached_files();
1293 }
1294
1295 // Define output language
1296 $outputlangs = $langs;
1297 $newlang = '';
1298 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->param['langsmodels'])) {
1299 $newlang = $this->param['langsmodels'];
1300 }
1301 if (!empty($newlang)) {
1302 $outputlangs = new Translate("", $conf);
1303 $outputlangs->setDefaultLang($newlang);
1304 $outputlangs->load('other');
1305 }
1306
1307 // Get message template for $this->param["models"] into c_email_templates
1308 $arraydefaultmessage = -1;
1309 if (isset($this->param['models']) && $this->param['models'] != 'none') {
1310 $model_id = 0;
1311 if (array_key_exists('models_id', $this->param)) {
1312 $model_id = (int) $this->param["models_id"];
1313 }
1314
1315 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one
1316 }
1317
1318 // Define list of attached files
1319 $listofpaths = array();
1320 $listofnames = array();
1321 $listofmimes = array();
1322
1323 if (!empty($this->trackid)) {
1324 $keytoavoidconflict = '-'.$this->trackid;
1325 } else {
1326 $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
1327 }
1328 //var_dump($keytoavoidconflict);
1329 if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
1330 if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
1331 foreach ($this->param['fileinit'] as $file) {
1332 $formmail->add_attached_files($file, basename($file), dol_mimetype($file));
1333 }
1334 }
1335 }
1336 //var_dump($_SESSION);
1337 //var_dump($_SESSION["listofpaths".$keytoavoidconflict]);
1338 if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
1339 $listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
1340 }
1341 if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
1342 $listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
1343 }
1344 if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
1345 $listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
1346 }
1347
1348 // Define output language
1349 $outputlangs = $langs;
1350 $newlang = '';
1351 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && isset($this->param['langsmodels'])) {
1352 $newlang = $this->param['langsmodels'];
1353 }
1354 if (!empty($newlang)) {
1355 $outputlangs = new Translate("", $conf);
1356 $outputlangs->setDefaultLang($newlang);
1357 $outputlangs->load('other');
1358 }
1359
1360 print "\n<!-- Begin message_form TICKET -->\n";
1361
1362 $send_email = GETPOST('send_email', 'int') ? GETPOST('send_email', 'int') : 0;
1363
1364 // Example 1 : Adding jquery code
1365 print '<script nonce="'.getNonce().'" type="text/javascript">
1366 jQuery(document).ready(function() {
1367 send_email=' . $send_email.';
1368 if (send_email) {
1369 if (!jQuery("#send_msg_email").is(":checked")) {
1370 jQuery("#send_msg_email").prop("checked", true).trigger("change");
1371 }
1372 jQuery(".email_line").show();
1373 } else {
1374 if (!jQuery("#private_message").is(":checked")) {
1375 jQuery("#private_message").prop("checked", true).trigger("change");
1376 }
1377 jQuery(".email_line").hide();
1378 }
1379 ';
1380
1381 // If constant set, allow to send private messages as email
1382 if (empty($conf->global->TICKET_SEND_PRIVATE_EMAIL)) {
1383 print 'jQuery("#send_msg_email").click(function() {
1384 console.log("Click send_msg_email");
1385 if(jQuery(this).is(":checked")) {
1386 if (jQuery("#private_message").is(":checked")) {
1387 jQuery("#private_message").prop("checked", false).trigger("change");
1388 }
1389 jQuery(".email_line").show();
1390 }
1391 else {
1392 jQuery(".email_line").hide();
1393 }
1394 });
1395
1396 jQuery("#private_message").click(function() {
1397 console.log("Click private_message");
1398 if (jQuery(this).is(":checked")) {
1399 if (jQuery("#send_msg_email").is(":checked")) {
1400 jQuery("#send_msg_email").prop("checked", false).trigger("change");
1401 }
1402 jQuery(".email_line").hide();
1403 }
1404 });';
1405 }
1406
1407 print '});
1408 </script>';
1409
1410
1411 print '<form method="post" name="ticket" id="ticket" enctype="multipart/form-data" action="'.$this->param["returnurl"].'">';
1412 print '<input type="hidden" name="token" value="'.newToken().'">';
1413 print '<input type="hidden" name="action" value="'.$this->action.'">';
1414 print '<input type="hidden" name="actionbis" value="add_message">';
1415 print '<input type="hidden" name="backtopage" value="'.$this->backtopage.'">';
1416 if (!empty($this->trackid)) {
1417 print '<input type="hidden" name="trackid" value="'.$this->trackid.'">';
1418 } else {
1419 print '<input type="hidden" name="trackid" value="'.(empty($this->track_id) ? '' : $this->track_id).'">';
1420 $keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
1421 }
1422 foreach ($this->param as $key => $value) {
1423 print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
1424 }
1425
1426 // Get message template
1427 $model_id = 0;
1428 if (array_key_exists('models_id', $this->param)) {
1429 $model_id = $this->param["models_id"];
1430 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);
1431 }
1432
1433 $result = $formmail->fetchAllEMailTemplate(!empty($this->param["models"]) ? $this->param["models"] : "", $user, $outputlangs);
1434 if ($result < 0) {
1435 setEventMessages($this->error, $this->errors, 'errors');
1436 }
1437 $modelmail_array = array();
1438 foreach ($formmail->lines_model as $line) {
1439 $modelmail_array[$line->id] = $line->label;
1440 }
1441
1442 print '<table class="border" width="'.$width.'">';
1443
1444 // External users can't send message email
1445 if ($user->hasRight("ticket", "write") && !$user->socid) {
1446 $ticketstat = new Ticket($this->db);
1447 $res = $ticketstat->fetch('', '', $this->track_id);
1448
1449 print '<tr><td></td><td>';
1450 $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : (getDolGlobalInt('TICKETS_MESSAGE_FORCE_MAIL')?'checked':''));
1451 print '<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.'/> ';
1452 print '<label for="send_msg_email">'.$langs->trans('SendMessageByEmail').'</label>';
1453 $texttooltip = $langs->trans("TicketMessageSendEmailHelp");
1454 if (empty($conf->global->TICKET_SEND_PRIVATE_EMAIL)) {
1455 $texttooltip .= ' '.$langs->trans("TicketMessageSendEmailHelp2b");
1456 } else {
1457 $texttooltip .= ' '.$langs->trans("TicketMessageSendEmailHelp2a", '{s1}');
1458 }
1459 $texttooltip = str_replace('{s1}', $langs->trans('MarkMessageAsPrivate'), $texttooltip);
1460 print ' '.$form->textwithpicto('', $texttooltip, 1, 'help');
1461 print '</td></tr>';
1462
1463 // Private message (not visible by customer/external user)
1464 if (!$user->socid) {
1465 print '<tr><td></td><td>';
1466 $checkbox_selected = (GETPOST('private_message', 'alpha') == "1" ? ' checked' : '');
1467 print '<input type="checkbox" name="private_message" value="1" id="private_message" '.$checkbox_selected.'/> ';
1468 print '<label for="private_message">'.$langs->trans('MarkMessageAsPrivate').'</label>';
1469 print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
1470 print '</td></tr>';
1471 }
1472
1473 // Zone to select its email template
1474 if (count($modelmail_array) > 0) {
1475 print '<tr class="email_line"><td></td><td colspan="2"><div style="padding: 3px 0 3px 0">'."\n";
1476 print $langs->trans('SelectMailModel').': '.$formmail->selectarray('modelmailselected', $modelmail_array, $this->param['models_id'], 1, 0, "", "", 0, 0, 0, '', 'minwidth200');
1477 if ($user->admin) {
1478 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1479 }
1480 print ' &nbsp; ';
1481 print '<input type="submit" class="button" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
1482 print '</div></td>';
1483 }
1484
1485 // Subject
1486 print '<tr class="email_line"><td>'.$langs->trans('Subject').'</td>';
1487 print '<td><input type="text" class="text minwidth500" name="subject" value="['.getDolGlobalString('MAIN_INFO_SOCIETE_NOM').' - '.$langs->trans("Ticket").' '.$ticketstat->ref.'] '.$langs->trans('TicketNewMessage').'" />';
1488 print '</td></tr>';
1489
1490 // Recipients / adressed-to
1491 print '<tr class="email_line"><td>'.$langs->trans('MailRecipients');
1492 print ' '.$form->textwithpicto('', $langs->trans("TicketMessageRecipientsHelp"), 1, 'help');
1493 print '</td><td>';
1494 if ($res) {
1495 // Retrieve email of all contacts (internal and external)
1496 $contacts = $ticketstat->getInfosTicketInternalContact(1);
1497 $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact(1));
1498
1499 $sendto = array();
1500
1501 // Build array to display recipient list
1502 if (is_array($contacts) && count($contacts) > 0) {
1503 foreach ($contacts as $key => $info_sendto) {
1504 if ($info_sendto['email'] != '') {
1505 $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">").' <small class="opacitymedium">('.dol_escape_htmltag($info_sendto['libelle']).")</small>";
1506 }
1507 }
1508 }
1509
1510 if ($ticketstat->origin_email && !in_array($ticketstat->origin_email, $sendto)) {
1511 $sendto[] = dol_escape_htmltag($ticketstat->origin_email).' <small class="opacitymedium">('.$langs->trans("TicketEmailOriginIssuer").")</small>";
1512 }
1513
1514 if ($ticketstat->fk_soc > 0) {
1515 $ticketstat->socid = $ticketstat->fk_soc;
1516 $ticketstat->fetch_thirdparty();
1517
1518 if (is_array($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) {
1519 $sendto[] = $ticketstat->thirdparty->email.' <small class="opacitymedium">('.$langs->trans('Customer').')</small>';
1520 }
1521 }
1522
1523 if (getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')) {
1524 $sendto[] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO').' <small class="opacitymedium">(generic email)</small>';
1525 }
1526
1527 // Print recipient list
1528 if (is_array($sendto) && count($sendto) > 0) {
1529 print img_picto('', 'email', 'class="pictofixedwidth"');
1530 print implode(', ', $sendto);
1531 } else {
1532 print '<div class="warning">'.$langs->trans('WarningNoEMailsAdded').' '.$langs->trans('TicketGoIntoContactTab').'</div>';
1533 }
1534 }
1535 print '</td></tr>';
1536 }
1537
1538 $uselocalbrowser = false;
1539
1540 // Intro
1541 // External users can't send message email
1542 /*
1543 if ($user->rights->ticket->write && !$user->socid && !empty($conf->global->TICKET_MESSAGE_MAIL_INTRO)) {
1544 $mail_intro = GETPOST('mail_intro') ? GETPOST('mail_intro') : $conf->global->TICKET_MESSAGE_MAIL_INTRO;
1545 print '<tr class="email_line"><td><label for="mail_intro">';
1546 print $form->textwithpicto($langs->trans("TicketMessageMailIntro"), $langs->trans("TicketMessageMailIntroHelp"), 1, 'help');
1547 print '</label>';
1548
1549 print '</td><td>';
1550 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1551
1552 $doleditor = new DolEditor('mail_intro', $mail_intro, '100%', 90, 'dolibarr_details', '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_TICKET'), ROWS_2, 70);
1553
1554 $doleditor->Create();
1555 print '</td></tr>';
1556 }
1557 */
1558
1559 // Attached files
1560 if (!empty($this->withfile)) {
1561 $out = '<tr>';
1562 $out .= '<td width="180">'.$langs->trans("MailFile").'</td>';
1563 $out .= '<td>';
1564 // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
1565 $out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
1566 $out .= '<script nonce="'.getNonce().'" type="text/javascript">';
1567 $out .= 'jQuery(document).ready(function () {';
1568 $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", true);';
1569 $out .= ' jQuery("#addedfile").on("change", function() {';
1570 $out .= ' if (jQuery(this).val().length) {';
1571 $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", false);';
1572 $out .= ' } else {';
1573 $out .= ' jQuery("#'.$addfileaction.'").prop("disabled", true);';
1574 $out .= ' }';
1575 $out .= ' });';
1576 $out .= ' jQuery(".removedfile").click(function() {';
1577 $out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
1578 $out .= ' });';
1579 $out .= '})';
1580 $out .= '</script>'."\n";
1581
1582 if (count($listofpaths)) {
1583 foreach ($listofpaths as $key => $val) {
1584 $out .= '<div id="attachfile_'.$key.'">';
1585 $out .= img_mime($listofnames[$key]).' '.$listofnames[$key];
1586 if (!$this->withfilereadonly) {
1587 $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.'" />';
1588 }
1589 $out .= '<br></div>';
1590 }
1591 } else {
1592 //$out .= $langs->trans("NoAttachedFiles").'<br>';
1593 }
1594 if ($this->withfile == 2) { // Can add other files
1595 $out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
1596 $out .= ' ';
1597 $out .= '<input type="submit" class="button smallpaddingimp reposition" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
1598 }
1599 $out .= "</td></tr>\n";
1600
1601 print $out;
1602 }
1603
1604 // MESSAGE
1605
1606 $defaultmessage = "";
1607 if (is_object($arraydefaultmessage) && $arraydefaultmessage->content) {
1608 $defaultmessage = $arraydefaultmessage->content;
1609 }
1610 $defaultmessage = str_replace('\n', "\n", $defaultmessage);
1611
1612 // Deal with format differences between message and signature (text / HTML)
1613 if (dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1614 $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
1615 } elseif (!dol_textishtml($defaultmessage) && isset($this->substit['__USER_SIGNATURE__']) && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
1616 $defaultmessage = dol_nl2br($defaultmessage);
1617 }
1618 if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
1619 $defaultmessage = GETPOST('message', 'restricthtml');
1620 } else {
1621 $defaultmessage = make_substitutions($defaultmessage, $this->substit);
1622 // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
1623 $defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
1624 $defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
1625 }
1626
1627 print '<tr><td colspan="2"><label for="message"><span class="fieldrequired">'.$langs->trans("Message").'</span>';
1628 if ($user->hasRight("ticket", "write") && !$user->socid) {
1629 $texttooltip = $langs->trans("TicketMessageHelp");
1630 if (getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO') || getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE')) {
1631 $texttooltip .= '<br><br>'.$langs->trans("ForEmailMessageWillBeCompletedWith").'...';
1632 }
1633 if (getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO')) {
1634 $texttooltip .= '<br><u>'.$langs->trans("TicketMessageMailIntro").'</u><br>'.getDolGlobalString('TICKET_MESSAGE_MAIL_INTRO');
1635 }
1636 if (getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE')) {
1637 $texttooltip .= '<br><br><u>'.$langs->trans("TicketMessageMailFooter").'</u><br>'.getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE');
1638 }
1639 print $form->textwithpicto('', $texttooltip, 1, 'help');
1640 }
1641 print '</label></td></tr>';
1642
1643
1644 print '<tr><td colspan="2">';
1645 //$toolbarname = 'dolibarr_details';
1646 $toolbarname = 'dolibarr_notes';
1647 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1648 $doleditor = new DolEditor('message', $defaultmessage, '100%', 200, $toolbarname, '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_5, 70);
1649 $doleditor->Create();
1650 print '</td></tr>';
1651
1652 // Footer
1653 // External users can't send message email
1654 /*if ($user->rights->ticket->write && !$user->socid && !empty($conf->global->TICKET_MESSAGE_MAIL_SIGNATURE)) {
1655 $mail_signature = GETPOST('mail_signature') ? GETPOST('mail_signature') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE;
1656 print '<tr class="email_line"><td><label for="mail_intro">'.$langs->trans("TicketMessageMailFooter").'</label>';
1657 print $form->textwithpicto('', $langs->trans("TicketMessageMailFooterHelp"), 1, 'help');
1658 print '</td><td>';
1659 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1660 $doleditor = new DolEditor('mail_signature', $mail_signature, '100%', 90, 'dolibarr_details', '', false, $uselocalbrowser, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_2, 70);
1661 $doleditor->Create();
1662 print '</td></tr>';
1663 }
1664 */
1665
1666 print '</table>';
1667
1668 print '<center><br>';
1669 print '<input type="submit" class="button" name="btn_add_message" value="'.$langs->trans("Add").'"';
1670 // Add a javascript test to avoid to forget to submit file before sending email
1671 if ($this->withfile == 2 && !empty($conf->use_javascript_ajax)) {
1672 print ' onClick="if (document.ticket.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
1673 }
1674 print ' />';
1675 if (!empty($this->withcancel)) {
1676 print " &nbsp; &nbsp; ";
1677 print '<input class="button button-cancel" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
1678 }
1679 print "</center>\n";
1680
1681 print '<input type="hidden" name="page_y">'."\n";
1682
1683 print "</form>\n";
1684
1685 // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1686 if (!empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY)) {
1687 print '<script type="text/javascript">';
1688 print 'jQuery(document).ready(function () {';
1689 print ' $(document).on("keypress", \'#ticket\', function (e) { /* Note this is called at every key pressed ! */
1690 var code = e.keyCode || e.which;
1691 if (code == 13) {
1692 console.log("Enter was intercepted and blocked");
1693 e.preventDefault();
1694 return false;
1695 }
1696 });';
1697 print '})';
1698 print '</script>';
1699 }
1700
1701 print "<!-- End form TICKET -->\n";
1702 }
1703}
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.