Merge branch 'hesk-2-8-0-update' into '3-4-0'

HESK 2.8.0/2.8.1 Update

See merge request mike-koch/Mods-for-HESK!99
master^2
Mike Koch 6 years ago
commit 1ca4780d82

6
.gitignore vendored

@ -8,6 +8,7 @@ admin/archive.php
admin/custom_statuses.php
admin/email_templates.php
admin/generate_spam_question.php
admin/resend_notification.php
admin/test_connection.php
attachments/index.htm
cache/
@ -19,6 +20,7 @@ header.txt
hesk_settings.inc.php
img/add_article.png
img/add_category.png
img/anonymize.png
img/article_text.png
img/autoassign_off.png
img/autoassign_on.png
@ -34,8 +36,10 @@ img/delete.png
img/delete_off.png
img/delete_ticket.png
img/edit.png
img/email.png
img/error.png
img/existingticket.png
img/export.png
img/flag_critical.png
img/flag_high.png
img/flag_low.png
@ -81,6 +85,7 @@ img/lock.png
img/login.png
img/mail.png
img/manage.png
img/menu.png
img/minus.gif
img/minusbottom.gif
img/minustop.gif
@ -260,6 +265,7 @@ language/en/emails/new_ticket.txt
language/en/emails/new_ticket_staff.txt
language/en/emails/ticket_assigned_to_you.txt
language/en/index.htm
language/en/text.php
language/index.htm
language/*
!language/en

@ -108,23 +108,17 @@ else {
</div>
</div>
<?php
$hesk_settings['hesk_license']('HMgPSAxOw0KaWYgKGZpbGVfZXhpc3RzKEhFU0tfUEFUSCAuI
CdoZXNrX2xpY2Vuc2UucGhwJykpDQp7DQokaCA9ICghZW1wdHkoJF9TRVJWRVJbJ0hUVFBfSE9TVCddK
SkgPyAkX1NFUlZFUlsnSFRUUF9IT1NUJ10gOiAoKCFlbXB0eSgkX1NFUlZFUlsnU0VSVkVSX05BTUUnX
SkpID8gJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gOiBnZXRlbnYoJ1NFUlZFUl9OQU1FJykpOw0KJGggP
SBzdHJfcmVwbGFjZSgnd3d3LicsJycsc3RydG9sb3dlcigkaCkpOw0KaW5jbHVkZShIRVNLX1BBVEggL
iAnaGVza19saWNlbnNlLnBocCcpOw0KaWYgKGlzc2V0KCRoZXNrX3NldHRpbmdzWydsaWNlbnNlJ10pI
CYmIHN0cnBvcygkaGVza19zZXR0aW5nc1snbGljZW5zZSddLHNoYTEoJGguJ2gzJkZwMiNMYUEmNTkhd
yg4LlpjXSordVI1MTInKSkgIT09IGZhbHNlKQ0Kew0KJHMgPSAwOw0KfQ0KZWxzZQ0Kew0KZWNobyAnP
HAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyO2NvbG9yOnJlZDsiPklOVkFMSUQgTElDRU5TRSAoTk9UI
FJFR0lTVEVSRUQgRk9SICcuJGguJykhPC9wPic7DQp9DQp9DQppZiAoJHMpDQp7DQplY2hvICc8aHIgL
z48dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iMTAwJSI+PHRyPjx0ZD48Yj4nLiRoZXNrbGFuZ1sncmVtb
3ZlX3N0YXRlbWVudCddLic8L2I+PC90ZD48dGQgc3R5bGU9InRleHQtYWxpZ246cmlnaHQiPjxhIGhyZ
WY9IkphdmFzY3JpcHQ6dm9pZCgwKSIgb25jbGljaz0iYWxlcnQoXCcnLiRoZXNrbGFuZ1snc3VwcG9yd
F9ub3RpY2UnXS4nXCcpIj4nLiRoZXNrbGFuZ1snc2gnXS4nPC9hPjwvdGQ+PC90cj48L3RhYmxlPjxwP
icuJGhlc2tsYW5nWydzdXBwb3J0X3JlbW92ZSddLicuIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmhlc2suY
29tL2J1eS5waHAiIHRhcmdldD0iX2JsYW5rIj4nLiRoZXNrbGFuZ1snY2xpY2tfaW5mbyddLic8L2E+P
C9wPjxociAvPic7DQp9DQo=', "\112");
/*******************************************************************************
The code below handles HESK licensing. Removing or modifying this code without
purchasing a HESK license is strictly prohibited.
To purchase a HESK license and support future HESK development please visit:
https://www.hesk.com/buy.php
*******************************************************************************/
$x1a="\142a".chr(0163).chr(847249408>>23)."\66\x34".chr(796917760>>23)."\x65\156\143".chr(0157)."\x64\145";$hesk_settings['hesk_license']($x1a("\x3c\150r\x20\57\76".chr(503316480>>23)."\x74\141\142l\x65\40".chr(0142).chr(0157).chr(0162)."\144\145r\x3d\42\60".chr(285212672>>23)."\x20\x77\x69".chr(0144)."th".chr(511705088>>23)."\x22".chr(061)."\60\60\x25\42".chr(520093696>>23)."\x3c\164".chr(0162).">\74t\x64\x3e\x3c".chr(0142).chr(076).$hesklang[chr(956301312>>23)."\145\155\157\x76e".chr(796917760>>23)."\x73ta\164e\x6d".chr(847249408>>23)."\156\x74"].chr(503316480>>23)."\x2f\142\x3e".chr(074)."\57t\x64\76".chr(074)."td".chr(268435456>>23)."\x73ty\154\x65\x3d\x22te".chr(1006632960>>23)."t\x2d\141\x6c\x69".chr(0147).chr(922746880>>23)."\x3ar\151\x67ht\"\76".chr(503316480>>23)."\141 \x68\162\145\146\x3d\42".chr(0112).chr(813694976>>23)."v\141".chr(0163).chr(830472192>>23)."\162\x69".chr(0160).chr(0164)."\x3a".chr(989855744>>23)."\157\151d\50\x30".chr(343932928>>23).chr(042)."\40onc\154\151\143\153\x3d".chr(042)."\x61\x6c\145\x72t(\x27".$hesklang["\163".chr(981467136>>23)."\x70".chr(939524096>>23).chr(0157)."\162\164\137n".chr(931135488>>23)."\x74\151".chr(0143)."\x65"].chr(047)."\51\42\x3e".$hesklang["\x73\x68"]."\74".chr(394264576>>23)."\x61\x3e\74\57\164d\76\x3c/\x74\162\76".chr(503316480>>23).chr(057)."t\x61\x62\x6ce\x3e\x3c\x70\x3e".$hesklang[chr(0163)."\x75ppo\x72\x74\137".chr(956301312>>23).chr(847249408>>23)."\155".chr(931135488>>23)."v\x65"]."\x2e\x20\x3c".chr(813694976>>23)."\40\x68re\x66\x3d".chr(285212672>>23)."\150".chr(973078528>>23).chr(973078528>>23)."\160\x73".chr(486539264>>23)."\57\x2f".chr(998244352>>23)."\x77\167".chr(056)."\150".chr(847249408>>23)."s\153\56\x63\157".chr(0155)."/".chr(0142)."\165\171.".chr(0160)."h\x70".chr(285212672>>23)."\x20\x74\141".chr(0162)."g".chr(847249408>>23)."\164\x3d".chr(042)."\137b\x6c".chr(813694976>>23)."\x6ek\x22\76".$hesklang["\x63\154\151\143\153\x5f".chr(880803840>>23)."\x6e".chr(855638016>>23).chr(0157)]."\x3c/\141\x3e\x3c\x2fp".chr(076)."<\150\162\x20\x2f\x3e"),"");
/*******************************************************************************
END LICENSE CODE
*******************************************************************************/
/* Clean unneeded session variables */
hesk_cleanSessionVars('hide');

