Bootswatch, Summernote, and Captcheck mods for Mods for HESK (mods-for-hesk.com). In use at support.netsyms.com.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

manage_statuses.php 51KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. <?php
  2. define('IN_SCRIPT', 1);
  3. define('HESK_PATH', '../');
  4. define('PAGE_TITLE', 'ADMIN_STATUSES');
  5. define('MFH_PAGE_LAYOUT', 'TOP_ONLY');
  6. /* Get all the required files and functions */
  7. require(HESK_PATH . 'hesk_settings.inc.php');
  8. require(HESK_PATH . 'inc/common.inc.php');
  9. require(HESK_PATH . 'inc/admin_functions.inc.php');
  10. require(HESK_PATH . 'inc/status_functions.inc.php');
  11. require(HESK_PATH . 'inc/mail_functions.inc.php');
  12. hesk_load_database_functions();
  13. hesk_session_start();
  14. hesk_dbConnect();
  15. hesk_isLoggedIn();
  16. hesk_checkPermission('can_man_ticket_statuses');
  17. define('WYSIWYG', 1);
  18. // Are we performing an action?
  19. if (isset($_REQUEST['a'])) {
  20. if (defined('HESK_DEMO')) {
  21. hesk_process_messages($hesklang['cannot_edit_status_demo'], 'manage_statuses.php');
  22. } elseif ($_REQUEST['a'] == 'create') {
  23. createStatus();
  24. } elseif ($_REQUEST['a'] == 'update') {
  25. updateStatus();
  26. } elseif ($_REQUEST['a'] == 'delete') {
  27. deleteStatus();
  28. } elseif ($_REQUEST['a'] == 'sort') {
  29. moveStatus();
  30. } elseif ($_REQUEST['a'] == 'save') {
  31. save();
  32. }
  33. }
  34. $modsForHesk_settings = mfh_getSettings();
  35. /* Print header */
  36. require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
  37. /* Print main manage users page */
  38. require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
  39. ?>
  40. <div class="content-wrapper">
  41. <section class="content">
  42. <div class="box">
  43. <div class="box-body">
  44. <div class="nav-tabs-custom">
  45. <ul class="nav nav-tabs" role="tablist">
  46. <?php
  47. // Show a link to banned_emails.php if user has permission
  48. if (hesk_checkPermission('can_ban_emails', 0)) {
  49. echo '
  50. <li role="presentation">
  51. <a title="' . $hesklang['banemail'] . '" href="banned_emails.php">' . $hesklang['banemail'] . '</a>
  52. </li>
  53. ';
  54. }
  55. if (hesk_checkPermission('can_ban_ips', 0)) {
  56. echo '
  57. <li role="presentation">
  58. <a title="' . $hesklang['banip'] . '" href="banned_ips.php">' . $hesklang['banip'] . '</a>
  59. </li>';
  60. }
  61. // Show a link to status_message.php if user has permission to do so
  62. if (hesk_checkPermission('can_service_msg', 0)) {
  63. echo '
  64. <li role="presentation">
  65. <a title="' . $hesklang['sm_title'] . '" href="service_messages.php">' . $hesklang['sm_title'] . '</a>
  66. </li>';
  67. }
  68. if (hesk_checkPermission('can_man_email_tpl', 0)) {
  69. echo '
  70. <li role="presentation">
  71. <a title="' . $hesklang['email_templates'] . '" href="manage_email_templates.php">' . $hesklang['email_templates'] . '</a>
  72. </li>
  73. ';
  74. }
  75. ?>
  76. <li role="presentation" class="active">
  77. <a href="#"><?php echo $hesklang['statuses']; ?> <i class="fa fa-question-circle settingsquestionmark"
  78. data-toggle="popover"
  79. title="<?php echo $hesklang['statuses']; ?>"
  80. data-content="<?php echo $hesklang['statuses_intro']; ?>"></i></a>
  81. </li>
  82. <?php
  83. if (hesk_checkPermission('can_man_settings', 0)) {
  84. echo '
  85. <li role="presentation">
  86. <a title="' . $hesklang['tab_4'] . '" href="custom_fields.php">' .
  87. $hesklang['tab_4']
  88. . '</a>
  89. </li>
  90. ';
  91. }
  92. ?>
  93. </ul>
  94. <div class="tab-content summaryList tabPadding">
  95. <div class="row">
  96. <div class="col-md-12">
  97. <?php
  98. /* This will handle error, success and notice messages */
  99. hesk_handle_messages();
  100. //-- We need to get all of the statuses and dump the information to the page.
  101. $numOfStatusesRS = hesk_dbQuery('SELECT 1 FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses`');
  102. $numberOfStatuses = hesk_dbNumRows($numOfStatusesRS);
  103. $statuses = mfh_getAllStatuses();
  104. ?>
  105. <form class="form-horizontal" method="post" action="manage_statuses.php" role="form">
  106. <div class="panel panel-default">
  107. <div class="panel-heading">
  108. <h4>
  109. <?php echo $hesklang['statuses']; ?>
  110. <span style="float: right; margin-top: -7px">
  111. <button type="button" class="btn btn-success" data-toggle="modal" data-target="#modal-status-new">
  112. <i class="fa fa-plus-circle"></i>
  113. <?php
  114. echo $hesklang['new_status'];
  115. ?>
  116. </button>
  117. </span>
  118. </h4>
  119. </div>
  120. <table class="table table-hover">
  121. <thead>
  122. <tr>
  123. <th><?php echo $hesklang['status_name_title']; ?></th>
  124. <th><?php echo $hesklang['closable_question']; ?></th>
  125. <th><?php echo $hesklang['closedQuestionMark']; ?></th>
  126. <th><?php echo $hesklang['actions']; ?></th>
  127. </tr>
  128. </thead>
  129. <tbody>
  130. <?php
  131. $j = 1;
  132. foreach ($statuses as $key => $row):
  133. ?>
  134. <tr id="s<?php echo $row['ID']; ?>_row">
  135. <td class="bold" style="color: <?php echo $row['TextColor']; ?>">
  136. <?php echo $row['text']; ?>
  137. </td>
  138. <td>
  139. <?php
  140. if ($row['Closable'] == 'yes') {
  141. echo $hesklang['yes_title_case'];
  142. } elseif ($row['Closable'] == 'conly') {
  143. echo $hesklang['customers_only'];
  144. } elseif ($row['Closable'] == 'sonly') {
  145. echo $hesklang['staff_only'];
  146. } elseif ($row['Closable'] == 'no') {
  147. echo $hesklang['no_title_case'];
  148. }
  149. ?>
  150. </td>
  151. <td>
  152. <?php
  153. if ($row['IsClosed']) {
  154. echo '<i class="fa fa-check-circle icon-link green"></i>';
  155. }
  156. ?>
  157. </td>
  158. <td>
  159. <span data-toggle="modal" data-target="#modal-status-<?php echo $row['ID']; ?>"
  160. style="cursor: pointer;">
  161. <i class="fa fa-pencil icon-link orange"
  162. data-toggle="tooltip" title="<?php echo $hesklang['edit']; ?>"></i>
  163. </span>
  164. <?php echoArrows($j, $numberOfStatuses, $row['ID'], $modsForHesk_settings); ?>
  165. <?php
  166. // Only show the delete button if (1) it's not a default action and (2) no tickets are set to that status
  167. $delete = canStatusBeDeleted($row['ID']);
  168. $cursor = 'cursor: pointer';
  169. $iconStyle = 'color: red';
  170. $dataTarget = 'data-target="#modal-status-delete-' . $row['ID'] . '"';
  171. $tooltip = $hesklang['delete'];
  172. if ($delete == 'no-default' || $delete == 'no-tickets') {
  173. $cursor = '';
  174. $dataTarget = '';
  175. $iconStyle = 'color: grey';
  176. }
  177. if ($delete == 'no-default') {
  178. $tooltip = $hesklang['whyCantIDeleteThisStatusReason'];
  179. } elseif ($delete == 'no-tickets') {
  180. $tooltip = $hesklang['cannot_delete_status_tickets'];
  181. }
  182. ?>
  183. <span data-toggle="modal" <?php echo $dataTarget; ?>
  184. style="<?php echo $cursor; ?>;">
  185. <i class="fa fa-times icon-link" style="<?php echo $iconStyle; ?>"
  186. data-toggle="tooltip" title="<?php echo $tooltip; ?>"></i>
  187. </span>
  188. </td>
  189. </tr>
  190. <?php
  191. $j++;
  192. endforeach; ?>
  193. </tbody>
  194. </table>
  195. </div>
  196. <div class="panel panel-default">
  197. <div class="panel-heading">
  198. <h4><?php echo $hesklang['defaultStatusForAction']; ?></h4>
  199. </div>
  200. <div class="panel-body">
  201. <div class="form-group">
  202. <label for="newTicket"
  203. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['isNewTicketMsg']; ?></label>
  204. <div class="col-sm-6 col-xs-12">
  205. <select name="newTicket" class="form-control" id="newTicket">
  206. <?php
  207. foreach ($statuses as $key => $row) {
  208. if ($row['IsClosed'] == 1) {
  209. continue;
  210. }
  211. $selectedEcho = ($row['IsNewTicketStatus'] == 1) ? 'selected="selected"' : '';
  212. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  213. }
  214. ?>
  215. </select>
  216. </div>
  217. </div>
  218. <div class="form-group">
  219. <label for="closedByClient"
  220. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['isClosedByClientMsg']; ?></label>
  221. <div class="col-sm-6 col-xs-12">
  222. <select name="closedByClient" class="form-control" id="closedByClient">
  223. <?php
  224. foreach ($statuses as $key => $row) {
  225. if ($row['IsClosed'] == 0) {
  226. continue;
  227. }
  228. $selectedEcho = ($row['IsClosedByClient'] == 1) ? 'selected="selected"' : '';
  229. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  230. }
  231. ?>
  232. </select>
  233. </div>
  234. </div>
  235. <div class="form-group">
  236. <label for="replyFromClient"
  237. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['isRepliedByClientMsg']; ?></label>
  238. <div class="col-sm-6 col-xs-12">
  239. <select name="replyFromClient" class="form-control" id="replyFromClient">
  240. <?php
  241. foreach ($statuses as $key => $row) {
  242. if ($row['IsClosed'] == 1) {
  243. continue;
  244. }
  245. $selectedEcho = ($row['IsCustomerReplyStatus'] == 1) ? 'selected="selected"' : '';
  246. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  247. }
  248. ?>
  249. </select>
  250. </div>
  251. </div>
  252. <div class="form-group">
  253. <label for="staffClosedOption"
  254. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['isStaffClosedOptionMsg']; ?></label>
  255. <div class="col-sm-6 col-xs-12">
  256. <select name="staffClosedOption" class="form-control" id="staffClosedOption">
  257. <?php
  258. foreach ($statuses as $key => $row) {
  259. if ($row['IsClosed'] == 0) {
  260. continue;
  261. }
  262. $selectedEcho = ($row['IsStaffClosedOption'] == 1) ? 'selected="selected"' : '';
  263. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  264. }
  265. ?>
  266. </select>
  267. </div>
  268. </div>
  269. <div class="form-group">
  270. <label for="staffReopenedStatus"
  271. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['isStaffReopenedStatusMsg']; ?></label>
  272. <div class="col-sm-6 col-xs-12">
  273. <select name="staffReopenedStatus" class="form-control"
  274. id="staffReopenedStatus">
  275. <?php
  276. foreach ($statuses as $key => $row) {
  277. if ($row['IsClosed'] == 1) {
  278. continue;
  279. }
  280. $selectedEcho = ($row['IsStaffReopenedStatus'] == 1) ? 'selected="selected"' : '';
  281. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  282. }
  283. ?>
  284. </select>
  285. </div>
  286. </div>
  287. <div class="form-group">
  288. <label for="defaultStaffReplyStatus"
  289. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['isDefaultStaffReplyStatusMsg']; ?></label>
  290. <div class="col-sm-6 col-xs-12">
  291. <select name="defaultStaffReplyStatus" class="form-control"
  292. id="defaultStaffReplyStatus">
  293. <?php
  294. foreach ($statuses as $key => $row) {
  295. if ($row['IsClosed'] == 1) {
  296. continue;
  297. }
  298. $selectedEcho = ($row['IsDefaultStaffReplyStatus'] == 1) ? 'selected="selected"' : '';
  299. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  300. }
  301. ?>
  302. </select>
  303. </div>
  304. </div>
  305. <div class="form-group">
  306. <label for="lockedTicketStatus"
  307. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['lockedTicketStatusMsg']; ?></label>
  308. <div class="col-sm-6 col-xs-12">
  309. <select name="lockedTicketStatus" class="form-control" id="lockedTicketStatus">
  310. <?php
  311. foreach ($statuses as $key => $row) {
  312. $selectedEcho = ($row['LockedTicketStatus'] == 1) ? 'selected="selected"' : '';
  313. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  314. }
  315. ?>
  316. </select>
  317. </div>
  318. </div>
  319. <div class="form-group">
  320. <label for="autocloseTicketOption"
  321. class="col-sm-6 col-xs-12 control-label"><?php echo $hesklang['autoclose_ticket_status']; ?></label>
  322. <div class="col-sm-6 col-xs-12">
  323. <select name="autocloseTicketOption" class="form-control"
  324. id="autocloseTicketOption">
  325. <?php
  326. foreach ($statuses as $key => $row) {
  327. if ($row['IsClosed'] == 0) {
  328. continue;
  329. }
  330. $selectedEcho = ($row['IsAutocloseOption'] == 1) ? 'selected' : '';
  331. echo '<option value="' . $row['ID'] . '" ' . $selectedEcho . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
  332. }
  333. ?>
  334. </select>
  335. </div>
  336. </div>
  337. </div>
  338. </div>
  339. <div class="col-sm-6 col-sm-offset-6">
  340. <input type="hidden" name="a" value="save">
  341. <input type="submit" class="btn btn-default"
  342. value="<?php echo $hesklang['save_changes']; ?>">
  343. </div>
  344. </form>
  345. </div>
  346. </div>
  347. </div>
  348. </div>
  349. </div>
  350. </div>
  351. </section>
  352. </div>
  353. <?php
  354. foreach ($statuses as $status) {
  355. buildEditModal($status['ID']);
  356. buildConfirmDeleteModal($status['ID']);
  357. }
  358. buildCreateModal();
  359. require_once(HESK_PATH . 'inc/footer.inc.php');
  360. exit();
  361. function buildConfirmDeleteModal($statusId)
  362. {
  363. global $hesklang;
  364. ?>
  365. <div class="modal fade" id="modal-status-delete-<?php echo $statusId; ?>" tabindex="-1" role="dialog"
  366. aria-labelledby="myLargeModalLabel" aria-hidden="true">
  367. <div class="modal-dialog modal-lg">
  368. <div class="modal-content">
  369. <div class="modal-header">
  370. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
  371. aria-hidden="true">&times;</span></button>
  372. <h4 class="modal-title"><?php echo $hesklang['confirm_delete_status_question']; ?></h4>
  373. </div>
  374. <div class="modal-body">
  375. <div class="row">
  376. <div class="col-md-12">
  377. <p><?php echo $hesklang['confirm_delete_status']; ?></p>
  378. </div>
  379. </div>
  380. </div>
  381. <div class="modal-footer">
  382. <input type="hidden" name="a" value="create">
  383. <div class="btn-group">
  384. <a href="manage_statuses.php?a=delete&id=<?php echo $statusId; ?>" class="btn btn-danger">
  385. <?php echo $hesklang['delete']; ?>
  386. </a>
  387. <button type="button" class="btn btn-default"
  388. data-dismiss="modal"><?php echo $hesklang['cancel']; ?></button>
  389. </div>
  390. </div>
  391. </div>
  392. </div>
  393. </div>
  394. <?php
  395. }
  396. function echoArrows($index, $numberOfStatuses, $statusId, $modsForHesk_settings)
  397. {
  398. global $hesklang;
  399. if ($modsForHesk_settings['statuses_order_column'] == 'name') {
  400. return;
  401. }
  402. if ($index !== 1) {
  403. // Display move up
  404. echo '<a href="manage_statuses.php?a=sort&move=-15&id=' . $statusId . '">
  405. <i class="fa fa-arrow-up icon-link green" data-toggle="tooltip"
  406. title="' . htmlspecialchars($hesklang['move_up']) . '"></i></a> ';
  407. } else {
  408. echo '<img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;"> ';
  409. }
  410. if ($index !== $numberOfStatuses) {
  411. // Display move down
  412. echo '<a href="manage_statuses.php?a=sort&move=15&id=' . $statusId . '">
  413. <i class="fa fa-arrow-down icon-link green" data-toggle="tooltip"
  414. title="' . htmlspecialchars($hesklang['move_dn']) . '"></i></a>';
  415. } else {
  416. echo '<img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;">';
  417. }
  418. }
  419. function buildCreateModal()
  420. {
  421. global $hesklang, $hesk_settings;
  422. $languages = array();
  423. foreach ($hesk_settings['languages'] as $key => $value) {
  424. $languages[$key] = $hesk_settings['languages'][$key]['folder'];
  425. }
  426. ?>
  427. <div class="modal fade" id="modal-status-new" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"
  428. aria-hidden="true">
  429. <div class="modal-dialog modal-lg">
  430. <div class="modal-content">
  431. <form action="manage_statuses.php" role="form" method="post" class="form-horizontal" data-toggle="validator">
  432. <div class="modal-header">
  433. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
  434. aria-hidden="true">&times;</span></button>
  435. <h4 class="modal-title"><?php echo $hesklang['create_new_status_title']; ?></h4>
  436. </div>
  437. <div class="modal-body">
  438. <div class="row">
  439. <div class="col-md-6">
  440. <h4><?php echo $hesklang['status_name_title']; ?>
  441. <i class="fa fa-question-circle settingsquestionmark"
  442. data-toggle="popover"
  443. title="<?php echo $hesklang['status_name_title']; ?>"
  444. data-content="<?php echo $hesklang['status_name_title_help']; ?>"></i></h4>
  445. <div class="footerWithBorder blankSpace"></div>
  446. <?php foreach ($languages as $language => $languageCode): ?>
  447. <div class="form-group">
  448. <label class="col-sm-3 control-label" for="name[<?php echo $language; ?>]">
  449. <?php echo $language; ?>
  450. </label>
  451. <div class="col-sm-9">
  452. <input type="text" placeholder="<?php echo htmlspecialchars($language); ?>"
  453. data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
  454. class="form-control" name="name[<?php echo $language; ?>]" required>
  455. <div class="help-block with-errors"></div>
  456. </div>
  457. </div>
  458. <?php endforeach; ?>
  459. </div>
  460. <div class="col-md-6">
  461. <h4><?php echo $hesklang['properties']; ?></h4>
  462. <div class="footerWithBorder blankSpace"></div>
  463. <div class="form-group">
  464. <label for="text-color" class="col-sm-4 control-label">
  465. <?php echo $hesklang['textColor']; ?>
  466. <i class="fa fa-question-circle settingsquestionmark"
  467. data-toggle="popover"
  468. title="<?php echo $hesklang['textColor']; ?>"
  469. data-content="<?php echo $hesklang['textColorDescr']; ?>"></i>
  470. </label>
  471. <div class="col-sm-8">
  472. <input type="text" name="text-color" class="form-control colorpicker-trigger"
  473. data-color=""
  474. data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
  475. placeholder="<?php echo htmlspecialchars($hesklang['textColor']); ?>" required>
  476. <div class="help-block with-errors"></div>
  477. </div>
  478. </div>
  479. <div class="form-group">
  480. <label for="closable" class="col-sm-4 control-label">
  481. <?php echo $hesklang['closable']; ?>
  482. <i class="fa fa-question-circle settingsquestionmark"
  483. data-toggle="htmlpopover"
  484. title="<?php echo $hesklang['closable']; ?>"
  485. data-content="<?php echo $hesklang['closable_description']; ?>"></i>
  486. </label>
  487. <div class="col-sm-8">
  488. <select name="closable" class="form-control">
  489. <option value="yes"><?php echo $hesklang['yes_title_case']; ?></option>
  490. <option value="conly"><?php echo $hesklang['customers_only']; ?></option>
  491. <option value="sonly"><?php echo $hesklang['staff_only']; ?></option>
  492. <option value="no"><?php echo $hesklang['no_title_case']; ?></option>
  493. </select>
  494. </div>
  495. </div>
  496. <div class="form-group">
  497. <label for="closed" class="col-sm-4 control-label">
  498. <?php echo $hesklang['closed_title']; ?>
  499. <i class="fa fa-question-circle settingsquestionmark"
  500. data-toggle="htmlpopover"
  501. title="<?php echo $hesklang['closed_title']; ?>"
  502. data-content="<?php echo $hesklang['closedQuestionMarkDescr']; ?>"></i>
  503. </label>
  504. <div class="col-sm-8">
  505. <select name="closed" class="form-control">
  506. <option value="1"><?php echo $hesklang['yes_title_case']; ?></option>
  507. <option value="0"><?php echo $hesklang['no_title_case']; ?></option>
  508. </select>
  509. </div>
  510. </div>
  511. </div>
  512. </div>
  513. </div>
  514. <div class="modal-footer">
  515. <input type="hidden" name="a" value="create">
  516. <div class="btn-group">
  517. <input type="submit" class="btn btn-success"
  518. value="<?php echo $hesklang['save_changes']; ?>">
  519. <button type="button" class="btn btn-default"
  520. data-dismiss="modal"><?php echo $hesklang['close_modal_without_saving']; ?></button>
  521. </div>
  522. </div>
  523. </form>
  524. </div>
  525. </div>
  526. </div>
  527. <?php
  528. }
  529. function buildEditModal($statusId)
  530. {
  531. global $hesklang, $hesk_settings;
  532. // Get status information for this status
  533. $getStatusRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `ID` = " . intval($statusId));
  534. $status = hesk_dbFetchAssoc($getStatusRs);
  535. $textRs = hesk_dbQuery("SELECT `language`, `text` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref`
  536. WHERE `status_id` = " . intval($statusId));
  537. $textArray = array();
  538. while ($row = hesk_dbFetchAssoc($textRs)) {
  539. $textArray[$row['language']] = $row['text'];
  540. }
  541. $languages = array();
  542. foreach ($hesk_settings['languages'] as $key => $value) {
  543. $languages[$key] = $hesk_settings['languages'][$key]['folder'];
  544. }
  545. ?>
  546. <div class="modal fade" id="modal-status-<?php echo $statusId; ?>" tabindex="-1" role="dialog"
  547. aria-labelledby="myLargeModalLabel" aria-hidden="true">
  548. <div class="modal-dialog modal-lg">
  549. <div class="modal-content">
  550. <form action="manage_statuses.php" role="form" method="post" class="form-horizontal" data-toggle="validator">
  551. <div class="modal-header">
  552. <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
  553. aria-hidden="true">&times;</span></button>
  554. <h4 class="modal-title"><?php echo sprintf($hesklang['editing_status_x'], $status['TextColor'], mfh_getDisplayTextForStatusId($statusId)); ?></h4>
  555. </div>
  556. <div class="modal-body">
  557. <div class="row">
  558. <div class="col-md-6">
  559. <h4>
  560. <?php echo $hesklang['status_name_title']; ?>
  561. <i class="fa fa-question-circle settingsquestionmark"
  562. data-toggle="popover"
  563. title="<?php echo $hesklang['status_name_title']; ?>"
  564. data-content="<?php echo $hesklang['status_name_title_help']; ?>"></i>
  565. </h4>
  566. <div class="footerWithBorder blankSpace"></div>
  567. <?php foreach ($languages as $language => $languageCode):
  568. $warning = '';
  569. if (isset($textArray[$language])) {
  570. $text = $textArray[$language];
  571. } else {
  572. hesk_setLanguage($language);
  573. $text = $hesklang[$status['Key']];
  574. hesk_resetLanguage();
  575. $warning = 'has-warning';
  576. }
  577. ?>
  578. <div class="form-group <?php echo $warning; ?>">
  579. <label class="col-sm-3 control-label" for="name[<?php echo $language; ?>]">
  580. <?php
  581. if ($warning != '') {
  582. echoWarningForStatus();
  583. }
  584. echo $language;
  585. ?>
  586. </label>
  587. <div class="col-sm-9">
  588. <input type="text" placeholder="<?php echo htmlspecialchars($language); ?>"
  589. class="form-control" name="name[<?php echo $language; ?>]"
  590. data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
  591. value="<?php echo htmlspecialchars($text); ?>" required>
  592. <div class="help-block with-errors"></div>
  593. </div>
  594. </div>
  595. <?php endforeach; ?>
  596. </div>
  597. <div class="col-md-6">
  598. <h4><?php echo $hesklang['properties']; ?></h4>
  599. <div class="footerWithBorder blankSpace"></div>
  600. <div class="form-group">
  601. <label for="text-color" class="col-sm-4 control-label">
  602. <?php echo $hesklang['textColor']; ?>
  603. <i class="fa fa-question-circle settingsquestionmark"
  604. data-toggle="popover"
  605. title="<?php echo $hesklang['textColor']; ?>"
  606. data-content="<?php echo $hesklang['textColorDescr']; ?>"></i>
  607. </label>
  608. <div class="col-sm-8">
  609. <input type="text" name="text-color" class="form-control colorpicker-trigger"
  610. value="<?php echo $status['TextColor']; ?>"
  611. data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
  612. placeholder="<?php echo htmlspecialchars($hesklang['textColor']); ?>" required>
  613. <div class="help-block with-errors"></div>
  614. </div>
  615. </div>
  616. <div class="form-group">
  617. <label for="closable" class="col-sm-4 control-label">
  618. <?php echo $hesklang['closable']; ?>
  619. <i class="fa fa-question-circle settingsquestionmark"
  620. data-toggle="htmlpopover"
  621. title="<?php echo $hesklang['closable']; ?>"
  622. data-content="<?php echo $hesklang['closable_description']; ?>"></i>
  623. </label>
  624. <div class="col-sm-8">
  625. <?php
  626. $yesSelected = $status['Closable'] == 'yes' ? 'selected' : '';
  627. $customersOnlySelected = $status['Closable'] == 'conly' ? 'selected' : '';
  628. $staffOnlySelected = $status['Closable'] == 'sonly' ? 'selected' : '';
  629. $noSelected = $status['Closable'] == 'no' ? 'selected' : '';
  630. ?>
  631. <select name="closable" class="form-control">
  632. <option
  633. value="yes" <?php echo $yesSelected; ?>><?php echo $hesklang['yes_title_case']; ?></option>
  634. <option
  635. value="conly" <?php echo $customersOnlySelected; ?>><?php echo $hesklang['customers_only']; ?></option>
  636. <option
  637. value="sonly" <?php echo $staffOnlySelected; ?>><?php echo $hesklang['staff_only']; ?></option>
  638. <option
  639. value="no" <?php echo $noSelected; ?>><?php echo $hesklang['no_title_case']; ?></option>
  640. </select>
  641. </div>
  642. </div>
  643. <div class="form-group">
  644. <label for="closed" class="col-sm-4 control-label">
  645. <?php echo $hesklang['closed_title']; ?>
  646. <i class="fa fa-question-circle settingsquestionmark"
  647. data-toggle="htmlpopover"
  648. title="<?php echo $hesklang['closed_title']; ?>"
  649. data-content="<?php echo $hesklang['closedQuestionMarkDescr']; ?>"></i>
  650. </label>
  651. <div class="col-sm-8">
  652. <?php
  653. $yes = $status['IsClosed'] == 1 ? 'selected' : '';
  654. $no = $status['IsClosed'] == 1 ? '' : 'selected';
  655. ?>
  656. <select name="closed" class="form-control">
  657. <option
  658. value="1" <?php echo $yes; ?>><?php echo $hesklang['yes_title_case']; ?></option>
  659. <option
  660. value="0" <?php echo $no; ?>><?php echo $hesklang['no_title_case']; ?></option>
  661. </select>
  662. </div>
  663. </div>
  664. </div>
  665. </div>
  666. </div>
  667. <div class="modal-footer">
  668. <input type="hidden" name="a" value="update">
  669. <input type="hidden" name="status-id" value="<?php echo $statusId; ?>">
  670. <div class="btn-group">
  671. <input type="submit" class="btn btn-success"
  672. value="<?php echo $hesklang['save_changes']; ?>">
  673. <button type="button" class="btn btn-default"
  674. data-dismiss="modal"><?php echo $hesklang['close_modal_without_saving']; ?></button>
  675. </div>
  676. </div>
  677. </form>
  678. </div>
  679. </div>
  680. </div>
  681. <?php
  682. }
  683. function canStatusBeDeleted($id)
  684. {
  685. global $hesk_settings;
  686. $defaultActionSql = "SELECT 1 FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `ID` = " . intval($id) . " AND
  687. (`IsNewTicketStatus` = 1 OR `IsClosedByClient` = 1 OR `IsCustomerReplyStatus` = 1 OR `IsStaffClosedOption` = 1
  688. OR `IsStaffReopenedStatus` = 1 OR `IsDefaultStaffReplyStatus` = 1 OR `LockedTicketStatus` = 1 OR `IsAutocloseOption` = 1)";
  689. $defaultActionRs = hesk_dbQuery($defaultActionSql);
  690. if (hesk_dbNumRows($defaultActionRs) > 0) {
  691. // it's a default action
  692. return 'no-default';
  693. }
  694. // check if any tickets have this status
  695. $statusRs = hesk_dbQuery("SELECT 1 FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `status` = " . intval($id));
  696. if (hesk_dbNumRows($statusRs) > 0) {
  697. return 'no-tickets';
  698. }
  699. return 'yes';
  700. }
  701. function echoWarningForStatus()
  702. {
  703. global $hesklang;
  704. echo '<i class="fa fa-exclamation-triangle" data-toggle="tooltip" title="' . htmlspecialchars($hesklang['status_not_in_database']) . '"></i> ';
  705. }
  706. function createStatus()
  707. {
  708. global $hesklang, $hesk_settings;
  709. hesk_dbConnect();
  710. // Create the new status record
  711. $isClosed = hesk_POST('closed');
  712. $closable = hesk_POST('closable');
  713. $textColor = hesk_POST('text-color');
  714. /* Get the latest cat_order */
  715. $res = hesk_dbQuery("SELECT `sort` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ORDER BY `sort` DESC LIMIT 1");
  716. $row = hesk_dbFetchRow($res);
  717. $my_order = $row[0] + 10;
  718. // Get the next status id
  719. $res = hesk_dbQuery("SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ORDER BY `ID` DESC LIMIT 1");
  720. $row = hesk_dbFetchAssoc($res);
  721. $nextId = $row['ID'] + 1;
  722. $insert = "INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (`ID`, `Key`, `TextColor`, `IsClosed`, `Closable`, `sort`)
  723. VALUES (" . intval($nextId) . ", 'STORED IN XREF TABLE', '" . hesk_dbEscape($textColor) . "', " . intval($isClosed) . ", '" . hesk_dbEscape($closable) . "', " . intval($my_order) . ")";
  724. hesk_dbQuery($insert);
  725. // For each language, create a value in the xref table
  726. foreach (hesk_POST_array('name') as $language => $translation) {
  727. hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref` (`language`, `text`, `status_id`)
  728. VALUES ('" . hesk_dbEscape($language) . "', '" . hesk_dbEscape($translation) . "', " . intval($nextId) . ")");
  729. }
  730. hesk_process_messages($hesklang['new_status_created'], 'manage_statuses.php', 'SUCCESS');
  731. }
  732. function updateStatus()
  733. {
  734. global $hesklang, $hesk_settings;
  735. $statusId = hesk_POST('status-id');
  736. $isClosed = hesk_POST('closed');
  737. $closable = hesk_POST('closable');
  738. $textColor = hesk_POST('text-color');
  739. $update = "UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`
  740. SET `TextColor` = '" . hesk_dbEscape($textColor) . "',
  741. `IsClosed` = " . intval($isClosed) . ",
  742. `Closable` = '" . hesk_dbEscape($closable) . "'
  743. WHERE `ID` = " . intval($statusId);
  744. hesk_dbQuery($update);
  745. // For each language, delete the xref record and insert the new ones
  746. hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref` WHERE `status_id` = " . intval($statusId));
  747. foreach (hesk_POST_array('name') as $language => $translation) {
  748. hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref` (`language`, `text`, `status_id`)
  749. VALUES ('" . hesk_dbEscape($language) . "', '" . hesk_dbEscape($translation) . "', " . intval($statusId) . ")");
  750. }
  751. hesk_process_messages($hesklang['ticket_status_updated'], 'manage_statuses.php', 'SUCCESS');
  752. }
  753. function deleteStatus()
  754. {
  755. global $hesklang, $hesk_settings;
  756. $statusId = hesk_GET('id');
  757. hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref` WHERE `status_id` = " . intval($statusId));
  758. hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `ID` = " . intval($statusId));
  759. resortStatuses();
  760. hesk_process_messages($hesklang['ticket_status_deleted'], 'manage_statuses.php', 'SUCCESS');
  761. }
  762. function moveStatus()
  763. {
  764. global $hesk_settings, $hesklang;
  765. $statusId = intval(hesk_GET('id'));
  766. $statusMove = intval(hesk_GET('move'));
  767. hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `sort` = `sort`+" . intval($statusMove) . "
  768. WHERE `ID` = '" . intval($statusId) . "' LIMIT 1");
  769. resortStatuses();
  770. hesk_process_messages($hesklang['status_sort_updated'], 'manage_statuses.php', 'SUCCESS');
  771. }
  772. function resortStatuses()
  773. {
  774. global $hesk_settings;
  775. /* Update all category fields with new order */
  776. $res = hesk_dbQuery("SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ORDER BY `sort` ASC");
  777. $i = 10;
  778. while ($myStatus = hesk_dbFetchAssoc($res)) {
  779. hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `sort`=" . intval($i) . "
  780. WHERE `ID`='" . intval($myStatus['ID']) . "' LIMIT 1");
  781. $i += 10;
  782. }
  783. }
  784. function save()
  785. {
  786. global $hesklang, $hesk_settings;
  787. //-- Update default status for actions
  788. $defaultQuery = "UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET ";
  789. hesk_dbQuery($defaultQuery . "`IsNewTicketStatus` = 0");
  790. $updateQuery = $defaultQuery . "`IsNewTicketStatus` = 1 WHERE `ID` = " . intval($_POST['newTicket']);
  791. hesk_dbQuery($updateQuery);
  792. hesk_dbQuery($defaultQuery . "`IsClosedByClient` = 0");
  793. $updateQuery = $defaultQuery . "`IsClosedByClient` = 1 WHERE `ID` = " . intval($_POST['closedByClient']);
  794. hesk_dbQuery($updateQuery);
  795. hesk_dbQuery($defaultQuery . "`IsCustomerReplyStatus` = 0");
  796. $updateQuery = $defaultQuery . "`IsCustomerReplyStatus` = 1 WHERE `ID` = " . intval($_POST['replyFromClient']);
  797. hesk_dbQuery($updateQuery);
  798. hesk_dbQuery($defaultQuery . "`IsStaffClosedOption` = 0");
  799. $updateQuery = $defaultQuery . "`IsStaffClosedOption` = 1 WHERE `ID` = " . intval($_POST['staffClosedOption']);
  800. hesk_dbQuery($updateQuery);
  801. hesk_dbQuery($defaultQuery . "`IsStaffReopenedStatus` = 0");
  802. $updateQuery = $defaultQuery . "`IsStaffReopenedStatus` = 1 WHERE `ID` = " . intval($_POST['staffReopenedStatus']);
  803. hesk_dbQuery($updateQuery);
  804. hesk_dbQuery($defaultQuery . "`IsDefaultStaffReplyStatus` = 0");
  805. $updateQuery = $defaultQuery . "`IsDefaultStaffReplyStatus` = 1 WHERE `ID` = " . intval($_POST['defaultStaffReplyStatus']);
  806. hesk_dbQuery($updateQuery);
  807. hesk_dbQuery($defaultQuery . "`LockedTicketStatus` = 0");
  808. $updateQuery = $defaultQuery . "`LockedTicketStatus` = 1 WHERE `ID` = " . intval($_POST['lockedTicketStatus']);
  809. hesk_dbQuery($updateQuery);
  810. hesk_dbQuery($defaultQuery . "`IsAutocloseOption` = 0");
  811. $updateQuery = $defaultQuery . "`IsAutocloseOption` = 1 WHERE `ID` = " . intval($_POST['autocloseTicketOption']);
  812. hesk_dbQuery($updateQuery);
  813. hesk_process_messages($hesklang['default_statuses_updated'], 'manage_statuses.php', 'SUCCESS');
  814. }