Pull 3.3.0 from upstream

master
Skylar Ittner 6 years ago
commit 1017b64913

93
.gitignore vendored

@ -8,7 +8,6 @@ admin/archive.php
admin/custom_statuses.php admin/custom_statuses.php
admin/email_templates.php admin/email_templates.php
admin/generate_spam_question.php admin/generate_spam_question.php
admin/priority.php
admin/test_connection.php admin/test_connection.php
attachments/index.htm attachments/index.htm
cache/ cache/
@ -198,52 +197,52 @@ inc/tabs/tabber-minimized.js
inc/tabs/tabber.css inc/tabs/tabber.css
inc/timer/hesk_timer.js inc/timer/hesk_timer.js
inc/timer/index.htm inc/timer/index.htm
inc/tiny_mce/3.5.11/langs/en.js inc/tiny_mce/3.5.12/langs/en.js
inc/tiny_mce/3.5.11/license.txt inc/tiny_mce/3.5.12/license.txt
inc/tiny_mce/3.5.11/themes/advanced/about.htm inc/tiny_mce/3.5.12/themes/advanced/about.htm
inc/tiny_mce/3.5.11/themes/advanced/anchor.htm inc/tiny_mce/3.5.12/themes/advanced/anchor.htm
inc/tiny_mce/3.5.11/themes/advanced/charmap.htm inc/tiny_mce/3.5.12/themes/advanced/charmap.htm
inc/tiny_mce/3.5.11/themes/advanced/color_picker.htm inc/tiny_mce/3.5.12/themes/advanced/color_picker.htm
inc/tiny_mce/3.5.11/themes/advanced/editor_template.js inc/tiny_mce/3.5.12/themes/advanced/editor_template.js
inc/tiny_mce/3.5.11/themes/advanced/image.htm inc/tiny_mce/3.5.12/themes/advanced/image.htm
inc/tiny_mce/3.5.11/themes/advanced/img/colorpicker.jpg inc/tiny_mce/3.5.12/themes/advanced/img/colorpicker.jpg
inc/tiny_mce/3.5.11/themes/advanced/img/flash.gif inc/tiny_mce/3.5.12/themes/advanced/img/flash.gif
inc/tiny_mce/3.5.11/themes/advanced/img/icons.gif inc/tiny_mce/3.5.12/themes/advanced/img/icons.gif
inc/tiny_mce/3.5.11/themes/advanced/img/iframe.gif inc/tiny_mce/3.5.12/themes/advanced/img/iframe.gif
inc/tiny_mce/3.5.11/themes/advanced/img/pagebreak.gif inc/tiny_mce/3.5.12/themes/advanced/img/pagebreak.gif
inc/tiny_mce/3.5.11/themes/advanced/img/quicktime.gif inc/tiny_mce/3.5.12/themes/advanced/img/quicktime.gif
inc/tiny_mce/3.5.11/themes/advanced/img/realmedia.gif inc/tiny_mce/3.5.12/themes/advanced/img/realmedia.gif
inc/tiny_mce/3.5.11/themes/advanced/img/shockwave.gif inc/tiny_mce/3.5.12/themes/advanced/img/shockwave.gif
inc/tiny_mce/3.5.11/themes/advanced/img/trans.gif inc/tiny_mce/3.5.12/themes/advanced/img/trans.gif
inc/tiny_mce/3.5.11/themes/advanced/img/video.gif inc/tiny_mce/3.5.12/themes/advanced/img/video.gif
inc/tiny_mce/3.5.11/themes/advanced/img/windowsmedia.gif inc/tiny_mce/3.5.12/themes/advanced/img/windowsmedia.gif
inc/tiny_mce/3.5.11/themes/advanced/js/about.js inc/tiny_mce/3.5.12/themes/advanced/js/about.js
inc/tiny_mce/3.5.11/themes/advanced/js/anchor.js inc/tiny_mce/3.5.12/themes/advanced/js/anchor.js
inc/tiny_mce/3.5.11/themes/advanced/js/charmap.js inc/tiny_mce/3.5.12/themes/advanced/js/charmap.js
inc/tiny_mce/3.5.11/themes/advanced/js/color_picker.js inc/tiny_mce/3.5.12/themes/advanced/js/color_picker.js
inc/tiny_mce/3.5.11/themes/advanced/js/image.js inc/tiny_mce/3.5.12/themes/advanced/js/image.js
inc/tiny_mce/3.5.11/themes/advanced/js/link.js inc/tiny_mce/3.5.12/themes/advanced/js/link.js
inc/tiny_mce/3.5.11/themes/advanced/js/source_editor.js inc/tiny_mce/3.5.12/themes/advanced/js/source_editor.js
inc/tiny_mce/3.5.11/themes/advanced/langs/en.js inc/tiny_mce/3.5.12/themes/advanced/langs/en.js
inc/tiny_mce/3.5.11/themes/advanced/langs/en_dlg.js inc/tiny_mce/3.5.12/themes/advanced/langs/en_dlg.js
inc/tiny_mce/3.5.11/themes/advanced/link.htm inc/tiny_mce/3.5.12/themes/advanced/link.htm
inc/tiny_mce/3.5.11/themes/advanced/shortcuts.htm inc/tiny_mce/3.5.12/themes/advanced/shortcuts.htm
inc/tiny_mce/3.5.11/themes/advanced/skins/default/content.css inc/tiny_mce/3.5.12/themes/advanced/skins/default/content.css
inc/tiny_mce/3.5.11/themes/advanced/skins/default/dialog.css inc/tiny_mce/3.5.12/themes/advanced/skins/default/dialog.css
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/buttons.png inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/buttons.png
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/items.gif inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/items.gif
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/menu_arrow.gif inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/menu_arrow.gif
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/menu_check.gif inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/menu_check.gif
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/progress.gif inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/progress.gif
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/tabs.gif inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/tabs.gif
inc/tiny_mce/3.5.11/themes/advanced/skins/default/ui.css inc/tiny_mce/3.5.12/themes/advanced/skins/default/ui.css
inc/tiny_mce/3.5.11/themes/advanced/source_editor.htm inc/tiny_mce/3.5.12/themes/advanced/source_editor.htm
inc/tiny_mce/3.5.11/tiny_mce.js inc/tiny_mce/3.5.12/tiny_mce.js
inc/tiny_mce/3.5.11/tiny_mce_popup.js inc/tiny_mce/3.5.12/tiny_mce_popup.js
inc/tiny_mce/3.5.11/utils/editable_selects.js inc/tiny_mce/3.5.12/utils/editable_selects.js
inc/tiny_mce/3.5.11/utils/form_utils.js inc/tiny_mce/3.5.12/utils/form_utils.js
inc/tiny_mce/3.5.11/utils/mctabs.js inc/tiny_mce/3.5.12/utils/mctabs.js
inc/tiny_mce/3.5.11/utils/validate.js inc/tiny_mce/3.5.12/utils/validate.js
inc/treemenu/TreeMenu.php inc/treemenu/TreeMenu.php
inc/treemenu/index.htm inc/treemenu/index.htm
inc/zip/Zip.php inc/zip/Zip.php

@ -1,32 +1,90 @@
image: tetraweb/php
stages: stages:
- validate
- test - test
- deploy - package
before_script: before_script:
- apt-get update - bash ci/docker_install.sh > /dev/null
- apt-get install zip unzip
- cd api validate:7.2:
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" image: php:7.2
- php composer-setup.php stage: validate
- php -r "unlink('composer-setup.php');" script:
- php composer.phar update - bash ci/php_lint.sh ./
test: validate:7.1:
image: php:7.1
stage: validate
script:
- bash ci/php_lint.sh ./
validate:7.0:
image: php:7.0
stage: validate
script:
- bash ci/php_lint.sh ./
validate:5.6:
image: php:5.6
stage: validate
script:
- bash ci/php_lint.sh ./
validate:5.5:
image: php:5.5
stage: validate
script:
- bash ci/php_lint.sh ./
validate:5.4:
image: php:5.4
stage: validate
script:
- bash ci/php_lint.sh ./
validate:5.3:
image: php:5.3
stage: validate
script:
- bash ci/php_lint.sh ./
test:7.1:
image: php:7.1
stage: test
script:
- cd api
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
- php composer.phar update
- php composer.phar install
- cd Tests
- phpunit
test:7.2:
image: php:7.2
stage: test stage: test
script: script:
- composer install - cd api
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
- php composer.phar update
- php composer.phar install
- cd Tests - cd Tests
- phpunit - phpunit
deploy: package:
image: tetraweb/php
when: manual when: manual
stage: deploy stage: package
script: script:
- apt-get update
- apt-get install zip unzip
- cd api
- composer install --no-dev - composer install --no-dev
- cd ../ci - cd ../ci
- bash build_zip.sh - bash build_zip.sh
artifacts: artifacts:
paths: paths:
- release.zip - release.zip

