ticket_details.php 17 KB

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