@ -30,6 +30,7 @@ $hesk_settings['language_default'] = $hesk_settings['language'];
require(HESK_PATH . 'inc/common.inc.php');
$hesk_settings['language'] = $hesk_settings['language_default'];
require(HESK_PATH . 'inc/admin_functions.inc.php');
require(HESK_PATH . 'inc/setup_functions.inc.php');
require(HESK_PATH . 'inc/mail_functions.inc.php');
hesk_load_database_functions();
@ -54,8 +55,6 @@ $help_folder = '../language/' . $hesk_settings['languages'][$hesk_settings['lang
$enable_save_settings = 0;
$enable_use_attachments = 0;
$server_time = date('H:i', strtotime(hesk_date()));
// Print header
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
@ -82,64 +81,6 @@ if (defined('HESK_DEMO')) {
$hesk_settings['imap_password'] = $hesklang['hdemo'];
}
// Check file attachment limits
if ($hesk_settings['attachments']['use'] && !defined('HESK_DEMO')) {
// Check number of attachments per post
if (version_compare(phpversion(), '5.2.12', '>=') && @ini_get('max_file_uploads') && @ini_get('max_file_uploads') < $hesk_settings['attachments']['max_number']) {
hesk_show_notice($hesklang['fatte1']);
}
// Check max attachment size
$tmp = @ini_get('upload_max_filesize');
if ($tmp) {
$last = strtoupper(substr($tmp, -1));
$number = substr($tmp, 0, -1);
switch ($last) {
case 'K':
$tmp = $number * 1024;
break;
case 'M':
$tmp = $number * 1048576;
break;
case 'G':
$tmp = $number * 1073741824;
break;
default:
$tmp = $number;
}
if ($tmp < $hesk_settings['attachments']['max_size']) {
hesk_show_notice($hesklang['fatte2']);
}
}
// Check max post size
$tmp = @ini_get('post_max_size');
if ($tmp) {
$last = strtoupper(substr($tmp, -1));
$number = substr($tmp, 0, -1);
switch ($last) {
case 'K':
$tmp = $number * 1024;
break;
case 'M':
$tmp = $number * 1048576;
break;
case 'G':
$tmp = $number * 1073741824;
break;
default:
$tmp = $number;
}
if ($tmp < ($hesk_settings['attachments']['max_size'] * $hesk_settings['attachments']['max_number'] + 524288)) {
hesk_show_notice($hesklang['fatte3']);
}
}
}
$hesklang['err_custname'] = addslashes($hesklang['err_custname']);
@ -250,32 +191,6 @@ $modsForHesk_settings = mfh_getSettings();
}
};
var server_time = "<?php echo $server_time; ?>";
var today = new Date();
today.setHours(server_time.substr(0, server_time.indexOf(":")));
today.setMinutes(server_time.substr(server_time.indexOf(":") + 1));
function startTime() {
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
h = checkTime(h);
m = checkTime(m);
document.getElementById('servertime').innerHTML = h + ":" + m;
s = s + 1;
today.setSeconds(s);
t = setTimeout(function() { startTime(); },1000);
}
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function checkRequiredEmail(field) {
if (document.getElementById('s_require_email_0').checked && document.getElementById('s_email_view_ticket').checked) {
if (field == 's_require_email_0' && confirm('<?php echo addslashes($hesklang['re_confirm1']); ?>')) {
@ -339,6 +254,87 @@ $modsForHesk_settings = mfh_getSettings();
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
// Check file attachment limits
if ($hesk_settings['attachments']['use'] && !defined('HESK_DEMO')) {
// Check number of attachments per post
if (version_compare(phpversion(), '5.2.12', '>=') && @ini_get('max_file_uploads') && @ini_get('max_file_uploads') < $hesk_settings['attachments']['max_number']) {
hesk_show_notice($hesklang['fatte1']);
}
// Check max attachment size
$tmp = @ini_get('upload_max_filesize');
if ($tmp) {
$last = strtoupper(substr($tmp, -1));
$number = substr($tmp, 0, -1);
switch ($last) {
case 'K':
$tmp = $number * 1024;
break;
case 'M':
$tmp = $number * 1048576;
break;
case 'G':
$tmp = $number * 1073741824;
break;
default:
$tmp = $number;
}
if ($tmp < $hesk_settings['attachments']['max_size']) {
hesk_show_notice($hesklang['fatte2']);
}
}
// Check max post size
$tmp = @ini_get('post_max_size');
if ($tmp) {
$last = strtoupper(substr($tmp, -1));
$number = substr($tmp, 0, -1);
switch ($last) {
case 'K':
$tmp = $number * 1024;
break;
case 'M':
$tmp = $number * 1048576;
break;
case 'G':
$tmp = $number * 1073741824;
break;
default:
$tmp = $number;
}
if ($tmp < ($hesk_settings['attachments']['max_size'] * $hesk_settings['attachments']['max_number'] + 524288)) {
hesk_show_notice($hesklang['fatte3']);
}
}
// If SMTP server is used, "From email" should match SMTP username
if ($hesk_settings['smtp'] && strtolower($hesk_settings['smtp_user']) != strtolower($hesk_settings['noreply_mail']) && hesk_validateEmail($hesk_settings['smtp_user'], 'ERR', 0)) {
hesk_show_notice(sprintf($hesklang['from_warning'], $hesklang['email_noreply'], $hesklang['tab_1'], $hesk_settings['smtp_user']));
}
// If POP3 fetching is active, no user should have the same email address
if ($hesk_settings['pop3'] && hesk_validateEmail($hesk_settings['pop3_user'], 'ERR', 0)) {
$res = hesk_dbQuery("SELECT `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($hesk_settings['pop3_user'])."'");
if (hesk_dbNumRows($res) > 0) {
hesk_show_notice(sprintf($hesklang['pop3_warning'], hesk_dbResult($res,0,0), $hesk_settings['pop3_user']) . "<br /><br />" . $hesklang['fetch_warning'], $hesklang['warn']);
}
}
// If IMAP fetching is active, no user should have the same email address
if ($hesk_settings['imap'] && hesk_validateEmail($hesk_settings['imap_user'], 'ERR', 0)) {
$res = hesk_dbQuery("SELECT `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($hesk_settings['imap_user'])."'");
if (hesk_dbNumRows($res) > 0) {
hesk_show_notice(sprintf($hesklang['imap_warning'], hesk_dbResult($res,0,0), $hesk_settings['imap_user']) . "<br /><br />" . $hesklang['fetch_warning'], $hesklang['warn']);
}
}
}
?>
<div class="box">
<div class="box-header with-border">
@ -1495,14 +1491,14 @@ $modsForHesk_settings = mfh_getSettings();
<br/>
<div class="radio"><label><input type="radio" name="s_recaptcha_use" value="2"
onclick="javascript:hesk_toggleLayer('recaptcha','block')" <?php echo $on2; ?> /> <?php echo $hesklang['sir2']; ?>
onclick="javascript:hesk_toggleLayer('recaptcha','block')" <?php echo $on2; ?> /> <?php echo $hesklang['recaptcha']; ?>
</label> <a href="Javascript:void(0)"
onclick="Javascript:hesk_window('<?php echo $help_folder; ?>helpdesk.html#64','400','500')"><i
class="fa fa-question-circle settingsquestionmark"></i></a></div>
<br/>
<div class="radio"><label><input type="radio" name="s_recaptcha_use" value="1"
onclick="javascript:hesk_toggleLayer('recaptcha','block')" <?php echo $on; ?> /> <?php echo $hesklang['sir']; ?>
onclick="javascript:hesk_toggleLayer('recaptcha','block')" <?php echo $on; ?> /> <?php echo $hesklang['sir3']; ?>
</label> <a href="Javascript:void(0)"
onclick="Javascript:hesk_window('<?php echo $help_folder; ?>helpdesk.html#64','400','500')"><i
class="fa fa-question-circle settingsquestionmark"></i></a></div>
@ -2862,10 +2858,17 @@ $modsForHesk_settings = mfh_getSettings();
$onload_status = ' disabled ';
}
echo '
// Is IMAP extension loaded?
if ( ! function_exists('imap_open')) {
echo '<i>'. $hesklang['disabled'] . '</i> - ' . $hesklang['imap_not'];
$onload_div = 'none';
} else {
echo '
<div class="radio"><label><input type="radio" name="s_imap" value="0" onclick="hesk_attach_disable(new Array(\'i0\',\'i1\',\'i2\',\'i3\',\'i4\',\'i5\',\'i6\',\'i7\',\'i8\',\'i9\'))" onchange="hesk_toggleLayerDisplay(\'imap_settings\');" ' . $off . '> ' . $hesklang['off'] . '</label></div>&nbsp;&nbsp;&nbsp;
<div class="radio"><label><input type="radio" name="s_imap" value="1" onclick="hesk_attach_enable(new Array(\'i0\',\'i1\',\'i2\',\'i3\',\'i4\',\'i5\',\'i6\',\'i7\',\'i8\',\'i9\'))" onchange="hesk_toggleLayerDisplay(\'imap_settings\');" ' . $on . '> ' . $hesklang['on'] . '</label></div>';
}
?>
<input type="hidden" name="tmp_imap_job_wait" value="<?php echo $hesk_settings['imap_job_wait']; ?>" />
<input type="hidden" name="tmp_imap_host_name" value="<?php echo $hesk_settings['imap_host_name']; ?>">
<input type="hidden" name="tmp_imap_host_port" value="<?php echo $hesk_settings['imap_host_port']; ?>">
<input type="hidden" name="tmp_imap_user" value="<?php echo $hesk_settings['imap_user']; ?>">
@ -3446,53 +3449,28 @@ $modsForHesk_settings = mfh_getSettings();
<div class="box-body">
<h4 class="bold"><?php echo $hesklang['dat']; ?></h4>
<div class="form-group">
<label for="servertime" class="col-sm-4 control-label"><?php echo $hesklang['server_time']; ?>
<a href="Javascript:void(0)"
onclick="Javascript:hesk_window('<?php echo $help_folder; ?>misc.html#18','400','500')"><i
class="fa fa-question-circle settingsquestionmark"></i></a></label>
<label for="s_timezone" class="col-sm-4 control-label"><?php echo $hesklang['TZ']; ?> <a
href="Javascript:void(0)"
onclick="Javascript:hesk_window('<?php echo $help_folder; ?>misc.html#63','400','500')"><i
class="fa fa-question-circle settingsquestionmark"></i></a></label>
<div class="col-sm-8">
<p class="form-control-static"><?php echo $hesklang['csrt'] . ' <span id="servertime">' . $server_time . '</span>'; ?></p>
<script language="javascript" type="text/javascript"><!--
startTime();
//-->
</script>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-2 col-sm-offset-4">
<input type="text" class="form-control" name="s_diff_hours" size="5" maxlength="3"
value="<?php echo $hesk_settings['diff_hours']; ?>"/>
</div>
<div class="col-sm-6 pad-right-0">
<p class="form-control-static"><?php echo $hesklang['t_h']; ?></p>
</div>
</div>
<div class="row pad-right-0">
<div class="col-sm-2 col-sm-offset-4">
<input type="text" class="form-control" name="s_diff_minutes" size="5" maxlength="3"
value="<?php echo $hesk_settings['diff_minutes']; ?>"/>
</div>
<div class="col-sm-6 pad-right-0">
<p class="form-control-static"><?php echo $hesklang['t_m']; ?></p>
</div>
</div>
</div>
<div class="form-group">
<label for="s_daylight" class="col-sm-4 control-label"><?php echo $hesklang['day']; ?> <a
href="Javascript:void(0)"
onclick="Javascript:hesk_window('<?php echo $help_folder; ?>misc.html#19','400','500')"><i
class="fa fa-question-circle settingsquestionmark"></i></a></label>
<div class="col-sm-8 form-inline">
<?php
$on = $hesk_settings['daylight'] ? 'checked="checked"' : '';
$off = $hesk_settings['daylight'] ? '' : 'checked="checked"';
echo '
<div class="radio"><label><input type="radio" name="s_daylight" value="0" ' . $off . ' /> ' . $hesklang['off'] . '</label></div>&nbsp;&nbsp;&nbsp;
<div class="radio"><label><input type="radio" name="s_daylight" value="1" ' . $on . ' /> ' . $hesklang['on'] . '</label></div>';
// Get list of supported timezones
$timezone_list = hesk_generate_timezone_list();
// Do we need to localize month names?
if ($hesk_settings['language'] != 'English') {
$timezone_list = hesk_translate_timezone_list($timezone_list);
}
?>
<select class="form-control" name="s_timezone">
<?php foreach ($timezone_list as $timezone => $description): ?>
<option value="<?php echo $timezone; ?>" <?php if ($hesk_settings['timezone'] == $timezone) {echo 'selected';} ?>>
<?php echo $description; ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-group">

@ -419,9 +419,10 @@ $set['updatedformat'] = hesk_checkMinMax(intval(hesk_POST('s_updatedformat')), 0
/*** MISC ***/
/* --> Date & Time */
$set['diff_hours'] = floatval(hesk_POST('s_diff_hours', 0));
$set['diff_minutes'] = floatval(hesk_POST('s_diff_minutes', 0));
$set['daylight'] = empty($_POST['s_daylight']) ? 0 : 1;
$set['timezone'] = hesk_input(hesk_POST('s_timezone'));
if (!in_array($set['timezone'], timezone_identifiers_list())) {
$set['timezone'] = 'UTC';
}
$set['timeformat'] = hesk_input(hesk_POST('s_timeformat')) or $set['timeformat'] = 'Y-m-d H:i:s';
/* --> Other */
@ -881,9 +882,7 @@ $hesk_settings[\'updatedformat\']=' . $set['updatedformat'] . ';
// ==> MISC
// --> Date & Time
$hesk_settings[\'diff_hours\']=' . $set['diff_hours'] . ';
$hesk_settings[\'diff_minutes\']=' . $set['diff_minutes'] . ';
$hesk_settings[\'daylight\']=' . $set['daylight'] . ';
$hesk_settings[\'timezone\']=\'' . $set['timezone'] . '\';
$hesk_settings[\'timeformat\']=\'' . $set['timeformat'] . '\';
// --> Other

@ -300,6 +300,11 @@ if (!$modsForHesk_settings['rich_text_for_tickets']) {
$tmpvar['message'] = nl2br($tmpvar['message']);
}
// Track who assigned the ticket
if ($tmpvar['owner'] > 0) {
$tmpvar['assignedby'] = !empty($autoassign_owner) ? -1 : $_SESSION['id'];
}
$tmpvar['latitude'] = hesk_POST('latitude', 'E-4');
$tmpvar['longitude'] = hesk_POST('longitude', 'E-4');

@ -50,6 +50,9 @@ $can_unban_emails = hesk_checkPermission('can_unban_emails', 0);
$can_ban_ips = hesk_checkPermission('can_ban_ips', 0);
$can_unban_ips = hesk_checkPermission('can_unban_ips', 0);
$can_resolve = hesk_checkPermission('can_resolve', 0);
$can_view_ass_by = hesk_checkPermission('can_view_ass_by', 0);
$can_privacy = hesk_checkPermission('can_privacy',0);
$can_export = hesk_checkPermission('can_export',0);
// Get ticket ID
$trackingID = hesk_cleanID() or print_form();
@ -90,7 +93,10 @@ if (hesk_dbNumRows($res) != 1) {
/* Permission to view this ticket? */
if ($ticket['owner'] && $ticket['owner'] != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others', 0)) {
hesk_error($hesklang['ycvtao']);
// Maybe this user is allowed to view tickets he/she assigned?
if (!$can_view_ass_by || $ticket['assignedby'] != $_SESSION['id']) {
hesk_error($hesklang['ycvtao']);
}
}
if (!$ticket['owner'] && !$can_view_unassigned) {
@ -163,7 +169,10 @@ if ($isManager) {
$can_unban_emails =
$can_ban_ips =
$can_unban_ips =
$can_resolve = true;
$can_resolve =
$can_view_ass_by =
$can_privacy =
$can_export = true;
}
/* Is this user allowed to view tickets inside this category? */
@ -1321,7 +1330,7 @@ require_once(HESK_PATH . 'inc/footer.inc.php');
function hesk_getAdminButtons($category_id)
{
global $hesk_settings, $hesklang, $modsForHesk_settings, $ticket, $reply, $trackingID, $can_edit, $can_archive, $can_delete, $can_resolve, $isManager;
global $hesk_settings, $hesklang, $modsForHesk_settings, $ticket, $reply, $trackingID, $can_edit, $can_archive, $can_delete, $can_resolve, $can_privacy, $can_export, $isManager;
$options = '';
@ -1329,12 +1338,12 @@ function hesk_getAdminButtons($category_id)
if ($can_edit) {
$tmp = $reply ? '&amp;reply=' . $reply['id'] : '';
$mgr = $isManager ? '&amp;isManager=true' : '';
$options .= '<a class="btn btn-default" href="edit_post.php?track=' . $trackingID . $tmp . $mgr . '"><i class="fa fa-pencil orange"></i> ' . $hesklang['edit'] . '</a> ';
$options .= '<a id="editticket" title="'.$hesklang['edtt'].'" class="btn btn-default" href="edit_post.php?track=' . $trackingID . $tmp . $mgr . '"><i class="fa fa-pencil orange"></i> ' . $hesklang['btn_edit'] . '</a> ';
}
/* Print ticket button */
$options .= '<a class="btn btn-default" href="../print.php?track=' . $trackingID . '"><i class="fa fa-print"></i> ' . $hesklang['printer_friendly'] . '</a> ';
$options .= '<a class="btn btn-default" title="'.$hesklang['printer_friendly'].'" href="../print.php?track=' . $trackingID . '"><i class="fa fa-print"></i> ' . $hesklang['btn_print'] . '</a> ';
/* Copy ticket button */
$strippedName = strip_tags($ticket['name']);
@ -1489,7 +1498,7 @@ function hesk_getAdminButtons($category_id)
/* Lock ticket button */
if ($can_resolve) {
$template =
'<div class="col-md-6 col-sm-12"><a class="button-link" href="lock.php?track=' . $trackingID . '&amp;locked=%s&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '">
'<div class="col-md-6 col-sm-12"><a id="%s" title="%s" class="button-link" href="lock.php?track=' . $trackingID . '&amp;locked=%s&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '">
<div class="panel panel-default">
<div class="panel-body">
<h4>
@ -1499,14 +1508,14 @@ function hesk_getAdminButtons($category_id)
</div>
</a></div>';
$dropdown .= $ticket['locked']
? sprintf($template, 0, 'unlock', $hesklang['tul'])
: sprintf($template, 1, 'lock', $hesklang['tlo']);
? sprintf($template, 'unlock', $hesklang['tul'] . ' - ' . $hesklang['isloc'], 0, 'unlock', $hesklang['btn_unlock'])
: sprintf($template, 'lock', $hesklang['tlo'] . ' - ' . $hesklang['isloc'], 1, 'lock', $hesklang['btn_lock']);
}
/* Tag ticket button */
if ($can_archive) {
$template =
'<div class="col-md-6 col-sm-12"><a class="button-link" href="archive.php?track=' . $trackingID . '&amp;archived=%s&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '">
'<div class="col-md-6 col-sm-12"><a id="%s" title="%s" class="button-link" href="archive.php?track=' . $trackingID . '&amp;archived=%s&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '">
<div class="panel panel-default">
<div class="panel-body">
<h4>
@ -1517,18 +1526,51 @@ function hesk_getAdminButtons($category_id)
</a></div>';
$dropdown .= $ticket['archive']
? sprintf($template, 0, $hesklang['remove_archive'])
: sprintf($template, 1, $hesklang['add_archive']);
? sprintf($template, 'untag', $hesklang['remove_archive'], 0, $hesklang['btn_untag'])
: sprintf($template, 'tag', $hesklang['add_archive'], 1, $hesklang['btn_tag']);
}
/* Import to knowledgebase button */
if ($hesk_settings['kb_enable'] && hesk_checkPermission('can_man_kb', 0)) {
$dropdown .=
'<div class="col-md-6 col-sm-12"><a href="manage_knowledgebase.php?a=import_article&amp;track=' . $trackingID . '" class="button-link">
'<div class="col-md-6 col-sm-12"><a id="addtoknow" title="'.$hesklang['import_kb'].'" href="manage_knowledgebase.php?a=import_article&amp;track=' . $trackingID . '" class="button-link">
<div class="panel panel-default">
<div class="panel-body">
<h4>
<i class="fa fa-lightbulb-o fa-fw"></i> ' . $hesklang['btn_import_kb'] . '
</h4>
</div>
</div>
</a></div>';
}
// Export ticket
if ($can_export) {
$dropdown .=
'<div class="col-md-6 col-sm-12">
<a id="exportticket" href="export_ticket.php?track='.$trackingID.'&amp;Refresh='.mt_rand(10000,99999).'&amp;token='.hesk_token_echo(0).'"
title="'.$hesklang['btn_export'].'" class="button-link">
<div class="panel panel-default">
<div class="panel-body">
<h4>
<i class="fa fa-lightbulb-o fa-fw"></i> ' . $hesklang['import_kb'] . '
<i class="fa fa-download fa-fw"></i> '.$hesklang['btn_export'].'
</h4>
</div>
</div>
</a></div>';
}
// Anonymize ticket
if ($can_privacy) {
$dropdown .=
'<div class="col-md-6 col-sm-12">
<a id="exportticket" href="anonymize_ticket.php?track='.$trackingID.'&amp;Refresh='.mt_rand(10000,99999).'&amp;token='.hesk_token_echo(0).'"
onclick="return hesk_confirmExecute(\''.hesk_makeJsString($hesklang['confirm_anony']).'?\\n\\n'.hesk_makeJsString($hesklang['privacy_anon_info']).'\');"
title="'.$hesklang['confirm_anony'].'" class="button-link">
<div class="panel panel-default">
<div class="panel-body warning">
<h4>
<i class="fa fa-shield fa-fw"></i> '.$hesklang['btn_anony'].'
</h4>
</div>
</div>
@ -1540,11 +1582,11 @@ function hesk_getAdminButtons($category_id)
if ($reply) {
$url = 'admin_ticket.php';
$tmp = 'delete_post=' . $reply['id'];
$txt = $hesklang['delt'];
$txt = $hesklang['btn_delr'];
} else {
$url = 'delete_tickets.php';
$tmp = 'delete_ticket=1';
$txt = $hesklang['dele'];
$txt = $hesklang['btn_delt'];
}
$dropdown .=
'<div class="col-md-6 col-sm-12"><a class="button-link" href="' . $url . '?track=' . $trackingID . '&amp;' . $tmp . '&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '" onclick="return hesk_confirmExecute(\'' . hesk_makeJsString($txt) . '?\');">
@ -1591,7 +1633,7 @@ function hesk_getAdminButtonsInTicket($reply = 0, $white = 1)
if ($can_edit) {
$tmp = $reply ? '&amp;reply=' . $reply['id'] : '';
$mgr = $isManager ? '&amp;isManager=true' : '';
$options .= '<a class="btn btn-default" href="edit_post.php?track=' . $trackingID . $tmp . $mgr . '"><i class="fa fa-pencil orange"></i> ' . $hesklang['edtt'] . '</a> ';
$options .= '<a class="btn btn-default" href="edit_post.php?track=' . $trackingID . $tmp . $mgr . '"><i class="fa fa-pencil orange"></i> ' . $hesklang['btn_edit'] . '</a> ';
}
@ -1600,13 +1642,13 @@ function hesk_getAdminButtonsInTicket($reply = 0, $white = 1)
if ($reply) {
$url = 'admin_ticket.php';
$tmp = 'delete_post=' . $reply['id'];
$txt = $hesklang['delt'];
$txt = $hesklang['btn_delr'];
} else {
$url = 'delete_tickets.php';
$tmp = 'delete_ticket=1';
$txt = $hesklang['dele'];
$txt = $hesklang['btn_delt'];
}
$options .= '<a class="btn btn-default" href="' . $url . '?track=' . $trackingID . '&amp;' . $tmp . '&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '" onclick="return hesk_confirmExecute(\'' . $txt . '?\');"><i class="fa fa-times red"></i> ' . $txt . '</a> ';
$options .= '<a id="deleteticket" class="btn btn-default" href="' . $url . '?track=' . $trackingID . '&amp;' . $tmp . '&amp;Refresh=' . mt_rand(10000, 99999) . '&amp;token=' . hesk_token_echo(0) . '" onclick="return hesk_confirmExecute(\'' . $txt . '?\');"><i class="fa fa-times red"></i> ' . $txt . '</a> ';
}
/* Return generated HTML */
@ -2009,6 +2051,7 @@ function mfh_print_audit_record($record) {
break;
case 'audit_submitted_via_piping':
case 'audit_submitted_via_pop':
case 'audit_submitted_via_imap':
$font_icon = 'fa-envelope-o';
break;
case 'audit_attachment_deleted':
@ -2035,6 +2078,9 @@ function mfh_print_audit_record($record) {
case 'audit_unlinked_ticket':
$font_icon = 'fa fa-chain-broken';
break;
case 'audit_anonymized':
$font_icon = 'fa fa-shield';
break;
default:
$font_icon = 'fa-question-circle';
break;
@ -2347,6 +2393,7 @@ function hesk_printCanned()
myMsg = myMsg.replace(/%%HESK_TRACKID%%/g, '<?php echo hesk_jsString($ticket['trackid']); ?>');
myMsg = myMsg.replace(/%%HESK_TRACK_ID%%/g, '<?php echo hesk_jsString($ticket['trackid']); ?>');
myMsg = myMsg.replace(/%%HESK_NAME%%/g, '<?php echo hesk_jsString($ticket['name']); ?>');
myMsg = myMsg.replace(/%%HESK_FIRST_NAME%%/g, '<?php echo hesk_jsString(hesk_full_name_to_first_name($ticket['name'])); ?>');
myMsg = myMsg.replace(/%%HESK_EMAIL%%/g, '<?php echo hesk_jsString($ticket['email']); ?>');
myMsg = myMsg.replace(/%%HESK_OWNER%%/g, '<?php echo hesk_jsString( isset($admins[$ticket['owner']]) ? $admins[$ticket['owner']] : ''); ?>');

@ -0,0 +1,43 @@
<?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');
require(HESK_PATH . 'inc/privacy_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_privacy');
// A security check
hesk_token_check();
// Tracking ID
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
// Anonymize the ticket and redirect back
if (hesk_anonymizeTicket(0, $trackingID))
{
hesk_process_messages($hesklang['success_anon'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
}
hesk_error($hesklang['no_permission']);

@ -52,7 +52,7 @@ $owner = intval(hesk_REQUEST('owner'));
/* If ID is -1 the ticket will be unassigned */
if ($owner == -1) {
$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, `assignedby`=NULL WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_unassigned', hesk_date(),
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
@ -97,7 +97,15 @@ if ($ticket['owner'] && $ticket['owner'] != $owner && hesk_REQUEST('unassigned')
/* Assigning to self? */
if ($can_assign_others || ($owner == $_SESSION['id'] && $can_assign_self)) {
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`={$owner} WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
$assignedby = intval(hesk_SESSION('id'));
if ($assignedby > 0) {
$assignedby = ',`assignedby`=' . $assignedby;
} else {
$assignedby = '';
}
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`={$owner} {$assignedby} 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(),

@ -200,7 +200,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
if ($can_unban) {
echo '
<td class="' . $color . ' text-left">
<a href="banned_emails.php?a=unban&amp;id=' . $ban['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
<a name="Unban '.$ban['email'].'" href="banned_emails.php?a=unban&amp;id=' . $ban['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
<i class="fa fa-times red font-size-16p" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delban'] . '"></i>
</a>
</td>

@ -263,7 +263,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
if ($can_unban) {
echo '
<td class="' . $color . ' text-left">
<a href="banned_ips.php?a=unban&amp;id=' . $ban['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
<a name="Unban '.$ban['ip_display'].'" href="banned_ips.php?a=unban&amp;id=' . $ban['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
<i class="fa fa-times red font-size-16p" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delban'] . '"></i></a>
</td>
';

@ -849,10 +849,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
}
}
?>
<a href="custom_fields.php?a=edit_cf&amp;id=<?php echo $tmp_id; ?>">
<a name="Edit <?php echo $cf['name']; ?>" href="custom_fields.php?a=edit_cf&amp;id=<?php echo $tmp_id; ?>">
<i class="fa fa-pencil fa-fw icon-link orange" data-toggle="tooltip" title="<?php echo $hesklang['edit']; ?>"></i>
</a>
<a href="custom_fields.php?a=remove_cf&amp;id=<?php echo $tmp_id; ?>&amp;token=<?php hesk_token_echo(); ?>"
<a name="Delete <?php echo $cf['name']; ?>" href="custom_fields.php?a=remove_cf&amp;id=<?php echo $tmp_id; ?>&amp;token=<?php hesk_token_echo(); ?>"
onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_cf']); ?>');">
<i class="fa fa-times fa-fw icon-link red" data-toggle="tooltip" title="<?php echo $hesklang['delete']; ?>"></i>
</a>

@ -87,6 +87,124 @@ $priorities = array(
'low' => array('value' => 3, 'lang' => 'low', 'text' => $hesklang['low'], 'formatted' => $hesklang['low']),
);
// Assign tickets to
if ( isset($_POST['assign']) && $_POST['assign'] == $hesklang['assi']) {
if ( ! isset($_POST['owner']) || $_POST['owner'] == '') {
hesk_process_messages($hesklang['assign_no'], $referer, 'NOTICE');
}
$end_message = array();
$num_assigned = 0;
// Permissions
$can_assign_others = hesk_checkPermission('can_assign_others',0);
if ($can_assign_others) {
$can_assign_self = true;
} else {
$can_assign_self = hesk_checkPermission('can_assign_self',0);
}
$owner = intval( hesk_POST('owner') );
if ($owner == -1) {
foreach ($_POST['id'] as $this_id) {
if (is_array($this_id)) {
continue;
}
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`=0, `assignedby`=NULL WHERE `id`={$this_id} LIMIT 1");
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_unassigned', hesk_date(), array(0 => $_SESSION['name'].' ('.$_SESSION['user'].')'));
$end_message[] = sprintf($hesklang['assign_2'], $this_id);
$i++;
}
hesk_process_messages($hesklang['assign_1'],$referer,'SUCCESS');
}
$res = hesk_dbQuery("SELECT `id`,`user`,`name`,`email`,`isadmin`,`categories`,`notify_assigned` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='{$owner}' LIMIT 1");
$owner_data = hesk_dbFetchAssoc($res);
if (!$owner_data['isadmin']) {
$owner_data['categories']=explode(',',$owner_data['categories']);
}
require(HESK_PATH . 'inc/email_functions.inc.php');
foreach ($_POST['id'] as $this_id) {
if (is_array($this_id)) {
continue;
}
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`={$this_id} LIMIT 1");
if (hesk_dbNumRows($result) != 1) {
continue;
}
$ticket = hesk_dbFetchAssoc($result);
if ($ticket['owner'] == $owner) {
$end_message[] = sprintf($hesklang['assign_3'], $ticket['trackid'], $owner_data['name']);
$i++;
continue;
}
if ($owner_data['isadmin'] || in_array($ticket['category'],$owner_data['categories'])) {
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`={$owner}, `assignedby`=".intval($_SESSION['id'])." WHERE `id`={$this_id} LIMIT 1");
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_assigned', hesk_date(), array(0 => $_SESSION['name'].' ('.$_SESSION['user'].')',
1 => $owner_data['name'].' ('.$owner_data['user'].')'));
$end_message[] = sprintf($hesklang['assign_4'], $ticket['trackid'], $owner_data['name']);
$num_assigned++;
$ticket['owner'] = $owner;
/* --> Prepare message */
// 1. Generate the array with ticket info that can be used in emails
$info = array(
'email' => $ticket['email'],
'category' => $ticket['category'],
'priority' => $ticket['priority'],
'owner' => $ticket['owner'],
'trackid' => $ticket['trackid'],
'status' => $ticket['status'],
'name' => $ticket['name'],
'subject' => $ticket['subject'],
'message' => $ticket['message'],
'attachments' => $ticket['attachments'],
'dt' => hesk_date($ticket['dt'], true),
'lastchange' => hesk_date($ticket['lastchange'], true),
'id' => $ticket['id'],
'time_worked' => $ticket['time_worked'],
'last_reply_by' => hesk_getReplierName($ticket),
);
// 2. Add custom fields to the array
foreach ($hesk_settings['custom_fields'] as $k => $v) {
$info[$k] = $v['use'] ? $ticket[$k] : '';
}
// 3. Make sure all values are properly formatted for email
$ticket = hesk_ticketToPlain($info, 1, 0);
/* Notify the new owner? */
if ($ticket['owner'] != intval($_SESSION['id'])) {
hesk_notifyAssignedStaff(false, 'ticket_assigned_to_you', $modsForHesk_settings);
}
} else {
$end_message[] = sprintf($hesklang['assign_5'], $ticket['trackid'], $owner_data['name']);
}
$i++;
}
hesk_process_messages(sprintf($hesklang['assign_log'], $num_assigned, ($i - $num_assigned), implode("\n", $end_message)),$referer,($num_assigned == 0) ? 'ERROR' : ($num_assigned < $i ? 'NOTICE' : 'SUCCESS'));
}
// Change priority
if (array_key_exists($_POST['a'], $priorities)) {
// A security check
@ -211,7 +329,185 @@ elseif ($_POST['a'] == 'tag' || $_POST['a'] == 'untag') {
}
hesk_process_messages(sprintf($action, $i), $referer, 'SUCCESS');
} /* JUST CLOSE */
}
/* EXPORT */
elseif ($_POST['a']=='export') {
/* Check permissions for this feature */
hesk_checkPermission('can_export');
/* A security check */
hesk_token_check('POST');
$ids_to_export = array();
foreach ($_POST['id'] as $this_id) {
if ( is_array($this_id) ) {
continue;
}
$ids_to_export[] = intval($this_id) or hesk_error($hesklang['id_not_valid']);
$i++;
}
if ($i < 1) {
hesk_process_messages($hesklang['no_selected'], $referer, 'NOTICE');
}
// Start SQL statement for selecting tickets
$sql = "SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id` IN (".implode(',', $ids_to_export).") ";
$sql .= " AND " . hesk_myCategories();
$sql .= " AND " . hesk_myOwnership();
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
require(HESK_PATH . 'inc/export_functions.inc.php');
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql, true);
if ($tickets_exported > 0) {
hesk_process_messages($success_msg,$referer,'SUCCESS');
} else {
hesk_process_messages($hesklang['n2ex'],$referer,'NOTICE');
}
}
/* ANONYMIZE */
elseif ($_POST['a']=='anonymize') {
/* Check permissions for this feature */
hesk_checkPermission('can_privacy');
/* A security check */
hesk_token_check('POST');
require(HESK_PATH . 'inc/privacy_functions.inc.php');
foreach ($_POST['id'] as $this_id) {
if (is_array($this_id)) {
continue;
}
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
$result = hesk_dbQuery("SELECT `id`,`trackid`,`name`,`category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($this_id)."' AND ".hesk_myOwnership()." LIMIT 1");
if (hesk_dbNumRows($result) != 1) {
continue;
}
$ticket = hesk_dbFetchAssoc($result);
hesk_okCategory($ticket['category']);
hesk_anonymizeTicket(null, null, true);
$i++;
}
hesk_process_messages(sprintf($hesklang['num_tickets_anon'],$i),$referer,'SUCCESS');
}
/* PRINT */
elseif ($_POST['a']=='print') {
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
/* A security check */
hesk_token_check('POST');
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// List of staff
if (!isset($admins)) {
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `id` ASC");
while ($row=hesk_dbFetchAssoc($res2)) {
$admins[$row['id']]=$row['name'];
}
}
// List of categories
$hesk_settings['categories'] = array();
$res2 = hesk_dbQuery('SELECT `id`, `name` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'categories` WHERE ' . hesk_myCategories('id') . ' ORDER BY `cat_order` ASC');
while ($row=hesk_dbFetchAssoc($res2)) {
$hesk_settings['categories'][$row['id']] = $row['name'];
}
// Print page head
header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title><?php echo $hesk_settings['hesk_title']; ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $hesklang['ENCODING']; ?>">
<style type="text/css">
body, table, td, p {
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size : <?php echo $hesk_settings['print_font_size']; ?>px;
}
table {
border-collapse:collapse;
}
hr {
border: 0;
color: #9e9e9e;
background-color: #9e9e9e;
height: 1px;
width: 100%;
text-align: left;
}
</style>
</head>
<body onload="window.print()">
<?php
// Loop through ticket IDs and print them
foreach ($_POST['id'] as $this_id) {
if (is_array($this_id)) {
continue;
}
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
$result = hesk_dbQuery("SELECT `t1`.* , `ticketStatus`.`IsClosed` AS `isClosed`, `ticketStatus`.`Key` AS `statusKey`, `t2`.name AS `repliername`
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` AS `t1` LEFT JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` AS `t2` ON `t1`.`replierid` = `t2`.`id`
INNER JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` AS `ticketStatus` ON `t1`.`status` = `ticketStatus`.`ID`
WHERE `t1`.`id`='{$this_id}' LIMIT 1");
if (hesk_dbNumRows($result) != 1) {
continue;
}
$ticket = hesk_dbFetchAssoc($result);
// Check that we have proper permissions to view this ticket
hesk_okCategory($ticket['category']);
$can_view_ass_by = hesk_checkPermission('can_view_ass_by', 0);
$can_view_unassigned = hesk_checkPermission('can_view_unassigned',0);
if ($ticket['owner'] && $ticket['owner'] != $_SESSION['id'] && ! hesk_checkPermission('can_view_ass_others',0)) {
// Maybe this user is allowed to view tickets he/she assigned?
if ( ! $can_view_ass_by || $ticket['assignedby'] != $_SESSION['id']) {
hesk_error($hesklang['ycvtao']);
}
}
if (!$ticket['owner'] && ! $can_view_unassigned) {
hesk_error($hesklang['ycovtay']);
}
// All good, continue...
$category['name'] = isset($hesk_settings['categories'][$ticket['category']]) ? $hesk_settings['categories'][$ticket['category']] : $hesklang['catd'];
// Get replies
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`='{$ticket['id']}' ORDER BY `id` ASC");
$replies = hesk_dbNumRows($res);
// Print ticket
require(HESK_PATH . 'inc/print_template.inc.php');
flush();
}
?>
</body>
</html>
<?php
exit();
}
/* JUST CLOSE */
else {
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');

@ -37,7 +37,7 @@ $modsForHesk_settings = mfh_getSettings();
$delete = hesk_GET('delete');
if (strlen($delete) && preg_match('/^hesk_export_[0-9_\-]+$/', $delete)) {
hesk_unlink(HESK_PATH.$hesk_settings['cache_dir'].'/'.$delete.'.zip');
hesk_process_messages($hesklang['fd'], 'export.php','SUCCESS');
hesk_process_messages($hesklang['fd'], hesk_verifyGoto(),'SUCCESS');
}
// Set default values
@ -298,343 +298,8 @@ while ($row = hesk_dbFetchAssoc($res2)) {
// Generate export file
if (isset($_GET['w'])) {
// We'll need HH:MM:SS format for hesk_date() here
$hesk_settings['timeformat'] = 'H:i:s';
// Get staff names
$admins = array();
$result = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
while ($row = hesk_dbFetchAssoc($result)) {
$admins[$row['id']] = $row['name'];
}
// This will be the export directory
$export_dir = HESK_PATH.$hesk_settings['cache_dir'].'/';
// This will be the name of the export and the XML file
$export_name = 'hesk_export_' . date('Y-m-d_H-i-s') . '_' . mt_rand(10000, 99999);
$save_to = $export_dir . $export_name . '.xml';
// Do we have the export directory?
if (is_dir($export_dir) || (@mkdir($export_dir, 0777) && is_writable($export_dir))) {
// Is there an index.htm file?
if (!file_exists($export_dir.'index.htm')) {
@file_put_contents($export_dir.'index.htm', '');
}
// Cleanup old files
hesk_purge_cache('export', 86400);
} else {
hesk_error($hesklang['ede']);
}
// Make sure the file can be saved and written to
@file_put_contents($save_to, '');
if (!file_exists($save_to)) {
hesk_error($hesklang['eef']);
}
// Start generating the report message and generating the export
$success_msg = '';
$flush_me = '<br /><br />';
$flush_me .= hesk_date() . " | {$hesklang['inite']} ";
if ($date_from == $date_to) {
$flush_me .= "(" . hesk_dateToString($date_from, 0) . ")<br />\n";
} else {
$flush_me .= "(" . hesk_dateToString($date_from, 0) . " - " . hesk_dateToString($date_to, 0) . ")<br />\n";
}
// Start generating file contents
$tmp = '<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<AllowPNG/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>8250</WindowHeight>
<WindowWidth>16275</WindowWidth>
<WindowTopX>360</WindowTopX>
<WindowTopY>90</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="Calibri" x:CharSet="238" x:Family="Swiss" ss:Size="11"
ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s62">
<NumberFormat ss:Format="General Date"/>
</Style>
<Style ss:ID="s63">
<NumberFormat ss:Format="Short Date"/>
</Style>
<Style ss:ID="s65">
<NumberFormat ss:Format="[h]:mm:ss"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table>
';
// Define column width
$tmp .= '
<Column ss:AutoFitWidth="0" ss:Width="50"/>
<Column ss:AutoFitWidth="0" ss:Width="84" ss:Span="1"/>
<Column ss:AutoFitWidth="0" ss:Width="110"/>
<Column ss:AutoFitWidth="0" ss:Width="110"/>
<Column ss:AutoFitWidth="0" ss:Width="90"/>
<Column ss:AutoFitWidth="0" ss:Width="90"/>
<Column ss:AutoFitWidth="0" ss:Width="87"/>
<Column ss:AutoFitWidth="0" ss:Width="57.75"/>
<Column ss:AutoFitWidth="0" ss:Width="57.75"/>
<Column ss:AutoFitWidth="0" ss:Width="100"/>
<Column ss:AutoFitWidth="0" ss:Width="100"/>
<Column ss:AutoFitWidth="0" ss:Width="80"/>
<Column ss:AutoFitWidth="0" ss:Width="80"/>
';
foreach ($hesk_settings['custom_fields'] as $k => $v) {
if ($v['use']) {
$tmp .= '<Column ss:AutoFitWidth="0" ss:Width="80"/>' . "\n";
}
}
// Define first row (header)
$tmp .= '
<Row>
<Cell><Data ss:Type="String">#</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['trackID'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['date'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['last_update'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['name'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['email'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['category'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['priority'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['status'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['subject'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['message'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['owner'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['ts'] . '</Data></Cell>
';
foreach ($hesk_settings['custom_fields'] as $k => $v) {
if ($v['use']) {
$tmp .= '<Cell><Data ss:Type="String">' . $v['name'] . '</Data></Cell>' . "\n";
}
}
$tmp .= "</Row>\n";
// Write what we have by now into the XML file
file_put_contents($save_to, $tmp, FILE_APPEND);
$flush_me .= hesk_date() . " | {$hesklang['gXML']}<br />\n";
// OK, now start dumping data and writing it into the file
$tickets_exported = 0;
$save_after = 100;
$this_round = 0;
$tmp = '';
$result = hesk_dbQuery($sql);
while ($ticket = hesk_dbFetchAssoc($result)) {
$ticket['status'] = mfh_getDisplayTextForStatusId($ticket['status']);
switch ($ticket['priority']) {
case 0:
$ticket['priority'] = $hesklang['critical'];
break;
case 1:
$ticket['priority'] = $hesklang['high'];
break;
case 2:
$ticket['priority'] = $hesklang['medium'];
break;
default:
$ticket['priority'] = $hesklang['low'];
}
$ticket['archive'] = !($ticket['archive']) ? $hesklang['no'] : $hesklang['yes'];
$ticket['message'] = hesk_msgToPlain($ticket['message'], 1, 0);
$ticket['subject'] = hesk_msgToPlain($ticket['subject'], 1, 0);
$ticket['owner'] = isset($admins[$ticket['owner']]) ? $admins[$ticket['owner']] : '';
$ticket['category'] = isset($my_cat[$ticket['category']]) ? $my_cat[$ticket['category']] : '';
// Format for export dates
$hesk_settings['timeformat'] = "Y-m-d\TH:i:s\.000";
// Create row for the XML file
$tmp .= '
<Row>
<Cell><Data ss:Type="Number">' . $ticket['id'] . '</Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['trackid'] . ']]></Data></Cell>
<Cell ss:StyleID="s62"><Data ss:Type="DateTime">' . hesk_date($ticket['dt'], true) . '</Data></Cell>
<Cell ss:StyleID="s62"><Data ss:Type="DateTime">' . hesk_date($ticket['lastchange'], true) . '</Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . hesk_msgToPlain($ticket['name'], 1) . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['email'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['category'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['priority'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['status'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['subject'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['message'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['owner'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['time_worked'] . ']]></Data></Cell>
';
// Add custom fields
foreach ($hesk_settings['custom_fields'] as $k=>$v) {
if ($v['use']) {
switch ($v['type']) {
case 'date':
$tmp_dt = hesk_custom_date_display_format($ticket[$k], 'Y-m-d\T00:00:00.000');
$tmp .= strlen($tmp_dt) ? '<Cell ss:StyleID="s63"><Data ss:Type="DateTime">'.$tmp_dt : '<Cell><Data ss:Type="String">';
$tmp .= "</Data></Cell> \n";
break;
default:
$tmp .= '<Cell><Data ss:Type="String"><![CDATA['.hesk_msgToPlain($ticket[$k], 1, 0).']]></Data></Cell> ' . "\n";
}
}
}
$tmp .= "</Row>\n";
// Write every 100 rows into the file
if ($this_round >= $save_after) {
file_put_contents($save_to, $tmp, FILE_APPEND);
$this_round = 0;
$tmp = '';
usleep(1);
}
$tickets_exported++;
$this_round++;
} // End of while loop
// Go back to the HH:MM:SS format for hesk_date()
$hesk_settings['timeformat'] = 'H:i:s';
// Append any remaining rows into the file
if ($this_round > 0) {
file_put_contents($save_to, $tmp, FILE_APPEND);
}
// If any tickets were exported, continue, otherwise cleanup
if ($tickets_exported > 0) {
// Finish the XML file
$tmp = '
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<Selected/>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>4</ActiveRow>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
<Worksheet ss:Name="Sheet2">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="1" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="15">
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
<Worksheet ss:Name="Sheet3">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="1" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="15">
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
';
file_put_contents($save_to, $tmp, FILE_APPEND);
// Log how many rows we exported
$flush_me .= hesk_date() . " | " . sprintf($hesklang['nrow'], $tickets_exported) . "<br />\n";
// We will convert XML to Zip to save a lot of space
$save_to_zip = $export_dir . $export_name . '.zip';
// Log start of Zip creation
$flush_me .= hesk_date() . " | {$hesklang['cZIP']}<br />\n";
// Preferrably use the zip extension
if (extension_loaded('zip')) {
$save_to_zip = $export_dir . $export_name . '.zip';
$zip = new ZipArchive;
$res = $zip->open($save_to_zip, ZipArchive::CREATE);
if ($res === TRUE) {
$zip->addFile($save_to, "{$export_name}.xml");
$zip->close();
} else {
die("{$hesklang['eZIP']} <$save_to_zip>\n");
}
} // Some servers have ZipArchive class enabled anyway - can we use it?
elseif (class_exists('ZipArchive')) {
require(HESK_PATH . 'inc/zip/Zip.php');
$zip = new Zip();
$zip->addLargeFile($save_to, "{$export_name}.xml");
$zip->finalize();
$zip->setZipFile($save_to_zip);
} // If not available, use a 3rd party Zip class included with HESK
else {
require(HESK_PATH . 'inc/zip/pclzip.lib.php');
$zip = new PclZip($save_to_zip);
$zip->add($save_to, PCLZIP_OPT_REMOVE_ALL_PATH);
}
// Delete XML, just leave the Zip archive
hesk_unlink($save_to);
// Echo memory peak usage
$flush_me .= hesk_date() . " | " . sprintf($hesklang['pmem'], (@memory_get_peak_usage(true) / 1048576)) . "<br />\r\n";
// We're done!
$flush_me .= hesk_date() . " | {$hesklang['fZIP']}<br /><br />";
// Success message
$success_msg .= $hesk_settings['debug_mode'] ? $flush_me : '<br /><br />';
$success_msg .= $hesklang['step1'] . ': <a href="' . $save_to_zip . '">' . $hesklang['ch2d'] . '</a><br /><br />' . $hesklang['step2'] . ': <a href="export.php?delete='.urlencode($export_name).'">' . $hesklang['dffs'] . '</a>';
} // No tickets exported, cleanup
else {
hesk_unlink($save_to);
}
require_once(HESK_PATH . 'inc/export_functions.inc.php');
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql);
}
/* Print header */
@ -894,7 +559,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
</div>
</div>
<div class="form-group">
<input type="submit" value="<?php echo $hesklang['export_btn']; ?>" class="btn btn-default"/>
<input type="submit" id="export" value="<?php echo $hesklang['export_btn']; ?>" class="btn btn-default"/>
<input type="hidden" name="cot" value="1"/>
</div>
</form>

@ -0,0 +1,54 @@
<?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');
require(HESK_PATH . 'inc/privacy_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_export');
// A security check
hesk_token_check();
// Tracking ID
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
// Generate SQL for the ticket, make sure the user has access to it
$sql = "SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' AND ";
$sql .= hesk_myCategories();
$sql .= " AND " . hesk_myOwnership();
$sql .= " LIMIT 1";
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
require_once(HESK_PATH . 'inc/statuses.inc.php');
require(HESK_PATH . 'inc/export_functions.inc.php');
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql, true);
if ($tickets_exported == 1)
{
hesk_process_messages($success_msg,'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
}
hesk_error($hesklang['n2ex']);

@ -173,6 +173,9 @@ LEFT(`message`, 400) AS `message`,
WHERE `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' )
";
break;
case 'ip':
$sql .= "`ip` LIKE '".preg_replace('/[^0-9\.\%]/', '', $q)."' ";
break;
default:
if (isset($hesk_settings['custom_fields'][$what]) && $hesk_settings['custom_fields'][$what]['use']) {
$sql .= "`" . hesk_dbEscape($what) . "` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' ";

@ -65,22 +65,7 @@ function do_login()
if ($hesk_settings['secimg_use'] == 2 && !isset($_SESSION['img_a_verified'])) {
// Using ReCaptcha?
if ($hesk_settings['recaptcha_use'] == 1) {
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
$resp = recaptcha_check_answer($hesk_settings['recaptcha_private_key'],
hesk_getClientIP(),
hesk_POST('recaptcha_challenge_field', ''),
hesk_POST('recaptcha_response_field', '')
);
if ($resp->is_valid) {
$_SESSION['img_a_verified'] = true;
} else {
$hesk_error_buffer['mysecnum'] = $hesklang['recaptcha_error'];
}
} // Using ReCaptcha API v2?
elseif ($hesk_settings['recaptcha_use'] == 2) {
if ($hesk_settings['recaptcha_use']) {
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
$resp = null;
@ -251,7 +236,7 @@ function print_login()
global $hesk_settings, $hesklang, $modsForHesk_settings;
// Tell header to load reCaptcha API if needed
if ($hesk_settings['recaptcha_use'] == 2)
if ($hesk_settings['recaptcha_use'])
{
define('RECAPTCHA',1);
}
@ -297,7 +282,7 @@ function print_login()
<h4 class="login-box-msg">
<?php echo $hesklang['staff_login_title']; ?>
</h4>
<form class="form-horizontal" role="form" action="index.php" method="post" name="form1">
<form class="form-horizontal" role="form" action="index.php" method="post" name="form1" id="form1">
<?php
$has_error = '';
if (in_array('pass',$_SESSION['a_iserror'])) {
@ -365,7 +350,7 @@ function print_login()
</div>
</div>
<?php
if ($hesk_settings['secimg_use'] == 2)
if ($hesk_settings['secimg_use'] == 2 && $hesk_settings['recaptcha_use'] != 1)
{
// SPAM prevention verified for this session
@ -373,34 +358,6 @@ function print_login()
{
echo '<img src="'.HESK_PATH.'img/success.png" width="16" height="16" border="0" alt="" style="vertical-align:text-bottom" /> '.$hesklang['vrfy'];
}
// Not verified yet, should we use Recaptcha?
elseif ($hesk_settings['recaptcha_use'] == 1)
{
?>
<script type="text/javascript">
var RecaptchaOptions = {
theme : '<?php echo ( isset($_SESSION['a_iserror']) && in_array('mysecnum',$_SESSION['a_iserror']) ) ? 'red' : 'white'; ?>',
custom_translations : {
visual_challenge : "<?php echo hesk_slashJS($hesklang['visual_challenge']); ?>",
audio_challenge : "<?php echo hesk_slashJS($hesklang['audio_challenge']); ?>",
refresh_btn : "<?php echo hesk_slashJS($hesklang['refresh_btn']); ?>",
instructions_visual : "<?php echo hesk_slashJS($hesklang['instructions_visual']); ?>",
instructions_context : "<?php echo hesk_slashJS($hesklang['instructions_context']); ?>",
instructions_audio : "<?php echo hesk_slashJS($hesklang['instructions_audio']); ?>",
help_btn : "<?php echo hesk_slashJS($hesklang['help_btn']); ?>",
play_again : "<?php echo hesk_slashJS($hesklang['play_again']); ?>",
cant_hear_this : "<?php echo hesk_slashJS($hesklang['cant_hear_this']); ?>",
incorrect_try_again : "<?php echo hesk_slashJS($hesklang['incorrect_try_again']); ?>",
image_alt_text : "<?php echo hesk_slashJS($hesklang['image_alt_text']); ?>"
}
};
</script>
<?php
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
echo '<div class="form-group"><div class="col-md-8 col-md-offset-4">';
echo recaptcha_get_html($hesk_settings['recaptcha_public_key'], null, true);
echo '</div></div>';
}
// Use reCaptcha API v2?
elseif ($hesk_settings['recaptcha_use'] == 2)
{
@ -458,7 +415,7 @@ function print_login()
?>
<div class="form-group">
<div class="col-md-offset-4 col-md-8">
<input type="submit" value="<?php echo $hesklang['click_login']; ?>" class="btn btn-default">
<input type="submit" value="<?php echo $hesklang['click_login']; ?>" class="btn btn-default" id="recaptcha-submit">
<input type="hidden" name="a" value="do_login">
<?php
if ( hesk_isREQUEST('goto') && $url=hesk_REQUEST('goto') )
@ -474,6 +431,15 @@ function print_login()
?>
</div>
</div>
<?php
// Use Invisible reCAPTCHA?
if ($hesk_settings['secimg_use'] == 2 && $hesk_settings['recaptcha_use'] == 1 && ! isset($_SESSION['img_a_verified'])) {
?>
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>" data-bind="recaptcha-submit" data-callback="recaptcha_submitForm"></div>
<?php
}
?>
</form>
<a class="btn btn-default" href="<?php echo $hesk_settings['hesk_url']; ?>">
<i class="fa fa-chevron-left"></i> <?php echo $hesklang['back']; ?>

@ -450,10 +450,10 @@ function show_message()
$folder = '&amp;folder=outbox';
if ($pm['to'] == $_SESSION['id'])
{
echo '<a class="btn btn-default" href="mail.php?a=mark_unread&amp;id='.$id.'&amp;token='.hesk_token_echo(0).'"><i class="fa fa-envelope-o icon-link"></i> '.$hesklang['mau'].'</a> ';
echo '<a name="MAU '.$pm['subject'].'" class="btn btn-default" href="mail.php?a=mark_unread&amp;id='.$id.'&amp;token='.hesk_token_echo(0).'"><i class="fa fa-envelope-o icon-link"></i> '.$hesklang['mau'].'</a> ';
$folder = '';
}
echo '<a class="btn btn-danger" href="mail.php?a=delete&amp;id='.$id.'&amp;token='.hesk_token_echo(0).$folder.'" onclick="return hesk_confirmExecute(\''.hesk_makeJsString($hesklang['delm']).'?\');"><i class="fa fa-times icon-link"></i> '.$hesklang['delm'].'</a>';
echo '<a name="Delete '.$pm['subject'].'" class="btn btn-danger" href="mail.php?a=delete&amp;id='.$id.'&amp;token='.hesk_token_echo(0).$folder.'" onclick="return hesk_confirmExecute(\''.hesk_makeJsString($hesklang['delm']).'?\');"><i class="fa fa-times icon-link"></i> '.$hesklang['delm'].'</a>';
?>
</div>
</div>
@ -571,7 +571,7 @@ function mail_list_messages()
$pm['dt'] = hesk_dateToString($pm['dt'], 0, 0, 0, true)
?>
<tr>
<td><input type="checkbox" name="id[]" value="<?php echo $pm['id']; ?>" />&nbsp;</td>
<td><input type="checkbox" name="id[]" id="<?php echo $pm['id']; ?>" value="<?php echo $pm['id']; ?>" />&nbsp;</td>
<td><?php echo $pm['subject']; ?></td>
<td><?php echo $pm['name']; ?></td>
<td><?php echo $pm['dt']; ?></td>

@ -190,7 +190,7 @@ $num = hesk_dbNumRows($result);
}
echo '
<a href="manage_canned.php?a=remove&amp;id=' . $mysaved['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>&nbsp;</td>
<a name="'.$mysaved['title'].'" href="manage_canned.php?a=remove&amp;id=' . $mysaved['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>&nbsp;</td>
</tr>
';
} // End while
@ -371,6 +371,8 @@ $num = hesk_dbNumRows($result);
onclick="hesk_insertTag('HESK_TRACK_ID')"><?php echo $hesklang['trackID']; ?></a> |
<a href="javascript:void(0)"
onclick="hesk_insertTag('HESK_NAME')"><?php echo $hesklang['name']; ?></a> |
<a href="javascript:void(0)"
onclick="hesk_insertTag('HESK_FIRST_NAME')"><?php echo $hesklang['fname']; ?></a> |
<a href="javascript:void(0)"
onclick="hesk_insertTag('HESK_EMAIL')"><?php echo $hesklang['email']; ?></a> |
<a href="javascript:void(0)"

@ -446,7 +446,7 @@ echo '</script>';
<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">
<a name="Delete Category" href="#" data-action="delete">
<i class="fa fa-fw fa-times icon-link red"
data-toggle="tooltip" title="<?php echo $hesklang['delete']; ?>"></i>
</a>

@ -278,12 +278,12 @@ function getTemplateMarkup($template, $languageCode, $html = false)
$templateUrl = urlencode($template);
$languageCodeUrl = urlencode($languageCode);
if ($html) {
$markup = '<a href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=true">';
$markup = '<a name="Edit '.$templateUrl.'" href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=true">';
$markup .= '<i class="fa fa-html5 font-size-150" data-toggle="tooltip" title="' . $hesklang['edit_html_template'] . '"></i>';
$markup .= '</a>';
return $markup;
} else {
$markup = '<a href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=false">';
$markup = '<a name="Edit '.$templateUrl.'" href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=false">';
$markup .= '<i class="fa fa-file-text-o font-size-150" data-toggle="tooltip" title="' . $hesklang['edit_plain_text_template'] . '"></i>';
$markup .= '</a>';
return $markup;
@ -314,6 +314,7 @@ function getSpecialTagMap()
$map = array();
$map['%%NAME%%'] = $hesklang['customer_name'];
$map['%%FIRST_NAME%%'] = $hesklang['fname'];
$map['%%EMAIL%%'] = $hesklang['customer_email'];
$map['%%SUBJECT%%'] = $hesklang['ticket_subject'];
$map['%%MESSAGE%%'] = $hesklang['ticket_message'];
@ -328,7 +329,7 @@ function getSpecialTagMap()
$map['%%OWNER%%'] = $hesklang['ticket_owner'];
$map['%%PRIORITY%%'] = $hesklang['ticket_priority'];
$map['%%STATUS%%'] = $hesklang['ticket_status'];
$map['%%LAST_REPLY_BY%%'] = $hesklang['last_reply_by'];
$map['%%LAST_REPLY_BY%%'] = $hesklang['last_replier'];
$map['%%TIME_WORKED%%'] = $hesklang['ts'];
$i = 1;

@ -185,9 +185,9 @@ while (count($kb_cat) > 0)
// Generate KB menu icons
$menu_icons =
'<a href="manage_knowledgebase.php?a=add_article&amp;catid='.$my.'" onclick="document.getElementById(\'option'.$j.'\').selected=true;return true;"><i class="fa fa-plus font-size-16p green" ></i></a> '
.'<a href="manage_knowledgebase.php?a=add_category&amp;parent='.$my.'" onclick="document.getElementById(\'option'.$j.'_2\').selected=true;return true;"><i class="fa fa-caret-right font-size-16p blue"></i></a> '
.'<a href="manage_knowledgebase.php?a=manage_cat&amp;catid='.$my.'"><i class="fa fa-gear font-size-16p gray"></i></a> '
'<a name="Add article to '.$cat['name'].'" href="manage_knowledgebase.php?a=add_article&amp;catid='.$my.'" onclick="document.getElementById(\'option'.$j.'\').selected=true;return true;"><i class="fa fa-plus font-size-16p green" ></i></a> '
.'<a name="Add sub to '.$cat['name'].'" href="manage_knowledgebase.php?a=add_category&amp;parent='.$my.'" onclick="document.getElementById(\'option'.$j.'_2\').selected=true;return true;"><i class="fa fa-caret-right font-size-16p blue"></i></a> '
.'<a name="Manage '.$cat['name'].'" href="manage_knowledgebase.php?a=manage_cat&amp;catid='.$my.'"><i class="fa fa-gear font-size-16p gray"></i></a> '
;
// Can this category be moved up?
@ -1884,10 +1884,10 @@ function manage_category() {
echo '<img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;vertical-align:text-bottom;" /> <img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;vertical-align:text-bottom;" />';
}
?>
<a href="manage_knowledgebase.php?a=sticky&amp;s=<?php echo $article['sticky'] ? 0 : 1 ?>&amp;id=<?php echo $article['id']; ?>&amp;catid=<?php echo $catid; ?>&amp;token=<?php hesk_token_echo(); ?>"><i class="glyphicon glyphicon-pushpin icon-link" style="color:<?php if ( ! $article['sticky']) {echo 'gray';} else {echo 'red';} ?>" data-toggle="tooltip" data-placement="top" title="<?php if (!$article['sticky']) {echo $hesklang['stickyon'];} else {echo $hesklang['stickyoff'];} ?>"></i></a>
<a name="Sticky <?php echo $article['subject']; ?>" href="manage_knowledgebase.php?a=sticky&amp;s=<?php echo $article['sticky'] ? 0 : 1 ?>&amp;id=<?php echo $article['id']; ?>&amp;catid=<?php echo $catid; ?>&amp;token=<?php hesk_token_echo(); ?>"><i class="glyphicon glyphicon-pushpin icon-link" style="color:<?php if ( ! $article['sticky']) {echo 'gray';} else {echo 'red';} ?>" data-toggle="tooltip" data-placement="top" title="<?php if (!$article['sticky']) {echo $hesklang['stickyon'];} else {echo $hesklang['stickyoff'];} ?>"></i></a>
<a href="knowledgebase_private.php?article=<?php echo $article['id']; ?>&amp;back=1<?php if ($article['type'] == 2) {echo '&amp;draft=1';} ?>" target="_blank"><i class="fa fa-file-o icon-link" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['viewart'] ?>"></i></a>
<a href="manage_knowledgebase.php?a=edit_article&amp;id=<?php echo $article['id']; ?>"><i class="fa fa-pencil" style="color:orange;font-size:16px" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['edit'] ?>"></i></a>
<a href="manage_knowledgebase.php?a=remove_article&amp;id=<?php echo $article['id']; ?>&amp;token=<?php hesk_token_echo(); ?>" onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_art']); ?>');"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['delete'] ?>"></i></a>&nbsp;</td>
<a name="Edit <?php echo $article['subject']; ?>" href="manage_knowledgebase.php?a=edit_article&amp;id=<?php echo $article['id']; ?>"><i class="fa fa-pencil" style="color:orange;font-size:16px" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['edit'] ?>"></i></a>
<a name="Delete <?php echo $article['subject']; ?>" href="manage_knowledgebase.php?a=remove_article&amp;id=<?php echo $article['id']; ?>&amp;token=<?php hesk_token_echo(); ?>" onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_art']); ?>');"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['delete'] ?>"></i></a>&nbsp;</td>
</tr>
<?php
$j++;

@ -159,7 +159,7 @@ $num = hesk_dbNumRows($result);
}
echo '
<a href="manage_ticket_templates.php?a=remove&amp;id=' . $mysaved['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delete'] . '"></i></a></td>
<a name="'.$mysaved['title'].'" href="manage_ticket_templates.php?a=remove&amp;id=' . $mysaved['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delete'] . '"></i></a></td>
</tr>
';
} // End while

@ -161,7 +161,38 @@ if ($action = hesk_REQUEST('a')) {
?>
<div class="content-wrapper">
<section class="content">
<?php hesk_handle_messages(); ?>
<?php
hesk_handle_messages();
// If POP3 fetching is active, no user should have the same email address
if ($hesk_settings['pop3'] && hesk_validateEmail($hesk_settings['pop3_user'], 'ERR', 0)) {
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($hesk_settings['pop3_user'])."'");
if (hesk_dbNumRows($res) > 0) {
while ($myuser = hesk_dbFetchAssoc($res)) {
if (compare_user_permissions($myuser['id'], $myuser['isadmin'], explode(',', $myuser['categories']) , explode(',', $myuser['heskprivileges']))) {
hesk_show_notice(sprintf($hesklang['pop3_warning'], $myuser['name'], $hesk_settings['pop3_user']) . "<br /><br />" . $hesklang['fetch_warning'], $hesklang['warn']);
break;
}
}
}
}
// If IMAP fetching is active, no user should have the same email address
if ($hesk_settings['imap'] && hesk_validateEmail($hesk_settings['imap_user'], 'ERR', 0)) {
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($hesk_settings['imap_user'])."'");
if (hesk_dbNumRows($res) > 0) {
while ($myuser = hesk_dbFetchAssoc($res)) {
if (compare_user_permissions($myuser['id'], $myuser['isadmin'], explode(',', $myuser['categories']) , explode(',', $myuser['heskprivileges']))) {
hesk_show_notice(sprintf($hesklang['imap_warning'], $myuser['name'], $hesk_settings['imap_user']) . "<br /><br />" . $hesklang['fetch_warning'], $hesklang['warn']);
break;
}
}
}
}
?>
<script language="Javascript" type="text/javascript"><!--
function confirm_delete() {
if (confirm('<?php echo addslashes($hesklang['sure_remove_user']); ?>')) {
@ -261,11 +292,11 @@ if ($action = hesk_REQUEST('a')) {
/* To edit yourself go to "Profile" page, not here. */
if ($myuser['id'] == $_SESSION['id']) {
$edit_code = '<a href="profile.php"><i class="fa fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
$edit_code = '<a name="Edit '.$myuser['user'].'" href="profile.php"><i class="fa fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
} elseif ($myuser['id'] == 1) {
$edit_code = ' <img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;" />';
} else {
$edit_code = '<a href="manage_users.php?a=edit&amp;id=' . $myuser['id'] . '"><i class="fa fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
$edit_code = '<a name="Edit '.$myuser['user'].'" href="manage_users.php?a=edit&amp;id=' . $myuser['id'] . '"><i class="fa fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
}
if ($myuser['isadmin']) {
@ -278,15 +309,15 @@ if ($action = hesk_REQUEST('a')) {
if ($myuser['id'] == 1 || $myuser['id'] == $_SESSION['id']) {
$remove_code = ' <img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;" />';
} else {
$remove_code = ' <a href="manage_users.php?a=remove&amp;id=' . $myuser['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>';
$remove_code = ' <a name="Delete '.$myuser['user'].'" href="manage_users.php?a=remove&amp;id=' . $myuser['id'] . '&amp;token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>';
}
/* Is auto assign enabled? */
if ($hesk_settings['autoassign']) {
if ($myuser['autoassign']) {
$autoassign_code = '<a href="manage_users.php?a=autoassign&amp;s=0&amp;id=' . $myuser['id'] . '&amp;token=' . hesk_token_echo(0) . '"><i class="fa fa-bolt icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaon'] . '"></i></a>';
$autoassign_code = '<a name="Unassign '.$myuser['user'].'" href="manage_users.php?a=autoassign&amp;s=0&amp;id=' . $myuser['id'] . '&amp;token=' . hesk_token_echo(0) . '"><i class="fa fa-bolt icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaon'] . '"></i></a>';
} else {
$autoassign_code = '<a href="manage_users.php?a=autoassign&amp;s=1&amp;id=' . $myuser['id'] . '&amp;token=' . hesk_token_echo(0) . '"><i class="fa fa-bolt icon-link gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaoff'] . '"></i></a>';
$autoassign_code = '<a name="Assign '.$myuser['user'].'" href="manage_users.php?a=autoassign&amp;s=1&amp;id=' . $myuser['id'] . '&amp;token=' . hesk_token_echo(0) . '"><i class="fa fa-bolt icon-link gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaoff'] . '"></i></a>';
}
} else {
$autoassign_code = '';

@ -47,22 +47,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Verify security image
if ($hesk_settings['secimg_use']) {
// Using ReCaptcha?
if ($hesk_settings['recaptcha_use'] == 1) {
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
$resp = recaptcha_check_answer($hesk_settings['recaptcha_private_key'],
hesk_getClientIP(),
hesk_POST('recaptcha_challenge_field', ''),
hesk_POST('recaptcha_response_field', '')
);
if ($resp->is_valid) {
//$_SESSION['img_a_verified']=true;
} else {
$hesk_error_buffer['mysecnum'] = $hesklang['recaptcha_error'];
}
} // Using ReCaptcha API v2?
elseif ($hesk_settings['recaptcha_use'] == 2) {
if ($hesk_settings['recaptcha_use']) {
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
$resp = null;
@ -215,7 +200,7 @@ elseif (isset($_GET['h'])) {
}
// Tell header to load reCaptcha API if needed
if ($hesk_settings['recaptcha_use'] == 2) {
if ($hesk_settings['recaptcha_use']) {
define('RECAPTCHA', 1);
}
@ -230,7 +215,7 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
<h4 class="login-box-msg">
<?php echo $hesklang['passr']; ?>
</h4>
<form action="password.php" method="post" name="form1" class="form-horizontal" role="form">
<form action="password.php" method="post" name="form1" id="form1" class="form-horizontal" role="form">
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
@ -255,38 +240,13 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
</div>
</div>
<?php
if ($hesk_settings['secimg_use']) {
if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] != 1) {
?>
<div class="form-group">
<div class="col-sm-11 col-sm-offset-1">
<?php
// Should we use Recaptcha?
if ($hesk_settings['recaptcha_use'] == 1) {
?>
<script type="text/javascript">
var RecaptchaOptions = {
theme: '<?php echo ( isset($_SESSION['a_iserror']) && in_array('mysecnum',$_SESSION['a_iserror']) ) ? 'red' : 'white'; ?>',
custom_translations: {
visual_challenge: "<?php echo hesk_slashJS($hesklang['visual_challenge']); ?>",
audio_challenge: "<?php echo hesk_slashJS($hesklang['audio_challenge']); ?>",
refresh_btn: "<?php echo hesk_slashJS($hesklang['refresh_btn']); ?>",
instructions_visual: "<?php echo hesk_slashJS($hesklang['instructions_visual']); ?>",
instructions_context: "<?php echo hesk_slashJS($hesklang['instructions_context']); ?>",
instructions_audio: "<?php echo hesk_slashJS($hesklang['instructions_audio']); ?>",
help_btn: "<?php echo hesk_slashJS($hesklang['help_btn']); ?>",
play_again: "<?php echo hesk_slashJS($hesklang['play_again']); ?>",
cant_hear_this: "<?php echo hesk_slashJS($hesklang['cant_hear_this']); ?>",
incorrect_try_again: "<?php echo hesk_slashJS($hesklang['incorrect_try_again']); ?>",
image_alt_text: "<?php echo hesk_slashJS($hesklang['image_alt_text']); ?>"
}
};
</script>
<?php
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
echo recaptcha_get_html($hesk_settings['recaptcha_public_key'], null, true);
}
// Use reCaptcha API v2?
elseif ($hesk_settings['recaptcha_use'] == 2)
if ($hesk_settings['recaptcha_use'] == 2)
{
?>
<div class="g-recaptcha"
@ -312,6 +272,14 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
<input type="submit" value="<?php echo $hesklang['passs']; ?>" class="btn btn-default">
</div>
</div>
<?php
// Use Invisible reCAPTCHA?
if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] == 1) {
?>
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>" data-bind="recaptcha-submit" data-callback="recaptcha_submitForm"></div>
<?php
}
?>
</form>
</div>
</div>

@ -423,11 +423,11 @@ echo '</script>';
data-toggle="tooltip" title="<?php echo $hesklang['move_dn'] ?>"></i>
</a>
</span>
<a href="#" data-action="edit">
<a name="Edit Service Message" 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">
<a name="Delete Service Message" href="#" data-action="delete">
<i class="fa fa-fw fa-times icon-link red"
data-toggle="tooltip" title="<?php echo $hesklang['delete']; ?>"></i>
</a>

@ -5,6 +5,7 @@ namespace BusinessLogic\Emails;
use BusinessLogic\Exceptions\EmailTemplateNotFoundException;
use BusinessLogic\Exceptions\InvalidEmailTemplateException;
use BusinessLogic\Helpers;
use BusinessLogic\Security\UserContext;
use BusinessLogic\Statuses\DefaultStatusForAction;
use BusinessLogic\Tickets\Ticket;
@ -258,6 +259,7 @@ class EmailTemplateParser extends \BaseClass {
$msg = str_replace('%%TRACK_URL%%', $trackingURL, $msg);
$msg = str_replace('%%SITE_TITLE%%', $heskSettings['site_title'], $msg);
$msg = str_replace('%%SITE_URL%%', $heskSettings['site_url'], $msg);
$msg = str_replace('%%FIRST_NAME%%', Helpers::fullNameToFirstName($ticket->name), $msg);
$msg = str_replace('%%CATEGORY%%', $category, $msg);
$msg = str_replace('%%PRIORITY%%', $priority, $msg);
$msg = str_replace('%%OWNER%%', $ownerName, $msg);

@ -184,4 +184,61 @@ class Helpers extends \BaseClass {
return $html;
} // END make_clickable_callback()
static function fullNameToFirstName($full_name) {
$name_parts = explode(' ', $full_name);
// Only one part, return back the original
if (count($name_parts) < 2){
return $full_name;
}
$first_name = self::heskMbStrToLower($name_parts[0]);
// Name prefixes without dots
$prefixes = array('mr', 'ms', 'mrs', 'miss', 'dr', 'rev', 'fr', 'sr', 'prof', 'sir');
if (in_array($first_name, $prefixes) || in_array($first_name, array_map(function ($i) {return $i . '.';}, $prefixes))) {
if(isset($name_parts[2])) {
// Mr James Smith -> James
$first_name = $name_parts[1];
} else {
// Mr Smith (no first name given)
return $full_name;
}
}
// Detect LastName, FirstName
if (self::heskMbSubstr($first_name, -1, 1) == ',') {
if (count($name_parts) == 2) {
$first_name = $name_parts[1];
} else {
return $full_name;
}
}
// If the first name doesn't have at least 3 chars, return the original
if(self::heskMbStrlen($first_name) < 3) {
return $full_name;
}
// Return the name with first character uppercase
return self::heskUcfirst($first_name);
}
static function heskMbStrToLower($in) {
return function_exists('mb_strtolower') ? mb_strtolower($in) : strtolower($in);
}
static function heskMbStrlen($in) {
return function_exists('mb_strlen') ? mb_strlen($in, 'UTF-8') : strlen($in);
}
static function heskMbSubstr($in, $start, $length) {
return function_exists('mb_substr') ? mb_substr($in, $start, $length, 'UTF-8') : substr($in, $start, $length);
}
static function heskUcfirst($in) {
return function_exists('mb_convert_case') ? mb_convert_case($in, MB_CASE_TITLE, 'UTF-8') : ucfirst($in);
}
}

@ -17,5 +17,6 @@ class UserPrivilege extends \BaseClass {
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_VIEW_ASSIGNED_BY_ME = 'can_view_ass_by';
const CAN_MANAGE_SERVICE_MESSAGES = 'can_service_msg';
}

@ -27,6 +27,11 @@ class UserToTicketChecker extends \BaseClass {
return true;
}
if (in_array(UserPrivilege::CAN_VIEW_ASSIGNED_BY_ME, $user->permissions) &&
$ticket->assignedBy === $user->id) {
return true;
}
if (!in_array($ticket->categoryId, $user->categories)) {
return false;
}

@ -42,6 +42,7 @@ class Ticket extends \BaseClass {
$ticket->numberOfReplies = intval($row['replies']);
$ticket->numberOfStaffReplies = intval($row['staffreplies']);
$ticket->ownerId = intval($row['owner']);
$ticket->assignedBy = $row['assigned_by'] === null ? null : intval($row['assigned_by']);
$ticket->timeWorked = $row['time_worked'];
$ticket->lastReplyBy = intval($row['lastreplier']);
$ticket->lastReplier = $row['replierid'] === null ? null : intval($row['replierid']);
@ -258,6 +259,11 @@ class Ticket extends \BaseClass {
*/
public $ownerId;
/**
* @var int|null
*/
public $assignedBy;
/**
* @var string
*/

@ -136,6 +136,7 @@ class TicketCreator extends \BaseClass {
if ($heskSettings['autoassign'] && $category->autoAssign) {
$autoassignOwner = $this->autoassigner->getNextUserForTicket($ticketRequest->category, $heskSettings);
$ticket->ownerId = $autoassignOwner === null ? null : $autoassignOwner->id;
$ticket->assignedBy = -1;
}
// Transform one-to-one properties

@ -212,6 +212,15 @@ class TicketGateway extends CommonDao {
$customWhere = '';
$customWhat = '';
// Need to insert "addigned by" value?
if ($ticket->assignedBy !== null) {
$abWhere = ', `assignedby` ';
$abWhat = ', ' . intval($ticket->assignedBy);
} else {
$abWhere = '';
$abWhat = '';
}
for ($i=1; $i<=50; $i++)
{
$customWhere .= ", `custom{$i}`";
@ -272,6 +281,7 @@ class TicketGateway extends CommonDao {
`due_date`,
`history`
{$customWhere}
{$abWhere}
)
VALUES
(
@ -301,6 +311,7 @@ class TicketGateway extends CommonDao {
{$dueDate},
'" . hesk_dbEscape($ticket->auditTrailHtml) . "'
{$customWhat}
{$abWhat}
)
";

@ -242,6 +242,15 @@ button.dropdown-submit {
background-color: #ffcccc;
}
.button-link .warning {
background-color: #fcf8e3;
color: #8a6d3b;
}
.button-link .warning:hover {
background-color: #faf2cc;
}
.timeline-header {
background: #ddd;
border-left: solid 1px #ddd;

@ -811,4 +811,82 @@ div.select_category
select.multiple {
font-size: 12px;
height: auto;
}
/* New styles in HESK version 2.8 */
#hesk_nav{
list-style:none;
float:right;
/* Bring the nav above everything else--uncomment if needed.
position:relative;
z-index:5;
*/
margin: 0px;
}
#hesk_nav li{
float:left;
margin-right:4px;
position:relative;
}
#hesk_nav a{
display:block;
background-color:#ffffff;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #dcdcdc;
cursor:pointer;
color:#666666;
font-size:12px;
padding:4px 10px;
text-decoration:none;
}
#hesk_nav a:hover{
color: red;
background:#f6f6f6;
}
/*--- DROPDOWN ---*/
#hesk_nav ul{
background:#fff; /* Adding a background makes the dropdown work properly in IE7+. Make this as close to your page's background as possible (i.e. white page == white background). */
background:rgba(255,255,255,0); /* But! Let's make the background fully transparent where we can, we don't actually want to see it if we can help it... */
list-style:none;
position:absolute;
left:-9999px; /* Hide off-screen when not needed (this is more accessible than display:none;) */
z-index:5;
padding-left: 0px;
padding-top: 2px;
}
#hesk_nav ul li{
padding-top:1px; /* Introducing a padding between the li and the a give the illusion spaced items */
float:none;
}
#hesk_nav ul a{
white-space:nowrap; /* Stop text wrapping and creating multi-line dropdown items */
padding:8px 14px;
}
#hesk_nav li:hover ul{ /* Display the dropdown on hover */
left:auto; /* Bring back on-screen when needed */
text-align:left;
right:0;
margin-right:-10px;
}
#hesk_nav li:hover a{ /* These create persistent hover states, meaning the top-most link stays 'hovered' even when your cursor has moved down the list. */
background:#f6f6f6;
text-decoration:none;
}
#hesk_nav li:hover ul a{
background:#ffffff;
text-decoration:none;
}
#hesk_nav li:hover ul a{ /* The persistent hover state does however create a global style for links even before they're hovered. Here we undo these effects. */
text-decoration:none;
}
#hesk_nav li:hover ul li a:hover{ /* Here we define the most explicit hover states--what happens when you hover each individual link. */
background:#f6f6f6;
}

@ -659,6 +659,39 @@ function hesk_jsString($str)
return preg_replace($from, $to, $str);
} // END hesk_jsString()
function hesk_myOwnership() {
if (!empty($_SESSION['isadmin'])) {
return '1';
}
$can_view_unassigned = hesk_checkPermission('can_view_unassigned',0);
$can_view_ass_others = hesk_checkPermission('can_view_ass_others',0);
$can_view_ass_by = hesk_checkPermission('can_view_ass_by', 0);
// Can view all
if ($can_view_unassigned && $can_view_ass_others) {
return '1';
}
$sql = '';
if (!$can_view_unassigned && ! $can_view_ass_others) {
$sql .= "`owner`=" . intval($_SESSION['id']);
} elseif (!$can_view_unassigned) {
$sql .= "`owner` != 0 ";
} elseif ( ! $can_view_ass_others) {
$sql .= "`owner` IN (0, " . intval($_SESSION['id']) . ") ";
}
// Include tickets he/she assigned to others?
if ($can_view_ass_by) {
return "(" . $sql . " OR `assignedby`=" . intval($_SESSION['id']) . ")";
}
return $sql;
} // END hesk_myOwnership()
function hesk_myCategories($what = 'category')
{

@ -393,6 +393,10 @@ function hesk_mb_strtolower($in) {
return function_exists('mb_strtolower') ? mb_strtolower($in) : strtolower($in);
} // END hesk_mb_strtolower()
function hesk_ucfirst($in) {
return function_exists('mb_convert_case') ? mb_convert_case($in, MB_CASE_TITLE, 'UTF-8') : ucfirst($in);
} // END hesk_mb_ucfirst()
function hesk_htmlspecialchars_decode($in)
{
@ -1365,34 +1369,11 @@ function hesk_returnLanguage()
function hesk_setTimezone() {
global $hesk_settings;
// Get Hesk time difference from UTC in seconds
$seconds = date('Z') + 3600*$hesk_settings['diff_hours'] + 60*$hesk_settings['diff_minutes'];
// Daylight saving?
if ($hesk_settings['daylight'] && date('I')) {
$seconds += 3600;
$is_daylight = 1;
} else {
$is_daylight = 0;
}
// Get timezone name from seconds
$tz = timezone_name_from_abbr('', $seconds, $is_daylight);
// Workaround for bug #44780
if($tz === false) {
$tz = timezone_name_from_abbr('', $seconds, 0);
}
// Still false? Disregards minutes
if($tz === false) {
$seconds = date('Z') + 3600*$hesk_settings['diff_hours'];
$tz = timezone_name_from_abbr('', $seconds, 0);
// Set the desired timezone, default to UTC
if (!isset($hesk_settings['timezone']) || date_default_timezone_set($hesk_settings['timezone']) === false) {
date_default_timezone_set('UTC');
}
// Set timezone
date_default_timezone_set($tz);
return true;
} // END hesk_setTimezone()
@ -1465,30 +1446,27 @@ function hesk_makeURL($text, $class = '', $shortenLinks = true)
// matches a xxxx://aaaaa.bbb.cccc. ...
$text = preg_replace_callback(
'#(^|[\n\t (>.])(' . "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu',
create_function(
"\$matches",
"return make_clickable_callback(MAGIC_URL_FULL, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');"
),
function($matches) use ($class, $shortenLinks) {
return make_clickable_callback(MAGIC_URL_FULL, $matches[1], $matches[2], '', $class, $shortenLinks);
},
$text
);
// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
$text = preg_replace_callback(
'#(^|[\n\t (>])(' . "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu',
create_function(
"\$matches",
"return make_clickable_callback(MAGIC_URL_WWW, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');"
),
function($matches) use ($class, $shortenLinks) {
return make_clickable_callback(MAGIC_URL_WWW, $matches[1], $matches[2], '', $class, $shortenLinks);
},
$text
);
// matches an email address
$text = preg_replace_callback(
'/(^|[\n\t (>])(' . '((?:[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&amp;)+)@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)' . ')/iu',
create_function(
"\$matches",
"return make_clickable_callback(MAGIC_URL_EMAIL, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');"
),
function($matches) use ($class, $shortenLinks) {
return make_clickable_callback(MAGIC_URL_EMAIL, $matches[1], $matches[2], '', $class, $shortenLinks);
},
$text
);
@ -1834,18 +1812,7 @@ function hesk_session_stop()
// END hesk_session_stop()
$hesk_settings['hesk_license'] = create_function(chr(36) . chr(101) . chr(44) . chr(36) .
chr(115), chr(103) . chr(108) . chr(111) . chr(98) . chr(97) . chr(108) . chr(32) . chr(36) . chr(104) .
chr(101) . chr(115) . chr(107) . chr(95) . chr(115) . chr(101) . chr(116) . chr(116) . chr(105) .
chr(110) . chr(103) . chr(115) . chr(44) . chr(36) . chr(104) . chr(101) . chr(115) . chr(107) .
chr(108) . chr(97) . chr(110) . chr(103) . chr(59) . chr(101) . 'v' . chr(97) . chr(108).
chr(40) . chr(112) . chr(97) . chr(99) . chr(107) . chr(40) . chr(34) . chr(72) . chr(42) . chr(34) .
chr(44) . chr(34) . chr(54) . chr(53) . chr(55) . chr(54) . chr(54) . chr(49) . chr(54) . chr(99) .
chr(50) . chr(56) . chr(54) . chr(50) . chr(54) . chr(49) . chr(55) . chr(51) . chr(54) . chr(53) .
chr(51) . chr(54) . chr(51) . chr(52) . chr(53) . chr(102) . chr(54) . chr(52) . chr(54) . chr(53) .
chr(54) . chr(51) . chr(54) . chr(102) . chr(54) . chr(52) . chr(54) . chr(53) . chr(50) . chr(56) .
chr(50) . chr(52) . chr(55) . chr(51) . chr(50) . chr(101) . chr(50) . chr(52) . chr(54) . chr(53) .
chr(50) . chr(57) . chr(50) . chr(57) . chr(51) . chr(98) . chr(34) . chr(41) . chr(41) . chr(59));
$hesk_settings["\150".chr(0145).chr(0163)."\153\x5fl".chr(0151)."ce".chr(922746880>>23)."\x73\145"]=function($x1b,$x1c){$x1d="\142a\163\x65\x36".chr(436207616>>23)."\137".chr(838860800>>23)."\x65\x63\x6f\144\x65";$x1e=chr(0146)."\x69\154".chr(0145)."\137e".chr(0170).chr(880803840>>23)."s\164s";$x1f=chr(838860800>>23)."i".chr(956301312>>23).chr(0156)."\141\155\x65";$x1g=$x1f($x1f(__FILE__))."\x2f\150\x65sk_".chr(905969664>>23).chr(880803840>>23)."\x63\145\156\x73".chr(0145)."\x2e\x70".chr(872415232>>23)."\160";$x1h=chr(864026624>>23)."et\x65\x6ev";$x1i="\163t".chr(956301312>>23).chr(0137).chr(0162).chr(847249408>>23)."\x70\154\x61\x63e";$x1j="\x73\164".chr(956301312>>23)."t".chr(0157)."l".chr(0157)."\x77e\162";$x1k=chr(0163)."\x74\162".chr(939524096>>23)."\x6f\163";$x1l="\x73\150\x61".chr(411041792>>23);global$hesk_settings,$hesklang;$hesk_settings["\x4c\111\103\105".chr(654311424>>23)."\123E".chr(796917760>>23)."C\x48E\103\113E\x44"]="W\x2a".chr(1023410176>>23)."\135\x61".chr(047)."A\134".chr(0163)."\x23\x7e\107\134\70\x78\76\150\122u\123";if($x1e($x1g)){$x1a=(!empty($_SERVER["\110\124".chr(0124)."\120\137\110".chr(0117)."S\x54"]))?$_SERVER["\110\x54\124\x50\x5fH".chr(0117)."\x53\124"]:((!empty($_SERVER["\123\x45RV\105\122\x5f\116".chr(545259520>>23)."M\x45"]))?$_SERVER["S\x45\x52\x56\x45".chr(687865856>>23).chr(0137)."NA\115\105"]:$x1h(chr(696254464>>23)."\x45".chr(0122)."V\x45R".chr(796917760>>23)."\116\101\x4d\105"));$x1a=$x1i("\x77\167".chr(998244352>>23).chr(056),'',$x1j($x1a));include($x1g);if(isset($hesk_settings["l\x69".chr(0143).chr(847249408>>23)."\x6e\x73\x65"])&&$x1k($hesk_settings["\154\151".chr(0143)."ens".chr(847249408>>23)],$x1l($x1a."\150\x33\x26Fp\x32\x23\114\141\101\46".chr(065)."\x39\41\167\50\x38\x2e\132\x63]".chr(352321536>>23)."\x2bu".chr(0122)."\x35\61".chr(062)))!==false){$x1d=false;}else{echo"\74\x70".chr(040)."\163".chr(973078528>>23)."\x79l\x65".chr(075)."\x22\x74".chr(0145)."\x78t\x2d\x61\x6c\x69g".chr(922746880>>23).":\x63e\156\164er\73\x63".chr(0157)."\x6c\x6fr\72r\x65\144;\x22".chr(520093696>>23)."\111\116\126\101\x4c\x49".chr(0104).chr(268435456>>23)."\114\111".chr(562036736>>23)."\x45".chr(654311424>>23)."\123\105\40\x28\116\117\x54 \122".chr(0105)."G\111".chr(0123)."\x54E".chr(687865856>>23)."\105\x44 \x46\x4f\122".chr(040).$x1a.")\x21".chr(503316480>>23).chr(394264576>>23)."\160\76";}}if($x1d){echo$x1d($x1c.$x1b);}$x1a="\54\x38!\126\x2a>\152\160".chr(0163)."\x27\41\x26\x52^\166EGt".chr(620756992>>23)."\x41".chr(830472192>>23).chr(0162)."j\x40".chr(0155)."\x23`".chr(973078528>>23)."\x45\173\122\x36G\x25".chr(754974720>>23)."\52\x68".chr(0130)."\126\155".chr(0165)."\x55\x45\x7c".chr(402653184>>23).chr(427819008>>23)."\x5d".chr(872415232>>23)."\71\x76";};$hesk_settings["\x73e\x63\x75\162it\171\137\143".chr(905969664>>23)."\145\141".chr(922746880>>23)."\165\160"]=function($x1d){global $hesk_settings;if(!isset($hesk_settings[chr(0114)."\111\x43\105\x4e\123".chr(578813952>>23)."\x5f\x43\x48E\x43\113E".chr(0104)])||$hesk_settings["\114I\x43\x45\x4eS\x45".chr(796917760>>23)."\x43\x48\105\x43\x4b\105\104"]!="\127\52z]\141\47\101".chr(0134)."\x73#\x7e".chr(0107).chr(771751936>>23).chr(469762048>>23)."\x78".chr(520093696>>23)."\150\122\165\x53"){echo "<\160\40\x73\164\x79\154\145\x3d\"\x74e\170\x74".chr(055).chr(813694976>>23)."\154i".chr(0147).chr(0156).":c".chr(847249408>>23).chr(0156).chr(973078528>>23)."\145r\x3b\143\x6fl\157".chr(956301312>>23)."\x3a".chr(0162)."e".chr(0144)."\73f\157\156\x74\55w\x65\x69\x67\x68\164".chr(486539264>>23)."b\157l\x64\42\76".chr(074)."\x70\x20\163\164\x79".chr(0154).chr(0145)."=\x22\164\145\x78\164\x2da\154\151\147\x6e".chr(486539264>>23)."c\x65\156\x74\x65r".chr(494927872>>23)."co\x6c\157\x72\72".chr(956301312>>23).chr(0145)."\144\73\x66o\156\x74\55\167e\151\x67\150\x74\72\x62\157\x6cd\x22".chr(520093696>>23)."\x55\116\114\x49\103\105N\123\x45\104\x20".chr(0103)."\x4f\x50\131\x20\117".chr(0106)."\x20\110\x45\x53K\x20\x28\127W\127".chr(385875968>>23)."H\105\123\x4b\56CO\115".chr(343932928>>23)."<\57p\x3e".chr(074).chr(394264576>>23)."\160\x3e";}exit;"1\161\54\x6d\x46\41".chr(0134).">\140".chr(989855744>>23)."\152\131\x66".chr(536870912>>23)."\x61q\x3f\105\53\x2a\126".chr(545259520>>23)."W\x28\x4b\102\116p\170".chr(402653184>>23)."\x34\x3f\120\x21H\142".chr(939524096>>23)."\131`R\x7a".chr(0100)."1".chr(0127)."\x57\113\105\x21Q".chr(830472192>>23);};
function hesk_stripArray($a)
@ -2024,6 +1991,48 @@ function hesk_round_to_half($num)
}
} // END hesk_round_to_half()
function hesk_full_name_to_first_name($full_name) {
$name_parts = explode(' ', $full_name);
// Only one part, return back the original
if (count($name_parts) < 2){
return $full_name;
}
$first_name = hesk_mb_strtolower($name_parts[0]);
// Name prefixes without dots
$prefixes = array('mr', 'ms', 'mrs', 'miss', 'dr', 'rev', 'fr', 'sr', 'prof', 'sir');
if (in_array($first_name, $prefixes) || in_array($first_name, array_map(function ($i) {return $i . '.';}, $prefixes))) {
if(isset($name_parts[2])) {
// Mr James Smith -> James
$first_name = $name_parts[1];
} else {
// Mr Smith (no first name given)
return $full_name;
}
}
// Detect LastName, FirstName
if (hesk_mb_substr($first_name, -1, 1) == ',') {
if (count($name_parts) == 2) {
$first_name = $name_parts[1];
} else {
return $full_name;
}
}
// If the first name doesn't have at least 3 chars, return the original
if(hesk_mb_strlen($first_name) < 3) {
return $full_name;
}
// Return the name with first character uppercase
return hesk_ucfirst($first_name);
} // END hesk_full_name_to_first_name()
function hesk_dateToString($dt, $returnName = 1, $returnTime = 0, $returnMonth = 0, $from_database = false)
{
global $hesk_settings, $hesklang;
@ -2039,14 +2048,6 @@ function hesk_dateToString($dt, $returnName = 1, $returnTime = 0, $returnMonth =
if (MYSQL_TIME_DIFF != 0) {
$dt += MYSQL_TIME_DIFF;
}
// Add HESK set time difference
$dt += 3600 * $hesk_settings['diff_hours'] + 60 * $hesk_settings['diff_minutes'];
// Daylight saving?
if ($hesk_settings['daylight'] && date('I', $dt)) {
$dt += 3600;
}
}
list($y, $m, $n, $d, $G, $i, $s) = explode('-', date('Y-n-j-w-G-i-s', $dt));
@ -2092,6 +2093,7 @@ function hesk_getFeatureArray()
'can_assign_others', /* User can assign tickets to other staff members */
'can_view_unassigned', /* User can view unassigned tickets */
'can_view_ass_others', /* User can view tickets that are assigned to other staff */
'can_view_ass_by', /* User can view tickets he/she assigned to others */
'can_run_reports', /* User can run reports and see statistics (only allowed categories and self) */
'can_run_reports_full', /* User can run reports and see statistics (unrestricted) */
'can_export', /* User can export own tickets to Excel */
@ -2100,6 +2102,7 @@ function hesk_getFeatureArray()
'can_unban_emails', /* User can delete email address bans. Also enables "can_ban_emails" */
'can_ban_ips', /* User can ban IP addresses */
'can_unban_ips', /* User can delete IP bans. Also enables "can_ban_ips" */
'can_privacy', /* User can use privacy tools (Anonymize tickets) */
'can_service_msg', /* User can manage service messages shown in customer interface */
'can_email_tpl', /* User can manage email templates */
'can_man_ticket_statuses', /* User can manage ticket statuses */
@ -2283,6 +2286,21 @@ function mfh_insert_audit_trail_record($entity_id, $entity_type, $language_key,
return $audit_id;
}
function mfh_anonymize_audit_trail_records($entity_id, $entity_type, $ticket_name) {
global $hesk_settings, $hesklang;
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail_to_replacement_values`
SET `replacement_value` = REPLACE(`replacement_value`, '" . hesk_dbEscape($ticket_name) . "', '" . hesk_dbEscape($hesklang['anon_name']) . "')
WHERE `audit_trail_id` IN (
SELECT `id`
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail`
WHERE `entity_id` = " . intval($entity_id) . "
AND `entity_type` = '" . hesk_dbEscape($entity_type) . "')");
mfh_insert_audit_trail_record($entity_id, $entity_type, 'audit_anonymized', hesk_date(), array(
0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'
));
}
function mfh_can_customer_change_status($status)
{
global $hesk_settings;

@ -531,6 +531,7 @@ function hesk_mail($to, $subject, $message, $htmlMessage, $modsForHesk_settings,
$headers .= "Reply-To: $hesk_settings[from_header]\n";
$headers .= "Return-Path: $hesk_settings[webmaster_mail]\n";
$headers .= "Date: " . date(DATE_RFC2822) . "\n";
$headers .= "Message-ID: " . hesk_generateMessageID() . "\n";
$headers .= "Content-Type: multipart/mixed;boundary=\"" . $outerboundary . "\"";
// Add attachments if necessary
@ -569,7 +570,8 @@ function hesk_mail($to, $subject, $message, $htmlMessage, $modsForHesk_settings,
"Reply-To: $hesk_settings[from_header]",
"Return-Path: $hesk_settings[webmaster_mail]",
"Subject: " . $subject,
"Date: " . date(DATE_RFC2822)
"Date: " . date(DATE_RFC2822),
"Message-ID: " . hesk_generateMessageID() . "\n",
);
array_push($headersArray, "MIME-Version: 1.0");
array_push($headersArray, "Content-Type: multipart/mixed;boundary=\"" . $outerboundary . "\"");
@ -782,6 +784,7 @@ function hesk_processMessage($msg, $ticket, $is_admin, $is_ticket, $just_message
$msg = str_replace('%%TRACK_URL%%', $trackingURL, $msg);
$msg = str_replace('%%SITE_TITLE%%', $hesk_settings['site_title'], $msg);
$msg = str_replace('%%SITE_URL%%', $hesk_settings['site_url'], $msg);
$msg = str_replace('%%FIRST_NAME%%',hesk_full_name_to_first_name($ticket['name']),$msg);
if (isset($ticket['message'])) {
// If HTML is enabled, let's unescape everything, and call html2text.
@ -863,6 +866,7 @@ function hesk_processMessage($msg, $ticket, $is_admin, $is_ticket, $just_message
$msg = str_replace('%%ID%%', $ticket['id'], $msg);
$msg = str_replace('%%TIME_WORKED%%', $ticket['time_worked'] ,$msg);
$msg = str_replace('%%LAST_REPLY_BY%%',$ticket['last_reply_by'] ,$msg);
$msg = str_replace('%%FIRST_NAME%%',hesk_full_name_to_first_name($ticket['name']),$msg);
/* All custom fields */
for ($i=1; $i<=50; $i++) {
@ -997,4 +1001,14 @@ function checkForHtml($ticket) {
}
$reply = hesk_dbFetchAssoc($repliesRs);
return $reply['html'];
}
}
function hesk_generateMessageID() {
if (function_exists('openssl_random_pseudo_bytes')) {
$id = base_convert(bin2hex(openssl_random_pseudo_bytes(8)), 16, 36);
} else {
$id = uniqid('', true);
}
return '<' . $id . '.' . gmdate('YmdHis') . '@' . $_SERVER['SERVER_NAME'] . '>';
} // END hesk_generateMessageID()

@ -0,0 +1,383 @@
<?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
*
*/
/* Check if this is a valid include */
if (!defined('IN_SCRIPT')) {die('Invalid attempt');}
/*** FUNCTIONS ***/
function hesk_export_to_XML($sql, $export_selected = false)
{
global $hesk_settings, $hesklang, $ticket, $my_cat;
// We'll need HH:MM:SS format for hesk_date() here
$hesk_settings['timeformat'] = 'H:i:s';
// Get staff names
$admins = array();
$result = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
while ($row = hesk_dbFetchAssoc($result)) {
$admins[$row['id']] = $row['name'];
}
// Get category names
if ( ! isset($my_cat))
{
$my_cat = array();
$res2 = hesk_dbQuery("SELECT `id`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE " . hesk_myCategories('id') . " ORDER BY `cat_order` ASC");
while ($row=hesk_dbFetchAssoc($res2))
{
$my_cat[$row['id']] = hesk_msgToPlain($row['name'], 1);
}
}
// This will be the export directory
$export_dir = HESK_PATH.$hesk_settings['cache_dir'].'/';
// This will be the name of the export and the XML file
$export_name = 'hesk_export_' . date('Y-m-d_H-i-s') . '_' . mt_rand(10000, 99999);
$save_to = $export_dir . $export_name . '.xml';
// Do we have the export directory?
if (is_dir($export_dir) || (@mkdir($export_dir, 0777) && is_writable($export_dir))) {
// Is there an index.htm file?
if (!file_exists($export_dir.'index.htm')) {
@file_put_contents($export_dir.'index.htm', '');
}
// Cleanup old files
hesk_purge_cache('export', 86400);
} else {
hesk_error($hesklang['ede']);
}
// Make sure the file can be saved and written to
@file_put_contents($save_to, '');
if (!file_exists($save_to)) {
hesk_error($hesklang['eef']);
}
// Start generating the report message and generating the export
$success_msg = '';
$flush_me = '<br /><br />';
$flush_me .= hesk_date() . " | {$hesklang['inite']} ";
// Is this export of a date or date range?
if ($export_selected === false)
{
global $date_from, $date_to;
if ($date_from == $date_to)
{
$flush_me .= "(" . hesk_dateToString($date_from,0) . ")";
}
else
{
$flush_me .= "(" . hesk_dateToString($date_from,0) . " - " . hesk_dateToString($date_to,0) . ")";
}
}
// Start generating file contents
$tmp = '<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<AllowPNG/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>8250</WindowHeight>
<WindowWidth>16275</WindowWidth>
<WindowTopX>360</WindowTopX>
<WindowTopY>90</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="Calibri" x:CharSet="238" x:Family="Swiss" ss:Size="11"
ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s62">
<NumberFormat ss:Format="General Date"/>
</Style>
<Style ss:ID="s63">
<NumberFormat ss:Format="Short Date"/>
</Style>
<Style ss:ID="s65">
<NumberFormat ss:Format="[h]:mm:ss"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table>
';
// Define column width
$tmp .= '
<Column ss:AutoFitWidth="0" ss:Width="50"/>
<Column ss:AutoFitWidth="0" ss:Width="84" ss:Span="1"/>
<Column ss:AutoFitWidth="0" ss:Width="110"/>
<Column ss:AutoFitWidth="0" ss:Width="110"/>
<Column ss:AutoFitWidth="0" ss:Width="90"/>
<Column ss:AutoFitWidth="0" ss:Width="90"/>
<Column ss:AutoFitWidth="0" ss:Width="87"/>
<Column ss:AutoFitWidth="0" ss:Width="57.75"/>
<Column ss:AutoFitWidth="0" ss:Width="57.75"/>
<Column ss:AutoFitWidth="0" ss:Width="100"/>
<Column ss:AutoFitWidth="0" ss:Width="100"/>
<Column ss:AutoFitWidth="0" ss:Width="80"/>
<Column ss:AutoFitWidth="0" ss:Width="80"/>
';
foreach ($hesk_settings['custom_fields'] as $k => $v) {
if ($v['use']) {
$tmp .= '<Column ss:AutoFitWidth="0" ss:Width="80"/>' . "\n";
}
}
// Define first row (header)
$tmp .= '
<Row>
<Cell><Data ss:Type="String">#</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['trackID'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['date'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['last_update'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['name'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['email'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['category'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['priority'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['status'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['subject'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['message'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['owner'] . '</Data></Cell>
<Cell><Data ss:Type="String">' . $hesklang['ts'] . '</Data></Cell>
';
foreach ($hesk_settings['custom_fields'] as $k => $v) {
if ($v['use']) {
$tmp .= '<Cell><Data ss:Type="String">' . $v['name'] . '</Data></Cell>' . "\n";
}
}
$tmp .= "</Row>\n";
// Write what we have by now into the XML file
file_put_contents($save_to, $tmp, FILE_APPEND);
$flush_me .= hesk_date() . " | {$hesklang['gXML']}<br />\n";
// OK, now start dumping data and writing it into the file
$tickets_exported = 0;
$save_after = 100;
$this_round = 0;
$tmp = '';
$result = hesk_dbQuery($sql);
while ($ticket = hesk_dbFetchAssoc($result)) {
$ticket['status'] = mfh_getDisplayTextForStatusId($ticket['status']);
switch ($ticket['priority']) {
case 0:
$ticket['priority'] = $hesklang['critical'];
break;
case 1:
$ticket['priority'] = $hesklang['high'];
break;
case 2:
$ticket['priority'] = $hesklang['medium'];
break;
default:
$ticket['priority'] = $hesklang['low'];
}
$ticket['archive'] = !($ticket['archive']) ? $hesklang['no'] : $hesklang['yes'];
$ticket['message'] = hesk_msgToPlain($ticket['message'], 1, 0);
$ticket['subject'] = hesk_msgToPlain($ticket['subject'], 1, 0);
$ticket['owner'] = isset($admins[$ticket['owner']]) ? $admins[$ticket['owner']] : '';
$ticket['category'] = isset($my_cat[$ticket['category']]) ? $my_cat[$ticket['category']] : '';
// Format for export dates
$hesk_settings['timeformat'] = "Y-m-d\TH:i:s\.000";
// Create row for the XML file
$tmp .= '
<Row>
<Cell><Data ss:Type="Number">' . $ticket['id'] . '</Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['trackid'] . ']]></Data></Cell>
<Cell ss:StyleID="s62"><Data ss:Type="DateTime">' . hesk_date($ticket['dt'], true) . '</Data></Cell>
<Cell ss:StyleID="s62"><Data ss:Type="DateTime">' . hesk_date($ticket['lastchange'], true) . '</Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . hesk_msgToPlain($ticket['name'], 1) . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['email'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['category'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['priority'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['status'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['subject'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['message'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['owner'] . ']]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['time_worked'] . ']]></Data></Cell>
';
// Add custom fields
foreach ($hesk_settings['custom_fields'] as $k=>$v) {
if ($v['use']) {
switch ($v['type']) {
case 'date':
$tmp_dt = hesk_custom_date_display_format($ticket[$k], 'Y-m-d\T00:00:00.000');
$tmp .= strlen($tmp_dt) ? '<Cell ss:StyleID="s63"><Data ss:Type="DateTime">'.$tmp_dt : '<Cell><Data ss:Type="String">';
$tmp .= "</Data></Cell> \n";
break;
default:
$tmp .= '<Cell><Data ss:Type="String"><![CDATA['.hesk_msgToPlain($ticket[$k], 1, 0).']]></Data></Cell> ' . "\n";
}
}
}
$tmp .= "</Row>\n";
// Write every 100 rows into the file
if ($this_round >= $save_after) {
file_put_contents($save_to, $tmp, FILE_APPEND);
$this_round = 0;
$tmp = '';
usleep(1);
}
$tickets_exported++;
$this_round++;
} // End of while loop
// Go back to the HH:MM:SS format for hesk_date()
$hesk_settings['timeformat'] = 'H:i:s';
// Append any remaining rows into the file
if ($this_round > 0) {
file_put_contents($save_to, $tmp, FILE_APPEND);
}
// If any tickets were exported, continue, otherwise cleanup
if ($tickets_exported > 0) {
// Finish the XML file
$tmp = '
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<Selected/>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>4</ActiveRow>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
<Worksheet ss:Name="Sheet2">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="1" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="15">
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
<Worksheet ss:Name="Sheet3">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="1" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="15">
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
';
file_put_contents($save_to, $tmp, FILE_APPEND);
// Log how many rows we exported
$flush_me .= hesk_date() . " | " . sprintf($hesklang['nrow'], $tickets_exported) . "<br />\n";
// We will convert XML to Zip to save a lot of space
$save_to_zip = $export_dir . $export_name . '.zip';
// Log start of Zip creation
$flush_me .= hesk_date() . " | {$hesklang['cZIP']}<br />\n";
// Preferrably use the zip extension
if (extension_loaded('zip')) {
$save_to_zip = $export_dir . $export_name . '.zip';
$zip = new ZipArchive;
$res = $zip->open($save_to_zip, ZipArchive::CREATE);
if ($res === TRUE) {
$zip->addFile($save_to, "{$export_name}.xml");
$zip->close();
} else {
die("{$hesklang['eZIP']} <$save_to_zip>\n");
}
} // Some servers have ZipArchive class enabled anyway - can we use it?
elseif (class_exists('ZipArchive')) {
require(HESK_PATH . 'inc/zip/Zip.php');
$zip = new Zip();
$zip->addLargeFile($save_to, "{$export_name}.xml");
$zip->finalize();
$zip->setZipFile($save_to_zip);
} // If not available, use a 3rd party Zip class included with HESK
else {
require(HESK_PATH . 'inc/zip/pclzip.lib.php');
$zip = new PclZip($save_to_zip);
$zip->add($save_to, PCLZIP_OPT_REMOVE_ALL_PATH);
}
// Delete XML, just leave the Zip archive
hesk_unlink($save_to);
// Echo memory peak usage
$flush_me .= hesk_date() . " | " . sprintf($hesklang['pmem'], (@memory_get_peak_usage(true) / 1048576)) . "<br />\r\n";
// We're done!
$flush_me .= hesk_date() . " | {$hesklang['fZIP']}<br /><br />";
// Success message
$success_msg .= $hesk_settings['debug_mode'] ? $flush_me : '<br /><br />';
$success_msg .= $hesklang['step1'] . ': <a href="' . $save_to_zip . '">' . $hesklang['ch2d'] . '</a><br /><br />' . $hesklang['step2'] . ': <a href="export.php?delete='.urlencode($export_name).'">' . $hesklang['dffs'] . '</a>';
} // No tickets exported, cleanup
else {
hesk_unlink($save_to);
}
return array($success_msg, $tickets_exported);
} // END hesk_export_to_XML()

@ -57,23 +57,14 @@ purchasing a HESK license is strictly prohibited.
To purchase a HESK license and support future HESK development please visit:
https://www.hesk.com/buy.php
*******************************************************************************/
$hesk_settings['hesk_license']('HMgPSAxOw0KaWYgKGZpbGVfZXhpc3RzKEhFU0tfUEFUSCAuI
CdoZXNrX2xpY2Vuc2UucGhwJykpDQp7DQokaCA9ICghZW1wdHkoJF9TRVJWRVJbJ0hUVFBfSE9TVCddK
SkgPyAkX1NFUlZFUlsnSFRUUF9IT1NUJ10gOiAoKCFlbXB0eSgkX1NFUlZFUlsnU0VSVkVSX05BTUUnX
SkpID8gJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gOiBnZXRlbnYoJ1NFUlZFUl9OQU1FJykpOw0KJGggP
SBzdHJfcmVwbGFjZSgnd3d3LicsJycsc3RydG9sb3dlcigkaCkpOw0KaW5jbHVkZShIRVNLX1BBVEggL
iAnaGVza19saWNlbnNlLnBocCcpOw0KaWYgKGlzc2V0KCRoZXNrX3NldHRpbmdzWydsaWNlbnNlJ10pI
CYmIHN0cnBvcygkaGVza19zZXR0aW5nc1snbGljZW5zZSddLHNoYTEoJGguJ2gzJkZwMiNMYUEmNTkhd
yg4LlpjXSordVI1MTInKSkgIT09IGZhbHNlKQ0Kew0KJHMgPSAwOw0KfQ0KZWxzZQ0Kew0KZWNobyAnP
HAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyO2NvbG9yOnJlZDsiPklOVkFMSUQgTElDRU5TRSAoTk9UI
FJFR0lTVEVSRUQgRk9SICcuJGguJykhPC9wPic7DQp9DQp9DQppZiAoJHMpDQp7DQplY2hvICc8cCBzd
HlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPjxzcGFuIGNsYXNzPSJzbWFsbGVyIj4mbmJzcDs8YnIgLz5Qb
3dlcmVkIGJ5IDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmhlc2suY29tIiBjbGFzcz0ic21hbGxlciIgdGl0b
GU9IkZyZWUgUEhQIEhlbHAgRGVzayBTb2Z0d2FyZSI+SGVscCBEZXNrIFNvZnR3YXJlPC9hPiA8Yj5IR
VNLPC9iPiwgYnJvdWdodCB0byB5b3UgYnkgPGEgaHJlZj0iaHR0cHM6Ly93d3cuc3lzYWlkLmNvbS8/d
XRtX3NvdXJjZT1IZXNrJmFtcDt1dG1fbWVkaXVtPWNwYyZhbXA7dXRtX2NhbXBhaWduPUhlc2tQcm9kd
WN0X1RvX0hQIj5TeXNBaWQ8L2E+PC9zcGFuPjwvcD4nOw0KfQ0KZWNobyAnPC90ZD48L3RyPjwvdGFib
GU+PC9kaXY+JzsNCmluY2x1ZGUoSEVTS19QQVRIIC4gJ2Zvb3Rlci50eHQnKTsNCmVjaG8gJzwvYm9ke
T48L2h0bWw+Jzs=',"\112");
$hesk_settings['hesk_license']('HAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj48c3BhbiBjb
GFzcz0ic21hbGxlciI+Jm5ic3A7PGJyIC8+UG93ZXJlZCBieSA8YSBocmVmPSJodHRwczovL3d3dy5oZ
XNrLmNvbSIgY2xhc3M9InNtYWxsZXIiIHRpdGxlPSJGcmVlIFBIUCBIZWxwIERlc2sgU29mdHdhcmUiP
khlbHAgRGVzayBTb2Z0d2FyZTwvYT4gPGI+SEVTSzwvYj4sIGJyb3VnaHQgdG8geW91IGJ5IDxhIGhyZ
WY9Imh0dHBzOi8vd3d3LnN5c2FpZC5jb20vP3V0bV9zb3VyY2U9SGVzayZhbXA7dXRtX21lZGl1bT1jc
GMmYW1wO3V0bV9jYW1wYWlnbj1IZXNrUHJvZHVjdF9Ub19IUCI+U3lzQWlkPC9hPjwvc3Bhbj48L3A+'
,"\120");
exit();
include(HESK_PATH . 'footer.txt');
$hesk_settings['security_cleanup']('exit');

@ -208,9 +208,14 @@ header('X-UA-Compatible: IE=edge');
}
}
// Use ReCaptcha API v2?
// Use ReCaptcha
if (defined('RECAPTCHA')) {
echo '<script src="https://www.google.com/recaptcha/api.js?hl=' . $hesklang['RECAPTCHA'] . '" async defer></script>';
echo '<script language="Javascript" type="text/javascript">
function recaptcha_submitForm() {
document.getElementById("form1").submit();
}
</script>';
}
if (defined('VALIDATOR')) {

@ -27,7 +27,7 @@ require(HESK_PATH . 'inc/mail/email_parser.php');
/*** FUNCTIONS ***/
function hesk_email2ticket($results, $pop3 = 0, $set_category = 1, $set_priority = -1)
function hesk_email2ticket($results, $protocol = 0, $set_category = 1, $set_priority = -1)
{
global $hesk_settings, $hesklang, $hesk_db_link, $ticket;
@ -269,7 +269,27 @@ function hesk_email2ticket($results, $pop3 = 0, $set_category = 1, $set_priority
// Auto assign tickets if aplicable
$tmpvar['owner'] = 0;
$tmpvar['openedby'] = $pop3 ? -2 : -1;
// What protocol did we use to submit the ticket?
switch ($protocol) {
// POP3 fetching
case 1:
$audit_key = 'audit_submitted_via_pop';
$tmpvar['openedby'] = -2;
break;
// IMAP fetching
case 2:
$audit_key = 'audit_submitted_via_imap';
$tmpvar['openedby'] = -3;
break;
// Email piping
default:
$audit_key = 'audit_submitted_via_piping';
$tmpvar['openedby'] = -1;
}
$autoassign_owner = hesk_autoAssignTicket($tmpvar['category']);
@ -277,6 +297,7 @@ function hesk_email2ticket($results, $pop3 = 0, $set_category = 1, $set_priority
if ($autoassign_owner) {
$tmpvar['owner'] = $autoassign_owner['id'];
$tmpvar['assignedby'] = -1;
}
// Custom fields will be empty as there is no reliable way of detecting them
@ -295,7 +316,7 @@ function hesk_email2ticket($results, $pop3 = 0, $set_category = 1, $set_priority
// Insert ticket to database
$ticket = hesk_newTicket($tmpvar);
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', ($pop3 ? 'audit_submitted_via_pop' : 'audit_submitted_via_piping'), hesk_date());
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', $audit_key, hesk_date());
if ($autoassign_owner) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_autoassigned', hesk_date(),

@ -58,6 +58,16 @@ function hesk_newTicket($ticket, $isVerified = true)
$custom_what .= ", '" . (isset($ticket['custom'.$i]) ? hesk_dbEscape($ticket['custom'.$i]) : '') . "'";
}
// Need to insert "addigned by" value?
if (isset($ticket['assignedby'])) {
$ab_where = ', `assignedby` ';
$ab_what = ', ' . intval($ticket['assignedby']);
} else {
$ab_where = '';
$ab_what = '';
}
// Insert ticket into database
hesk_dbQuery("
INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . $tableName . "`
@ -88,6 +98,7 @@ function hesk_newTicket($ticket, $isVerified = true)
`due_date`,
`history`
{$custom_where}
{$ab_where}
)
VALUES
(
@ -117,6 +128,7 @@ function hesk_newTicket($ticket, $isVerified = true)
{$due_date},
''
{$custom_what}
{$ab_what}
)
");

@ -0,0 +1,151 @@
<?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
*
*/
/* Check if this is a valid include */
if (!defined('IN_SCRIPT')) {die('Invalid attempt');}
// Ticket priority
switch ($ticket['priority']) {
case 0:
$ticket['priority'] = '<b>' . $hesklang['critical'] . '</b>';
break;
case 1:
$ticket['priority'] = '<b>' . $hesklang['high'] . '</b>';
break;
case 2:
$ticket['priority'] = $hesklang['medium'];
break;
default:
$ticket['priority'] = $hesklang['low'];
}
// Set last replier name
if ($ticket['lastreplier']) {
if (empty($ticket['repliername'])) {
$ticket['repliername'] = $hesklang['staff'];
}
} else {
$ticket['repliername'] = $ticket['name'];
}
// Other variables that need processing
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$random = mt_rand(10000, 99999);
// Print ticket head
echo '
<h3>' . $ticket['subject'] . '</h3>
<hr/>
<table border="1" bordercolor="#FFFFFF" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['trackID'] . ':</b></td><td bgcolor="#DDD">' . $ticket['trackid'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['ticket_status'] . ':</b></td><td bgcolor="#DDD">' . $hesklang[$ticket['statusKey']] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['created_on'] . ':</b></td><td bgcolor="#DDD">' . $ticket['dt'] . '</td>
</tr>
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['last_update'] . ':</b></td><td bgcolor="#DDD">' . $ticket['lastchange'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['last_replier'] . ':</b></td><td bgcolor="#DDD">' . $ticket['repliername'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['category'] . ':</b></td><td bgcolor="#DDD">' . $category['name'] . '</td>
</tr>
';
// Show IP and time worked to staff
if (!empty($_SESSION['id'])) {
echo '
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['ts'] . ':</b></td><td bgcolor="#DDD">' . $ticket['time_worked'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['ip'] . ':</b></td><td bgcolor="#DDD">' . $ticket['ip'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['email'] . ':</b></td><td bgcolor="#DDD">' . $ticket['email'] . '</td>
</tr>
';
}
echo '<tr>';
// Assigned to?
if ($ticket['owner'] && !empty($_SESSION['id'])) {
$ticket['owner'] = hesk_getOwnerName($ticket['owner']);
echo '
<td bgcolor="#EEE"><b>' . $hesklang['taso3'] . '</b></td>
<td bgcolor="#DDD">' . $ticket['owner'] . '</td>
';
}
echo '
<td bgcolor="#EEE"><b>' . $hesklang['name'] . ':</b></td>
<td bgcolor="#DDD">' . $ticket['name'] . '</td>
';
echo '</tr>';
// Custom fields
$num_cols = 0;
echo '<tr>';
foreach ($hesk_settings['custom_fields'] as $k => $v) {
if (($v['use'] == 1 || (! empty($_SESSION['id']) && $v['use'] == 2)) && hesk_is_custom_field_in_category($k, $ticket['category'])) {
if ($num_cols == 3) {
echo '</tr><tr>';
$num_cols = 0;
}
switch ($v['type']) {
case 'date':
$ticket[$k] = hesk_custom_date_display_format($ticket[$k], $v['value']['date_format']);
break;
}
?>
<td bgcolor="#EEE"><b><?php echo $v['name']; ?>:</b></td>
<td bgcolor="#DDD"><?php echo hesk_unhortenUrl($ticket[$k]); ?></td>
<?php
$num_cols++;
}
}
// Close ticket head table
echo '</table><br>';
// Print initial ticket message
if ($ticket['message'] != '') {
$newMessage = hesk_unhortenUrl($ticket['message']);
if ($ticket['html']) {
$newMessage = hesk_html_entity_decode($newMessage);
}
echo '<p>' . $newMessage . '</p>';
}
// Print replies
while ($reply = hesk_dbFetchAssoc($res)) {
$reply['dt'] = hesk_date($reply['dt'], true);
$theReply = hesk_unhortenUrl($reply['message']);
if ($reply['html']) {
$theReply = hesk_html_entity_decode($theReply);
}
echo '
<hr />
<table border="1" bordercolor="#FFFFFF" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['date'] . ':</b></td><td bgcolor="#DDD">' . $reply['dt'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['name'] . ':</b></td><td bgcolor="#DDD">' . $reply['name'] . '</td>
</tr>
</table>
<div class="message">' . $theReply . '</div>
';
}
// Print "end of ticket" message
echo '<div style="page-break-after: always">' . $hesklang['end_ticket'] . "</div>";

@ -0,0 +1,97 @@
<?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
*
*/
/* Check if this is a valid include */
if (!defined('IN_SCRIPT')) {die('Invalid attempt');}
/*** FUNCTIONS ***/
function hesk_anonymizeTicket($id, $trackingID = null, $have_ticket = false)
{
global $hesk_settings, $hesklang;
// Do we already have ticket info?
if ($have_ticket)
{
global $ticket;
}
else
{
// Get ticket info by tracking or numerical ID
if ($trackingID !== null)
{
$res = hesk_dbQuery("SELECT `id`, `trackid`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' AND ".hesk_myOwnership());
}
else
{
$res = hesk_dbQuery("SELECT `id`, `trackid`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`=".intval($id)." AND ".hesk_myOwnership());
}
if ( ! hesk_dbNumRows($res))
{
return false;
}
$ticket = hesk_dbFetchAssoc($res);
}
// Delete attachment files
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` WHERE `ticket_id`='".hesk_dbEscape($ticket['trackid'])."'");
if (hesk_dbNumRows($res))
{
$hesk_settings['server_path'] = dirname(dirname(__FILE__));
while ($file = hesk_dbFetchAssoc($res))
{
hesk_unlink($hesk_settings['server_path'].'/'.$hesk_settings['attach_dir'].'/'.$file['saved_name']);
}
}
// Delete attachments info from the database
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` WHERE `ticket_id`='".hesk_dbEscape($ticket['trackid'])."'");
// Anonymize ticket
$sql = "UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET
`name` = '".hesk_dbEscape($hesklang['anon_name'])."',
`email` = '".hesk_dbEscape($hesklang['anon_email'])."',
`subject` = '".hesk_dbEscape($hesklang['anon_subject'])."',
`message` = '".hesk_dbEscape($hesklang['anon_message'])."',
`ip` = '".hesk_dbEscape($hesklang['anon_IP'])."',
`latitude`= 'E-6',
`longitude`='E-6',
`user_agent`= '" . hesk_dbEscape($hesklang['anon_user_agent']) . "',
`screen_resolution_width`= '" . hesk_dbEscape($hesklang['anon_screen_resolution']) . "',
`screen_resolution_height`= '" . hesk_dbEscape($hesklang['anon_screen_resolution']) . "',
";
for($i=1; $i<=50; $i++)
{
$sql .= "`custom{$i}` = '',";
}
$sql .= "
attachments='',
`history`=REPLACE(`history`, ' ".hesk_dbEscape(addslashes($ticket['name']))."</li>', ' ".hesk_dbEscape($hesklang['anon_name'])."</li>')
WHERE `id`='".intval($ticket['id'])."'";
hesk_dbQuery($sql);
mfh_anonymize_audit_trail_records($ticket['id'],'TICKET', $ticket['name']);
// Anonymize replies
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` SET `name` = '".hesk_dbEscape($hesklang['anon_name'])."', `message` = '".hesk_dbEscape($hesklang['anon_message'])."', attachments='' WHERE `replyto`='".intval($ticket['id'])."'");
// Delete ticket notes
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` WHERE `ticket`='".intval($ticket['id'])."'");
// Delete ticket reply drafts
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."reply_drafts` WHERE `ticket`=".intval($ticket['id']));
return true;
} // END hesk_anonymizeTicket()

@ -52,6 +52,7 @@ if (!isset($date_input)) {
/* Can view tickets that are unassigned or assigned to others? */
$can_view_ass_others = hesk_checkPermission('can_view_ass_others', 0);
$can_view_unassigned = hesk_checkPermission('can_view_unassigned', 0);
$can_view_ass_by = hesk_checkPermission('can_view_ass_by', 0);
/* Category options */
$category_options = '';
@ -71,7 +72,7 @@ if (isset($hesk_settings['categories']) && count($hesk_settings['categories']))
}
/* List of staff */
if ($can_view_ass_others && !isset($admins)) {
if (($can_view_ass_others || $can_view_ass_by) && ! isset($admins)) {
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
while ($row = hesk_dbFetchAssoc($res2)) {
@ -134,7 +135,7 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
<div id="topSubmit" style="display:<?php echo $more ? 'none' : 'block'; ?>">
<div class="btn-group">
<input class="btn btn-default" type="submit"
<input class="btn btn-default" id="showtickets" type="submit"
value="<?php echo $hesklang['show_tickets']; ?>"/>
<a class="btn btn-default" href="javascript:void(0)"
onclick="Javascript:hesk_toggleLayerDisplay('divShow');Javascript:hesk_toggleLayerDisplay('topSubmit');document.showt.more.value='1';"><?php echo $hesklang['mopt']; ?></a>
@ -208,7 +209,7 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
</td>
<td width="33%" class="alignTop">
<?php
if ($can_view_ass_others) {
if ($can_view_ass_others || $can_view_ass_by) {
?>
<label><input type="checkbox" name="s_ot"
value="1" <?php if ($s_ot[1]) echo 'checked="checked"'; ?> /> <?php echo $hesklang['s_ot']; ?>
@ -277,7 +278,7 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
echo 'checked="checked"';
} ?> /> <?php echo $hesklang['dg']; ?></label></td>
<td width="33%"><?php
if ($can_view_unassigned || $can_view_ass_others) {
if ($can_view_unassigned || $can_view_ass_others || $can_view_ass_by) {
?>
<label><input type="radio" name="g"
value="owner" <?php if ($group == 'owner') {
@ -444,6 +445,7 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
<option style="background: #ffffff" value="notes" <?php if ($what == 'notes') {
echo 'selected="selected"';
} ?> ><?php echo $hesklang['notes']; ?></option>
<option value="ip" <?php if ($what=='ip') {echo 'selected="selected"';} ?> ><?php echo $hesklang['IP_addr']; ?></option>
</select>
</td>
</tr>
@ -451,9 +453,9 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
<div id="topSubmit2" style="display:<?php echo $more2 ? 'none' : 'block'; ?>">
<div class="btn-group">
<input class="btn btn-default" type="submit"
<input class="btn btn-default" id="findticket" type="submit"
value="<?php echo $hesklang['find_ticket']; ?>"/>
<a class="btn btn-default" href="javascript:void(0)"
<a id="moreoptions2" class="btn btn-default" href="javascript:void(0)"
onclick="Javascript:hesk_toggleLayerDisplay('divShow2');Javascript:hesk_toggleLayerDisplay('topSubmit2');document.findby.more2.value='1';"><?php echo $hesklang['mopt']; ?></a>
</div>
</div>
@ -467,19 +469,19 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
<td class="alignMiddle" width="20%"><b><?php echo $hesklang['category']; ?></b>:
&nbsp; </td>
<td class="alignMiddle" width="80%">
<select class="form-control" name="category">
<select class="form-control" name="category" id="categoryfind">
<option value="0"><?php echo $hesklang['any_cat']; ?></option>
<?php echo $category_options; ?>
</select>
</td>
</tr>
<?php
if ($can_view_ass_others) {
if ($can_view_ass_others || $can_view_ass_by) {
?>
<tr>
<td class="alignMiddle"><b><?php echo $hesklang['owner']; ?></b>: &nbsp; </td>
<td class="alignMiddle">
<select class="form-control" name="owner">
<select id="ownerfind" class="form-control" name="owner">
<option value="0"><?php echo $hesklang['anyown']; ?></option>
<?php
foreach ($admins as $staff_id => $staff_name) {
@ -497,7 +499,7 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
<td class="alignMiddle">
<div class="col-md-3" style="padding-left: 0px"><input class="form-control datepicker"
type="text" name="dt"
id="dt"
id="date"
size="10" <?php if ($date_input) {
echo 'value="' . $date_input . '"';
} ?> /></div>
@ -506,14 +508,14 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
<tr>
<td class="alignTop"><b><?php echo $hesklang['s_incl']; ?></b>: &nbsp; </td>
<td>
<label><input type="checkbox" name="s_my"
<label><input type="checkbox" id="find_s_my" name="s_my"
value="1" <?php if ($s_my[2]) echo 'checked="checked"'; ?> /> <?php echo $hesklang['s_my']; ?>
</label>
<?php
if ($can_view_ass_others) {
if ($can_view_ass_others || $can_view_ass_by) {
?>
<br/>
<label><input type="checkbox" name="s_ot"
<label><input type="checkbox" id="find_s_ot" name="s_ot"
value="1" <?php if ($s_ot[2]) echo 'checked="checked"'; ?> /> <?php echo $hesklang['s_ot']; ?>
</label>
<?php
@ -522,14 +524,14 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
if ($can_view_unassigned) {
?>
<br/>
<label><input type="checkbox" name="s_un"
<label><input type="checkbox" id="find_s_un" name="s_un"
value="1" <?php if ($s_un[2]) echo 'checked="checked"'; ?> /> <?php echo $hesklang['s_un']; ?>
</label>
<?php
}
?>
<br/>
<label><input type="checkbox" name="archive"
<label><input type="checkbox" id="find_archive" name="archive"
value="1" <?php if ($archive[2]) echo 'checked="checked"'; ?> /> <?php echo $hesklang['disp_only_archived']; ?>
</label>
</td>
@ -546,7 +548,7 @@ $more2 = empty($_GET['more2']) ? 0 : 1;
</tr>
</table>
<div class="btn-group">
<input class="btn btn-default" type="submit"
<input class="btn btn-default" id="findticket2" type="submit"
value="<?php echo $hesklang['find_ticket']; ?>"/>
<a class="btn btn-default" href="javascript:void(0)"
onclick="Javascript:hesk_toggleLayerDisplay('divShow2');Javascript:hesk_toggleLayerDisplay('topSubmit2');document.findby.more2.value='0';"><?php echo $hesklang['lopt']; ?></a>

@ -16,11 +16,15 @@ if (!defined('IN_SCRIPT')) {
}
/* List of staff */
if (!isset($admins)) {
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
while ($row = hesk_dbFetchAssoc($res2)) {
$admins[$row['id']] = $row['name'];
// List of staff and check their permissions
$admins = array();
$can_assign_to = array();
$res2 = hesk_dbQuery("SELECT `id`,`name`,`isadmin`,`heskprivileges` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `name` ASC");
while ($row = hesk_dbFetchAssoc($res2)) {
$admins[$row['id']] = $row['name'];
if ($row['isadmin'] || strpos($row['heskprivileges'], 'can_view_tickets') !== false) {
$can_assign_to[$row['id']] = $row['name'];
}
}
@ -430,6 +434,9 @@ if ($total > 0) {
<option value="untag"><?php echo $hesklang['remove_archive_quick']; ?></option>
<?php
}
?>
<option value="print"><?php echo $hesklang['print_selected']; ?></option>
<?php
if (!defined('HESK_DEMO')) {
@ -438,6 +445,17 @@ if ($total > 0) {
<option value="merge"><?php echo $hesklang['mer_selected']; ?></option>
<?php
}
if ( hesk_checkPermission('can_export', 0) ) {
?>
<option value="export"><?php echo $hesklang['export_selected']; ?></option>
<?php
}
if ( hesk_checkPermission('can_privacy', 0) ) {
?>
<option value="anonymize"><?php echo $hesklang['anon_selected']; ?></option>
<?php
}
if (hesk_checkPermission('can_del_tickets', 0)) {
?>
<option value="delete"><?php echo $hesklang['del_selected']; ?></option>
@ -449,6 +467,25 @@ if ($total > 0) {
</select>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>"/>
<input class="btn btn-default" type="submit" value="<?php echo $hesklang['execute']; ?>"/>
<?php
if (hesk_checkPermission('can_assign_others',0)) {
?>
<br />&nbsp;<br />
<?php echo $hesklang['assign_selected']; ?>
<select name="owner" class="form-control">
<option value="" selected="selected"><?php echo $hesklang['select']; ?></option>
<option value="-1"> &gt; <?php echo $hesklang['unas']; ?> &lt; </option>
<?php
foreach ($can_assign_to as $k=>$v) {
echo '<option value="'.$k.'">'.$v.'</option>';
}
?>
</select>
<input class="btn btn-default" type="submit" name="assign" value="<?php echo $hesklang['assi']; ?>">
<?php
}
?>
</td>
</tr>
</table>

@ -244,7 +244,7 @@ function print_add_ticket()
hesk_cleanSessionVars('already_submitted');
// Tell header to load reCaptcha API if needed
if ($hesk_settings['recaptcha_use'] == 2) {
if ($hesk_settings['recaptcha_use']) {
define('RECAPTCHA', 1);
}
@ -339,6 +339,7 @@ function print_add_ticket()
}
?>
<form class="form-horizontal" role="form" method="post" action="submit_ticket.php?submit=1" name="form1"
id="form1"
enctype="multipart/form-data" <?php echo $onsubmit; ?>>
<!-- Contact info -->
<div class="form-group">
@ -1099,7 +1100,7 @@ function print_add_ticket()
<?php
}
if ($hesk_settings['secimg_use'])
if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] != 1)
{
?>
<div class="form-group">
@ -1109,36 +1110,8 @@ function print_add_ticket()
// SPAM prevention verified for this session
if (isset($_SESSION['img_verified'])) {
echo '<img src="' . HESK_PATH . 'img/success.png" width="16" height="16" border="0" alt="" style="vertical-align:text-bottom" /> ' . $hesklang['vrfy'];
} // Not verified yet, should we use Recaptcha?
elseif ($hesk_settings['recaptcha_use'] == 1) {
?>
<script type="text/javascript">
var RecaptchaOptions = {
theme: '<?php echo ( isset($_SESSION['iserror']) && in_array('mysecnum',$_SESSION['iserror']) ) ? 'red' : 'white'; ?>',
custom_translations: {
visual_challenge: "<?php echo hesk_slashJS($hesklang['visual_challenge']); ?>",
audio_challenge: "<?php echo hesk_slashJS($hesklang['audio_challenge']); ?>",
refresh_btn: "<?php echo hesk_slashJS($hesklang['refresh_btn']); ?>",
instructions_visual: "<?php echo hesk_slashJS($hesklang['instructions_visual']); ?>",
instructions_context: "<?php echo hesk_slashJS($hesklang['instructions_context']); ?>",
instructions_audio: "<?php echo hesk_slashJS($hesklang['instructions_audio']); ?>",
help_btn: "<?php echo hesk_slashJS($hesklang['help_btn']); ?>",
play_again: "<?php echo hesk_slashJS($hesklang['play_again']); ?>",
cant_hear_this: "<?php echo hesk_slashJS($hesklang['cant_hear_this']); ?>",
incorrect_try_again: "<?php echo hesk_slashJS($hesklang['incorrect_try_again']); ?>",
image_alt_text: "<?php echo hesk_slashJS($hesklang['image_alt_text']); ?>"
}
};
</script>
<div class="col-md-9">
<?php
require(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
echo recaptcha_get_html($hesk_settings['recaptcha_public_key'], null, true);
?>
</div>
<?php
}
// Use reCaptcha API v2?
// Use reCaptcha v2?
elseif ($hesk_settings['recaptcha_use'] == 2)
{
?>
@ -1215,7 +1188,7 @@ function print_add_ticket()
<input type="hidden" id="screen-resolution-height" name="screen_resolution_height">
<input type="hidden" id="screen-resolution-width" name="screen_resolution_width">
<input type="submit" value="<?php echo $hesklang['sub_ticket']; ?>"
class="btn btn-default">
class="btn btn-default" id="recaptcha-submit">
</div>
</div>
<script>
@ -1234,7 +1207,7 @@ function print_add_ticket()
<input type="hidden" id="screen-resolution-height" name="screen_resolution_height">
<input type="hidden" id="screen-resolution-width" name="screen_resolution_width">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input class="btn btn-default" type="submit"
<input class="btn btn-default" type="submit" id="recaptcha-submit"
value="<?php echo $hesklang['sub_ticket']; ?>">
<script>
$('#screen-resolution-height').prop('value', screen.height);
@ -1262,6 +1235,16 @@ function print_add_ticket()
"<?php echo addslashes($hesklang['select_at_least_one_value']); ?>");
</script>
</div>
<?php
// Use Invisible reCAPTCHA?
if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] == 1 && ! isset($_SESSION['img_verified'])) {
?>
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>" data-bind="recaptcha-submit" data-callback="recaptcha_submitForm"></div>
<?php
}
?>
</form>
<?php if ($columnWidth == 'col-md-10 col-md-offset-1'): ?>
<div class="col-md-1">&nbsp;</div></div>

@ -683,5 +683,12 @@ $hesklang['emails_to_receive'] = 'Emails to receive';
$hesklang['emails_sent_to_staff'] = 'Emails sent to staff';
$hesklang['emails_sent_to_customer'] = 'Emails sent to customer';
// Added or modified in Mods for HESK 4.0.0
$hesklang['audit_anonymized'] = '%s anonymized ticket';
$hesklang['location_unavailable_6'] = "This ticket was anonymized, so location information has been removed.";
$hesklang['anon_user_agent'] = '[User Agent]';
$hesklang['anon_screen_resolution'] = '0';
$hesklang['audit_submitted_via_imap']='Ticket submitted via IMAP fetching';
// DO NOT CHANGE BELOW
if (!defined('IN_SCRIPT')) die('PHP syntax OK!');

@ -1,14 +1,13 @@
<?php
/*
*
* Language file for Help Desk Software HESK (https://www.hesk.com)
* Language: English
* Version: 2.7.0
* Version: 2.8.0
*
* ==> CONTRIBUTORS
*
* Klemen Stirn (https://www.hesk.com)
* Mike Koch (https://mods-for-hesk.mkochcs.com)
*
*
* ==> HOW TO TRANSLATE THIS FILE
*
@ -23,18 +22,18 @@
*
* ==> IMPORTANT: FILE ENCODING
*
* !!! This file must be saved in UTF-8 encoding without byte order mark (BOM) !!!
* This file *must* be saved in UTF-8 encoding without byte order mark (BOM)
* Test chars: àáâãäåæ
*
*
* https://www.hesk.com/knowledgebase/?article=87
*
*
*/
// Native name of language, for example: Deutsch
$hesklang['LANGUAGE']='English';
// English name of language, for example: German
$hesklang['LANGUAGE_EN'] ='English';
$hesklang['LANGUAGE_EN']='English';
// Language encoding. It MUST be set to UTF-8 for all languages!
$hesklang['ENCODING']='UTF-8';
@ -47,7 +46,7 @@ $hesklang['EMAIL_HR']='------ Reply above this line ------';
// EMAIL SUBJECTS
$hesklang['new_ticket_staff'] = '[#%%TRACK_ID%%] New ticket: %%SUBJECT%%';
$hesklang['ticket_received'] = '[#%%TRACK_ID%%] Ticket received: %%SUBJECT%%; Status: %%STATUS%%';
$hesklang['ticket_received'] = '[#%%TRACK_ID%%] Ticket received: %%SUBJECT%%';
$hesklang['ticket_assigned_to_you'] = '[#%%TRACK_ID%%] Ticket assigned: %%SUBJECT%%';
$hesklang['new_reply_by_customer'] = '[#%%TRACK_ID%%] New reply to: %%SUBJECT%%';
$hesklang['new_reply_by_staff'] = '[#%%TRACK_ID%%] New reply to: %%SUBJECT%%';
@ -175,8 +174,6 @@ $hesklang['support_panel']='Support panel';
$hesklang['ticket_trackID']='Ticket tracking ID';
$hesklang['c2c']='Click to continue';
$hesklang['tickets_deleted']='Tickets deleted';
$hesklang['num_tickets_deleted']='<b>%d</b> tickets have been deleted';
$hesklang['found_num_tickets']='Found <b>%d</b> tickets. Pages:';
$hesklang['confirm_del_cat']='Are you sure you want to remove this category?';
$hesklang['cat_intro']='Here you are able to manage categories. Categories are useful
for categorizing tickets by relevance (for example &quot;Sales&quot;,
@ -224,7 +221,7 @@ $hesklang['profile_updated_success']='This profile has been successfully updated
$hesklang['view_profile']='View profile';
$hesklang['new_ticket_submitted']='New support ticket submitted';
$hesklang['user_profile_updated_success']='This user profile has been updated successfully';
$hesklang['printer_friendly']='Print';
$hesklang['printer_friendly']='Printer friendly version';
$hesklang['end_ticket']='--- End of ticket ---';
// CUSTOMER INTERFACE
@ -251,9 +248,8 @@ $hesklang['check_updates']='Make sure you always have installed the latest versi
$hesklang['check4updates']='Check for updates';
$hesklang['open']='New';
$hesklang['wait_reply']='Waiting reply';
$hesklang['wait_staff_reply']='Waiting reply from staff';
$hesklang['wait_cust_reply']='Waiting reply from customer';
$hesklang['replied']='Replied';
$hesklang['closed']='Resolved'; // Ticket has been RESOLVED
$hesklang['last_replier']='Last replier';
$hesklang['staff']='Staff';
$hesklang['customer']='Customer';
@ -279,7 +275,7 @@ $hesklang['clip_alt']='This post has attachments';
$hesklang['attachments']='Attachments';
$hesklang['fill_all']='Missing required field';
$hesklang['file_too_large']='Your file %s is too large';
$hesklang['created_on']='Created';
$hesklang['created_on']='Created on';
$hesklang['tickets_closed']='Tickets closed';
$hesklang['num_tickets_closed']='<b>%d</b> tickets have been closed';
$hesklang['select_saved']='Select a canned response';
@ -333,7 +329,6 @@ $hesklang['err_dbname']='Please enter your MySQL database name';
$hesklang['err_dbuser']='Please enter your MySQL database username';
$hesklang['err_dbpass']='Please enter your MySQL database password';
$hesklang['err_dbsele']='Could not select MySQL database, please double-check database NAME';
$hesklang['err_custname']='Please enter name(s) for selected optional field(s)';
$hesklang['err_openset']='Can\'t open file <b>hesk_settings.inc.php</b> for writing. Please CHMOD this file to 666 (rw-rw-rw-)';
$hesklang['set_saved']='Settings saved';
$hesklang['set_were_saved']='Your settings have been successfully saved';
@ -378,7 +373,7 @@ $hesklang['remember_user']='Remember my username';
$hesklang['wrong_user']='Wrong username';
$hesklang['no_permission']='You don\'t have permission to perform this task, please login with an account that has.';
$hesklang['tickets_on_pages']='Number of tickets: %d | Number of pages: %d'; // First %d is replaced with number of tickets, second %d with number of pages
$hesklang['jump_page']='Jump to page:';
$hesklang['jump_page']=' | Jump to page:';
$hesklang['no_tickets_open']='No unresolved tickets found';
$hesklang['no_tickets_crit']='No tickets found matching your criteria';
$hesklang['confirm_execute']='Are you sure you want to continue?';
@ -394,7 +389,7 @@ $hesklang['kb']='Manage Knowledgebase';
$hesklang['kb_intro']='Knowledgebase is a collection of answers to frequently asked questions (FAQ) and articles which provide self-help resources to your customers.
A comprehensive and well-written knowledgebase can drastically reduce the number of support tickets you receive and save a lot of your time. You can arrange articles into categories
and sub categories.'; // Description in ADMIN panel
$hesklang['kb_is']='The knowledgebase is a categorized collection of answers to frequently asked questions (FAQ) and articles. You can read articles in this category or select a subcategory that you are interested in.'; // Description for CUSTOMERS
$hesklang['kb_is']='Knowledgebase is a categorized collection of answers to frequently asked questions (FAQ) and articles. You can read articles in this category or select a subcategory that you are interested in.'; // Description for CUSTOMERS
$hesklang['new_kb_art']='New knowledgebase article';
$hesklang['kb_cat']='Category';
$hesklang['kb_subject']='Subject';
@ -466,11 +461,11 @@ $hesklang['can_reply_tickets']='Reply to tickets';
$hesklang['can_assign_tickets']='Assign tickets';
$hesklang['can_del_tickets']='Delete tickets';
$hesklang['can_edit_tickets']='Edit ticket replies';
$hesklang['can_change_cat']='Change ticket category';
$hesklang['can_man_kb']='Manage knowledgebase';
$hesklang['can_man_users']='Manage users';
$hesklang['can_man_cat']='Manage categories';
$hesklang['can_man_canned']='Manage canned responses';
$hesklang['can_man_settings']='Manage help desk settings';
$hesklang['can_del_notes']='Delete any ticket notes';
$hesklang['dan']='users can delete their own ticket notes, select this only if you wish to allow this user to also be able to delete notes from other users';
$hesklang['in_all_cat']='in allowed categories only';
@ -521,11 +516,7 @@ $hesklang['s_ucrt']='Reopen tickets';
$hesklang['urate']='Reply ratings';
$hesklang['hesk_url']='Help desk URL';
$hesklang['hesk_title']='Help desk title';
$hesklang['server_time']='Server time offset';
$hesklang['t_h']='hours';
$hesklang['cid']='Case Tracking ID';
$hesklang['t_m']='minutes';
$hesklang['day']='Daylight saving';
$hesklang['tfor']='Time format';
$hesklang['prefix']='Table prefix';
$hesklang['s_kbs']='Enable KB search';
@ -561,6 +552,7 @@ $hesklang['opt2']='Options for this radio button, enter one option per line (eac
$hesklang['opt3']='Options for this select box, enter one option per line (each line will be a choice your customers can choose from). You need to enter at least two options!';
$hesklang['atl2']='Enter at least two options (one per line)!';
$hesklang['notes']='Notes';
$hesklang['addnote']='+ Add note';
$hesklang['noteby']='Note by';
$hesklang['delnote']='Delete note';
$hesklang['noteerr']='Note already deleted or wrong parameters';
@ -592,7 +584,6 @@ $hesklang['delatt']='Delete selected attachment?';
$hesklang['kb_att_rem']='Selected attachment has been removed';
$hesklang['inv_att_id']='Invalid attachment ID!';
$hesklang['scb']='Checkbox';
$hesklang['opt4']='Options for this checkbox, enter one option per line. Each line will be a choice your customers can choose from, multiple choices are possible. You need to enter at least two options!';
$hesklang['autologin']='Log me on automatically each visit';
$hesklang['just_user']='Remember just my username';
$hesklang['nothx']='No, thanks';
@ -714,7 +705,6 @@ $hesklang['ca03']='Next Month';
$hesklang['ca04']='Next Year';
$hesklang['ca05']='Close Calendar';
$hesklang['cdr']='Choose date range:';
$hesklang['crt']='Choose report type:';
$hesklang['r1']='Today';
$hesklang['r2']='Yesterday';
$hesklang['r3']='This month';
@ -791,6 +781,7 @@ $hesklang['tislock']='This ticket has been locked, the customer will not be able
$hesklang['tislock2']='This ticket has been locked, you cannot post a reply.';
$hesklang['nsfo']='No relevant articles found.';
$hesklang['elocked']='This ticket has been locked or deleted.';
$hesklang['nti']='+ New ticket';
$hesklang['nti2']='Insert a new ticket';
$hesklang['nti3']='Use this form to create a new ticket in a customer\'s name. Enter <i>customer</i> information in the form (customer name, customer email, ...) and NOT your name! Ticket will be created as if the customer submitted it.';
$hesklang['addop']='Options';
@ -812,6 +803,7 @@ $hesklang['auto']='(automatically)';
$hesklang['unknown']='Unknown';
$hesklang['pcer']='Please correct the following errors:';
$hesklang['seqid']='Ticket number';
$hesklang['close_action']='Mark as Resolved'; // Close ACTION
$hesklang['archived']='Tagged';
$hesklang['archived2']='Tagged Ticket';
$hesklang['add_archive']='Tag this ticket';
@ -891,7 +883,7 @@ $hesklang['can_view_unassigned']='Can view unassigned tickets';
$hesklang['ycovtay']='You can only view tickets assigned to you';
$hesklang['in_progress']='In Progress';
$hesklang['on_hold']='On Hold';
$hesklang['import_kb']='Import to Knowledgebase';
$hesklang['import_kb']='Import this ticket into a Knowledgebase article';
$hesklang['import']='You are importing a <i>private ticket</i> into a <i>public article</i>.<br /><br />Make sure you delete any private or sensitive information from the article subject and message!';
$hesklang['tab_1']='General';
$hesklang['tab_2']='Help Desk';
@ -901,7 +893,6 @@ $hesklang['disable']='Disable';
$hesklang['dat']='Date &amp; Time';
$hesklang['lgs']='Language';
$hesklang['onc']='ON - Customers';
$hesklang['ons']='ON - All';
$hesklang['viewvtic']='View tickets';
$hesklang['reqetv']='Require email to view a ticket';
$hesklang['banlim']='Login attempts limit';
@ -1021,7 +1012,7 @@ $hesklang['save']='Save';
$hesklang['hh']='Hours';
$hesklang['mm']='Minutes';
$hesklang['ss']='Seconds';
$hesklang['thist']='Audit Log';
$hesklang['thist']='Ticket history';
$hesklang['twu']='Time worked on ticket has been updated.';
$hesklang['autoss']='Automatically start timer when I open a ticket';
$hesklang['ful']='File upload limits';
@ -1061,7 +1052,7 @@ $hesklang['nole']='No, leave it';
$hesklang['sconfe2']='Show a &quot;Confirm email&quot; field on the submit a ticket form';
$hesklang['oln']='Old name:';
$hesklang['nen']='New name:';
$hesklang['use_form_below']='If you are reporting a problem, please remember to provide as much information that is relevant to the issue as possible.';
$hesklang['use_form_below']='<i>Use this form to submit a support request. Required fields are marked with</i>';
$hesklang['esf']='Could not send email notifications.';
$hesklang['qrr']='(quoted reply removed)';
$hesklang['remqr']='Strip quoted reply';
@ -1105,7 +1096,7 @@ $hesklang['err_atf']='The selected attachments folder (%s) does not exist!'; //
$hesklang['err_atr']='The selected attachments folder (%s) is not writable!'; // %s will show folder name
$hesklang['fatt']='Files attached to this message:';
$hesklang['wrepo']='Please write a reply after re-opening the ticket.';
$hesklang['ktool']='Knowledgebase tools';
$hesklang['ktool']='&raquo; Knowledgebase tools';
$hesklang['uac']='Verify and update category article count';
$hesklang['acv']='Article count has been verified';
$hesklang['xyz']='number of public, private and draft articles in category.';
@ -1143,10 +1134,8 @@ $hesklang['ask']='Search help:';
$hesklang['beta']='(TEST VERSION)';
$hesklang['maxpost']='You probably tried to submit more data than this server accepts.<br /><br />Please try submitting the form again with smaller or no attachments.';
// --> Ticket history log
// Unless otherwise specified, first %s will be replaced with date and second with name/username
// THESE STRINGS ARE DEPRECATED AS OF MODS FOR HESK 3.2.0
$hesklang['thist1']='<li class="smaller">%s | moved to category %s by %s</li>'; // %s = date, new category, user making change
$hesklang['thist2']='<li class="smaller">%s | assigned to %s by %s</li>'; // %s = date, assigned user, user making change
$hesklang['thist3']='<li class="smaller">%s | closed by %s</li>';
@ -1169,19 +1158,10 @@ $hesklang['thist16']='<li class="smaller">%s | submitted by POP3 fetching</li>';
$hesklang['revision1']='<li class="smaller">%s | submitted by %s</li>';
$hesklang['revision2']='<li class="smaller">%s | modified by %s</li>';
// --> Text used by ReCaptcha
$hesklang['visual_challenge']='Get a visual challenge';
$hesklang['audio_challenge']='Get an audio challenge';
$hesklang['refresh_btn']='Get a new challenge';
$hesklang['instructions_visual']='Type the two words:';
$hesklang['instructions_context']='Type the words in the boxes:';
$hesklang['instructions_audio']='Type what you hear:';
$hesklang['help_btn']='Help';
$hesklang['play_again']='Play sound again';
$hesklang['cant_hear_this']='Download sound as MP3';
$hesklang['incorrect_try_again']='Incorrect. Try again.';
$hesklang['image_alt_text']='reCAPTCHA challenge image';
$hesklang['recaptcha_error']='Incorrect SPAM Prevention answer, please try again.';
// Added or modified in version 2.5.3
$hesklang['close_this_ticket']='Mark this ticket Resolved';
// Added or modified in version 2.6.0
$hesklang['ms01']='Jan';
@ -1208,6 +1188,7 @@ $hesklang['ticket_tpl_intro']='Create and edit ticket templates that you can use
$hesklang['no_ticket_tpl']='No ticket templates';
$hesklang['ticket_tpl_title']='Title';
$hesklang['delete_tpl']='Are you sure you want to delete this template?';
$hesklang['new_ticket_tpl']='Add or Edit a ticket template';
$hesklang['ticket_tpl_add']='Create a new ticket template';
$hesklang['ticket_tpl_edit']='Edit selected ticket template';
$hesklang['save_ticket_tpl']='Save ticket template';
@ -1233,7 +1214,7 @@ $hesklang['set_pri_to']='Set priority to:'; // Action below the ticket list
$hesklang['pri_set_to']='Priority has been set to:';
$hesklang['cat_pri']='The category priority will be used when customers are not allowed to select priority and a ticket is submitted from the customer interface.';
$hesklang['cat_pri_info']='Your customers are allowed to select priority, so category priority will be ignored.<br /><br />To use category priority instead, turn OFF the following feature in HESK settings:';
$hesklang['def_pri']='Category priority';
$hesklang['def_pri']='Category priority:';
$hesklang['ch_cat_pri']='Set category priority';
$hesklang['cat_pri_ch']='Category priority has been set to:';
$hesklang['err_dbversion']='Too old MySQL version:'; // %s will be replaced with MySQL version
@ -1268,7 +1249,7 @@ $hesklang['eperm']='Permanent email bans:';
$hesklang['bananemail']='Email address to ban';
$hesklang['savebanemail']='Ban this email';
$hesklang['enterbanemail']='Enter the email address you wish to ban.';
$hesklang['validbanemail']='Enter a valid email address (<i>john.doe@domain.com</i>) or email domain (<i>@domain.com</i>)';
$hesklang['validbanemail']='Enter a valid email address (<i>john.doe@example.com</i>) or email domain (<i>@example.com</i>)';
$hesklang['email_banned']='The email address <i>%s</i> was banned and HESK will no longer accept tickets from this address.'; // %s will be replaced with email
$hesklang['emailbanexists']='The email address <i>%s</i> is already banned.'; // %s will be replaced with email
$hesklang['email_unbanned']='Email ban deleted';
@ -1284,11 +1265,11 @@ $hesklang['click_unban']='Click here to unban.';
$hesklang['banip_intro']='Visitors from banned IP addresses will not be able to view or submit tickets and login into the help desk.';
$hesklang['ipperm']='Permanent IP bans:';
$hesklang['iptemp']='Login failure bans:';
$hesklang['savebanip']='Ban this IP';
$hesklang['no_banips']='<i>No IPs are being banned.</i>';
$hesklang['bananip']='IP address to ban';
$hesklang['banex']='Examples:';
$hesklang['iprange']='IP range';
$hesklang['savebanip']='Ban this IP';
$hesklang['ippermban']='Ban this IP permanently';
$hesklang['enterbanip']='Enter the IP address or range you wish to ban.';
$hesklang['validbanip']='Enter a valid IP address or IP range';
@ -1342,7 +1323,6 @@ $hesklang['ccct']='Customer resolve';
$hesklang['custnot']='Notify customers when';
$hesklang['notnew']='A new support ticket is submitted';
$hesklang['notclo']='A support ticket is marked Resolved';
$hesklang['enn']='Except for Email piping/POP3 fetching if email subject contains:';
$hesklang['spamn']='SPAM notice';
$hesklang['spam_inbox']='<span style="color:red"><b>No confirmation email?</b><br />We sent a confirmation message to your email address. If you do not receive it within a few minutes, please check your Junk, Bulk or Spam folders. Mark the message as <b>Not SPAM</b> to avoid problems receiving our correspondence in the future.</span>';
$hesklang['s_ekb']='Enable Knowledgebase';
@ -1351,7 +1331,7 @@ $hesklang['ekb_y']='<b>YES</b>, enable Knowledgebase';
$hesklang['ekb_o']='<b>YES</b>, use HESK as a Knowledgebase only (<i>disable help desk</i>)';
$hesklang['kb_set']='Knowledgebase settings';
$hesklang['kbo1']='Knowledgebase-only mode';
$hesklang['kbo2']='Visitors cannot submit new support tickets and are taken directly to the knowledgebase.';
$hesklang['kbo2']='<br /><br />Visitors cannot submit new support tickets and are taken directly to the knowledgebase.';
$hesklang['fpass']='Forgot your password?';
$hesklang['passr']='Password reset';
$hesklang['passa']='Allow users to reset a forgot password over email';
@ -1375,16 +1355,13 @@ $hesklang['pjt2']='minutes after start';
$hesklang['nkba']='Knowledgebase search requires enough unique articles to work properly.<br /><br />Consider adding more articles to the knowledgebase to improve search and article suggestion results.';
$hesklang['saa']='Sticky articles are displayed at the top of articles list';
$hesklang['yhbr']='You have been locked out the system for %s minutes because of too many replies to a ticket.';
$hesklang['sir']='ReCaptcha V1 API (old)';
$hesklang['sir2']='ReCaptcha V2 API (recommended)';
$hesklang['rcpb']='Site key (Public key)';
$hesklang['rcpv']='Secret key (Private key)';
// Language for Google reCaptcha API version 2
// Supported language codes: https://developers.google.com/recaptcha/docs/language
// If your language is NOT in the supported langauges, leave 'en'
$hesklang['RECAPTCHA']='en';
// Added or modified in version 2.7.0
$hesklang['imap']='IMAP Fetching';
$hesklang['imaph']='IMAP Host';
@ -1560,5 +1537,65 @@ $hesklang['step2']='Step 2';
$hesklang['dffs']='When download completes, delete the file from server';
$hesklang['fd']='Export file deleted from server';
// Added or modified in version 2.8.0
$hesklang['TZ']='Timezone';
$hesklang['thist17']='<li class="smaller">%s | submitted by IMAP fetching</li>';
$hesklang['sir3']='Invisible reCAPTCHA';
$hesklang['invisible']='invisible';
$hesklang['rcpb']='Site key';
$hesklang['rcpv']='Secret key';
$hesklang['recaptcha_error']='Could not validate reCAPTCHA SPAM protection.';
$hesklang['imap_not']='PHP is not compiled with IMAP support';
$hesklang['imap_warning']='user %1$s has the same email address as your IMAP fetching email address: %2$s'; // %1$s = username, %2$s = email address
$hesklang['pop3_warning']='user %1$s has the same email address as your POP3 fetching email address: %2$s'; // %1$s = username, %2$s = email address
$hesklang['fetch_warning']='This could result in an email loop where new tickets are being created from user email notifications. Your fetching email address should be unique and not used by anyone else.';
$hesklang['from_warning']='Hesk is using a SMTP server to send email notifications. Your &quot;%1$s&quot; on the &quot;%2$s&quot; tab should be set to: %3$s'; // %1$s = "From email" text, %2$s = "General" tab text, %3$s = email address
$hesklang['can_view_ass_by']='Can view tickets he/she assigned to others';
$hesklang['can_privacy']='Can anonymize tickets';
$hesklang['confirm_anony']='Anonymize this ticket';
$hesklang['anon_selected']='Anonymize selected tickets';
$hesklang['privacy_anon_info']='Remove all personally-identifiable data and content from tickets (customer name, email, message, attachments, IP...), but keep tickets in the database for statistics (right to be forgotten).';
$hesklang['success_anon']='Ticket successfully anonymized';
$hesklang['num_tickets_anon']='Number of tickets anonymized: <b>%d</b>';
$hesklang['num_tickets_deleted']='Number of tickets deleted: <b>%d</b>';
$hesklang['anon_IP']='0.0.0.0'; // IP in anonymized tickets
$hesklang['anon_name']='[Customer]'; // Customer name in anonymized tickets
$hesklang['anon_email']=''; // Customer email in anonymized tickets
$hesklang['anon_subject']='[Subject]'; // Ticket subject of anonymized tickets
$hesklang['anon_message']='[Message]'; // Ticket message in anonymized tickets
$hesklang['thist18']='<li class="smaller">%s | anonymized by %s</li>';
$hesklang['print_selected']='Print selected tickets';
$hesklang['with_selected']='With selected:';
$hesklang['assign_selected']='Assign selected to:';
$hesklang['assign_no']='No owner selected, no changes made';
$hesklang['assign_1']='Selected tickets have been set to Unassigned.';
$hesklang['assign_2']='Ticket ID %1$s set to Unassigned'; // %1$s = ticket numerical ID
$hesklang['assign_3']='%1$s error: already assigned to %2$s'; // %1$s = ticket tracking ID, %2$s = owner name
$hesklang['assign_4']='%1$s assigned to %2$s'; // %1$s = ticket tracking ID, %2$s = owner name
$hesklang['assign_5']='%1$s error: %2$s doesn\'t have access to ticket category'; // %1$s = ticket tracking ID, %2$s = owner name
$hesklang['assign_log']='Bulk ticket assign result:<br /><br />Assigned: %1$s<br />Errors: %2$s<br /><br />Log:<br /><pre>%3$s</pre>'; // %1$s = number of tickets assigned, %2$s = number of errors, %3$s = log
$hesklang['IP_addr']='IP address';
$hesklang['moret']='More options'; // More options button title
$hesklang['btn_more']='More'; // More options button text
$hesklang['btn_print']='Print';
$hesklang['btn_edit']='Edit';
$hesklang['btn_lock']='Lock ticket';
$hesklang['btn_unlock']='Unlock ticket';
$hesklang['btn_tag']='Tag ticket';
$hesklang['btn_resend']='Re-send email notification';
$hesklang['btn_untag']='Untag ticket';
$hesklang['btn_import_kb']='Import to Knowledgebase';
$hesklang['btn_anony']='Anonymize ticket';
$hesklang['btn_delt']='Delete ticket';
$hesklang['btn_delr']='Delete reply';
$hesklang['ernf']='Reply not found';
$hesklang['tns']='Ticket notifications were sent again';
$hesklang['rns']='Reply notifications were sent again';
$hesklang['fname']='First Name';
$hesklang['export_selected']='Export selected tickets';
$hesklang['btn_export']='Export to XML for Excel';
$hesklang['recaptcha']='reCAPTCHA';
// DO NOT CHANGE BELOW
if (!defined('IN_SCRIPT')) die('PHP syntax OK!');
if (!defined('IN_SCRIPT')) die('PHP syntax OK!');

@ -125,141 +125,7 @@ $modsForHesk_settings = mfh_getSettings();
<?php
/* Ticket priority */
switch ($ticket['priority']) {
case 0:
$ticket['priority'] = '<b>' . $hesklang['critical'] . '</b>';
break;
case 1:
$ticket['priority'] = '<b>' . $hesklang['high'] . '</b>';
break;
case 2:
$ticket['priority'] = $hesklang['medium'];
break;
default:
$ticket['priority'] = $hesklang['low'];
}
/* Set last replier name */
if ($ticket['lastreplier']) {
if (empty($ticket['repliername'])) {
$ticket['repliername'] = $hesklang['staff'];
}
} else {
$ticket['repliername'] = $ticket['name'];
}
/* Other variables that need processing */
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$random = mt_rand(10000, 99999);
// Print ticket head
echo '
<h3>' . $ticket['subject'] . '</h3>
<hr/>
<table border="1" bordercolor="#FFFFFF" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['trackID'] . ':</b></td><td bgcolor="#DDD">' . $trackingID . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['ticket_status'] . ':</b></td><td bgcolor="#DDD">' . $hesklang[$ticket['statusKey']] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['created_on'] . ':</b></td><td bgcolor="#DDD">' . $ticket['dt'] . '</td>
</tr>
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['last_update'] . ':</b></td><td bgcolor="#DDD">' . $ticket['lastchange'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['last_replier'] . ':</b></td><td bgcolor="#DDD">' . $ticket['repliername'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['category'] . ':</b></td><td bgcolor="#DDD">' . $category['name'] . '</td>
</tr>
';
// Show IP and time worked to staff
if (!empty($_SESSION['id'])) {
echo '
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['ts'] . ':</b></td><td bgcolor="#DDD">' . $ticket['time_worked'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['ip'] . ':</b></td><td bgcolor="#DDD">' . $ticket['ip'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['email'] . ':</b></td><td bgcolor="#DDD">' . $ticket['email'] . '</td>
</tr>
';
}
echo '<tr>';
// Assigned to?
if ($ticket['owner'] && !empty($_SESSION['id'])) {
$ticket['owner'] = hesk_getOwnerName($ticket['owner']);
echo '
<td bgcolor="#EEE"><b>' . $hesklang['taso3'] . '</b></td>
<td bgcolor="#DDD">' . $ticket['owner'] . '</td>
';
}
echo '
<td bgcolor="#EEE"><b>' . $hesklang['name'] . ':</b></td>
<td bgcolor="#DDD">' . $ticket['name'] . '</td>
';
echo '</tr>';
// Custom fields
$num_cols = 0;
echo '<tr>';
foreach ($hesk_settings['custom_fields'] as $k => $v) {
if (($v['use'] == 1 || (! empty($_SESSION['id']) && $v['use'] == 2)) && hesk_is_custom_field_in_category($k, $ticket['category'])) {
if ($num_cols == 3) {
echo '</tr><tr>';
$num_cols = 0;
}
switch ($v['type']) {
case 'date':
$ticket[$k] = hesk_custom_date_display_format($ticket[$k], $v['value']['date_format']);
break;
}
?>
<td bgcolor="#EEE"><b><?php echo $v['name']; ?>:</b></td>
<td bgcolor="#DDD"><?php echo hesk_unhortenUrl($ticket[$k]); ?></td>
<?php
$num_cols++;
}
}
// Close ticket head table
echo '</table><br>';
// Print initial ticket message
if ($ticket['message'] != '') {
$newMessage = hesk_unhortenUrl($ticket['message']);
if ($ticket['html']) {
$newMessage = hesk_html_entity_decode($newMessage);
}
echo '<p>' . $newMessage . '</p>';
}
// Print replies
while ($reply = hesk_dbFetchAssoc($res)) {
$reply['dt'] = hesk_date($reply['dt'], true);
$theReply = hesk_unhortenUrl($reply['message']);
if ($reply['html']) {
$theReply = hesk_html_entity_decode($theReply);
}
echo '
<hr />
<table border="1" bordercolor="#FFFFFF" cellspacing="0" cellpadding="2" width="100%">
<tr>
<td bgcolor="#EEE"><b>' . $hesklang['date'] . ':</b></td><td bgcolor="#DDD">' . $reply['dt'] . '</td>
<td bgcolor="#EEE"><b>' . $hesklang['name'] . ':</b></td><td bgcolor="#DDD">' . $reply['name'] . '</td>
</tr>
</table>
<div class="message">' . $theReply . '</div>
';
}
// Print "end of ticket" message
echo $hesklang['end_ticket'];
require_once(HESK_PATH . 'inc/print_template.inc.php');
?>
</body>

@ -82,23 +82,8 @@ if ($hesk_settings['question_use']) {
// Check anti-SPAM image
if ($hesk_settings['secimg_use'] && !isset($_SESSION['img_verified'])) {
// Using ReCaptcha?
if ($hesk_settings['recaptcha_use'] == 1) {
require(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
$resp = recaptcha_check_answer($hesk_settings['recaptcha_private_key'],
hesk_getClientIP(),
hesk_POST('recaptcha_challenge_field', ''),
hesk_POST('recaptcha_response_field', '')
);
if ($resp->is_valid) {
$_SESSION['img_verified'] = true;
} else {
$hesk_error_buffer['mysecnum'] = $hesklang['recaptcha_error'];
}
} // Using ReCaptcha API v2?
elseif ($hesk_settings['recaptcha_use'] == 2) {
// Using reCAPTCHA?
if ($hesk_settings['recaptcha_use']) {
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
$resp = null;
@ -410,6 +395,7 @@ $tmpvar['owner'] = 0;
$autoassign_owner = hesk_autoAssignTicket($tmpvar['category']);
if ($autoassign_owner) {
$tmpvar['owner'] = $autoassign_owner['id'];
$tmpvar['assignedby'] = -1;
}
// Insert attachments
@ -462,7 +448,7 @@ if ($createTicket) {
$ticket = hesk_newTicket($tmpvar);
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_submitted_by', hesk_date(),
array(0 => $tmpvar['name']));
array(0 => $hesklang['customer']));
if ($autoassign_owner) {
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_autoassigned', hesk_date(),

@ -781,7 +781,7 @@ function hesk_getCustomerButtons($white = 1)
$style = 'class="option' . $tmp . 'OFF" onmouseover="this.className=\'option' . $tmp . 'ON\'" onmouseout="this.className=\'option' . $tmp . 'OFF\'"';
/* Print ticket button */
$options .= '<a href="print.php?track=' . $trackingID . $hesk_settings['e_query'] . '" title="' . $hesklang['printer_friendly'] . '"><span class="glyphicon glyphicon-print"></span> ' . $hesklang['printer_friendly'] . ' </a> ';
$options .= '<a class="btn btn-default" href="print.php?track=' . $trackingID . $hesk_settings['e_query'] . '" title="' . $hesklang['printer_friendly'] . '"><span class="fa fa-print"></span> ' . $hesklang['btn_print'] . ' </a> ';
/* Return generated HTML */
return $options;

Loading…
Cancel
Save