Bootswatch, Summernote, and Captcheck mods for Mods for HESK (mods-for-hesk.com). In use at support.netsyms.com.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

ticket.php 34KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. <?php
  2. /**
  3. *
  4. * This file is part of HESK - PHP Help Desk Software.
  5. *
  6. * (c) Copyright Klemen Stirn. All rights reserved.
  7. * https://www.hesk.com
  8. *
  9. * For the full copyright and license agreement information visit
  10. * https://www.hesk.com/eula.php
  11. *
  12. */
  13. define('IN_SCRIPT', 1);
  14. define('HESK_PATH', './');
  15. define('HESK_NO_ROBOTS', 1);
  16. define('WYSIWYG', 1);
  17. define('VALIDATOR', 1);
  18. define('PAGE_TITLE', 'CUSTOMER_TICKET');
  19. /* Get all the required files and functions */
  20. require(HESK_PATH . 'hesk_settings.inc.php');
  21. require(HESK_PATH . 'inc/common.inc.php');
  22. require(HESK_PATH . 'inc/view_attachment_functions.inc.php');
  23. hesk_load_database_functions();
  24. /* Connect to database */
  25. hesk_dbConnect();
  26. // Are we in maintenance mode?
  27. hesk_check_maintenance();
  28. hesk_session_start();
  29. $modsForHesk_settings = mfh_getSettings();
  30. $hesk_error_buffer = array();
  31. $do_remember = '';
  32. $display = 'none';
  33. /* A message from ticket reminder? */
  34. if ( ! empty($_GET['remind']) )
  35. {
  36. $display = 'block';
  37. print_form();
  38. }
  39. // Do we have parameters in query string? If yes, store them in session and redirect
  40. if ( isset($_GET['track']) || isset($_GET['e']) || isset($_GET['f']) || isset($_GET['r']) )
  41. {
  42. $_SESSION['t_track'] = hesk_GET('track');
  43. $_SESSION['t_email'] = hesk_getCustomerEmail(1);
  44. $_SESSION['t_form'] = hesk_GET('f');
  45. $_SESSION['t_remember'] = strlen($do_remember) ? 'Y' : hesk_GET('r');
  46. header('Location: ticket.php');
  47. die();
  48. }
  49. /* Was this accessed by the form or link? */
  50. $is_form = hesk_SESSION('t_form');
  51. /* Get the tracking ID */
  52. $trackingID = hesk_cleanID('', hesk_SESSION('t_track'));
  53. /* Email required to view ticket? */
  54. $my_email = hesk_getCustomerEmail(1, 't_email', 1);
  55. /* Remember email address? */
  56. $do_remember = strlen($do_remember) || strlen(hesk_SESSION('t_remember')) ? ' checked="checked" ' : '';
  57. /* Clean ticket parameters from the session data, we don't need them anymore */
  58. hesk_cleanSessionVars( array('t_track', 't_email', 't_form', 't_remember') );
  59. /* Any errors? Show the form */
  60. if ($is_form) {
  61. if (empty($trackingID)) {
  62. $hesk_error_buffer[] = $hesklang['eytid'];
  63. }
  64. if ($hesk_settings['email_view_ticket'] && empty($my_email)) {
  65. $hesk_error_buffer[] = $hesklang['enter_valid_email'];
  66. }
  67. $tmp = count($hesk_error_buffer);
  68. if ($tmp == 1) {
  69. $hesk_error_buffer = implode('', $hesk_error_buffer);
  70. hesk_process_messages($hesk_error_buffer, 'NOREDIRECT');
  71. print_form();
  72. } elseif ($tmp == 2) {
  73. $hesk_error_buffer = $hesklang['pcer'] . '<br /><br /><ul><li>' . $hesk_error_buffer[0] . '</li><li>' . $hesk_error_buffer[1] . '</li></ul>';
  74. hesk_process_messages($hesk_error_buffer, 'NOREDIRECT');
  75. print_form();
  76. }
  77. } elseif (empty($trackingID) || ($hesk_settings['email_view_ticket'] && empty($my_email))) {
  78. print_form();
  79. }
  80. /* Limit brute force attempts */
  81. hesk_limitBfAttempts();
  82. require_once(HESK_PATH . 'inc/custom_fields.inc.php');
  83. /* Get ticket info */
  84. $res = hesk_dbQuery("SELECT `t1`.* , `t2`.name AS `repliername`, `ticketStatus`.`IsClosed` AS `isClosed`, `ticketStatus`.`Key` AS `statusKey` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` AS `t1` INNER JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` AS `ticketStatus` ON `t1`.`status` = `ticketStatus`.`ID` LEFT JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` AS `t2` ON `t1`.`replierid` = `t2`.`id` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1");
  85. /* Ticket found? */
  86. if (hesk_dbNumRows($res) != 1) {
  87. /* Ticket not found, perhaps it was merged with another ticket? */
  88. $res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `merged` LIKE '%#" . hesk_dbEscape($trackingID) . "#%' LIMIT 1");
  89. if (hesk_dbNumRows($res) == 1) {
  90. /* OK, found in a merged ticket. Get info */
  91. $ticket = hesk_dbFetchAssoc($res);
  92. /* If we require e-mail to view tickets check if it matches the one from merged ticket */
  93. if (hesk_verifyEmailMatch($ticket['trackid'], $my_email, $ticket['email'], 0)) {
  94. hesk_process_messages(sprintf($hesklang['tme'], $trackingID, $ticket['trackid']), 'NOREDIRECT', 'NOTICE');
  95. $trackingID = $ticket['trackid'];
  96. } else {
  97. hesk_process_messages(sprintf($hesklang['tme1'], $trackingID, $ticket['trackid']) . '<br /><br />' . sprintf($hesklang['tme2'], $ticket['trackid']), 'NOREDIRECT', 'NOTICE');
  98. $trackingID = $ticket['trackid'];
  99. print_form();
  100. }
  101. } else {
  102. /* Nothing found, error out */
  103. hesk_process_messages($hesklang['ticket_not_found'], 'NOREDIRECT');
  104. print_form();
  105. }
  106. } else {
  107. /* We have a match, get ticket info */
  108. $ticket = hesk_dbFetchAssoc($res);
  109. /* If we require e-mail to view tickets check if it matches the one in database */
  110. hesk_verifyEmailMatch($trackingID, $my_email, $ticket['email']);
  111. }
  112. /* Ticket exists, clean brute force attempts */
  113. hesk_cleanBfAttempts();
  114. /* Remember email address? */
  115. if ($is_form) {
  116. if ( strlen($do_remember) ) {
  117. hesk_setcookie('hesk_myemail', $my_email, strtotime('+1 year'));
  118. } elseif (isset($_COOKIE['hesk_myemail'])) {
  119. hesk_setcookie('hesk_myemail', '');
  120. }
  121. }
  122. /* Set last replier name */
  123. if ($ticket['lastreplier']) {
  124. if (empty($ticket['repliername'])) {
  125. $ticket['repliername'] = $hesklang['staff'];
  126. }
  127. } else {
  128. $ticket['repliername'] = $ticket['name'];
  129. }
  130. // If IP is unknown (tickets via email pipe/pop3 fetching) assume current visitor IP as customer IP
  131. if ($ticket['ip'] == '' || $ticket['ip'] == 'Unknown' || $ticket['ip'] == $hesklang['unknown']) {
  132. hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `ip` = '".hesk_dbEscape(hesk_getClientIP())."' WHERE `id`=".intval($ticket['id']));
  133. }
  134. /* Get category name and ID */
  135. $result = hesk_dbQuery("SELECT `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE `id`='" . intval($ticket['category']) . "' LIMIT 1");
  136. /* If this category has been deleted use the default category with ID 1 */
  137. if (hesk_dbNumRows($result) != 1) {
  138. $result = hesk_dbQuery("SELECT `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE `id`='1' LIMIT 1");
  139. }
  140. $category = hesk_dbFetchAssoc($result);
  141. /* Get replies */
  142. $result = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`='" . intval($ticket['id']) . "' ORDER BY `id` " . ($hesk_settings['new_top'] ? 'DESC' : 'ASC'));
  143. $replies = hesk_dbNumRows($result);
  144. $unread_replies = array();
  145. // Demo mode
  146. if (defined('HESK_DEMO')) {
  147. $ticket['email'] = 'hidden@demo.com';
  148. }
  149. /* Print header */
  150. require_once(HESK_PATH . 'inc/header.inc.php');
  151. ?>
  152. <ol class="breadcrumb">
  153. <li><a href="<?php echo $hesk_settings['site_url']; ?>"><?php echo $hesk_settings['site_title']; ?></a></li>
  154. <li><a href="<?php echo $hesk_settings['hesk_url']; ?>"><?php echo $hesk_settings['hesk_title']; ?></a></li>
  155. <li><a href="ticket.php"><?php echo $hesklang['view_ticket_nav']; ?></a></li>
  156. <li class="active"><?php hesk_showTopBar($hesklang['cid'] . ': ' . $trackingID); ?></li>
  157. </ol>
  158. <?php
  159. $columnWidth = 'col-md-8';
  160. $showRs = hesk_dbQuery("SELECT `show` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` WHERE `id` = 3");
  161. $show = hesk_dbFetchAssoc($showRs);
  162. if (!$show['show']) {
  163. $columnWidth = 'col-md-10 col-md-offset-1';
  164. }
  165. ?>
  166. <div class="row">
  167. <?php if ($columnWidth == 'col-md-8'): ?>
  168. <div align="left" class="col-md-4">
  169. <div class="panel panel-default">
  170. <div class="panel-heading"><?php echo $hesklang['quick_help']; ?></div>
  171. <div class="panel-body">
  172. <p><?php echo $hesklang['quick_help_ticket']; ?></p>
  173. </div>
  174. </div>
  175. </div>
  176. <?php endif; ?>
  177. <div class="<?php echo $columnWidth; ?>">
  178. <?php
  179. // Service messages
  180. $service_messages = mfh_get_service_messages('CUSTOMER_VIEW_TICKET');
  181. foreach ($service_messages as $sm) {
  182. hesk_service_message($sm);
  183. }
  184. /* This will handle error, success and notice messages */
  185. hesk_handle_messages();
  186. /*
  187. * If the ticket has been reopened by customer:
  188. * - show the "Add a reply" form on top
  189. * - and ask them why the form has been reopened
  190. */
  191. if (isset($_SESSION['force_form_top'])) {
  192. hesk_printCustomerReplyForm(1);
  193. echo ' <p>&nbsp;</p> ';
  194. unset($_SESSION['force_form_top']);
  195. }
  196. ?>
  197. <h3 align="left"><?php echo $hesklang['view_ticket']; ?>: <?php
  198. if ($hesk_settings['sequential']) {
  199. echo $trackingID . ' (' . $hesklang['seqid'] . ': ' . $ticket['id'] . ')';
  200. } else {
  201. echo $trackingID;
  202. }
  203. ?></h3>
  204. <div class="footerWithBorder"></div>
  205. <div class="blankSpace"></div>
  206. <div class="table-bordered">
  207. <div class="row">
  208. <div class="col-md-10">
  209. <h2><?php echo $ticket['subject']; ?></h2>
  210. </div>
  211. <div class="col-md-2 pull-right pad-down-20">
  212. <a href="ticket.php?track=<?php echo $trackingID.$hesk_settings['e_query']; ?>">
  213. <i class="fa fa-refresh"></i>
  214. <?php echo $hesklang['refresh_page']; ?>
  215. </a>
  216. </div>
  217. </div>
  218. <div class="row">
  219. <div class="col-md-3 col-sm-12">
  220. <p><?php echo $hesklang['created_on']; ?>: <?php echo hesk_date($ticket['dt'], true); ?></p>
  221. </div>
  222. <div class="col-md-3 col-sm-12">
  223. <p><?php echo $hesklang['last_update']; ?>
  224. : <?php echo hesk_date($ticket['lastchange'], true); ?></p>
  225. </div>
  226. <div class="col-md-2 col-md-offset-4 col-sm-12 close-ticket">
  227. <p><?php
  228. $statusRS = hesk_dbQuery('SELECT * FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `ID` = ' . intval($ticket['status']));
  229. $status = hesk_dbFetchAssoc($statusRS);
  230. $isClosable = $status['Closable'] == 'yes' || $status['Closable'] == 'conly';
  231. $random = rand(10000, 99999);
  232. if (!$ticket['locked']) {
  233. if ($ticket['isClosed'] == true && $hesk_settings['custopen']) {
  234. echo '<a href="change_status.php?track=' . $trackingID . $hesk_settings['e_query'] . '&amp;s=2&amp;Refresh=' . $random . '&amp;token=' . hesk_token_echo(0) . '" title="' . $hesklang['open_action'] . '">' . $hesklang['open_action'] . '</a>';
  235. } elseif ($hesk_settings['custclose'] && $isClosable) {
  236. echo '<a href="change_status.php?track=' . $trackingID . $hesk_settings['e_query'] . '&amp;s=3&amp;Refresh=' . $random . '&amp;token=' . hesk_token_echo(0) . '" title="' . $hesklang['close_action'] . '">' . $hesklang['close_action'] . '</a>';
  237. }
  238. }
  239. ?>
  240. </p>
  241. </div>
  242. </div>
  243. <div class="row medLowPriority">
  244. <?php //This entire conditional is all just for priority
  245. if ($hesk_settings['cust_urgency']) {
  246. $repliesColumnWidth = 2;
  247. echo '<div class="col-md-2 col-sm-12 ticket-cell ';
  248. if ($ticket['priority'] == 0) {
  249. echo 'critical-priority">';
  250. } elseif ($ticket['priority'] == 1) {
  251. echo 'highPriority">';
  252. } elseif ($ticket['priority'] == 2) {
  253. echo 'medLowPriority">';
  254. } else {
  255. echo 'lowPriority">';
  256. }
  257. echo '<p class="ticketPropertyTitle">' . $hesklang['priority'] . '</p>';
  258. if ($ticket['priority'] == 0) {
  259. echo '<p class="ticketPropertyText">' . $hesklang['critical'] . '</p>';
  260. } elseif ($ticket['priority'] == 1) {
  261. echo '<p class="ticketPropertyText">' . $hesklang['high'] . '</p>';
  262. } elseif ($ticket['priority'] == 2) {
  263. echo '<p class="ticketPropertyText">' . $hesklang['medium'] . '</p>';
  264. } else {
  265. echo '<p class="ticketPropertyText">' . $hesklang['low'] . '</p>';
  266. }
  267. echo '</div>';
  268. } else {
  269. $repliesColumnWidth = 3;
  270. }
  271. echo '<div class="col-md-3 col-sm-12 ticket-cell"><p class="ticketPropertyTitle">' . $hesklang['status'] . '</p>';
  272. echo '<p class="ticketPropertyText">' . mfh_getDisplayTextForStatusId($status['ID']) . '</p>';
  273. echo '</div>';
  274. echo '<div class="col-md-3 col-sm-12 ticket-cell"><p class="ticketPropertyTitle">' . $hesklang['last_replier'] . '</p>
  275. <p class="ticketPropertyText">' . $ticket['repliername'] . '</p></div>';
  276. echo '<div class="col-md-' . $repliesColumnWidth . ' col-sm-12 ticket-cell"><p class="ticketPropertyTitle">' . $hesklang['category'] . '</p>
  277. <p class="ticketPropertyText">' . $category['name'] . '</p></div>';
  278. echo '<div class="col-md-' . $repliesColumnWidth . ' col-sm-12 ticket-cell"><p class="ticketPropertyTitle">' . $hesklang['replies'] . '</p>
  279. <p class="ticketPropertyText">' . $replies . '</p></div>';
  280. ?>
  281. </div>
  282. </div>
  283. <div class="blankSpace"></div>
  284. <!-- REPLIES -->
  285. <?php
  286. // Print "Submit a reply" form?
  287. if ($ticket['locked'] != 1 && $ticket['status'] != 3 && $hesk_settings['reply_top'] == 1) {
  288. hesk_printCustomerReplyForm();
  289. }
  290. if ($hesk_settings['new_top']) {
  291. $i = hesk_printCustomerTicketReplies() ? 0 : 1;
  292. } else {
  293. $i = 1;
  294. }
  295. /* Make sure original message is in correct color if newest are on top */
  296. $color = 'class="ticketMessageContainer"';
  297. ?>
  298. <div class="row ticketMessageContainer">
  299. <div class="col-md-3 col-xs-12">
  300. <div class="ticketName"><?php echo $ticket['name']; ?></div>
  301. <?php if ($ticket['email'] != '') { ?>
  302. <div class="ticketEmail"><a href="mailto:<?php echo $ticket['email']; ?>"><?php echo $ticket['email']; ?></a></div>
  303. <?php } ?>
  304. </div>
  305. <div class="col-md-9 col-xs-12 pushMarginLeft">
  306. <div class="ticketMessageTop withBorder">
  307. <!-- Date and Action buttons -->
  308. <p><?php echo $hesklang['date']; ?>: <?php echo hesk_date($ticket['dt'], true); ?><span
  309. class="nu-floatRight"><?php echo hesk_getCustomerButtons($i); ?></span></p>
  310. <!-- Custom Fields Before Message -->
  311. <?php
  312. foreach ($hesk_settings['custom_fields'] as $k => $v) {
  313. if ($v['use'] == 1 && $v['place'] == 0 && hesk_is_custom_field_in_category($k, $ticket['category'])) {
  314. echo '<p>' . $v['name'] . ': ';
  315. switch ($v['type'])
  316. {
  317. case 'email':
  318. $ticket[$k] = '<a href="mailto:'.$ticket[$k].'">'.$ticket[$k].'</a>';
  319. break;
  320. case 'date':
  321. $ticket[$k] = hesk_custom_date_display_format($ticket[$k], $v['value']['date_format']);
  322. break;
  323. }
  324. echo $ticket[$k].'</p>';
  325. }
  326. }
  327. ?>
  328. </div>
  329. <div class="ticketMessageBottom">
  330. <?php if ($ticket['message'] != '') { ?>
  331. <!-- Message -->
  332. <p><b><?php echo $hesklang['message']; ?>:</b></p>
  333. <div class="message">
  334. <?php if ($ticket['html']) {
  335. echo hesk_html_entity_decode($ticket['message']);
  336. } else {
  337. echo $ticket['message'];
  338. }
  339. ?>
  340. </div>
  341. <?php } ?>
  342. </div>
  343. <div class="ticketMessageTop">
  344. <!-- Custom Fields after Message -->
  345. <?php
  346. foreach ($hesk_settings['custom_fields'] as $k => $v) {
  347. if ($v['use'] == 1 && $v['place'] && hesk_is_custom_field_in_category($k, $ticket['category'])) {
  348. echo '<p>' . $v['name'] . ': ';
  349. switch ($v['type'])
  350. {
  351. case 'email':
  352. $ticket[$k] = '<a href="mailto:'.$ticket[$k].'">'.$ticket[$k].'</a>';
  353. break;
  354. case 'date':
  355. $ticket[$k] = hesk_custom_date_display_format($ticket[$k], $v['value']['date_format']);
  356. break;
  357. }
  358. echo $ticket[$k].'</p>';
  359. }
  360. }
  361. /* Attachments */
  362. mfh_listAttachments($ticket['attachments'], $i, false);
  363. ?>
  364. </div>
  365. </div>
  366. </div>
  367. <?php
  368. if (!$hesk_settings['new_top']) {
  369. hesk_printCustomerTicketReplies();
  370. }
  371. ?>
  372. <!-- END REPLIES -->
  373. <?php
  374. /* Print "Submit a reply" form? */
  375. if ($ticket['locked'] != 1 && $ticket['status'] != 3 && !$hesk_settings['reply_top']) {
  376. hesk_printCustomerReplyForm();
  377. }
  378. /* If needed update unread replies as read for staff to know */
  379. if (count($unread_replies)) {
  380. hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` SET `read` = '1' WHERE `id` IN ('" . implode("','", $unread_replies) . "')");
  381. }
  382. ?>
  383. </div>
  384. <!-- End col-md-7 -->
  385. </div> <!-- End row -->
  386. <?php
  387. /* Clear unneeded session variables */
  388. hesk_cleanSessionVars('ticket_message');
  389. require_once(HESK_PATH . 'inc/footer.inc.php');
  390. /*** START FUNCTIONS ***/
  391. function print_form()
  392. {
  393. global $hesk_settings, $hesklang;
  394. global $hesk_error_buffer, $my_email, $trackingID, $do_remember, $display;
  395. /* Print header */
  396. $hesk_settings['tmp_title'] = $hesk_settings['hesk_title'] . ' - ' . $hesklang['view_ticket'];
  397. require_once(HESK_PATH . 'inc/header.inc.php');
  398. ?>
  399. <ol class="breadcrumb">
  400. <li><a href="<?php echo $hesk_settings['site_url']; ?>"><?php echo $hesk_settings['site_title']; ?></a></li>
  401. <li><a href="<?php echo $hesk_settings['hesk_url']; ?>"><?php echo $hesk_settings['hesk_title']; ?></a></li>
  402. <li class="active"><?php echo $hesklang['view_ticket_nav']; ?></li>
  403. </ol>
  404. <?php
  405. hesk_dbConnect();
  406. $columnWidth = 'col-md-8';
  407. $showRs = hesk_dbQuery("SELECT `show` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` WHERE `id` = 2");
  408. $show = hesk_dbFetchAssoc($showRs);
  409. if (!$show['show']) {
  410. $columnWidth = 'col-md-10 col-md-offset-1';
  411. }
  412. ?>
  413. <div class="row">
  414. <?php if ($columnWidth == 'col-md-8'): ?>
  415. <div align="left" class="col-md-4">
  416. <div class="panel panel-default">
  417. <div class="panel-heading">
  418. <?php echo $hesklang['quick_help']; ?>
  419. </div>
  420. <div class="panel-body">
  421. <p><?php echo $hesklang['quick_help_view_ticket']; ?></p>
  422. </div>
  423. </div>
  424. </div>
  425. <?php endif; ?>
  426. <div class="<?php echo $columnWidth; ?>">
  427. <?php
  428. // Service messages
  429. $service_messages = mfh_get_service_messages('CUSTOMER_VIEW_TICKET');
  430. foreach ($service_messages as $sm) {
  431. hesk_service_message($sm);
  432. }
  433. /* This will handle error, success and notice messages */
  434. hesk_handle_messages();
  435. ?>
  436. <h3 align="left"><?php echo $hesklang['view_existing']; ?></h3>
  437. <div class="footerWithBorder"></div>
  438. <div class="blankSpace"></div>
  439. <form data-toggle="validator" action="ticket.php" class="form-horizontal" role="form" method="get" name="form2">
  440. <div class="form-group">
  441. <label for="track" class="col-sm-3 control-label"><?php echo $hesklang['ticket_trackID']; ?></label>
  442. <div class="col-sm-9">
  443. <input type="text" class="form-control" name="track" id="track" maxlength="20" size="35"
  444. value="<?php echo $trackingID; ?>"
  445. placeholder="<?php echo htmlspecialchars($hesklang['ticket_trackID']); ?>"
  446. data-error="<?php echo htmlspecialchars($hesklang['eytid']); ?>" required>
  447. <div class="help-block with-errors"></div>
  448. </div>
  449. </div>
  450. <?php
  451. $tmp = '';
  452. if ($hesk_settings['email_view_ticket']) {
  453. $tmp = 'document.form1.email.value=document.form2.e.value;';
  454. ?>
  455. <div class="form-group">
  456. <label for="e" class="col-sm-3 control-label"><?php echo $hesklang['email']; ?></label>
  457. <div class="col-sm-9">
  458. <input type="text" class="form-control" id="e" name="e" size="35"
  459. value="<?php echo $my_email; ?>"
  460. placeholder="<?php echo htmlspecialchars($hesklang['email']); ?>"
  461. data-error="<?php echo htmlspecialchars($hesklang['enter_valid_email']); ?>" required>
  462. <div class="help-block with-errors"></div>
  463. </div>
  464. </div>
  465. <div align="left" class="form-group">
  466. <div class="col-sm-offset-3 col-sm-9">
  467. <div class="checkbox">
  468. <label>
  469. <input type="checkbox" name="r"
  470. value="Y" <?php echo $do_remember; ?> /> <?php echo $hesklang['rem_email']; ?>
  471. </label>
  472. </div>
  473. </div>
  474. </div>
  475. <?php } ?>
  476. <div align="left" class="form-group">
  477. <div class="col-sm-offset-3 col-sm-9">
  478. <button type="submit" class="btn btn-default"
  479. value="<?php echo $hesklang['view_ticket']; ?>"><?php echo $hesklang['view_ticket']; ?></button>
  480. <input type="hidden" name="Refresh" value="<?php echo rand(10000, 99999); ?>"><input
  481. type="hidden" name="f" value="1">
  482. <div class="blankSpace"></div>
  483. <a href="Javascript:void(0)"
  484. onclick="javascript:hesk_toggleLayerDisplay('forgot');<?php echo $tmp; ?>"><?php echo $hesklang['forgot_tid']; ?></a>
  485. </div>
  486. </div>
  487. </form>
  488. <div align="left" id="forgot" class="panel panel-info" style="display: <?php echo $display; ?>;">
  489. <div class="panel-heading">
  490. <?php echo $hesklang['tid_mail']; ?>
  491. </div>
  492. <div class="panel-body">
  493. <form data-toggle="validator" action="index.php" method="post" class="form-horizontal" name="form1">
  494. <div class="form-group">
  495. <label for="email" class="col-sm-3 control-label"><?php echo $hesklang['email']; ?></label>
  496. <div class="col-sm-9">
  497. <input type="text" id="email" class="form-control" name="email" size="35"
  498. value="<?php echo $my_email; ?>"
  499. placeholder="<?php echo htmlspecialchars($hesklang['email']); ?>"
  500. data-error="<?php echo htmlspecialchars($hesklang['enter_valid_email']); ?>" required>
  501. <div class="help-block with-errors"></div>
  502. <input type="hidden" name="a" value="forgot_tid"/>
  503. </div>
  504. </div>
  505. <div class="form-group">
  506. <div class="col-sm-9 col-sm-offset-3">
  507. <div class="radio">
  508. <label>
  509. <input type="radio" name="open_only"
  510. value="1" <?php echo $hesk_settings['open_only'] ? 'checked="checked"' : ''; ?> /><?php echo $hesklang['oon1']; ?>
  511. </label>
  512. </div>
  513. <div class="radio">
  514. <label>
  515. <input type="radio" name="open_only"
  516. value="0" <?php echo !$hesk_settings['open_only'] ? 'checked="checked"' : ''; ?> /><?php echo $hesklang['oon2']; ?>
  517. </label>
  518. </div>
  519. </div>
  520. </div>
  521. <div class="form-group">
  522. <div class="col-sm-offset-3 col-sm-9">
  523. <button type="submit" class="btn btn-default"
  524. value="<?php echo $hesklang['tid_send']; ?>"><?php echo $hesklang['tid_send']; ?></button>
  525. </div>
  526. </div>
  527. </form>
  528. </div>
  529. </div>
  530. </div>
  531. </div>
  532. <?php
  533. require_once(HESK_PATH . 'inc/footer.inc.php');
  534. exit();
  535. } // End print_form()
  536. function hesk_printCustomerReplyForm($reopen = 0)
  537. {
  538. global $hesklang, $hesk_settings, $trackingID, $my_email, $modsForHesk_settings;
  539. // Already printed?
  540. if (defined('REPLY_FORM')) {
  541. return '';
  542. }
  543. ?>
  544. <h3 class="text-left"><?php echo $hesklang['add_reply']; ?></h3>
  545. <div class="footerWithBorder"></div>
  546. <div class="blankSpace"></div>
  547. <?php
  548. $onsubmit = '';
  549. if ($modsForHesk_settings['rich_text_for_tickets_for_customers']) {
  550. $onsubmit = 'onclick="return validateRichText(\'message-help-block\', \'message-group\', \'message\', \''.htmlspecialchars($hesklang['this_field_is_required']).'\')"';
  551. }
  552. ?>
  553. <form data-toggle="validator" role="form" class="form-horizontal" method="post" action="reply_ticket.php"
  554. enctype="multipart/form-data" <?php echo $onsubmit; ?>>
  555. <div class="form-group" id="message-group">
  556. <label for="message" class="col-sm-3 control-label"><?php echo $hesklang['message']; ?>: <span
  557. class="important">*</span></label>
  558. <div class="col-sm-9">
  559. <textarea name="message" class="form-control htmlEditor" rows="12"
  560. cols="60" data-error="<?php echo htmlspecialchars($hesklang['enter_message']); ?>" required><?php if (isset($_SESSION['ticket_message'])) {
  561. echo stripslashes(hesk_input($_SESSION['ticket_message']));
  562. } ?></textarea>
  563. <div class="help-block with-errors" id="message-help-block"></div>
  564. <?php if ($modsForHesk_settings['rich_text_for_tickets_for_customers']): ?>
  565. <script type="text/javascript">
  566. /* <![CDATA[ */
  567. $(document).ready(function() {
  568. $('.htmlEditor').summernote({
  569. height: 200,
  570. toolbar: [
  571. ['style', ['bold', 'italic', 'underline', 'clear']],
  572. ['font', ['strikethrough', 'superscript', 'subscript']],
  573. ['para', ['ul', 'ol']]
  574. ]
  575. });
  576. });
  577. /* ]]> */
  578. </script>
  579. <?php endif; ?>
  580. </div>
  581. </div>
  582. <?php
  583. /* attachments */
  584. if ($hesk_settings['attachments']['use']) {
  585. ?>
  586. <div class="form-group">
  587. <label for="attachments" class="col-sm-3 control-label"><?php echo $hesklang['attachments']; ?>
  588. :</label>
  589. <div align="left" class="col-sm-9">
  590. <?php build_dropzone_markup(); ?>
  591. </div>
  592. </div>
  593. <?php
  594. display_dropzone_field(HESK_PATH . 'internal-api/ticket/upload-attachment.php');
  595. }
  596. ?>
  597. <input type="hidden" name="token" value="<?php hesk_token_echo(); ?>"/>
  598. <input type="hidden" name="orig_track" value="<?php echo $trackingID; ?>"/>
  599. <?php
  600. if ($hesk_settings['email_view_ticket']) {
  601. echo '<input type="hidden" name="e" value="' . $my_email . '" />';
  602. }
  603. if ($reopen) {
  604. echo '<input type="hidden" name="reopen" value="1" />';
  605. }
  606. ?>
  607. <div class="form-group">
  608. <div class="col-sm-9 col-sm-offset-3">
  609. <input type="submit" value="<?php echo $hesklang['submit_reply']; ?>" class="btn btn-default">
  610. </div>
  611. </div>
  612. </form>
  613. <?php
  614. // Make sure the form is only printed once per page
  615. define('REPLY_FORM', true);
  616. } // End hesk_printCustomerReplyForm()
  617. function hesk_printCustomerTicketReplies()
  618. {
  619. global $hesklang, $hesk_settings, $result, $reply, $trackingID, $unread_replies;
  620. $i = $hesk_settings['new_top'] ? 0 : 1;
  621. while ($reply = hesk_dbFetchAssoc($result)) {
  622. $color = 'class="ticketMessageContainer"';
  623. /* Store unread reply IDs for later */
  624. if ($reply['staffid'] && !$reply['read']) {
  625. $unread_replies[] = $reply['id'];
  626. }
  627. $reply['dt'] = hesk_date($reply['dt'], true);
  628. ?>
  629. <div class="row ticketMessageContainer">
  630. <div class="col-md-3 col-xs-12">
  631. <div class="ticketName"><?php echo $reply['name']; ?></div>
  632. </div>
  633. <div class="col-md-9 col-xs-12 pushMarginLeft">
  634. <div class="ticketMessageTop withBorder">
  635. <p><?php echo $hesklang['date']; ?>: <?php echo $reply['dt']; ?><span
  636. style="float: right;"><?php echo hesk_getCustomerButtons($i); ?></span></p>
  637. <?php
  638. /* Staff rating */
  639. if ($hesk_settings['rating'] && $reply['staffid']) {
  640. if ($reply['rating'] == 1) {
  641. echo '<p class="rate">' . $hesklang['rnh'] . '</p>';
  642. } elseif ($reply['rating'] == 5) {
  643. echo '<p class="rate">' . $hesklang['rh'] . '</p>';
  644. } else {
  645. echo '
  646. <div id="rating' . $reply['id'] . '" class="rate">
  647. ' . $hesklang['r'] . '
  648. <a href="Javascript:void(0)" onclick="Javascript:hesk_rate(\'rate.php?rating=5&amp;id=' . $reply['id'] . '&amp;track=' . $trackingID . '\',\'rating' . $reply['id'] . '\')">' . hesk_mb_strtolower($hesklang['yes']) . '</a> /
  649. <a href="Javascript:void(0)" onclick="Javascript:hesk_rate(\'rate.php?rating=1&amp;id=' . $reply['id'] . '&amp;track=' . $trackingID . '\',\'rating' . $reply['id'] . '\')">' . hesk_mb_strtolower($hesklang['no']) . '</a>
  650. </div>
  651. ';
  652. }
  653. }
  654. ?>
  655. </div>
  656. <div class="ticketMessageBottom">
  657. <!-- Message -->
  658. <p><b><?php echo $hesklang['message']; ?>:</b></p>
  659. <div class="message">
  660. <?php
  661. if ($reply['html']) {
  662. echo hesk_html_entity_decode($reply['message']);
  663. } else {
  664. echo $reply['message'];
  665. }
  666. ?>
  667. </div>
  668. </div>
  669. <div class="ticketMessageTop">
  670. <?php mfh_listAttachments($reply['attachments'], $i, false); ?>
  671. </div>
  672. </div>
  673. </div>
  674. <?php
  675. }
  676. return $i;
  677. } // End hesk_printCustomerTicketReplies()
  678. function hesk_getCustomerButtons($white = 1)
  679. {
  680. global $hesk_settings, $hesklang, $trackingID;
  681. $options = '';
  682. /* Style and mousover/mousout */
  683. $tmp = $white ? 'White' : 'Blue';
  684. $style = 'class="option' . $tmp . 'OFF" onmouseover="this.className=\'option' . $tmp . 'ON\'" onmouseout="this.className=\'option' . $tmp . 'OFF\'"';
  685. /* Print ticket button */
  686. $options .= '<a class="btn btn-default" href="print.php?track=' . $trackingID . $hesk_settings['e_query'] . '" title="' . $hesklang['printer_friendly'] . '"><span class="fa fa-print"></span> ' . $hesklang['btn_print'] . ' </a> ';
  687. /* Return generated HTML */
  688. return $options;
  689. } // END hesk_getCustomerButtons()
  690. ?>