Browse Source

Update to 2018.2.0

master
Skylar Ittner 9 months ago
parent
commit
6fcd22b533
100 changed files with 5751 additions and 953 deletions
  1. 7
    2
      .gitignore
  2. 11
    17
      admin/admin_main.php
  3. 110
    132
      admin/admin_settings.php
  4. 5
    6
      admin/admin_settings_save.php
  5. 5
    0
      admin/admin_submit_ticket.php
  6. 70
    19
      admin/admin_ticket.php
  7. 43
    0
      admin/anonymize_ticket.php
  8. 10
    2
      admin/assign_owner.php
  9. 1
    1
      admin/banned_emails.php
  10. 1
    1
      admin/banned_ips.php
  11. 2
    2
      admin/custom_fields.php
  12. 297
    1
      admin/delete_tickets.php
  13. 4
    339
      admin/export.php
  14. 54
    0
      admin/export_ticket.php
  15. 3
    0
      admin/find_tickets.php
  16. 14
    48
      admin/index.php
  17. 3
    3
      admin/mail.php
  18. 3
    1
      admin/manage_canned.php
  19. 2
    1
      admin/manage_categories.php
  20. 4
    3
      admin/manage_email_templates.php
  21. 6
    6
      admin/manage_knowledgebase.php
  22. 7
    5
      admin/manage_permission_groups.php
  23. 1
    1
      admin/manage_ticket_templates.php
  24. 58
    15
      admin/manage_users.php
  25. 13
    45
      admin/password.php
  26. 80
    83
      admin/service_messages.php
  27. 0
    17
      admin/show_tickets.php
  28. 3
    0
      api/BusinessLogic/Calendar/SearchEventsFilter.php
  29. 2
    0
      api/BusinessLogic/Emails/EmailTemplateParser.php
  30. 5
    3
      api/BusinessLogic/Emails/MailgunEmailSender.php
  31. 207
    0
      api/BusinessLogic/Helpers.php
  32. 2
    0
      api/BusinessLogic/Security/UserPrivilege.php
  33. 7
    2
      api/BusinessLogic/Security/UserToTicketChecker.php
  34. 13
    0
      api/BusinessLogic/Tickets/CreateReplyRequest.php
  35. 13
    0
      api/BusinessLogic/Tickets/CustomerCreatedReplyModel.php
  36. 11
    1
      api/BusinessLogic/Tickets/NewTicketValidator.php
  37. 156
    0
      api/BusinessLogic/Tickets/ReplyCreator.php
  38. 6
    0
      api/BusinessLogic/Tickets/Ticket.php
  39. 18
    3
      api/BusinessLogic/Tickets/TicketCreator.php
  40. 1
    1
      api/BusinessLogic/Tickets/TicketEditor.php
  41. 4
    2
      api/Controllers/Calendar/CalendarController.php
  42. 1
    1
      api/Controllers/System/HeskVersionController.php
  43. 37
    0
      api/Controllers/Tickets/CustomerReplyController.php
  44. 9
    1
      api/Controllers/Tickets/StaffTicketController.php
  45. 8
    0
      api/DataAccess/AuditTrail/AuditTrailGateway.php
  46. 4
    0
      api/DataAccess/Calendar/CalendarGateway.php
  47. 24
    0
      api/DataAccess/Security/LoginGateway.php
  48. 15
    0
      api/DataAccess/Security/UserGateway.php
  49. 18
    0
      api/DataAccess/Statuses/StatusGateway.php
  50. 33
    0
      api/DataAccess/Tickets/ReplyGateway.php
  51. 43
    2
      api/DataAccess/Tickets/TicketGateway.php
  52. 2
    0
      api/Tests/BusinessLogic/Security/UserToTicketCheckerTest.php
  53. 11
    1
      api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php
  54. 1
    0
      api/index.php
  55. 1
    1
      build.php
  56. 8
    8
      calendar.php
  57. 4
    0
      css/font-awesome.min.css
  58. 479
    0
      css/leaflet.css
  59. 9
    0
      css/mods-for-hesk-new.css
  60. BIN
      fonts/FontAwesome.otf
  61. BIN
      fonts/fontawesome-webfont.eot
  62. 2671
    0
      fonts/fontawesome-webfont.svg
  63. BIN
      fonts/fontawesome-webfont.ttf
  64. BIN
      fonts/fontawesome-webfont.woff
  65. BIN
      fonts/fontawesome-webfont.woff2
  66. 78
    0
      hesk_style.css
  67. BIN
      img/leaflet/layers-2x.png
  68. BIN
      img/leaflet/layers.png
  69. BIN
      img/leaflet/marker-icon-2x.png
  70. BIN
      img/leaflet/marker-icon.png
  71. BIN
      img/leaflet/marker-shadow.png
  72. 35
    2
      inc/admin_functions.inc.php
  73. 82
    59
      inc/common.inc.php
  74. 32
    2
      inc/email_functions.inc.php
  75. 383
    0
      inc/export_functions.inc.php
  76. 10
    19
      inc/footer.inc.php
  77. 9
    4
      inc/header.inc.php
  78. 8
    3
      inc/headerAdmin.inc.php
  79. 24
    3
      inc/pipe_functions.inc.php
  80. 12
    0
      inc/posting_functions.inc.php
  81. 151
    0
      inc/print_template.inc.php
  82. 97
    0
      inc/privacy_functions.inc.php
  83. 18
    6
      inc/profile_functions.inc.php
  84. 18
    16
      inc/show_search_form.inc.php
  85. 42
    5
      inc/ticket_list.inc.php
  86. 16
    36
      index.php
  87. BIN
      install/background.jpg
  88. 2
    2
      install/install_functions.inc.php
  89. 8
    1
      install/migrations/core.php
  90. 49
    0
      install/migrations/vv201820/MigrateServiceMessageLanguages.php
  91. 8
    5
      internal-api/js/admin-ticket.js
  92. 17
    13
      internal-api/js/manage-categories.js
  93. 3
    1
      internal-api/js/service-messages.js
  94. BIN
      js/images/layers-2x.png
  95. BIN
      js/images/layers.png
  96. BIN
      js/images/marker-icon-2x.png
  97. BIN
      js/images/marker-icon.png
  98. BIN
      js/images/marker-shadow.png
  99. 9
    0
      js/leaflet.js
  100. 0
    0
      language/en/help_files/custom.html

