diff --git a/admin/admin_ticket.php b/admin/admin_ticket.php index 150b54e6..36804051 100644 --- a/admin/admin_ticket.php +++ b/admin/admin_ticket.php @@ -939,6 +939,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); /* This will handle error, success and notice messages */ hesk_handle_messages(); + $service_messages = mfh_get_service_messages('STAFF_VIEW_TICKET'); + foreach ($service_messages as $sm) { + hesk_service_message($sm); + } + // Prepare special custom fields foreach ($hesk_settings['custom_fields'] as $k=>$v) { if ($v['use'] && hesk_is_custom_field_in_category($k, $ticket['category']) ) { diff --git a/admin/index.php b/admin/index.php index aec1e374..f623d4a0 100644 --- a/admin/index.php +++ b/admin/index.php @@ -278,6 +278,12 @@ function print_login()
diff --git a/admin/knowledgebase_private.php b/admin/knowledgebase_private.php
index 041da9bd..e2cd0277 100644
--- a/admin/knowledgebase_private.php
+++ b/admin/knowledgebase_private.php
@@ -121,7 +121,9 @@ function hesk_kb_header($kb_link, $catid=1)
';
hesk_kbSearchLarge(1);
+ echo '
';
} // END hesk_kb_header()
@@ -214,7 +216,15 @@ function hesk_show_kb_article($artid)
?>
-
+ ';
+ $service_messages = mfh_get_service_messages('STAFF_VIEW_KB_ARTICLE');
+ foreach ($service_messages as $sm) {
+ hesk_service_message($sm);
+ }
+ echo '
';
+ ?>
@@ -397,6 +407,13 @@ function hesk_show_kb_category($catid, $is_search = 0) {
{
/* Print header */
hesk_kb_header($hesk_settings['kb_link'], $catid);
+
+ echo '
diff --git a/admin/manage_knowledgebase.php b/admin/manage_knowledgebase.php
index b126a326..03e4ba6f 100644
--- a/admin/manage_knowledgebase.php
+++ b/admin/manage_knowledgebase.php
@@ -270,6 +270,12 @@ if (!isset($_SESSION['hide']['treemenu']))
';
+ $service_messages = mfh_get_service_messages('STAFF_KB_HOME');
+ foreach ($service_messages as $sm) {
+ hesk_service_message($sm);
+ }
+ echo '
';
} ?>
diff --git a/admin/service_messages.php b/admin/service_messages.php
index 580d0012..052e0eb4 100644
--- a/admin/service_messages.php
+++ b/admin/service_messages.php
@@ -15,6 +15,7 @@ define('IN_SCRIPT', 1);
define('HESK_PATH', '../');
define('PAGE_TITLE', 'ADMIN_SERVICE_MESSAGES');
define('MFH_PAGE_LAYOUT', 'TOP_ONLY');
+define('EXTRA_JS', '');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
@@ -31,26 +32,8 @@ hesk_isLoggedIn();
hesk_checkPermission('can_service_msg');
// Define required constants
-define('LOAD_TABS', 1);
define('WYSIWYG', 1);
-// What should we do?
-if ($action = hesk_REQUEST('a')) {
- if ($action == 'edit_sm') {
- edit_sm();
- } elseif (defined('HESK_DEMO')) {
- hesk_process_messages($hesklang['ddemo'], 'service_messages.php', 'NOTICE');
- } elseif ($action == 'new_sm') {
- new_sm();
- } elseif ($action == 'save_sm') {
- save_sm();
- } elseif ($action == 'order_sm') {
- order_sm();
- } elseif ($action == 'remove_sm') {
- remove_sm();
- }
-}
-
/* Print header */
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
@@ -60,652 +43,401 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
+ $error \n";
- }
- $hesk_error_buffer = $tmp;
-
- $hesk_error_buffer = $hesklang['rfm'] . '
$error \n";
- }
- $hesk_error_buffer = $tmp;
-
- $hesk_error_buffer = $hesklang['rfm'] . '
+
+ + +
+
-
+
+
+var users = [];';
+$usersRs = hesk_dbQuery("SELECT `id`, `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `active` = '1'");
+$users = array();
+while ($row = hesk_dbFetchAssoc($usersRs)) {
+ $users[] = $row;
+ echo "users[" . $row['id'] . "] = {
+ id: ".$row['id'].",
+ name: '".$row['name']."'
+ }\n";
+}
+echo "
+var languages = [];\n";
+foreach ($hesk_settings['languages'] as $key => $value) {
+ echo "languages[" . json_encode($value['folder']) . "] = " . json_encode($key) . ";\n";
+}
+echo '';
+?>
+
+
+
4 || $style < 0) {
- $style = 0;
- }
-
- $type = empty($_POST['type']) ? 0 : 1;
- $icon = hesk_POST('icon');
- $title = hesk_input(hesk_POST('title')) or $hesk_error_buffer[] = $hesklang['sm_e_title'];
- $message = hesk_getHTML(hesk_POST('message'));
-
- // Clean the HTML code
- require(HESK_PATH . 'inc/htmlpurifier/HeskHTMLPurifier.php');
- $purifier = new HeskHTMLPurifier($hesk_settings['cache_dir']);
- $message = $purifier->heskPurify($message);
-
- // Any errors?
- if (count($hesk_error_buffer)) {
- $_SESSION['edit_sm'] = true;
-
- $_SESSION['new_sm'] = array(
- 'id' => $id,
- 'style' => $style,
- 'type' => $type,
- 'title' => $title,
- 'icon' => $icon,
- 'message' => hesk_input(hesk_POST('message')),
- );
-
- $tmp = '';
- foreach ($hesk_error_buffer as $error) {
- $tmp .= "
+
+
+ - ' . $hesk_error_buffer . '
- ' . $hesk_error_buffer . '
'; ?>
-
+
+
+
-
@@ -322,6 +321,13 @@ function print_add_ticket()
+
@@ -1315,15 +1321,13 @@ function print_start()
0)
- {
+ $service_messages = mfh_get_service_messages('CUSTOMER_HOME');
+ if (count($service_messages) > 0) {
?>
diff --git a/install/migrations/core.php b/install/migrations/core.php
index f52740e7..798f7fa9 100644
--- a/install/migrations/core.php
+++ b/install/migrations/core.php
@@ -218,5 +218,9 @@ function getAllMigrations() {
161 => new UpdateMigration('3.2.2', '3.2.1', 161),
162 => new UpdateMigration('3.2.3', '3.2.2', 162),
163 => new UpdateMigration('3.2.4', '3.2.3', 163),
+ // 3.3.0
+ 164 => new \v330\ServiceMessagesImprovements\CreateServiceMessageToLocationTable(164),
+ 165 => new \v330\ServiceMessagesImprovements\UpdateExistingServiceMessagesLocations(165),
+ 166 => new \v330\ServiceMessagesImprovements\AddLanguageColumnToServiceMessages(166),
);
}
\ No newline at end of file
diff --git a/install/migrations/v330/ServiceMessagesImprovements/AddLanguageColumnToServiceMessages.php b/install/migrations/v330/ServiceMessagesImprovements/AddLanguageColumnToServiceMessages.php
new file mode 100644
index 00000000..21481b99
--- /dev/null
+++ b/install/migrations/v330/ServiceMessagesImprovements/AddLanguageColumnToServiceMessages.php
@@ -0,0 +1,17 @@
+executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages`
+ ADD COLUMN `mfh_language` VARCHAR(255) NOT NULL DEFAULT 'ALL'");
+ }
+
+ function innerDown($hesk_settings) {
+ $this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages`
+ DROP COLUMN `mfh_language`");
+ }
+}
\ No newline at end of file
diff --git a/install/migrations/v330/ServiceMessagesImprovements/CreateServiceMessageToLocationTable.php b/install/migrations/v330/ServiceMessagesImprovements/CreateServiceMessageToLocationTable.php
new file mode 100644
index 00000000..0fe7d1ec
--- /dev/null
+++ b/install/migrations/v330/ServiceMessagesImprovements/CreateServiceMessageToLocationTable.php
@@ -0,0 +1,16 @@
+executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_service_message_to_location`
+ (`service_message_id` INT NOT NULL, `location` VARCHAR(100) NOT NULL)");
+ }
+
+ function innerDown($hesk_settings) {
+ $this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_service_message_to_location`");
+ }
+}
\ No newline at end of file
diff --git a/install/migrations/v330/ServiceMessagesImprovements/UpdateExistingServiceMessagesLocations.php b/install/migrations/v330/ServiceMessagesImprovements/UpdateExistingServiceMessagesLocations.php
new file mode 100644
index 00000000..b9da7cc4
--- /dev/null
+++ b/install/migrations/v330/ServiceMessagesImprovements/UpdateExistingServiceMessagesLocations.php
@@ -0,0 +1,19 @@
+executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_service_message_to_location` (`service_message_id`, `location`)
+ SELECT `id`, '" . hesk_dbEscape(ServiceMessageLocation::CUSTOMER_HOME) . "' FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages`");
+ }
+
+ function innerDown($hesk_settings) {
+ $this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_service_message_to_location`
+ WHERE `service_message_id` IN (SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages`)");
+ }
+}
\ No newline at end of file
diff --git a/internal-api/js/service-messages.js b/internal-api/js/service-messages.js
new file mode 100644
index 00000000..e75719eb
--- /dev/null
+++ b/internal-api/js/service-messages.js
@@ -0,0 +1,361 @@
+var serviceMessages = [];
+
+var g_styles = [];
+g_styles["ERROR"] = 4;
+g_styles["NOTICE"] = 3;
+g_styles["INFO"] = 2;
+g_styles["SUCCESS"] = 1;
+g_styles["NONE"] = 0;
+
+$(document).ready(function() {
+ loadTable();
+ bindEditModal();
+ bindFormSubmit();
+ bindDeleteButton();
+ bindCreateModal();
+ bindSortButtons();
+ bindPreview();
+});
+
+
+function loadTable() {
+ $('#overlay').show();
+ var heskUrl = $('p#hesk-path').text();
+ var $tableBody = $('#table-body');
+
+ $.ajax({
+ method: 'GET',
+ url: heskUrl + 'api/index.php/v1/service-messages',
+ headers: { 'X-Internal-Call': true },
+ success: function(data) {
+ $tableBody.html('');
+
+ if (data.length === 0) {
+ $tableBody.append('' + mfhLang.text('no_sm') + ' ');
+ $('#overlay').hide();
+ return;
+ }
+
+ var first = true;
+ var lastElement = null;
+ $.each(data, function() {
+ var $template = $($('#service-message-template').html());
+
+ $template.find('[data-property="id"]').attr('data-value', this.id);
+ $template.find('span[data-property="title"]').html(
+ getFormattedTitle(this.icon, this.title, this.style));
+ $template.find('span[data-property="author"]').text(users[this.createdBy].name);
+ if (this.published) {
+ $template.find('span[data-property="type"]').text(mfhLang.text('sm_published'));
+ } else {
+ $template.find('span[data-property="type"]').text(mfhLang.text('sm_draft'));
+ }
+ $template.find('[data-property="language"]').text(this.language === 'ALL' ?
+ mfhLang.text('all') :
+ languages[this.language]);
+
+ $tableBody.append($template);
+
+ serviceMessages[this.id] = this;
+
+ lastElement = this;
+
+ if (first) {
+ $template.find('[data-direction="up"]').css('visibility', 'hidden');
+ first = false;
+ }
+ });
+
+ if (lastElement) {
+ //-- Hide the down arrow on the last element
+ $('[data-value="' + lastElement.id + '"]').parent().parent()
+ .find('[data-direction="down"]').css('visibility', 'hidden');
+ }
+ },
+ error: function(data) {
+ mfhAlert.errorWithLog(mfhLang.text('error_retrieving_sm'), data.responseJSON);
+ console.error(data);
+ },
+ complete: function() {
+ $('#overlay').hide();
+ }
+ });
+}
+
+function getFormattedTitle(icon, title, style) {
+ var $template = $($('#service-message-title-template').html());
+
+ var alertClass = 'none';
+ switch (style) {
+ case 'ERROR':
+ alertClass = 'alert alert-danger';
+ break;
+ case 'NOTICE':
+ alertClass = 'alert alert-warning';
+ break;
+ case 'INFO':
+ alertClass = 'alert alert-info';
+ break;
+ case 'SUCCESS':
+ alertClass = 'alert alert-success';
+ break;
+ }
+ $template.addClass(alertClass)
+ .find('[data-property="icon"]').addClass(icon).end()
+ .find('[data-property="title"]').text(title);
+
+ return $template;
+}
+
+function getServiceMessagePreview(icon, title, message, style) {
+ var $template = $('#service-message-preview-template').html();
+
+ var alertClass = 'none';
+ switch (style) {
+ case 'ERROR':
+ alertClass = 'alert alert-danger';
+ break;
+ case 'NOTICE':
+ alertClass = 'alert alert-warning';
+ break;
+ case 'INFO':
+ alertClass = 'alert alert-info';
+ break;
+ case 'SUCCESS':
+ alertClass = 'alert alert-success';
+ break;
+ }
+ $template = $template.replace('none', alertClass)
+ .replace('{{TITLE}}', title)
+ .replace('{{MESSAGE}}', message);
+ $template = $($template);
+ if (icon !== '') {
+ $template.find('i.fa').removeClass('fa').addClass(icon);
+ }
+
+ return $template;
+}
+
+function bindEditModal() {
+ $(document).on('click', '[data-action="edit"]', function() {
+ var element = serviceMessages[$(this).parent().parent().find('[data-property="id"]').data('value')];
+ var $modal = $('#service-message-modal');
+ $modal.find('#preview-pane').html('').end()
+ .find('input[name="location[]"]').prop('checked', false);
+
+ $modal.find('#edit-label').show();
+ $modal.find('#create-label').hide();
+
+ $modal.find('input[name="style"][value="' + (g_styles[element.style]) + '"]').prop('checked', 'checked').end()
+ .find('input[name="type"][value="' + (element.published ? 0 : 1) + '"]')
+ .prop('checked', 'checked').end()
+ .find('input[name="title"]').val(element.title).end()
+ .find('input[name="id"]').val(element.id).end()
+ .find('input[name="order"]').val(element.order).end()
+ .find('select[name="language"]').val(element.language).end();
+ setIcon(element.icon);
+
+ $.each(element.locations, function() {
+ $modal.find('input[name="location[]"][value="' + this + '"]').prop('checked', 'checked');
+ });
+
+ if ($('input[name="kb_wysiwyg"]').val() === "1") {
+ tinyMCE.get('content').setContent(element.message);
+ } else {
+ $('textarea[name="message"]').val(element.message);
+ }
+
+ $('.tab-pane#sm-contents').addClass('active');
+ $('.tab-pane#properties').removeClass('active');
+ $('.nav-tabs > li').removeClass('active');
+ $('.nav-tabs > li:first').addClass('active');
+
+
+ $modal.modal('show');
+ });
+}
+
+function bindCreateModal() {
+ $('#create-button').click(function() {
+ var $modal = $('#service-message-modal');
+ $modal.find('#edit-label').hide().end()
+ .find('#create-label').show().end()
+ .find('input[name="style"][value="0"]').prop('checked', 'checked').end() // "None" style
+ .find('input[name="type"][value="0"]').prop('checked', 'checked').end() // Published
+ .find('input[name="title"]').val('').end()
+ .find('input[name="id"]').val(-1).end()
+ .find('input[name="order"]').val('').end()
+ .find('#preview-pane').html('').end()
+ .find('input[name="location[]"]').prop('checked', false)
+ .find('select[name="language"]').val('ALL');
+ setIcon('');
+
+ if ($('input[name="kb_wysiwyg"]').val() === "1") {
+ tinyMCE.get('content').setContent('');
+ } else {
+ $('textarea[name="message"]').val('');
+ }
+
+ $('.tab-pane#sm-contents').addClass('active');
+ $('.tab-pane#properties').removeClass('active');
+ $('.nav-tabs > li').removeClass('active');
+ $('.nav-tabs > li:first').addClass('active');
+
+ $modal.modal('show');
+ });
+}
+
+function bindFormSubmit() {
+ $('form#service-message').submit(function(e) {
+ e.preventDefault();
+ var heskUrl = $('p#hesk-path').text();
+
+ var $modal = $('#service-message-modal');
+
+ var styles = [];
+ styles[0] = "NONE";
+ styles[1] = "SUCCESS";
+ styles[2] = "INFO";
+ styles[3] = "NOTICE";
+ styles[4] = "ERROR";
+
+ var domLocations = $modal.find('input[name="location[]"]:checked');
+
+ var locations = [];
+ $.each(domLocations, function() {
+ locations.push($(this).val());
+ });
+
+ var data = {
+ icon: $modal.find('input[name="icon"]').val(),
+ title: $modal.find('input[name="title"]').val(),
+ message: getMessage(),
+ published: $modal.find('input[name="type"]:checked').val() === "0",
+ style: styles[$modal.find('input[name="style"]:checked').val()],
+ order: $modal.find('input[name="order"]').val(),
+ language: $modal.find('select[name="language"]').val(),
+ locations: locations
+ };
+
+ var url = heskUrl + 'api/index.php/v1/service-messages/';
+ var method = 'POST';
+
+ var serviceMessageId = parseInt($modal.find('input[name="id"]').val());
+ if (serviceMessageId !== -1) {
+ url += serviceMessageId;
+ method = 'PUT';
+ }
+
+ $modal.find('#action-buttons').find('.cancel-button').attr('disabled', 'disabled');
+ $modal.find('#action-buttons').find('.save-button').attr('disabled', 'disabled');
+
+ $.ajax({
+ method: 'POST',
+ url: url,
+ headers: {
+ 'X-Internal-Call': true,
+ 'X-HTTP-Method-Override': method
+ },
+ data: JSON.stringify(data),
+ success: function(data) {
+ if (serviceMessageId === -1) {
+ mfhAlert.success(mfhLang.text('sm_added'));
+ } else {
+ mfhAlert.success(mfhLang.text('sm_mdf'));
+ }
+ $modal.modal('hide');
+ loadTable();
+ },
+ error: function(data) {
+ mfhAlert.errorWithLog(mfhLang.text('error_saving_updating_sm'), data.responseJSON);
+ console.error(data);
+ },
+ complete: function(data) {
+ $modal.find('#action-buttons').find('.cancel-button').removeAttr('disabled');
+ $modal.find('#action-buttons').find('.save-button').removeAttr('disabled');
+ }
+ });
+ });
+}
+
+function bindDeleteButton() {
+ $(document).on('click', '[data-action="delete"]', function() {
+ $('#overlay').show();
+
+ var heskUrl = $('p#hesk-path').text();
+ var element = serviceMessages[$(this).parent().parent().find('[data-property="id"]').data('value')];
+
+ $.ajax({
+ method: 'POST',
+ url: heskUrl + 'api/index.php/v1/service-messages/' + element.id,
+ headers: {
+ 'X-Internal-Call': true,
+ 'X-HTTP-Method-Override': 'DELETE'
+ },
+ success: function() {
+ mfhAlert.success(mfhLang.text('sm_deleted'));
+ loadTable();
+ },
+ error: function(data) {
+ $('#overlay').hide();
+ mfhAlert.errorWithLog(mfhLang.text('error_deleting_sm'), data.responseJSON);
+ console.error(data);
+ }
+ });
+ });
+}
+
+function bindSortButtons() {
+ $(document).on('click', '[data-action="sort"]', function() {
+ $('#overlay').show();
+ var heskUrl = $('p#hesk-path').text();
+ var direction = $(this).data('direction');
+ var element = serviceMessages[$(this).parent().parent().parent().find('[data-property="id"]').data('value')];
+
+ $.ajax({
+ method: 'POST',
+ url: heskUrl + 'api/index.php/v1-internal/service-messages/' + element.id + '/sort/' + direction,
+ headers: { 'X-Internal-Call': true },
+ success: function() {
+ loadTable();
+ },
+ error: function(data) {
+ mfhAlert.errorWithLog(mfhLang.text('error_sorting_categories'), data.responseJSON);
+ console.error(data);
+ $('#overlay').hide();
+ }
+ })
+ });
+}
+
+function bindPreview() {
+ $('.preview-button').click(function() {
+ var styles = [];
+ styles[0] = "NONE";
+ styles[1] = "SUCCESS";
+ styles[2] = "INFO";
+ styles[3] = "NOTICE";
+ styles[4] = "ERROR";
+
+ var $modal = $('#service-message-modal');
+ var data = {
+ icon: $modal.find('input[name="icon"]').val(),
+ title: $modal.find('input[name="title"]').val(),
+ message: getMessage(),
+ published: $modal.find('input[name="type"]:checked').val() === "0",
+ style: styles[$modal.find('input[name="style"]:checked').val()],
+ order: $modal.find('input[name="order"]').val()
+ };
+
+ var preview = getServiceMessagePreview(data.icon, data.title, data.message, data.style);
+ $('#preview-pane').html(preview);
+ });
+}
+
+function getMessage() {
+ if ($('input[name="kb_wysiwyg"]').val() === "1") {
+ return tinyMCE.get('content').getContent();
+ }
+
+ return $('textarea[name="message"]').val();
+}
\ No newline at end of file
diff --git a/knowledgebase.php b/knowledgebase.php
index fdb2a3a4..22e86586 100644
--- a/knowledgebase.php
+++ b/knowledgebase.php
@@ -254,6 +254,13 @@ if (!$show['show']) {
require_once(HESK_PATH . 'inc/header.inc.php');
hesk_kb_header($hesk_settings['kb_link']);
+
+ // Service messages
+ $service_messages = mfh_get_service_messages('CUSTOMER_VIEW_KB_ARTICLE');
+ foreach ($service_messages as $sm) {
+ hesk_service_message($sm);
+ }
+
// Update views by 1 - exclude known bots and reloads because of ratings
if (!isset($_GET['rated']) && !hesk_detect_bots()) {
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "kb_articles` SET `views`=`views`+1 WHERE `id`={$artid}");
@@ -406,11 +413,11 @@ if (!$show['show']) {
hesk_kb_header($hesk_settings['kb_link']);
}
- // If we are in "Knowledgebase only" mode show system messages
- if ($catid == 1 && hesk_check_kb_only(false)) {
+ // Display service messages on the default category
+ if ($catid == 1) {
// Service messages
- $res = hesk_dbQuery('SELECT `title`, `message`, `style` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` WHERE `type`='0' ORDER BY `order` ASC");
- while ($sm = hesk_dbFetchAssoc($res)) {
+ $service_messages = mfh_get_service_messages('CUSTOMER_KB_HOME');
+ foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
}
diff --git a/language/en/text.php b/language/en/text.php
index e55cd0e4..7d62e3f3 100644
--- a/language/en/text.php
+++ b/language/en/text.php
@@ -2214,5 +2214,20 @@ $hesklang['audit_due_date_changed'] = '%s changed due date to %s';
$hesklang['audit_linked_ticket'] = '%s linked ticket %s to this ticket';
$hesklang['audit_unlinked_ticket'] = '%s unlinked ticket %s';
+// Added or modified in Mods for HESK 3.3.0
+$hesklang['error_retrieving_sm'] = 'An error occurred retrieving service messages!';
+$hesklang['error_saving_updating_sm'] = 'An error occurred creating / saving the service message!';
+$hesklang['error_deleting_sm'] = 'An error occurred when trying to delete the service message.';
+$hesklang['error_sorting_sm'] = 'An error occurred sorting service messages!';
+$hesklang['sm_location'] = 'Location'; // Location for service messages
+$hesklang['sm_customer_pages'] = 'Customer Pages';
+$hesklang['sm_staff_pages'] = 'Staff Pages';
+$hesklang['sm_homepage'] = 'Homepage';
+$hesklang['sm_kb_home'] = 'Knowledgebase Home';
+$hesklang['sm_view_kb_article'] = 'View Knowledgebase Article';
+$hesklang['sm_submit_ticket'] = 'Submit Ticket';
+$hesklang['sm_view_ticket'] = 'View Ticket';
+$hesklang['sm_login_page'] = 'Login Page';
+
// DO NOT CHANGE BELOW
if (!defined('IN_SCRIPT')) die('PHP syntax OK!');
diff --git a/ticket.php b/ticket.php
index cb7ef11b..316dac96 100644
--- a/ticket.php
+++ b/ticket.php
@@ -215,6 +215,13 @@ if (!$show['show']) {