ticket_details.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  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']) {
  167. $response = $_POST['response'] == '1' ? true : $_POST['response'] == "0" ? false : null;
  168. if ($response && $ticket['ticket']['status_id'] == TicketManager::STATUS_UNCONFIRMED) {
  169. /*TicketManager::close_ticket($_GET['ticket_id'], $user_id);
  170. $ticket['ticket']['status_id'] = TicketManager::STATUS_CLOSE;
  171. $ticket['ticket']['status'] = get_lang('Closed');*/
  172. } else if (!is_null($response) && $ticket['ticket']['status_id'] == TicketManager::STATUS_UNCONFIRMED) {
  173. TicketManager::update_ticket_status(TicketManager::STATUS_PENDING, $_GET['ticket_id'], $user_id);
  174. $ticket['ticket']['status_id'] = TicketManager::STATUS_PENDING;
  175. $ticket['ticket']['status'] = get_lang('StatusPending');
  176. }
  177. }
  178. }
  179. if (isset($_REQUEST['action'])) {
  180. $action = $_REQUEST['action'];
  181. switch ($action) {
  182. case 'assign':
  183. if (api_is_platform_admin() && isset($_GET['ticket_id'])) {
  184. TicketManager::assign_ticket_user($_GET['ticket_id'], $_POST['admins']);
  185. }
  186. Display::addFlash(Display::return_message(get_lang('Updated')));
  187. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  188. exit;
  189. break;
  190. case 'unassign':
  191. if (api_is_platform_admin() && isset($_GET['ticket_id'])) {
  192. TicketManager::assign_ticket_user($_GET['ticket_id'], 0);
  193. }
  194. Display::addFlash(Display::return_message(get_lang('Updated')));
  195. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  196. exit;
  197. break;
  198. default:
  199. break;
  200. }
  201. }
  202. $title = 'Ticket #' . $ticket['ticket']['code'];
  203. if (!isset($_POST['compose'])) {
  204. if (isset($_REQUEST['close'])) {
  205. TicketManager::close_ticket($_REQUEST['ticket_id'], $user_id);
  206. $ticket['ticket']['status_id'] = TicketManager::STATUS_CLOSE;
  207. $ticket['ticket']['status'] = get_lang('Closed');
  208. }
  209. /*$ticket['ticket']['request_user'] = intval($ticket['ticket']['request_user']);
  210. if ($ticket['ticket']['request_user'] == $user_id || intval($ticket['ticket']['assigned_last_user']) == $user_id) {
  211. TicketManager::update_message_status($ticket_id, $ticket['ticket']['request_user']);
  212. }*/
  213. Display::display_header();
  214. $form_close_ticket = '';
  215. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
  216. $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE &&
  217. $isAdmin
  218. ) {
  219. /*if (intval($ticket['ticket']['assigned_last_user']) == $user_id) {
  220. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE) {
  221. $form_close_ticket.= '<a href="' . api_get_self() . '?close=1&ticket_id=' . $ticket['ticket']['id'] . '" id="close" class="btn btn-danger" >';
  222. $form_close_ticket.= get_lang('Close') . '</a>';
  223. }
  224. }*/
  225. }
  226. $img_assing = '';
  227. if (empty($ticket['ticket']['assigned_last_user'])) {
  228. if ($isAdmin) {
  229. $img_assing = '<a href="#" id="assign" class="btn btn-success">'.get_lang('Assign').'</a>';
  230. }
  231. } else {
  232. if ($isAdmin) {
  233. $img_assing = '<a class="btn btn-warning" href="#" id="assign">
  234. '.get_lang('ChangeAssign').'
  235. </a>';
  236. }
  237. }
  238. $bold = '';
  239. if ($ticket['ticket']['status_id'] == TicketManager::STATUS_CLOSE) {
  240. $bold = 'style = "font-weight: bold;"';
  241. echo "<style>
  242. #confirmticket {
  243. display: none;
  244. }
  245. </style>";
  246. }
  247. if ($isAdmin) {
  248. $senderData = get_lang('AddedBy'). ' '.$ticket['ticket']['user_url'].' (' . $ticket['usuario']['username'] . ').';
  249. } else {
  250. $senderData = get_lang('AddedBy'). ' '.$ticket['usuario']['complete_name'].' (' . $ticket['usuario']['username']. ').';
  251. }
  252. echo '<table width="100%" >
  253. <tr>
  254. <td colspan="3">
  255. <h1>'.$title.' '.$form_close_ticket.'</h1>
  256. <h2>'.$ticket['ticket']['subject'].'</h2>
  257. <p>
  258. '.$senderData.' ' .
  259. get_lang('Created') . ' '.
  260. Display::url(
  261. date_to_str_ago($ticket['ticket']['start_date_from_db']),
  262. '#',
  263. ['title' => $ticket['ticket']['start_date'], 'class' => 'boot-tooltip']
  264. ).'. '.
  265. get_lang('TicketUpdated').' '.
  266. Display::url(
  267. date_to_str_ago($ticket['ticket']['sys_lastedit_datetime_from_db']),
  268. '#',
  269. ['title' => $ticket['ticket']['sys_lastedit_datetime'], 'class' => 'boot-tooltip']
  270. ).'
  271. </p>
  272. </td>
  273. </tr>
  274. <tr>
  275. <td><p><b>' . get_lang('Category') . ': </b>' . $ticket['ticket']['name'] . '</p></td>
  276. </tr>
  277. <tr>
  278. <td><p ' . $bold . '><b>' . get_lang('Status') . ':</b> ' . $ticket['ticket']['status'] . '</p></td>
  279. </tr>
  280. <tr>
  281. <td><p><b>' . get_lang('Priority') . ': </b>' . $ticket['ticket']['priority'] . '<p></td>
  282. </tr>';
  283. if (!empty($ticket['ticket']['assigned_last_user'])) {
  284. $assignedUser = api_get_user_info($ticket['ticket']['assigned_last_user']);
  285. echo '<tr>
  286. <td><p><b>' . get_lang('AssignedTo') . ': </b>' . $assignedUser['complete_name'] . '<p></td>
  287. </tr>';
  288. } else {
  289. echo '<tr>
  290. <td><p><b>' . get_lang('AssignedTo') . ': </b>-<p></td>
  291. </tr>';
  292. }
  293. if ($ticket['ticket']['course_url'] != null) {
  294. if (!empty($ticket['ticket']['session_id'])) {
  295. $sessionInfo = api_get_session_info($ticket['ticket']['session_id']);
  296. echo '<tr>
  297. <td><b>' . get_lang('Session') . ':</b> ' . $sessionInfo['name'] . ' </td>
  298. <td></td>
  299. <td colspan="2"></td>
  300. </tr>';
  301. }
  302. echo '<tr>
  303. <td><b>' . get_lang('Course') . ':</b> ' . $ticket['ticket']['course_url'] . ' </td>
  304. <td></td>
  305. <td colspan="2"></td>
  306. </tr>';
  307. }
  308. echo '<tr>
  309. <td>
  310. <hr />
  311. <b>' . get_lang('Description') . ':</b> <br />
  312. '.$ticket['ticket']['message'].'
  313. <hr />
  314. </td>
  315. </tr>
  316. ';
  317. echo '</table>';
  318. $messages = $ticket['messages'];
  319. $logs = TicketManager::get_assign_log($ticket_id);
  320. $counter = 1;
  321. foreach ($messages as $message) {
  322. $date = Display::url(
  323. date_to_str_ago($message['sys_insert_datetime']),
  324. '#',
  325. ['title' => api_get_local_time($message['sys_insert_datetime']), 'class' => 'boot-tooltip']
  326. );
  327. $receivedMessage = '';
  328. if (!empty($message['subject'])) {
  329. $receivedMessage = '<b>'.get_lang('Subject') . ': </b> '.$message['subject'].'<br/>';
  330. }
  331. $receivedMessage = '<b>'.get_lang('Message') . ':</b><br/>'.$message['message'].'<br/>';
  332. $attachmentLinks = '';
  333. if (isset($message['attachments'])) {
  334. $attributeClass = array(
  335. 'class' => 'attachment-link'
  336. );
  337. foreach ($message['attachments'] as $attach) {
  338. $attachmentLinks .= Display::tag('div', $attach['attachment_link'], $attributeClass);
  339. }
  340. }
  341. $entireMessage = $receivedMessage . $attachmentLinks;
  342. $counterLink = Display::url('#'.$counter, api_get_self().'?ticket_id='.$ticket_id.'#note-'.$counter);
  343. echo '<a id="note-'.$counter.'"> </a><h4>' . sprintf(get_lang('UpdatedByX'), $message['user_created']).' '.$date.
  344. ' <span class="pull-right">'.$counterLink.'</span></h4>';
  345. echo Display::div(
  346. $entireMessage,
  347. ['class' => 'well']
  348. );
  349. $counter++;
  350. }
  351. $subject = get_lang('ReplyShort') .': '.$ticket['ticket']['subject'];
  352. if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
  353. $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE
  354. ) {
  355. if (!$isAdmin && $ticket['ticket']['status_id'] != TicketManager::STATUS_UNCONFIRMED) {
  356. show_form_send_message($ticket['ticket']);
  357. } else {
  358. if (
  359. $ticket['ticket']['assigned_last_user'] == $user_id ||
  360. $ticket['ticket']['sys_insert_user_id'] == $user_id ||
  361. $isAdmin
  362. ) {
  363. show_form_send_message($ticket['ticket']);
  364. }
  365. }
  366. }
  367. Display::display_footer();
  368. } else {
  369. $ticket_id = $_POST['ticket_id'];
  370. $content = $_POST['content'];
  371. $subject = $_POST['subject'];
  372. $message = isset($_POST['confirmation']) ? true : false;
  373. $file_attachments = $_FILES;
  374. $user_id = api_get_user_id();
  375. TicketManager::insert_message(
  376. $ticket_id,
  377. $subject,
  378. $content,
  379. $file_attachments,
  380. $user_id,
  381. 'NOL',
  382. $message
  383. );
  384. if ($isAdmin) {
  385. TicketManager::updateTicket(
  386. [
  387. 'priority_id' => $_POST['priority_id'],
  388. 'status_id' => $_POST['status_id']
  389. ],
  390. $ticket_id,
  391. api_get_user_id()
  392. );
  393. if (isset($_POST['assigned_last_user']) && !empty($_POST['assigned_last_user'])) {
  394. TicketManager::assign_ticket_user($ticket_id, $_POST['assigned_last_user']);
  395. }
  396. }
  397. Display::addFlash(Display::return_message(get_lang('Saved')));
  398. header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
  399. exit;
  400. }
  401. /**
  402. * @param array $ticket
  403. */
  404. function show_form_send_message($ticket)
  405. {
  406. global $isAdmin;
  407. global $subject;
  408. $form = new FormValidator(
  409. 'send_ticket',
  410. 'POST',
  411. api_get_self() . '?ticket_id=' . $ticket['id'],
  412. '',
  413. array(
  414. 'enctype' => 'multipart/form-data',
  415. 'onsubmit' => 'return validate()',
  416. 'class' => 'form-horizontal'
  417. )
  418. );
  419. if ($isAdmin) {
  420. $statusList = TicketManager::getStatusList();
  421. $form->addElement(
  422. 'select',
  423. 'status_id',
  424. get_lang('Status'),
  425. $statusList
  426. );
  427. $priorityList = TicketManager::getPriorityList();
  428. $form->addElement(
  429. 'select',
  430. 'priority_id',
  431. get_lang('Priority'),
  432. $priorityList,
  433. array(
  434. 'id' => 'priority_id',
  435. 'for' => 'priority_id'
  436. )
  437. );
  438. $admins = UserManager::get_user_list_like(
  439. array('status' => COURSEMANAGER), array('username'),
  440. true
  441. );
  442. $adminList = ['' => get_lang('Select')];
  443. foreach ($admins as $admin) {
  444. $adminList[$admin['user_id']] = $admin['complete_name'];
  445. }
  446. $form->addElement(
  447. 'select',
  448. 'assigned_last_user',
  449. get_lang('Assign'),
  450. $adminList,
  451. array(
  452. 'id' => 'assigned_last_user',
  453. 'for' => 'assigned_last_user'
  454. )
  455. );
  456. $form->setDefaults(
  457. [
  458. 'priority_id' => $ticket['priority_id'],
  459. 'status_id' => $ticket['status_id'],
  460. 'assigned_last_user' => $ticket['assigned_last_user']
  461. ]
  462. );
  463. }
  464. $form->addElement(
  465. 'text',
  466. 'subject',
  467. get_lang('Subject'),
  468. array(
  469. 'for' => 'subject',
  470. 'value' => $subject,
  471. 'style' => 'width: 540px;'
  472. )
  473. );
  474. $form->addElement('hidden', 'ticket_id', $ticket['id']);
  475. $form->addHtmlEditor(
  476. 'content',
  477. get_lang('Message'),
  478. false,
  479. false,
  480. array(
  481. 'ToolbarSet' => 'Profile',
  482. 'Width' => '550',
  483. 'Height' => '250'
  484. )
  485. );
  486. if ($isAdmin) {
  487. $form->addElement(
  488. 'checkbox',
  489. 'confirmation',
  490. null,
  491. get_lang('RequestConfirmation')
  492. );
  493. }
  494. $form->addElement('file', 'attach_1', get_lang('FilesAttachment'));
  495. $form->addLabel('', '<span id="filepaths"><div id="filepath_1"></div></span>');
  496. $form->addLabel('',
  497. '<span id="link-more-attach">
  498. <span class="btn btn-success" onclick="return add_image_form()">' . get_lang('AddOneMoreFile') . '</span>
  499. </span>
  500. ('.sprintf(get_lang('MaximunFileSizeX'), format_file_size(api_get_setting('message_max_upload_filesize'))).')
  501. ');
  502. $form->addElement('html', '<br/>');
  503. $form->addElement(
  504. 'button',
  505. 'compose',
  506. get_lang('SendMessage'),
  507. null,
  508. null,
  509. null,
  510. 'btn btn-primary'
  511. );
  512. $form->display();
  513. }