+ 7
- 2
.gitignore View File

@@ -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
@@ -250,6 +255,7 @@ inc/zip/index.htm
inc/zip/pclzip.lib.php
install/hesk.png
install/update.php
language/en/help_files
language/en/emails/category_moved.txt
language/en/emails/forgot_ticket_id.txt
language/en/emails/index.htm
@@ -260,9 +266,8 @@ 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
print_sec_img.php
rate.php
readme.html

+ 11
- 17
admin/admin_main.php View File

@@ -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');

+ 110
- 132
admin/admin_settings.php View File

@@ -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">
@@ -1499,14 +1495,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>
@@ -2872,10 +2868,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']; ?>">
@@ -3456,53 +3459,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">

+ 5
- 6
admin/admin_settings_save.php View File

@@ -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 */
@@ -886,9 +887,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

+ 5
- 0
admin/admin_submit_ticket.php View File

@@ -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');


+ 70
- 19
admin/admin_ticket.php View File

@@ -50,6 +50,10 @@ $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);
$can_change_due_date = hesk_checkPermission('can_change_due_date', 0);

// Get ticket ID
$trackingID = hesk_cleanID() or print_form();
@@ -90,7 +94,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 +170,11 @@ if ($isManager) {
$can_unban_emails =
$can_ban_ips =
$can_unban_ips =
$can_resolve = true;
$can_resolve =
$can_view_ass_by =
$can_privacy =
$can_export =
$can_change_due_date = true;
}

/* Is this user allowed to view tickets inside this category? */
@@ -748,9 +759,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
</span>
</b><br>
<?php if ($can_change_due_date): ?>
<button class="btn btn-default btn-sm" id="change-button">
<?php echo $hesklang['chg']; ?>
</button>
<?php endif; ?>
</div>
<div id="editable-due-date" style="display: none">
<span class="form-group">
@@ -1321,7 +1334,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 +1342,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 +1502,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 +1512,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 +1530,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 +1586,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 +1637,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 +1646,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 +2055,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 +2082,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;
@@ -2340,6 +2390,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']] : ''); ?>');


+ 43
- 0
admin/anonymize_ticket.php View File

@@ -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']);

+ 10
- 2
admin/assign_owner.php View File

@@ -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(),

+ 1
- 1
admin/banned_emails.php View File

@@ -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>

+ 1
- 1
admin/banned_ips.php View File

@@ -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>
';

+ 2
- 2
admin/custom_fields.php View File

@@ -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>

+ 297
- 1
admin/delete_tickets.php View File

@@ -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');

+ 4
- 339
admin/export.php View File

@@ -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>

+ 54
- 0
admin/export_ticket.php View File

@@ -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']);

+ 3
- 0
admin/find_tickets.php View File

@@ -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() . "' ";

+ 14
- 48
admin/index.php View File

@@ -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']; ?>

+ 3
- 3
admin/mail.php View File

@@ -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>

