ticket_details.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. $cidReset = true;
  4. require_once __DIR__.'/../inc/global.inc.php';
  5. api_block_anonymous_users();
  6. $user_id = api_get_user_id();
  7. $isAdmin = api_is_platform_admin();
  8. $interbreadcrumb[] = [
  9. 'url' => api_get_path(WEB_CODE_PATH).'ticket/tickets.php',
  10. 'name' => get_lang('My tickets'),
  11. ];
  12. $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Ticket details')];
  13. $disableReponseButtons = '';
  14. $htmlHeadXtra[] = '<script>
  15. $(function() {
  16. $("#dialog-form").dialog({
  17. autoOpen: false,
  18. height: 450,
  19. width: 600,
  20. modal: true,
  21. buttons: {
  22. '.get_lang('Accept').': function(){
  23. $("#frmResponsable").submit()
  24. },
  25. '.ucfirst(get_lang('Close')).': function() {
  26. $(this).dialog("close");
  27. }
  28. }
  29. });
  30. $("a#assign").click(function () {
  31. $( "#dialog-form" ).dialog( "open" );
  32. });
  33. $(".responseyes").click(function () {
  34. if(!confirm("'.get_lang('Are you sure').' : '.strtoupper(get_lang('Yes')).'. '.get_lang('If you are certain, the ticket will be closed.').'")){
  35. return false;
  36. }
  37. });
  38. $(".responseno").click(function () {
  39. if(!confirm("'.get_lang('Are you sure').' : '.strtoupper(get_lang('No')).'")){
  40. return false;
  41. }
  42. });
  43. '.$disableReponseButtons.'
  44. });
  45. var counter_image = 1;
  46. function remove_image_form(element_id) {
  47. $("#" + element_id).remove();
  48. counter_image = counter_image - 1;
  49. $("#link-more-attach").css("display", "block");
  50. }
  51. function add_image_form() {
  52. // Multiple filepaths for image form
  53. var filepaths = $("#filepaths");
  54. var new_elem, input_file, link_remove, img_remove, new_filepath_id;
  55. if ($("#filepath_"+counter_image)) {
  56. counter_image = counter_image + 1;
  57. } else {
  58. counter_image = counter_image;
  59. }
  60. new_elem = "filepath_"+counter_image;
  61. $("<div/>", {
  62. id: new_elem,
  63. class: "controls"
  64. }).appendTo(filepaths);
  65. input_file = $("<input/>", {
  66. type: "file",
  67. name: "attach_" + counter_image,
  68. size: 20
  69. });
  70. link_remove = $("<a/>", {
  71. onclick: "remove_image_form(\'" + new_elem + "\')",
  72. style: "cursor: pointer"
  73. });
  74. img_remove = $("<img/>", {
  75. src: "'.Display::returnIconPath('delete.png').'"
  76. });
  77. new_filepath_id = $("#filepath_" + counter_image);
  78. new_filepath_id.append(input_file, link_remove.append(img_remove));
  79. if (counter_image === 6) {
  80. var link_attach = $("#link-more-attach");
  81. if (link_attach) {
  82. $(link_attach).css("display", "none");
  83. }
  84. }
  85. }
  86. </script>';
  87. $htmlHeadXtra[] = '<style>
  88. .attachment-link {
  89. margin: 12px;
  90. }
  91. #link-more-attach {
  92. color: white;
  93. cursor: pointer;
  94. width: 120px;
  95. }
  96. </style>';
  97. $ticket_id = (int) $_REQUEST['ticket_id'];
  98. $ticket = TicketManager::get_ticket_detail_by_id($ticket_id);
  99. if (!isset($ticket['ticket']) ||
  100. // make sure it's either a user assigned to this ticket, or the reporter, or and admin
  101. !($ticket['ticket']['assigned_last_user'] == $user_id ||
  102. $ticket['ticket']['sys_insert_user_id'] == $user_id ||
  103. $isAdmin)
  104. ) {
  105. api_not_allowed(true);
  106. }
  107. if (!isset($_REQUEST['ticket_id'])) {
  108. header('Location: '.api_get_path(WEB_CODE_PATH).'ticket/tickets.php');
  109. exit;
  110. }
  111. /*if (isset($_POST['response'])) {
  112. if ($user_id == $ticket['ticket']['assigned_last_user'] || api_is_platform_admin()) {
  113. $response = $_POST['response'] === '1' ? true : false;
  114. $newStatus = TicketManager::STATUS_PENDING;
  115. if ($response) {
  116. $newStatus = TicketManager::STATUS_CLOSE;
  117. }
  118. TicketManager::update_ticket_status(
  119. TicketManager::getStatusIdFromCode($newStatus),
  120. $ticket_id,
  121. $user_id
  122. );
  123. Display::addFlash(Display::return_message(get_lang('Update successful')));
  124. header("Location:".api_get_self()."?ticket_id=".$ticket_id);
  125. exit;
  126. }
  127. }*/
  128. $title = 'Ticket #'.$ticket['ticket']['code'];
  129. if (isset($_REQUEST['close'])) {
  130. TicketManager::close_ticket($ticket_id, $user_id);
  131. $ticket['ticket']['status_id'] = TicketManager::STATUS_CLOSE;
  132. $ticket['ticket']['status'] = get_lang('Closed');
  133. }
  134. $projectId = $ticket['ticket']['project_id'];
  135. $messages = $ticket['messages'];
  136. $counter = 1;
  137. $messageToShow = '';
  138. $formToShow = '';
  139. foreach ($messages as $message) {
  140. $date = Display::url(
  141. date_to_str_ago($message['sys_insert_datetime']),
  142. '#',
  143. ['title' => api_get_local_time($message['sys_insert_datetime']), 'class' => 'boot-tooltip']
  144. );
  145. $receivedMessage = '';
  146. if (!empty($message['subject'])) {
  147. $receivedMessage = '<b>'.get_lang('Subject').': </b> '.Security::remove_XSS($message['subject']).'<br />';
  148. }
  149. if (!empty($message['message'])) {
  150. $receivedMessage = '<b>'.get_lang('Message').':</b><br />'.Security::remove_XSS($message['message']).'<br />';
  151. }
  152. $attachmentLinks = '';
  153. if (isset($message['attachments'])) {
  154. $attributeClass = [
  155. 'class' => 'attachment-link',
  156. ];
  157. foreach ($message['attachments'] as $attach) {
  158. $attachmentLinks .= Display::tag('div', $attach['attachment_link'], $attributeClass);
  159. }
  160. }
  161. $entireMessage = $receivedMessage.$attachmentLinks;
  162. $counterLink = Display::url('#'.$counter, api_get_self().'?ticket_id='.$ticket_id.'#note-'.$counter);
  163. $messageToShow .= '<a id="note-'.$counter.'"> </a><h4>'.sprintf(
  164. get_lang('Update successfulByX'),
  165. $message['user_info']['complete_name_with_message_link']
  166. );
  167. $messageToShow .= ' '.$date.' <span class="pull-right">'.$counterLink.'</span></h4>';
  168. $messageToShow .= '<hr />';
  169. if (!empty($entireMessage)) {
  170. $messageToShow .= Display::div(
  171. $entireMessage,
  172. ['class' => 'well']
  173. );
  174. }
  175. $counter++;
  176. }
  177. $subject = get_lang('Re:').': '.Security::remove_XSS($ticket['ticket']['subject']);
  178. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
  179. $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE
  180. ) {
  181. if ($ticket['ticket']['assigned_last_user'] == $user_id ||
  182. $ticket['ticket']['sys_insert_user_id'] == $user_id ||
  183. $isAdmin
  184. ) {
  185. $form = getForm($ticket['ticket']);
  186. $formToShow = $form->returnForm();
  187. if ($form->validate()) {
  188. $ticket_id = (int) $_POST['ticket_id'];
  189. $messageToSend = '';
  190. $message = isset($_POST['confirmation']) ? true : false;
  191. $file_attachments = $_FILES;
  192. if ($isAdmin) {
  193. $oldUserId = $ticket['ticket']['assigned_last_user'];
  194. if (isset($_POST['assigned_last_user']) && !empty($_POST['assigned_last_user']) &&
  195. $_POST['assigned_last_user'] != $oldUserId
  196. ) {
  197. TicketManager::assignTicketToUser(
  198. $ticket_id,
  199. $_POST['assigned_last_user']
  200. );
  201. $oldUserName = '-';
  202. if (!empty($oldUserId)) {
  203. $oldUserInfo = api_get_user_info($oldUserId);
  204. $oldUserName = $oldUserInfo['complete_name_with_message_link'];
  205. }
  206. $userCompleteName = '-';
  207. if (!empty($_POST['assigned_last_user'])) {
  208. $userInfo = api_get_user_info(
  209. $_POST['assigned_last_user']
  210. );
  211. $userCompleteName = $userInfo['complete_name_with_message_link'];
  212. }
  213. $messageToSend .= sprintf(
  214. get_lang('Assignee changed from %s to %s'),
  215. $oldUserName,
  216. $userCompleteName
  217. ).'<br />';
  218. }
  219. TicketManager::updateTicket(
  220. [
  221. 'priority_id' => (int) $_POST['priority_id'],
  222. 'status_id' => (int) $_POST['status_id'],
  223. ],
  224. $ticket_id,
  225. api_get_user_id()
  226. );
  227. if ($_POST['priority_id'] != $ticket['ticket']['priority_id']) {
  228. $newPriority = TicketManager::getPriority(
  229. $_POST['priority_id']
  230. );
  231. $newPriorityTitle = '-';
  232. if ($newPriority) {
  233. $newPriorityTitle = $newPriority->getName();
  234. }
  235. $oldPriority = TicketManager::getPriority(
  236. $ticket['ticket']['priority_id']
  237. );
  238. $oldPriorityTitle = '-';
  239. if ($oldPriority) {
  240. $oldPriorityTitle = $oldPriority->getName();
  241. }
  242. $messageToSend .= sprintf(
  243. get_lang('Priority changed from %s to %s'),
  244. $oldPriorityTitle,
  245. $newPriorityTitle
  246. ).'<br />';
  247. }
  248. if ($_POST['status_id'] != $ticket['ticket']['status_id']) {
  249. $newStatus = TicketManager::getStatus(
  250. $_POST['status_id']
  251. );
  252. $newTitle = '-';
  253. if ($newStatus) {
  254. $newTitle = $newStatus->getName();
  255. }
  256. $oldStatus = TicketManager::getStatus(
  257. $ticket['ticket']['status_id']
  258. );
  259. $oldStatusTitle = '-';
  260. if ($oldStatus) {
  261. $oldStatusTitle = $oldStatus->getName();
  262. }
  263. $messageToSend .= sprintf(
  264. get_lang('Status changed from %s to %s'),
  265. $oldStatusTitle,
  266. $newTitle
  267. ).'<br />';
  268. }
  269. }
  270. $messageToSend .= $_POST['content'];
  271. TicketManager::insertMessage(
  272. $ticket_id,
  273. $_POST['subject'],
  274. $messageToSend,
  275. $file_attachments,
  276. $user_id,
  277. 'NOL',
  278. $message
  279. );
  280. TicketManager::sendNotification(
  281. $ticket_id,
  282. get_lang('TicketUpdate successful'),
  283. $messageToSend
  284. );
  285. Display::addFlash(Display::return_message(get_lang('Saved.')));
  286. header("Location:".api_get_self()."?ticket_id=".$ticket_id);
  287. exit;
  288. }
  289. }
  290. }
  291. Display::display_header();
  292. echo '<div class="actions">';
  293. echo Display::url(
  294. Display::return_icon('back.png', get_lang('Tickets'), [], ICON_SIZE_MEDIUM),
  295. api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id='.$projectId
  296. );
  297. echo '</div>';
  298. $bold = '';
  299. if ($ticket['ticket']['status_id'] == TicketManager::STATUS_CLOSE) {
  300. $bold = 'style = "font-weight: bold;"';
  301. }
  302. $senderData = get_lang('added by').' '.$ticket['usuario']['complete_name_with_message_link'];
  303. echo '<table width="100%" >
  304. <tr>
  305. <td colspan="3">
  306. <h1>'.$title.'</h1>
  307. <h2>'.Security::remove_XSS($ticket['ticket']['subject']).'</h2>
  308. <p>
  309. '.$senderData.' '.
  310. get_lang('Created').' '.
  311. Display::url(
  312. date_to_str_ago($ticket['ticket']['start_date_from_db']),
  313. '#',
  314. ['title' => $ticket['ticket']['start_date'], 'class' => 'boot-tooltip']
  315. ).'. '.
  316. get_lang('TicketUpdate successful').' '.
  317. Display::url(
  318. date_to_str_ago($ticket['ticket']['sys_lastedit_datetime_from_db']),
  319. '#',
  320. ['title' => $ticket['ticket']['sys_lastedit_datetime'], 'class' => 'boot-tooltip']
  321. ).'
  322. </p>
  323. </td>
  324. </tr>
  325. <tr>
  326. <td><p><b>'.get_lang('Category').': </b>'.$ticket['ticket']['name'].'</p></td>
  327. </tr>
  328. <tr>
  329. <td><p '.$bold.'><b>'.get_lang('Status').':</b> '.$ticket['ticket']['status'].'</p></td>
  330. </tr>
  331. <tr>
  332. <td><p><b>'.get_lang('Priority').': </b>'.$ticket['ticket']['priority'].'<p></td>
  333. </tr>';
  334. if (!empty($ticket['ticket']['assigned_last_user'])) {
  335. $assignedUser = api_get_user_info($ticket['ticket']['assigned_last_user']);
  336. echo '<tr>
  337. <td><p><b>'.get_lang('Assigned to').': </b>'.$assignedUser['complete_name_with_message_link'].'<p></td>
  338. </tr>';
  339. } else {
  340. echo '<tr>
  341. <td><p><b>'.get_lang('Assigned to').': </b>-<p></td>
  342. </tr>';
  343. }
  344. if ($ticket['ticket']['course_url'] != null) {
  345. if (!empty($ticket['ticket']['session_id'])) {
  346. $sessionInfo = api_get_session_info($ticket['ticket']['session_id']);
  347. echo '<tr>
  348. <td><b>'.get_lang('Session').':</b> '.$sessionInfo['name'].' </td>
  349. <td></td>
  350. <td colspan="2"></td>
  351. </tr>';
  352. }
  353. echo '<tr>
  354. <td><b>'.get_lang('Course').':</b> '.$ticket['ticket']['course_url'].' </td>
  355. <td></td>
  356. <td colspan="2"></td>
  357. </tr>';
  358. }
  359. echo '<tr>
  360. <td>
  361. <hr />
  362. <b>'.get_lang('Description').':</b> <br />
  363. '.Security::remove_XSS($ticket['ticket']['message']).'
  364. <hr />
  365. </td>
  366. </tr>
  367. ';
  368. echo '</table>';
  369. echo $messageToShow;
  370. echo $formToShow;
  371. Display::display_footer();
  372. /**
  373. * @param array $ticket
  374. *
  375. * @return FormValidator
  376. */
  377. function getForm($ticket)
  378. {
  379. $isAdmin = api_is_platform_admin();
  380. global $subject;
  381. $form = new FormValidator(
  382. 'send_ticket',
  383. 'POST',
  384. api_get_self().'?ticket_id='.$ticket['id'],
  385. '',
  386. [
  387. 'enctype' => 'multipart/form-data',
  388. 'class' => 'form-horizontal',
  389. ]
  390. );
  391. if ($isAdmin) {
  392. $statusList = TicketManager::getStatusList();
  393. $form->addElement(
  394. 'select',
  395. 'status_id',
  396. get_lang('Status'),
  397. $statusList
  398. );
  399. $priorityList = TicketManager::getPriorityList();
  400. $form->addElement(
  401. 'select',
  402. 'priority_id',
  403. get_lang('Priority'),
  404. $priorityList,
  405. [
  406. 'id' => 'priority_id',
  407. 'for' => 'priority_id',
  408. ]
  409. );
  410. $form->addSelectAjax(
  411. 'assigned_last_user',
  412. get_lang('Assign'),
  413. null,
  414. ['url' => api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_like']
  415. );
  416. $form->setDefaults(
  417. [
  418. 'priority_id' => $ticket['priority_id'],
  419. 'status_id' => $ticket['status_id'],
  420. 'assigned_last_user' => $ticket['assigned_last_user'],
  421. ]
  422. );
  423. }
  424. $form->addElement(
  425. 'text',
  426. 'subject',
  427. get_lang('Subject'),
  428. [
  429. 'for' => 'subject',
  430. 'value' => $subject,
  431. 'style' => 'width: 540px;',
  432. ]
  433. );
  434. $form->addElement('hidden', 'ticket_id', $ticket['id']);
  435. $form->addHtmlEditor(
  436. 'content',
  437. get_lang('Message'),
  438. false,
  439. false,
  440. [
  441. 'ToolbarSet' => 'Profile',
  442. 'Width' => '550',
  443. 'Height' => '250',
  444. ]
  445. );
  446. if ($isAdmin) {
  447. $form->addElement(
  448. 'checkbox',
  449. 'confirmation',
  450. null,
  451. get_lang('Request confirmation')
  452. );
  453. }
  454. $form->addElement('file', 'attach_1', get_lang('Files attachments'));
  455. $form->addLabel(
  456. '',
  457. '<span id="filepaths"><div id="filepath_1"></div></span>'
  458. );
  459. $form->addLabel(
  460. '',
  461. '<span id="link-more-attach">
  462. <span class="btn btn-success" onclick="return add_image_form()">'.get_lang('Add one more file').'</span>
  463. </span>
  464. ('.sprintf(get_lang('Maximun file size: %s'), format_file_size(api_get_setting('message_max_upload_filesize'))).')'
  465. );
  466. $form->addElement('html', '<br/>');
  467. $form->addButtonSend(get_lang('Send message'));
  468. return $form;
  469. }