ticket_details.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. *
  5. * @package chamilo.plugin.ticket
  6. */
  7. require_once __DIR__.'/../inc/global.inc.php';
  8. api_block_anonymous_users();
  9. $user_id = api_get_user_id();
  10. $isAdmin = api_is_platform_admin();
  11. $interbreadcrumb[] = array(
  12. 'url' => api_get_path(WEB_CODE_PATH).'ticket/tickets.php',
  13. 'name' => get_lang('MyTickets')
  14. );
  15. $interbreadcrumb[] = array('url' => '#', 'name' => get_lang('TicketDetail'));
  16. $disableReponseButtons = '';
  17. $htmlHeadXtra[] = '<script>
  18. $(document).ready(function() {
  19. $("#dialog-form").dialog({
  20. autoOpen: false,
  21. height: 450,
  22. width: 600,
  23. modal: true,
  24. buttons: {
  25. ' . get_lang('Accept') . ': function(){
  26. $("#frmResponsable").submit()
  27. },
  28. ' . ucfirst(get_lang('Close')) . ': function() {
  29. $(this).dialog("close");
  30. }
  31. }
  32. });
  33. $("a#assign").click(function () {
  34. $( "#dialog-form" ).dialog( "open" );
  35. });
  36. $(".responseyes").click(function () {
  37. if(!confirm("' . get_lang('AreYouSure') . ' : ' . strtoupper(get_lang('Yes')) . '. ' . get_lang('IfYouAreSureTheTicketWillBeClosed') . '")){
  38. return false;
  39. }
  40. });
  41. $("input#responseno").click(function () {
  42. if(!confirm("' . get_lang('AreYouSure') . ' : ' . strtoupper(get_lang('No')) . '")){
  43. return false;
  44. }
  45. });
  46. $("#unassign").click(function () {
  47. if (!confirm("' . get_lang('AreYouSureYouWantToUnassignTheTicket') . '")) {
  48. return false;
  49. }
  50. });
  51. $("#close").click(function () {
  52. if (!confirm("' . get_lang('AreYouSureYouWantToCloseTheTicket') . '")) {
  53. return false;
  54. }
  55. });
  56. '.$disableReponseButtons.'
  57. });
  58. function validate() {
  59. fckEditor1val = CKEDITOR.instances["content"].getData();
  60. document.getElementById("content").value= fckEditor1val;
  61. if (fckEditor1val == ""){
  62. alert("' . get_lang('Filled') . '");
  63. return false;
  64. }
  65. }
  66. var counter_image = 1;
  67. function remove_image_form(element_id) {
  68. $("#" + element_id).remove();
  69. counter_image = counter_image - 1;
  70. $("#link-more-attach").css("display", "block");
  71. }
  72. function add_image_form() {
  73. // Multiple filepaths for image form
  74. var filepaths = $("#filepaths");
  75. var new_elem, input_file, link_remove, img_remove, new_filepath_id;
  76. if ($("#filepath_"+counter_image)) {
  77. counter_image = counter_image + 1;
  78. } else {
  79. counter_image = counter_image;
  80. }
  81. new_elem = "filepath_"+counter_image;
  82. $("<div/>", {
  83. id: new_elem,
  84. class: "controls"
  85. }).appendTo(filepaths);
  86. input_file = $("<input/>", {
  87. type: "file",
  88. name: "attach_" + counter_image,
  89. size: 20
  90. });
  91. link_remove = $("<a/>", {
  92. onclick: "remove_image_form(\'" + new_elem + "\')",
  93. style: "cursor: pointer"
  94. });
  95. img_remove = $("<img/>", {
  96. src: "' . Display::returnIconPath('delete.png').'"
  97. });
  98. new_filepath_id = $("#filepath_" + counter_image);
  99. new_filepath_id.append(input_file, link_remove.append(img_remove));
  100. if (counter_image === 6) {
  101. var link_attach = $("#link-more-attach");
  102. if (link_attach) {
  103. $(link_attach).css("display", "none");
  104. }
  105. }
  106. }
  107. </script>';
  108. $htmlHeadXtra[] = '<style>
  109. div.row div.label2 {
  110. float:left;
  111. text-align: right;
  112. width:22%;
  113. }
  114. div.row div.formw2 {
  115. width:50%;
  116. margin-left: 2%;
  117. margin-right: 16%;
  118. float:left;
  119. }
  120. .messageuser, .messagesupport {
  121. border: 1px solid;
  122. margin: 10px 0px;
  123. padding:15px 10px 15px 50px;
  124. background-repeat: no-repeat;
  125. background-position: 10px center;
  126. width:50%;
  127. behavior: url(/pie/PIE.htc);
  128. }
  129. .messageuser {
  130. color: #00529B;
  131. -moz-border-radius: 15px 15px 15px 15px;
  132. -webkit-border-radius: 15px 15px 15px 15px;
  133. background-color: #BDE5F8;
  134. margin-left:20%;
  135. border-radius:15px;
  136. float: left;
  137. }
  138. .messagesupport {
  139. color: #4F8A10;
  140. -moz-border-radius: 15px 15px 15px 15px;
  141. -webkit-border-radius: 15px 15px 15px 15px;
  142. background-color: #DFF2BF;
  143. margin-right: 20%;
  144. float: right;
  145. border-radius:15px;
  146. }
  147. .attachment-link {
  148. margin: 12px;
  149. }
  150. #link-more-attach {
  151. color: white;
  152. cursor: pointer;
  153. width: 120px;
  154. }
  155. </style>';
  156. $ticket_id = $_GET['ticket_id'];
  157. $ticket = TicketManager::get_ticket_detail_by_id($ticket_id);
  158. if (!isset($ticket['ticket'])) {
  159. api_not_allowed();
  160. }
  161. if (!isset($_GET['ticket_id'])) {
  162. header('Location: '.api_get_path(WEB_CODE_PATH).'ticket/tickets.php');
  163. exit;
  164. }
  165. if (isset($_POST['response'])) {
  166. if ($user_id == $ticket['ticket']['assigned_last_user'] || api_is_platform_admin()) {
  167. $response = $_POST['response'] === '1' ? true : false;
  168. $newStatus = TicketManager::STATUS_PENDING;
  169. if ($response) {
  170. $newStatus = TicketManager::STATUS_CLOSE;
  171. }
  172. TicketManager::update_ticket_status(
  173. TicketManager::getStatusIdFromCode($newStatus),
  174. $ticket_id,
  175. $user_id
  176. );
  177. Display::addFlash(Display::return_message(get_lang('Updated')));
  178. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  179. exit;
  180. }
  181. }
  182. if (isset($_REQUEST['action'])) {
  183. $action = $_REQUEST['action'];
  184. switch ($action) {
  185. case 'assign':
  186. if (api_is_platform_admin() && isset($_GET['ticket_id'])) {
  187. TicketManager::assign_ticket_user($_GET['ticket_id'], $_POST['admins']);
  188. }
  189. Display::addFlash(Display::return_message(get_lang('Updated')));
  190. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  191. exit;
  192. break;
  193. case 'unassign':
  194. if (api_is_platform_admin() && isset($_GET['ticket_id'])) {
  195. TicketManager::assign_ticket_user($_GET['ticket_id'], 0);
  196. }
  197. Display::addFlash(Display::return_message(get_lang('Updated')));
  198. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  199. exit;
  200. break;
  201. default:
  202. break;
  203. }
  204. }
  205. $title = 'Ticket #' . $ticket['ticket']['code'];
  206. if (!isset($_POST['compose'])) {
  207. if (isset($_REQUEST['close'])) {
  208. TicketManager::close_ticket($_REQUEST['ticket_id'], $user_id);
  209. $ticket['ticket']['status_id'] = TicketManager::STATUS_CLOSE;
  210. $ticket['ticket']['status'] = get_lang('Closed');
  211. }
  212. Display::display_header();
  213. $form_close_ticket = '';
  214. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
  215. $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE &&
  216. $isAdmin
  217. ) {
  218. /*if (intval($ticket['ticket']['assigned_last_user']) == $user_id) {
  219. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE) {
  220. $form_close_ticket.= '<a href="' . api_get_self() . '?close=1&ticket_id=' . $ticket['ticket']['id'] . '" id="close" class="btn btn-danger" >';
  221. $form_close_ticket.= get_lang('Close') . '</a>';
  222. }
  223. }*/
  224. }
  225. $img_assing = '';
  226. if (empty($ticket['ticket']['assigned_last_user'])) {
  227. if ($isAdmin) {
  228. $img_assing = '<a href="#" id="assign" class="btn btn-success">'.get_lang('Assign').'</a>';
  229. }
  230. } else {
  231. if ($isAdmin) {
  232. $img_assing = '<a class="btn btn-warning" href="#" id="assign">
  233. '.get_lang('ChangeAssign').'
  234. </a>';
  235. }
  236. }
  237. $bold = '';
  238. if ($ticket['ticket']['status_id'] == TicketManager::STATUS_CLOSE) {
  239. $bold = 'style = "font-weight: bold;"';
  240. echo "<style>
  241. #confirmticket {
  242. display: none;
  243. }
  244. </style>";
  245. }
  246. if ($isAdmin) {
  247. $senderData = get_lang('AddedBy'). ' '.$ticket['ticket']['user_url'].' (' . $ticket['usuario']['username'] . ').';
  248. } else {
  249. $senderData = get_lang('AddedBy'). ' '.$ticket['usuario']['complete_name'].' (' . $ticket['usuario']['username']. ').';
  250. }
  251. echo '<table width="100%" >
  252. <tr>
  253. <td colspan="3">
  254. <h1>'.$title.' '.$form_close_ticket.'</h1>
  255. <h2>'.$ticket['ticket']['subject'].'</h2>
  256. <p>
  257. '.$senderData.' ' .
  258. get_lang('Created') . ' '.
  259. Display::url(
  260. date_to_str_ago($ticket['ticket']['start_date_from_db']),
  261. '#',
  262. ['title' => $ticket['ticket']['start_date'], 'class' => 'boot-tooltip']
  263. ).'. '.
  264. get_lang('TicketUpdated').' '.
  265. Display::url(
  266. date_to_str_ago($ticket['ticket']['sys_lastedit_datetime_from_db']),
  267. '#',
  268. ['title' => $ticket['ticket']['sys_lastedit_datetime'], 'class' => 'boot-tooltip']
  269. ).'
  270. </p>
  271. </td>
  272. </tr>
  273. <tr>
  274. <td><p><b>' . get_lang('Category') . ': </b>' . $ticket['ticket']['name'] . '</p></td>
  275. </tr>
  276. <tr>
  277. <td><p ' . $bold . '><b>' . get_lang('Status') . ':</b> ' . $ticket['ticket']['status'] . '</p></td>
  278. </tr>
  279. <tr>
  280. <td><p><b>' . get_lang('Priority') . ': </b>' . $ticket['ticket']['priority'] . '<p></td>
  281. </tr>';
  282. if (!empty($ticket['ticket']['assigned_last_user'])) {
  283. $assignedUser = api_get_user_info($ticket['ticket']['assigned_last_user']);
  284. echo '<tr>
  285. <td><p><b>' . get_lang('AssignedTo') . ': </b>' . $assignedUser['complete_name'] . '<p></td>
  286. </tr>';
  287. } else {
  288. echo '<tr>
  289. <td><p><b>' . get_lang('AssignedTo') . ': </b>-<p></td>
  290. </tr>';
  291. }
  292. if ($ticket['ticket']['course_url'] != null) {
  293. if (!empty($ticket['ticket']['session_id'])) {
  294. $sessionInfo = api_get_session_info($ticket['ticket']['session_id']);
  295. echo '<tr>
  296. <td><b>' . get_lang('Session') . ':</b> ' . $sessionInfo['name'] . ' </td>
  297. <td></td>
  298. <td colspan="2"></td>
  299. </tr>';
  300. }
  301. echo '<tr>
  302. <td><b>' . get_lang('Course') . ':</b> ' . $ticket['ticket']['course_url'] . ' </td>
  303. <td></td>
  304. <td colspan="2"></td>
  305. </tr>';
  306. }
  307. echo '<tr>
  308. <td>
  309. <hr />
  310. <b>' . get_lang('Description') . ':</b> <br />
  311. '.$ticket['ticket']['message'].'
  312. <hr />
  313. </td>
  314. </tr>
  315. ';
  316. echo '</table>';
  317. $messages = $ticket['messages'];
  318. $logs = TicketManager::get_assign_log($ticket_id);
  319. $counter = 1;
  320. foreach ($messages as $message) {
  321. $date = Display::url(
  322. date_to_str_ago($message['sys_insert_datetime']),
  323. '#',
  324. ['title' => api_get_local_time($message['sys_insert_datetime']), 'class' => 'boot-tooltip']
  325. );
  326. $receivedMessage = '';
  327. if (!empty($message['subject'])) {
  328. $receivedMessage = '<b>'.get_lang('Subject') . ': </b> '.$message['subject'].'<br/>';
  329. }
  330. $receivedMessage = '<b>'.get_lang('Message') . ':</b><br/>'.$message['message'].'<br/>';
  331. $attachmentLinks = '';
  332. if (isset($message['attachments'])) {
  333. $attributeClass = array(
  334. 'class' => 'attachment-link'
  335. );
  336. foreach ($message['attachments'] as $attach) {
  337. $attachmentLinks .= Display::tag('div', $attach['attachment_link'], $attributeClass);
  338. }
  339. }
  340. $entireMessage = $receivedMessage . $attachmentLinks;
  341. $counterLink = Display::url('#'.$counter, api_get_self().'?ticket_id='.$ticket_id.'#note-'.$counter);
  342. echo '<a id="note-'.$counter.'"> </a><h4>' . sprintf(get_lang('UpdatedByX'), $message['user_created']).' '.$date.
  343. ' <span class="pull-right">'.$counterLink.'</span></h4>';
  344. echo Display::div(
  345. $entireMessage,
  346. ['class' => 'well']
  347. );
  348. $counter++;
  349. }
  350. $subject = get_lang('ReplyShort') .': '.$ticket['ticket']['subject'];
  351. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
  352. $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE
  353. ) {
  354. if (!$isAdmin && $ticket['ticket']['status_id'] != TicketManager::STATUS_UNCONFIRMED) {
  355. show_form_send_message($ticket['ticket']);
  356. } else {
  357. if (
  358. $ticket['ticket']['assigned_last_user'] == $user_id ||
  359. $ticket['ticket']['sys_insert_user_id'] == $user_id ||
  360. $isAdmin
  361. ) {
  362. show_form_send_message($ticket['ticket']);
  363. }
  364. }
  365. }
  366. Display::display_footer();
  367. } else {
  368. $ticket_id = $_POST['ticket_id'];
  369. $content = $_POST['content'];
  370. $subject = $_POST['subject'];
  371. $message = isset($_POST['confirmation']) ? true : false;
  372. $file_attachments = $_FILES;
  373. $user_id = api_get_user_id();
  374. TicketManager::insert_message(
  375. $ticket_id,
  376. $subject,
  377. $content,
  378. $file_attachments,
  379. $user_id,
  380. 'NOL',
  381. $message
  382. );
  383. if ($isAdmin) {
  384. TicketManager::updateTicket(
  385. [
  386. 'priority_id' => $_POST['priority_id'],
  387. 'status_id' => $_POST['status_id']
  388. ],
  389. $ticket_id,
  390. api_get_user_id()
  391. );
  392. if (isset($_POST['assigned_last_user']) && !empty($_POST['assigned_last_user'])) {
  393. TicketManager::assign_ticket_user($ticket_id, $_POST['assigned_last_user']);
  394. }
  395. }
  396. Display::addFlash(Display::return_message(get_lang('Saved')));
  397. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  398. exit;
  399. }
  400. /**
  401. * @param array $ticket
  402. */
  403. function show_form_send_message($ticket)
  404. {
  405. global $isAdmin;
  406. global $subject;
  407. $form = new FormValidator(
  408. 'send_ticket',
  409. 'POST',
  410. api_get_self() . '?ticket_id=' . $ticket['id'],
  411. '',
  412. array(
  413. 'enctype' => 'multipart/form-data',
  414. 'onsubmit' => 'return validate()',
  415. 'class' => 'form-horizontal'
  416. )
  417. );
  418. if ($isAdmin) {
  419. $statusList = TicketManager::getStatusList();
  420. $form->addElement(
  421. 'select',
  422. 'status_id',
  423. get_lang('Status'),
  424. $statusList
  425. );
  426. $priorityList = TicketManager::getPriorityList();
  427. $form->addElement(
  428. 'select',
  429. 'priority_id',
  430. get_lang('Priority'),
  431. $priorityList,
  432. array(
  433. 'id' => 'priority_id',
  434. 'for' => 'priority_id'
  435. )
  436. );
  437. $admins = UserManager::get_user_list_like(
  438. array('status' => COURSEMANAGER), array('username'),
  439. true
  440. );
  441. $adminList = ['' => get_lang('Select')];
  442. foreach ($admins as $admin) {
  443. $adminList[$admin['user_id']] = $admin['complete_name'];
  444. }
  445. $form->addElement(
  446. 'select',
  447. 'assigned_last_user',
  448. get_lang('Assign'),
  449. $adminList,
  450. array(
  451. 'id' => 'assigned_last_user',
  452. 'for' => 'assigned_last_user'
  453. )
  454. );
  455. $form->setDefaults(
  456. [
  457. 'priority_id' => $ticket['priority_id'],
  458. 'status_id' => $ticket['status_id'],
  459. 'assigned_last_user' => $ticket['assigned_last_user']
  460. ]
  461. );
  462. }
  463. $form->addElement(
  464. 'text',
  465. 'subject',
  466. get_lang('Subject'),
  467. array(
  468. 'for' => 'subject',
  469. 'value' => $subject,
  470. 'style' => 'width: 540px;'
  471. )
  472. );
  473. $form->addElement('hidden', 'ticket_id', $ticket['id']);
  474. $form->addHtmlEditor(
  475. 'content',
  476. get_lang('Message'),
  477. false,
  478. false,
  479. array(
  480. 'ToolbarSet' => 'Profile',
  481. 'Width' => '550',
  482. 'Height' => '250'
  483. )
  484. );
  485. if ($isAdmin) {
  486. $form->addElement(
  487. 'checkbox',
  488. 'confirmation',
  489. null,
  490. get_lang('RequestConfirmation')
  491. );
  492. }
  493. $form->addElement('file', 'attach_1', get_lang('FilesAttachment'));
  494. $form->addLabel('', '<span id="filepaths"><div id="filepath_1"></div></span>');
  495. $form->addLabel('',
  496. '<span id="link-more-attach">
  497. <span class="btn btn-success" onclick="return add_image_form()">' . get_lang('AddOneMoreFile') . '</span>
  498. </span>
  499. ('.sprintf(get_lang('MaximunFileSizeX'), format_file_size(api_get_setting('message_max_upload_filesize'))).')
  500. ');
  501. $form->addElement('html', '<br/>');
  502. $form->addElement(
  503. 'button',
  504. 'compose',
  505. get_lang('SendMessage'),
  506. null,
  507. null,
  508. null,
  509. 'btn btn-primary'
  510. );
  511. $form->display();
  512. }