+ 3
- 1
admin/manage_canned.php View File

@@ -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
@@ -363,6 +363,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)"

+ 2
- 1
admin/manage_categories.php View File

@@ -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>
@@ -477,6 +477,7 @@ echo mfh_get_hidden_fields_for_language(array(
'geco',
'cpric',
'no_manager',
'e_udel',
));

require_once(HESK_PATH . 'inc/footer.inc.php');

+ 4
- 3
admin/manage_email_templates.php View File

@@ -274,12 +274,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;
@@ -310,6 +310,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'];
@@ -324,7 +325,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;

+ 6
- 6
admin/manage_knowledgebase.php View File

@@ -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?
@@ -1879,10 +1879,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++;

+ 7
- 5
admin/manage_permission_groups.php View File

@@ -189,8 +189,9 @@ function createEditModal($template, $features, $categories)
<div class="footerWithBorder blankSpace"></div>
<div class="form-group">
<?php
foreach ($categories as $category): ?>
<?php
foreach ($categories as $category):
$can_man_categories = hesk_checkPermission('can_man_cat', 0);

$checked = '';
$disabled = '';
if (in_array($category['id'], $enabledCategories) ||
@@ -198,12 +199,13 @@ function createEditModal($template, $features, $categories)
$checked = 'checked ';
}
if ((!hesk_SESSION('isadmin') &&
!in_array($category['id'], $_SESSION['categories'])) ||
!in_array($category['id'], $_SESSION['categories']) &&
!$can_man_categories) ||
$template['categories'] === 'ALL') {
$disabled = ' disabled';
}?>
}

<?php if ($_SESSION['isadmin'] || in_array($category['id'], $_SESSION['categories']) || $checked): ?>
if ($_SESSION['isadmin'] || $can_man_categories || in_array($category['id'], $_SESSION['categories']) || $checked): ?>
<div class="checkbox">
<label>
<input type="checkbox" name="categories[]"

+ 1
- 1
admin/manage_ticket_templates.php View File

@@ -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

+ 58
- 15
admin/manage_users.php View File

@@ -42,6 +42,9 @@ $calendar_view_array = array(
);
$default_view = $calendar_view_array[$modsForHesk_settings['default_calendar_view']];

$staff_permission_template_rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` WHERE `id` = 2");
$staff_permission_template = hesk_dbFetchAssoc($staff_permission_template_rs);

/* Set default values */
$default_userdata = array(

@@ -58,12 +61,15 @@ $default_userdata = array(
// Permissions
'isadmin' => 1,
'active' => 1,
'categories' => array('1'),
'features' => array('can_view_tickets', 'can_reply_tickets', 'can_change_cat', 'can_assign_self', 'can_view_unassigned', 'can_view_online'),
'categories' => explode(',', $staff_permission_template['categories']),
'features' => explode(',', $staff_permission_template['heskprivileges']),

// Preferences
'afterreply' => 0,

// Permission template
'permission_template' => 2,

// Defaults
'autostart' => 1,
'notify_customer_new' => 1,
@@ -89,7 +95,7 @@ $orderBy = $modsForHesk_settings['category_order_column'];
$hesk_settings['categories'] = array();
$res = hesk_dbQuery('SELECT `id`,`name` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'categories` ORDER BY `' . $orderBy . '` ASC');
while ($row = hesk_dbFetchAssoc($res)) {
if (hesk_okCategory($row['id'], 0)) {
if (hesk_checkPermission('can_man_cat', 0) || hesk_okCategory($row['id'], 0)) {
$hesk_settings['categories'][$row['id']] = $row['name'];
}
}
@@ -161,7 +167,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']); ?>')) {
@@ -253,19 +290,19 @@ if ($action = hesk_REQUEST('a')) {
/* User online? */
if ($hesk_settings['online']) {
if (isset($hesk_settings['users_online'][$myuser['id']])) {
$myuser['name'] = '<i class="fa fa-circle green" data-toggle="tooltip" data-placement="top" title="' . $hesklang['online'] . '"></i> ' . $myuser['name'];
$myuser['name'] = '<i class="fa fa-fw fa-circle green" data-toggle="tooltip" data-placement="top" title="' . $hesklang['online'] . '"></i> ' . $myuser['name'];
} else {
$myuser['name'] = '<i class="fa fa-circle gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['offline'] . '"></i> ' . $myuser['name'];
$myuser['name'] = '<i class="fa fa-fw fa-circle gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['offline'] . '"></i> ' . $myuser['name'];
}
}

/* 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-fw 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-fw fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
}

if ($myuser['isadmin']) {
@@ -278,15 +315,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-fw fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>';
}

/* Is auto assign enabled? */