@ -54,7 +54,15 @@ else {
?> ?>
<div class="content-wrapper"> <div class="content-wrapper">
<section class="content"> <section class="content">
<?php hesk_handle_messages(); ?> <?php
// Service messages
$service_messages = mfh_get_service_messages('STAFF_HOME');
foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
hesk_handle_messages();
?>
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h1 class="box-title"> <h1 class="box-title">

@ -189,15 +189,20 @@ if ($hesk_settings['attachments']['use'] && !empty($attachments)) {
// Add reply // Add reply
$html = $modsForHesk_settings['rich_text_for_tickets']; $html = $modsForHesk_settings['rich_text_for_tickets'];
if ($submit_as_customer) { if ($submit_as_customer) {
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($ticket['name'])) . "','" . hesk_dbEscape($message . "<br /><br /><i>{$hesklang['creb']} {$_SESSION['name']}</i>") . "',NOW(),'" . hesk_dbEscape($myattachments) . "', '" . $html . "')"); hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($ticket['name'])) . "','" . hesk_dbEscape($message . "<br /><br /><i>{$hesklang['creb']} {$_SESSION['name']}</i>") . "', NOW(),'" . hesk_dbEscape($myattachments) . "', '" . $html . "')");
} else { } else {
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($_SESSION['name'])) . "','" . hesk_dbEscape($message) . "',NOW(),'" . hesk_dbEscape($myattachments) . "','" . intval($_SESSION['id']) . "', '" . $html . "')"); hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($_SESSION['name'])) . "','" . hesk_dbEscape($message) . "', NOW(),'" . hesk_dbEscape($myattachments) . "','" . intval($_SESSION['id']) . "', '" . $html . "')");
} }
/* Track ticket status changes for history */ /* Track ticket status changes for history */
$revision = ''; $revision = '';
/* Change the status of priority? */ /* Change the status of priority? */
$audit_priority = null;
$audit_closed = null;
$audit_status = null;
$audit_customer_status = null;
$audit_assigned_self = null;
if (!empty($_POST['set_priority'])) { if (!empty($_POST['set_priority'])) {
$priority = intval(hesk_POST('priority')); $priority = intval(hesk_POST('priority'));
if ($priority < 0 || $priority > 3) { if ($priority < 0 || $priority > 3) {
@ -211,9 +216,17 @@ if (!empty($_POST['set_priority'])) {
3 => $hesklang['low'] 3 => $hesklang['low']
); );
$revision = sprintf($hesklang['thist8'], hesk_date(), $options[$priority], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $plain_options = array(
0 => 'critical',
1 => 'high',
2 => 'medium',
3 => 'low'
);
$priority_sql = ",`priority`='$priority' ";
$priority_sql = ",`priority`='$priority', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') "; $audit_priority = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $plain_options[$priority]);
} else { } else {
$priority_sql = ""; $priority_sql = "";
} }
@ -238,8 +251,11 @@ if ($ticket['locked']) {
$newStatus = hesk_dbFetchAssoc($newStatusRs); $newStatus = hesk_dbFetchAssoc($newStatusRs);
if ($newStatus['IsClosed'] && hesk_checkPermission('can_resolve', 0)) { if ($newStatus['IsClosed'] && hesk_checkPermission('can_resolve', 0)) {
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_closed = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
$sql_status = " , `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . ", `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') "; $audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => mfh_getDisplayTextForStatusId($new_status)
);
$sql_status = " , `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . " ";
// Lock the ticket if customers are not allowed to reopen tickets // Lock the ticket if customers are not allowed to reopen tickets
if ($hesk_settings['custopen'] != 1) { if ($hesk_settings['custopen'] != 1) {
@ -247,8 +263,8 @@ if ($ticket['locked']) {
} }
} else { } else {
// Ticket isn't being closed, just add the history to the sql query (or tried to close but doesn't have permission) // Ticket isn't being closed, just add the history to the sql query (or tried to close but doesn't have permission)
$revision = sprintf($hesklang['thist9'], hesk_date(), $hesklang[$newStatus['Key']], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
$sql_status = " , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') "; 1 => mfh_getDisplayTextForStatusId($new_status));
} }
} }
} // -> Submit as Customer reply } // -> Submit as Customer reply
@ -259,8 +275,8 @@ elseif ($submit_as_customer) {
$new_status = $customerReplyStatus['ID']; $new_status = $customerReplyStatus['ID'];
if ($ticket['status'] != $new_status) { if ($ticket['status'] != $new_status) {
$revision = sprintf($hesklang['thist9'], hesk_date(), $hesklang['wait_reply'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_customer_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
$sql_status = " , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') "; 1 => mfh_getDisplayTextForStatusId($new_status));
} }
} // -> Default: submit as "Replied by staff" } // -> Default: submit as "Replied by staff"
else { else {
@ -278,12 +294,21 @@ $sql .= $submit_as_customer ? "`lastreplier`='0', `replierid`='0' " : "`lastrepl
if ($time_worked == '00:00:00') { if ($time_worked == '00:00:00') {
$sql .= ", `lastchange` = NOW() "; $sql .= ", `lastchange` = NOW() ";
} else { } else {
$parts = explode(':', $ticket['time_worked']);
$seconds = ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
$parts = explode(':', $time_worked);
$seconds += ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
require(HESK_PATH . 'inc/reporting_functions.inc.php');
$ticket['time_worked'] = hesk_SecondsToHHMMSS($seconds);
$sql .= ",`time_worked` = ADDTIME(`time_worked`,'" . hesk_dbEscape($time_worked) . "') "; $sql .= ",`time_worked` = ADDTIME(`time_worked`,'" . hesk_dbEscape($time_worked) . "') ";
} }
if (!empty($_POST['assign_self']) && (hesk_checkPermission('can_assign_self', 0) || (isset($_REQUEST['isManager']) && $_REQUEST['isManager']))) { if (!empty($_POST['assign_self']) && (hesk_checkPermission('can_assign_self', 0) || (isset($_REQUEST['isManager']) && $_REQUEST['isManager']))) {
$revision = sprintf($hesklang['thist2'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')', $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_assigned_self = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
$sql .= " , `owner`=" . intval($_SESSION['id']) . ", `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') "; $sql .= " , `owner`=" . intval($_SESSION['id']) . " ";
} }
$sql .= " $priority_sql "; $sql .= " $priority_sql ";
@ -306,6 +331,29 @@ unset($sql);
/* Update number of replies in the users table */ /* Update number of replies in the users table */
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `replies`=`replies`+1 WHERE `id`='" . intval($_SESSION['id']) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `replies`=`replies`+1 WHERE `id`='" . intval($_SESSION['id']) . "'");
//-- Insert necessary audit trail records
if ($audit_priority != null) {
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_priority', hesk_date(), $audit_priority);
}
if ($audit_closed != null) {
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_closed', hesk_date(), $audit_closed);
}
if ($audit_status != null) {
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_status', hesk_date(), $audit_status);
}
if ($audit_customer_status != null) {
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_status', hesk_date(),
$audit_customer_status);
}
if ($audit_assigned_self != null) {
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_assigned_self', hesk_date(), $audit_assigned_self);
}
// --> Prepare reply message // --> Prepare reply message
// 1. Generate the array with ticket info that can be used in emails // 1. Generate the array with ticket info that can be used in emails
@ -324,7 +372,9 @@ $info = array(
'dt' => hesk_date($ticket['dt'], true), 'dt' => hesk_date($ticket['dt'], true),
'lastchange' => hesk_date($ticket['lastchange'], true), 'lastchange' => hesk_date($ticket['lastchange'], true),
'id' => $ticket['id'], 'id' => $ticket['id'],
'language' => $ticket['language'] 'language' => $ticket['language'],
'time_worked' => $ticket['time_worked'],
'last_reply_by' => ($submit_as_customer ? $ticket['name'] : $_SESSION['name']),
); );
// 2. Add custom fields to the array // 2. Add custom fields to the array

@ -93,19 +93,20 @@ if ($hesk_settings['attachments']['use'] && !defined('HESK_DEMO')) {
$tmp = @ini_get('upload_max_filesize'); $tmp = @ini_get('upload_max_filesize');
if ($tmp) { if ($tmp) {
$last = strtoupper(substr($tmp, -1)); $last = strtoupper(substr($tmp, -1));
$number = substr($tmp, 0, -1);
switch ($last) { switch ($last) {
case 'K': case 'K':
$tmp = $tmp * 1024; $tmp = $number * 1024;
break; break;
case 'M': case 'M':
$tmp = $tmp * 1048576; $tmp = $number * 1048576;
break; break;
case 'G': case 'G':
$tmp = $tmp * 1073741824; $tmp = $number * 1073741824;
break; break;
default: default:
$tmp = $tmp; $tmp = $number;
} }
if ($tmp < $hesk_settings['attachments']['max_size']) { if ($tmp < $hesk_settings['attachments']['max_size']) {
@ -117,19 +118,20 @@ if ($hesk_settings['attachments']['use'] && !defined('HESK_DEMO')) {
$tmp = @ini_get('post_max_size'); $tmp = @ini_get('post_max_size');
if ($tmp) { if ($tmp) {
$last = strtoupper(substr($tmp, -1)); $last = strtoupper(substr($tmp, -1));
$number = substr($tmp, 0, -1);
switch ($last) { switch ($last) {
case 'K': case 'K':
$tmp = $tmp * 1024; $tmp = $number * 1024;
break; break;
case 'M': case 'M':
$tmp = $tmp * 1048576; $tmp = $number * 1048576;
break; break;
case 'G': case 'G':
$tmp = $tmp * 1073741824; $tmp = $number * 1073741824;
break; break;
default: default:
$tmp = $tmp; $tmp = $number;
} }
if ($tmp < ($hesk_settings['attachments']['max_size'] * $hesk_settings['attachments']['max_number'] + 524288)) { if ($tmp < ($hesk_settings['attachments']['max_size'] * $hesk_settings['attachments']['max_number'] + 524288)) {
@ -355,86 +357,121 @@ $modsForHesk_settings = mfh_getSettings();
<td class="text-right"> <td class="text-right">
<?php echo $hesklang['v']; ?>: <?php echo $hesklang['v']; ?>:
</td> </td>
<?php <td class="pad-right-10" id="hesk-version-status">
$cellClass = '';
if ($hesk_settings['check_updates']) {
$latest = hesk_checkVersion();
if ($latest === true) {
$cellClass = 'success';
} elseif ($latest != -1) {
$cellClass = 'warning';
}
}
?>
<td class="pad-right-10 <?php echo $cellClass; ?>">
<?php echo $hesk_settings['hesk_version']; ?> <?php echo $hesk_settings['hesk_version']; ?>
<?php <?php if ($hesk_settings['check_updates']) : ?>
if ($hesk_settings['check_updates']) { -
<i class="spinner fa fa-spin fa-spinner"></i>
if ($latest === true) { <span class="up-to-date green" style="display: none">
echo ' - <span class="green">' . $hesklang['hud'] . '</span> '; <?php echo $hesklang['hud']; ?>
} elseif ($latest != -1) { </span>
// Is this a beta/dev version? <span class="beta-version orange" style="display: none">
if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) { <?php echo $hesklang['beta']; ?>
echo ' <span class="dark-orange">' . $hesklang['beta'] . '</span> '; ?> <a <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a>
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php </span>
} else { <span class="update-available orange" style="display: none">
echo ' - <span class="dark-orange bold">' . $hesklang['hnw'] . '</span> '; ?> <a <?php echo $hesklang['hnw']; ?>
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['getup']; ?></a><?php target="_blank">
} <?php echo $hesklang['getup']; ?>
} else { </a>
?> - <a </span>
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" <a class="response-error" href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php target="_blank" style="display: none"><?php echo $hesklang['check4updates']; ?></a>
} <script>
} else { var heskUrl = $('p#hesk-path').text();
?> - <a var $versionStatus = $('#hesk-version-status');
$.ajax({
url: heskUrl + 'api/index.php/v1-public/hesk-version',
method: 'GET',
success: function(data) {
if ('<?php echo $hesk_settings['hesk_version']; ?>' === data.version) {
$versionStatus.addClass('success');
$versionStatus.find('.up-to-date').show();
} else if (<?php echo strpos($hesk_settings['hesk_version'], 'beta') ||
strpos($hesk_settings['hesk_version'], 'dev') ||
strpos($hesk_settings['hesk_version'], 'RC') ? 'true' : 'false'; ?>) {
$versionStatus.addClass('warning');
$versionStatus.find('.beta-version').show();
} else {
$versionStatus.addClass('warning');
$versionStatus.find('.update-available').show();
}
},
error: function() {
$versionStatus.find('.response-error').show();
},
complete: function(data) {
$versionStatus.find('.spinner').hide();
}
});
</script>
<?php else: ?>
- <a
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php target="_blank"><?php echo $hesklang['check4updates']; ?></a>
} <?php endif; ?>
?>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="text-right pad-up-5"> <td class="text-right pad-up-5">
<?php echo $hesklang['mods_for_hesk_version']; ?>: <?php echo $hesklang['mods_for_hesk_version']; ?>:
</td> </td>
<?php <td class="pad-right-10 pad-up-5" id="mfh-version-status">
$cellClass = '';
if ($hesk_settings['check_updates']) {
$latest = hesk_checkMfhVersion($modsForHeskVersion);
if ($latest === true) {
$cellClass = 'success';
} elseif ($latest != -1) {
$cellClass = 'warning';
}
}
?>
<td class="pad-right-10 pad-up-5 <?php echo $cellClass; ?>">
<?php echo $modsForHeskVersion; ?> <?php echo $modsForHeskVersion; ?>
<?php <?php if ($hesk_settings['check_updates']) : ?>
if ($hesk_settings['check_updates']) { -
if (strpos($modsForHeskVersion, 'beta') || strpos($modsForHeskVersion, 'dev') || strpos($modsForHeskVersion, 'RC')) { <i class="spinner fa fa-spin fa-spinner"></i>
echo ' <span class="dark-orange">' . $hesklang['beta'] . '</span> '; ?> <a <span class="up-to-date green" style="display: none">
href="https://mods-for-hesk.mkochcs.com/versioncheck.php?v=<?php echo $modsForHeskVersion; ?>" <?php echo $hesklang['mfh_up_to_date']; ?>
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php </span>
} elseif ($latest === true) { <span class="beta-version orange" style="display: none">
echo ' - <span class="green">' . $hesklang['mfh_up_to_date'] . '</span>'; <?php echo $hesklang['beta']; ?>
} else { <a href="https://www.mods-for-hesk.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>"
?> - <a href="https://mods-for-hesk.mkochcs.com" target="_blank" target="_blank"><?php echo $hesklang['check4updates']; ?></a>
class="orange bold"><?php echo $hesklang['hnw']; ?></a> </span>
<?php <span class="update-available" style="display: none">
} <a class="orange" href="https://www.mods-for-hesk.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>"
} else { target="_blank">
?> - <a <?php echo $hesklang['hnw']; ?>
href="https://mods-for-hesk.mkochcs.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>" </a>
</span>
<a class="response-error" href="https://www.mods-for-hesk.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>"
target="_blank" style="display: none"><?php echo $hesklang['check4updates']; ?></a>
<?php else: ?>
- <a
href="https://www.mods-for-hesk.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a> target="_blank"><?php echo $hesklang['check4updates']; ?></a>
<?php <?php endif; ?>
} <script>
?> var heskUrl = $('p#hesk-path').text();
var $mfhVersionStatus = $('#mfh-version-status');
$.ajax({
url: heskUrl + 'api/index.php/v1-public/mods-for-hesk-version',
method: 'GET',
success: function(data) {
if ('<?php echo $modsForHeskVersion; ?>' === data.version) {
$mfhVersionStatus.addClass('success');
$mfhVersionStatus.find('.up-to-date').show();
} else if (<?php echo strpos($modsForHeskVersion, 'beta') ||
strpos($modsForHeskVersion, 'dev') ||
strpos($modsForHeskVersion, 'RC') ? 'true' : 'false'; ?>) {
$mfhVersionStatus.addClass('warning');
$mfhVersionStatus.find('.beta-version').show();
} else {
$mfhVersionStatus.addClass('warning');
$mfhVersionStatus.find('.update-available').show();
}
},
error: function() {
$mfhVersionStatus.find('.response-error').show();
},
complete: function(data) {
$mfhVersionStatus.find('.spinner').hide();
}
});
</script>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -2195,6 +2232,106 @@ $modsForHesk_settings = mfh_getSettings();
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label for="show-start-time" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['show_event_start_time']; ?>
<i class="fa fa-question-circle settingsquestionmark" data-toggle="popover"
title="<?php echo $hesklang['show_event_start_time']; ?>"
data-content="<?php echo $hesklang['show_event_start_time_help']; ?>"></i>
</label>
<div class="col-sm-8 form-inline">
<?php
$on = $modsForHesk_settings['calendar_show_start_time'] == 'true' ? 'checked="checked"' : '';
$off = $modsForHesk_settings['calendar_show_start_time'] == 'false' ? 'checked="checked"' : '';
echo '
<div class="radio"><label><input type="radio" name="calendar-show-start-time" value="true" ' . $on . ' /> ' . $hesklang['yes'] . '</label></div><br>
<div class="radio"><label><input type="radio" name="calendar-show-start-time" value="false" ' . $off . ' /> ' . $hesklang['no'] . '</label></div><br>'; ?>
</div>
</div>
<h4 class="bold">
<?php echo $hesklang['business_hours']; ?>
<i class="fa fa-question-circle settingsquestionmark" data-toggle="popover"
title="<?php echo $hesklang['business_hours']; ?>"
data-content="<?php echo $hesklang['business_hours_help']; ?>"></i>
</h4>
<?php
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`");
$business_hours = array();
while ($row = hesk_dbFetchAssoc($rs)) {
$business_hours[intval($row['day_of_week'])]['start'] = $row['start_time'];
$business_hours[intval($row['day_of_week'])]['end'] = $row['end_time'];
}
?>
<div class="form-group">
<label for="business-hours-sunday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d0']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-sunday[0]" value="<?php echo $business_hours[0]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-sunday[1]" value="<?php echo $business_hours[0]['end']; ?>">
</div>
</div>
<div class="form-group">
<label for="business-hours-monday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d1']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-monday[0]" value="<?php echo $business_hours[1]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-monday[1]" value="<?php echo $business_hours[1]['end']; ?>">
</div>
</div>
<div class="form-group">
<label for="business-hours-tuesday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d2']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-tuesday[0]" value="<?php echo $business_hours[2]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-tuesday[1]" value="<?php echo $business_hours[2]['end']; ?>">
</div>
</div>
<div class="form-group">
<label for="business-hours-wednesday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d3']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-wednesday[0]" value="<?php echo $business_hours[3]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-wednesday[1]" value="<?php echo $business_hours[3]['end']; ?>">
</div>
</div>
<div class="form-group">
<label for="business-hours-thursday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d4']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-thursday[0]" value="<?php echo $business_hours[4]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-thursday[1]" value="<?php echo $business_hours[4]['end']; ?>">
</div>
</div>
<div class="form-group">
<label for="business-hours-friday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d5']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-friday[0]" value="<?php echo $business_hours[5]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-friday[1]" value="<?php echo $business_hours[5]['end']; ?>">
</div>
</div>
<div class="form-group">
<label for="business-hours-saturday" class="col-sm-4 col-xs-12 control-label">
<?php echo $hesklang['d6']; ?>
</label>
<div class="col-sm-8 col-xs-12 form-inline">
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-saturday[0]" value="<?php echo $business_hours[6]['start']; ?>">
<?php echo $hesklang['to']; ?>
<input type="text" class="form-control clockpicker" data-autoclose="true" name="business-hours-saturday[1]" value="<?php echo $business_hours[6]['end']; ?>">
</div>
</div>
</div> </div>
</div> </div>
@ -3247,6 +3384,27 @@ $modsForHesk_settings = mfh_getSettings();
</div> </div>
</div> </div>
</div> </div>
<div class="form-group">
<label for="show_number_merged" class="col-sm-4 control-label">
<span class="label label-primary"
data-toggle="tooltip"
title="<?php echo $hesklang['added_in_mods_for_hesk'] ?>"><?php echo $hesklang['mods_for_hesk_acronym']; ?></span>
<?php echo $hesklang['highlight_ticket_rows_based_on_priority']; ?>
<i class="fa fa-question-circle settingsquestionmark" data-toggle="popover"
title="<?php echo $hesklang['highlight_ticket_rows_based_on_priority']; ?>"
data-content="<?php echo $hesklang['highlight_ticket_rows_based_on_priority_help']; ?>"></i>
</label>
<div class="col-sm-8">
<div class="checkbox">
<label>
<input type="checkbox"
name="highlight_ticket_rows_based_on_priority" <?php if ($modsForHesk_settings['highlight_ticket_rows_based_on_priority']) {
echo 'checked';
} ?>> <?php echo $hesklang['highlight_ticket_rows_based_on_priority_descr']; ?>
</label>
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="s_submittedformat" class="col-sm-4 control-label"><?php echo $hesklang['sdf']; ?> <a <label for="s_submittedformat" class="col-sm-4 control-label"><?php echo $hesklang['sdf']; ?> <a
href="Javascript:void(0)" href="Javascript:void(0)"
@ -3362,13 +3520,13 @@ $modsForHesk_settings = mfh_getSettings();
<h4 class="bold"><?php echo $hesklang['other']; ?></h4> <h4 class="bold"><?php echo $hesklang['other']; ?></h4>
<div class="form-group"> <div class="form-group">
<label for="s_ip_whois" class="col-sm-4 control-label"><?php echo $hesklang['ip_whois']; ?> <a <label for="s_ip_whois_url" class="col-sm-4 control-label"><?php echo $hesklang['ip_whois']; ?> <a
href="Javascript:void(0)" href="Javascript:void(0)"
onclick="Javascript:hesk_window('<?php echo $help_folder; ?>misc.html#61','400','500')"><i onclick="Javascript:hesk_window('<?php echo $help_folder; ?>misc.html#61','400','500')"><i
class="fa fa-question-circle settingsquestionmark"></i></a></label> class="fa fa-question-circle settingsquestionmark"></i></a></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input type="text" class="form-control" name="s_ip_whois" size="40" maxlength="255" <input type="text" class="form-control" name="s_ip_whois_url" size="40" maxlength="255"
value="<?php echo $hesk_settings['ip_whois']; ?>"/> value="<?php echo $hesk_settings['ip_whois']; ?>"/>
</div> </div>
</div> </div>
@ -3971,130 +4129,6 @@ $modsForHesk_settings = mfh_getSettings();
} }
function hesk_checkVersion()
{
global $hesk_settings;
if ($latest = hesk_getLatestVersion()) {
if (strlen($latest) > 12) {
return -1;
} elseif ($latest == $hesk_settings['hesk_version']) {
return true;
} else {
return $latest;
}
} else {
return -1;
}
} // END hesk_checkVersion()
function hesk_getLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if (file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt')) {
if (preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600) {
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'https://hesk.com/version';
// Try using cURL
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($hesk_version_url)) {
return hesk_cacheLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
} // END hesk_getLatestVersion()
function hesk_cacheLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest);
return $latest;
} // END hesk_cacheLatestVersion()
function hesk_checkMfhVersion($currentVersion)
{
if ($latest = hesk_getMfhLatestVersion()) {
if (strlen($latest) > 12) {
return -1;
} elseif ($latest == $currentVersion) {
return true;
} else {
return $latest;
}
} else {
return -1;
}
}
function hesk_getMfhLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if (file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt')) {
if (preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt'), $matches) && (time() - intval($matches[1])) < 3600) {
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'http://mods-for-hesk.mkochcs.com/latestversion.php';
// Try using cURL
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheMfhLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = file_get_contents($hesk_version_url)) {
return hesk_cacheMfhLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
}
function hesk_cacheMfhLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt', time() . '|' . $latest);
return $latest;
}
function hesk_testLanguage($return_options = 0) function hesk_testLanguage($return_options = 0)
{ {
global $hesk_settings, $hesklang, $modsForHesk_settings; global $hesk_settings, $hesklang, $modsForHesk_settings;

@ -62,6 +62,7 @@ $set['noreply_mail'] = hesk_validateEmail(hesk_POST('s_noreply_mail'), $hesklang
$set['noreply_name'] = hesk_input(hesk_POST('s_noreply_name')); $set['noreply_name'] = hesk_input(hesk_POST('s_noreply_name'));
$set['noreply_name'] = str_replace(array('\\&quot;', '&lt;', '&gt;'), '', $set['noreply_name']); $set['noreply_name'] = str_replace(array('\\&quot;', '&lt;', '&gt;'), '', $set['noreply_name']);
$set['noreply_name'] = trim(preg_replace('/\s{2,}/', ' ', $set['noreply_name'])); $set['noreply_name'] = trim(preg_replace('/\s{2,}/', ' ', $set['noreply_name']));
$set['noreply_name'] = preg_replace("/\n|\r|\t|%0A|%0D|%08|%09/", '', $set['noreply_name']);
/* --> Language settings */ /* --> Language settings */
$set['can_sel_lang'] = empty($_POST['s_can_sel_lang']) ? 0 : 1; $set['can_sel_lang'] = empty($_POST['s_can_sel_lang']) ? 0 : 1;
@ -424,7 +425,7 @@ $set['daylight'] = empty($_POST['s_daylight']) ? 0 : 1;
$set['timeformat'] = hesk_input(hesk_POST('s_timeformat')) or $set['timeformat'] = 'Y-m-d H:i:s'; $set['timeformat'] = hesk_input(hesk_POST('s_timeformat')) or $set['timeformat'] = 'Y-m-d H:i:s';
/* --> Other */ /* --> Other */
$set['ip_whois'] = hesk_input(hesk_POST('s_ip_whois', 'http://whois.domaintools.com/{IP}')); $set['ip_whois'] = hesk_input(hesk_POST('s_ip_whois_url', 'http://whois.domaintools.com/{IP}'));
// If no {IP} tag append it to the end // If no {IP} tag append it to the end
if (strlen($set['ip_whois']) == 0) { if (strlen($set['ip_whois']) == 0) {
@ -457,6 +458,7 @@ $set['use_bootstrap_theme'] = empty($_POST['use_bootstrap_theme']) ? 0 : 1;
$set['new_kb_article_visibility'] = hesk_checkMinMax(intval(hesk_POST('new_kb_article_visibility')), 0, 2, 2); $set['new_kb_article_visibility'] = hesk_checkMinMax(intval(hesk_POST('new_kb_article_visibility')), 0, 2, 2);
$set['mfh_attachments'] = empty($_POST['email_attachments']) ? 0 : 1; $set['mfh_attachments'] = empty($_POST['email_attachments']) ? 0 : 1;
$set['show_number_merged'] = empty($_POST['show_number_merged']) ? 0 : 1; $set['show_number_merged'] = empty($_POST['show_number_merged']) ? 0 : 1;
$set['highlight_ticket_rows_based_on_priority'] = empty($_POST['highlight_ticket_rows_based_on_priority']) ? 0 : 1;
$set['request_location'] = empty($_POST['request_location']) ? 0 : 1; $set['request_location'] = empty($_POST['request_location']) ? 0 : 1;
$set['category_order_column'] = empty($_POST['category_order_column']) ? 'cat_order' : 'name'; $set['category_order_column'] = empty($_POST['category_order_column']) ? 'cat_order' : 'name';
@ -479,6 +481,7 @@ $set['navbar_title_url'] = hesk_POST('navbar_title_url');
$set['enable_calendar'] = hesk_checkMinMax(intval(hesk_POST('enable_calendar')), 0, 2, 2); $set['enable_calendar'] = hesk_checkMinMax(intval(hesk_POST('enable_calendar')), 0, 2, 2);
$set['first_day_of_week'] = hesk_POST('first-day-of-week', 0); $set['first_day_of_week'] = hesk_POST('first-day-of-week', 0);
$set['default_view'] = hesk_POST('default-view', 'month'); $set['default_view'] = hesk_POST('default-view', 'month');
$set['calendar_show_start_time'] = hesk_POST('calendar-show-start-time', 'true');
if ($set['customer-email-verification-required']) { if ($set['customer-email-verification-required']) {
//-- Don't allow multiple emails if verification is required //-- Don't allow multiple emails if verification is required
@ -516,6 +519,13 @@ $set['admin_sidebar_text_hover'] = hesk_input(hesk_POST('admin-sidebar-text-hove
$set['login_background_type'] = hesk_input(hesk_POST('login-background')); $set['login_background_type'] = hesk_input(hesk_POST('login-background'));
$set['login_box_header'] = hesk_input(hesk_POST('login-box-header')); $set['login_box_header'] = hesk_input(hesk_POST('login-box-header'));
$set['business_hours_sunday'] = hesk_POST_array('business-hours-sunday');
$set['business_hours_monday'] = hesk_POST_array('business-hours-monday');
$set['business_hours_tuesday'] = hesk_POST_array('business-hours-tuesday');
$set['business_hours_wednesday'] = hesk_POST_array('business-hours-wednesday');
$set['business_hours_thursday'] = hesk_POST_array('business-hours-thursday');
$set['business_hours_friday'] = hesk_POST_array('business-hours-friday');
$set['business_hours_saturday'] = hesk_POST_array('business-hours-saturday');
$changedBackground = false; $changedBackground = false;
$loadedAttachmentFuncs = false; $loadedAttachmentFuncs = false;
@ -615,6 +625,7 @@ mfh_updateSetting('use_bootstrap_theme', $set['use_bootstrap_theme']);
mfh_updateSetting('new_kb_article_visibility', $set['new_kb_article_visibility']); mfh_updateSetting('new_kb_article_visibility', $set['new_kb_article_visibility']);
mfh_updateSetting('attachments', $set['mfh_attachments']); mfh_updateSetting('attachments', $set['mfh_attachments']);
mfh_updateSetting('show_number_merged', $set['show_number_merged']); mfh_updateSetting('show_number_merged', $set['show_number_merged']);
mfh_updateSetting('highlight_ticket_rows_based_on_priority', $set['highlight_ticket_rows_based_on_priority']);
mfh_updateSetting('request_location', $set['request_location']); mfh_updateSetting('request_location', $set['request_location']);
mfh_updateSetting('category_order_column', $set['category_order_column'], true); mfh_updateSetting('category_order_column', $set['category_order_column'], true);
mfh_updateSetting('rich_text_for_tickets', $set['rich_text_for_tickets']); mfh_updateSetting('rich_text_for_tickets', $set['rich_text_for_tickets']);
@ -657,6 +668,7 @@ mfh_updateSetting('use_mailgun', $set['use_mailgun'], false);
mfh_updateSetting('enable_calendar', $set['enable_calendar'], false); mfh_updateSetting('enable_calendar', $set['enable_calendar'], false);
mfh_updateSetting('first_day_of_week', $set['first_day_of_week'], false); mfh_updateSetting('first_day_of_week', $set['first_day_of_week'], false);
mfh_updateSetting('default_calendar_view', $set['default_view'], true); mfh_updateSetting('default_calendar_view', $set['default_view'], true);
mfh_updateSetting('calendar_show_start_time', $set['calendar_show_start_time'], true);
mfh_updateSetting('admin_color_scheme', $set['admin_color_scheme'], true); mfh_updateSetting('admin_color_scheme', $set['admin_color_scheme'], true);
mfh_updateSetting('login_background_type', $set['login_background_type'], true); mfh_updateSetting('login_background_type', $set['login_background_type'], true);
@ -671,6 +683,29 @@ if ($changedLoginImage) {
mfh_updateSetting('bootswatch_theme', $set['bootswatch_theme'], true); mfh_updateSetting('bootswatch_theme', $set['bootswatch_theme'], true);
// Update business hours
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_sunday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_sunday'][1]) . "' WHERE `day_of_week` = " . intval(0));
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_monday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_monday'][1]) . "' WHERE `day_of_week` = " . intval(1));
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_tuesday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_tuesday'][1]) . "' WHERE `day_of_week` = " . intval(2));
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_wednesday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_wednesday'][1]) . "' WHERE `day_of_week` = " . intval(3));
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_thursday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_thursday'][1]) . "' WHERE `day_of_week` = " . intval(4));
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_friday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_friday'][1]) . "' WHERE `day_of_week` = " . intval(5));
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
SET `start_time` = '" . hesk_dbEscape($set['business_hours_saturday'][0]) . "',
`end_time` = '" . hesk_dbEscape($set['business_hours_saturday'][1]) . "' WHERE `day_of_week` = " . intval(6));
// Prepare settings file and save it // Prepare settings file and save it
$settings_file_content = '<?php $settings_file_content = '<?php
// Settings file for HESK ' . $set['hesk_version'] . ' // Settings file for HESK ' . $set['hesk_version'] . '

@ -176,11 +176,11 @@ foreach ($hesk_settings['custom_fields'] as $k=>$v) {
$tmpvar['trackid'] = hesk_createID(); $tmpvar['trackid'] = hesk_createID();
// Log who submitted ticket // Log who submitted ticket
$tmpvar['history'] = sprintf($hesklang['thist7'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
$tmpvar['openedby'] = $_SESSION['id']; $tmpvar['openedby'] = $_SESSION['id'];
// Owner // Owner
$tmpvar['owner'] = 0; $tmpvar['owner'] = 0;
$autoassign_owner = null;
if (hesk_checkPermission('can_assign_others', 0)) { if (hesk_checkPermission('can_assign_others', 0)) {
$tmpvar['owner'] = intval(hesk_POST('owner')); $tmpvar['owner'] = intval(hesk_POST('owner'));
@ -192,7 +192,6 @@ if (hesk_checkPermission('can_assign_others', 0)) {
$autoassign_owner = hesk_autoAssignTicket($tmpvar['category']); $autoassign_owner = hesk_autoAssignTicket($tmpvar['category']);
if ($autoassign_owner) { if ($autoassign_owner) {
$tmpvar['owner'] = intval($autoassign_owner['id']); $tmpvar['owner'] = intval($autoassign_owner['id']);
$tmpvar['history'] .= sprintf($hesklang['thist10'], hesk_date(), $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')');
} else { } else {
$tmpvar['owner'] = 0; $tmpvar['owner'] = 0;
} }
@ -315,6 +314,14 @@ $tmpvar['screen_resolution_width'] = "NULL";
// Insert ticket to database // Insert ticket to database
$ticket = hesk_newTicket($tmpvar); $ticket = hesk_newTicket($tmpvar);
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_created', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
if ($autoassign_owner) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_autoassigned', hesk_date(),
array(0 => $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')'));
}
// Notify the customer about the ticket? // Notify the customer about the ticket?
if ($notify && $email_available) { if ($notify && $email_available) {
hesk_notifyCustomer($modsForHesk_settings); hesk_notifyCustomer($modsForHesk_settings);

@ -97,6 +97,37 @@ if (!$ticket['owner'] && !$can_view_unassigned) {
hesk_error($hesklang['ycovtay']); hesk_error($hesklang['ycovtay']);
} }
// Get audit information
$audit_sort = $hesk_settings['new_top'] ? "ASC" : "DESC";
$auditRes = hesk_dbQuery("SELECT `audit`.`id`, `audit`.`language_key`, `audit`.`date`,
`values`.`replacement_index`, `values`.`replacement_value`
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail` AS `audit`
LEFT JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail_to_replacement_values` AS `values`
ON `audit`.`id` = `values`.`audit_trail_id`
WHERE `entity_type` = 'TICKET' AND `entity_id` = " . intval($ticket['id']) . "
ORDER BY `audit`.`date` {$audit_sort}");
$audit_records = array();
$current_audit_record = null;
while ($row = hesk_dbFetchAssoc($auditRes)) {
if ($current_audit_record == null || $current_audit_record['id'] != $row['id']) {
if ($current_audit_record != null) {
$audit_records[] = $current_audit_record;
}
$current_audit_record['id'] = $row['id'];
$current_audit_record['language_key'] = $row['language_key'];
$current_audit_record['date'] = $row['date'];
$current_audit_record['replacement_values'] = array();
}
if ($row['replacement_index'] != null) {
$current_audit_record['replacement_values'][intval($row['replacement_index'])] = $row['replacement_value'];
}
}
if ($current_audit_record != null) {
$audit_records[] = $current_audit_record;
}
/* Set last replier name */ /* Set last replier name */
if ($ticket['lastreplier']) { if ($ticket['lastreplier']) {
if (empty($ticket['repliername'])) { if (empty($ticket['repliername'])) {
@ -120,19 +151,19 @@ $managerRow = hesk_dbFetchAssoc($managerRS);
$isManager = $managerRow['id'] == $category['manager']; $isManager = $managerRow['id'] == $category['manager'];
if ($isManager) { if ($isManager) {
$can_del_notes = $can_del_notes =
$can_reply = $can_reply =
$can_delete = $can_delete =
$can_edit = $can_edit =
$can_archive = $can_archive =
$can_assign_self = $can_assign_self =
$can_view_unassigned = $can_view_unassigned =
$can_change_own_cat = $can_change_own_cat =
$can_change_cat = $can_change_cat =
$can_ban_emails = $can_ban_emails =
$can_unban_emails = $can_unban_emails =
$can_ban_ips = $can_ban_ips =
$can_unban_ips = $can_unban_ips =
$can_resolve = true; $can_resolve = true;
} }
/* Is this user allowed to view tickets inside this category? */ /* Is this user allowed to view tickets inside this category? */
@ -392,13 +423,14 @@ if (isset($_POST['notemsg']) && hesk_token_check('POST')) {
'trackid' => $ticket['trackid'], 'trackid' => $ticket['trackid'],
'status' => $ticket['status'], 'status' => $ticket['status'],
'name' => $_SESSION['name'], 'name' => $_SESSION['name'],
'lastreplier' => $ticket['lastreplier'],
'subject' => $ticket['subject'], 'subject' => $ticket['subject'],
'message' => stripslashes($msg), 'message' => stripslashes($msg),
'dt' => hesk_date($ticket['dt'], true), 'dt' => hesk_date($ticket['dt'], true),
'lastchange' => hesk_date($ticket['lastchange'], true), 'lastchange' => hesk_date($ticket['lastchange'], true),
'attachments' => $myattachments, 'attachments' => $myattachments,
'id' => $ticket['id'], 'id' => $ticket['id'],
'time_worked' => $ticket['time_worked'],
'last_reply_by' => $ticket['repliername'],
); );
// 2. Add custom fields to the array // 2. Add custom fields to the array
@ -439,8 +471,10 @@ if ($hesk_settings['time_worked'] && ($can_reply || $can_edit) && isset($_POST['
$time_worked = hesk_getTime($h . ':' . $m . ':' . $s); $time_worked = hesk_getTime($h . ':' . $m . ':' . $s);
/* Update database */ /* Update database */
$revision = sprintf($hesklang['thist14'], hesk_date(), $time_worked, $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `time_worked`='" . hesk_dbEscape($time_worked) . "' WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `time_worked`='" . hesk_dbEscape($time_worked) . "', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'"); mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_time_worked', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $time_worked));
/* Show ticket */ /* Show ticket */
hesk_process_messages($hesklang['twu'], 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS'); hesk_process_messages($hesklang['twu'], 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS');
@ -476,13 +510,26 @@ if (($can_reply || $can_edit) && isset($_POST['childTrackingId'])) {
} }
hesk_dbQuery('UPDATE `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'tickets` SET `parent` = ' . intval($ticket['id']) . ' WHERE `trackid` = \'' . hesk_dbEscape(hesk_POST('childTrackingId')) . '\''); hesk_dbQuery('UPDATE `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'tickets` SET `parent` = ' . intval($ticket['id']) . ' WHERE `trackid` = \'' . hesk_dbEscape(hesk_POST('childTrackingId')) . '\'');
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_linked_ticket', hesk_date(),
array(
0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => hesk_POST('childTrackingId')
));
hesk_process_messages(sprintf($hesklang['link_added'], $_POST['childTrackingId']), 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS'); hesk_process_messages(sprintf($hesklang['link_added'], $_POST['childTrackingId']), 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS');
} }
/* Delete child action */ /* Delete child action */
if (($can_reply || $can_edit) && isset($_GET['deleteChild'])) { if (($can_reply || $can_edit) && isset($_GET['deleteChild'])) {
//-- Delete the relationship //-- Delete the relationship
$innerTrackingRs = hesk_dbQuery("SELECT `trackid` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `id` = " . hesk_dbEscape($_GET['deleteChild']));
$innerTrackingId = hesk_dbFetchAssoc($innerTrackingRs);
hesk_dbQuery('UPDATE `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'tickets` SET `parent` = NULL WHERE `ID` = ' . hesk_dbEscape($_GET['deleteChild'])); hesk_dbQuery('UPDATE `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'tickets` SET `parent` = NULL WHERE `ID` = ' . hesk_dbEscape($_GET['deleteChild']));
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_unlinked_ticket', hesk_date(),
array(
0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $innerTrackingId['trackid']
));
hesk_process_messages($hesklang['ticket_no_longer_linked'], 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS'); hesk_process_messages($hesklang['ticket_no_longer_linked'], 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS');
} elseif (($can_reply || $can_edit) && isset($_GET['deleteParent'])) { } elseif (($can_reply || $can_edit) && isset($_GET['deleteParent'])) {
@ -528,7 +575,6 @@ if (isset($_GET['delatt']) && hesk_token_check()) {
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` WHERE `att_id`='" . intval($att_id) . "'"); hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` WHERE `att_id`='" . intval($att_id) . "'");
/* Update ticket or reply in the database */ /* Update ticket or reply in the database */
$revision = sprintf($hesklang['thist12'], hesk_date(), $att['real_name'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
if ($reply) { if ($reply) {
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` SET `attachments`=REPLACE(`attachments`,'" . hesk_dbEscape($att_id . '#' . $att['real_name'] . '#' . $att['saved_name']) . ",','') WHERE `id`='" . intval($reply) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` SET `attachments`=REPLACE(`attachments`,'" . hesk_dbEscape($att_id . '#' . $att['real_name'] . '#' . $att['saved_name']) . ",','') WHERE `id`='" . intval($reply) . "'");
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`='" . intval($ticket['id']) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`='" . intval($ticket['id']) . "'");
@ -539,6 +585,9 @@ if (isset($_GET['delatt']) && hesk_token_check()) {
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `attachments`=REPLACE(`attachments`,'" . hesk_dbEscape($att_id . '#' . $att['real_name'] . '#' . $att['saved_name']) . ",','') WHERE `id`='" . intval($ticket['id']) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `attachments`=REPLACE(`attachments`,'" . hesk_dbEscape($att_id . '#' . $att['real_name'] . '#' . $att['saved_name']) . ",','') WHERE `id`='" . intval($ticket['id']) . "'");
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `attachments`=REPLACE(`attachments`,'" . hesk_dbEscape($att_id . '#' . $att['real_name']) . ",',''), `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`='" . intval($ticket['id']) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `attachments`=REPLACE(`attachments`,'" . hesk_dbEscape($att_id . '#' . $att['real_name']) . ",',''), `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`='" . intval($ticket['id']) . "'");
} }
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_attachment_deleted', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $att['real_name']));
hesk_process_messages($hesklang['kb_att_rem'], 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS'); hesk_process_messages($hesklang['kb_att_rem'], 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . mt_rand(10000, 99999), 'SUCCESS');
} }
@ -890,6 +939,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */ /* This will handle error, success and notice messages */
hesk_handle_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 // Prepare special custom fields
foreach ($hesk_settings['custom_fields'] as $k=>$v) { foreach ($hesk_settings['custom_fields'] as $k=>$v) {
if ($v['use'] && hesk_is_custom_field_in_category($k, $ticket['category']) ) { if ($v['use'] && hesk_is_custom_field_in_category($k, $ticket['category']) ) {
@ -948,25 +1002,42 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
); );
$options = array(); $options = array();
for ($i = 0; $i < 4; $i++) { for ($i = 0; $i < 4; $i++) {
if ($ticket['priority'] == $i) {
if ($i === 0) {
$cssClass = 'critical-priority';
} elseif ($i === 1) {
$cssClass = 'high-priority';
} elseif ($i === 2) {
$cssClass = 'medium-priority';
} else {
$cssClass = 'low-priority';
}
}
$selected = $ticket['priority'] == $i ? 'selected' : ''; $selected = $ticket['priority'] == $i ? 'selected' : '';
array_push($options, '<option value="' . $i . '" ' . $selected . '>' . $priorityLanguages[$i] . '</option>'); $content = "<i class='fa fa-fw fa-%s %s' style='font-size: 1em'></i> {$priorityLanguages[$i]}";
}
if ($i === 0) {
$content = sprintf($content, 'long-arrow-up', 'critical');
} elseif ($i === 1) {
$content = sprintf($content, 'angle-double-up', 'orange');
} elseif ($i === 2) {
$content = sprintf($content, 'angle-double-down', 'green');
} else {
$content = sprintf($content, 'long-arrow-down', 'blue');
}
echo '<div class="ticket-cell-admin col-md-3 col-sm-12 '; array_push($options, '<option data-content="' . $content . '" value="' . $i . '" ' . $selected . '>' . $priorityLanguages[$i] . '</option>');
if ($ticket['priority'] == 0) {
echo 'critical-priority">';
} elseif ($ticket['priority'] == 1) {
echo 'high-priority">';
} else {
echo 'med-low-priority">';
} }
echo '<div class="ticket-cell-admin col-md-3 col-sm-12 ' . $cssClass . '">';
echo '<p class="ticket-property-title">' . $hesklang['priority'] . '</p>'; echo '<p class="ticket-property-title">' . $hesklang['priority'] . '</p>';
echo '<form style="margin-bottom:0;" id="changePriorityForm" action="priority.php" method="post"> echo '<form style="margin-bottom:0;" id="changePriorityForm" action="priority.php" method="post">
<span style="white-space:nowrap;"> <span style="white-space:nowrap;">
<select class="form-control" name="priority" onchange="document.getElementById(\'changePriorityForm\').submit();">'; <select class="selectpicker form-control" name="priority" onchange="document.getElementById(\'changePriorityForm\').submit();">';
echo implode('', $options); echo implode('', $options);
echo ' echo '
</select> </select>
@ -987,13 +1058,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
$results = mfh_getAllStatuses(); $results = mfh_getAllStatuses();
foreach ($results as $row) { foreach ($results as $row) {
$selected = $ticket['status'] == $row['ID'] ? 'selected' : ''; $selected = $ticket['status'] == $row['ID'] ? 'selected' : '';
$status_options[$row['ID']] = '<option value="' . $row['ID'] . '" ' . $selected . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>'; $status_options[$row['ID']] = '<option style="color: ' . $row['TextColor'] . '" value="' . $row['ID'] . '" ' . $selected . '>' . mfh_getDisplayTextForStatusId($row['ID']) . '</option>';
} }
echo ' echo '
<form role="form" id="changeStatusForm" style="margin-bottom:0;" action="change_status.php" method="post"> <form role="form" id="changeStatusForm" style="margin-bottom:0;" action="change_status.php" method="post">
<span style="white-space:nowrap;"> <span style="white-space:nowrap;">
<select class="form-control" onchange="document.getElementById(\'changeStatusForm\').submit();" name="s"> <select class="selectpicker form-control" onchange="document.getElementById(\'changeStatusForm\').submit();" name="s">
' . implode('', $status_options) . ' ' . implode('', $status_options) . '
</select> </select>
@ -1011,7 +1082,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
echo ' echo '
<form style="margin-bottom:0;" id="changeOwnerForm" action="assign_owner.php" method="post"> <form style="margin-bottom:0;" id="changeOwnerForm" action="assign_owner.php" method="post">
<span style="white-space:nowrap;"> <span style="white-space:nowrap;">
<select class="form-control" name="owner" onchange="document.getElementById(\'changeOwnerForm\').submit();">'; <select class="selectpicker form-control" name="owner" onchange="document.getElementById(\'changeOwnerForm\').submit();">';
$selectedForUnassign = 'selected'; $selectedForUnassign = 'selected';
foreach ($admins as $k => $v) { foreach ($admins as $k => $v) {
$selected = ''; $selected = '';
@ -1046,7 +1117,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<form style="margin-bottom:0;" id="changeCategory" action="move_category.php" method="post"> <form style="margin-bottom:0;" id="changeCategory" action="move_category.php" method="post">
<span style="white-space:nowrap;"> <span style="white-space:nowrap;">
<select name="category" class="form-control" onchange="document.getElementById(\'changeCategory\').submit();"> <select name="category" class="selectpicker form-control" onchange="document.getElementById(\'changeCategory\').submit();">
' . $categories_options . ' ' . $categories_options . '
</select> </select>
@ -1122,9 +1193,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
echo ' echo '
<a href="../download_attachment.php?att_id=' . $att_id . '&amp;track=' . $trackingID . '"> <a href="../download_attachment.php?att_id=' . $att_id . '&amp;track=' . $trackingID . '">
<i class="fa fa-paperclip" style="font-size:16px;" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['dnl'] . ' ' . $att_name . '"></i> <i class="fa fa-paperclip" style="font-size:16px;" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['dnl'] . '"></i>
</a> </a>
<a href="../download_attachment.php?att_id=' . $att_id . '&amp;track=' . $trackingID . '">' . $att_name . '</a><br /> <a href="../download_attachment.php?att_id=' . $att_id . '&amp;track=' . $trackingID . '">' . $att_name . ' (' . mfh_getAttachmentFileSize($att_id) . ')' . '</a><br />
'; ';
} }
} }
@ -1496,7 +1567,7 @@ function hesk_getAdminButtons($category_id)
function hesk_getAdminButtonsInTicket($reply = 0, $white = 1) function hesk_getAdminButtonsInTicket($reply = 0, $white = 1)
{ {
global $hesk_settings, $hesklang, $ticket, $reply, $trackingID, $can_edit, $can_archive, $can_delete, $isManager; global $hesk_settings, $hesklang, $ticket, $trackingID, $can_edit, $can_archive, $can_delete, $isManager;
$options = $reply ? '' : '<div class="pull-right">'; $options = $reply ? '' : '<div class="pull-right">';
@ -1588,7 +1659,7 @@ function print_form()
} // End print_form() } // End print_form()
function mfh_print_message() { function mfh_print_message() {
global $ticket, $hesklang, $hesk_settings, $can_ban_emails, $can_ban_ips, $trackingID, $modsForHesk_settings; global $ticket, $hesklang, $hesk_settings, $can_ban_emails, $can_ban_ips, $can_unban_emails, $can_unban_ips, $trackingID, $modsForHesk_settings;
?> ?>
<li><i class="fa fa-comment bg-red" data-toggle="tooltip" title="<?php echo $hesklang['original_message']; ?>"></i> <li><i class="fa fa-comment bg-red" data-toggle="tooltip" title="<?php echo $hesklang['original_message']; ?>"></i>
<div class="timeline-item"> <div class="timeline-item">
@ -1749,7 +1820,46 @@ function mfh_print_message() {
function hesk_printTicketReplies() function hesk_printTicketReplies()
{ {
global $hesklang, $hesk_settings, $result, $reply; global $hesklang, $hesk_settings, $result, $reply, $audit_records;
// Sort replies and audit messages. They'll be in the proper order already
$combined_records = array();
foreach ($audit_records as $audit_record) {
$audit_record['SORT_TYPE'] = 'AUDIT_RECORD';
$combined_records[] = $audit_record;
}
while ($reply = hesk_dbFetchAssoc($result)) {
$reply['SORT_TYPE'] = 'REPLY';
$combined_records[] = $reply;
}
// Re-sort them so they're in order by date
usort($combined_records, function ($a, $b) use (&$hesk_settings) {
$a_date = null;
$b_date = null;
if ($a['SORT_TYPE'] == 'REPLY') {
$a_date = strtotime($a['dt']);
} else {
$a_date = strtotime($a['date']);
}
if ($b['SORT_TYPE'] == 'REPLY') {
$b_date = strtotime($b['dt']);
} else {
$b_date = strtotime($b['date']);
}
if ($a_date === $b_date && $a['SORT_TYPE'] != $b['SORT_TYPE']) {
if ($hesk_settings['new_top']) {
return $a['SORT_TYPE'] == 'REPLY' ? 1 : -1;
}
return $a['SORT_TYPE'] == 'REPLY' ? -1 : 1;
}
return $hesk_settings['new_top'] ? $b_date - $a_date : $a_date - $b_date;
});
echo '<ul class="timeline">'; echo '<ul class="timeline">';
if (!$hesk_settings['new_top']) { if (!$hesk_settings['new_top']) {
@ -1758,83 +1868,194 @@ function hesk_printTicketReplies()
echo '<li class="today-top"><i class="fa fa-clock-o bg-gray" data-toggle="tooltip" title="' . $hesklang['timeline_today'] . '"></i></li>'; echo '<li class="today-top"><i class="fa fa-clock-o bg-gray" data-toggle="tooltip" title="' . $hesklang['timeline_today'] . '"></i></li>';
} }
while ($reply = hesk_dbFetchAssoc($result)) { foreach ($combined_records as $record) {
$reply['dt'] = hesk_date($reply['dt'], true); if ($record['SORT_TYPE'] == 'REPLY') {
?> mfh_print_reply($record);
<li> } else {
<?php if ($reply['staffid']): ?> mfh_print_audit_record($record);
<i class="fa fa-reply bg-orange" data-toggle="tooltip" title="<?php echo $hesklang['reply_by_staff']; ?>"></i> }
<?php else: ?> }
<i class="fa fa-share bg-blue" data-toggle="tooltip" title="<?php echo $hesklang['reply_by_customer']; ?>"></i>
<?php endif; ?> if ($hesk_settings['new_top']) {
<div class="timeline-item"> mfh_print_message();
<span class="time"><i class="fa fa-clock-o"></i> <?php echo $reply['dt']; ?></span> } else {
<h3 class="timeline-header"><?php echo $reply['name']; ?></h3> echo '<li><i class="fa fa-clock-o bg-gray" data-toggle="tooltip" title="' . $hesklang['timeline_today'] . '"></i></li>';
<div class="timeline-body"> }
<div class="row"> echo '</ul>';
<div class="col-md-3 text-right">
<strong><?php echo $hesklang['message_colon']; ?></strong> return;
</div>
<div class="col-md-9"> } // End hesk_printTicketReplies()
<?php
if ($reply['html']) { function mfh_print_reply($reply) {
echo hesk_html_entity_decode($reply['message']); global $hesklang, $hesk_settings;
} else {
echo $reply['message']; $reply['dt'] = hesk_date($reply['dt'], true);
} ?> ?>
</div> <li>
<?php if ($reply['staffid']): ?>
<i class="fa fa-reply bg-orange" data-toggle="tooltip" title="<?php echo $hesklang['reply_by_staff']; ?>"></i>
<?php else: ?>
<i class="fa fa-share bg-blue" data-toggle="tooltip" title="<?php echo $hesklang['reply_by_customer']; ?>"></i>
<?php endif; ?>
<div class="timeline-item">
<span class="time"><i class="fa fa-clock-o"></i> <?php echo $reply['dt']; ?></span>
<h3 class="timeline-header"><?php echo $reply['name']; ?></h3>
<div class="timeline-body">
<div class="row">
<div class="col-md-3 text-right">
<strong><?php echo $hesklang['message_colon']; ?></strong>
</div>
<div class="col-md-9">
<?php
if ($reply['html']) {
echo hesk_html_entity_decode($reply['message']);
} else {
echo $reply['message'];
} ?>
</div> </div>
</div> </div>
<?php </div>
if ($hesk_settings['attachments']['use'] && strlen($reply['attachments'])): <?php
if ($hesk_settings['attachments']['use'] && strlen($reply['attachments'])):
?> ?>
<div class="timeline-footer"> <div class="timeline-footer">
<?php mfh_listAttachments($reply['attachments'], $reply['id'], true); ?> <?php mfh_listAttachments($reply['attachments'], $reply['id'], true); ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="timeline-footer"> <div class="timeline-footer">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<?php <?php
/* Staff rating */ /* Staff rating */
if ($hesk_settings['rating'] && $reply['staffid']) { if ($hesk_settings['rating'] && $reply['staffid']) {
if ($reply['rating'] == 1) { if ($reply['rating'] == 1) {
echo '<p class="rate">' . $hesklang['rnh'] . '</p>'; echo '<p class="rate">' . $hesklang['rnh'] . '</p>';
} elseif ($reply['rating'] == 5) { } elseif ($reply['rating'] == 5) {
echo '<p class="rate">' . $hesklang['rh'] . '</p>'; echo '<p class="rate">' . $hesklang['rh'] . '</p>';
}
}
/* Show "unread reply" message? */
if ($reply['staffid'] && !$reply['read']) {
echo '<p class="rate">' . $hesklang['unread'] . '</p>';
} }
?> }
</div> /* Show "unread reply" message? */
<div class="col-md-6 text-right"> if ($reply['staffid'] && !$reply['read']) {
<?php echo hesk_getAdminButtonsInTicket(); ?> echo '<p class="rate">' . $hesklang['unread'] . '</p>';
</div> }
?>
</div>
<div class="col-md-6 text-right">
<?php echo hesk_getAdminButtonsInTicket($reply); ?>
</div> </div>
</div> </div>
</div> </div>
</li> </div>
<?php </li>
} <?php
}
if ($hesk_settings['new_top']) { function mfh_print_audit_record($record) {
mfh_print_message(); global $hesklang;
} else {
echo '<li><i class="fa fa-clock-o bg-gray" data-toggle="tooltip" title="' . $hesklang['timeline_today'] . '"></i></li>';
}
echo '</ul>';
return; $record['date'] = hesk_date($record['date'], true);
$font_icon = null;
switch ($record['language_key']) {
case 'audit_moved_category':
$font_icon = 'fa-pie-chart';
break;
case 'audit_assigned':
case 'audit_assigned_self':
$font_icon = 'fa-user-plus';
break;
case 'audit_unassigned':
$font_icon = 'fa-user-times';
break;
case 'audit_autoassigned':
$font_icon = 'fa-bolt';
break;
case 'audit_closed':
case 'audit_automatically_closed':
$font_icon = 'fa-check-circle';
break;
case 'audit_opened':
$font_icon = 'fa-circle-o';
break;
case 'audit_locked':
case 'audit_automatically_locked':
$font_icon = 'fa-lock';
break;
case 'audit_unlocked':
$font_icon = 'fa-unlock-alt';
break;
case 'audit_created':
case 'audit_submitted_by':
$font_icon = 'fa-user';
break;
case 'audit_priority':
// The new priority is in arg[1]
$priority = $record['replacement_values'][1];
if ($priority === 'critical') {
$font_icon = 'fa-long-arrow-up';
} elseif ($priority === 'high') {
$font_icon = 'fa-angle-double-up';
} elseif ($priority === 'medium') {
$font_icon = 'fa-angle-double-down';
} else {
$font_icon = 'fa-long-arrow-down';
}
} // End hesk_printTicketReplies() // Now localize the text for display
$record['replacement_values'][1] = $hesklang[$priority];
break;
case 'audit_status':
$font_icon = 'fa-exchange';
break;
case 'audit_submitted_via_piping':
case 'audit_submitted_via_pop':
$font_icon = 'fa-envelope-o';
break;
case 'audit_attachment_deleted':
$font_icon = 'fa-paperclip';
break;
case 'audit_merged':
$font_icon = 'fa-code-fork';
break;
case 'audit_time_worked':
$font_icon = 'fa fa-clock-o';
break;
case 'audit_due_date_removed':
$font_icon = 'fa fa-calendar-minus-o';
break;
case 'audit_due_date_changed':
$font_icon = 'fa fa-calendar';
//-- Format the date
$record['replacement_values'][1] = date('Y-m-d', strtotime($record['replacement_values'][1]));
break;
case 'audit_linked_ticket':
$font_icon = 'fa fa-link';
break;
case 'audit_unlinked_ticket':
$font_icon = 'fa fa-chain-broken';
break;
default:
$font_icon = 'fa-question-circle';
break;
}
?>
<li>
<i class="fa <?php echo $font_icon; ?> bg-gray"></i>
<div class="timeline-item">
<span class="time"><i class="fa fa-clock-o"></i> <?php echo $record['date']; ?></span>
<h3 class="timeline-header audit-record">
<?php echo vsprintf($hesklang[$record['language_key']], $record['replacement_values']); ?>
</h3>
</div>
</li>
<?php
}
function hesk_printReplyForm() function hesk_printReplyForm()
{ {
global $hesklang, $hesk_settings, $ticket, $admins, $can_options, $can_resolve, $options, $can_assign_self, $isManager, $modsForHesk_settings; global $hesklang, $hesk_settings, $ticket, $admins, $can_options, $can_resolve, $options, $can_assign_self, $modsForHesk_settings, $isManager;
// Force assigning a ticket before allowing to reply? // Force assigning a ticket before allowing to reply?
if ($hesk_settings['require_owner'] && ! $ticket['owner']) if ($hesk_settings['require_owner'] && ! $ticket['owner'])

@ -52,8 +52,9 @@ $owner = intval(hesk_REQUEST('owner'));
/* If ID is -1 the ticket will be unassigned */ /* If ID is -1 the ticket will be unassigned */
if ($owner == -1) { if ($owner == -1) {
$revision = sprintf($hesklang['thist2'], hesk_date(), '<i>' . $hesklang['unas'] . '</i>', $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0 WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0 , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'"); mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_unassigned', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
hesk_process_messages($hesklang['tunasi2'], $_SERVER['PHP_SELF'], 'SUCCESS'); hesk_process_messages($hesklang['tunasi2'], $_SERVER['PHP_SELF'], 'SUCCESS');
} elseif ($owner < 1) { } elseif ($owner < 1) {
@ -96,8 +97,17 @@ if ($ticket['owner'] && $ticket['owner'] != $owner && hesk_REQUEST('unassigned')
/* Assigning to self? */ /* Assigning to self? */
if ($can_assign_others || ($owner == $_SESSION['id'] && $can_assign_self)) { if ($can_assign_others || ($owner == $_SESSION['id'] && $can_assign_self)) {
$revision = sprintf($hesklang['thist2'], hesk_date(), $row['name'] . ' (' . $row['user'] . ')', $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`={$owner} WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`={$owner} , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
if ($owner == $_SESSION['id'] && $can_assign_self) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_assigned_self', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
} else {
// current user -> assigned user
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_assigned', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $row['name'] . ' (' . $row['user'] . ')'));
}
if ($owner != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others', 0)) { if ($owner != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others', 0)) {
$_SERVER['PHP_SELF'] = 'admin_main.php'; $_SERVER['PHP_SELF'] = 'admin_main.php';
@ -119,13 +129,14 @@ $info = array(
'trackid' => $ticket['trackid'], 'trackid' => $ticket['trackid'],
'status' => $ticket['status'], 'status' => $ticket['status'],
'name' => $ticket['name'], 'name' => $ticket['name'],
'lastreplier' => $ticket['lastreplier'],
'subject' => $ticket['subject'], 'subject' => $ticket['subject'],
'message' => $ticket['message'], 'message' => $ticket['message'],
'attachments' => $ticket['attachments'], 'attachments' => $ticket['attachments'],
'dt' => hesk_date($ticket['dt'], true), 'dt' => hesk_date($ticket['dt'], true),
'lastchange' => hesk_date($ticket['lastchange'], true), 'lastchange' => hesk_date($ticket['lastchange'], true),
'id' => $ticket['id'], 'id' => $ticket['id'],
'time_worked' => $ticket['time_worked'],
'last_reply_by' => hesk_getReplierName($ticket),
); );
// 2. Add custom fields to the array // 2. Add custom fields to the array

@ -282,10 +282,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<select name="reminder-unit" class="form-control"> <select name="reminder-unit" class="form-control">
<option value="0"><?php echo $hesklang['event_min_before_event']; ?></option> <option value="MINUTE"><?php echo $hesklang['event_min_before_event']; ?></option>
<option value="1"><?php echo $hesklang['event_hours_before_event']; ?></option> <option value="HOUR"><?php echo $hesklang['event_hours_before_event']; ?></option>
<option value="2"><?php echo $hesklang['event_days_before_event']; ?></option> <option value="DAY"><?php echo $hesklang['event_days_before_event']; ?></option>
<option value="3"><?php echo $hesklang['event_weeks_before_event']; ?></option> <option value="WEEK"><?php echo $hesklang['event_weeks_before_event']; ?></option>
</select> </select>
</div> </div>
</div> </div>
@ -334,147 +334,168 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
</div> </div>
<form id="edit-form" class="form-horizontal" data-toggle="validator"> <form id="edit-form" class="form-horizontal" data-toggle="validator">
<div class="modal-body"> <div class="modal-body">
<div class="row"> <ul class="nav nav-tabs" role="tablist" id="edit-modal-tabs">
<div class="col-md-12"> <li role="presentation" class="active"><a href="#edit-contents" aria-controls="home" role="tab" data-toggle="tab"><?php echo $hesklang['information']; ?></a></li>
<div class="form-group"> <li role="presentation"><a href="#edit-history" aria-controls="profile" role="tab" data-toggle="tab"><?php echo $hesklang['thist']; ?></a></li>
<label for="name" class="col-sm-3 control-label"> </ul>
<?php echo $hesklang['event_title']; ?> <div class="tab-content" id="information-tab">
<i class="fa fa-question-circle settingsquestionmark" <div role="tabpanel" class="tab-pane active" id="edit-contents">
data-toggle="tooltip" <br>
title="<?php echo htmlspecialchars($hesklang['event_title_tooltip']); ?>"></i></label> <div class="row">
<div class="col-sm-9"> <div class="col-md-12">
<input type="text" name="name" class="form-control" <div class="form-group">
placeholder="<?php echo htmlspecialchars($hesklang['event_title']); ?>" <label for="name" class="col-sm-3 control-label">
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>" <?php echo $hesklang['event_title']; ?>
required> <i class="fa fa-question-circle settingsquestionmark"
<div class="help-block with-errors"></div> data-toggle="tooltip"
</div> title="<?php echo htmlspecialchars($hesklang['event_title_tooltip']); ?>"></i></label>
</div> <div class="col-sm-9">
<div class="form-group"> <input type="text" name="name" class="form-control"
<label for="location" class="col-sm-3 control-label"> placeholder="<?php echo htmlspecialchars($hesklang['event_title']); ?>"
<?php echo $hesklang['event_location']; ?> data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
<i class="fa fa-question-circle settingsquestionmark" required>
data-toggle="tooltip" <div class="help-block with-errors"></div>
title="<?php echo htmlspecialchars($hesklang['event_location_tooltip']); ?>"></i> </div>
</label> </div>
<div class="col-sm-9"> <div class="form-group">
<input type="text" name="location" class="form-control" <label for="location" class="col-sm-3 control-label">
placeholder="<?php echo htmlspecialchars($hesklang['event_location']); ?>"> <?php echo $hesklang['event_location']; ?>
<div class="help-block with-errors"></div> <i class="fa fa-question-circle settingsquestionmark"
</div> data-toggle="tooltip"
</div> title="<?php echo htmlspecialchars($hesklang['event_location_tooltip']); ?>"></i>
<div class="form-group"> </label>
<label for="category" class="col-sm-3 control-label"> <div class="col-sm-9">
<?php echo $hesklang['category']; ?> <input type="text" name="location" class="form-control"
<i class="fa fa-question-circle settingsquestionmark" placeholder="<?php echo htmlspecialchars($hesklang['event_location']); ?>">
data-toggle="tooltip" <div class="help-block with-errors"></div>
title="<?php echo htmlspecialchars($hesklang['event_category_tooltip']); ?>"></i> </div>
</label> </div>
<div class="col-sm-9"> <div class="form-group">
<select name="category" class="form-control" <label for="category" class="col-sm-3 control-label">
pattern="[0-9]+" <?php echo $hesklang['category']; ?>
data-error="<?php echo htmlspecialchars($hesklang['sel_app_cat']); ?>" required> <i class="fa fa-question-circle settingsquestionmark"
<?php data-toggle="tooltip"
if ($hesk_settings['select_cat']) { title="<?php echo htmlspecialchars($hesklang['event_category_tooltip']); ?>"></i>
echo '<option value="">'.$hesklang['select'].'</option>'; </label>
} <div class="col-sm-9">
foreach ($categories as $category): ?> <select name="category" class="form-control"
<option value="<?php echo $category['id']; ?>" data-background-color="<?php echo htmlspecialchars($category['background_color']); ?>" pattern="[0-9]+"
data-foreground-color="<?php echo htmlspecialchars($category['foreground_color']); ?>" data-error="<?php echo htmlspecialchars($hesklang['sel_app_cat']); ?>" required>
data-display-border="<?php echo htmlspecialchars($category['display_border_outline']); ?>"> <?php
<?php echo $category['name']; ?> if ($hesk_settings['select_cat']) {
</option> echo '<option value="">'.$hesklang['select'].'</option>';
<?php endforeach; ?> }
</select> foreach ($categories as $category): ?>
<div class="help-block with-errors"></div> <option value="<?php echo $category['id']; ?>" data-background-color="<?php echo htmlspecialchars($category['background_color']); ?>"
data-foreground-color="<?php echo htmlspecialchars($category['foreground_color']); ?>"
data-display-border="<?php echo htmlspecialchars($category['display_border_outline']); ?>">
<?php echo $category['name']; ?>
</option>
<?php endforeach; ?>
</select>
<div class="help-block with-errors"></div>
</div>
</div>
</div> </div>
</div> </div>
</div> <div class="row">
</div> <div class="col-md-6">
<div class="row"> <div class="form-group">
<div class="col-md-6"> <label for="start-date" class="col-sm-6 control-label">
<div class="form-group"> <?php echo $hesklang['event_start']; ?>
<label for="start-date" class="col-sm-6 control-label"> <i class="fa fa-question-circle settingsquestionmark"
<?php echo $hesklang['event_start']; ?> data-toggle="tooltip"
<i class="fa fa-question-circle settingsquestionmark" title="<?php echo htmlspecialchars($hesklang['event_start_tooltip']); ?>"></i>
data-toggle="tooltip" </label>
title="<?php echo htmlspecialchars($hesklang['event_start_tooltip']); ?>"></i> <div class="col-sm-6">
</label> <input type="text" name="start-date" class="form-control datepicker"
<div class="col-sm-6"> placeholder="<?php echo htmlspecialchars($hesklang['event_start_date']); ?>"
<input type="text" name="start-date" class="form-control datepicker" data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
placeholder="<?php echo htmlspecialchars($hesklang['event_start_date']); ?>" required>
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>" <input type="text" name="start-time" class="form-control clockpicker"
required> placeholder="<?php echo htmlspecialchars($hesklang['event_start_time']); ?>"
<input type="text" name="start-time" class="form-control clockpicker" data-placement="left" data-align="top" data-autoclose="true">
placeholder="<?php echo htmlspecialchars($hesklang['event_start_time']); ?>" <div class="help-block with-errors"></div>
data-placement="left" data-align="top" data-autoclose="true">
<div class="help-block with-errors"></div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" name="all-day"> <?php echo $hesklang['event_all_day']; ?> <input type="checkbox" name="all-day"> <?php echo $hesklang['event_all_day']; ?>
</label>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="end-date" class="col-sm-6 control-label">
<?php echo $hesklang['event_end']; ?>
<i class="fa fa-question-circle settingsquestionmark"
data-toggle="tooltip"
title="<?php echo htmlspecialchars($hesklang['event_end_tooltip']); ?>"></i>
</label> </label>
<div class="col-sm-6">
<input type="text" name="end-date" class="form-control datepicker"
placeholder="<?php echo htmlspecialchars($hesklang['event_end_date']); ?>"
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
required>
<input type="text" name="end-time" class="form-control clockpicker"
data-placement="left" data-align="top" data-autoclose="true"
placeholder="<?php echo htmlspecialchars($hesklang['event_end_time']); ?>">
<div class="help-block with-errors"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="row">
<div class="col-md-6"> <div class="col-md-12">
<div class="form-group"> <div class="form-group">
<label for="end-date" class="col-sm-6 control-label"> <label for="reminder" class="col-sm-3 control-label">
<?php echo $hesklang['event_end']; ?> <?php echo $hesklang['event_reminder']; ?>
<i class="fa fa-question-circle settingsquestionmark" <i class="fa fa-question-circle settingsquestionmark"
data-toggle="tooltip" data-toggle="tooltip"
title="<?php echo htmlspecialchars($hesklang['event_end_tooltip']); ?>"></i> title="<?php echo htmlspecialchars($hesklang['event_reminder_tooltip']); ?>"></i>
</label> </label>
<div class="col-sm-6"> <div class="col-sm-2">
<input type="text" name="end-date" class="form-control datepicker" <input type="text" name="reminder-value" class="form-control" placeholder="#">
placeholder="<?php echo htmlspecialchars($hesklang['event_end_date']); ?>" </div>
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>" <div class="col-sm-4">
required> <select name="reminder-unit" class="form-control">
<input type="text" name="end-time" class="form-control clockpicker" <option value="MINUTE"><?php echo $hesklang['event_min_before_event']; ?></option>
data-placement="left" data-align="top" data-autoclose="true" <option value="HOUR"><?php echo $hesklang['event_hours_before_event']; ?></option>
placeholder="<?php echo htmlspecialchars($hesklang['event_end_time']); ?>"> <option value="DAY"><?php echo $hesklang['event_days_before_event']; ?></option>
<div class="help-block with-errors"></div> <option value="WEEK"><?php echo $hesklang['event_weeks_before_event']; ?></option>
</select>
</div>
</div>
</div> </div>
</div> </div>
</div> <div class="row">
</div> <div class="col-md-12">
<div class="row"> <div class="form-group">
<div class="col-md-12"> <label for="comments" class="col-sm-3 control-label">
<div class="form-group"> <?php echo $hesklang['event_comments']; ?>
<label for="reminder" class="col-sm-3 control-label"> <i class="fa fa-question-circle settingsquestionmark"
<?php echo $hesklang['event_reminder']; ?> data-toggle="tooltip"
<i class="fa fa-question-circle settingsquestionmark" title="<?php echo htmlspecialchars($hesklang['event_comments_tooltip']); ?>"></i>
data-toggle="tooltip" </label>
title="<?php echo htmlspecialchars($hesklang['event_reminder_tooltip']); ?>"></i> <div class="col-sm-9">
</label> <textarea name="comments" class="form-control" placeholder="<?php echo htmlspecialchars($hesklang['event_comments']); ?>"></textarea>
<div class="col-sm-2"> </div>
<input type="text" name="reminder-value" class="form-control" placeholder="#"> </div>
</div>
<div class="col-sm-4">
<select name="reminder-unit" class="form-control">
<option value="0"><?php echo $hesklang['event_min_before_event']; ?></option>
<option value="1"><?php echo $hesklang['event_hours_before_event']; ?></option>
<option value="2"><?php echo $hesklang['event_days_before_event']; ?></option>
<option value="3"><?php echo $hesklang['event_weeks_before_event']; ?></option>
</select>
</div> </div>
</div> </div>
</div> </div>
</div> <div role="tabpanel" class="tab-pane" id="edit-history">
<div class="row"> <br>
<div class="col-md-12"> <table class="table table-striped">
<div class="form-group"> <thead>
<label for="comments" class="col-sm-3 control-label"> <tr>
<?php echo $hesklang['event_comments']; ?> <th><?php echo $hesklang['date']; ?></th>
<i class="fa fa-question-circle settingsquestionmark" <th><?php echo $hesklang['description']; ?></th>
data-toggle="tooltip" </tr>
title="<?php echo htmlspecialchars($hesklang['event_comments_tooltip']); ?>"></i> </thead>
</label> <tbody id="history-table"></tbody>
<div class="col-sm-9"> </table>
<textarea name="comments" class="form-control" placeholder="<?php echo htmlspecialchars($hesklang['event_comments']); ?>"></textarea>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -545,22 +566,34 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<strong><?php echo $hesklang['category']; ?></strong> <strong><?php echo $hesklang['category']; ?></strong>
<span></span> <span></span>
</div> </div>
<div class="popover-status">
<strong><?php echo $hesklang['status']; ?></strong>
<span></span>
</div>
<div class="popover-priority"> <div class="popover-priority">
<strong><?php echo $hesklang['priority']; ?></strong> <strong><?php echo $hesklang['priority']; ?></strong>
<span></span> <span></span>
</div> </div>
</div> </div>
</div> </div>
<?php
echo mfh_get_hidden_fields_for_language(array('error_loading_events',
'error_deleting_event',
'event_deleted',
'event_created',
'error_creating_event',
'event_updated',
'error_updating_event',
'ticket_due_date_updated',
'error_updating_ticket_due_date',
'critical',
'high',
'medium',
'low',
'audit_event_created',
'audit_event_updated'));
?>
<div style="display: none"> <div style="display: none">
<p id="lang_error_loading_events"><?php echo $hesklang['error_loading_events']; ?></p>
<p id="lang_error_deleting_event"><?php echo $hesklang['error_deleting_event']; ?></p>
<p id="lang_event_deleted"><?php echo $hesklang['event_deleted']; ?></p>
<p id="lang_event_created"><?php echo $hesklang['event_created']; ?></p>
<p id="lang_error_creating_event"><?php echo $hesklang['error_creating_event']; ?></p>
<p id="lang_event_updated"><?php echo $hesklang['event_updated']; ?></p>
<p id="lang_error_updating_event"><?php echo $hesklang['error_updating_event']; ?></p>
<p id="lang_ticket_due_date_updated"><?php echo $hesklang['ticket_due_date_updated']; ?></p>
<p id="lang_error_updating_ticket_due_date"><?php echo $hesklang['error_updating_ticket_due_date']; ?></p>
<p id="setting_first_day_of_week"><?php echo $modsForHesk_settings['first_day_of_week']; ?></p> <p id="setting_first_day_of_week"><?php echo $modsForHesk_settings['first_day_of_week']; ?></p>
<p id="setting_default_view"> <p id="setting_default_view">
<?php <?php
@ -572,7 +605,21 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
echo $view_array[$_SESSION['default_calendar_view']]; echo $view_array[$_SESSION['default_calendar_view']];
?> ?>
</p> </p>
<p id="setting_show_start_time"><?php echo $modsForHesk_settings['calendar_show_start_time']; ?></p>
<?php
$businessHoursRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`");
while ($row = hesk_dbFetchAssoc($businessHoursRs)):
?>
<p id="business_hours_<?php echo $row['day_of_week']; ?>_start"><?php echo $row['start_time']; ?></p>
<p id="business_hours_<?php echo $row['day_of_week']; ?>_end"><?php echo $row['end_time']; ?></p>
<?php endwhile; ?>
</div> </div>
<script type="text/html" id="audit-trail-template">
<tr>
<td data-property="date"></td>
<td data-property="description"></td>
</tr>
</script>
<?php <?php
require_once(HESK_PATH . 'inc/footer.inc.php'); require_once(HESK_PATH . 'inc/footer.inc.php');

@ -37,6 +37,10 @@ hesk_token_check();
/* Ticket ID */ /* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']); $trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']);
$ticket_id_rs = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($trackingID) . "'");
$ticket_id_row = hesk_dbFetchAssoc($ticket_id_rs);
$ticket_id = $ticket_id_row['id'];
/* Valid statuses */ /* Valid statuses */
$statusSql = "SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`"; $statusSql = "SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`";
$status_options = array(); $status_options = array();
@ -54,6 +58,11 @@ if (!isset($status_options[$status])) {
$locked = 0; $locked = 0;
$audit_closed = null;
$audit_locked = null;
$audit_status = null;
$audit_opened = null;
$statusRow = hesk_dbFetchAssoc(hesk_dbQuery("SELECT `ID`, `IsClosed` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE ID = " . $status)); $statusRow = hesk_dbFetchAssoc(hesk_dbQuery("SELECT `ID`, `IsClosed` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE ID = " . $status));
if ($statusRow['IsClosed']) // Closed if ($statusRow['IsClosed']) // Closed
{ {
@ -62,10 +71,14 @@ if ($statusRow['IsClosed']) // Closed
} }
$action = $hesklang['ticket_been'] . ' ' . $hesklang['close']; $action = $hesklang['ticket_been'] . ' ' . $hesklang['close'];
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_closed = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
$audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $status_options[$status]);
if ($hesk_settings['custopen'] != 1) { if ($hesk_settings['custopen'] != 1) {
$locked = 1; $locked = 1;
$audit_locked = array();
} }
// Notify customer of closed ticket? // Notify customer of closed ticket?
@ -91,21 +104,43 @@ if ($statusRow['IsClosed']) // Closed
} elseif ($statusRow['IsNewTicketStatus'] == 0) //Ticket is still open, but not new } elseif ($statusRow['IsNewTicketStatus'] == 0) //Ticket is still open, but not new
{ {
$action = sprintf($hesklang['tsst'], $status_options[$status]); $action = sprintf($hesklang['tsst'], $status_options[$status]);
$revision = sprintf($hesklang['thist9'], hesk_date(), $status_options[$status], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $status_options[$status]);
// Ticket is not resolved // Ticket is not resolved
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL '; $closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
} else // Ticket is marked as "NEW" } else // Ticket is marked as "NEW"
{ {
$action = $hesklang['ticket_been'] . ' ' . $hesklang['opened']; $action = $hesklang['ticket_been'] . ' ' . $hesklang['opened'];
$revision = sprintf($hesklang['thist4'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_opened = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
// Ticket is not resolved // Ticket is not resolved
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL '; $closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
} }
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
if ($audit_status !== null) {
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_status', hesk_date(),
$audit_status);
}
if ($audit_closed !== null) {
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_closed', hesk_date(),
$audit_closed);
}
if ($audit_locked !== null) {
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_automatically_locked', hesk_date(),
array());
}
if ($audit_opened !== null) {
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_opened', hesk_date(),
$audit_opened);
}
if (hesk_dbAffectedRows() != 1) { if (hesk_dbAffectedRows() != 1) {
hesk_error("$hesklang[int_error]: $hesklang[trackID_not_found]."); hesk_error("$hesklang[int_error]: $hesklang[trackID_not_found].");

@ -166,7 +166,31 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
</div> </div>
<?php <?php
} }
?>
$descriptions = hesk_SESSION(array('new_cf','descriptions')); ?>
</div>
<div class="form-group">
<label for="description[]" class="col-sm-3 control-label">
<?php echo $hesklang['description']; ?>
</label>
<?php if ($hesk_settings['can_sel_lang'] && count($hesk_settings['languages']) > 1): ?>
<table border="0">
<?php foreach ($hesk_settings['languages'] as $lang => $info): ?>
<tr>
<td><?php echo $lang; ?></td>
<td>
<textarea class="form-control"
name="description[<?php echo $lang; ?>]"><?php echo (isset($descriptions[$lang]) ? $descriptions[$lang] : ''); ?></textarea>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php else: ?>
<div class="col-sm-9">
<textarea class="form-control"
name="description[<?php echo $hesk_settings['language']; ?>]"><?php echo (isset($descriptions[$hesk_settings['language']]) ? $descriptions[$hesk_settings['language']] : ''); ?></textarea>
</div>
<?php endif; ?>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="name[]" class="col-sm-3 control-label"> <label for="name[]" class="col-sm-3 control-label">
@ -495,7 +519,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<?php echo $hesklang['email_custom_field_label']; ?> <?php echo $hesklang['email_custom_field_label']; ?>
</label> </label>
<div class="col-sm-8"> <div class="col-sm-8">
<?php $address_type = empty($value['email_type']) ? 'none' : $value['email_type']; ?> <?php
$address_type = empty($value['email_type']) ? 'none' : $value['email_type'];
?>
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="email_type" value="none" <input type="radio" name="email_type" value="none"
@ -772,7 +798,16 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?> ?>
<tr> <tr>
<td><?php echo $tmp_id; ?></td> <td><?php echo $tmp_id; ?></td>
<td><?php echo $cf['name']; ?></td> <td>
<?php
echo $cf['name'];
if ($cf['mfh_description'] !== null && trim($cf['mfh_description']) !== '') {
echo ' <i class="fa fa-info-circle" data-toggle="popover"
data-title="' . htmlspecialchars($hesklang['description']) . '"
data-content="' . htmlspecialchars($cf['mfh_description']) . '"></i>';
}
?>
</td>
<td><?php echo $cf['type']; ?></td> <td><?php echo $cf['type']; ?></td>
<td><?php echo $cf['use']; ?></td> <td><?php echo $cf['use']; ?></td>
<td><?php echo $cf['req']; ?></td> <td><?php echo $cf['req']; ?></td>
@ -885,6 +920,7 @@ function save_cf()
`req` = '{$cf['req']}', `req` = '{$cf['req']}',
`category` = ".(count($cf['categories']) ? "'".json_encode($cf['categories'])."'" : 'NULL').", `category` = ".(count($cf['categories']) ? "'".json_encode($cf['categories'])."'" : 'NULL').",
`name` = '".hesk_dbEscape($cf['names'])."', `name` = '".hesk_dbEscape($cf['names'])."',
`mfh_description` = '".hesk_dbEscape($cf['descriptions'])."',
`value` = ".(strlen($cf['value']) ? "'".hesk_dbEscape($cf['value'])."'" : 'NULL')." `value` = ".(strlen($cf['value']) ? "'".hesk_dbEscape($cf['value'])."'" : 'NULL')."
WHERE `id`={$id}"); WHERE `id`={$id}");
@ -916,6 +952,9 @@ function edit_cf()
$cf['names'] = json_decode($cf['name'], true); $cf['names'] = json_decode($cf['name'], true);
unset($cf['name']); unset($cf['name']);
$cf['descriptions'] = json_decode($cf['mfh_description'], true);
unset($cf['mfh_description']);
if (strlen($cf['category'])) if (strlen($cf['category']))
{ {
$cf['categories'] = json_decode($cf['category'], true); $cf['categories'] = json_decode($cf['category'], true);
@ -994,7 +1033,7 @@ function remove_cf()
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['cf_e_id']); $id = intval( hesk_GET('id') ) or hesk_error($hesklang['cf_e_id']);
// Reset the custom field // Reset the custom field
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_fields` SET `use`='0', `place`='0', `type`='text', `req`='0', `category`=NULL, `name`='', `value`=NULL, `order`=1000 WHERE `id`={$id}"); hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_fields` SET `use`='0', `place`='0', `type`='text', `req`='0', `category`=NULL, `name`='', `mfh_description`=NULL, `value`=NULL, `order`=1000 WHERE `id`={$id}");
// Were we successful? // Were we successful?
if ( hesk_dbAffectedRows() == 1 ) if ( hesk_dbAffectedRows() == 1 )
@ -1057,6 +1096,27 @@ function cf_validate()
$hesk_error_buffer[] = $hesklang['err_custname']; $hesk_error_buffer[] = $hesklang['err_custname'];
} }
// Descriptions
$cf['descriptions'] = hesk_POST_array('description');
// Make sure only non-empty descriptions pass
foreach ($cf['descriptions'] as $key => $description) {
if (!isset($hesk_settings['languages'][$key])) {
unset($cf['descriptions'][$key]);
} else {
$description = is_array($description) ? '' : hesk_input($description, 0, 0, HESK_SLASH);
if (strlen($description) < 1)
{
unset($cf['descriptions'][$key]);
}
else
{
$cf['descriptions'][$key] = stripslashes($description);
}
}
}
// Get type and values // Get type and values
$cf['type'] = hesk_POST('type'); $cf['type'] = hesk_POST('type');
switch ($cf['type']) switch ($cf['type'])
@ -1264,8 +1324,10 @@ function cf_validate()
} }
$cf['names'] = addslashes(json_encode($cf['names'])); $cf['names'] = addslashes(json_encode($cf['names']));
$cf['descriptions'] = addslashes(json_encode($cf['descriptions']));
$cf['value'] = $cf['type'] == 'date' ? json_encode($cf['value']) : addslashes(json_encode($cf['value'])); $cf['value'] = $cf['type'] == 'date' ? json_encode($cf['value']) : addslashes(json_encode($cf['value']));
return $cf; return $cf;
} // END cf_validate() } // END cf_validate()
@ -1305,7 +1367,8 @@ function new_cf()
`req` = '{$cf['req']}', `req` = '{$cf['req']}',
`category` = ".(count($cf['categories']) ? "'".json_encode($cf['categories'])."'" : 'NULL').", `category` = ".(count($cf['categories']) ? "'".json_encode($cf['categories'])."'" : 'NULL').",
`name` = '".hesk_dbEscape($cf['names'])."', `name` = '".hesk_dbEscape($cf['names'])."',
`value` = ".(strlen($cf['value']) ? "'".hesk_dbEscape($cf['value'])."'" : 'NULL').", `mfh_description` = '".hesk_dbEscape($cf['descriptions'])."',
`value` = ".(strlen($cf['value']) ? "'".hesk_dbEscape($cf['value'])."'" : 'NULL').",
`order` = 990 `order` = 990
WHERE `id`={$_SESSION['cford']}"); WHERE `id`={$_SESSION['cford']}");

@ -81,10 +81,10 @@ $i = 0;
// Possible priorities // Possible priorities
$priorities = array( $priorities = array(
'critical' => array('value' => 0, 'text' => $hesklang['critical'], 'formatted' => '<font class="critical">' . $hesklang['critical'] . '</font>'), 'critical' => array('value' => 0, 'lang' => 'critical', 'text' => $hesklang['critical'], 'formatted' => '<font class="critical">' . $hesklang['critical'] . '</font>'),
'high' => array('value' => 1, 'text' => $hesklang['high'], 'formatted' => '<font class="important">' . $hesklang['high'] . '</font>'), 'high' => array('value' => 1, 'lang' => 'high', 'text' => $hesklang['high'], 'formatted' => '<font class="important">' . $hesklang['high'] . '</font>'),
'medium' => array('value' => 2, 'text' => $hesklang['medium'], 'formatted' => '<font class="medium">' . $hesklang['medium'] . '</font>'), 'medium' => array('value' => 2, 'lang' => 'medium', 'text' => $hesklang['medium'], 'formatted' => '<font class="medium">' . $hesklang['medium'] . '</font>'),
'low' => array('value' => 3, 'text' => $hesklang['low'], 'formatted' => $hesklang['low']), 'low' => array('value' => 3, 'lang' => 'low', 'text' => $hesklang['low'], 'formatted' => $hesklang['low']),
); );
// Change priority // Change priority
@ -113,8 +113,10 @@ if (array_key_exists($_POST['a'], $priorities)) {
hesk_okCategory($ticket['category']); hesk_okCategory($ticket['category']);
$revision = sprintf($hesklang['thist8'], hesk_date(), $priority['formatted'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `priority`='{$priority['value']}' WHERE `id`={$this_id}");
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `priority`='{$priority['value']}', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`={$this_id}"); mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_priority', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $priority['lang']));
$i++; $i++;
} }
@ -133,8 +135,6 @@ elseif ($_POST['a'] == 'delete') {
require(HESK_PATH . 'inc/email_functions.inc.php'); require(HESK_PATH . 'inc/email_functions.inc.php');
} }
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
foreach ($_POST['id'] as $this_id) { foreach ($_POST['id'] as $this_id) {
if (is_array($this_id)) { if (is_array($this_id)) {
continue; continue;
@ -222,8 +222,6 @@ else {
hesk_token_check('POST'); hesk_token_check('POST');
require(HESK_PATH . 'inc/email_functions.inc.php'); require(HESK_PATH . 'inc/email_functions.inc.php');
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
foreach ($_POST['id'] as $this_id) { foreach ($_POST['id'] as $this_id) {
if (is_array($this_id)) { if (is_array($this_id)) {
continue; continue;
@ -239,7 +237,11 @@ else {
$closedStatusRS = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsStaffClosedOption` = 1"); $closedStatusRS = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsStaffClosedOption` = 1");
$closedStatus = hesk_dbFetchAssoc($closedStatusRS); $closedStatus = hesk_dbFetchAssoc($closedStatusRS);
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='" . $closedStatus['ID'] . "', `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . ", `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`='" . intval($this_id) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='" . $closedStatus['ID'] . "', `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . " WHERE `id`='" . intval($this_id) . "'");
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_closed', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
$i++; $i++;
// Notify customer of closed ticket? // Notify customer of closed ticket?
@ -284,6 +286,14 @@ function hesk_fullyDeleteTicket()
/* Delete ticket notes */ /* Delete ticket notes */
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` WHERE `ticket`='" . intval($ticket['id']) . "'"); hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` WHERE `ticket`='" . intval($ticket['id']) . "'");
/* Delete audit trail records */
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail_to_replacement_values`
WHERE `audit_trail_id` IN (
SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail`
WHERE `entity_type` = 'TICKET' AND `entity_id` = " . intval($ticket['id']) . ")");
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail` WHERE `entity_type`='TICKET'
AND `entity_id` = " . intval($ticket['id']));
/* Delete ticket reply drafts */ /* Delete ticket reply drafts */
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "reply_drafts` WHERE `ticket`=" . intval($ticket['id'])); hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "reply_drafts` WHERE `ticket`=" . intval($ticket['id']));

@ -36,6 +36,7 @@ if (!isset($_REQUEST['isManager']) || !$_REQUEST['isManager']) {
hesk_checkPermission('can_view_tickets'); hesk_checkPermission('can_view_tickets');
hesk_checkPermission('can_edit_tickets'); hesk_checkPermission('can_edit_tickets');
} }
$modsForHesk_settings = mfh_getSettings(); $modsForHesk_settings = mfh_getSettings();
/* Ticket ID */ /* Ticket ID */
@ -65,6 +66,7 @@ if (!isset($_REQUEST['isManager']) || !$_REQUEST['isManager']) {
hesk_okCategory($ticket['category']); hesk_okCategory($ticket['category']);
} }
if (hesk_isREQUEST('reply')) { if (hesk_isREQUEST('reply')) {
$tmpvar['id'] = intval(hesk_REQUEST('reply')) or die($hesklang['id_not_valid']); $tmpvar['id'] = intval(hesk_REQUEST('reply')) or die($hesklang['id_not_valid']);
@ -366,7 +368,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<label for="subject" class="col-sm-3 control-label"><?php echo $hesklang['subject'] . $required; ?></label> <label for="subject" class="col-sm-3 control-label"><?php echo $hesklang['subject'] . $required; ?></label>
<div class="col-sm-9"> <div class="col-sm-9">
<input class="form-control" type="text" name="subject" size="40" maxlength="40" <input class="form-control" type="text" name="subject" size="40" maxlength="70"
value="<?php echo $ticket['subject']; ?>" value="<?php echo $ticket['subject']; ?>"
placeholder="<?php echo htmlspecialchars($hesklang['subject']); ?>"/> placeholder="<?php echo htmlspecialchars($hesklang['subject']); ?>"/>
</div> </div>
@ -378,7 +380,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input class="form-control" type="text" name="name" size="40" maxlength="30" <input class="form-control" type="text" name="name" size="40" maxlength="50"
value="<?php echo $ticket['name']; ?>" value="<?php echo $ticket['name']; ?>"
placeholder="<?php echo htmlspecialchars($hesklang['name']); ?>" placeholder="<?php echo htmlspecialchars($hesklang['name']); ?>"
data-error="<?php echo $hesklang['this_field_is_required']; ?>" data-error="<?php echo $hesklang['this_field_is_required']; ?>"
@ -443,6 +445,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
echo '<div class="radio"><label><input type="radio" name="' . $k . '" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>'; echo '<div class="radio"><label><input type="radio" name="' . $k . '" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
} }
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div> echo '<div class="help-block with-errors"></div></div>
</div>'; </div>';
@ -473,9 +478,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
echo '<option ' . $selected . '>' . $option . '</option>'; echo '<option ' . $selected . '>' . $option . '</option>';
} }
if (!empty($v['mfh_description'])) {
echo '</select> echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
<div class="help-block with-errors"></div> }
echo '</select>';
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
break; break;
@ -496,6 +503,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
echo '<div class="checkbox"><label><input type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>'; echo '<div class="checkbox"><label><input type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
} }
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div> echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
@ -510,8 +520,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<div class="form-group' . $cls . '"> <div class="form-group' . $cls . '">
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label> <label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<textarea name="' . $k . '" class="form-control" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea> <textarea name="' . $k . '" class="form-control" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
break; break;
@ -530,8 +543,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<div class="form-group' . $cls . '"> <div class="form-group' . $cls . '">
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label> <label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" name="' . $k . '" value="' . $k_value . '" class="datepicker form-control" size="10" ' . $required_attribute . '> <input type="text" name="' . $k . '" value="' . $k_value . '" class="datepicker form-control" size="10" ' . $required_attribute . '>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
break; break;
@ -546,8 +562,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<div class="form-group' . $cls . '"> <div class="form-group' . $cls . '">
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label> <label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input class="form-control" type="text" name="' . $k . '" id="' . $k . '" value="' . $k_value . '" size="40" ' . $suggest . ' ' . $required_attribute . '> <input class="form-control" type="text" name="' . $k . '" id="' . $k . '" value="' . $k_value . '" size="40" ' . $suggest . ' ' . $required_attribute . '>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
<div id="' . $k . '_suggestions"></div> <div id="' . $k . '_suggestions"></div>
</div> </div>
@ -558,9 +577,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
case 'hidden': case 'hidden':
case 'readonly': case 'readonly':
default: default:
if (strlen($k_value) != 0) { $k_value = hesk_msgToPlain($k_value,0,0);
$v['value']['default_value'] = $k_value;
}
$cls = in_array($k, $_SESSION['iserror']) ? ' isError' : ''; $cls = in_array($k, $_SESSION['iserror']) ? ' isError' : '';
@ -568,8 +585,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<div class="form-group' . $cls . '"> <div class="form-group' . $cls . '">
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label> <label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $required_attribute . '> <input type="text" class="form-control" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $k_value . '" ' . $required_attribute . '>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div> </div>
'; ';
@ -624,16 +644,20 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
} }
?> ?>
</div> </div>
<div class="form-group" style="text-align: center"> <div class="form-group">
<?php <div class="col-md-9 col-md-offset-3">
$html = $ticket['html'] ? 1 : 0; <?php
?> $html = $ticket['html'] ? 1 : 0;
<input type="hidden" name="html" value="<?php echo $html; ?>"> ?>
<input type="submit" value="<?php echo $hesklang['save_changes']; ?>" class="btn btn-default"> <input type="hidden" name="html" value="<?php echo $html; ?>">
<?php if (isset($_REQUEST['isManager']) && $_REQUEST['isManager']): ?> <div class="btn-group">
<input type="hidden" name="isManager" value="1"> <input type="submit" value="<?php echo $hesklang['save_changes']; ?>" class="btn btn-primary">
<?php endif; ?> <a class="btn btn-default" href="javascript:history.go(-1)"><?php echo $hesklang['back']; ?></a>
<a class="btn btn-default" href="javascript:history.go(-1)"><?php echo $hesklang['back']; ?></a> </div>
<?php if (isset($_REQUEST['isManager']) && $_REQUEST['isManager']): ?>
<input type="hidden" name="isManager" value="1">
<?php endif; ?>
</div>
</div> </div>
</form> </form>
</div> </div>

@ -291,7 +291,7 @@ $orderBy = $modsForHesk_settings['category_order_column'];
$res2 = hesk_dbQuery("SELECT `id`, `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE " . hesk_myCategories('id') . " ORDER BY `" . $orderBy . "` ASC"); $res2 = hesk_dbQuery("SELECT `id`, `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE " . hesk_myCategories('id') . " ORDER BY `" . $orderBy . "` ASC");
while ($row = hesk_dbFetchAssoc($res2)) { while ($row = hesk_dbFetchAssoc($res2)) {
$my_cat[$row['id']] = hesk_msgToPlain($row['name'], 1); $my_cat[$row['id']] = hesk_msgToPlain($row['name'], 1);
$row['name'] = (strlen($row['name']) > 50) ? substr($row['name'], 0, 50) . '...' : $row['name']; $row['name'] = (hesk_mb_strlen($row['name']) > 50) ? hesk_mb_substr($row['name'],0,50) . '...' : $row['name'];
$cat_selected = ($row['id'] == $category) ? 'selected="selected"' : ''; $cat_selected = ($row['id'] == $category) ? 'selected="selected"' : '';
$category_options .= '<option value="' . $row['id'] . '" ' . $cat_selected . '>' . $row['name'] . '</option>'; $category_options .= '<option value="' . $row['id'] . '" ' . $cat_selected . '>' . $row['name'] . '</option>';
} }
@ -697,7 +697,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
(<?php echo $hesklang['m' . date('n')]; ?>) (<?php echo $hesklang['m' . date('n')]; ?>)
</option> </option>
<option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?> <option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?>
(<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, date('d'), date('Y')))]; ?> (<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, 1, date('Y')))]; ?>
) )
</option> </option>
<option value="5" <?php echo $selected['time'][5]; ?>><?php echo $hesklang['r5']; ?></option> <option value="5" <?php echo $selected['time'][5]; ?>><?php echo $hesklang['r5']; ?></option>

@ -145,21 +145,21 @@ LEFT(`message`, 400) AS `message`,
$sql .= " ( `trackid` = '" . hesk_dbEscape($q) . "' OR `merged` LIKE '%#" . hesk_dbEscape($q) . "#%' ) "; $sql .= " ( `trackid` = '" . hesk_dbEscape($q) . "' OR `merged` LIKE '%#" . hesk_dbEscape($q) . "#%' ) ";
break; break;
case 'name': case 'name':
$sql .= "`name` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' "; $sql .= "`name` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' ";
break; break;
case 'email': case 'email':
$sql .= "`email` LIKE '%" . hesk_dbEscape($q) . "%' "; $sql .= "`email` LIKE '%" . hesk_dbEscape($q) . "%' ";
break; break;
case 'subject': case 'subject':
$sql .= "`subject` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' "; $sql .= "`subject` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' ";
break; break;
case 'message': case 'message':
$sql .= " ( `message` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' $sql .= " ( `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "'
OR OR
`id` IN ( `id` IN (
SELECT DISTINCT `replyto` SELECT DISTINCT `replyto`
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies`
WHERE `message` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' ) WHERE `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' )
) )
"; ";
break; break;
@ -170,7 +170,7 @@ LEFT(`message`, 400) AS `message`,
$sql .= "`id` IN ( $sql .= "`id` IN (
SELECT DISTINCT `ticket` SELECT DISTINCT `ticket`
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes`
WHERE `message` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' ) WHERE `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' )
"; ";
break; break;
default: default:
@ -220,6 +220,9 @@ LEFT(`message`, 400) AS `message`,
$sql_count .= $sql; $sql_count .= $sql;
$sql = $sql_final . $sql; $sql = $sql_final . $sql;
// Strip extra slashes
$q = stripslashes($q);
/* Prepare variables used in search and forms */ /* Prepare variables used in search and forms */
require_once(HESK_PATH . 'inc/prepare_ticket_search.inc.php'); require_once(HESK_PATH . 'inc/prepare_ticket_search.inc.php');
?> ?>

@ -158,7 +158,7 @@ function do_login()
exit(); exit();
} }
$pass_enc = hesk_Pass2Hash($_SESSION['pass'] . strtolower($user) . $_SESSION['pass']); $pass_enc = hesk_Pass2Hash($_SESSION['pass'].hesk_mb_strtolower($user).$_SESSION['pass']);
/* Check if default password */ /* Check if default password */
if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079') { if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079') {
@ -202,7 +202,6 @@ function do_login()
/* Close any old tickets here so Cron jobs aren't necessary */ /* Close any old tickets here so Cron jobs aren't necessary */
if ($hesk_settings['autoclose']) { if ($hesk_settings['autoclose']) {
$revision = sprintf($hesklang['thist3'], hesk_date(), $hesklang['auto']);
$dt = date('Y-m-d H:i:s', time() - $hesk_settings['autoclose'] * 86400); $dt = date('Y-m-d H:i:s', time() - $hesk_settings['autoclose'] * 86400);
@ -210,22 +209,25 @@ function do_login()
$closedStatus = hesk_dbFetchAssoc($closedStatusRs); $closedStatus = hesk_dbFetchAssoc($closedStatusRs);
// Are we allowed to close tickets in this status? // Are we allowed to close tickets in this status?
if ($closedStatus['Closable'] == 'yes' || $closedStatus['Closable'] == 'sonly') { if ($closedStatus['Closable'] == 'yes' || $closedStatus['Closable'] == 'sonly') {
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed']) {
// Get list of tickets
$result = hesk_dbQuery("SELECT * FROM `" . $hesk_settings['db_pfix'] . "tickets` WHERE `status` = " . $closedStatus['ID'] . " AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
if (hesk_dbNumRows($result) > 0) {
global $ticket;
// Load required functions?
if (!function_exists('hesk_notifyCustomer')) {
require(HESK_PATH . 'inc/email_functions.inc.php');
}
while ($ticket = hesk_dbFetchAssoc($result)) { $result = hesk_dbQuery("SELECT * FROM `" . $hesk_settings['db_pfix'] . "tickets` WHERE `status` = " . $closedStatus['ID'] . " AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
$ticket['dt'] = hesk_date($ticket['dt'], true); if (hesk_dbNumRows($result) > 0) {
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true); global $ticket;
$ticket = hesk_ticketToPlain($ticket, 1, 0);
// Load required functions?
if (!function_exists('hesk_notifyCustomer')) {
require(HESK_PATH . 'inc/email_functions.inc.php');
}
while ($ticket = hesk_dbFetchAssoc($result)) {
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$ticket = hesk_ticketToPlain($ticket, 1, 0);
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_automatically_closed', hesk_date(), array());
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed']) {
// Get list of tickets
hesk_notifyCustomer($modsForHesk_settings, 'ticket_closed'); hesk_notifyCustomer($modsForHesk_settings, 'ticket_closed');
} }
} }
@ -234,7 +236,7 @@ function do_login()
// Update ticket statuses and history in database if we're allowed to do so // Update ticket statuses and history in database if we're allowed to do so
$defaultCloseRs = hesk_dbQuery('SELECT `ID` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `IsAutocloseOption` = 1'); $defaultCloseRs = hesk_dbQuery('SELECT `ID` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `IsAutocloseOption` = 1');
$defaultCloseStatus = hesk_dbFetchAssoc($defaultCloseRs); $defaultCloseStatus = hesk_dbFetchAssoc($defaultCloseRs);
hesk_dbQuery("UPDATE `" . $hesk_settings['db_pfix'] . "tickets` SET `status`=" . intval($defaultCloseStatus['ID']) . ", `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `status` = '" . $closedStatus['ID'] . "' AND `lastchange` <= '" . hesk_dbEscape($dt) . "' "); hesk_dbQuery("UPDATE `" . $hesk_settings['db_pfix'] . "tickets` SET `status`=" . intval($defaultCloseStatus['ID']) . ", `closedat`=NOW(), `closedby`='-1' WHERE `status` = " . $closedStatus['ID'] . " AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
} }
} }
@ -276,6 +278,12 @@ function print_login()
<?php <?php
/* This will handle error, success and notice messages */ /* This will handle error, success and notice messages */
hesk_handle_messages(); hesk_handle_messages();
// Service messages
$service_messages = mfh_get_service_messages('STAFF_LOGIN');
foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
?> ?>
</div> </div>
<div class="login-logo"> <div class="login-logo">
@ -328,7 +336,7 @@ function print_login()
<select class="form-control" name="user"> <select class="form-control" name="user">
<?php <?php
while ($row = hesk_dbFetchAssoc($res)): while ($row = hesk_dbFetchAssoc($res)):
$sel = (strtolower($savedUser) == strtolower($row['user'])) ? 'selected' : ''; $sel = (hesk_mb_strtolower($savedUser) == hesk_mb_strtolower($row['user'])) ? 'selected="selected"' : '';
?> ?>
<option value="<?php echo $row['user']; ?>" <?php echo $sel; ?>> <option value="<?php echo $row['user']; ?>" <?php echo $sel; ?>>
<?php echo $row['user']; ?> <?php echo $row['user']; ?>
@ -467,6 +475,9 @@ function print_login()
</div> </div>
</div> </div>
</form> </form>
<a class="btn btn-default" href="<?php echo $hesk_settings['hesk_url']; ?>">
<i class="fa fa-chevron-left"></i> <?php echo $hesklang['back']; ?>
</a>
</div> </div>
</div> </div>
</div> </div>

@ -121,7 +121,9 @@ function hesk_kb_header($kb_link, $catid=1)
</ol> </ol>
<?php <?php
show_subnav('view', $catid); show_subnav('view', $catid);
echo '<div style="margin-left:40px;margin-right:40px">';
hesk_kbSearchLarge(1); hesk_kbSearchLarge(1);
echo '</div>';
} // END hesk_kb_header() } // END hesk_kb_header()
@ -214,7 +216,15 @@ function hesk_show_kb_article($artid)
?> ?>
<div class="content-wrapper"> <div class="content-wrapper">
<?php hesk_kb_header($hesk_settings['kb_link'], $article['catid']); ?> <?php
hesk_kb_header($hesk_settings['kb_link'], $article['catid']);
echo '<div style="margin-left:40px;margin-right:40px">';
$service_messages = mfh_get_service_messages('STAFF_VIEW_KB_ARTICLE');
foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
echo '</div>';
?>
<section class="content"> <section class="content">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
@ -397,6 +407,13 @@ function hesk_show_kb_category($catid, $is_search = 0) {
{ {
/* Print header */ /* Print header */
hesk_kb_header($hesk_settings['kb_link'], $catid); hesk_kb_header($hesk_settings['kb_link'], $catid);
echo '<div style="margin-left:40px;margin-right:40px">';
$service_messages = mfh_get_service_messages('STAFF_KB_HOME');
foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
echo '</div>';
} ?> } ?>
<section class="content"> <section class="content">
<?php if ($thiscat['parent']): ?> <?php if ($thiscat['parent']): ?>

@ -37,27 +37,31 @@ hesk_token_check();
/* Ticket ID */ /* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']); $trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']);
// Get ticket info
$result = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1");
if (hesk_dbNumRows($result) != 1) {
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
$audit_unlocked = null;
$audit_locked = null;
/* New locked status */ /* New locked status */
if (empty($_GET['locked'])) { if (empty($_GET['locked'])) {
$status = 0; $status = 0;
$tmp = $hesklang['tunlock']; $tmp = $hesklang['tunlock'];
$revision = sprintf($hesklang['thist6'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_unlocked = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL '; $closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
} else { } else {
$status = 1; $status = 1;
$tmp = $hesklang['tlock']; $tmp = $hesklang['tlock'];
$revision = sprintf($hesklang['thist5'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); $audit_locked = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
$closedby_sql = ' , `closedat`=NOW(), `closedby`=' . intval($_SESSION['id']) . ' '; $closedby_sql = ' , `closedat`=NOW(), `closedby`=' . intval($_SESSION['id']) . ' ';
// Notify customer of closed ticket? // Notify customer of closed ticket?
if ($hesk_settings['notify_closed']) { if ($hesk_settings['notify_closed']) {
// Get ticket info
$result = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1");
if (hesk_dbNumRows($result) != 1) {
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
$closedStatusRS = hesk_dbQuery('SELECT `ID` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `IsClosed` = 1'); $closedStatusRS = hesk_dbQuery('SELECT `ID` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `IsClosed` = 1');
$ticketIsOpen = true; $ticketIsOpen = true;
while ($row = hesk_dbFetchAssoc($closedStatusRS)) { while ($row = hesk_dbFetchAssoc($closedStatusRS)) {
@ -82,7 +86,17 @@ $statusRs = hesk_dbQuery($statusSql);
$statusRow = hesk_dbFetchAssoc($statusRs); $statusRow = hesk_dbFetchAssoc($statusRs);
$statusId = $statusRow['ID']; $statusId = $statusRow['ID'];
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`= {$statusId},`locked`='{$status}' $closedby_sql , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`= {$statusId},`locked`='{$status}' $closedby_sql WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
if ($audit_unlocked) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_unlocked', hesk_date(),
$audit_unlocked);
}
if ($audit_locked) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_locked', hesk_date(),
$audit_locked);
}
/* Back to ticket page and show a success message */ /* Back to ticket page and show a success message */
hesk_process_messages($tmp, 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . rand(10000, 99999), 'SUCCESS'); hesk_process_messages($tmp, 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . rand(10000, 99999), 'SUCCESS');

@ -32,7 +32,7 @@ $modsForHesk_settings = mfh_getSettings();
/* List of staff */ /* List of staff */
$admins = array(); $admins = array();
$res = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC"); $res = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `active` = '1' ORDER BY `name` ASC");
while ($row = hesk_dbFetchAssoc($res)) { while ($row = hesk_dbFetchAssoc($res)) {
$admins[$row['id']] = $row['name']; $admins[$row['id']] = $row['name'];
} }

File diff suppressed because it is too large Load Diff

@ -324,6 +324,8 @@ function getSpecialTagMap()
$map['%%OWNER%%'] = $hesklang['ticket_owner']; $map['%%OWNER%%'] = $hesklang['ticket_owner'];
$map['%%PRIORITY%%'] = $hesklang['ticket_priority']; $map['%%PRIORITY%%'] = $hesklang['ticket_priority'];
$map['%%STATUS%%'] = $hesklang['ticket_status']; $map['%%STATUS%%'] = $hesklang['ticket_status'];
$map['%%LAST_REPLY_BY%%'] = $hesklang['last_reply_by'];
$map['%%TIME_WORKED%%'] = $hesklang['ts'];
$i = 1; $i = 1;
foreach ($hesk_settings['custom_fields'] as $key => $value) { foreach ($hesk_settings['custom_fields'] as $key => $value) {

@ -212,7 +212,8 @@ while (count($kb_cat) > 0)
if (isset($node[$up])) if (isset($node[$up]))
{ {
$node[$my] = &$node[$up]->addItem(new HTML_TreeNode(array('hesk_selected' => $selected, 'text' => $text, 'text_short' => $text_short, 'menu_icons' => $menu_icons, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true))); $HTML_TreeNode[$my] = new HTML_TreeNode(array('hesk_selected' => $selected, 'text' => $text, 'text_short' => $text_short, 'menu_icons' => $menu_icons, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true));
$node[$my] = &$node[$up]->addItem($HTML_TreeNode[$my]);
} }
else else
{ {
@ -242,8 +243,11 @@ while (count($kb_cat) > 0)
$menu->addItem($node[1]); $menu->addItem($node[1]);
// Create the presentation class // Create the presentation class
$treeMenu = & ref_new(new HTML_TreeMenu_DHTML($menu, array('images' => '../img', 'defaultClass' => 'treeMenuDefault', 'isDynamic' => true))); $HTML_TreeMenu_DHTML = new HTML_TreeMenu_DHTML($menu, array('images' => '../img', 'defaultClass' => 'treeMenuDefault', 'isDynamic' => true));
$listBox = & ref_new(new HTML_TreeMenu_Listbox($menu)); $treeMenu = & ref_new($HTML_TreeMenu_DHTML);
$HTML_TreeMenu_Listbox = new HTML_TreeMenu_Listbox($menu);
$listBox = & ref_new($HTML_TreeMenu_Listbox);
/* Hide new article and new category forms by default */ /* Hide new article and new category forms by default */
if (!isset($_SESSION['hide'])) if (!isset($_SESSION['hide']))
@ -270,6 +274,12 @@ if (!isset($_SESSION['hide']['treemenu']))
<?php <?php
show_subnav(); show_subnav();
// Service messages
$service_messages = mfh_get_service_messages('STAFF_KB_HOME');
foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
// Show a notice if total public articles is less than 5 // Show a notice if total public articles is less than 5
if ($total_articles < 5) if ($total_articles < 5)
{ {
@ -895,7 +905,7 @@ function import_article()
$_SESSION['new_article'] = array( $_SESSION['new_article'] = array(
'html' => 0, 'html' => 0,
'subject' => $ticket['subject'], 'subject' => $ticket['subject'],
'content' => hesk_msgToPlain($ticket['message']), 'content' => hesk_msgToPlain($ticket['message'], 0, 0),
); );
} }
@ -910,10 +920,14 @@ function import_article()
} }
else else
{ {
$_SESSION['new_article']['content'] .= "\n\n" . hesk_msgToPlain($reply['message']); $_SESSION['new_article']['content'] .= "\n\n" . hesk_msgToPlain($reply['message'], 0, 0);
} }
} }
// Make sure everything is extra slashed as stripslashes will be called later
$_SESSION['new_article']['subject'] = addslashes($_SESSION['new_article']['subject']);
$_SESSION['new_article']['content'] = addslashes($_SESSION['new_article']['content']);
hesk_process_messages($hesklang['import'],'NOREDIRECT','NOTICE'); hesk_process_messages($hesklang['import'],'NOREDIRECT','NOTICE');
} // END add_article() } // END add_article()
@ -1338,7 +1352,8 @@ function edit_article()
if (isset($node[$up])) if (isset($node[$up]))
{ {
$node[$my] = &$node[$up]->addItem(new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true))); $HTML_TreeNode[$my] = new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true));
$node[$my] = &$node[$up]->addItem($HTML_TreeNode[$my]);
} }
else else
{ {
@ -1368,7 +1383,8 @@ function edit_article()
$menu->addItem($node[1]); $menu->addItem($node[1]);
// Create the presentation class // Create the presentation class
$listBox = & ref_new(new HTML_TreeMenu_Listbox($menu)); $HTML_TreeMenu_Listbox = new HTML_TreeMenu_Listbox($menu);
$listBox = & ref_new($HTML_TreeMenu_Listbox);
/* Print header */ /* Print header */
require_once(HESK_PATH . 'inc/headerAdmin.inc.php'); require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
@ -1595,6 +1611,9 @@ function manage_category() {
foreach ($kb_cat as $k=>$cat) foreach ($kb_cat as $k=>$cat)
{ {
if ($cat['id'] == $catid) {
continue;
}
if (in_array($cat['parent'],$thislevel)) if (in_array($cat['parent'],$thislevel))
{ {
@ -1607,7 +1626,8 @@ function manage_category() {
if (isset($node[$up])) if (isset($node[$up]))
{ {
$node[$my] = &$node[$up]->addItem(new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true))); $HTML_TreeNode[$my] = new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true));
$node[$my] = &$node[$up]->addItem($HTML_TreeNode[$my]);
} }
else else
{ {
@ -1637,7 +1657,8 @@ function manage_category() {
$menu->addItem($node[1]); $menu->addItem($node[1]);
// Create the presentation class // Create the presentation class
$listBox = & ref_new(new HTML_TreeMenu_Listbox($menu)); $HTML_TreeMenu_Listbox = new HTML_TreeMenu_Listbox($menu);
$listBox = & ref_new($HTML_TreeMenu_Listbox);
/* Print header */ /* Print header */
require_once(HESK_PATH . 'inc/headerAdmin.inc.php'); require_once(HESK_PATH . 'inc/headerAdmin.inc.php');

@ -39,10 +39,6 @@ if ($action = hesk_REQUEST('a')) {
create(); create();
} elseif ($action == 'delete') { } elseif ($action == 'delete') {
deleteTemplate(); deleteTemplate();
} elseif ($action == 'addadmin') {
toggleAdmin(true);
} elseif ($action == 'deladmin') {
toggleAdmin(false);
} }
} }
@ -51,34 +47,20 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
/* Print main manage users page */ /* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<script language="Javascript" type="text/javascript"><!--
function confirm_delete() {
if (confirm('<?php echo hesk_makeJsString($hesklang['confirm_del_cat']); ?>')) {
return true;
}
else {
return false;
}
}
//-->
</script>
<?php
$modsForHesk_settings = mfh_getSettings(); $modsForHesk_settings = mfh_getSettings();
$res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` ORDER BY `name` ASC"); $res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` ORDER BY `name` ASC");
$templates = array(); $templates = array();
while ($row = hesk_dbFetchAssoc($res)) { while ($row = hesk_dbFetchAssoc($res)) {
array_push($templates, $row); $templates[] = $row;
} }
$featureArray = hesk_getFeatureArray(); $featureArray = hesk_getFeatureArray();
$orderBy = $modsForHesk_settings['category_order_column']; $orderBy = $modsForHesk_settings['category_order_column'];
$res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` ORDER BY `" . $orderBy . "` ASC"); $res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` ORDER BY `" . $orderBy . "` ASC");
$categories = array(); $categories = array();
while ($row = hesk_dbFetchAssoc($res)) { while ($row = hesk_dbFetchAssoc($res)) {
array_push($categories, $row); $categories[] = $row;
} }
?> ?>
<div class="content-wrapper"> <div class="content-wrapper">
@ -87,9 +69,9 @@ while ($row = hesk_dbFetchAssoc($res)) {
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h1 class="box-title"> <h1 class="box-title">
<?php echo $hesklang['manage_permission_templates']; ?> <?php echo $hesklang['manage_permission_groups']; ?>
<i class="fa fa-question-circle settingsquestionmark" data-toggle="tooltip" data-placement="right" <i class="fa fa-question-circle settingsquestionmark" data-toggle="tooltip" data-placement="right"
title="<?php echo $hesklang['manage_permission_templates_help']; ?>"></i> title="<?php echo $hesklang['manage_permission_groups_help']; ?>"></i>
</h1> </h1>
<div class="box-tools pull-right"> <div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"> <button type="button" class="btn btn-box-tool" data-widget="collapse">
@ -98,14 +80,19 @@ while ($row = hesk_dbFetchAssoc($res)) {
</div> </div>
</div> </div>
<div class="box-body"> <div class="box-body">
<a href="#" data-toggle="modal" data-target="#modal-template-new" class="btn btn-success nu-floatRight"> <div class="text-right">
<i class="fa fa-plus-circle"></i> <?php echo $hesklang['create_new_template']; ?> <a href="#" data-toggle="modal" data-target="#modal-template-new" class="btn btn-success nu-floatRight">
</a> <i class="fa fa-plus-circle"></i> <?php echo $hesklang['create_new']; ?>
</a>
</div>
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<th><?php echo $hesklang['name']; ?></th> <tr>
<th><?php echo $hesklang['number_of_users']; ?></th> <th><?php echo $hesklang['name']; ?></th>
<th><?php echo $hesklang['actions']; ?></th> <th><?php echo $hesklang['number_of_users']; ?></th>
<th><?php echo $hesklang['actions']; ?></th>
</tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($templates as $row): ?> <?php foreach ($templates as $row): ?>
@ -114,30 +101,13 @@ while ($row = hesk_dbFetchAssoc($res)) {
<td><?php echo getNumberOfUsersWithPermissionGroup($row['id']); ?></td> <td><?php echo getNumberOfUsersWithPermissionGroup($row['id']); ?></td>
<td> <td>
<a href="#" data-toggle="modal" data-target="#modal-template-<?php echo $row['id'] ?>"> <a href="#" data-toggle="modal" data-target="#modal-template-<?php echo $row['id'] ?>">
<i class="fa fa-pencil icon-link" data-toggle="tooltip" <i class="fa fa-fw fa-pencil icon-link orange" data-toggle="tooltip"
title="<?php echo $hesklang['view_permissions_for_this_template'] ?>"></i></a> title="<?php echo $hesklang['view_permissions_for_this_group'] ?>"></i></a>
<?php if ($row['id'] == 1) { ?> <?php
<i class="fa fa-star icon-link orange" data-toggle="tooltip"
title="<?php echo $hesklang['admin_cannot_be_staff']; ?>"></i></a>
<?php } elseif ($row['heskprivileges'] == 'ALL' && $row['categories'] == 'ALL'){ ?>
<a href="manage_permission_templates.php?a=deladmin&amp;id=<?php echo $row['id']; ?>">
<i class="fa fa-star icon-link orange" data-toggle="tooltip"
title="<?php echo $hesklang['template_has_admin_privileges']; ?>"></i></a>
<?php } elseif ($row['id'] != 2) { ?>
<a href="manage_permission_templates.php?a=addadmin&amp;id=<?php echo $row['id']; ?>">
<i class="fa fa-star-o icon-link gray" data-toggle="tooltip"
title="<?php echo $hesklang['template_has_no_admin_privileges']; ?>"></i></a>
<?php
} else {
?>
<i class="fa fa-star-o icon-link gray" data-toggle="tooltip"
title="<?php echo $hesklang['staff_cannot_be_admin']; ?>"></i>
<?php
}
if ($row['id'] != 1 && $row['id'] != 2): if ($row['id'] != 1 && $row['id'] != 2):
?> ?>
<a href="manage_permission_templates.php?a=delete&amp;id=<?php echo $row['id']; ?>"> <a href="manage_permission_groups.php?a=delete&amp;id=<?php echo $row['id']; ?>">
<i class="fa fa-times icon-link red" data-toggle="tooltip" <i class="fa fa-fw fa-times icon-link red" data-toggle="tooltip"
title="<?php echo $hesklang['delete']; ?>"></i></a> title="<?php echo $hesklang['delete']; ?>"></i></a>
<?php endif; ?> <?php endif; ?>
</td> </td>
@ -172,13 +142,9 @@ function createEditModal($template, $features, $categories)
{ {
global $hesklang; global $hesklang;
$showNotice = true;
$disabled = 'checked="checked" disabled';
$enabledFeatures = array(); $enabledFeatures = array();
$enabledCategories = array(); $enabledCategories = array();
if ($template['heskprivileges'] != 'ALL') { if ($template['heskprivileges'] !== 'ALL') {
$showNotice = false;
$disabled = '';
$enabledFeatures = explode(',', $template['heskprivileges']); $enabledFeatures = explode(',', $template['heskprivileges']);
$enabledCategories = explode(',', $template['categories']); $enabledCategories = explode(',', $template['categories']);
} }
@ -187,30 +153,29 @@ function createEditModal($template, $features, $categories)
aria-labelledby="myLargeModalLabel" aria-hidden="true"> aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<form action="manage_permission_templates.php" role="form" method="post" id="form<?php echo $template['id']; ?>"> <form action="manage_permission_groups.php" role="form" method="post" id="form<?php echo $template['id']; ?>">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><?php echo sprintf($hesklang['permissions_for_template'], $template['name']); ?></h4> <h4 class="modal-title"><?php echo sprintf($hesklang['permissions_for_group'], $template['name']); ?></h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<?php if ($template['id'] == 1): ?>
<div class="alert alert-info">
<i class="fa fa-info-circle"></i>
<?php echo $hesklang['protected_group']; ?>
</div>
<?php endif; ?>
<div class="row"> <div class="row">
<?php if ($showNotice): ?>
<div class="col-sm-12">
<div class="alert alert-info">
<i class="fa fa-info-circle"></i> <?php echo $hesklang['template_is_admin_cannot_change']; ?>
</div>
</div>
<?php endif; ?>
<div class="form-group"> <div class="form-group">
<div class="col-sm-2"> <div class="col-sm-2">
<label for="name" <label for="name"
class="control-label"><?php echo $hesklang['template_name']; ?></label> class="control-label"><?php echo $hesklang['group_name']; ?></label>
</div> </div>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="text" class="form-control" name="name" <input type="text" class="form-control" name="name"
value="<?php echo htmlspecialchars($template['name']); ?>" value="<?php echo htmlspecialchars($template['name']); ?>"
placeholder="<?php echo htmlspecialchars($hesklang['template_name']); ?>" placeholder="<?php echo htmlspecialchars($hesklang['group_name']); ?>"
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>" data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
required> required>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
@ -223,20 +188,32 @@ function createEditModal($template, $features, $categories)
<div class="footerWithBorder blankSpace"></div> <div class="footerWithBorder blankSpace"></div>
<div class="form-group"> <div class="form-group">
<?php foreach ($categories as $category): ?> <?php
foreach ($categories as $category): ?>
<?php
$checked = '';
$disabled = '';
if (in_array($category['id'], $enabledCategories) ||
$template['categories'] == 'ALL') {
$checked = 'checked ';
}
if ((!hesk_SESSION('isadmin') &&
!in_array($category['id'], $_SESSION['categories'])) ||
$template['categories'] === 'ALL') {
$disabled = ' disabled';
}?>
<?php if ($_SESSION['isadmin'] || in_array($category['id'], $_SESSION['categories']) || $checked): ?>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<?php
$checked = '';
if (in_array($category['id'], $enabledCategories) && !$showNotice) {
$checked = 'checked';
} ?>
<input type="checkbox" name="categories[]" <input type="checkbox" name="categories[]"
value="<?php echo $category['id']; ?>" <?php echo $checked . $disabled; ?>> value="<?php echo $category['id']; ?>" <?php echo $checked . ' ' . $disabled; ?>>
<?php echo $category['name']; ?> <?php echo $category['name']; ?>
</label> </label>
</div> </div>
<?php endforeach; ?> <?php
endif;
endforeach; ?>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
@ -245,19 +222,30 @@ function createEditModal($template, $features, $categories)
<div class="footerWithBorder blankSpace"></div> <div class="footerWithBorder blankSpace"></div>
<div class="form-group"> <div class="form-group">
<?php foreach ($features as $feature): ?> <?php
foreach ($features as $feature): ?>
<?php
$checked = '';
$disabled = '';
if (in_array($feature, $enabledFeatures) ||
$template['heskprivileges'] === 'ALL') {
$checked = 'checked ';
}
if ((!hesk_SESSION('isadmin') &&
strpos($_SESSION['heskprivileges'], $feature) === false) ||
$template['heskprivileges'] === 'ALL') {
$disabled = ' disabled';
}
if ($_SESSION['isadmin'] || strpos($_SESSION['heskprivileges'], $feature) !== false || $checked): ?>
<div class="checkbox"> <div class="checkbox">
<label><?php <label>
$checked = '';
if (in_array($feature, $enabledFeatures) && !$showNotice) {
$checked = 'checked';
} ?>
<input type="checkbox" name="features[]" <input type="checkbox" name="features[]"
value="<?php echo $feature; ?>" <?php echo $checked . $disabled; ?>> value="<?php echo $feature; ?>" <?php echo $checked . $disabled; ?>>
<?php echo $hesklang[$feature]; ?> <?php echo $hesklang[$feature]; ?>
</label> </label>
</div> </div>
<?php endforeach; ?> <?php endif;
endforeach; ?>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
@ -266,9 +254,6 @@ function createEditModal($template, $features, $categories)
<div class="modal-footer"> <div class="modal-footer">
<input type="hidden" name="a" value="save"> <input type="hidden" name="a" value="save">
<input type="hidden" name="template_id" value="<?php echo $template['id']; ?>"> <input type="hidden" name="template_id" value="<?php echo $template['id']; ?>">
<?php if ($showNotice): ?>
<input type="hidden" name="name_only" value="1">
<?php endif; ?>
<div class="btn-group"> <div class="btn-group">
<input type="submit" class="btn btn-success" <input type="submit" class="btn btn-success"
value="<?php echo $hesklang['save_changes']; ?>"> value="<?php echo $hesklang['save_changes']; ?>">
@ -291,22 +276,22 @@ function buildCreateModal($features, $categories)
aria-hidden="true"> aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<form action="manage_permission_templates.php" role="form" method="post" id="createForm"> <form action="manage_permission_groups.php" role="form" method="post" id="createForm">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><?php echo $hesklang['create_new_template_title']; ?></h4> <h4 class="modal-title"><?php echo $hesklang['create_new_group_title']; ?></h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">
<div class="form-group"> <div class="form-group">
<div class="col-sm-2"> <div class="col-sm-2">
<label for="name" <label for="name"
class="control-label"><?php echo $hesklang['template_name']; ?></label> class="control-label"><?php echo $hesklang['group_name']; ?></label>
</div> </div>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="text" class="form-control" name="name" <input type="text" class="form-control" name="name"
placeholder="<?php echo $hesklang['template_name']; ?>" required> placeholder="<?php echo $hesklang['group_name']; ?>" required>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
@ -317,7 +302,9 @@ function buildCreateModal($features, $categories)
<div class="footerWithBorder blankSpace"></div> <div class="footerWithBorder blankSpace"></div>
<div class="form-group"> <div class="form-group">
<?php foreach ($categories as $category): ?> <?php
foreach ($categories as $category):
if (hesk_SESSION('isadmin') || in_array($category['id'], $_SESSION['categories'])): ?>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" name="categories[]" <input type="checkbox" name="categories[]"
@ -327,7 +314,7 @@ function buildCreateModal($features, $categories)
<?php echo $category['name']; ?> <?php echo $category['name']; ?>
</label> </label>
</div> </div>
<?php endforeach; ?> <?php endif; endforeach; ?>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
@ -336,7 +323,9 @@ function buildCreateModal($features, $categories)
<div class="footerWithBorder blankSpace"></div> <div class="footerWithBorder blankSpace"></div>
<div class="form-group"> <div class="form-group">
<?php foreach ($features as $feature): ?> <?php foreach ($features as $feature):
if (strpos($_SESSION['heskprivileges'], $feature) !== false || hesk_SESSION('isadmin')):
?>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" name="features[]" <input type="checkbox" name="features[]"
@ -346,7 +335,7 @@ function buildCreateModal($features, $categories)
<?php echo $hesklang[$feature]; ?> <?php echo $hesklang[$feature]; ?>
</label> </label>
</div> </div>
<?php endforeach; ?> <?php endif; endforeach; ?>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
@ -381,40 +370,68 @@ function save()
WHERE `id` = " . intval($templateId)); WHERE `id` = " . intval($templateId));
$row = hesk_dbFetchAssoc($res); $row = hesk_dbFetchAssoc($res);
if (hesk_POST('name_only', 0)) { // Add 'can ban emails' if 'can unban emails' is set (but not added). Same with 'can ban ips'
// We are only able to update the name $catArray = hesk_POST_array('categories');
$name = hesk_POST('name'); $featArray = hesk_POST_array('features');
validate($featArray, $catArray);
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` if (in_array('can_unban_emails', $featArray) && !in_array('can_ban_emails', $featArray)) {
SET `name` = '" . hesk_dbEscape($name) . "' WHERE `id` = " . intval($templateId)); array_push($catArray, 'can_ban_emails');
} else { }
// Add 'can ban emails' if 'can unban emails' is set (but not added). Same with 'can ban ips' if (in_array('can_unban_ips', $featArray) && !in_array('can_ban_ips', $featArray)) {
$catArray = hesk_POST_array('categories'); array_push($featArray, 'can_ban_ips');
$featArray = hesk_POST_array('features'); }
validate($featArray, $catArray); $categories = implode(',', $catArray);
if (in_array('can_unban_emails', $featArray) && !in_array('can_ban_emails', $featArray)) { $features = implode(',', $featArray);
array_push($catArray, 'can_ban_emails'); $name = hesk_POST('name');
}
if (in_array('can_unban_ips', $featArray) && !in_array('can_ban_ips', $featArray)) { // Only allow users to add what they are allowed to add
array_push($featArray, 'can_ban_ips'); // Admins can handle anything
if (!$_SESSION['isadmin']) {
// Update categories based on user visibility
$originalCategories = explode(',', $row['categories']);
$newCategories = array();
foreach ($originalCategories as $innerCategory) {
if (in_array($innerCategory, $catArray) && in_array($innerCategory, $_SESSION['categories'])) {
$newCategories[] = $innerCategory;
} elseif (!in_array($innerCategory, $catArray) && !in_array($innerCategory, $_SESSION['categories'])) {
// The user can't modify this, so keep it in
$newCategories[] = $innerCategory;
}
// If neither, the user removed it.
} }
$categories = implode(',', $catArray);
$features = implode(',', $featArray); // Update features based on user visibility
$name = hesk_POST('name'); $originalFeatures = explode(',', $row['heskprivileges']);
$newFeatures = array();
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` foreach ($originalFeatures as $innerFeature) {
SET `categories` = '" . hesk_dbEscape($categories) . "', `heskprivileges` = '" . hesk_dbEscape($features) . "', if (in_array($innerFeature, $featArray) && strpos($_SESSION['heskprivileges'], $innerFeature) !== false) {
`name` = '" . hesk_dbEscape($name) . "' $newFeatures[] = $innerFeature;
WHERE `id` = " . intval($templateId)); } elseif (!in_array($innerFeature, $featArray) && strpos($_SESSION['heskprivileges'], $innerFeature) === false) {
// The user can't modify this, so keep it in
if ($row['categories'] != $categories || $row['heskprivileges'] != $features) { $newFeatures[] = $innerFeature;
// Any users with this template should be switched to "custom" }
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `permission_template` = NULL // If neither, the user removed it.
WHERE `permission_template` = " . intval($templateId));
} }
$categories = implode(',', $newCategories);
$features = implode(',', $newFeatures);
} }
hesk_process_messages($hesklang['permission_template_updated'], $_SERVER['PHP_SELF'], 'SUCCESS');
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
SET `categories` = '" . hesk_dbEscape($categories) . "', `heskprivileges` = '" . hesk_dbEscape($features) . "',
`name` = '" . hesk_dbEscape($name) . "'
WHERE `id` = " . intval($templateId));
if ($row['categories'] != $categories || $row['heskprivileges'] != $features) {
// Any users with this template should have their permissions updated
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `heskprivileges` = '" . hesk_dbEscape($features) . "',
`categories` = '" . hesk_dbEscape($categories) . "'
WHERE `permission_template` = " . intval($templateId));
}
hesk_process_messages($hesklang['permission_group_updated'], $_SERVER['PHP_SELF'], 'SUCCESS');
} }
function create() function create()
@ -439,7 +456,7 @@ function create()
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` (`name`, `heskprivileges`, `categories`) hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` (`name`, `heskprivileges`, `categories`)
VALUES ('" . hesk_dbEscape($name) . "', '" . hesk_dbEscape($features) . "', '" . hesk_dbEscape($categories) . "')"); VALUES ('" . hesk_dbEscape($name) . "', '" . hesk_dbEscape($features) . "', '" . hesk_dbEscape($categories) . "')");
hesk_process_messages($hesklang['template_created'], $_SERVER['PHP_SELF'], 'SUCCESS'); hesk_process_messages($hesklang['group_created'], $_SERVER['PHP_SELF'], 'SUCCESS');
} }
function validate($features, $categories, $create = false, $name = '') function validate($features, $categories, $create = false, $name = '')
@ -449,7 +466,7 @@ function validate($features, $categories, $create = false, $name = '')
$errorMarkup = '<ul>'; $errorMarkup = '<ul>';
$isValid = true; $isValid = true;
if ($create && $name == '') { if ($create && $name == '') {
$errorMarkup .= '<li>' . $hesklang['template_name_required'] . '</li>'; $errorMarkup .= '<li>' . $hesklang['group_name_required'] . '</li>';
$isValid = false; $isValid = false;
} }
if (count($features) == 0) { if (count($features) == 0) {
@ -463,7 +480,7 @@ function validate($features, $categories, $create = false, $name = '')
$errorMarkup .= '</ul>'; $errorMarkup .= '</ul>';
if (!$isValid) { if (!$isValid) {
$error = sprintf($hesklang['permission_template_error'], $errorMarkup); $error = sprintf($hesklang['permission_group_error'], $errorMarkup);
hesk_process_messages($error, $_SERVER['PHP_SELF']); hesk_process_messages($error, $_SERVER['PHP_SELF']);
} }
return true; return true;
@ -483,36 +500,14 @@ function deleteTemplate()
// Otherwise delete the template // Otherwise delete the template
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` WHERE `id` = " . intval($id)); hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` WHERE `id` = " . intval($id));
if (hesk_dbAffectedRows() != 1) { if (hesk_dbAffectedRows() != 1) {
hesk_process_messages($hesklang['no_templates_were_deleted'], $_SERVER['PHP_SELF']); hesk_process_messages($hesklang['no_group_were_deleted'], $_SERVER['PHP_SELF']);
} }
hesk_process_messages($hesklang['permission_template_deleted'], $_SERVER['PHP_SELF'], 'SUCCESS');
}
function toggleAdmin($admin) // Move all users who used to be in this group to "custom"
{ hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `permission_template` = NULL
global $hesk_settings, $hesklang; WHERE `permission_template` = " . intval($id));
$id = hesk_GET('id'); hesk_process_messages($hesklang['permission_group_deleted'], $_SERVER['PHP_SELF'], 'SUCCESS');
if ($id == 1 || $id == 2) {
hesk_process_messages($hesklang['cannot_change_admin_staff'], $_SERVER['PHP_SELF']);
}
if ($admin) {
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` SET `heskprivileges` = 'ALL',
`categories` = 'ALL' WHERE `id` = " . intval($id));
hesk_process_messages($hesklang['permission_template_now_admin'], $_SERVER['PHP_SELF'], 'SUCCESS');
} else {
// Get default privileges
$res = hesk_dbQuery("SELECT `heskprivileges`, `categories` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
WHERE `id` = 2");
$row = hesk_dbFetchAssoc($res);
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
SET `heskprivileges` = '" . hesk_dbEscape($row['heskprivileges']) . "',
`categories` = '" . hesk_dbEscape($row['categories']) . "' WHERE `id` = " . intval($id));
hesk_process_messages($hesklang['permission_template_no_longer_admin'], $_SERVER['PHP_SELF'], 'SUCCESS');
}
} }
?> ?>

@ -214,7 +214,7 @@ if ($action = hesk_REQUEST('a')) {
<th><b><i><?php echo $hesklang['name']; ?></i></b></th> <th><b><i><?php echo $hesklang['name']; ?></i></b></th>
<th><b><i><?php echo $hesklang['email']; ?></i></b></th> <th><b><i><?php echo $hesklang['email']; ?></i></b></th>
<th><b><i><?php echo $hesklang['username']; ?></i></b></th> <th><b><i><?php echo $hesklang['username']; ?></i></b></th>
<th><b><i><?php echo $hesklang['permission_template']; ?></i></b></th> <th><b><i><?php echo $hesklang['permission_group']; ?></i></b></th>
<?php <?php
/* Is user rating enabled? */ /* Is user rating enabled? */
if ($hesk_settings['rating']) { if ($hesk_settings['rating']) {
@ -591,6 +591,7 @@ function update_user()
$myuser['notify_overdue_unassigned'] = 0; $myuser['notify_overdue_unassigned'] = 0;
} }
/* Check for duplicate usernames */ /* Check for duplicate usernames */
$res = hesk_dbQuery("SELECT `id`,`isadmin`,`categories`,`heskprivileges` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `user` = '" . hesk_dbEscape($myuser['user']) . "' LIMIT 1"); $res = hesk_dbQuery("SELECT `id`,`isadmin`,`categories`,`heskprivileges` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `user` = '" . hesk_dbEscape($myuser['user']) . "' LIMIT 1");
if (hesk_dbNumRows($res) == 1) { if (hesk_dbNumRows($res) == 1) {
@ -735,7 +736,7 @@ function hesk_validateUserInfo($pass_required = 1, $redirect_to = './manage_user
} }
} }
if (strlen($myuser['signature']) > 1000) { if (hesk_mb_strlen($myuser['signature']) > 1000) {
$hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>'; $hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>';
} }
@ -847,6 +848,7 @@ function remove()
// Revoke manager rights // Revoke manager rights
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` SET `manager` = 0 WHERE `manager` = " . intval($myuser)); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` SET `manager` = 0 WHERE `manager` = " . intval($myuser));
/* Un-assign all tickets for this user */ /* Un-assign all tickets for this user */
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0 WHERE `owner`='" . intval($myuser) . "'"); $res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0 WHERE `owner`='" . intval($myuser) . "'");

@ -59,7 +59,7 @@ if (!$row['autoassign']) {
$category_ok = hesk_okCategory($category, 0); $category_ok = hesk_okCategory($category, 0);
// Is user allowed to move tickets to this category? // Is user allowed to move tickets to this category?
if (!$category_ok && !hesk_checkPermission('can_submit_any_cat', 0)) { if ( ! $category_ok && ! hesk_checkPermission('can_change_cat', 0) ) {
hesk_process_messages($hesklang['noauth_move'],'admin_main.php'); hesk_process_messages($hesklang['noauth_move'],'admin_main.php');
} }
@ -70,8 +70,6 @@ if (hesk_dbNumRows($res) != 1) {
} }
$ticket = hesk_dbFetchAssoc($res); $ticket = hesk_dbFetchAssoc($res);
/* Log that ticket is being moved */
$history = sprintf($hesklang['thist1'], hesk_date(), $row['name'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
/* Is the ticket assigned to someone? If yes, check that the user has access to category or change to unassigned */ /* Is the ticket assigned to someone? If yes, check that the user has access to category or change to unassigned */
$need_to_reassign = 0; $need_to_reassign = 0;
@ -92,18 +90,30 @@ if ($ticket['owner']) {
} }
/* Reassign automatically if possible */ /* Reassign automatically if possible */
$autoassign_owner = null;
if ($need_to_reassign || !$ticket['owner']) { if ($need_to_reassign || !$ticket['owner']) {
$need_to_reassign = 1; $need_to_reassign = 1;
$autoassign_owner = hesk_autoAssignTicket($category); $autoassign_owner = hesk_autoAssignTicket($category);
if ($autoassign_owner) { if ($autoassign_owner) {
$ticket['owner'] = $autoassign_owner['id']; $ticket['owner'] = $autoassign_owner['id'];
$history .= sprintf($hesklang['thist10'], hesk_date(), $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')');
} else { } else {
$ticket['owner'] = 0; $ticket['owner'] = 0;
} }
} }
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `category`='" . intval($category) . "', `owner`='" . intval($ticket['owner']) . "' , `history`=CONCAT(`history`,'" . hesk_dbEscape($history) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'"); hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `category`='" . intval($category) . "', `owner`='" . intval($ticket['owner']) . "' WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
/* Log that ticket is being moved */
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_moved_category', hesk_date(), array(
0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
1 => $row['name']
));
if ($autoassign_owner) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_autoassigned', hesk_date(), array(
0 => $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')'
));
}
$ticket['category'] = $category; $ticket['category'] = $category;
@ -118,13 +128,13 @@ $info = array(
'trackid' => $ticket['trackid'], 'trackid' => $ticket['trackid'],
'status' => $ticket['status'], 'status' => $ticket['status'],
'name' => $ticket['name'], 'name' => $ticket['name'],
'lastreplier' => $ticket['lastreplier'],
'subject' => $ticket['subject'], 'subject' => $ticket['subject'],
'message' => $ticket['message'], 'message' => $ticket['message'],
'attachments' => $ticket['attachments'], 'attachments' => $ticket['attachments'],
'dt' => hesk_date($ticket['dt'], true), 'dt' => hesk_date($ticket['dt'], true),
'lastchange' => hesk_date($ticket['lastchange'], true), 'lastchange' => hesk_date($ticket['lastchange'], true),
'id' => $ticket['id'], 'id' => $ticket['id'],'time_worked' => $ticket['time_worked'],
'last_reply_by' => hesk_getReplierName($ticket),
); );
// 2. Add custom fields to the array // 2. Add custom fields to the array

@ -113,13 +113,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
$hesk_settings['categories'] = array(); $hesk_settings['categories'] = array();
if (hesk_checkPermission('can_submit_any_cat', 0)) { if (hesk_checkPermission('can_submit_any_cat', 0)) {
$res = hesk_dbQuery("SELECT `id`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC"); $res = hesk_dbQuery("SELECT `id`, `name`, `mfh_description` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC");
} else { } else {
$res = hesk_dbQuery("SELECT `id`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE ".hesk_myCategories('id')." ORDER BY `cat_order` ASC"); $res = hesk_dbQuery("SELECT `id`, `name`, `mfh_description` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE ".hesk_myCategories('id')." ORDER BY `cat_order` ASC");
} }
while ($row = hesk_dbFetchAssoc($res)) { while ($row = hesk_dbFetchAssoc($res)) {
$hesk_settings['categories'][$row['id']] = $row['name']; $hesk_settings['categories'][$row['id']] = $row;
} }
$number_of_categories = count($hesk_settings['categories']); $number_of_categories = count($hesk_settings['categories']);
@ -147,7 +147,7 @@ $show_quick_help = $show['show'];
<li><a href="admin_main.php"><?php echo $hesk_settings['hesk_title']; ?></a></li> <li><a href="admin_main.php"><?php echo $hesk_settings['hesk_title']; ?></a></li>
<?php if ($number_of_categories > 1): ?> <?php if ($number_of_categories > 1): ?>
<li><a href="new_ticket.php"><?php echo $hesklang['nti2']; ?></a></li> <li><a href="new_ticket.php"><?php echo $hesklang['nti2']; ?></a></li>
<li class="active"><?php echo $hesk_settings['categories'][$category]; ?></li> <li class="active"><?php echo $hesk_settings['categories'][$category]['name']; ?></li>
<?php else: ?> <?php else: ?>
<li class="active"><?php echo $hesklang['nti2']; ?></li> <li class="active"><?php echo $hesklang['nti2']; ?></li>
<?php endif; ?> <?php endif; ?>
@ -157,6 +157,11 @@ $show_quick_help = $show['show'];
/* This will handle error, success and notice messages */ /* This will handle error, success and notice messages */
hesk_handle_messages(); hesk_handle_messages();
$service_messages = mfh_get_service_messages('STAFF_SUBMIT_TICKET');
foreach ($service_messages as $sm) {
hesk_service_message($sm);
}
if ($show_quick_help): ?> if ($show_quick_help): ?>
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
@ -237,7 +242,7 @@ $show_quick_help = $show['show'];
class="important">*</span></label> class="important">*</span></label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" name="name" size="40" maxlength="30" <input type="text" class="form-control" name="name" size="40" maxlength="50"
value="<?php if (isset($_SESSION['as_name'])) { value="<?php if (isset($_SESSION['as_name'])) {
echo stripslashes(hesk_input($_SESSION['as_name'])); echo stripslashes(hesk_input($_SESSION['as_name']));
} else if (isset($_GET['name'])) { } else if (isset($_GET['name'])) {
@ -374,6 +379,10 @@ $show_quick_help = $show['show'];
</div>'; </div>';
} }
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo ' echo '
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
@ -403,8 +412,14 @@ $show_quick_help = $show['show'];
echo '<option ' . $selected . '>' . $option . '</option>'; echo '<option ' . $selected . '>' . $option . '</option>';
} }
echo '</select> echo '</select>';
<div class="help-block with-errors"></div></div></div>';
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div></div>';
break; break;
/* Checkbox */ /* Checkbox */
@ -425,6 +440,11 @@ $show_quick_help = $show['show'];
echo '<div class="checkbox"><label><input ' . $validator . ' type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute . '> ' . $option . '</label></div>'; echo '<div class="checkbox"><label><input ' . $validator . ' type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute . '> ' . $option . '</label></div>';
} }
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo ' echo '
<div class="help-block with-errors"></div></div></div>'; <div class="help-block with-errors"></div></div></div>';
break; break;
@ -435,8 +455,13 @@ $show_quick_help = $show['show'];
echo '<div class="form-group' . $cls . '"> echo '<div class="form-group' . $cls . '">
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
<div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea> <div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>';
<div class="help-block with-errors"></div></div></div>';
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div></div>';
break; break;
case 'date': case 'date':
@ -451,8 +476,13 @@ $show_quick_help = $show['show'];
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="datepicker form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" <input type="text" class="datepicker form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40"
value="' . $k_value . '" ' . $required_attribute . '> value="' . $k_value . '" ' . $required_attribute . '>';
<div class="help-block with-errors"></div>
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
break; break;
@ -464,8 +494,13 @@ $show_quick_help = $show['show'];
echo '<div class="form-group' . $cls . '"> echo '<div class="form-group' . $cls . '">
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.$required_attribute.'> <input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.$required_attribute.'>';
<div class="help-block with-errors"></div>
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div><div id="'.$k.'_suggestions"></div>'; </div><div id="'.$k.'_suggestions"></div>';
@ -484,8 +519,13 @@ $show_quick_help = $show['show'];
echo '<div class="form-group' . $cls . '"> echo '<div class="form-group' . $cls . '">
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $cls . $required_attribute . '> <input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $cls . $required_attribute . '>';
<div class="help-block with-errors"></div>
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
} }
@ -657,7 +697,7 @@ $show_quick_help = $show['show'];
?> ?>
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<span id="HeskSub"><input class="form-control" type="text" name="subject" id="subject" size="40" maxlength="40" <span id="HeskSub"><input class="form-control" type="text" name="subject" id="subject" size="40" maxlength="70"
value="<?php if (isset($_SESSION['as_subject']) || isset($_GET['subject'])) { value="<?php if (isset($_SESSION['as_subject']) || isset($_GET['subject'])) {
echo stripslashes(hesk_input($_SESSION['as_subject'])); echo stripslashes(hesk_input($_SESSION['as_subject']));
} ?>" placeholder="<?php echo htmlspecialchars($hesklang['subject']); ?>" } ?>" placeholder="<?php echo htmlspecialchars($hesklang['subject']); ?>"
@ -745,7 +785,9 @@ $show_quick_help = $show['show'];
echo '<div class="radio"><label><input type="radio" name="' . $k . '" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>'; echo '<div class="radio"><label><input type="radio" name="' . $k . '" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
} }
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div></div>'; echo '<div class="help-block with-errors"></div></div></div>';
break; break;
@ -772,7 +814,11 @@ $show_quick_help = $show['show'];
echo '<option ' . $selected . '>' . $option . '</option>'; echo '<option ' . $selected . '>' . $option . '</option>';
} }
echo '</select><div class="help-block with-errors"></div></div></div>'; echo '</select>';
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div></div>';
break; break;
/* Checkbox */ /* Checkbox */
@ -793,6 +839,9 @@ $show_quick_help = $show['show'];
echo '<div class="checkbox"><label><input ' . $validator . ' type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute .'> ' . $option . '</label></div>'; echo '<div class="checkbox"><label><input ' . $validator . ' type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute .'> ' . $option . '</label></div>';
} }
if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div></div>'; echo '<div class="help-block with-errors"></div></div></div>';
break; break;
@ -802,8 +851,11 @@ $show_quick_help = $show['show'];
echo '<div class="form-group' . $cls . '"> echo '<div class="form-group' . $cls . '">
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea> <div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>';
<div class="help-block with-errors"></div></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div></div>
</div>'; </div>';
break; break;
@ -819,8 +871,11 @@ $show_quick_help = $show['show'];
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="datepicker form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" <input type="text" class="datepicker form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40"
value="' . $k_value . '" ' . $required_attribute . '> value="' . $k_value . '" ' . $required_attribute . '>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
break; break;
@ -832,8 +887,11 @@ $show_quick_help = $show['show'];
echo '<div class="form-group"> echo '<div class="form-group">
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.' ' . $required_attribute . '> <input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.' ' . $required_attribute . '>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div><div id="'.$k.'_suggestions"></div>'; </div><div id="'.$k.'_suggestions"></div>';
@ -851,8 +909,11 @@ $show_quick_help = $show['show'];
echo '<div class="form-group"> echo '<div class="form-group">
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label> <label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $required_attribute . '> <input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $required_attribute . '>';
<div class="help-block with-errors"></div> if (!empty($v['mfh_description'])) {
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
}
echo '<div class="help-block with-errors"></div>
</div> </div>
</div>'; </div>';
} }
@ -1030,9 +1091,10 @@ function print_select_category($number_of_categories) {
// Print a select box if number of categories is large // Print a select box if number of categories is large
if ($number_of_categories > $hesk_settings['cat_show_select']) if ($number_of_categories > $hesk_settings['cat_show_select'])
{ {
$firstDescription = null;
?> ?>
<form action="new_ticket.php" method="get"> <form action="new_ticket.php" method="get">
<select name="category" id="select_category" class="form-control"> <select name="category" id="select_category" class="form-control" onchange="showDescription()">
<?php <?php
if ($hesk_settings['select_cat']) if ($hesk_settings['select_cat'])
{ {
@ -1040,23 +1102,45 @@ function print_select_category($number_of_categories) {
} }
foreach ($hesk_settings['categories'] as $k=>$v) foreach ($hesk_settings['categories'] as $k=>$v)
{ {
echo '<option value="'.$k.'">'.$v.'</option>'; if ($firstDescription === null) {
$firstDescription = $v['mfh_description'];
}
echo '<option value="'.$k.'" data-description="'.$v['mfh_description'].'">'.$v['name'].'</option>';
} }
?> ?>
</select> </select>
<?php
$display = ' style="display: none"';
&nbsp;<br /> if (!$hesk_settings['select_cat'] && $firstDescription !== null && trim($firstDescription) !== '') {
$display = '';
}
?>
<span id="category-description"<?php echo $display; ?>>
<b><?php echo $hesklang['description_colon']; ?></b>
<span><?php echo $firstDescription; ?></span>
</span>
<br>
<div style="text-align:center"> <div style="text-align:center">
<input type="submit" value="<?php echo $hesklang['c2c']; ?>" class="btn btn-default"> <input type="submit" value="<?php echo $hesklang['c2c']; ?>" class="btn btn-default">
</div> </div>
</form> </form>
<script>
function showDescription() {
var $value = $('#select_category').find(':selected');
if ($value.data('description') !== '') {
$('#category-description').show().find('span').text($value.data('description'));
} else {
$('#category-description').hide();
}
}
</script>
<?php <?php
} }
// Otherwise print quick links // Otherwise print quick links
else else
{ {
// echo '<li><a href="new_ticket.php?a=add&amp;category='.$k.'">&raquo; '.$v.'</a></li>';
$new_row = 1; $new_row = 1;
foreach ($hesk_settings['categories'] as $k=>$v): foreach ($hesk_settings['categories'] as $k=>$v):
@ -1071,7 +1155,14 @@ function print_select_category($number_of_categories) {
<div class="panel-body"> <div class="panel-body">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<?php echo $v; ?> <?php
echo $v['name'];
if ($v['mfh_description'] !== null && trim($v['mfh_description']) !== '') {
echo '&nbsp;<i class="fa fa-info-circle" data-toggle="popover"
title="'. $hesklang['description'] .'" data-content="' . $v['mfh_description'] . '"></i>';
}
?>
</div> </div>
</div> </div>
</div> </div>

@ -0,0 +1,73 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
hesk_checkPermission('can_reply_tickets');
/* A security check */
hesk_token_check('POST');
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
$priority = intval( hesk_POST('priority') );
if ($priority < 0 || $priority > 3)
{
hesk_process_messages($hesklang['inpr'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'NOTICE');
}
$options = array(
0 => '<font class="critical">'.$hesklang['critical'].'</font>',
1 => '<font class="important">'.$hesklang['high'].'</font>',
2 => '<font class="medium">'.$hesklang['medium'].'</font>',
3 => $hesklang['low']
);
$plain_options = array(
0 => 'critical',
1 => 'high',
2 => 'medium',
3 => 'low'
);
$ticketRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($trackingID) . "'");
$ticket = hesk_dbFetchAssoc($ticketRs);
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `priority`='{$priority}' WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_priority', hesk_date(), array(
0 => $_SESSION['name'].' ('.$_SESSION['user'].')',
1 => $plain_options[$priority]
));
if (hesk_dbAffectedRows() != 1)
{
hesk_process_messages($hesklang['inpr'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'NOTICE');
}
hesk_process_messages(sprintf($hesklang['chpri2'],$options[$priority]),'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
?>

@ -166,11 +166,11 @@ function update_profile()
$hesk_error_buffer = ''; $hesk_error_buffer = '';
$_SESSION['new']['name'] = hesk_input(hesk_POST('name')) or $hesk_error_buffer .= '<li>' . $hesklang['enter_your_name'] . '</li>'; $_SESSION['new']['name'] = hesk_input(hesk_POST('name')) or $hesk_error_buffer .= '<li>' . $hesklang['enter_your_name'] . '</li>';
$_SESSION['new']['email'] = hesk_validateEmail(hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer = '<li>' . $hesklang['enter_valid_email'] . '</li>'; $_SESSION['new']['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer .= '<li>' . $hesklang['enter_valid_email'] . '</li>';
$_SESSION['new']['signature'] = hesk_input(hesk_POST('signature')); $_SESSION['new']['signature'] = hesk_input(hesk_POST('signature'));
/* Signature */ /* Signature */
if (strlen($_SESSION['new']['signature']) > 1000) { if (hesk_mb_strlen($_SESSION['new']['signature']) > 1000) {
$hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>'; $hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>';
} }

@ -249,7 +249,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
(<?php echo $hesklang['m' . date('n')]; ?>) (<?php echo $hesklang['m' . date('n')]; ?>)
</option> </option>
<option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?> <option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?>
(<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, date('d'), date('Y')))]; ?> (<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, 1, date('Y')))]; ?>
) )
</option> </option>
<option <option

@ -15,6 +15,7 @@ define('IN_SCRIPT', 1);
define('HESK_PATH', '../'); define('HESK_PATH', '../');
define('PAGE_TITLE', 'ADMIN_SERVICE_MESSAGES'); define('PAGE_TITLE', 'ADMIN_SERVICE_MESSAGES');
define('MFH_PAGE_LAYOUT', 'TOP_ONLY'); define('MFH_PAGE_LAYOUT', 'TOP_ONLY');
define('EXTRA_JS', '<script src="'.HESK_PATH.'internal-api/js/service-messages.js"></script>');
/* Get all the required files and functions */ /* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php'); require(HESK_PATH . 'hesk_settings.inc.php');
@ -31,26 +32,8 @@ hesk_isLoggedIn();
hesk_checkPermission('can_service_msg'); hesk_checkPermission('can_service_msg');
// Define required constants // Define required constants
define('LOAD_TABS', 1);
define('WYSIWYG', 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 */ /* Print header */
require_once(HESK_PATH . 'inc/headerAdmin.inc.php'); require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
@ -60,9 +43,23 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<div class="content-wrapper"> <div class="content-wrapper">
<section class="content"> <section class="content">
<div class="box"> <div class="box">
<div class="box-header with-border">
<h1 class="box-title">
<?php echo $hesklang['manage_service_messages']; ?>
<i class="fa fa-question-circle settingsquestionmark" data-toggle="tooltip"
title="<?php echo hesk_makeJsString($hesklang['sm_intro']); ?>"
data-placement="bottom"></i>
</h1>
</div>
<div class="box-body"> <div class="box-body">
<div class="nav-tabs-custom"> <div class="row">
<ul class="nav nav-tabs" role="tablist"> <div class="col-md-12 text-right">
<button id="create-button" class="btn btn-success">
<i class="fa fa-plus-circle"></i>&nbsp;
<?php echo $hesklang['create_new']; ?>
</button>
</div>
<div class="col-sm-12">
<?php <?php
// Show a link to banned_emails.php if user has permission to do so // Show a link to banned_emails.php if user has permission to do so
if (hesk_checkPermission('can_ban_emails', 0)) { if (hesk_checkPermission('can_ban_emails', 0)) {
@ -149,558 +146,297 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
<div class="panel-body"> <div class="panel-body">
<?php <?php
// Get service messages from database <div class="col-md-10">
$res = hesk_dbQuery('SELECT * FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'service_messages` ORDER BY `order` ASC'); <textarea placeholder="<?php echo htmlspecialchars($hesklang['sm_msg']); ?>"
$num = hesk_dbNumRows($res); class="form-control" name="message" id="content"></textarea>
if ($num < 1) {
echo '<p>' . $hesklang['no_sm'] . '</p>';
} else {
// List of staff
if (!isset($admins)) {
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users`");
while ($row = hesk_dbFetchAssoc($res2)) {
$admins[$row['id']] = $row['name'];
}
}
?>
<table class="table table-hover">
<thead>
<tr>
<th><?php echo $hesklang['sm_mtitle']; ?></th>
<th><?php echo $hesklang['sm_author']; ?></th>
<th><?php echo $hesklang['sm_type']; ?></th>
<th>&nbsp;<?php echo $hesklang['opt']; ?>&nbsp;</th>
</tr>
</thead>
<tbody>
<?php
$j = 1;
$k = 1;
while ($sm = hesk_dbFetchAssoc($res)) {
$faIcon = $sm['icon'];
switch ($sm['style']) {
case 1:
$sm_style = "alert alert-success";
break;
case 2:
$sm_style = "alert alert-info";
break;
case 3:
$sm_style = "alert alert-warning";
break;
case 4:
$sm_style = "alert alert-danger";
break;
default:
$sm_style = "none";
}
$type = $sm['type'] ? $hesklang['sm_draft'] : $hesklang['sm_published'];
?>
<tr>
<td>
<div class="<?php echo $sm_style; ?>">
<i class="<?php echo $faIcon; ?>"></i>
<b><?php echo $sm['title']; ?></b>
</div>
</td>
<td><?php echo(isset($admins[$sm['author']]) ? $admins[$sm['author']] : $hesklang['e_udel']); ?></td>
<td><?php echo $type; ?></td>
<td>
<?php
if ($num > 1) {
if ($k == 1) {
?>
<img src="../img/blank.gif" width="16" height="16" alt=""
style="padding:3px;border:none;"/>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=15&amp;token=<?php hesk_token_echo(); ?>">
<i class="fa fa-arrow-down font-size-16p green"
data-toggle="tooltip" data-placement="top"
data-original-title="<?php echo $hesklang['move_dn']; ?>"></i></a>
<?php
} elseif ($k == $num) {
?>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=-15&amp;token=<?php hesk_token_echo(); ?>">
<i class="fa fa-arrow-up font-size-16p green" data-toggle="tooltip"
data-placement="top"
data-original-title="<?php echo $hesklang['move_up']; ?>"></i></a>
<img src="../img/blank.gif" width="16" height="16" alt=""
style="padding:3px;border:none;"/>
<?php
} else {
?>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=-15&amp;token=<?php hesk_token_echo(); ?>">
<i class="fa fa-arrow-up font-size-16p green" data-toggle="tooltip"
data-placement="top"
data-original-title="<?php echo $hesklang['move_up']; ?>"></i></a>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=15&amp;token=<?php hesk_token_echo(); ?>">
<i class="fa fa-arrow-down font-size-16p green"
data-toggle="tooltip" data-placement="top"
data-original-title="<?php echo $hesklang['move_dn']; ?>"></i></a>
<?php
}
}
?>
<a href="service_messages.php?a=edit_sm&amp;id=<?php echo $sm['id']; ?>">
<i class="fa fa-pencil font-size-16p orange" data-toggle="tooltip"
data-placement="top"
data-original-title="<?php echo $hesklang['edit']; ?>"></i></a>
<a href="service_messages.php?a=remove_sm&amp;id=<?php echo $sm['id']; ?>&amp;token=<?php hesk_token_echo(); ?>"
onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_sm']); ?>');">
<i class="fa fa-times font-size-16p red" data-toggle="tooltip"
data-placement="top"
data-original-title="<?php echo $hesklang['delete']; ?>"></i></a>&nbsp;
</td>
</tr>
<?php
$j++;
$k++;
} // End while
?>
</tbody>
</table>
<?php
}
?>
</div> </div>
</div> </div>
</div>
<div class="panel panel-default"> <div role="tabpanel" class="tab-pane" id="properties">
<div class="panel-heading"> <div class="form-group">
<h4><a name="new_article"></a><?php echo hesk_SESSION('edit_sm') ? $hesklang['edit_sm'] : $hesklang['new_sm']; ?></h4> <label for="language" class="col-md-2 control-label">
<?php echo $hesklang['lgs']; ?>
</label>
<div class="col-md-10">
<select name="language" class="form-control">
<option value="ALL"><?php echo $hesklang['all']; ?></option>
<?php foreach($hesk_settings['languages'] as $name => $info): ?>
<option value="<?php echo $info['folder']; ?>">
<?php echo $name; ?>
</option>
<?php endforeach; ?>
</select>
</div> </div>
<div class="panel-body"> </div>
<form action="service_messages.php" method="post" name="form1" role="form" class="form-horizontal" data-toggle="validator"> <div class="form-group">
<div class="form-group"> <div class="row" style="padding-bottom: 10px;">
<label for="style" <label for="style"
class="col-md-2 control-label"><?php echo $hesklang['sm_style']; ?></label> class="col-md-2 control-label"><?php echo $hesklang['sm_style']; ?></label>
<div class="col-md-2"> <div class="col-md-3">
<div class="radio alert pad-5" style="box-shadow: none; border-radius: 4px;"> <div class="radio alert pad-5" style="box-shadow: none; border-radius: 4px;">
<label> <label>
<input type="radio" name="style" value="0" onclick="setIcon('')" <input type="radio" name="style" value="0" onclick="setIcon('')">
<?php if (!isset($_SESSION['new_sm']['style']) || (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 0)) { <?php echo $hesklang['sm_none']; ?>
echo 'checked'; </label>
} ?>>
<?php echo $hesklang['sm_none']; ?>
</label>
</div>
</div>
<div class="col-md-2">
<div class="radio alert alert-success pad-5">
<label style="margin-top: -5px">
<input type="radio" name="style" value="1"
onclick="setIcon('fa fa-check-circle')"
<?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 1) {
echo 'checked';
} ?>>
<?php echo $hesklang['sm_success']; ?>
</label>
</div>
</div>
<div class="col-md-2">
<div class="radio alert alert-info pad-5" onclick="setIcon('fa fa-comment')">
<label style="margin-top: -5px">
<input type="radio" name="style" value="2"
<?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 2) {
echo 'checked';
} ?>>
<?php echo $hesklang['sm_info']; ?>
</label>
</div>
</div>
<div class="col-md-2">
<div class="radio alert alert-warning pad-5"
onclick="setIcon('fa fa-exclamation-triangle')">
<label style="margin-top: -5px">
<input type="radio" name="style" value="3"
<?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 3) {
echo 'checked';
} ?>>
<?php echo $hesklang['sm_notice']; ?>
</label>
</div>
</div>
<div class="col-md-2">
<div class="radio alert alert-danger pad-5" onclick="setIcon('fa fa-times-circle')">
<label style="margin-top: -5px">
<input type="radio" name="style" value="4"
<?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 4) {
echo 'checked';
} ?> >
<?php echo $hesklang['sm_error']; ?>
</label>
</div>
</div>
</div> </div>
<div class="form-group"> </div>
<label for="icon" class="col-md-2 control-label"><?php echo $hesklang['sm_icon']; ?></label> <div class="col-md-3">
<?php <div class="radio alert alert-success pad-5">
$icon = ''; <label style="margin-top: -5px">
if (isset($_SESSION['new_sm']['icon'])) { <input type="radio" name="style" value="1" onclick="setIcon('fa fa-check-circle')">
$icon = $_SESSION['new_sm']['icon']; <?php echo $hesklang['sm_success']; ?>
} </label>
?> </div>
<div class="col-md-10"> </div>
<p style="display:none" id="no-icon"><?php echo $hesklang['sm_no_icon']; ?></p> <div class="col-md-3">
<div class="radio alert alert-info pad-5" onclick="setIcon('fa fa-comment')">
<p style="display:none" id="search-icon"><?php echo $hesklang['sm_search_icon']; ?></p> <label style="margin-top: -5px">
<input type="radio" name="style" value="2">
<?php echo $hesklang['sm_info']; ?>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-2">
<div class="radio alert alert-warning pad-5">
<label style="margin-top: -5px">
<input type="radio" name="style" value="3"
onclick="setIcon('fa fa-exclamation-triangle')">
<?php echo $hesklang['sm_notice']; ?>
</label>
</div>
</div>
<div class="col-md-3">
<div class="radio alert alert-danger pad-5">
<label style="margin-top: -5px">
<input type="radio" name="style" value="4" onclick="setIcon('fa fa-times-circle')">
<?php echo $hesklang['sm_error']; ?>
</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="icon" class="col-md-2 control-label"><?php echo $hesklang['sm_icon']; ?></label>
<div class="col-md-10">
<p style="display:none" id="no-icon"><?php echo $hesklang['sm_no_icon']; ?></p>
<p style="display:none" <p style="display:none" id="search-icon"><?php echo $hesklang['sm_search_icon']; ?></p>
id="footer-icon"><?php echo $hesklang['sm_iconpicker_footer_label']; ?></p>
<div name="icon" class="btn btn-default iconpicker-container" data-toggle="iconpicker" <p style="display:none"
data-icon="<?php echo $icon; ?>"></div> id="footer-icon"><?php echo $hesklang['sm_iconpicker_footer_label']; ?></p>
</div>
</div>
<div class="form-group">
<label for="type" class="col-md-2 control-label"><?php echo $hesklang['sm_type']; ?></label>
<div class="col-md-2"> <div name="icon" class="btn btn-default iconpicker-container" data-toggle="iconpicker"
<div class="radio pad-5"> data-search="false" data-icon=""></div>
<label> </div>
<input type="radio" name="type" value="0" </div>
<?php if (!isset($_SESSION['new_sm']['type']) || (isset($_SESSION['new_sm']['type']) && $_SESSION['new_sm']['type'] == 0)) { <div class="form-group">
echo 'checked'; <label for="type" class="col-md-2 control-label"><?php echo $hesklang['sm_type']; ?></label>
} ?> >
<?php echo $hesklang['sm_published']; ?> <div class="col-md-2">
</label> <div class="radio pad-5">
</div> <label>
</div> <input type="radio" name="type" value="0">
<div class="col-md-2"> <?php echo $hesklang['sm_published']; ?>
<div class="radio pad-5"> </label>
<label> </div>
<input type="radio" name="type" value="1" </div>
<?php if (isset($_SESSION['new_sm']['type']) && $_SESSION['new_sm']['type'] == 1) { <div class="col-md-2">
echo 'checked'; <div class="radio pad-5">
} ?> > <label>
<?php echo $hesklang['sm_draft']; ?> <input type="radio" name="type" value="1">
</label> <?php echo $hesklang['sm_draft']; ?>
</div> </label>
</div> </div>
</div>
</div>
<div class="form-group">
<label for="location" class="col-md-2 control-label"><?php echo $hesklang['sm_location']; ?></label>
<div class="col-sm-4" style="margin-left:20px">
<h5 style="text-decoration: underline;"><?php echo $hesklang['sm_customer_pages']; ?></h5>
<div class="btn-group btn-group-sm">
<div data-select-all="customer-location" class="btn btn-default">
<?php echo $hesklang['select_all_title_case']; ?>
</div> </div>
<div class="form-group"> <div data-deselect-all="customer-location" class="btn btn-default">
<label for="title" <?php echo $hesklang['deselect_all_title_case']; ?>
class="col-md-2 control-label"><?php echo $hesklang['sm_mtitle']; ?></label>
<div class="col-md-10">
<input class="form-control"
placeholder="<?php echo htmlspecialchars($hesklang['sm_mtitle']); ?>"
type="text" name="title" size="70" maxlength="255"
<?php if (isset($_SESSION['new_sm']['title'])) {
echo 'value="' . $_SESSION['new_sm']['title'] . '"';
} ?> data-error="<?php echo htmlspecialchars($hesklang['sm_e_title']); ?>" required>
<div class="help-block with-errors"></div>
</div>
</div> </div>
<div class="form-group"> </div>
<label for="message" <div class="checkbox">
class="col-md-2 control-label"><?php echo $hesklang['sm_msg']; ?></label> <input data-select-target="customer-location" type="checkbox"
name="location[]" value="CUSTOMER_HOME"> <?php echo $hesklang['sm_homepage']; ?>
<div class="col-md-10"> </div>
<textarea placeholder="<?php echo htmlspecialchars($hesklang['sm_msg']); ?>" <?php if ($hesk_settings['kb_enable'] > 0): ?>
class="form-control" name="message" rows="25" cols="70" id="content"> <div class="checkbox">
<?php if (isset($_SESSION['new_sm']['message'])) { <input data-select-target="customer-location" type="checkbox"
echo $_SESSION['new_sm']['message']; name="location[]" value="CUSTOMER_KB_HOME"> <?php echo $hesklang['sm_kb_home']; ?>
} ?> </div>
</textarea> <div class="checkbox">
</div> <input data-select-target="customer-location" type="checkbox"
name="location[]" value="CUSTOMER_VIEW_KB_ARTICLE"> <?php echo $hesklang['sm_view_kb_article']; ?>
</div>
<?php endif; if ($hesk_settings['kb_enable'] != 2): ?>
<div class="checkbox">
<input data-select-target="customer-location" type="checkbox"
name="location[]" value="CUSTOMER_SUBMIT_TICKET"> <?php echo $hesklang['sm_submit_ticket']; ?>
</div>
<div class="checkbox">
<input data-select-target="customer-location" type="checkbox"
name="location[]" value="CUSTOMER_VIEW_TICKET"> <?php echo $hesklang['sm_view_ticket']; ?>
</div>
<?php endif; ?>
</div>
<div class="col-sm-4" style="margin-left:20px">
<h5 style="text-decoration: underline;"><?php echo $hesklang['sm_staff_pages']; ?></h5>
<div class="btn-group btn-group-sm">
<div data-select-all="staff-location" class="btn btn-default">
<?php echo $hesklang['select_all_title_case']; ?>
</div> </div>
<div class="form-group"> <div data-deselect-all="staff-location" class="btn btn-default">
<?php echo isset($_SESSION['edit_sm']) ? '<input type="hidden" name="a" value="save_sm" /><input type="hidden" name="id" value="' . intval($_SESSION['new_sm']['id']) . '" />' : '<input type="hidden" name="a" value="new_sm" />'; ?> <?php echo $hesklang['deselect_all_title_case']; ?>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>"/>
<div class="col-md-10 col-md-offset-2">
<div class="btn-group" role="group">
<input type="submit" name="sm_save" value="<?php echo $hesklang['sm_save']; ?>"
class="btn btn-primary">
<input type="submit" name="sm_preview"
value="<?php echo $hesklang['sm_preview']; ?>" class="btn btn-default">
</div>
</div>
</div> </div>
</form> </div>
<div class="checkbox">
<input data-select-target="staff-location" type="checkbox"
name="location[]" value="STAFF_LOGIN"> <?php echo $hesklang['sm_login_page']; ?>
</div>
<div class="checkbox">
<input data-select-target="staff-location" type="checkbox"
name="location[]" value="STAFF_HOME"> <?php echo $hesklang['sm_homepage']; ?>
</div>
<?php if ($hesk_settings['kb_enable'] > 0): ?>
<div class="checkbox">
<input data-select-target="staff-location" type="checkbox"
name="location[]" value="STAFF_KB_HOME"> <?php echo $hesklang['sm_kb_home']; ?>
</div>
<div class="checkbox">
<input data-select-target="staff-location" type="checkbox"
name="location[]" value="STAFF_VIEW_KB_ARTICLE"> <?php echo $hesklang['sm_view_kb_article']; ?>
</div>
<?php endif; if ($hesk_settings['kb_enable'] != 2): ?>
<div class="checkbox">
<input data-select-target="staff-location" type="checkbox"
name="location[]" value="STAFF_SUBMIT_TICKET"> <?php echo $hesklang['sm_submit_ticket']; ?>
</div>
<div class="checkbox">
<input data-select-target="staff-location" type="checkbox"
name="location[]" value="STAFF_VIEW_TICKET"> <?php echo $hesklang['sm_view_ticket']; ?>
</div>
<?php endif; ?>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div id="preview-pane"></div>
</div>
<div class="modal-footer">
<input type="hidden" name="id">
<input type="hidden" name="order">
<div id="action-buttons" class="btn-group">
<button type="button" class="btn btn-default cancel-button cancel-callback" data-dismiss="modal">
<i class="fa fa-times-circle"></i>
<span><?php echo $hesklang['cancel']; ?></span>
</button>
<button type="button" class="btn btn-primary preview-button">
<i class="fa fa-search"></i>
<span><?php echo $hesklang['sm_preview']; ?></span>
</button>
<button type="submit" class="btn btn-success save-button">
<i class="fa fa-check-circle"></i>
<span><?php echo $hesklang['save']; ?></span>
</button>
</div>
</div> </div>
</div> </form>
</div> </div>
</div> </div>
</section>
</div> </div>
<?php <?php
echo mfh_get_hidden_fields_for_language(array(
'sm_published',
'sm_draft',
'no_sm',
'sm_added',
'sm_mdf',
'error_saving_updating_sm',
'sm_deleted',
'error_deleting_sm',
'error_sorting_categories',
'error_retrieving_sm',
'all',
));
echo '<script>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 '</script>';
?>
<script type="text/html" id="service-message-title-template">
<div class="{{CLASS}}">
<i data-property="icon"></i>
<b data-property="title"></b>
</div>
</script>
<script type="text/html" id="service-message-preview-template">
<?php
$sm = array(
'icon' => 'fa',
'style' => 0,
'title' => '{{TITLE}}',
'message' => '{{MESSAGE}}'
);
hesk_service_message($sm);
?>
</script>
<script type="text/html" id="service-message-template">
<tr>
<td style="display: none"><span data-property="id" data-value="x"></span></td>
<td><span data-property="title"></span></td>
<td><span data-property="author"></span></td>
<td><span data-property="language"></span></td>
<td><span data-property="type"></span></td>
<td>
<span class="sort-arrows">
<a href="#" data-action="sort"
data-direction="up">
<i class="fa fa-fw fa-arrow-up icon-link green"
data-toggle="tooltip" title="<?php echo $hesklang['move_up']; ?>"></i>
</a>
<a href="#" data-action="sort"
data-direction="down">
<i class="fa fa-fw fa-arrow-down icon-link green"
data-toggle="tooltip" title="<?php echo $hesklang['move_dn'] ?>"></i>
</a>
</span>
<a href="#" data-action="edit">
<i class="fa fa-fw fa-pencil icon-link orange"
data-toggle="tooltip" title="<?php echo $hesklang['edit']; ?>"></i>
</a>
<a href="#" data-action="delete">
<i class="fa fa-fw fa-times icon-link red"
data-toggle="tooltip" title="<?php echo $hesklang['delete']; ?>"></i>
</a>
</td>
</tr>
</script>
hesk_cleanSessionVars(array('new_sm', 'preview_sm', 'edit_sm')); <?php
require_once(HESK_PATH . 'inc/footer.inc.php'); require_once(HESK_PATH . 'inc/footer.inc.php');
exit(); exit();
/*** START FUNCTIONS ***/
function save_sm()
{
global $hesk_settings, $hesklang, $listBox;
global $hesk_error_buffer;
// A security check
# hesk_token_check('POST');
$hesk_error_buffer = array();
// Get service messageID
$id = intval(hesk_POST('id')) or hesk_error($hesklang['sm_e_id']);
$style = intval(hesk_POST('style', 0));
if ($style > 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 .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['rfm'] . '<br /><br /><ul>' . $hesk_error_buffer . '</ul>';
hesk_process_messages($hesk_error_buffer, 'service_messages.php');
}
// Just preview the message?
if (isset($_POST['sm_preview'])) {
$_SESSION['preview_sm'] = true;
$_SESSION['edit_sm'] = true;
$_SESSION['new_sm'] = array(
'id' => $id,
'style' => $style,
'type' => $type,
'title' => $title,
'message' => $message,
'icon' => $icon,
);
header('Location: service_messages.php');
exit;
}
// Update the service message in the database
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` SET
`author` = '" . intval($_SESSION['id']) . "',
`title` = '" . hesk_dbEscape($title) . "',
`message` = '" . hesk_dbEscape($message) . "',
`style` = '{$style}',
`type` = '{$type}',
`icon` = '{$icon}'
WHERE `id`={$id}");
$_SESSION['smord'] = $id;
hesk_process_messages($hesklang['sm_mdf'], 'service_messages.php', 'SUCCESS');
} // End save_sm()
function edit_sm()
{
global $hesk_settings, $hesklang;
// Get service messageID
$id = intval(hesk_GET('id')) or hesk_error($hesklang['sm_e_id']);
// Get details from the database
$res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` WHERE `id`={$id} LIMIT 1");
if (hesk_dbNumRows($res) != 1) {
hesk_error($hesklang['sm_not_found']);
}
$sm = hesk_dbFetchAssoc($res);
$_SESSION['new_sm'] = $sm;
$_SESSION['edit_sm'] = true;
} // End edit_sm()
function order_sm()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get ID and move parameters
$id = intval(hesk_GET('id')) or hesk_error($hesklang['sm_e_id']);
$move = intval(hesk_GET('move'));
$_SESSION['smord'] = $id;
// Update article details
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` SET `order`=`order`+" . intval($move) . " WHERE `id`={$id}");
// Update order of all service messages
update_sm_order();
// Finish
header('Location: service_messages.php');
exit();
} // End order_sm()
function update_sm_order()
{
global $hesk_settings, $hesklang;
// Get list of current service messages
$res = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` ORDER BY `order` ASC");
// Update database
$i = 10;
while ($sm = hesk_dbFetchAssoc($res)) {
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` SET `order`=" . intval($i) . " WHERE `id`='" . intval($sm['id']) . "'");
$i += 10;
}
return true;
} // END update_sm_order()
function remove_sm()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get ID
$id = intval(hesk_GET('id')) or hesk_error($hesklang['sm_e_id']);
// Delete the service message
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` WHERE `id`={$id}");
// Were we successful?
if (hesk_dbAffectedRows() == 1) {
hesk_process_messages($hesklang['sm_deleted'], './service_messages.php', 'SUCCESS');
} else {
hesk_process_messages($hesklang['sm_not_found'], './service_messages.php');
}
} // End remove_sm()
function new_sm()
{
global $hesk_settings, $hesklang, $listBox;
global $hesk_error_buffer;
// A security check
# hesk_token_check('POST');
$hesk_error_buffer = array();
$style = intval(hesk_POST('style', 0));
if ($style > 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['new_sm'] = array(
'style' => $style,
'type' => $type,
'title' => $title,
'icon' => $icon,
'message' => hesk_input(hesk_POST('message')),
);
$tmp = '';
foreach ($hesk_error_buffer as $error) {
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['rfm'] . '<br /><br /><ul>' . $hesk_error_buffer . '</ul>';
hesk_process_messages($hesk_error_buffer, 'service_messages.php');
}
// Just preview the message?
if (isset($_POST['sm_preview'])) {
$_SESSION['preview_sm'] = true;
$_SESSION['new_sm'] = array(
'style' => $style,
'type' => $type,
'title' => $title,
'icon' => $icon,
'message' => $message,
);
header('Location: service_messages.php');
exit;
}
// Get the latest service message order
$res = hesk_dbQuery("SELECT `order` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` ORDER BY `order` DESC LIMIT 1");
$row = hesk_dbFetchRow($res);
$my_order = intval($row[0]) + 10;
// Insert service message into database
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` (`author`,`title`,`message`,`style`,`type`,`order`, `icon`) VALUES (
'" . intval($_SESSION['id']) . "',
'" . hesk_dbEscape($title) . "',
'" . hesk_dbEscape($message) . "',
'{$style}',
'{$type}',
'{$my_order}',
'{$icon}'
)");
$_SESSION['smord'] = hesk_dbInsertID();
hesk_process_messages($hesklang['sm_added'], 'service_messages.php', 'SUCCESS');
} // End new_sm()
?> ?>

@ -1,142 +0,0 @@
<?php
// Responsible for loading in all necessary classes. AKA a poor man's DI solution.
use BusinessLogic\Attachments\AttachmentHandler;
use BusinessLogic\Attachments\AttachmentRetriever;
use BusinessLogic\Categories\CategoryRetriever;
use BusinessLogic\Emails\BasicEmailSender;
use BusinessLogic\Emails\EmailSenderHelper;
use BusinessLogic\Emails\EmailTemplateParser;
use BusinessLogic\Emails\EmailTemplateRetriever;
use BusinessLogic\Emails\MailgunEmailSender;
use BusinessLogic\Navigation\CustomNavElementHandler;
use BusinessLogic\Security\BanRetriever;
use BusinessLogic\Security\UserContextBuilder;
use BusinessLogic\Security\UserToTicketChecker;
use BusinessLogic\Settings\ApiChecker;
use BusinessLogic\Settings\SettingsRetriever;
use BusinessLogic\Statuses\StatusRetriever;
use BusinessLogic\Tickets\Autoassigner;
use BusinessLogic\Tickets\TicketDeleter;
use BusinessLogic\Tickets\TicketEditor;
use BusinessLogic\Tickets\TicketRetriever;
use BusinessLogic\Tickets\TicketCreator;
use BusinessLogic\Tickets\NewTicketValidator;
use BusinessLogic\Tickets\TicketValidators;
use BusinessLogic\Tickets\TrackingIdGenerator;
use BusinessLogic\Tickets\VerifiedEmailChecker;
use DataAccess\Attachments\AttachmentGateway;
use DataAccess\Categories\CategoryGateway;
use DataAccess\Files\FileDeleter;
use DataAccess\Files\FileReader;
use DataAccess\Files\FileWriter;
use DataAccess\Logging\LoggingGateway;
use DataAccess\Navigation\CustomNavElementGateway;
use DataAccess\Security\BanGateway;
use DataAccess\Security\UserGateway;
use DataAccess\Settings\ModsForHeskSettingsGateway;
use DataAccess\Statuses\StatusGateway;
use DataAccess\Tickets\TicketGateway;
use DataAccess\Tickets\VerifiedEmailGateway;
class ApplicationContext {
public $get;
/**
* ApplicationContext constructor.
*/
function __construct() {
$this->get = array();
// Settings
$this->get[ModsForHeskSettingsGateway::class] = new ModsForHeskSettingsGateway();
// API Checker
$this->get[ApiChecker::class] = new ApiChecker($this->get[ModsForHeskSettingsGateway::class]);
// Custom Navigation
$this->get[CustomNavElementGateway::class] = new CustomNavElementGateway();
$this->get[CustomNavElementHandler::class] = new CustomNavElementHandler($this->get[CustomNavElementGateway::class]);
// Logging
$this->get[LoggingGateway::class] = new LoggingGateway();
// Verified Email Checker
$this->get[VerifiedEmailGateway::class] = new VerifiedEmailGateway();
$this->get[VerifiedEmailChecker::class] = new VerifiedEmailChecker($this->get[VerifiedEmailGateway::class]);
// Users
$this->get[UserGateway::class] = new UserGateway();
$this->get[UserContextBuilder::class] = new UserContextBuilder($this->get[UserGateway::class]);
// Categories
$this->get[CategoryGateway::class] = new CategoryGateway();
$this->get[CategoryRetriever::class] = new CategoryRetriever($this->get[CategoryGateway::class]);
// Bans
$this->get[BanGateway::class] = new BanGateway();
$this->get[BanRetriever::class] = new BanRetriever($this->get[BanGateway::class]);
// Statuses
$this->get[StatusGateway::class] = new StatusGateway();
// Email Sender
$this->get[EmailTemplateRetriever::class] = new EmailTemplateRetriever();
$this->get[EmailTemplateParser::class] = new EmailTemplateParser($this->get[StatusGateway::class],
$this->get[CategoryGateway::class],
$this->get[UserGateway::class],
$this->get[EmailTemplateRetriever::class]);
$this->get[BasicEmailSender::class] = new BasicEmailSender();
$this->get[MailgunEmailSender::class] = new MailgunEmailSender();
$this->get[EmailSenderHelper::class] = new EmailSenderHelper($this->get[EmailTemplateParser::class],
$this->get[BasicEmailSender::class],
$this->get[MailgunEmailSender::class]);
// Tickets
$this->get[UserToTicketChecker::class] = new UserToTicketChecker($this->get[UserGateway::class]);
$this->get[TicketGateway::class] = new TicketGateway();
$this->get[TicketRetriever::class] = new TicketRetriever($this->get[TicketGateway::class],
$this->get[UserToTicketChecker::class]);
$this->get[TicketValidators::class] = new TicketValidators($this->get[TicketGateway::class]);
$this->get[TrackingIdGenerator::class] = new TrackingIdGenerator($this->get[TicketGateway::class]);
$this->get[Autoassigner::class] = new Autoassigner($this->get[CategoryGateway::class], $this->get[UserGateway::class]);
$this->get[NewTicketValidator::class] = new NewTicketValidator($this->get[CategoryRetriever::class],
$this->get[BanRetriever::class],
$this->get[TicketValidators::class]);
$this->get[TicketCreator::class] = new TicketCreator($this->get[NewTicketValidator::class],
$this->get[TrackingIdGenerator::class],
$this->get[Autoassigner::class],
$this->get[StatusGateway::class],
$this->get[TicketGateway::class],
$this->get[VerifiedEmailChecker::class],
$this->get[EmailSenderHelper::class],
$this->get[UserGateway::class],
$this->get[ModsForHeskSettingsGateway::class]);
$this->get[FileWriter::class] = new FileWriter();
$this->get[FileReader::class] = new FileReader();
$this->get[FileDeleter::class] = new FileDeleter();
$this->get[AttachmentGateway::class] = new AttachmentGateway();
$this->get[AttachmentHandler::class] = new AttachmentHandler($this->get[TicketGateway::class],
$this->get[AttachmentGateway::class],
$this->get[FileWriter::class],
$this->get[UserToTicketChecker::class],
$this->get[FileDeleter::class]);
$this->get[AttachmentRetriever::class] = new AttachmentRetriever($this->get[AttachmentGateway::class],
$this->get[FileReader::class],
$this->get[TicketGateway::class],
$this->get[UserToTicketChecker::class]);
$this->get[TicketDeleter::class] =
new TicketDeleter($this->get[TicketGateway::class],
$this->get[UserToTicketChecker::class],
$this->get[AttachmentHandler::class]);
$this->get[TicketEditor::class] =
new TicketEditor($this->get[TicketGateway::class], $this->get[UserToTicketChecker::class]);
// Statuses
$this->get[StatusRetriever::class] = new StatusRetriever($this->get[StatusGateway::class]);
// Settings
$this->get[SettingsRetriever::class] = new SettingsRetriever($this->get[ModsForHeskSettingsGateway::class]);
}
}

@ -0,0 +1,7 @@
<?php
class BaseClass {
static function clazz() {
return get_called_class();
}
}

@ -0,0 +1,7 @@
<?php
class BaseException extends Exception {
static function clazz() {
return get_called_class();
}
}

@ -3,7 +3,7 @@
namespace BusinessLogic\Attachments; namespace BusinessLogic\Attachments;
class Attachment { class Attachment extends \BaseClass {
/* @var $id int */ /* @var $id int */
public $id; public $id;

@ -17,7 +17,7 @@ use DataAccess\Files\FileDeleter;
use DataAccess\Files\FileWriter; use DataAccess\Files\FileWriter;
use DataAccess\Tickets\TicketGateway; use DataAccess\Tickets\TicketGateway;
class AttachmentHandler { class AttachmentHandler extends \BaseClass {
/* @var $ticketGateway TicketGateway */ /* @var $ticketGateway TicketGateway */
private $ticketGateway; private $ticketGateway;
@ -33,7 +33,11 @@ class AttachmentHandler {
/* @var $userToTicketChecker UserToTicketChecker */ /* @var $userToTicketChecker UserToTicketChecker */
private $userToTicketChecker; private $userToTicketChecker;
function __construct($ticketGateway, $attachmentGateway, $fileWriter, $userToTicketChecker, $fileDeleter) { function __construct(TicketGateway $ticketGateway,
AttachmentGateway $attachmentGateway,
FileWriter $fileWriter,
UserToTicketChecker $userToTicketChecker,
FileDeleter $fileDeleter) {
$this->ticketGateway = $ticketGateway; $this->ticketGateway = $ticketGateway;
$this->attachmentGateway = $attachmentGateway; $this->attachmentGateway = $attachmentGateway;
$this->fileWriter = $fileWriter; $this->fileWriter = $fileWriter;

@ -10,7 +10,7 @@ use DataAccess\Attachments\AttachmentGateway;
use DataAccess\Files\FileReader; use DataAccess\Files\FileReader;
use DataAccess\Tickets\TicketGateway; use DataAccess\Tickets\TicketGateway;
class AttachmentRetriever { class AttachmentRetriever extends \BaseClass {
/* @var $attachmentGateway AttachmentGateway */ /* @var $attachmentGateway AttachmentGateway */
private $attachmentGateway; private $attachmentGateway;

@ -3,7 +3,7 @@
namespace BusinessLogic\Attachments; namespace BusinessLogic\Attachments;
class AttachmentType { class AttachmentType extends \BaseClass {
const MESSAGE = 0; const MESSAGE = 0;
const REPLY = 1; const REPLY = 1;
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Attachments; namespace BusinessLogic\Attachments;
class CreateAttachmentModel { class CreateAttachmentModel extends \BaseClass {
/* @var $savedName string */ /* @var $savedName string */
public $savedName; public $savedName;

@ -0,0 +1,22 @@
<?php
namespace BusinessLogic\Calendar;
class AbstractEvent {
public $id;
public $startTime;
public $title;
public $categoryId;
public $categoryName;
public $backgroundColor;
public $foregroundColor;
public $displayBorder;
}

@ -0,0 +1,15 @@
<?php
namespace BusinessLogic\Calendar;
class BusinessHours {
/* @var $dayOfWeek int */
public $dayOfWeek;
/* @var $startTime string */
public $startTime;
/* @var $endTime string */
public $endTime;
}

@ -0,0 +1,26 @@
<?php
namespace BusinessLogic\Calendar;
use BusinessLogic\Tickets\AuditTrail;
class CalendarEvent extends AbstractEvent {
public $type = 'CALENDAR';
public $endTime;
/* @var $allDay bool */
public $allDay;
public $location;
public $comments;
public $reminderValue;
public $reminderUnits;
/* @var $auditTrail AuditTrail[] */
public $auditTrail = array();
}

@ -0,0 +1,96 @@
<?php
namespace BusinessLogic\Calendar;
use BusinessLogic\DateTimeHelpers;
use BusinessLogic\Security\UserContext;
use BusinessLogic\Tickets\AuditTrailEntityType;
use DataAccess\AuditTrail\AuditTrailGateway;
use DataAccess\Calendar\CalendarGateway;
class CalendarHandler extends \BaseClass {
private $calendarGateway;
private $auditTrailGateway;
public function __construct(CalendarGateway $calendarGateway,
AuditTrailGateway $auditTrailGateway) {
$this->calendarGateway = $calendarGateway;
$this->auditTrailGateway = $auditTrailGateway;
}
public function getEventsForStaff($searchEventsFilter, $heskSettings) {
return $this->calendarGateway->getEventsForStaff($searchEventsFilter, $heskSettings);
}
/**
* @param $calendarEvent CalendarEvent
* @param $userContext UserContext
* @param $heskSettings array
* @return CalendarEvent
* @throws \Exception If more than one event is returned for the given ID
*/
public function updateEvent($calendarEvent, $userContext, $heskSettings) {
$this->calendarGateway->updateEvent($calendarEvent, $userContext, $heskSettings);
$this->auditTrailGateway->insertAuditTrailRecord($calendarEvent->id,
AuditTrailEntityType::CALENDAR_EVENT,
'audit_event_updated',
DateTimeHelpers::heskDate($heskSettings),
array(0 => $userContext->name . ' (' . $userContext->username . ')'), $heskSettings);
$eventFilter = new SearchEventsFilter();
$eventFilter->eventId = $calendarEvent->id;
$eventFilter->reminderUserId = $userContext->id;
$events = $this->calendarGateway->getEventsForStaff($eventFilter, $heskSettings);
if (count($events) !== 1) {
throw new \Exception("Expected exactly 1 event, found: " . count($events));
}
$event = $events[0];
return $event;
}
/**
* @param $calendarEvent CalendarEvent
* @param $userContext UserContext
* @param $heskSettings array
* @return AbstractEvent
* @throws \Exception
*/
public function createEvent($calendarEvent, $userContext, $heskSettings) {
$this->calendarGateway->createEvent($calendarEvent, $userContext, $heskSettings);
$eventFilter = new SearchEventsFilter();
$eventFilter->eventId = $calendarEvent->id;
$eventFilter->reminderUserId = $userContext->id;
$events = $this->calendarGateway->getEventsForStaff($eventFilter, $heskSettings);
if (count($events) !== 1) {
throw new \Exception("Expected exactly 1 event, found: " . count($events));
}
$event = $events[0];
$this->auditTrailGateway->insertAuditTrailRecord($event->id,
AuditTrailEntityType::CALENDAR_EVENT,
'audit_event_created',
DateTimeHelpers::heskDate($heskSettings),
array(0 => $userContext->name . ' (' . $userContext->username . ')'), $heskSettings);
return $event;
}
public function deleteEvent($id, $userContext, $heskSettings) {
$this->calendarGateway->deleteEvent($id, $userContext, $heskSettings);
}
public function getBusinessHours($heskSettings) {
return $this->calendarGateway->getBusinessHours($heskSettings);
}
}

@ -0,0 +1,41 @@
<?php
namespace BusinessLogic\Calendar;
class ReminderUnit {
const MINUTE = 0;
const HOUR = 1;
const DAY = 2;
const WEEK = 3;
static function getByValue($value) {
switch ($value) {
case 0:
return 'MINUTE';
case 1:
return 'HOUR';
case 2:
return 'DAY';
case 3:
return 'WEEK';
default:
return 'UNKNOWN';
}
}
static function getByName($name) {
switch ($name) {
case 'MINUTE':
return self::MINUTE;
case 'HOUR':
return self::HOUR;
case 'DAY':
return self::DAY;
case 'WEEK':
return self::WEEK;
default:
return null;
}
}
}

@ -0,0 +1,30 @@
<?php
namespace BusinessLogic\Calendar;
class SearchEventsFilter {
/* @var $startTime int|null */
public $startTime;
/* @var $endTime int|null */
public $endTime;
/* @var $id int|null */
public $eventId;
/* @var $categories int[]|null */
public $categories;
/* @var $reminderUserId int|null */
public $reminderUserId;
/* @var $includeTickets bool */
public $includeTickets;
/* @var $includeUnassignedTickets bool */
public $includeUnassignedTickets;
/* @var $includeTicketsAssignedToOthers bool */
public $includeTicketsAssignedToOthers;
}

@ -0,0 +1,20 @@
<?php
namespace BusinessLogic\Calendar;
class TicketEvent extends AbstractEvent {
public $type = 'TICKET';
public $trackingId;
public $subject;
public $url;
public $owner;
public $priority;
public $status;
}

@ -2,7 +2,7 @@
namespace BusinessLogic\Categories; namespace BusinessLogic\Categories;
class Category { class Category extends \BaseClass {
/** /**
* @var int The Categories ID * @var int The Categories ID
*/ */
@ -22,7 +22,7 @@ class Category {
public $autoAssign; public $autoAssign;
/** /**
* @var int The type of Categories (1 = Private, 2 = Public) * @var int The type of Categories (1 = Private, 0 = Public)
*/ */
public $type; public $type;
@ -60,4 +60,14 @@ class Category {
* @var bool Indication if the user has access to the Categories * @var bool Indication if the user has access to the Categories
*/ */
public $accessible; public $accessible;
/**
* @var string
*/
public $description;
/**
* @var int
*/
public $numberOfTickets;
} }

@ -0,0 +1,203 @@
<?php
namespace BusinessLogic\Categories;
use BusinessLogic\Exceptions\AccessViolationException;
use BusinessLogic\Exceptions\ValidationException;
use BusinessLogic\Navigation\Direction;
use BusinessLogic\Security\PermissionChecker;
use BusinessLogic\Security\UserPrivilege;
use BusinessLogic\ValidationModel;
use DataAccess\Categories\CategoryGateway;
use DataAccess\Settings\ModsForHeskSettingsGateway;
use DataAccess\Tickets\TicketGateway;
class CategoryHandler extends \BaseClass {
/* @var $categoryGateway CategoryGateway */
private $categoryGateway;
/* @var $ticketGateway TicketGateway */
private $ticketGateway;
/* @var $permissionChecker PermissionChecker */
private $permissionChecker;
/* @var $modsForHeskSettingsGateway ModsForHeskSettingsGateway */
private $modsForHeskSettingsGateway;
function __construct(CategoryGateway $categoryGateway,
TicketGateway $ticketGateway,
PermissionChecker $permissionChecker,
ModsForHeskSettingsGateway $modsForHeskSettingsGateway) {
$this->categoryGateway = $categoryGateway;
$this->ticketGateway = $ticketGateway;
$this->permissionChecker = $permissionChecker;
$this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway;
}
/**
* @param $category Category
* @param $userContext
* @param $heskSettings array
* @return Category The newly created category with ID
* @throws ValidationException When validation fails
* @throws \Exception When the newly created category was not retrieved
*/
//TODO Test
function createCategory($category, $userContext, $heskSettings) {
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
$validationModel = $this->validate($category, $userContext);
if (count($validationModel->errorKeys) > 0) {
throw new ValidationException($validationModel);
}
$id = $this->categoryGateway->createCategory($category, $heskSettings);
$allCategories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
foreach ($allCategories as $innerCategory) {
if ($innerCategory->id === $id) {
return $innerCategory;
}
}
throw new \BaseException("Newly created category {$id} lost! :O");
}
/**
* @param $category Category
* @param $userContext
* @param $creating bool
* @return ValidationModel
* @throws AccessViolationException
*/
//TODO Test
private function validate($category, $userContext, $creating = true) {
$validationModel = new ValidationModel();
if (!$this->permissionChecker->doesUserHavePermission($userContext, UserPrivilege::CAN_MANAGE_CATEGORIES)) {
throw new AccessViolationException('User cannot manage categories!');
}
if (!$creating && $category->id < 1) {
$validationModel->errorKeys[] = 'ID_MISSING';
}
if ($category->backgroundColor === null || trim($category->backgroundColor) === '') {
$validationModel->errorKeys[] = 'BACKGROUND_COLOR_MISSING';
}
if ($category->foregroundColor === null || trim($category->foregroundColor) === '') {
$validationModel->errorKeys[] = 'FOREGROUND_COLOR_MISSING';
}
if ($category->name === null || trim($category->name) === '') {
$validationModel->errorKeys[] = 'NAME_MISSING';
}
if ($category->priority === null || intval($category->priority) < 0 || intval($category->priority) > 3) {
$validationModel->errorKeys[] = 'INVALID_PRIORITY';
}
if ($category->autoAssign === null || !is_bool($category->autoAssign)) {
$validationModel->errorKeys[] = 'INVALID_AUTOASSIGN';
}
if ($category->displayBorder === null || !is_bool($category->displayBorder)) {
$validationModel->errorKeys[] = 'INVALID_DISPLAY_BORDER';
}
if ($category->type === null || (intval($category->type) !== 0 && intval($category->type) !== 1)) {
$validationModel->errorKeys[] = 'INVALID_TYPE';
}
return $validationModel;
}
/**
* @param $category Category
* @param $userContext
* @param $heskSettings array
* @return Category
* @throws ValidationException
* @throws \Exception When the category is missing
*/
function editCategory($category, $userContext, $heskSettings) {
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
$validationModel = $this->validate($category, $userContext, false);
if (count($validationModel->errorKeys) > 0) {
throw new ValidationException($validationModel);
}
$this->categoryGateway->updateCategory($category, $heskSettings);
$this->categoryGateway->resortAllCategories($heskSettings);
$allCategories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
foreach ($allCategories as $innerCategory) {
if ($innerCategory->id === $category->id) {
return $innerCategory;
}
}
throw new \BaseException("Category {$category->id} vanished! :O");
}
function deleteCategory($id, $userContext, $heskSettings) {
if (!$this->permissionChecker->doesUserHavePermission($userContext, UserPrivilege::CAN_MANAGE_CATEGORIES)) {
throw new AccessViolationException('User cannot manage categories!');
}
if ($id === 1) {
throw new \BaseException("Category 1 cannot be deleted!");
}
$this->ticketGateway->moveTicketsToDefaultCategory($id, $heskSettings);
$this->categoryGateway->deleteCategory($id, $heskSettings);
$this->categoryGateway->resortAllCategories($heskSettings);
}
function sortCategory($id, $direction, $heskSettings) {
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
$category = null;
foreach ($categories as $innerCategory) {
if ($innerCategory->id === intval($id)) {
$category = $innerCategory;
break;
}
}
if ($category === null) {
throw new \BaseException("Could not find category with ID {$id}!");
}
if ($direction === Direction::UP) {
$category->catOrder -= 15;
} else {
$category->catOrder += 15;
}
$this->categoryGateway->updateCategory($category, $heskSettings);
$this->categoryGateway->resortAllCategories($heskSettings);
}
function getPublicCategories($heskSettings) {
$allCategories = $this->categoryGateway->getAllCategories($heskSettings, $this->modsForHeskSettingsGateway->getAllSettings($heskSettings));
$publicCategories = array();
foreach ($allCategories as $category) {
if ($category->type === 0) {
$publicCategories[] = $category;
}
}
return $publicCategories;
}
}

@ -4,15 +4,23 @@ namespace BusinessLogic\Categories;
use BusinessLogic\Security\UserContext; use BusinessLogic\Security\UserContext;
use DataAccess\Categories\CategoryGateway; use DataAccess\Categories\CategoryGateway;
use DataAccess\Settings\ModsForHeskSettingsGateway;
class CategoryRetriever { class CategoryRetriever extends \BaseClass {
/** /**
* @var CategoryGateway * @var CategoryGateway
*/ */
private $categoryGateway; private $categoryGateway;
function __construct($categoryGateway) { /**
* @var ModsForHeskSettingsGateway
*/
private $modsForHeskSettingsGateway;
function __construct(CategoryGateway $categoryGateway,
ModsForHeskSettingsGateway $modsForHeskSettingsGateway) {
$this->categoryGateway = $categoryGateway; $this->categoryGateway = $categoryGateway;
$this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway;
} }
/** /**
@ -21,7 +29,9 @@ class CategoryRetriever {
* @return array * @return array
*/ */
function getAllCategories($heskSettings, $userContext) { function getAllCategories($heskSettings, $userContext) {
$categories = $this->categoryGateway->getAllCategories($heskSettings); $modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
foreach ($categories as $category) { foreach ($categories as $category) {
$category->accessible = $userContext->admin || $category->accessible = $userContext->admin ||

@ -0,0 +1,19 @@
<?php
namespace BusinessLogic;
class DateTimeHelpers {
static function heskDate($heskSettings, $dt = '', $isStr = true, $return_str = true) {
if (!$dt) {
$dt = time();
} elseif ($isStr) {
$dt = strtotime($dt);
}
// Return formatted date
return $return_str ? date($heskSettings['timeformat'], $dt) : $dt;
}
}

@ -3,7 +3,7 @@
namespace BusinessLogic\Emails; namespace BusinessLogic\Emails;
class Addressees { class Addressees extends \BaseClass {
/** /**
* @var $to string[] * @var $to string[]
*/ */
@ -12,10 +12,10 @@ class Addressees {
/** /**
* @var $cc string[]|null * @var $cc string[]|null
*/ */
public $cc; public $cc = array();
/** /**
* @var $bcc string[]|null * @var $bcc string[]|null
*/ */
public $bcc; public $bcc = array();
} }

@ -7,14 +7,23 @@ use BusinessLogic\Tickets\Attachment;
use BusinessLogic\Tickets\Ticket; use BusinessLogic\Tickets\Ticket;
use PHPMailer; use PHPMailer;
class BasicEmailSender implements EmailSender { class BasicEmailSender extends \BaseClass implements EmailSender {
function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml) { function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml) {
$toEmails = implode(',', $emailBuilder->to);
if (preg_match("/\n|\r|\t|%0A|%0D|%08|%09/", $toEmails . $emailBuilder->subject)) {
return false;
}
$mailer = new PHPMailer(); $mailer = new PHPMailer();
if ($heskSettings['smtp']) { if ($heskSettings['smtp']) {
$mailer->isSMTP(); $mailer->isSMTP();
$mailer->SMTPAuth = true; $mailer->SMTPAuth = true;
//-- We'll set this explicitly below if the user has it enabled.
$mailer->SMTPAutoTLS = false;
if ($heskSettings['smtp_ssl']) { if ($heskSettings['smtp_ssl']) {
$mailer->SMTPSecure = "ssl"; $mailer->SMTPSecure = "ssl";
} elseif ($heskSettings['smtp_tls']) { } elseif ($heskSettings['smtp_tls']) {

@ -5,7 +5,7 @@ namespace BusinessLogic\Emails;
use BusinessLogic\Tickets\Attachment; use BusinessLogic\Tickets\Attachment;
class EmailBuilder { class EmailBuilder extends \BaseClass {
/** /**
* @var $to string[] * @var $to string[]
*/ */

@ -5,7 +5,7 @@ namespace BusinessLogic\Emails;
use BusinessLogic\Tickets\Ticket; use BusinessLogic\Tickets\Ticket;
class EmailSenderHelper { class EmailSenderHelper extends \BaseClass {
/** /**
* @var $emailTemplateParser EmailTemplateParser * @var $emailTemplateParser EmailTemplateParser
*/ */
@ -21,7 +21,9 @@ class EmailSenderHelper {
*/ */
private $mailgunEmailSender; private $mailgunEmailSender;
function __construct($emailTemplateParser, $basicEmailSender, $mailgunEmailSender) { function __construct(EmailTemplateParser $emailTemplateParser,
BasicEmailSender $basicEmailSender,
MailgunEmailSender $mailgunEmailSender) {
$this->emailTemplateParser = $emailTemplateParser; $this->emailTemplateParser = $emailTemplateParser;
$this->basicEmailSender = $basicEmailSender; $this->basicEmailSender = $basicEmailSender;
$this->mailgunEmailSender = $mailgunEmailSender; $this->mailgunEmailSender = $mailgunEmailSender;

@ -3,7 +3,7 @@
namespace BusinessLogic\Emails; namespace BusinessLogic\Emails;
class EmailTemplate { class EmailTemplate extends \BaseClass {
/** /**
* @var $languageKey string * @var $languageKey string
*/ */

@ -3,17 +3,18 @@
namespace BusinessLogic\Emails; namespace BusinessLogic\Emails;
use BusinessLogic\Exceptions\ApiFriendlyException;
use BusinessLogic\Exceptions\EmailTemplateNotFoundException; use BusinessLogic\Exceptions\EmailTemplateNotFoundException;
use BusinessLogic\Exceptions\InvalidEmailTemplateException; use BusinessLogic\Exceptions\InvalidEmailTemplateException;
use BusinessLogic\Security\UserContext;
use BusinessLogic\Statuses\DefaultStatusForAction; use BusinessLogic\Statuses\DefaultStatusForAction;
use BusinessLogic\Tickets\Ticket; use BusinessLogic\Tickets\Ticket;
use Core\Constants\Priority; use Core\Constants\Priority;
use DataAccess\Categories\CategoryGateway; use DataAccess\Categories\CategoryGateway;
use DataAccess\Logging\LoggingGateway;
use DataAccess\Security\UserGateway; use DataAccess\Security\UserGateway;
use DataAccess\Statuses\StatusGateway; use DataAccess\Statuses\StatusGateway;
class EmailTemplateParser { class EmailTemplateParser extends \BaseClass {
/** /**
* @var $statusGateway StatusGateway * @var $statusGateway StatusGateway
@ -35,11 +36,21 @@ class EmailTemplateParser {
*/ */
private $emailTemplateRetriever; private $emailTemplateRetriever;
function __construct($statusGateway, $categoryGateway, $userGateway, $emailTemplateRetriever) { /**
* @var $logger LoggingGateway
*/
private $logger;
function __construct(StatusGateway $statusGateway,
CategoryGateway $categoryGateway,
UserGateway $userGateway,
EmailTemplateRetriever $emailTemplateRetriever,
LoggingGateway $loggingGateway) {
$this->statusGateway = $statusGateway; $this->statusGateway = $statusGateway;
$this->categoryGateway = $categoryGateway; $this->categoryGateway = $categoryGateway;
$this->userGateway = $userGateway; $this->userGateway = $userGateway;
$this->emailTemplateRetriever = $emailTemplateRetriever; $this->emailTemplateRetriever = $emailTemplateRetriever;
$this->logger = $loggingGateway;
} }
/** /**
@ -50,6 +61,7 @@ class EmailTemplateParser {
* @param $modsForHeskSettings array * @param $modsForHeskSettings array
* @return ParsedEmailProperties * @return ParsedEmailProperties
* @throws InvalidEmailTemplateException * @throws InvalidEmailTemplateException
* @throws \Exception
*/ */
function getFormattedEmailForLanguage($templateId, $languageCode, $ticket, $heskSettings, $modsForHeskSettings) { function getFormattedEmailForLanguage($templateId, $languageCode, $ticket, $heskSettings, $modsForHeskSettings) {
global $hesklang; global $hesklang;
@ -73,10 +85,10 @@ class EmailTemplateParser {
} }
if ($fullLanguageName === null) { if ($fullLanguageName === null) {
throw new \Exception("Language code {$languageCode} did not return any valid HESK languages!"); throw new \BaseException("Language code {$languageCode} did not return any valid HESK languages!");
} }
$subject = $this->parseSubject($subject, $ticket, $fullLanguageName, $heskSettings); $subject = $this->parseSubject($subject, $ticket, $fullLanguageName, $heskSettings, $modsForHeskSettings);
$message = $this->parseMessage($template, $ticket, $fullLanguageName, $emailTemplate->forStaff, $heskSettings, $modsForHeskSettings, false); $message = $this->parseMessage($template, $ticket, $fullLanguageName, $emailTemplate->forStaff, $heskSettings, $modsForHeskSettings, false);
$htmlMessage = $this->parseMessage($htmlTemplate, $ticket, $fullLanguageName, $emailTemplate->forStaff, $heskSettings, $modsForHeskSettings, true); $htmlMessage = $this->parseMessage($htmlTemplate, $ticket, $fullLanguageName, $emailTemplate->forStaff, $heskSettings, $modsForHeskSettings, true);
@ -113,11 +125,11 @@ class EmailTemplateParser {
* @return string * @return string
* @throws \Exception if common.inc.php isn't loaded * @throws \Exception if common.inc.php isn't loaded
*/ */
private function parseSubject($subjectTemplate, $ticket, $language, $heskSettings) { private function parseSubject($subjectTemplate, $ticket, $language, $heskSettings, $modsForHeskSettings) {
global $hesklang; global $hesklang;
if (!function_exists('hesk_msgToPlain')) { if (!function_exists('hesk_msgToPlain')) {
throw new \Exception("common.inc.php not loaded!"); throw new \BaseException("common.inc.php not loaded!");
} }
if ($ticket === null) { if ($ticket === null) {
@ -126,8 +138,25 @@ class EmailTemplateParser {
// Status name and category name // Status name and category name
$defaultStatus = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings); $defaultStatus = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings);
$statusName = $defaultStatus->localizedNames[$language];
$category = $this->categoryGateway->getAllCategories($heskSettings)[$ticket->categoryId]; if (key_exists($language, $defaultStatus->localizedNames)) {
$statusName = $defaultStatus->localizedNames[$language];
} elseif (key_exists('English', $defaultStatus->localizedNames)) {
$statusName = $defaultStatus->localizedNames['English'];
$this->logger->logWarning('EmailTemplateParser', "No localized status found for status '{$defaultStatus->id}' and language '{$language}'. Defaulted to English.", "", new UserContext(), $heskSettings);
} else {
$statusName = "[ERROR: No localized status found for status '{$defaultStatus->id}']";
$this->logger->logError('EmailTemplateParser', "No localized status found for status '{$defaultStatus->id}'", "", new UserContext(), $heskSettings);
}
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
$category = null;
foreach ($categories as $innerCategory) {
if ($innerCategory->id === $ticket->categoryId) {
$category = $innerCategory;
break;
}
}
switch ($ticket->priorityId) { switch ($ticket->priorityId) {
case Priority::CRITICAL: case Priority::CRITICAL:
@ -169,7 +198,7 @@ class EmailTemplateParser {
global $hesklang; global $hesklang;
if (!function_exists('hesk_msgToPlain')) { if (!function_exists('hesk_msgToPlain')) {
throw new \Exception("common.inc.php not loaded!"); throw new \BaseException("common.inc.php not loaded!");
} }
if ($ticket === null) { if ($ticket === null) {
@ -189,8 +218,20 @@ class EmailTemplateParser {
// Status name and category name // Status name and category name
$defaultStatus = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings); $defaultStatus = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings);
$statusName = hesk_msgToPlain($defaultStatus->localizedNames[$language]); $statusName = hesk_msgToPlain($defaultStatus->localizedNames[$language]);
$category = hesk_msgToPlain($this->categoryGateway->getAllCategories($heskSettings)[$ticket->categoryId]->name);
$owner = hesk_msgToPlain($this->userGateway->getUserById($ticket->ownerId, $heskSettings)->name); $categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
$category = null;
foreach ($categories as $innerCategory) {
if ($innerCategory->id === $ticket->categoryId) {
$category = $innerCategory;
break;
}
}
$category = hesk_msgToPlain($category->name);
$owner = $this->userGateway->getUserById($ticket->ownerId, $heskSettings);
$ownerName = $owner === null ? $hesklang['unas'] : hesk_msgToPlain($owner->name);
switch ($ticket->priorityId) { switch ($ticket->priorityId) {
case Priority::CRITICAL: case Priority::CRITICAL:
@ -219,12 +260,23 @@ class EmailTemplateParser {
$msg = str_replace('%%SITE_URL%%', $heskSettings['site_url'], $msg); $msg = str_replace('%%SITE_URL%%', $heskSettings['site_url'], $msg);
$msg = str_replace('%%CATEGORY%%', $category, $msg); $msg = str_replace('%%CATEGORY%%', $category, $msg);
$msg = str_replace('%%PRIORITY%%', $priority, $msg); $msg = str_replace('%%PRIORITY%%', $priority, $msg);
$msg = str_replace('%%OWNER%%', $owner, $msg); $msg = str_replace('%%OWNER%%', $ownerName, $msg);
$msg = str_replace('%%STATUS%%', $statusName, $msg); $msg = str_replace('%%STATUS%%', $statusName, $msg);
$msg = str_replace('%%EMAIL%%', implode(';',$ticket->email), $msg); $msg = str_replace('%%EMAIL%%', implode(';', $ticket->email), $msg);
$msg = str_replace('%%CREATED%%', $ticket->dateCreated, $msg); $msg = str_replace('%%CREATED%%', $ticket->dateCreated, $msg);
$msg = str_replace('%%UPDATED%%', $ticket->lastChanged, $msg); $msg = str_replace('%%UPDATED%%', $ticket->lastChanged, $msg);
$msg = str_replace('%%ID%%', $ticket->id, $msg); $msg = str_replace('%%ID%%', $ticket->id, $msg);
$msg = str_replace('%%TIME_WORKED%%', $ticket->timeWorked, $msg);
$lastReplyBy = '';
// Get the last reply by
if (!empty($ticket->lastReplier)) {
$lastReplyBy = $ticket->lastReplier;
} else {
$lastReplyBy = $ticket->name;
}
$msg = str_replace('%%LAST_REPLY_BY%%', $lastReplyBy, $msg);
/* All custom fields */ /* All custom fields */
for ($i=1; $i<=50; $i++) { for ($i=1; $i<=50; $i++) {

@ -3,7 +3,7 @@
namespace BusinessLogic\Emails; namespace BusinessLogic\Emails;
class EmailTemplateRetriever { class EmailTemplateRetriever extends \BaseClass {
/** /**
* @var $validTemplates EmailTemplate[] * @var $validTemplates EmailTemplate[]
*/ */

@ -7,7 +7,7 @@ use BusinessLogic\Tickets\Attachment;
use BusinessLogic\Tickets\Ticket; use BusinessLogic\Tickets\Ticket;
use Mailgun\Mailgun; use Mailgun\Mailgun;
class MailgunEmailSender implements EmailSender { class MailgunEmailSender extends \BaseClass implements EmailSender {
function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml) { function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml) {
$mailgunArray = array(); $mailgunArray = array();

@ -1,15 +1,9 @@
<?php <?php
/**
* Created by PhpStorm.
* User: mkoch
* Date: 2/28/2017
* Time: 9:36 PM
*/
namespace BusinessLogic\Emails; namespace BusinessLogic\Emails;
class ParsedEmailProperties { class ParsedEmailProperties extends \BaseClass {
function __construct($subject, $message, $htmlMessage) { function __construct($subject, $message, $htmlMessage) {
$this->subject = $subject; $this->subject = $subject;
$this->message = $message; $this->message = $message;

@ -5,7 +5,7 @@ namespace BusinessLogic\Exceptions;
use Exception; use Exception;
class ApiFriendlyException extends Exception { class ApiFriendlyException extends \BaseException {
public $title; public $title;
public $httpResponseCode; public $httpResponseCode;

@ -4,8 +4,8 @@ namespace BusinessLogic\Exceptions;
class MissingAuthenticationTokenException extends ApiFriendlyException { class MissingAuthenticationTokenException extends ApiFriendlyException {
function __construct() { function __construct() {
parent::__construct("An 'X-Auth-Token' is required for all requests", parent::__construct("An 'X-Auth-Token' is required for this request",
'Security Exception', 'Security Exception',
400); 401);
} }
} }

@ -3,7 +3,7 @@
namespace BusinessLogic; namespace BusinessLogic;
class Helpers { class Helpers extends \BaseClass {
static function getHeader($key) { static function getHeader($key) {
$headers = getallheaders(); $headers = getallheaders();
@ -26,4 +26,12 @@ class Helpers {
? $array[$key] ? $array[$key]
: null; : null;
} }
static function boolval($val) {
return $val == true;
}
static function heskHtmlSpecialCharsDecode($in) {
return str_replace(array('&amp;', '&lt;', '&gt;', '&quot;'), array('&', '<', '>', '"'), $in);
}
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Navigation; namespace BusinessLogic\Navigation;
class CustomNavElement { class CustomNavElement extends \BaseClass {
/* @var $id int*/ /* @var $id int*/
public $id; public $id;

@ -6,11 +6,11 @@ namespace BusinessLogic\Navigation;
use BusinessLogic\Exceptions\ApiFriendlyException; use BusinessLogic\Exceptions\ApiFriendlyException;
use DataAccess\Navigation\CustomNavElementGateway; use DataAccess\Navigation\CustomNavElementGateway;
class CustomNavElementHandler { class CustomNavElementHandler extends \BaseClass {
/* @var $customNavElementGateway CustomNavElementGateway */ /* @var $customNavElementGateway CustomNavElementGateway */
private $customNavElementGateway; private $customNavElementGateway;
function __construct($customNavElementGateway) { function __construct(CustomNavElementGateway $customNavElementGateway) {
$this->customNavElementGateway = $customNavElementGateway; $this->customNavElementGateway = $customNavElementGateway;
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Navigation; namespace BusinessLogic\Navigation;
class CustomNavElementPlace { class CustomNavElementPlace extends \BaseClass {
const HOMEPAGE_BLOCK = 1; const HOMEPAGE_BLOCK = 1;
const CUSTOMER_NAVIGATION = 2; const CUSTOMER_NAVIGATION = 2;
const ADMIN_NAVIGATION = 3; const ADMIN_NAVIGATION = 3;

@ -3,7 +3,7 @@
namespace BusinessLogic\Navigation; namespace BusinessLogic\Navigation;
class Direction { class Direction extends \BaseClass {
const UP = 'up'; const UP = 'up';
const DOWN = 'down'; const DOWN = 'down';
} }

@ -5,13 +5,13 @@ namespace BusinessLogic\Security;
use DataAccess\Security\BanGateway; use DataAccess\Security\BanGateway;
class BanRetriever { class BanRetriever extends \BaseClass {
/** /**
* @var BanGateway * @var BanGateway
*/ */
private $banGateway; private $banGateway;
function __construct($banGateway) { function __construct(BanGateway $banGateway) {
$this->banGateway = $banGateway; $this->banGateway = $banGateway;
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Security; namespace BusinessLogic\Security;
class BannedEmail { class BannedEmail extends \BaseClass {
/** /**
* @var int * @var int
*/ */

@ -3,7 +3,7 @@
namespace BusinessLogic\Security; namespace BusinessLogic\Security;
class BannedIp { class BannedIp extends \BaseClass {
/** /**
* @var int * @var int
*/ */

@ -0,0 +1,23 @@
<?php
namespace BusinessLogic\Security;
class PermissionChecker extends \BaseClass {
/**
* @param $userContext UserContext
* @param $permission string
* @return bool
*/
function doesUserHavePermission($userContext, $permission) {
if ($userContext->admin) {
return true;
}
if (in_array($permission, $userContext->permissions)) {
return true;
}
return false;
}
}

@ -3,7 +3,9 @@
namespace BusinessLogic\Security; namespace BusinessLogic\Security;
class UserContext { use BusinessLogic\Helpers;
class UserContext extends \BaseClass {
/* @var $id int */ /* @var $id int */
public $id; public $id;
@ -55,6 +57,25 @@ class UserContext {
/* @var $active bool */ /* @var $active bool */
public $active; public $active;
function isAnonymousUser() {
return $this->id === -1;
}
static function buildAnonymousUser() {
$userContext = new UserContext();
$userContext->id = -1;
$userContext->username = "API - ANONYMOUS USER"; // Usernames can't have spaces, so no one will take this username
$userContext->admin = false;
$userContext->name = "ANONYMOUS USER";
$userContext->email = "anonymous-user@example.com";
$userContext->categories = array();
$userContext->permissions = array();
$userContext->autoAssign = false;
$userContext->active = true;
return $userContext;
}
/** /**
* Builds a user context based on the current session. **The session must be active!** * Builds a user context based on the current session. **The session must be active!**
* @param $dataRow array the $_SESSION superglobal or the hesk_users result set * @param $dataRow array the $_SESSION superglobal or the hesk_users result set
@ -64,7 +85,7 @@ class UserContext {
$userContext = new UserContext(); $userContext = new UserContext();
$userContext->id = intval($dataRow['id']); $userContext->id = intval($dataRow['id']);
$userContext->username = $dataRow['user']; $userContext->username = $dataRow['user'];
$userContext->admin = boolval($dataRow['isadmin']); $userContext->admin = Helpers::boolval($dataRow['isadmin']);
$userContext->name = $dataRow['name']; $userContext->name = $dataRow['name'];
$userContext->email = $dataRow['email']; $userContext->email = $dataRow['email'];
$userContext->signature = $dataRow['signature']; $userContext->signature = $dataRow['signature'];
@ -75,34 +96,34 @@ class UserContext {
$userContext->categories = explode(',', $dataRow['categories']); $userContext->categories = explode(',', $dataRow['categories']);
} }
$userContext->permissions = explode(',', $dataRow['heskprivileges']); $userContext->permissions = explode(',', $dataRow['heskprivileges']);
$userContext->autoAssign = boolval($dataRow['autoassign']); $userContext->autoAssign = Helpers::boolval($dataRow['autoassign']);
$userContext->ratingNegative = intval($dataRow['ratingneg']); $userContext->ratingNegative = intval($dataRow['ratingneg']);
$userContext->ratingPositive = intval($dataRow['ratingpos']); $userContext->ratingPositive = intval($dataRow['ratingpos']);
$userContext->rating = floatval($dataRow['rating']); $userContext->rating = floatval($dataRow['rating']);
$userContext->totalNumberOfReplies = intval($dataRow['replies']); $userContext->totalNumberOfReplies = intval($dataRow['replies']);
$userContext->active = boolval($dataRow['active']); $userContext->active = Helpers::boolval($dataRow['active']);
$preferences = new UserContextPreferences(); $preferences = new UserContextPreferences();
$preferences->afterReply = intval($dataRow['afterreply']); $preferences->afterReply = intval($dataRow['afterreply']);
$preferences->autoStartTimeWorked = boolval($dataRow['autostart']); $preferences->autoStartTimeWorked = Helpers::boolval($dataRow['autostart']);
$preferences->autoreload = intval($dataRow['autoreload']); $preferences->autoreload = intval($dataRow['autoreload']);
$preferences->defaultNotifyCustomerNewTicket = boolval($dataRow['notify_customer_new']); $preferences->defaultNotifyCustomerNewTicket = Helpers::boolval($dataRow['notify_customer_new']);
$preferences->defaultNotifyCustomerReply = boolval($dataRow['notify_customer_reply']); $preferences->defaultNotifyCustomerReply = Helpers::boolval($dataRow['notify_customer_reply']);
$preferences->showSuggestedKnowledgebaseArticles = boolval($dataRow['show_suggested']); $preferences->showSuggestedKnowledgebaseArticles = Helpers::boolval($dataRow['show_suggested']);
$preferences->defaultCalendarView = intval($dataRow['default_calendar_view']); $preferences->defaultCalendarView = intval($dataRow['default_calendar_view']);
$preferences->defaultTicketView = $dataRow['default_list']; $preferences->defaultTicketView = $dataRow['default_list'];
$userContext->preferences = $preferences; $userContext->preferences = $preferences;
$notifications = new UserContextNotifications(); $notifications = new UserContextNotifications();
$notifications->newUnassigned = boolval($dataRow['notify_new_unassigned']); $notifications->newUnassigned = Helpers::boolval($dataRow['notify_new_unassigned']);
$notifications->newAssignedToMe = boolval($dataRow['notify_new_my']); $notifications->newAssignedToMe = Helpers::boolval($dataRow['notify_new_my']);
$notifications->replyUnassigned = boolval($dataRow['notify_reply_unassigned']); $notifications->replyUnassigned = Helpers::boolval($dataRow['notify_reply_unassigned']);
$notifications->replyToMe = boolval($dataRow['notify_reply_my']); $notifications->replyToMe = Helpers::boolval($dataRow['notify_reply_my']);
$notifications->ticketAssignedToMe = boolval($dataRow['notify_assigned']); $notifications->ticketAssignedToMe = Helpers::boolval($dataRow['notify_assigned']);
$notifications->privateMessage = boolval($dataRow['notify_pm']); $notifications->privateMessage = Helpers::boolval($dataRow['notify_pm']);
$notifications->noteOnTicketAssignedToMe = boolval($dataRow['notify_note']); $notifications->noteOnTicketAssignedToMe = Helpers::boolval($dataRow['notify_note']);
$notifications->noteOnTicketNotAssignedToMe = boolval($dataRow['notify_note_unassigned']); $notifications->noteOnTicketNotAssignedToMe = Helpers::boolval($dataRow['notify_note_unassigned']);
$notifications->overdueTicketUnassigned = boolval($dataRow['notify_overdue_unassigned']); $notifications->overdueTicketUnassigned = Helpers::boolval($dataRow['notify_overdue_unassigned']);
$userContext->notificationSettings = $notifications; $userContext->notificationSettings = $notifications;
return $userContext; return $userContext;

@ -8,13 +8,13 @@ use BusinessLogic\Exceptions\MissingAuthenticationTokenException;
use BusinessLogic\Helpers; use BusinessLogic\Helpers;
use DataAccess\Security\UserGateway; use DataAccess\Security\UserGateway;
class UserContextBuilder { class UserContextBuilder extends \BaseClass {
/** /**
* @var UserGateway * @var UserGateway
*/ */
private $userGateway; private $userGateway;
function __construct($userGateway) { function __construct(UserGateway $userGateway) {
$this->userGateway = $userGateway; $this->userGateway = $userGateway;
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Security; namespace BusinessLogic\Security;
class UserContextNotifications { class UserContextNotifications extends \BaseClass {
public $newUnassigned; public $newUnassigned;
public $newAssignedToMe; public $newAssignedToMe;
public $replyUnassigned; public $replyUnassigned;

@ -3,7 +3,7 @@
namespace BusinessLogic\Security; namespace BusinessLogic\Security;
class UserContextPreferences { class UserContextPreferences extends \BaseClass {
public $afterReply; public $afterReply;
public $autoStartTimeWorked; public $autoStartTimeWorked;
public $autoreload; public $autoreload;

@ -9,9 +9,13 @@
namespace BusinessLogic\Security; namespace BusinessLogic\Security;
class UserPrivilege { class UserPrivilege extends \BaseClass {
const CAN_VIEW_TICKETS = 'can_view_tickets'; const CAN_VIEW_TICKETS = 'can_view_tickets';
const CAN_REPLY_TO_TICKETS = 'can_reply_tickets'; const CAN_REPLY_TO_TICKETS = 'can_reply_tickets';
const CAN_EDIT_TICKETS = 'can_edit_tickets'; const CAN_EDIT_TICKETS = 'can_edit_tickets';
const CAN_DELETE_TICKETS = 'can_del_tickets'; const CAN_DELETE_TICKETS = 'can_del_tickets';
const CAN_MANAGE_CATEGORIES = 'can_man_cat';
const CAN_VIEW_ASSIGNED_TO_OTHER = 'can_view_ass_others';
const CAN_VIEW_UNASSIGNED = 'can_view_unassigned';
const CAN_MANAGE_SERVICE_MESSAGES = 'can_service_msg';
} }

@ -6,11 +6,11 @@ namespace BusinessLogic\Security;
use BusinessLogic\Tickets\Ticket; use BusinessLogic\Tickets\Ticket;
use DataAccess\Security\UserGateway; use DataAccess\Security\UserGateway;
class UserToTicketChecker { class UserToTicketChecker extends \BaseClass {
/* @var $userGateway UserGateway */ /* @var $userGateway UserGateway */
private $userGateway; private $userGateway;
function __construct($userGateway) { function __construct(UserGateway $userGateway) {
$this->userGateway = $userGateway; $this->userGateway = $userGateway;
} }
@ -32,7 +32,7 @@ class UserToTicketChecker {
} }
$categoryManagerId = $this->userGateway->getManagerForCategory($ticket->categoryId, $heskSettings); $categoryManagerId = $this->userGateway->getManagerForCategory($ticket->categoryId, $heskSettings);
if ($user->id === $categoryManagerId) { if ($user->id === $categoryManagerId) {
return true; return true;
} }

@ -0,0 +1,12 @@
<?php
namespace BusinessLogic\ServiceMessages;
class GetServiceMessagesFilter {
/* @var $includeStaffServiceMessages bool */
public $includeStaffServiceMessages = true;
/* @var $includeDrafts bool */
public $includeDrafts = true;
}

@ -0,0 +1,39 @@
<?php
namespace BusinessLogic\ServiceMessages;
class ServiceMessage extends \BaseClass {
/* @var $id int */
public $id;
/* @var $dateCreated string */
public $dateCreated;
/* @var $createdBy int */
public $createdBy;
/* @var $title string */
public $title;
/* @var $message string */
public $message;
/* @var $style string */
public $style;
/* @var $published bool */
public $published;
/* @var $order int */
public $order;
/* @var $icon string */
public $icon;
/* @var $locations string[] */
public $locations;
/* @var $language string */
public $language;
}

@ -0,0 +1,164 @@
<?php
namespace BusinessLogic\ServiceMessages;
// TODO Test
use BusinessLogic\Exceptions\ValidationException;
use BusinessLogic\Navigation\Direction;
use BusinessLogic\ValidationModel;
use DataAccess\ServiceMessages\ServiceMessagesGateway;
class ServiceMessageHandler extends \BaseClass {
/* @var $serviceMessageGateway ServiceMessagesGateway */
private $serviceMessageGateway;
function __construct(ServiceMessagesGateway $serviceMessagesGateway) {
$this->serviceMessageGateway = $serviceMessagesGateway;
}
function createServiceMessage($serviceMessage, $heskSettings) {
$this->validate($serviceMessage, $heskSettings);
if ($serviceMessage->icon === null) {
switch ($serviceMessage->style) {
case ServiceMessageStyle::NONE:
$serviceMessage->icon = '';
break;
case ServiceMessageStyle::INFO:
$serviceMessage->icon = 'fa fa-comment';
break;
case ServiceMessageStyle::NOTICE:
$serviceMessage->icon = 'fa fa-exclamation-triangle';
break;
case ServiceMessageStyle::ERROR:
$serviceMessage->icon = 'fa fa-times-circle';
break;
case ServiceMessageStyle::SUCCESS:
$serviceMessage->icon = 'fa fa-check-circle';
break;
}
}
return $this->serviceMessageGateway->createServiceMessage($serviceMessage, $heskSettings);
}
function getServiceMessages($heskSettings, $searchFilter) {
return $this->serviceMessageGateway->getServiceMessages($heskSettings, $searchFilter);
}
function editServiceMessage($serviceMessage, $heskSettings) {
$this->validate($serviceMessage, $heskSettings, false);
if ($serviceMessage->icon === null) {
switch ($serviceMessage->style) {
case ServiceMessageStyle::NONE:
$serviceMessage->icon = '';
break;
case ServiceMessageStyle::INFO:
$serviceMessage->icon = 'fa fa-comment';
break;
case ServiceMessageStyle::NOTICE:
$serviceMessage->icon = 'fa fa-exclamation-triangle';
break;
case ServiceMessageStyle::ERROR:
$serviceMessage->icon = 'fa fa-times-circle';
break;
case ServiceMessageStyle::SUCCESS:
$serviceMessage->icon = 'fa fa-check-circle';
break;
}
}
return $this->serviceMessageGateway->updateServiceMessage($serviceMessage, $heskSettings);
}
function deleteServiceMessage($id, $heskSettings) {
$this->serviceMessageGateway->deleteServiceMessage($id, $heskSettings);
}
function sortServiceMessage($id, $direction, $heskSettings) {
$serviceMessages = $this->serviceMessageGateway->getServiceMessages($heskSettings, new GetServiceMessagesFilter());
$serviceMessage = null;
foreach ($serviceMessages as $innerServiceMessage) {
if (intval($innerServiceMessage->id) === intval($id)) {
$serviceMessage = $innerServiceMessage;
break;
}
}
if ($serviceMessage === null) {
throw new \BaseException("Could not find service message with ID {$id}!");
}
if ($direction === Direction::UP) {
$serviceMessage->order -= 15;
} else {
$serviceMessage->order += 15;
}
$this->serviceMessageGateway->updateServiceMessage($serviceMessage, $heskSettings);
$this->serviceMessageGateway->resortAllServiceMessages($heskSettings);
}
/**
* @param $serviceMessage ServiceMessage
* @param bool $isNew
* @throws ValidationException
*/
private function validate($serviceMessage, $heskSettings, $isNew = true) {
$validationModel = new ValidationModel();
if ($isNew && $serviceMessage->createdBy < 1) {
$validationModel->errorKeys[] = 'MISSING_CREATOR';
}
if ($serviceMessage->message === null || trim($serviceMessage->message) === '') {
$validationModel->errorKeys[] = 'MISSING_MESSAGE';
} else {
$htmlPurifier = new \HeskHTMLPurifier($heskSettings['cache_dir']);
$serviceMessage->message = $htmlPurifier->heskPurify($serviceMessage->message);
}
if ($serviceMessage->language === null || trim($serviceMessage->language) === '') {
$validationModel->errorKeys[] = 'MISSING_LANGUAGE';
}
$languageFound = false;
foreach ($heskSettings['languages'] as $key => $value) {
if ($value['folder'] === $serviceMessage->language || $serviceMessage->language === 'ALL') {
$languageFound = true;
break;
}
}
if (!$languageFound && !in_array('MISSING_LANGUAGE', $validationModel->errorKeys)) {
$validationModel->errorKeys[] = 'LANGUAGE_NOT_INSTALLED';
}
if ($serviceMessage->title === null || trim($serviceMessage->title) === '') {
$validationModel->errorKeys[] = 'MISSING_TITLE';
}
if ($serviceMessage->style === null || trim($serviceMessage->style) === '') {
$validationModel->errorKeys[] = 'MISSING_STYLE';
}
try {
ServiceMessageStyle::getIdForStyle($serviceMessage->style);
} catch (\Exception $e) {
$validationModel->errorKeys[] = 'INVALID_STYLE';
}
if ($serviceMessage->locations === null || count($serviceMessage->locations) === 0) {
$validationModel->errorKeys[] = 'MISSING_LOCATIONS';
} else {
$locations = ServiceMessageLocation::getAll();
foreach ($serviceMessage->locations as $location) {
if (!in_array($location, $locations)) {
$validationModel->errorKeys[] = 'INVALID_LOCATION';
break;
}
}
}
if (count($validationModel->errorKeys) > 0) {
// Validation failed
throw new ValidationException($validationModel);
}
}
}

@ -0,0 +1,34 @@
<?php
namespace BusinessLogic\ServiceMessages;
class ServiceMessageLocation {
const CUSTOMER_HOME = 'CUSTOMER_HOME';
const CUSTOMER_KB_HOME = 'CUSTOMER_KB_HOME';
const CUSTOMER_VIEW_KB_ARTICLE = 'CUSTOMER_VIEW_KB_ARTICLE';
const CUSTOMER_SUBMIT_TICKET = 'CUSTOMER_SUBMIT_TICKET';
const CUSTOMER_VIEW_TICKET = 'CUSTOMER_VIEW_TICKET';
const STAFF_LOGIN = 'STAFF_LOGIN';
const STAFF_HOME = 'STAFF_HOME';
const STAFF_KB_HOME = 'STAFF_KB_HOME';
const STAFF_VIEW_KB_ARTICLE = 'STAFF_VIEW_KB_ARTICLE';
const STAFF_SUBMIT_TICKET = 'STAFF_SUBMIT_TICKET';
const STAFF_VIEW_TICKET = 'STAFF_VIEW_TICKET';
static function getAll() {
return array(
self::CUSTOMER_HOME,
self::CUSTOMER_KB_HOME,
self::CUSTOMER_VIEW_KB_ARTICLE,
self::CUSTOMER_SUBMIT_TICKET,
self::CUSTOMER_VIEW_TICKET,
self::STAFF_LOGIN,
self::STAFF_HOME,
self::STAFF_KB_HOME,
self::STAFF_VIEW_KB_ARTICLE,
self::STAFF_SUBMIT_TICKET,
self::STAFF_VIEW_TICKET,
);
}
}

@ -0,0 +1,44 @@
<?php
namespace BusinessLogic\ServiceMessages;
class ServiceMessageStyle {
const NONE = 'NONE'; // 0
const SUCCESS = 'SUCCESS'; // 1
const INFO = 'INFO'; // 2
const NOTICE = 'NOTICE'; // 3
const ERROR = 'ERROR'; // 4
static function getStyleById($id) {
$styles = array(
0 => self::NONE,
1 => self::SUCCESS,
2 => self::INFO,
3 => self::NOTICE,
4 => self::ERROR
);
if (!isset($styles[$id])) {
throw new \Exception("Style {$id} is not a valid service message style.");
}
return $styles[$id];
}
static function getIdForStyle($style) {
$styles = array(
self::NONE => 0,
self::SUCCESS => 1,
self::INFO => 2,
self::NOTICE => 3,
self::ERROR => 4
);
if (!isset($styles[$style])) {
throw new \Exception("Style {$style} is not a valid service message style.");
}
return $styles[$style];
}
}

@ -5,11 +5,11 @@ namespace BusinessLogic\Settings;
use DataAccess\Settings\ModsForHeskSettingsGateway; use DataAccess\Settings\ModsForHeskSettingsGateway;
class ApiChecker { class ApiChecker extends \BaseClass {
/* @var $modsForHeskSettingsGateway ModsForHeskSettingsGateway */ /* @var $modsForHeskSettingsGateway ModsForHeskSettingsGateway */
private $modsForHeskSettingsGateway; private $modsForHeskSettingsGateway;
function __construct($modsForHeskSettingsGateway) { function __construct(ModsForHeskSettingsGateway $modsForHeskSettingsGateway) {
$this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway; $this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway;
} }

@ -5,11 +5,11 @@ namespace BusinessLogic\Settings;
// TODO Test! // TODO Test!
use DataAccess\Settings\ModsForHeskSettingsGateway; use DataAccess\Settings\ModsForHeskSettingsGateway;
class SettingsRetriever { class SettingsRetriever extends \BaseClass {
/* @var $modsForHeskSettingsGateway ModsForHeskSettingsGateway */ /* @var $modsForHeskSettingsGateway ModsForHeskSettingsGateway */
private $modsForHeskSettingsGateway; private $modsForHeskSettingsGateway;
function __construct($modsForHeskSettingsGateway) { function __construct(ModsForHeskSettingsGateway $modsForHeskSettingsGateway) {
$this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway; $this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway;
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Statuses; namespace BusinessLogic\Statuses;
class Closable { class Closable extends \BaseClass {
const YES = "yes"; const YES = "yes";
const STAFF_ONLY = "sonly"; const STAFF_ONLY = "sonly";
const CUSTOMERS_ONLY = "conly"; const CUSTOMERS_ONLY = "conly";

@ -3,7 +3,7 @@
namespace BusinessLogic\Statuses; namespace BusinessLogic\Statuses;
class DefaultStatusForAction { class DefaultStatusForAction extends \BaseClass {
const NEW_TICKET = "IsNewTicketStatus"; const NEW_TICKET = "IsNewTicketStatus";
const CLOSED_STATUS = "IsClosed"; const CLOSED_STATUS = "IsClosed";
const CLOSED_BY_CLIENT = "IsClosedByClient"; const CLOSED_BY_CLIENT = "IsClosedByClient";

@ -3,7 +3,7 @@
namespace BusinessLogic\Statuses; namespace BusinessLogic\Statuses;
class Status { class Status extends \BaseClass {
static function fromDatabase($row, $languageRs) { static function fromDatabase($row, $languageRs) {
$status = new Status(); $status = new Status();
$status->id = intval($row['ID']); $status->id = intval($row['ID']);

@ -6,11 +6,11 @@ namespace BusinessLogic\Statuses;
use DataAccess\Statuses\StatusGateway; use DataAccess\Statuses\StatusGateway;
// TODO Test! // TODO Test!
class StatusRetriever { class StatusRetriever extends \BaseClass {
/* @var $statusGateway StatusGateway */ /* @var $statusGateway StatusGateway */
private $statusGateway; private $statusGateway;
function __construct($statusGateway) { function __construct(StatusGateway $statusGateway) {
$this->statusGateway = $statusGateway; $this->statusGateway = $statusGateway;
} }

@ -3,7 +3,7 @@
namespace BusinessLogic\Tickets; namespace BusinessLogic\Tickets;
class Attachment { class Attachment extends \BaseClass {
/** /**
* @var int * @var int
*/ */

@ -0,0 +1,24 @@
<?php
namespace BusinessLogic\Tickets;
class AuditTrail extends \BaseClass {
/* @var $id int */
public $id;
/* @var $entityId int */
public $entityId;
/* @var $entityType string */
public $entityType;
/* @var $languageKey string */
public $languageKey;
/* @var $date string */
public $date;
/* @var $replacementValues string[] */
public $replacementValues;
}

@ -0,0 +1,9 @@
<?php
namespace BusinessLogic\Tickets;
class AuditTrailEntityType extends \BaseClass {
const TICKET = 'TICKET';
const CALENDAR_EVENT = 'CALENDAR_EVENT';
}

@ -0,0 +1,9 @@
<?php
namespace BusinessLogic\Tickets;
class AuditTrailEvent extends \BaseClass {
const DUE_DATE_REMOVED = 'audit_due_date_removed';
const DUE_DATE_CHANGED = 'audit_due_date_changed';
}

@ -8,14 +8,15 @@ use BusinessLogic\Security\UserPrivilege;
use DataAccess\Categories\CategoryGateway; use DataAccess\Categories\CategoryGateway;
use DataAccess\Security\UserGateway; use DataAccess\Security\UserGateway;
class Autoassigner { class Autoassigner extends \BaseClass {
/* @var $categoryGateway CategoryGateway */ /* @var $categoryGateway CategoryGateway */
private $categoryGateway; private $categoryGateway;
/* @var $userGateway UserGateway */ /* @var $userGateway UserGateway */
private $userGateway; private $userGateway;
function __construct($categoryGateway, $userGateway) { function __construct(CategoryGateway $categoryGateway,
UserGateway $userGateway) {
$this->categoryGateway = $categoryGateway; $this->categoryGateway = $categoryGateway;
$this->userGateway = $userGateway; $this->userGateway = $userGateway;
} }

@ -2,7 +2,7 @@
namespace BusinessLogic\Tickets; namespace BusinessLogic\Tickets;
class CreateTicketByCustomerModel { class CreateTicketByCustomerModel extends \BaseClass {
/** /**
* @var string * @var string
*/ */

@ -3,7 +3,7 @@
namespace BusinessLogic\Tickets; namespace BusinessLogic\Tickets;
class CreatedTicketModel { class CreatedTicketModel extends \BaseClass {
/* @var $ticket Ticket */ /* @var $ticket Ticket */
public $ticket; public $ticket;

@ -0,0 +1,17 @@
<?php
namespace BusinessLogic\Tickets\CustomFields;
class CustomField {
/* @var $id int */
public $id;
/* @var $name string */
public $name;
/* @var $type string */
public $type;
/* @var $properties array */
public $properties;
}

@ -3,7 +3,7 @@
namespace BusinessLogic\Tickets\CustomFields; namespace BusinessLogic\Tickets\CustomFields;
class CustomFieldValidator { class CustomFieldValidator extends \BaseClass {
static function isCustomFieldInCategory($customFieldId, $categoryId, $staff, $heskSettings) { static function isCustomFieldInCategory($customFieldId, $categoryId, $staff, $heskSettings) {
$customField = $heskSettings['custom_fields']["custom{$customFieldId}"]; $customField = $heskSettings['custom_fields']["custom{$customFieldId}"];

@ -3,7 +3,7 @@
namespace BusinessLogic\Tickets; namespace BusinessLogic\Tickets;
class EditTicketModel { class EditTicketModel extends \BaseClass {
/* @var $id int */ /* @var $id int */
public $id; public $id;

@ -3,9 +3,7 @@
namespace BusinessLogic\Tickets\Exceptions; namespace BusinessLogic\Tickets\Exceptions;
use Exception; class UnableToGenerateTrackingIdException extends \BaseException {
class UnableToGenerateTrackingIdException extends Exception {
public function __construct() { public function __construct() {
parent::__construct("Error generating a unique ticket ID."); parent::__construct("Error generating a unique ticket ID.");
} }

@ -10,7 +10,7 @@ use BusinessLogic\ValidationModel;
use BusinessLogic\Validators; use BusinessLogic\Validators;
use Core\Constants\CustomField; use Core\Constants\CustomField;
class NewTicketValidator { class NewTicketValidator extends \BaseClass {
/** /**
* @var $categoryRetriever CategoryRetriever * @var $categoryRetriever CategoryRetriever
*/ */
@ -24,7 +24,9 @@ class NewTicketValidator {
*/ */
private $ticketValidators; private $ticketValidators;
function __construct($categoryRetriever, $banRetriever, $ticketValidators) { function __construct(CategoryRetriever $categoryRetriever,
BanRetriever $banRetriever,
TicketValidators $ticketValidators) {
$this->categoryRetriever = $categoryRetriever; $this->categoryRetriever = $categoryRetriever;
$this->banRetriever = $banRetriever; $this->banRetriever = $banRetriever;
$this->ticketValidators = $ticketValidators; $this->ticketValidators = $ticketValidators;

@ -9,7 +9,7 @@
namespace BusinessLogic\Tickets; namespace BusinessLogic\Tickets;
class Reply { class Reply extends \BaseClass {
/** /**
* @var $id int * @var $id int
*/ */

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save