31require_once DOL_DOCUMENT_ROOT .
'/core/class/html.form.class.php';
32require_once DOL_DOCUMENT_ROOT .
'/core/class/html.formmail.class.php';
33require_once DOL_DOCUMENT_ROOT .
'/core/class/html.formprojet.class.php';
35if (!class_exists(
'FormCompany')) {
36 include DOL_DOCUMENT_ROOT.
'/core/class/html.formcompany.class.php';
67 public $fk_user_create;
104 public $withfilereadonly;
119 public $withtitletopic;
123 public $withtopicreadonly;
136 public $withfromsocid;
140 public $withfromcontactid;
144 public $withnotifytiersatcreate;
148 public $withusercreate;
152 public $withcreatereadonly;
157 public $withextrafields;
175 public $category_code;
179 public $severity_code;
186 public $substit = array();
190 public $param = array();
199 public $errors = array();
213 $this->action =
'add';
216 $this->withfromsocid = 0;
217 $this->withfromcontactid = 0;
218 $this->withreadid = 0;
220 $this->withnotifytiersatcreate = 0;
221 $this->withusercreate = 1;
222 $this->withcreatereadonly = 1;
223 $this->withemail = 0;
225 $this->withextrafields = 0;
241 foreach ($fields as $field => $type) {
242 if (!
GETPOST($field, $type[
'check'])) {
244 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentities($type[
'langs'])),
null,
'errors');
260 public function showForm($withdolfichehead = 0, $mode =
'edit', $public = 0, $with_contact =
null, $action =
'',
$object =
null)
262 global $conf, $langs, $user, $hookmanager;
265 $langs->loadLangs(array(
'other',
'mails',
'ticket'));
267 if ($mode ==
'create') {
268 $ref = GETPOSTISSET(
"ref") ?
GETPOST(
"ref",
'alpha') :
'';
269 $type_code = GETPOSTISSET(
'type_code') ?
GETPOST(
'type_code',
'alpha') :
'';
270 $category_code = GETPOSTISSET(
'category_code') ?
GETPOST(
'category_code',
'alpha') :
'';
271 $severity_code = GETPOSTISSET(
'severity_code') ?
GETPOST(
'severity_code',
'alpha') :
'';
272 $subject = GETPOSTISSET(
'subject') ?
GETPOST(
'subject',
'alpha') :
'';
273 $email = GETPOSTISSET(
'email') ?
GETPOST(
'email',
'alpha') :
'';
274 $msg = GETPOSTISSET(
'message') ?
GETPOST(
'message',
'restricthtml') :
'';
275 $projectid = GETPOSTISSET(
'projectid') ?
GETPOSTINT(
'projectid') : 0;
276 $user_assign = GETPOSTISSET(
'fk_user_assign') ?
GETPOSTINT(
'fk_user_assign') : $this->fk_user_create;
279 $type_code = GETPOSTISSET(
'type_code') ?
GETPOST(
'type_code',
'alpha') :
$object->type_code;
280 $category_code = GETPOSTISSET(
'category_code') ?
GETPOST(
'category_code',
'alpha') :
$object->category_code;
281 $severity_code = GETPOSTISSET(
'severity_code') ?
GETPOST(
'severity_code',
'alpha') :
$object->severity_code;
282 $subject = GETPOSTISSET(
'subject') ?
GETPOST(
'subject',
'alpha') :
$object->subject;
283 $email = GETPOSTISSET(
'email') ?
GETPOST(
'email',
'alpha') :
$object->email_from;
284 $msg = GETPOSTISSET(
'message') ?
GETPOST(
'message',
'restricthtml') :
$object->message;
285 $projectid = GETPOSTISSET(
'projectid') ?
GETPOSTINT(
'projectid') : (int)
$object->fk_project;
286 $user_assign = GETPOSTISSET(
'fk_user_assign') ?
GETPOSTINT(
'fk_user_assign') :
$object->fk_user_assign;
289 $form =
new Form($this->db);
291 $ticketstatic =
new Ticket($this->db);
294 if (!empty($this->withfromsocid) && $this->withfromsocid > 0) {
295 $soc->fetch($this->withfromsocid);
298 $ticketstat =
new Ticket($this->db);
301 $extrafields->fetch_name_optionals_label($ticketstat->table_element);
303 print
"\n<!-- Begin form TICKET -->\n";
305 if ($withdolfichehead) {
309 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']).
'">';
311 print
'<input type="hidden" name="token" value="'.newToken().
'">';
312 print
'<input type="hidden" name="action" value="'.$this->action.
'">';
314 print
'<input type="hidden" name="id" value="'.
$object->id .
'">';
316 print
'<input type="hidden" name="trackid" value="'.$this->trackid.
'">';
317 foreach ($this->param as $key => $value) {
318 print
'<input type="hidden" name="'.$key.
'" value="'.$value.
'">';
320 print
'<input type="hidden" name="fk_user_create" value="'.$this->fk_user_create.
'">';
322 print
'<table class="border centpercent">';
325 if ($this->withref) {
326 $defaultref = $ticketstat->getDefaultRef();
328 if ($mode ==
'edit') {
329 $defaultref = (string)
$object->ref;
331 print
'<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans(
"Ref").
'</span></td><td>';
332 print
'<input type="text" name="ref" value="'.dol_escape_htmltag($defaultref).
'">';
337 if ($this->withemail) {
338 print
'<tr><td class="titlefield"><label for="email"><span class="fieldrequired">'.$langs->trans(
"Email").
'</span></label></td><td>';
339 print
'<input class="text minwidth200" id="email" name="email" value="'.$email.
'" autofocus>';
344 $html_contact_search =
'';
345 $html_contact_search .=
'<tr id="contact_search_line">';
346 $html_contact_search .=
'<td class="titlefield">';
347 $html_contact_search .=
'<label for="contact"><span class="fieldrequired">' . $langs->trans(
'Contact') .
'</span></label>';
348 $html_contact_search .=
'<input type="hidden" id="contact_id" name="contact_id" value="" />';
349 $html_contact_search .=
'</td>';
350 $html_contact_search .=
'<td id="contact_search_result"></td>';
351 $html_contact_search .=
'</tr>';
352 print $html_contact_search;
354 $html_contact_lastname =
'';
355 $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>';
356 $html_contact_lastname .=
'<input type="text" id="contact_lastname" name="contact_lastname" value="' .
dol_escape_htmltag(GETPOSTISSET(
'contact_lastname') ?
GETPOST(
'contact_lastname',
'alphanohtml') :
'') .
'" />';
357 $html_contact_lastname .=
'</td></tr>';
358 print $html_contact_lastname;
360 $html_contact_firstname =
'';
361 $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>';
362 $html_contact_firstname .=
'<input type="text" id="contact_firstname" name="contact_firstname" value="' .
dol_escape_htmltag(GETPOSTISSET(
'contact_firstname') ?
GETPOST(
'contact_firstname',
'alphanohtml') :
'') .
'" />';
363 $html_contact_firstname .=
'</td></tr>';
364 print $html_contact_firstname;
366 $html_company_name =
'';
367 $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>';
368 $html_company_name .=
'<input type="text" id="company_name" name="company_name" value="' .
dol_escape_htmltag(GETPOSTISSET(
'company_name') ?
GETPOST(
'company_name',
'alphanohtml') :
'') .
'" />';
369 $html_company_name .=
'</td></tr>';
370 print $html_company_name;
372 $html_contact_phone =
'';
373 $html_contact_phone .=
'<tr id="contact_phone_line" class="contact_field"><td><label for="contact_phone"><span>' . $langs->trans(
'Phone') .
'</span></label></td><td>';
374 $html_contact_phone .=
'<input type="text" id="contact_phone" name="contact_phone" value="' .
dol_escape_htmltag(GETPOSTISSET(
'contact_phone') ?
GETPOST(
'contact_phone',
'alphanohtml') :
'') .
'" />';
375 $html_contact_phone .=
'</td></tr>';
376 print $html_contact_phone;
379 $langs->load(
'errors');
380 print
'<script nonce="'.getNonce().
'" type="text/javascript">
381 jQuery(document).ready(function() {
382 var contact = jQuery.parseJSON("'.
dol_escape_js(json_encode($with_contact), 2).
'");
383 jQuery("#contact_search_line").hide();
385 if (contact.id > 0) {
386 jQuery("#contact_search_line").show();
387 jQuery("#contact_id").val(contact.id);
388 jQuery("#contact_search_result").html(contact.firstname+" "+contact.lastname);
389 jQuery(".contact_field").hide();
391 jQuery(".contact_field").show();
395 jQuery("#email").change(function() {
396 jQuery("#contact_search_line").show();
397 jQuery("#contact_search_result").html("'.
dol_escape_js($langs->trans(
'Select2SearchInProgress')).
'");
398 jQuery("#contact_id").val("");
399 jQuery("#contact_lastname").val("");
400 jQuery("#contact_firstname").val("");
401 jQuery("#company_name").val("");
402 jQuery("#contact_phone").val("");
407 action: "getContacts",
408 email: jQuery("#email").val()
411 if (response.error) {
412 jQuery("#contact_search_result").html("<span class=\"error\">"+response.error+"</span>");
414 var contact_list = response.contacts;
415 if (contact_list.length == 1) {
416 var contact = contact_list[0];
417 jQuery("#contact_id").val(contact.id);
418 jQuery("#contact_search_result").html(contact.firstname+" "+contact.lastname);
419 jQuery(".contact_field").hide();
420 } else if (contact_list.length <= 0) {
421 jQuery("#contact_search_line").hide();
422 jQuery(".contact_field").show();
426 ).fail(function(jqxhr, textStatus, error) {
427 var error_msg = "'.
dol_escape_js($langs->trans(
'ErrorAjaxRequestFailed')).
'"+" ["+textStatus+"] : "+error;
428 jQuery("#contact_search_result").html("<span class=\"error\">"+error_msg+"</span>");
438 if (isset($this->param[
'origin']) && $this->param[
'originid'] > 0) {
440 $element = $subelement = $this->param[
'origin'];
442 if (preg_match(
'/^([^_]+)_([^_]+)/i', $this->param[
'origin'], $regs)) {
444 $subelement = $regs[2];
448 $classname = ucfirst($subelement);
449 $objectsrc =
new $classname($this->db);
450 '@phan-var-force CommonObject $objectsrc';
453 if (empty($objectsrc->lines) && method_exists($objectsrc,
'fetch_lines')) {
454 $objectsrc->fetch_lines();
457 $objectsrc->fetch_thirdparty();
458 $newclassname = $classname;
459 print
'<tr><td>'.$langs->trans($newclassname).
'</td><td colspan="2"><input name="'.$subelement.
'id" value="'.
GETPOST(
'originid').
'" type="hidden" />'.$objectsrc->getNomUrl(1).
'</td></tr>';
463 print
'<tr><td class="titlefield"><span class="fieldrequired"><label for="selecttype_code">'.$langs->trans(
"TicketTypeRequest").
'</span></label></td><td>';
464 $this->
selectTypesTickets($type_code,
'type_code',
'', 2,
'ifone', 0, 0,
'minwidth200 maxwidth500');
468 print
'<tr><td><span class="fieldrequired"><label for="selectcategory_code">'.$langs->trans(
"TicketCategory").
'</span></label></td><td>';
471 $filter =
'(public:=:1)';
473 $this->
selectGroupTickets($category_code,
'category_code', $filter, 2,
'ifone', 0, 0,
'minwidth200 maxwidth500');
477 print
'<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans(
"TicketSeverity").
'</span></label></td><td>';
478 $this->
selectSeveritiesTickets($severity_code,
'severity_code',
'', 2,
'ifone', 0, 0,
'minwidth200 maxwidth500');
483 print
'<tr id="KWwithajax" class="hidden"><td></td></tr>';
484 print
'<!-- Script to manage change of ticket group -->
485 <script nonce="'.getNonce().
'">
486 jQuery(document).ready(function() {
487 function groupticketchange() {
488 console.log("We called groupticketchange, so we try to load list KM linked to event");
489 $("#KWwithajax").html("");
490 idgroupticket = $("#selectcategory_code").val();
492 console.log("We have selected id="+idgroupticket);
494 if (idgroupticket != "") {
495 $.ajax({ url: \''.DOL_URL_ROOT.
'/core/ajax/fetchKnowledgeRecord.php\',
496 data: { action: \'getKnowledgeRecord\', idticketgroup: idgroupticket, token: \''.
newToken().
'\', lang:\
''.$langs->defaultlang.
'\',
public:
'.($public).' },
498 success: function(response) {
500 console.log("We received response "+response);
501 if (typeof response == "object") {
502 console.log("response is already type object, no need to parse it");
504 console.log("response is type "+(typeof response));
505 response = JSON.parse(response);
507 for (key in response) {
508 answer = response[key].answer;
509 urllist += \'<li><a href="#" title="\'+response[key].title+\'" class="button_KMpopup" data-html="\'+answer+\'">\' +response[key].title+\'</a></li>\';
512 $("#KWwithajax").html(\'<td>'.$langs->trans(
"KMFoundForTicketGroup").
'</td><td><ul>\'+urllist+\'</ul></td>\');
513 $("#KWwithajax").show();
514 $(".button_KMpopup").on("click",function(){
515 console.log("Open popup with jQuery(...).dialog() with KM article")
516 var $dialog = $("<div></div>").html($(this).attr("data-html"))
520 height: (window.innerHeight - 150),
522 title: $(this).attr("title"),
524 $dialog.dialog("open");
525 console.log($dialog);
529 error : function(output) {
530 console.error("Error on Fetch of KM articles");
535 $("#selectcategory_code").on("change",function() { groupticketchange(); });
536 if ($("#selectcategory_code").val() != "") {
544 if ($this->withtitletopic) {
545 print
'<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans(
"Subject").
'</span></label></td><td>';
547 if ($this->withtopicreadonly) {
548 print $langs->trans(
'SubjectAnswerToTicket').
' '.$this->topic_title;
550 if (isset($this->withreadid) && $this->withreadid > 0) {
551 $subject = $langs->trans(
'SubjectAnswerToTicket').
' '.$this->withreadid.
' : '.$this->topic_title;
553 print
'<input class="text minwidth500" id="subject" name="subject" value="'.$subject.
'"'.(empty($this->withemail) ?
' autofocus' :
'').
' />';
559 print
'<tr><td><label for="message"><span class="fieldrequired">'.$langs->trans(
"Message").
'</span></label></td><td>';
562 $toolbarname =
'dolibarr_notes';
563 if ($this->ispublic) {
564 $toolbarname =
'dolibarr_details';
565 print
'<div class="warning hideonsmartphone">'.(getDolGlobalString(
"TICKET_PUBLIC_TEXT_HELP_MESSAGE", $langs->trans(
'TicketPublicPleaseBeAccuratelyDescribe'))).
'</div>';
567 include_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
568 $uselocalbrowser =
true;
569 $doleditor =
new DolEditor(
'message', $msg,
'100%', 230, $toolbarname,
'In',
true, $uselocalbrowser,
getDolGlobalInt(
'FCKEDITOR_ENABLE_TICKET'), ROWS_8,
'90%');
570 $doleditor->Create();
576 print
'<tr><td class="wordbreak"></td><td>';
577 print $form->selectCategories(Categorie::TYPE_TICKET,
'categories',
$object);
582 if (!empty($this->withfile)) {
584 $listofpaths = array();
585 $listofnames = array();
586 $listofmimes = array();
587 if (!empty($_SESSION[
"listofpaths"])) {
588 $listofpaths = explode(
';', $_SESSION[
"listofpaths"]);
591 if (!empty($_SESSION[
"listofnames"])) {
592 $listofnames = explode(
';', $_SESSION[
"listofnames"]);
595 if (!empty($_SESSION[
"listofmimes"])) {
596 $listofmimes = explode(
';', $_SESSION[
"listofmimes"]);
603 $out .=
'<input type="hidden" class="removedfilehidden" name="removedfile" value="">'.
"\n";
604 $out .=
'<script nonce="'.getNonce().
'" type="text/javascript">';
605 $out .=
'jQuery(document).ready(function () {';
606 $out .=
' jQuery(".removedfile").click(function() {';
607 $out .=
' jQuery(".removedfilehidden").val(jQuery(this).val());';
610 $out .=
'</script>'.
"\n";
611 if (count($listofpaths)) {
612 foreach ($listofpaths as $key => $val) {
613 $out .=
'<div id="attachfile_'.$key.
'">';
614 $out .=
img_mime($listofnames[$key]).
' '.$listofnames[$key];
615 if (!$this->withfilereadonly) {
616 $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.
'" />';
618 $out .=
'<br></div>';
621 if ($this->withfile == 2) {
623 $maxmin = $maxfilesizearray[
'maxmin'];
625 $out .=
'<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).
'">';
627 $out .=
'<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans(
"Upload").
'" />';
629 $out .=
'<input type="submit" class="button smallpaddingimp reposition" id="addfile" name="addfile" value="'.$langs->trans(
"MailingAddFile").
'" />';
631 $out .=
"</td></tr>\n";
637 if ($this->withusercreate > 0 && $this->fk_user_create) {
638 print
'<tr><td class="titlefield">'.$langs->trans(
"CreatedBy").
'</td><td>';
639 $langs->load(
"users");
640 $fuser =
new User($this->db);
642 if ($this->withcreatereadonly) {
643 if ($res = $fuser->fetch($this->fk_user_create)) {
644 print $fuser->getNomUrl(1);
648 print
"</td></tr>\n";
652 if ($this->withcompany) {
654 if (empty($user->socid)) {
656 print
'<tr><td class="titlefield">'.$langs->trans(
"ThirdParty").
'</td><td>';
658 $events[] = array(
'method' =>
'getContacts',
'url' =>
dol_buildpath(
'/core/ajax/contacts.php', 1),
'htmlname' =>
'contactid',
'params' => array(
'add-customer-contact' =>
'disabled'));
659 print
img_picto(
'',
'company',
'class="paddingright"');
660 print $form->select_company($this->withfromsocid,
'socid',
'', 1, 1, 0, $events, 0,
'minwidth200');
662 if (!empty($conf->use_javascript_ajax) &&
getDolGlobalString(
'COMPANY_USE_SEARCH_TO_SELECT')) {
664 print
'<script nonce="'.getNonce().
'" type="text/javascript">
665 $(document).ready(function () {
666 jQuery("#'.$htmlname.
'").change(function () {
667 var obj = '.json_encode($events).
';
668 $.each(obj, function(key,values) {
669 if (values.method.length) {
670 runJsCodeForEvent'.$htmlname.
'(values);
675 function runJsCodeForEvent'.$htmlname.
'(obj) {
676 console.log("Run runJsCodeForEvent'.$htmlname.
'");
677 var id = $("#'.$htmlname.
'").val();
678 var method = obj.method;
680 var htmlname = obj.htmlname;
681 var showempty = obj.showempty;
690 $.each(obj.params, function(key,action) {
692 var num = response.num;
694 $("#" + key).removeAttr(action);
696 $("#" + key).attr(action, action);
700 $("select#" + htmlname).html(response.value);
702 var selecthtml_str = response.value;
703 var selecthtml_dom=$.parseHTML(selecthtml_str);
704 if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
705 $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
708 $("#inputautocomplete"+htmlname).val("");
710 $("select#" + htmlname).change(); /* Trigger event change */
717 if ($mode ==
'create') {
719 print
'<tr><td>'.$langs->trans(
"Contact").
'</td><td>';
721 $selectedCompany = ($this->withfromsocid > 0) ? $this->withfromsocid : -1;
722 print
img_picto(
'',
'contact',
'class="paddingright"');
724 print $form->select_contact($selectedCompany, $this->withfromcontactid,
'contactid', 3,
'',
'', 1,
'maxwidth300 widthcentpercentminusx',
true);
727 $formcompany->selectTypeContact($ticketstatic,
'',
'type',
'external',
'', 0,
'maginleftonly');
731 print
'<tr><td class="titlefield"><input type="hidden" name="socid" value="'.$user->socid.
'"/></td>';
732 print
'<td><input type="hidden" name="contactid" value="'.$user->contact_id.
'"/></td>';
733 print
'<td><input type="hidden" name="type" value="Z"/></td></tr>';
737 if (empty($this->ispublic) && ($action ==
'create' || $action ==
'presend')) {
738 print
'<tr><td><label for="notify_tiers_at_create">'.$langs->trans(
"TicketNotifyTiersAtCreation").
'</label></td><td>';
739 print
'<input type="checkbox" id="notify_tiers_at_create" name="notify_tiers_at_create"'.($this->withnotifytiersatcreate ?
' checked="checked"' :
'').
'>';
745 print $langs->trans(
"AssignedTo");
747 print
img_picto(
'',
'user',
'class="pictofixedwidth"');
748 print $form->select_dolusers($user_assign,
'fk_user_assign', 1);
753 if ($subelement !=
'project') {
756 print
'<tr><td><label for="project"><span class="">'.$langs->trans(
"Project").
'</span></label></td><td>';
757 print
img_picto(
'',
'project',
'class="pictofixedwidth"').$formproject->select_projects(-1, $projectid,
'projectid', 0, 0, 1, 1, 0, 0, 0,
'', 1, 0,
'maxwidth500');
762 if ($subelement !=
'contract' && $subelement !=
'contrat') {
764 $langs->load(
'contracts');
766 print
'<tr><td><label for="contract"><span class="">'.$langs->trans(
"Contract").
'</span></label></td><td>';
767 print
img_picto(
'',
'contract',
'class="pictofixedwidth"');
769 print $formcontract->select_contract($user->socid ?? -1,
GETPOSTINT(
'contractid'),
'contractid', 0, 1, 1, 1);
775 $parameters = array();
776 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $ticketstat, $action);
777 if (empty($reshook)) {
778 if ($mode ==
'create') {
779 print
$object->showOptionals($extrafields,
'create');
781 print
$object->showOptionals($extrafields,
'edit');
788 print
'<tr><td class="titlefield"></td><td><br>';
790 require_once DOL_DOCUMENT_ROOT.
'/core/lib/security2.lib.php';
794 $dirModCaptcha = array_merge(array(
'main' =>
'/core/modules/security/captcha/'), is_array($conf->modules_parts[
'captcha']) ? $conf->modules_parts[
'captcha'] : array());
796 $fullpathclassfile =
'';
797 foreach ($dirModCaptcha as $dir) {
798 $fullpathclassfile =
dol_buildpath($dir.
"modCaptcha".ucfirst($captcha).
'.class.php', 0, 2);
799 if ($fullpathclassfile) {
804 if ($fullpathclassfile) {
805 include_once $fullpathclassfile;
809 $classname =
"modCaptcha".ucfirst($captcha);
810 if (class_exists($classname)) {
812 $captchaobj =
new $classname($this->db, $conf, $langs, $user);
813 '@phan-var-force ModeleCaptcha $captchaobj';
815 if (is_object($captchaobj) && method_exists($captchaobj,
'getCaptchaCodeForForm')) {
816 print $captchaobj->getCaptchaCodeForForm(
'');
818 print
'Error, the captcha handler '.get_class($captchaobj).
' does not have any method getCaptchaCodeForForm()';
821 print
'Error, the captcha handler class '.$classname.
' was not found after the include';
824 print
'Error, the captcha handler '.$captcha.
' has no class file found modCaptcha'.ucfirst($captcha);
827 print
'<br></td></tr>';
832 if ($withdolfichehead) {
838 if ($mode ==
'create') {
839 print $form->buttonsSaveCancel(((isset($this->withreadid) && $this->withreadid > 0) ?
"SendResponse" :
"CreateTicket"), ($this->withcancel ?
"Cancel" :
""));
841 print $form->buttonsSaveCancel(((isset($this->withreadid) && $this->withreadid > 0) ?
"SendResponse" :
"Save"), ($this->withcancel ?
"Cancel" :
""));
856 print
'<input type="hidden" name="page_y">'.
"\n";
859 print
"<!-- End form TICKET -->\n";
876 public function selectTypesTickets($selected =
'', $htmlname =
'tickettype', $filtertype =
'', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss =
'', $multiselect = 0)
878 global $langs, $user;
880 $selected = is_array($selected) ? $selected : (!empty($selected) ? explode(
',', $selected) : array());
881 $ticketstat =
new Ticket($this->db);
883 dol_syslog(get_class($this) .
"::select_types_tickets " . implode(
';', $selected) .
", " . $htmlname .
", " . $filtertype .
", " . $format .
", " . $multiselect, LOG_DEBUG);
885 $filterarray = array();
887 if ($filtertype !=
'' && $filtertype !=
'-1') {
888 $filterarray = explode(
',', $filtertype);
891 $ticketstat->loadCacheTypesTickets();
893 print
'<select id="select'.$htmlname.
'" class="flat minwidth100'.($morecss ?
' '.$morecss :
'').
'" name="'.$htmlname.($multiselect ?
'[]' :
'').
'"'.($multiselect ?
' multiple' :
'').
'>';
894 if ($empty && !$multiselect) {
895 print
'<option value="">'.((is_numeric($empty) || $empty ==
'ifone') ?
' ' : $empty).
'</option>';
898 if (is_array($ticketstat->cache_types_tickets) && count($ticketstat->cache_types_tickets)) {
899 foreach ($ticketstat->cache_types_tickets as
$id => $arraytypes) {
901 if (count($filterarray) && !in_array($arraytypes[
'code'], $filterarray)) {
906 if ($empty && empty($arraytypes[
'code'])) {
911 print
'<option value="'.$id.
'"';
915 print
'<option value="'.$arraytypes[
'code'].
'"';
919 print
'<option value="'.$arraytypes[
'code'].
'"';
923 print
'<option value="'.$id.
'"';
927 if (in_array($arraytypes[
'code'], $selected)) {
928 print
' selected="selected"';
929 } elseif (in_array(
$id, $selected)) {
930 print
' selected="selected"';
931 } elseif ($arraytypes[
'use_default'] ==
"1" && empty($selected) && !$multiselect) {
932 print
' selected="selected"';
933 } elseif (count($ticketstat->cache_types_tickets) == 1 && (!$empty || $empty ==
'ifone')) {
934 print
' selected="selected"';
941 $value = ($maxlength ?
dol_trunc($arraytypes[
'label'], $maxlength) : $arraytypes[
'label']);
942 } elseif ($format == 1) {
943 $value = $arraytypes[
'code'];
944 } elseif ($format == 2) {
945 $value = ($maxlength ?
dol_trunc($arraytypes[
'label'], $maxlength) : $arraytypes[
'label']);
946 } elseif ($format == 3) {
947 $value = $arraytypes[
'code'];
950 print $value ? $value :
' ';
955 if (isset($user->admin) && $user->admin && !$noadmininfo) {
956 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
977 public function selectGroupTickets($selected =
'', $htmlname =
'ticketcategory', $filtertype =
'', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss =
'', $use_multilevel = 0, $outputlangs =
null)
979 global $conf, $langs, $user;
981 dol_syslog(get_class($this).
"::selectCategoryTickets ".$selected.
", ".$htmlname.
", ".$filtertype.
", ".$format, LOG_DEBUG);
983 if (is_null($outputlangs) || !is_object($outputlangs)) {
984 $outputlangs = $langs;
986 $outputlangs->load(
"ticket");
988 $publicgroups = ($filtertype ==
'public=1' || $filtertype ==
'(public:=:1)');
990 $ticketstat =
new Ticket($this->db);
991 $ticketstat->loadCacheCategoriesTickets($publicgroups ? 1 : -1);
993 if ($use_multilevel <= 0) {
994 print
'<select id="select'.$htmlname.
'" class="flat minwidth100'.($morecss ?
' '.$morecss :
'').
'" name="'.$htmlname.
'">';
996 print
'<option value="">'.((is_numeric($empty) || $empty ==
'ifone') ?
' ' : $empty).
'</option>';
999 if (is_array($conf->cache[
'category_tickets']) && count($conf->cache[
'category_tickets'])) {
1000 foreach ($conf->cache[
'category_tickets'] as
$id => $arraycategories) {
1002 if ($publicgroups) {
1003 if (empty($arraycategories[
'public'])) {
1009 if ($empty && empty($arraycategories[
'code'])) {
1013 $label = ($arraycategories[
'label'] !=
'-' ? $arraycategories[
'label'] :
'');
1014 if ($outputlangs->trans(
"TicketCategoryShort".$arraycategories[
'code']) !=
"TicketCategoryShort".$arraycategories[
'code']) {
1015 $label = $outputlangs->trans(
"TicketCategoryShort".$arraycategories[
'code']);
1016 } elseif ($outputlangs->trans($arraycategories[
'code']) != $arraycategories[
'code']) {
1017 $label = $outputlangs->trans($arraycategories[
'code']);
1021 print
'<option value="'.$id.
'"';
1025 print
'<option value="'.$arraycategories[
'code'].
'"';
1029 print
'<option value="'.$arraycategories[
'code'].
'"';
1033 print
'<option value="'.$id.
'"';
1037 if (isset($selected) && preg_match(
'/[a-z]/i', $selected) && $selected == $arraycategories[
'code']) {
1038 print
' selected="selected"';
1039 } elseif (isset($selected) && $selected ==
$id) {
1040 print
' selected="selected"';
1041 } elseif ($arraycategories[
'use_default'] ==
"1" && empty($selected) && (!$empty || $empty ==
'ifone')) {
1042 print
' selected="selected"';
1043 } elseif (count($conf->cache[
'category_tickets']) == 1 && (!$empty || $empty ==
'ifone')) {
1044 print
' selected="selected"';
1051 $value = ($maxlength ?
dol_trunc($label, $maxlength) : $label);
1055 $value = $arraycategories[
'code'];
1059 $value = ($maxlength ?
dol_trunc($label, $maxlength) : $label);
1063 $value = $arraycategories[
'code'];
1066 print $value ? $value :
' ';
1071 if (isset($user->admin) && $user->admin && !$noadmininfo) {
1072 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1076 } elseif ($htmlname !=
'') {
1077 $selectedgroups = array();
1079 $groupticket =
GETPOST($htmlname,
'aZ09');
1080 $child_id =
GETPOST($htmlname.
'_child_id',
'aZ09') ?
GETPOST($htmlname.
'_child_id',
'aZ09') : 0;
1081 if (!empty($groupticket)) {
1082 $tmpgroupticket = $groupticket;
1083 $sql =
"SELECT ctc.rowid, ctc.fk_parent, ctc.code";
1084 $sql .=
" FROM ".$this->db->prefix().
"c_ticket_category as ctc WHERE ctc.code = '".$this->db->escape($tmpgroupticket).
"'";
1085 $resql = $this->db->query($sql);
1087 $obj = $this->db->fetch_object($resql);
1088 $selectedgroups[] = $obj->code;
1089 while ($obj->fk_parent > 0) {
1090 $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).
"'";
1091 $resql = $this->db->query($sql);
1093 $obj = $this->db->fetch_object($resql);
1094 $selectedgroups[] = $obj->code;
1100 $arrayidused = array();
1101 $arrayidusedconcat = array();
1102 $arraycodenotparent = array();
1103 $arraycodenotparent[] =
"";
1105 $stringtoprint =
'<span class="supportemailfield bold">'.$langs->trans(
"GroupOfTicket").
'</span> ';
1106 $stringtoprint .=
'<select id="'.$htmlname.
'" class="minwidth500" child_id="0">';
1107 $stringtoprint .=
'<option value=""> </option>';
1109 $sql =
"SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ";
1110 $sql .= $this->db->ifsql(
"ctc.rowid NOT IN (SELECT ctcfather.rowid FROM ".MAIN_DB_PREFIX.
"c_ticket_category as ctcfather JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as ctcjoin ON ctcfather.rowid = ctcjoin.fk_parent WHERE ctcjoin.active > 0)",
"'NOTPARENT'",
"'PARENT'").
" as isparent";
1111 $sql .=
" FROM ".$this->db->prefix().
"c_ticket_category as ctc";
1112 $sql .=
" WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
1113 $public = ($filtertype ==
'public=1' || $filtertype ==
'(public:=:1)');
1115 $sql .=
" AND ctc.public = 1";
1117 $sql .=
" AND ctc.fk_parent = 0";
1118 $sql .= $this->db->order(
'ctc.pos',
'ASC');
1120 $resql = $this->db->query($sql);
1122 $num_rows_level0 = $this->db->num_rows($resql);
1124 while ($i < $num_rows_level0) {
1125 $obj = $this->db->fetch_object($resql);
1127 $label = ($obj->label !=
'-' ? $obj->label :
'');
1128 if ($outputlangs->trans(
"TicketCategoryShort".$obj->code) !=
"TicketCategoryShort".$obj->code) {
1129 $label = $outputlangs->trans(
"TicketCategoryShort".$obj->code);
1130 } elseif ($outputlangs->trans($obj->code) != $obj->code) {
1131 $label = $outputlangs->trans($obj->code);
1134 $grouprowid = $obj->rowid;
1135 $groupvalue = $obj->code;
1136 $grouplabel = $label;
1138 $isparent = $obj->isparent;
1139 if (is_array($selectedgroups)) {
1140 $iselected = in_array($obj->code, $selectedgroups) ?
'selected' :
'';
1142 $iselected = $groupticket == $obj->code ?
'selected' :
'';
1145 if ($isparent ==
'NOTPARENT') {
1146 $arraycodenotparent[] = $groupvalue;
1148 $arrayidused[] = $grouprowid;
1149 $arrayidusedconcat[] = $grouprowid;
1156 if (count($arrayidused) == 1) {
1157 return '<input type="hidden" name="'.$htmlname.
'" id="'.$htmlname.
'" value="'.
dol_escape_htmltag($groupvalue).
'">';
1159 $stringtoprint .=
'<input type="hidden" name="'.$htmlname.
'" id="'.$htmlname.
'_select" class="maxwidth500 minwidth400" value="'.
GETPOST($htmlname).
'">';
1160 $stringtoprint .=
'<input type="hidden" name="'.$htmlname.
'_child_id" id="'.$htmlname.
'_select_child_id" class="maxwidth500 minwidth400" '.
GETPOST($htmlname).
' value="'.
GETPOST($htmlname.
"_child_id").
'">';
1162 $stringtoprint .=
'</select> ';
1165 while ($levelid <= $use_multilevel) {
1166 $tabscript = array();
1167 $stringtoprint .=
'<select id="'.$htmlname.
'_child_'.$levelid.
'" class="maxwidth500 minwidth400 groupticketchild" child_id="'.$levelid.
'">';
1168 $stringtoprint .=
'<option value=""> </option>';
1170 $sql =
"SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, ctcjoin.code as codefather";
1171 $sql .=
" FROM ".$this->db->prefix().
"c_ticket_category as ctc";
1172 $sql .=
" JOIN ".$this->db->prefix().
"c_ticket_category as ctcjoin ON ctc.fk_parent = ctcjoin.rowid";
1173 $sql .=
" WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity);
1174 $sql .=
" AND ctc.rowid NOT IN (".$this->db->sanitize(implode(
',', $arrayidusedconcat)).
")";
1176 $public = ($filtertype ==
'public=1' || $filtertype ==
'(public:=:1)');
1178 $sql .=
" AND ctc.public = 1";
1181 if (!empty($arrayidused)) {
1182 $sql .=
" AND ctc.fk_parent IN ( ";
1183 foreach ($arrayidused as $idused) {
1184 $sql .= $idused.
", ";
1186 $sql = substr($sql, 0, -2);
1189 $sql .= $this->db->order(
'ctc.pos',
'ASC');
1191 $resql = $this->db->query($sql);
1193 $num_rows = $this->db->num_rows($resql);
1195 $arrayidused = array();
1196 while ($i < $num_rows) {
1197 $obj = $this->db->fetch_object($resql);
1199 $label = ($obj->label !=
'-' ? $obj->label :
'');
1200 if ($outputlangs->trans(
"TicketCategoryShort".$obj->code) !=
"TicketCategoryShort".$obj->code) {
1201 $label = $outputlangs->trans(
"TicketCategoryShort".$obj->code);
1202 } elseif ($outputlangs->trans($obj->code) != $obj->code) {
1203 $label = $outputlangs->trans($obj->code);
1206 $grouprowid = $obj->rowid;
1207 $groupvalue = $obj->code;
1208 $grouplabel = $label;
1209 $isparent = $obj->isparent;
1210 $fatherid = $obj->fk_parent;
1211 $arrayidused[] = $grouprowid;
1212 $arrayidusedconcat[] = $grouprowid;
1213 $groupcodefather = $obj->codefather;
1214 if ($isparent ==
'NOTPARENT') {
1215 $arraycodenotparent[] = $groupvalue;
1217 if (is_array($selectedgroups)) {
1218 $iselected = in_array($obj->code, $selectedgroups) ?
'selected' :
'';
1220 $iselected = $groupticket == $obj->code ?
'selected' :
'';
1223 if (empty($tabscript[$groupcodefather])) {
1224 $tabscript[$groupcodefather] =
'if ($("#'.$htmlname.($levelid > 1 ?
'_child_'.($levelid - 1) :
'').
'").val() == "'.
dol_escape_js($groupcodefather).
'"){
1226 console.log("We show child tickets of '.$groupcodefather.
' group ticket")
1229 console.log("We hide child tickets of '.$groupcodefather.
' group ticket")
1238 $stringtoprint .=
'</select>';
1240 $stringtoprint .=
'<script nonce="'.getNonce().
'">';
1241 $stringtoprint .=
'arraynotparents = '.json_encode($arraycodenotparent).
';';
1242 $stringtoprint .=
'if (arraynotparents.includes($("#'.$htmlname.($levelid > 1 ?
'_child_'.($levelid - 1) :
'').
'").val())){
1243 console.log("'.$htmlname.
'_child_'.$levelid.
'")
1244 if($("#'.$htmlname.
'_child_'.$levelid.
'").val() == "" && ($("#'.$htmlname.
'_child_'.$levelid.
'").attr("child_id")>'.$child_id.
')){
1245 $("#'.$htmlname.
'_child_'.$levelid.
'").hide();
1246 console.log("We hide '.$htmlname.
'_child_'.$levelid.
' input")
1248 if(arraynotparents.includes("'.$groupticket.
'") && '.$child_id.
' == 0){
1249 $("#ticketcategory_select_child_id").val($("#'.$htmlname.
'").attr("child_id"))
1250 $("#ticketcategory_select").val($("#'.$htmlname.
'").val()) ;
1251 console.log("We choose '.$htmlname.
' input and reload hidden input");
1254 $("#'.$htmlname.($levelid > 1 ?
'_child_'.($levelid - 1) :
'').
'").change(function() {
1255 child_id = $("#'.$htmlname.($levelid > 1 ?
'_child_'.$levelid :
'').
'").attr("child_id");
1257 /* Change of value to select this value*/
1258 if (arraynotparents.includes($(this).val()) || $(this).attr("child_id") == '.$use_multilevel.
') {
1259 $("#ticketcategory_select").val($(this).val());
1260 $("#ticketcategory_select_child_id").val($(this).attr("child_id")) ;
1261 console.log("We choose to select "+ $(this).val());
1263 if ($("#'.$htmlname.
'_child_'.$levelid.
' option").length <= 1) {
1264 $("#ticketcategory_select").val($(this).val());
1265 $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1266 console.log("We choose to select "+ $(this).val() + " and next combo has no item, so we keep this selection");
1268 console.log("We choose to select "+ $(this).val() + " but next combo has some item, so we clean selected item");
1269 $("#ticketcategory_select").val("");
1270 $("#ticketcategory_select_child_id").val("");
1274 console.log("We select a new value into combo child_id="+child_id);
1276 // Hide all selected box that are child of the one modified
1277 $(".groupticketchild").each(function(){
1278 if ($(this).attr("child_id") > child_id) {
1279 console.log("hide child_id="+$(this).attr("child_id"));
1285 // Now we enable the next combo
1286 $("#'.$htmlname.
'_child_'.$levelid.
'").val("");
1287 if (!arraynotparents.includes($(this).val()) && $("#'.$htmlname.
'_child_'.$levelid.
' option").length > 1) {
1288 console.log($("#'.$htmlname.
'_child_'.$levelid.
' option").length);
1289 $("#'.$htmlname.
'_child_'.$levelid.
'").show()
1291 $("#'.$htmlname.
'_child_'.$levelid.
'").hide()
1295 foreach ($tabscript as $script) {
1296 $stringtoprint .= $script;
1298 $stringtoprint .=
'})';
1299 $stringtoprint .=
'</script>';
1301 $stringtoprint .=
'<script nonce="'.getNonce().
'">';
1302 $stringtoprint .=
'$("#'.$htmlname.
'_child_'.$use_multilevel.
'").change(function() {
1303 $("#ticketcategory_select").val($(this).val());
1304 $("#ticketcategory_select_child_id").val($(this).attr("child_id"));
1305 tmpvalselect = $("#ticketcategory_select").val();
1306 if(tmpvalselect == "" && $("#ticketcategory_select_child_id").val() >= 1){
1307 $("#ticketcategory_select_child_id").val($(this).attr("child_id")-1);
1309 console.log($("#ticketcategory_select").val());
1311 $stringtoprint .=
'</script>';
1314 return $stringtoprint;
1331 public function selectSeveritiesTickets($selected =
'', $htmlname =
'ticketseverity', $filtertype =
'', $format = 0, $empty = 0, $noadmininfo = 0, $maxlength = 0, $morecss =
'')
1333 global $conf, $langs, $user;
1335 $ticketstat =
new Ticket($this->db);
1337 dol_syslog(get_class($this).
"::selectSeveritiesTickets ".$selected.
", ".$htmlname.
", ".$filtertype.
", ".$format, LOG_DEBUG);
1339 $filterarray = array();
1341 if ($filtertype !=
'' && $filtertype !=
'-1') {
1342 $filterarray = explode(
',', $filtertype);
1345 $ticketstat->loadCacheSeveritiesTickets();
1347 print
'<select id="select'.$htmlname.
'" class="flat minwidth100'.($morecss ?
' '.$morecss :
'').
'" name="'.$htmlname.
'">';
1349 print
'<option value="">'.((is_numeric($empty) || $empty ==
'ifone') ?
' ' : $empty).
'</option>';
1352 if (is_array($conf->cache[
'severity_tickets']) && count($conf->cache[
'severity_tickets'])) {
1353 foreach ($conf->cache[
'severity_tickets'] as
$id => $arrayseverities) {
1355 if (count($filterarray) && !in_array($arrayseverities[
'type'], $filterarray)) {
1360 if ($empty && empty($arrayseverities[
'code'])) {
1365 print
'<option value="'.$id.
'"';
1369 print
'<option value="'.$arrayseverities[
'code'].
'"';
1373 print
'<option value="'.$arrayseverities[
'code'].
'"';
1377 print
'<option value="'.$id.
'"';
1381 if (isset($selected) && preg_match(
'/[a-z]/i', $selected) && $selected == $arrayseverities[
'code']) {
1382 print
' selected="selected"';
1383 } elseif (isset($selected) && $selected ==
$id) {
1384 print
' selected="selected"';
1385 } elseif ($arrayseverities[
'use_default'] ==
"1" && empty($selected) && (!$empty || $empty ==
'ifone')) {
1386 print
' selected="selected"';
1387 } elseif (count($conf->cache[
'severity_tickets']) == 1 && (!$empty || $empty ==
'ifone')) {
1388 print
' selected="selected"';
1395 $value = ($maxlength ?
dol_trunc($arrayseverities[
'label'], $maxlength) : $arrayseverities[
'label']);
1399 $value = $arrayseverities[
'code'];
1403 $value = ($maxlength ?
dol_trunc($arrayseverities[
'label'], $maxlength) : $arrayseverities[
'label']);
1407 $value = $arrayseverities[
'code'];
1410 print $value ? $value :
' ';
1415 if (isset($user->admin) && $user->admin && !$noadmininfo) {
1416 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1431 global $conf, $user;
1432 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1435 $vardir = $conf->user->dir_output.
"/".$user->id;
1436 $upload_dir = $vardir.
'/temp/';
1437 if (is_dir($upload_dir)) {
1441 if (!empty($this->trackid)) {
1442 $keytoavoidconflict =
'-'.$this->trackid;
1444 $keytoavoidconflict = empty($this->track_id) ?
'' :
'-'.$this->track_id;
1446 unset($_SESSION[
"listofpaths".$keytoavoidconflict]);
1447 unset($_SESSION[
"listofnames".$keytoavoidconflict]);
1448 unset($_SESSION[
"listofmimes".$keytoavoidconflict]);
1459 global $conf, $langs, $user, $hookmanager, $form;
1461 $formmail =
new FormMail($this->db);
1462 $addfileaction =
'addfile';
1464 if (!is_object($form)) {
1465 $form =
new Form($this->db);
1469 $langs->loadLangs(array(
'other',
'mails',
'ticket'));
1472 if (
GETPOST(
'mode',
'alpha') ==
'init' || (
GETPOST(
'modelselected') &&
GETPOST(
'modelmailselected',
'alpha') &&
GETPOST(
'modelmailselected',
'alpha') !=
'-1')) {
1473 $this->clear_attached_files();
1477 $outputlangs = $langs;
1479 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && empty($newlang) && isset($this->param[
'langsmodels'])) {
1480 $newlang = $this->param[
'langsmodels'];
1482 if (!empty($newlang)) {
1483 $outputlangs =
new Translate(
"", $conf);
1484 $outputlangs->setDefaultLang($newlang);
1485 $outputlangs->load(
'other');
1489 $arraydefaultmessage = -1;
1490 if (isset($this->param[
'models']) && $this->param[
'models'] !=
'none') {
1492 if (array_key_exists(
'models_id', $this->param)) {
1493 $model_id = (int) $this->param[
"models_id"];
1497 $usedefault = ($model_id ? -1 : 1);
1498 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param[
"models"], $user, $outputlangs, $model_id, 1,
'', $usedefault);
1499 if (isset($arraydefaultmessage->id) && empty($model_id)) {
1500 $model_id = $arraydefaultmessage->id;
1501 $this->param[
'models_id'] = $model_id;
1506 $listofpaths = array();
1507 $listofnames = array();
1508 $listofmimes = array();
1510 if (!empty($this->trackid)) {
1511 $keytoavoidconflict =
'-'.$this->trackid;
1513 $keytoavoidconflict = empty($this->track_id) ?
'' :
'-'.$this->track_id;
1516 if (
GETPOST(
'mode',
'alpha') ==
'init' || (
GETPOST(
'modelselected') &&
GETPOST(
'modelmailselected',
'alpha') &&
GETPOST(
'modelmailselected',
'alpha') !=
'-1')) {
1517 if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param[
'fileinit']) && is_array($this->param[
'fileinit'])) {
1518 foreach ($this->param[
'fileinit'] as $path) {
1519 $formmail->add_attached_files($path, basename($path),
dol_mimetype($path));
1525 if (!empty($_SESSION[
"listofpaths".$keytoavoidconflict])) {
1526 $listofpaths = explode(
';', $_SESSION[
"listofpaths".$keytoavoidconflict]);
1528 if (!empty($_SESSION[
"listofnames".$keytoavoidconflict])) {
1529 $listofnames = explode(
';', $_SESSION[
"listofnames".$keytoavoidconflict]);
1531 if (!empty($_SESSION[
"listofmimes".$keytoavoidconflict])) {
1532 $listofmimes = explode(
';', $_SESSION[
"listofmimes".$keytoavoidconflict]);
1536 $outputlangs = $langs;
1538 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && empty($newlang) && isset($this->param[
'langsmodels'])) {
1539 $newlang = $this->param[
'langsmodels'];
1541 if (!empty($newlang)) {
1542 $outputlangs =
new Translate(
"", $conf);
1543 $outputlangs->setDefaultLang($newlang);
1544 $outputlangs->load(
'other');
1547 print
"\n<!-- Begin message_form TICKET -->\n";
1552 print
'<script nonce="'.getNonce().
'" type="text/javascript">
1553 jQuery(document).ready(function() {
1554 send_email='.((int) $send_email).
';
1556 if (!jQuery("#send_msg_email").is(":checked")) {
1557 jQuery("#send_msg_email").prop("checked", true).trigger("change");
1559 jQuery(".email_line").show();
1561 if (!jQuery("#private_message").is(":checked")) {
1562 jQuery("#private_message").prop("checked", true).trigger("change");
1564 jQuery(".email_line").hide();
1570 print
'jQuery("#send_msg_email").click(function() {
1571 console.log("Click send_msg_email");
1572 if(jQuery(this).is(":checked")) {
1573 if (jQuery("#private_message").is(":checked")) {
1574 jQuery("#private_message").prop("checked", false).trigger("change");
1576 jQuery(".email_line").show();
1579 jQuery(".email_line").hide();
1583 jQuery("#private_message").click(function() {
1584 console.log("Click private_message");
1585 if (jQuery(this).is(":checked")) {
1586 if (jQuery("#send_msg_email").is(":checked")) {
1587 jQuery("#send_msg_email").prop("checked", false).trigger("change");
1589 jQuery(".email_line").hide();
1598 print
'<form method="post" name="ticket" id="ticket" enctype="multipart/form-data" action="'.$this->param[
"returnurl"].
'">';
1599 print
'<input type="hidden" name="token" value="'.newToken().
'">';
1600 print
'<input type="hidden" name="action" value="'.$this->action.
'">';
1601 print
'<input type="hidden" name="actionbis" value="add_message">';
1602 print
'<input type="hidden" name="backtopage" value="'.$this->backtopage.
'">';
1603 if (!empty($this->trackid)) {
1604 print
'<input type="hidden" name="trackid" value="'.$this->trackid.
'">';
1606 print
'<input type="hidden" name="trackid" value="'.(empty($this->track_id) ?
'' : $this->track_id).
'">';
1607 $keytoavoidconflict = empty($this->track_id) ?
'' :
'-'.$this->track_id;
1609 foreach ($this->param as $key => $value) {
1610 print
'<input type="hidden" name="'.$key.
'" value="'.$value.
'">';
1615 if (array_key_exists(
'models_id', $this->param)) {
1616 $model_id = $this->param[
"models_id"];
1617 $usedefault = ($model_id ? -1 : 1);
1618 $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $this->param[
"models"], $user, $outputlangs, $model_id, 1,
'', $usedefault);
1621 $result = $formmail->fetchAllEMailTemplate(!empty($this->param[
"models"]) ? $this->param[
"models"] :
"", $user, $outputlangs);
1625 $modelmail_array = array();
1626 foreach ($formmail->lines_model as $line) {
1627 $modelmail_array[$line->id] = $line->label;
1630 $ticketstat =
new Ticket($this->db);
1631 $res = $ticketstat->fetch(0,
'', $this->track_id);
1633 print
'<table class="border" width="'.$width.
'">';
1636 if ($user->hasRight(
"ticket",
"write") && !$user->socid) {
1637 print
'<tr><td class="width200"></td><td>';
1638 $checkbox_selected = (
GETPOST(
'send_email') ==
"1" ?
' checked' : (
getDolGlobalInt(
'TICKETS_MESSAGE_FORCE_MAIL') ?
'checked' :
''));
1639 print
'<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.
'/> ';
1640 print
'<label for="send_msg_email">'.$langs->trans(
'SendMessageByEmail').
'</label>';
1641 $texttooltip = $langs->trans(
"TicketMessageSendEmailHelp");
1643 $texttooltip .=
' '.$langs->trans(
"TicketMessageSendEmailHelp2b");
1645 $texttooltip .=
' '.$langs->trans(
"TicketMessageSendEmailHelp2a",
'{s1}');
1647 $texttooltip = str_replace(
'{s1}', $langs->trans(
'MarkMessageAsPrivate'), $texttooltip);
1648 print
' '.$form->textwithpicto(
'', $texttooltip, 1,
'help');
1651 if (count($modelmail_array) > 0) {
1652 print
' <span class="email_line">';
1653 print $formmail->selectarray(
'modelmailselected', $modelmail_array, $this->param[
'models_id'], $langs->trans(
'SelectMailModel'), 0, 0,
"", 0, 0, 0,
'',
'minwidth200');
1655 print
info_admin($langs->trans(
"YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv(
"Tools").
' - '.$langs->transnoentitiesnoconv(
"EMailTemplates")), 1);
1658 print
'<input type="submit" class="button smallpaddingimp" value="'.$langs->trans(
'Apply').
'" name="modelselected" id="modelselected">';
1665 if (!$user->socid) {
1666 print
'<tr><td></td><td>';
1667 $checkbox_selected = (
GETPOST(
'private_message',
'alpha') ==
"1" ?
' checked' :
'');
1668 print
'<input type="checkbox" name="private_message" value="1" id="private_message" '.$checkbox_selected.
'/> ';
1669 print
'<label for="private_message">'.$langs->trans(
'MarkMessageAsPrivate').
'</label>';
1670 print
' '.$form->textwithpicto(
'', $langs->trans(
"TicketMessagePrivateHelp"), 1,
'help');
1691 print
'<tr class="email_line"><td class="width200"><span class="">'.$langs->trans(
"MailFrom");
1693 print
' <span class="opacitymedium">('.$langs->trans(
"MailReply").
')</span>';
1695 print
'</span></td>';
1696 print
'<td><span class="">'.img_picto(
'',
'email',
'class="pictofixedwidth"').$from;
1698 print
' <span class="opacitymedium">('.$replyto.
')</span>';
1700 print
'</span></td></tr>';
1703 print
'<tr class="email_line"><td>'.$langs->trans(
'MailRecipients');
1704 print
' '.$form->textwithpicto(
'', $langs->trans(
"TicketMessageRecipientsHelp"), 1,
'help');
1708 $contacts = $ticketstat->getInfosTicketInternalContact(1);
1709 $contacts = array_merge($contacts, $ticketstat->getInfosTicketExternalContact(1));
1714 if (is_array($contacts) && count($contacts) > 0) {
1715 foreach ($contacts as $key => $info_sendto) {
1716 if ($info_sendto[
'email'] !=
'') {
1717 $sendto[] =
dol_escape_htmltag(trim($info_sendto[
'firstname'].
" ".$info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">").
' <small class="opacitymedium">('.
dol_escape_htmltag($info_sendto[
'libelle']).
")</small>";
1722 if (!empty($ticketstat->origin_replyto) && !in_array($ticketstat->origin_replyto, $sendto)) {
1723 $sendto[] =
dol_escape_htmltag($ticketstat->origin_replyto).
' <small class="opacitymedium">('.$langs->trans(
"TicketEmailOriginIssuer").
")</small>";
1724 } elseif ($ticketstat->origin_email && !in_array($ticketstat->origin_email, $sendto)) {
1725 $sendto[] =
dol_escape_htmltag($ticketstat->origin_email).
' <small class="opacitymedium">('.$langs->trans(
"TicketEmailOriginIssuer").
")</small>";
1728 if ($ticketstat->fk_soc > 0) {
1729 $ticketstat->socid = $ticketstat->fk_soc;
1730 $ticketstat->fetch_thirdparty();
1732 if (!empty($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) {
1733 $sendto[] = $ticketstat->thirdparty->email.
' <small class="opacitymedium">('.$langs->trans(
'Customer').
')</small>';
1738 $sendto[] =
getDolGlobalString(
'TICKET_NOTIFICATION_EMAIL_TO').
' <small class="opacitymedium">(generic email)</small>';
1742 if (is_array($sendto) && count($sendto) > 0) {
1743 print
img_picto(
'',
'email',
'class="pictofixedwidth"');
1744 print implode(
', ', $sendto);
1746 print
'<div class="warning">'.$langs->trans(
'WarningNoEMailsAdded').
' '.$langs->trans(
'TicketGoIntoContactTab').
'</div>';
1754 print
'<tr class="email_line"><td><span class="">'.$langs->trans(
"MailCC").
'</span></td>';
1755 print
'<td><span class="">'.img_picto(
'',
'email',
'class="pictofixedwidth"').$sendtocc.
'</span></td></tr>';
1759 $uselocalbrowser =
false;
1782 foreach ($formmail->lines_model as $line) {
1783 if (!empty($this->substit) && $this->param[
'models_id'] == $line->id) {
1788 print
'<tr class="email_line"><td class="fieldrequired">'.$langs->trans(
'MailTopic').
'</td>';
1789 if (empty($topic)) {
1790 print
'<td><input type="text" class="text minwidth500" name="subject" value="['.getDolGlobalString(
'MAIN_INFO_SOCIETE_NOM').
' - '.$langs->trans(
"Ticket").
' '.$ticketstat->ref.
'] '. $ticketstat->subject .
'" />';
1792 print
'<td><input type="text" class="text minwidth500" name="subject" value="'.make_substitutions($topic, $this->substit).
'" />';
1797 if (!empty($this->withfile)) {
1799 $out .=
'<td>'.$langs->trans(
"MailFile").
'</td>';
1802 $out .=
'<input type="hidden" class="removedfilehidden" name="removedfile" value="">'.
"\n";
1803 $out .=
'<script nonce="'.getNonce().
'" type="text/javascript">';
1804 $out .=
'jQuery(document).ready(function () {';
1805 $out .=
' jQuery("#'.$addfileaction.
'").prop("disabled", true);';
1806 $out .=
' jQuery("#addedfile").on("change", function() {';
1807 $out .=
' if (jQuery(this).val().length) {';
1808 $out .=
' jQuery("#'.$addfileaction.
'").prop("disabled", false);';
1809 $out .=
' } else {';
1810 $out .=
' jQuery("#'.$addfileaction.
'").prop("disabled", true);';
1813 $out .=
' jQuery(".removedfile").click(function() {';
1814 $out .=
' jQuery(".removedfilehidden").val(jQuery(this).val());';
1817 $out .=
'</script>'.
"\n";
1819 if (count($listofpaths)) {
1820 foreach ($listofpaths as $key => $val) {
1821 $out .=
'<div id="attachfile_'.$key.
'">';
1822 $out .=
img_mime($listofnames[$key]).
' '.$listofnames[$key];
1823 if (!$this->withfilereadonly) {
1824 $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.
'" />';
1826 $out .=
'<br></div>';
1831 if ($this->withfile == 2) {
1832 $out .=
'<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans(
"Upload").
'" />';
1834 $out .=
'<input type="submit" class="button smallpaddingimp reposition" id="'.$addfileaction.
'" name="'.$addfileaction.
'" value="'.$langs->trans(
"MailingAddFile").
'" />';
1836 $out .=
"</td></tr>\n";
1842 $defaultmessage =
"";
1843 if (is_object($arraydefaultmessage) && $arraydefaultmessage->content) {
1844 $defaultmessage = (string) $arraydefaultmessage->content;
1846 $defaultmessage = str_replace(
'\n',
"\n", $defaultmessage);
1850 $this->substit[
'__USER_SIGNATURE__'] =
dol_nl2br($this->substit[
'__USER_SIGNATURE__']);
1851 } elseif (!
dol_textishtml($defaultmessage) && isset($this->substit[
'__USER_SIGNATURE__']) &&
dol_textishtml($this->substit[
'__USER_SIGNATURE__'])) {
1852 $defaultmessage =
dol_nl2br($defaultmessage);
1854 if (GETPOSTISSET(
"message") && !
GETPOST(
'modelselected')) {
1855 $defaultmessage =
GETPOST(
'message',
'restricthtml');
1859 $defaultmessage = preg_replace(
"/^(<br>)+/",
"", $defaultmessage);
1860 $defaultmessage = preg_replace(
"/^\n+/",
"", $defaultmessage);
1863 print
'<tr><td colspan="2"><label for="message"><span class="fieldrequired">'.$langs->trans(
"Message").
'</span>';
1864 if ($user->hasRight(
"ticket",
"write") && !$user->socid) {
1865 $texttooltip = $langs->trans(
"TicketMessageHelp");
1867 $texttooltip .=
'<br><br>'.$langs->trans(
"ForEmailMessageWillBeCompletedWith").
'...';
1869 $allowedmailtags = array(
'a',
'div',
'strong',
'em',
'i',
'u',
'p',
'ul',
'ol',
'li',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'img');
1872 print
'<input type="hidden" name="mail_intro" value="'.dolPrintHTMLForAttribute($mail_intro, 0, $allowedmailtags).
'">';
1873 $texttooltip .=
'<br><u>'.$langs->trans(
"TicketMessageMailIntro").
'</u><br>'.$mail_intro;
1877 print
'<input type="hidden" name="mail_signature" value="'.dolPrintHTMLForAttribute($mail_signature, 0, $allowedmailtags).
'">';
1878 $texttooltip .=
'<br><br><u>'.$langs->trans(
"TicketMessageMailFooter").
'</u><br>'.$mail_signature;
1880 print $form->textwithpicto(
'', $texttooltip, 1,
'help');
1882 print
'</label></td></tr>';
1885 print
'<tr><td colspan="2">';
1887 $toolbarname =
'dolibarr_notes';
1888 include_once DOL_DOCUMENT_ROOT.
'/core/class/doleditor.class.php';
1889 $doleditor =
new DolEditor(
'message', $defaultmessage,
'100%', 200, $toolbarname,
'',
false, $uselocalbrowser,
getDolGlobalInt(
'FCKEDITOR_ENABLE_TICKET'), ROWS_5,
'90%');
1890 $doleditor->Create();
1909 print
'<br><center>';
1910 print
'<input type="submit" class="button" name="btn_add_message" value="'.$langs->trans(
"Add").
'"';
1912 if ($this->withfile == 2 && !empty($conf->use_javascript_ajax)) {
1913 print
' onClick="if (document.ticket.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans(
"FileWasNotUploaded")).
'\');
return false; }
else {
return true; }
"';
1916 if (!empty($this->withcancel)) {
1917 print "
";
1918 print '<input class="button button-cancel
" type="submit
" name="cancel
" value="'.$langs->trans("Cancel").'">';
1920 print "</center>\n
";
1922 print '<input type="hidden
" name="page_y
">'."\n
";
1924 print "</form><br>\n
";
1926 // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
1927 if (getDolGlobalString('MAIN_MAILFORM_DISABLE_ENTERKEY')) {
1928 print '<script type="text/javascript
">';
1929 print 'jQuery(document).ready(function () {';
1930 print ' $(document).on("keypress
", \'#ticket\', function (e) { /* Note this is called at every key pressed ! */
1931 var code = e.keyCode || e.which;
1933 console.log("Enter was intercepted and blocked
");
1942 print "<!-- End form TICKET -->\n
";
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Class to manage a WYSIWYG editor.
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, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
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.
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.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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 a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
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...
multi select 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|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
getMaxFileSizeArray()
Return the max allowed for file upload.