Initial commit

Signed-off-by: Luke Tainton <luke@tainton.uk>
This commit is contained in:
Luke Tainton
2020-02-26 12:23:50 +00:00
commit 39782c53ef
500 changed files with 141257 additions and 0 deletions

5
Dockerfile Normal file
View File

@@ -0,0 +1,5 @@
FROM php:apache
LABEL maintainer="Luke Tainton <luke@tainton.uk>"
COPY hesk /srv
COPY vhost.conf /etc/apache2/sites-enabled/000-default.conf
RUN a2enmod rewrite

121
hesk/admin/admin_main.php Normal file
View File

@@ -0,0 +1,121 @@
<?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','../');
/* Make sure the install folder is deleted */
if (is_dir(HESK_PATH . 'install')) {die('Please delete the <b>install</b> folder from your server for security reasons then refresh this page!');}
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
define('CALENDAR',1);
define('MAIN_PAGE',1);
define('AUTO_RELOAD',1);
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<div class="main__content tickets">
<div style="margin-left: -16px; margin-right: -24px;">
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
</div>
<?php
/* Print tickets? */
if (hesk_checkPermission('can_view_tickets',0))
{
if ( ! isset($_SESSION['hide']['ticket_list']) )
{
// Show 'Tickets' if resolved tickets are shown by default
if (isset($_SESSION['default_list']) && strpos($_SESSION['default_list'], 's3=1') !== false) {
$table_title = $hesklang['tickets'];
} else {
$table_title = $hesklang['open_tickets'];
}
$header_text = '
<section style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px">
<h2 style="font-size: 18px; font-weight: bold">'.$table_title.' (%%HESK_TICKET_COUNT%%)</h2>
<div class="checkbox-custom">
<input type="checkbox" id="reloadCB" onclick="toggleAutoRefresh(this);">
<label for="reloadCB">'.$hesklang['arp'].'</label>&nbsp;<span id="timer"></span>
<script type="text/javascript">heskCheckReloading();</script>
</div>
</section>
';
}
/* Reset default settings? */
if ( isset($_GET['reset']) && hesk_token_check() )
{
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` SET `default_list`='' WHERE `id` = '".intval($_SESSION['id'])."'");
$_SESSION['default_list'] = '';
}
/* Get default settings */
else
{
parse_str($_SESSION['default_list'],$defaults);
$_GET = isset($_GET) && is_array($_GET) ? array_merge($_GET, $defaults) : $defaults;
}
/* Print the list of tickets */
require(HESK_PATH . 'inc/print_tickets.inc.php');
echo "&nbsp;<br />";
/* Print forms for listing and searching tickets */
require(HESK_PATH . 'inc/show_search_form.inc.php');
}
else
{
echo '<p><i>'.$hesklang['na_view_tickets'].'</i></p>';
}
/*******************************************************************************
The code below handles HESK licensing and must be included in the template.
Removing this code is a direct violation of the HESK End User License Agreement,
will void all support and may result in unexpected behavior.
To purchase a HESK license and support future HESK development please visit:
https://www.hesk.com/buy.php
*******************************************************************************/
"\x61\104".chr(822083584>>23).chr(0153)."\x54".chr(0140)."\x26\171".chr(0176)."\43\x2b"."s".chr(738197504>>23)."\x32"."-\115".chr(0144)."v\162".chr(629145600>>23)."\133\x58\166";if(!file_exists(dirname(dirname(__FILE__))."\x2f".chr(872415232>>23).chr(0145)."\163".chr(0153).chr(796917760>>23)."\x6c\x69\x63".chr(847249408>>23)."\x6e".chr(0163)."\145".chr(385875968>>23)."\x70\150"."p")){echo"\xd\xa\x20\x20\x20\x20\x20\x20\x20\x20"."<\x64"."i\166\x20"."cla".chr(964689920>>23)."s\x3d\x22"."m".chr(813694976>>23).chr(880803840>>23)."n__\143\157".chr(922746880>>23)."\164\145\x6e"."t\x20\156\x6f"."t\151".chr(0143)."\145\x2d"."f\x6c\141\163\x68\x22\x20"."s\x74".chr(1015021568>>23)."l\145\x3d\x22\160\141\144\144\x69\x6e\x67".":\x20\x32\64".chr(0160)."\x78\x20\x30\x20\60\x20\60\x22\x3e\15\xa\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\74\x64\151\x76\x20\x63\x6c\x61\163"."s\x3d\x22"."n\x6f\164"."i\x66"."i".chr(0143).chr(0141)."\164\151"."o\x6e\x20\x6f\x72".chr(813694976>>23)."\x6e\147".chr(847249408>>23)."\x22\x20\163".chr(973078528>>23)."\x79\x6c\145".chr(075)."\x22\167"."i\144\164\x68\72".chr(061)."0\60\45\x22\76".chr(015)."\xa\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20".$hesklang["\x73\x75\x70\x70".chr(0157)."\162".chr(0164)."\x5f"."r\145"."mo".chr(0166)."\x65"]."\x3c\142\x72\x3e\x3c".chr(822083584>>23).chr(956301312>>23).chr(520093696>>23)."\15\xa\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x61\x20\x68".chr(0162)."\145\146\x3d\x22".chr(872415232>>23)."\164"."tp\163".chr(072)."\57\x2f\x77\167".chr(998244352>>23).chr(056).chr(872415232>>23).chr(847249408>>23)."\163\153\x2e\x63".chr(931135488>>23)."m\x2f\x62\x75\171\56\160\150\x70\x22\x20\143\154\141\x73\x73\75\x22\x62".chr(0164)."n\x20\x62"."t\x6e\55"."-b".chr(0154).chr(0165)."e\x2d"."b\157\162\x64\x65\x72\x22\x20"."s\164\171\154".chr(847249408>>23)."\x3d\x22"."b\141\143\153"."gr\x6f"."u\x6e\x64\55\143\157\x6c"."o".chr(956301312>>23)."\x3a\x20\167"."h\x69\x74\x65\x22\76".$hesklang["\x63\x6c\x69\x63\x6b\x5f\x69\x6e\x66"."o"]."\x3c\57\141\76\xd\xa\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\74\57\x64".chr(0151)."\x76".">\xd\xa\x20\x20\x20\x20\x20\x20\x20\x20"."<".chr(394264576>>23)."\144".chr(0151).chr(989855744>>23).">";}"\x67".chr(729808896>>23).chr(578813952>>23)."\x4a".chr(0116)."\102\x5d"."C@}\125\74".chr(461373440>>23)."\x3f\75\x73".chr(0176)."\165\x7b\136\x2b\104\x2e\53\150\136"."}";
/*******************************************************************************
END LICENSE CODE
*******************************************************************************/
echo '</div>';
/* Clean unneeded session variables */
hesk_cleanSessionVars('hide');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
?>

View File

@@ -0,0 +1,413 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/email_functions.inc.php');
require(HESK_PATH . 'inc/posting_functions.inc.php');
// We only allow POST requests from the HESK form to this file
if ( $_SERVER['REQUEST_METHOD'] != 'POST' )
{
header('Location: admin_main.php');
exit();
}
// Check for POST requests larger than what the server can handle
if ( empty($_POST) && ! empty($_SERVER['CONTENT_LENGTH']) )
{
hesk_error($hesklang['maxpost']);
}
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_reply_tickets');
/* A security check */
# hesk_token_check('POST');
/* Original ticket ID */
$replyto = intval( hesk_POST('orig_id', 0) ) or die($hesklang['int_error']);
/* Get details about the original ticket */
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='{$replyto}' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
$trackingID = $ticket['trackid'];
// Do we require owner before allowing to reply?
if ($hesk_settings['require_owner'] && ! $ticket['owner'])
{
hesk_process_messages($hesklang['atbr'],'admin_ticket.php?track='.$ticket['trackid'].'&Refresh='.rand(10000,99999));
}
$hesk_error_buffer = array();
// Get the message
$message = hesk_input(hesk_POST('message'));
// Submit as customer?
$submit_as_customer = isset($_POST['submit_as_customer']) ? true : false;
if (strlen($message))
{
// Save message for later and ignore the rest?
if ( isset($_POST['save_reply']) )
{
// Delete any existing drafts from this owner for this ticket
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."reply_drafts` WHERE `owner`=".intval($_SESSION['id'])." AND `ticket`=".intval($ticket['id']));
// Save the message draft
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."reply_drafts` (`owner`, `ticket`, `message`) VALUES (".intval($_SESSION['id']).", ".intval($ticket['id']).", '".hesk_dbEscape($message)."')");
/* Set reply submitted message */
$_SESSION['HESK_SUCCESS'] = TRUE;
$_SESSION['HESK_MESSAGE'] = $hesklang['reply_saved'];
/* What to do after reply? */
if ($_SESSION['afterreply'] == 1)
{
header('Location: admin_main.php');
}
elseif ($_SESSION['afterreply'] == 2)
{
/* Get the next open ticket that needs a reply */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` IN ('0','".intval($_SESSION['id'])."') AND " . hesk_myCategories() . " AND `status` IN ('0','1') ORDER BY `owner` DESC, `priority` ASC LIMIT 1");
if (hesk_dbNumRows($res) == 1)
{
$row = hesk_dbFetchAssoc($res);
$_SESSION['HESK_MESSAGE'] .= '<br /><br />'.$hesklang['rssn'];
header('Location: admin_ticket.php?track='.$row['trackid'].'&Refresh='.rand(10000,99999));
}
else
{
header('Location: admin_main.php');
}
}
else
{
header('Location: admin_ticket.php?track='.$ticket['trackid'].'&Refresh='.rand(10000,99999));
}
exit();
}
// Attach signature to the message?
if ( ! $submit_as_customer && ! empty($_POST['signature']) && strlen($_SESSION['signature']))
{
$message .= "\n\n" . addslashes($_SESSION['signature']) . "\n";
}
// Make links clickable
$message = hesk_makeURL($message);
// Turn newlines into <br /> tags
$message = nl2br($message);
}
else
{
$hesk_error_buffer[] = $hesklang['enter_message'];
}
/* Attachments */
if ($hesk_settings['attachments']['use'])
{
require(HESK_PATH . 'inc/attachments.inc.php');
$attachments = array();
for ($i=1;$i<=$hesk_settings['attachments']['max_number'];$i++)
{
$att = hesk_uploadFile($i);
if ($att !== false && !empty($att))
{
$attachments[$i] = $att;
}
}
}
$myattachments='';
/* Time spent working on ticket */
$time_worked = hesk_getTime(hesk_POST('time_worked'));
/* Any errors? */
if (count($hesk_error_buffer)!=0)
{
$_SESSION['ticket_message'] = hesk_POST('message');
$_SESSION['time_worked'] = $time_worked;
// Remove any successfully uploaded attachments
if ($hesk_settings['attachments']['use'])
{
hesk_removeAttachments($attachments);
}
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['pcer'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'admin_ticket.php?track='.$ticket['trackid'].'&Refresh='.rand(10000,99999));
}
if ($hesk_settings['attachments']['use'] && !empty($attachments))
{
foreach ($attachments as $myatt)
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES ('".hesk_dbEscape($trackingID)."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."')");
$myattachments .= hesk_dbInsertID() . '#' . $myatt['real_name'] .',';
}
}
// Add reply
if ($submit_as_customer)
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` (`replyto`,`name`,`message`,`dt`,`attachments`) VALUES ('".intval($replyto)."','".hesk_dbEscape(addslashes($ticket['name']))."','".hesk_dbEscape($message."<br /><br /><i>{$hesklang['creb']} {$_SESSION['name']}</i>")."',NOW(),'".hesk_dbEscape($myattachments)."')");
}
else
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`) VALUES ('".intval($replyto)."','".hesk_dbEscape(addslashes($_SESSION['name']))."','".hesk_dbEscape($message)."',NOW(),'".hesk_dbEscape($myattachments)."','".intval($_SESSION['id'])."')");
}
/* Track ticket status changes for history */
$revision = '';
/* Change the status of priority? */
if ( ! empty($_POST['set_priority']) )
{
$priority = intval( hesk_POST('priority') );
if ($priority < 0 || $priority > 3)
{
hesk_error($hesklang['select_priority']);
}
$options = array(
0 => $hesklang['critical'],
1 => $hesklang['high'],
2 => $hesklang['medium'],
3 => $hesklang['low']
);
$revision = sprintf($hesklang['thist8'],hesk_date(),$options[$priority],$_SESSION['name'].' ('.$_SESSION['user'].')');
$priority_sql = ",`priority`='$priority', `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') ";
}
else
{
$priority_sql = "";
}
// Get new ticket status
$sql_status = '';
// -> If locked, keep it resolved
if ($ticket['locked'])
{
$new_status = 3;
}
// -> Submit as: Resolved
elseif ( isset($_POST['submit_as_resolved']) && hesk_checkPermission('can_resolve', 0) )
{
$new_status = 3;
if ($ticket['status'] != $new_status)
{
$revision = sprintf($hesklang['thist3'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')');
$sql_status = " , `closedat`=NOW(), `closedby`=".intval($_SESSION['id']).", `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') ";
// Lock the ticket if customers are not allowed to reopen tickets
if ($hesk_settings['custopen'] != 1)
{
$sql_status .= " , `locked`='1' ";
}
}
}
// -> Submit as: In Progress
elseif ( isset($_POST['submit_as_in_progress']) )
{
$new_status = 4;
if ($ticket['status'] != $new_status)
{
$revision = sprintf($hesklang['thist9'],hesk_date(),$hesklang['in_progress'],$_SESSION['name'].' ('.$_SESSION['user'].')');
$sql_status = " , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') ";
}
}
// -> Submit as: On Hold
elseif ( isset($_POST['submit_as_on_hold']) )
{
$new_status = 5;
if ($ticket['status'] != $new_status)
{
$revision = sprintf($hesklang['thist9'],hesk_date(),$hesklang['on_hold'],$_SESSION['name'].' ('.$_SESSION['user'].')');
$sql_status = " , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') ";
}
}
// -> Submit as Customer reply
elseif ($submit_as_customer)
{
$new_status = 1;
if ($ticket['status'] != $new_status)
{
$revision = sprintf($hesklang['thist9'],hesk_date(),$hesklang['wait_reply'],$_SESSION['name'].' ('.$_SESSION['user'].')');
$sql_status = " , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') ";
}
}
// -> Default: submit as "Replied by staff"
else
{
$new_status = 2;
}
$sql = "UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$new_status}',";
$sql.= $submit_as_customer ? "`lastreplier`='0', `replierid`='0' " : "`lastreplier`='1', `replierid`='".intval($_SESSION['id'])."' ";
/* Update time_worked or force update lastchange */
if ($time_worked == '00:00:00')
{
$sql .= ", `lastchange` = NOW() ";
}
else
{
$parts = explode(':', $ticket['time_worked']);
$seconds = ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
$parts = explode(':', $time_worked);
$seconds += ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
require(HESK_PATH . 'inc/reporting_functions.inc.php');
$ticket['time_worked'] = hesk_SecondsToHHMMSS($seconds);
$sql .= ",`time_worked` = ADDTIME(`time_worked`,'" . hesk_dbEscape($time_worked) . "') ";
}
if ( ! empty($_POST['assign_self']) && hesk_checkPermission('can_assign_self',0))
{
$revision = sprintf($hesklang['thist2'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')',$_SESSION['name'].' ('.$_SESSION['user'].')');
$sql .= " , `owner`=".intval($_SESSION['id']).", `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') ";
}
$sql .= " $priority_sql ";
$sql .= " $sql_status ";
// Is this the first staff reply? Log it for reporting
if ( ! $ticket['firstreplyby'] )
{
$sql .= " , `firstreply`=NOW(), `firstreplyby`=".intval($_SESSION['id'])." ";
}
// Keep track of replies to this ticket for easier reporting
$sql .= " , `replies`=`replies`+1 ";
$sql .= $submit_as_customer ? '' : " , `staffreplies`=`staffreplies`+1 ";
// End and execute the query
$sql .= " WHERE `id`='{$replyto}'";
hesk_dbQuery($sql);
unset($sql);
/* Update number of replies in the users table */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` SET `replies`=`replies`+1 WHERE `id`='".intval($_SESSION['id'])."'");
// --> Prepare reply 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' => $new_status,
'name' => $ticket['name'],
'subject' => $ticket['subject'],
'message' => stripslashes($message),
'attachments' => $myattachments,
'dt' => hesk_date($ticket['dt'], true),
'lastchange' => hesk_date($ticket['lastchange'], true),
'id' => $ticket['id'],
'language' => $ticket['language'],
'time_worked' => $ticket['time_worked'],
'last_reply_by' => ($submit_as_customer ? $ticket['name'] : $_SESSION['name']),
);
// 2. Add custom fields to the array
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 assigned staff?
if ($submit_as_customer)
{
if ($ticket['owner'] && $ticket['owner'] != $_SESSION['id'])
{
hesk_notifyAssignedStaff(false, 'new_reply_by_customer', 'notify_reply_my');
}
}
// Notify customer?
elseif ( ! isset($_POST['no_notify']) || intval( hesk_POST('no_notify') ) != 1)
{
hesk_notifyCustomer('new_reply_by_staff');
}
// Delete any existing drafts from this owner for this ticket
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."reply_drafts` WHERE `owner`=".intval($_SESSION['id'])." AND `ticket`=".intval($ticket['id']));
/* Set reply submitted message */
$_SESSION['HESK_SUCCESS'] = TRUE;
$_SESSION['HESK_MESSAGE'] = $hesklang['reply_submitted'];
/* What to do after reply? */
if ($_SESSION['afterreply'] == 1)
{
header('Location: admin_main.php');
}
elseif ($_SESSION['afterreply'] == 2)
{
/* Get the next open ticket that needs a reply */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` IN ('0','".intval($_SESSION['id'])."') AND " . hesk_myCategories() . " AND `status` IN ('0','1') ORDER BY `owner` DESC, `priority` ASC LIMIT 1");
if (hesk_dbNumRows($res) == 1)
{
$row = hesk_dbFetchAssoc($res);
$_SESSION['HESK_MESSAGE'] .= '<br /><br />'.$hesklang['rssn'];
header('Location: admin_ticket.php?track='.$row['trackid'].'&Refresh='.rand(10000,99999));
}
else
{
header('Location: admin_main.php');
}
}
else
{
header('Location: admin_ticket.php?track='.$ticket['trackid'].'&Refresh='.rand(10000,99999));
}
exit();
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,990 @@
<?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','../');
define('LOAD_TABS',1);
// Make sure the install folder is deleted
if (is_dir(HESK_PATH . 'install')) {die('Please delete the <b>install</b> folder from your server for security reasons then refresh this page!');}
// Get all the required files and functions
require(HESK_PATH . 'hesk_settings.inc.php');
// Save the default language for the settings page before choosing user's preferred one
$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');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// Test languages function
if (isset($_GET['test_languages']))
{
hesk_testLanguage(0);
} elseif (isset($_GET['test_themes'])) {
hesk_testTheme(0);
}
$help_folder = '../language/' . $hesk_settings['languages'][$hesk_settings['language']]['folder'] . '/help_files/';
$enable_save_settings = 0;
$enable_use_attachments = 0;
// Print header
require_once(HESK_PATH . 'inc/header.inc.php');
// Print main manage users page
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
// Demo mode? Hide values of sensitive settings
if ( defined('HESK_DEMO') )
{
$hesk_settings['db_host'] = $hesklang['hdemo'];
$hesk_settings['db_name'] = $hesklang['hdemo'];
$hesk_settings['db_user'] = $hesklang['hdemo'];
$hesk_settings['db_pass'] = $hesklang['hdemo'];
$hesk_settings['db_pfix'] = $hesklang['hdemo'];
$hesk_settings['smtp_host_name'] = $hesklang['hdemo'];
$hesk_settings['smtp_user'] = $hesklang['hdemo'];
$hesk_settings['smtp_password'] = $hesklang['hdemo'];
$hesk_settings['pop3_host_name'] = $hesklang['hdemo'];
$hesk_settings['pop3_user'] = $hesklang['hdemo'];
$hesk_settings['pop3_password'] = $hesklang['hdemo'];
$hesk_settings['imap_host_name'] = $hesklang['hdemo'];
$hesk_settings['imap_user'] = $hesklang['hdemo'];
$hesk_settings['imap_password'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_public_key'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_private_key'] = $hesklang['hdemo'];
}
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content settings">
<div class="settings__status">
<h3><?php echo $hesklang['check_status']; ?></h3>
<ul class="settings__status_list">
<li>
<div class="list--name"><?php echo $hesklang['v']; ?></div>
<div class="list--status">
<?php echo $hesk_settings['hesk_version']; ?>
<?php
if ($hesk_settings['check_updates']) {
$latest = hesk_checkVersion();
if ($latest === true) {
echo ' - <span style="color:green">' . $hesklang['hud'] . '</span> ';
} elseif ($latest != -1) {
// Is this a beta/dev version?
if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) {
echo ' <span style="color:darkorange">' . $hesklang['beta'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
} else {
echo ' - <span style="color:darkorange;font-weight:bold">' . $hesklang['hnw'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['getup']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
?>
</div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['phpv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : PHP_VERSION . ' ' . (function_exists('mysqli_connect') ? '(MySQLi)' : '(MySQL)'); ?></div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['mysqlv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : hesk_dbResult( hesk_dbQuery('SELECT VERSION() AS version') ); ?></div>
</li>
<li>
<div class="list--name">/hesk_settings.inc.php</div>
<div class="list--status">
<?php
if (is_writable(HESK_PATH . 'hesk_settings.inc.php')) {
$enable_save_settings = 1;
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_settings'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['attach_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['attach_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['attach_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['cache_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['cache_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['cache_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
?>
</div>
</li>
</ul>
</div>
<script language="javascript" type="text/javascript"><!--
function hesk_checkFields() {
var d=document.form1;
// GENERAL
if (d.s_site_title.value=='') {alert('<?php echo addslashes($hesklang['err_sname']); ?>'); return false;}
if (d.s_site_url.value=='') {alert('<?php echo addslashes($hesklang['err_surl']); ?>'); return false;}
if (d.s_hesk_title.value=='') {alert('<?php echo addslashes($hesklang['err_htitle']); ?>'); return false;}
if (d.s_hesk_url.value=='') {alert('<?php echo addslashes($hesklang['err_hurl']); ?>'); return false;}
if (d.s_webmaster_mail.value=='' || d.s_webmaster_mail.value.indexOf(".") == -1 || d.s_webmaster_mail.value.indexOf("@") == -1)
{alert('<?php echo addslashes($hesklang['err_wmmail']); ?>'); return false;}
if (d.s_noreply_mail.value=='' || d.s_noreply_mail.value.indexOf(".") == -1 || d.s_noreply_mail.value.indexOf("@") == -1)
{alert('<?php echo addslashes($hesklang['err_nomail']); ?>'); return false;}
if (d.s_db_host.value=='') {alert('<?php echo addslashes($hesklang['err_dbhost']); ?>'); return false;}
if (d.s_db_name.value=='') {alert('<?php echo addslashes($hesklang['err_dbname']); ?>'); return false;}
if (d.s_db_user.value=='') {alert('<?php echo addslashes($hesklang['err_dbuser']); ?>'); return false;}
if (d.s_db_pass.value=='')
{
if (!confirm('<?php echo addslashes($hesklang['mysql_root']); ?>'))
{
return false;
}
}
// DISABLE SUBMIT BUTTON
d.submitbutton.disabled=true;
return true;
}
function hesk_toggleLayer(nr,setto) {
if (document.all)
document.all[nr].style.display = setto;
else if (document.getElementById)
document.getElementById(nr).style.display = setto;
}
function hesk_testLanguage()
{
window.open('admin_settings_general.php?test_languages=1',"Hesk_window","height=400,width=500,menubar=0,location=0,toolbar=0,status=0,resizable=1,scrollbars=1");
return false;
}
function hesk_testTheme()
{
window.open('admin_settings_general.php?test_themes=1',"Hesk_window","height=400,width=500,menubar=0,location=0,toolbar=0,status=0,resizable=1,scrollbars=1");
return false;
}
//-->
</script>
<form method="post" action="admin_settings_save.php" name="form1" onsubmit="return hesk_checkFields()">
<div class="settings__form form">
<section class="settings__form_block">
<h3><?php echo $hesklang['gs']; ?></h3>
<div class="form-group">
<label>
<span><?php echo $hesklang['wbst_title']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#1','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_site_title" maxlength="255" value="<?php echo $hesk_settings['site_title']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['wbst_url']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#2','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_site_url" maxlength="255" value="<?php echo $hesk_settings['site_url']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['hesk_title']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>helpdesk.html#6','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_hesk_title" maxlength="255" value="<?php echo $hesk_settings['hesk_title']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['hesk_url']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>helpdesk.html#7','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_hesk_url" maxlength="255" value="<?php echo $hesk_settings['hesk_url']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['email_wm']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#4','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_webmaster_mail" maxlength="255" value="<?php echo $hesk_settings['webmaster_mail']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['email_noreply']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#5','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_noreply_mail" maxlength="255" value="<?php echo $hesk_settings['noreply_mail']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['email_name']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#6','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_noreply_name" maxlength="255" value="<?php echo $hesk_settings['noreply_name']; ?>">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['site_theme']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#58','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<div class="dropdown-select center out-close">
<select name="s_site_theme">
<?php echo hesk_testTheme(1); ?>
</select>
</div>
<button type="button" class="btn btn--blue-border" style="margin-left: 20px" ripple="ripple"
onclick="return hesk_testTheme()">
<?php echo $hesklang['test_theme_folder']; ?>
</button>
</div>
</section>
<section class="settings__form_block language">
<h3><?php echo $hesklang['lgs']; ?></h3>
<div class="form-group row">
<label>
<span><?php echo $hesklang['hesk_lang']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#9','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<div class="dropdown-select center out-close">
<select name="s_language">
<?php echo hesk_testLanguage(1); ?>
</select>
</div>
<button type="button" class="btn btn--blue-border" style="margin-left: 20px" ripple="ripple"
onclick="return hesk_testLanguage()">
<?php echo $hesklang['s_inl']; ?>
</button>
</div>
<div class="checkbox-group row">
<h5>
<span><?php echo $hesklang['s_mlang']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#43','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<label class="switch-checkbox">
<input type="checkbox" name="s_can_sel_lang" <?php echo $hesk_settings['can_sel_lang'] ? 'checked' : ''; ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
</div>
</section>
<section class="settings__form_block">
<h3><?php echo $hesklang['db']; ?></h3>
<div class="form-group">
<label>
<span><?php echo $hesklang['db_host']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#32','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_db_host" id="m1" maxlength="255" value="<?php echo $hesk_settings['db_host']; ?>" autocomplete="off">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['db_name']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#33','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_db_name" id="m2" maxlength="255" value="<?php echo $hesk_settings['db_name']; ?>" autocomplete="off">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['db_user']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#34','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_db_user" id="m3" maxlength="255" value="<?php echo $hesk_settings['db_user']; ?>" autocomplete="off">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['db_pass']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#35','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="password" class="form-control" name="s_db_pass" id="m4" maxlength="255" value="<?php echo $hesk_settings['db_pass'] ; ?>" autocomplete="off">
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['prefix']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>general.html#36','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_db_pfix" id="m5" maxlength="255" value="<?php echo $hesk_settings['db_pfix']; ?>" autocomplete="off">
</div>
</section>
<div class="settings__form_submit">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input type="hidden" name="section" value="GENERAL">
<button id="submitbutton" style="display: inline-flex" type="submit" class="btn btn-full" ripple="ripple"
<?php echo $enable_save_settings ? '' : 'disabled'; ?>>
<?php echo $hesklang['save_changes']; ?>
</button>
<a style="height: 40px" href="javascript:hesk_testMySQL()" class="btn btn--blue-border test-connection" ripple="ripple">
<?php echo $hesklang['mysqltest']; ?>
</a>
<?php if (!$enable_save_settings): ?>
<div class="error"><?php echo $hesklang['e_save_settings']; ?></div>
<?php endif; ?>
</div>
<!-- START MYSQL TEST -->
<div id="mysql_test" style="display:none">
</div>
<script language="Javascript" type="text/javascript"><!--
function hesk_testMySQL()
{
var element = document.getElementById('mysql_test');
element.innerHTML = '<img src="<?php echo HESK_PATH; ?>img/loading.gif" width="24" height="24" alt="" border="0" style="vertical-align:text-bottom" /> <i><?php echo addslashes($hesklang['contest']); ?></i>';
element.style.display = 'block';
var s_db_host = document.getElementById('m1').value;
var s_db_name = document.getElementById('m2').value;
var s_db_user = document.getElementById('m3').value;
var s_db_pass = document.getElementById('m4').value;
var s_db_pfix = document.getElementById('m5').value;
var params = "test=mysql" +
"&s_db_host=" + encodeURIComponent( s_db_host ) +
"&s_db_name=" + encodeURIComponent( s_db_name ) +
"&s_db_user=" + encodeURIComponent( s_db_user ) +
"&s_db_pass=" + encodeURIComponent( s_db_pass ) +
"&s_db_pfix=" + encodeURIComponent( s_db_pfix );
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
return;
}
xmlHttp.open('POST','test_connection.php',true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", params.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
{
element.innerHTML = xmlHttp.responseText;
}
}
xmlHttp.send(params);
}
//-->
</script>
<!-- END MYSQL TEST -->
</div>
</form>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
function hesk_checkVersion()
{
global $hesk_settings;
if ($latest = hesk_getLatestVersion() )
{
if ( strlen($latest) > 12 )
{
return -1;
}
elseif ($latest == $hesk_settings['hesk_version'])
{
return true;
}
else
{
return $latest;
}
}
else
{
return -1;
}
} // END hesk_checkVersion()
function hesk_getLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if ( file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt') )
{
if ( preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600 )
{
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'http://hesk.com/version';
// Try using cURL
if ( function_exists('curl_init') )
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($hesk_version_url) )
{
return hesk_cacheLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
} // END hesk_getLatestVersion()
function hesk_cacheLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest);
return $latest;
} // END hesk_cacheLatestVersion()
function hesk_testTheme($return_options = 1) {
global $hesk_settings, $hesklang;
$dir = HESK_PATH . 'theme/';
$path = opendir($dir);
$themes = "/theme\n";
$html = '';
/* Test all folders inside the theme folder */
while (false !== ($subdir = readdir($path))) {
if ($subdir === '.' || $subdir === '..') {
continue;
}
if (filetype($dir . $subdir) === 'dir') {
$add = 1;
$themes .= " |-> /$subdir\n";
$themes .= " |-> /customer\n";
$err = '';
//region Create Ticket
$files_to_test = array('category-select.php', 'create-ticket.php', 'create-ticket-confirmation.php');
$themes .= " |-> /create-ticket: ";
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/create-ticket/' . $test_file)) {
$err .= " |----> MISSING: $test_file\n";
}
}
if ($err) {
$add = 0;
$themes .= "ERROR\n$err";
} else {
$themes .= "OK\n";
}
//endregion
$err = '';
//region Knowledgebase
$files_to_test = array('search-results.php', 'view-article.php', 'view-category.php');
$themes .= " |-> /knowledgebase: ";
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/knowledgebase/' . $test_file)) {
$err .= " |----> MISSING: $test_file\n";
}
}
if ($err) {
$add = 0;
$themes .= "ERROR\n$err";
} else {
$themes .= "OK\n";
}
//endregion
$err = '';
//region View Ticket
$files_to_test = array('form.php', 'view-ticket.php');
$themes .= " |-> /view-ticket";
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/view-ticket/' . $test_file)) {
$err .= " |----> MISSING: $test_file\n";
}
}
if ($err) {
$add = 0;
$themes .= "ERROR\n$err";
} else {
$themes .= ": OK\n";
}
//endregion
//region Solo files
$files_to_test = array('error.php', 'index.php', 'maintenance.php');
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/' . $test_file)) {
$add = 0;
$themes .= " |----> MISSING: $test_file\n";
} else {
$themes .= " |-> $test_file: OK\n";
}
}
//endregion
if (!file_exists($dir . $subdir . '/print-ticket.php')) {
$add = 0;
$themes .= " |----> MISSING: print-ticket.php\n";
} else {
$themes .= " |-> print-ticket.php: OK\n";
}
if (!file_exists($dir . $subdir . '/config.json')) {
$add = 0;
$themes .= " |----> MISSING: config.json\n";
} else {
$themes .= " |-> config.json: OK\n";
}
}
// Build markup
if ($add) {
// Pull the name from config.json
$config = file_get_contents($dir . $subdir . '/config.json');
$config_json = json_decode($config, true);
$html .= '<option value="'.$subdir.'" '.($hesk_settings['site_theme'] === $subdir ? 'selected' : '').'>'.$config_json['name'].'</option>';
}
}
if ($return_options) {
return $html;
} else {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $hesklang['test_theme_folder']; ?></title>
<meta http-equiv="Content-Type" content="text/html;charset=<?php echo $hesklang['ENCODING']; ?>" />
<style type="text/css">
body
{
margin:5px 5px;
padding:0;
background:#fff;
color: black;
font : 68.8%/1.5 Verdana, Geneva, Arial, Helvetica, sans-serif;
text-align:left;
}
p
{
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.0em;
}
h3
{
color : #AF0000;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 1.0em;
text-align:center;
}
.title
{
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 1.0em;
}
.wrong {color : red;}
.correct {color : green;}
pre {font-size:1.2em;}
</style>
</head>
<body>
<h3><?php echo $hesklang['test_theme_folder']; ?></h3>
<p><i><?php echo $hesklang['test_theme_folder_description']; ?></i></p>
<pre><?php echo $themes; ?></pre>
<p class="text-center">
<a href="admin_settings_general.php?test_themes=1&amp;<?php echo rand(10000,99999); ?>">
<?php echo $hesklang['ta']; ?>
</a> |
<a href="#" onclick="Javascript:window.close()">
<?php echo $hesklang['cwin']; ?>
</a>
</p>
</body>
</html>
<?php
exit();
}
}
function hesk_testLanguage($return_options = 0)
{
global $hesk_settings, $hesklang;
/* Get a list of valid emails */
include_once(HESK_PATH . 'inc/email_functions.inc.php');
$valid_emails = array_keys( hesk_validEmails() );
$dir = HESK_PATH . 'language/';
$path = opendir($dir);
$text = '';
$html = '';
$text .= "/language\n";
/* Test all folders inside the language folder */
while (false !== ($subdir = readdir($path)))
{
if ($subdir == "." || $subdir == "..")
{
continue;
}
if (filetype($dir . $subdir) == 'dir')
{
$add = 1;
$langu = $dir . $subdir . '/text.php';
$email = $dir . $subdir . '/emails';
/* Check the text.php */
$text .= " |-> /$subdir\n";
$text .= " |-> text.php: ";
if (file_exists($langu))
{
$tmp = file_get_contents($langu);
// Some servers add slashes to file_get_contents output
if ( strpos ($tmp, '[\\\'LANGUAGE\\\']') !== false )
{
$tmp = stripslashes($tmp);
}
$err = '';
if (!preg_match('/\$hesklang\[\'LANGUAGE\'\]\=\'(.*)\'\;/',$tmp,$l))
{
$err .= " |----> MISSING: \$hesklang['LANGUAGE']\n";
}
if (strpos($tmp,'$hesklang[\'ENCODING\']') === false)
{
$err .= " |----> MISSING: \$hesklang['ENCODING']\n";
}
if (strpos($tmp,'$hesklang[\'_COLLATE\']') === false)
{
$err .= " |----> MISSING: \$hesklang['_COLLATE']\n";
}
if (strpos($tmp,'$hesklang[\'EMAIL_HR\']') === false)
{
$err .= " |----> MISSING: \$hesklang['EMAIL_HR']\n";
}
/* Check if language file is for current version */
if (strpos($tmp,'$hesklang[\'team\']') === false)
{
$err .= " |----> WRONG VERSION (not ".$hesk_settings['hesk_version'].")\n";
}
if ($err)
{
$text .= "ERROR\n" . $err;
$add = 0;
}
else
{
$l[1] = hesk_input($l[1]);
$l[1] = str_replace('|',' ',$l[1]);
$text .= "OK ($l[1])\n";
}
}
else
{
$text .= "ERROR\n";
$text .= " |----> MISSING: text.php\n";
$add = 0;
}
/* Check emails folder */
$text .= " |-> /emails: ";
if (file_exists($email) && filetype($email) == 'dir')
{
$err = '';
foreach ($valid_emails as $eml)
{
if (!file_exists($email.'/'.$eml.'.txt'))
{
$err .= " |----> MISSING: $eml.txt\n";
}
}
if ($err)
{
$text .= "ERROR\n" . $err;
$add = 0;
}
else
{
$text .= "OK\n";
}
}
else
{
$text .= "ERROR\n";
$text .= " |----> MISSING: /emails folder\n";
$add = 0;
}
$text .= "\n";
/* Add an option for the <select> if needed */
if ($add)
{
if ($l[1] == $hesk_settings['language'])
{
$html .= '<option value="'.$subdir.'|'.$l[1].'" selected="selected">'.$l[1].'</option>';
}
else
{
$html .= '<option value="'.$subdir.'|'.$l[1].'">'.$l[1].'</option>';
}
}
}
}
closedir($path);
/* Output select options or the test log for debugging */
if ($return_options)
{
return $html;
}
else
{
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title><?php echo $hesklang['s_inl']; ?></title>
<meta http-equiv="Content-Type" content="text/html;charset=<?php echo $hesklang['ENCODING']; ?>" />
<style type="text/css">
body
{
margin:5px 5px;
padding:0;
background:#fff;
color: black;
font : 68.8%/1.5 Verdana, Geneva, Arial, Helvetica, sans-serif;
text-align:left;
}
p
{
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.0em;
}
h3
{
color : #AF0000;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 1.0em;
text-align:center;
}
.title
{
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 1.0em;
}
.wrong {color : red;}
.correct {color : green;}
pre {font-size:1.2em;}
</style>
</head>
<body>
<h3><?php echo $hesklang['s_inl']; ?></h3>
<p><i><?php echo $hesklang['s_inle']; ?></i></p>
<pre><?php echo $text; ?></pre>
<p>&nbsp;</p>
<p align="center"><a href="admin_settings_general.php?test_languages=1&amp;<?php echo rand(10000,99999); ?>"><?php echo $hesklang['ta']; ?></a> | <a href="#" onclick="Javascript:window.close()"><?php echo $hesklang['cwin']; ?></a></p>
<p>&nbsp;</p>
</body>
</html>
<?php
exit();
}
} // END hesk_testLanguage()
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,603 @@
<?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','../');
define('LOAD_TABS',1);
// Make sure the install folder is deleted
if (is_dir(HESK_PATH . 'install')) {die('Please delete the <b>install</b> folder from your server for security reasons then refresh this page!');}
// Get all the required files and functions
require(HESK_PATH . 'hesk_settings.inc.php');
// Save the default language for the settings page before choosing user's preferred one
$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');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
$help_folder = '../language/' . $hesk_settings['languages'][$hesk_settings['language']]['folder'] . '/help_files/';
$enable_save_settings = 0;
$enable_use_attachments = 0;
// Print header
require_once(HESK_PATH . 'inc/header.inc.php');
// Print main manage users page
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
// Demo mode? Hide values of sensitive settings
if ( defined('HESK_DEMO') )
{
$hesk_settings['db_host'] = $hesklang['hdemo'];
$hesk_settings['db_name'] = $hesklang['hdemo'];
$hesk_settings['db_user'] = $hesklang['hdemo'];
$hesk_settings['db_pass'] = $hesklang['hdemo'];
$hesk_settings['db_pfix'] = $hesklang['hdemo'];
$hesk_settings['smtp_host_name'] = $hesklang['hdemo'];
$hesk_settings['smtp_user'] = $hesklang['hdemo'];
$hesk_settings['smtp_password'] = $hesklang['hdemo'];
$hesk_settings['pop3_host_name'] = $hesklang['hdemo'];
$hesk_settings['pop3_user'] = $hesklang['hdemo'];
$hesk_settings['pop3_password'] = $hesklang['hdemo'];
$hesk_settings['imap_host_name'] = $hesklang['hdemo'];
$hesk_settings['imap_user'] = $hesklang['hdemo'];
$hesk_settings['imap_password'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_public_key'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_private_key'] = $hesklang['hdemo'];
}
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content settings">
<div class="settings__status">
<h3><?php echo $hesklang['check_status']; ?></h3>
<ul class="settings__status_list">
<li>
<div class="list--name"><?php echo $hesklang['v']; ?></div>
<div class="list--status">
<?php echo $hesk_settings['hesk_version']; ?>
<?php
if ($hesk_settings['check_updates']) {
$latest = hesk_checkVersion();
if ($latest === true) {
echo ' - <span style="color:green">' . $hesklang['hud'] . '</span> ';
} elseif ($latest != -1) {
// Is this a beta/dev version?
if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) {
echo ' <span style="color:darkorange">' . $hesklang['beta'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
} else {
echo ' - <span style="color:darkorange;font-weight:bold">' . $hesklang['hnw'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['getup']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
?>
</div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['phpv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : PHP_VERSION . ' ' . (function_exists('mysqli_connect') ? '(MySQLi)' : '(MySQL)'); ?></div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['mysqlv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : hesk_dbResult( hesk_dbQuery('SELECT VERSION() AS version') ); ?></div>
</li>
<li>
<div class="list--name">/hesk_settings.inc.php</div>
<div class="list--status">
<?php
if (is_writable(HESK_PATH . 'hesk_settings.inc.php')) {
$enable_save_settings = 1;
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_settings'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['attach_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['attach_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['attach_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['cache_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['cache_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['cache_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
?>
</div>
</li>
</ul>
</div>
<script language="javascript" type="text/javascript"><!--
function hesk_checkFields() {
var d = document.form1;
// DISABLE SUBMIT BUTTON
d.submitbutton.disabled=true;
return true;
}
function hesk_toggleLayer(nr,setto) {
if (document.all)
document.all[nr].style.display = setto;
else if (document.getElementById)
document.getElementById(nr).style.display = setto;
}
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']); ?>'))
{
document.getElementById('s_email_view_ticket').checked = false;
return true;
}
else if (field == 's_email_view_ticket' && confirm('<?php echo addslashes($hesklang['re_confirm2']); ?>'))
{
document.getElementById('s_require_email_1').checked = true;
return true;
}
return false;
}
return true;
}
//-->
</script>
<form method="post" action="admin_settings_save.php" name="form1" onsubmit="return hesk_checkFields()">
<div class="settings__form form">
<section class="settings__form_block">
<h3><?php echo $hesklang['tab_3']; ?></h3>
<div class="radio-group">
<h5>
<span><?php echo $hesklang['s_ekb']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#22','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<?php
$on = $hesk_settings['kb_enable'] == 1 ? 'checked' : '';
$off = $hesk_settings['kb_enable'] ? '' : 'checked';
$only = $hesk_settings['kb_enable'] == 2 ? 'checked' : '';
?>
<div class="radio-list">
<div class="radio-custom">
<input type="radio" id="s_kb_enable1" name="s_kb_enable" value="1" <?php echo $on; ?>>
<label for="s_kb_enable1"><?php echo $hesklang['ekb_y']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_kb_enable2" name="s_kb_enable" value="2" <?php echo $only; ?>>
<label for="s_kb_enable2"><?php echo $hesklang['ekb_o']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_kb_enable0" name="s_kb_enable" value="0" <?php echo $off; ?>>
<label for="s_kb_enable0"><?php echo $hesklang['ekb_n']; ?></label>
</div>
</div>
</div>
</section>
<section class="settings__form_block">
<h3><?php echo $hesklang['kb_set']; ?></h3>
<div class="checkbox-group row">
<h5>
<span><?php echo $hesklang['swyse']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#52','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<label class="switch-checkbox">
<input type="checkbox" name="s_kb_wysiwyg" value="1" <?php if ($hesk_settings['kb_wysiwyg']) { echo 'checked'; } ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
</div>
<div class="checkbox-group row">
<h5>
<span><?php echo $hesklang['s_suggest']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#23','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<label class="switch-checkbox">
<input type="checkbox" name="s_kb_recommendanswers" value="1" <?php if ($hesk_settings['kb_recommendanswers']) { echo 'checked'; } ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
</div>
<div class="checkbox-group row">
<h5>
<span><?php echo $hesklang['s_kbr']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#24','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<label class="switch-checkbox">
<input type="checkbox" name="s_kb_rating" value="1" <?php if ($hesk_settings['kb_rating']) { echo 'checked'; } ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
</div>
<div class="checkbox-group row">
<h5>
<span><?php echo $hesklang['sav']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#58','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<label class="switch-checkbox">
<input type="checkbox" name="s_kb_views" value="1" <?php if ($hesk_settings['kb_views']) { echo 'checked'; } ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
</div>
<div class="checkbox-group row">
<h5>
<span><?php echo $hesklang['sad']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#59','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<label class="switch-checkbox">
<input type="checkbox" name="s_kb_date" value="1" <?php if ($hesk_settings['kb_date']) { echo 'checked'; } ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
</div>
<?php
$off = $hesk_settings['kb_search'] ? '' : 'checked="checked"';
$small = $hesk_settings['kb_search'] == 1 ? 'checked="checked"' : '';
$large = $hesk_settings['kb_search'] == 2 ? 'checked="checked"' : '';
?>
<div class="radio-group">
<h5>
<span><?php echo $hesklang['s_kbs']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#25','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="radio-list">
<div class="radio-custom">
<input type="radio" id="s_kb_search0" name="s_kb_search" value="0" <?php echo $off; ?>>
<label for="s_kb_search0"><?php echo $hesklang['off']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_kb_search1" name="s_kb_search" value="1" <?php echo $small; ?>>
<label for="s_kb_search1"><?php echo $hesklang['small']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_kb_search2" name="s_kb_search" value="2" <?php echo $large; ?>>
<label for="s_kb_search2"><?php echo $hesklang['large']; ?></label>
</div>
</div>
</div>
<div class="form-group short">
<label>
<span><?php echo $hesklang['s_maxsr']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#26','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_kb_search_limit" maxlength="3" value="<?php echo $hesk_settings['kb_search_limit']; ?>">
</div>
<div class="form-group short">
<label>
<span><?php echo $hesklang['s_ptxt']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#27','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" name="s_kb_substrart" class="form-control" maxlength="5" value="<?php echo $hesk_settings['kb_substrart']; ?>">
</div>
<div class="form-group short">
<label>
<span><?php echo $hesklang['s_scol']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#28','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_kb_cols" maxlength="2" value="<?php echo $hesk_settings['kb_cols']; ?>">
</div>
<div class="form-group short">
<label>
<span><?php echo $hesklang['s_psubart']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#29','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_kb_numshow" maxlength="2" value="<?php echo $hesk_settings['kb_numshow']; ?>">
</div>
<div class="form-group short list">
<label>
<span><?php echo $hesklang['s_spop']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#30','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<ul class="input-list">
<li style="display: list-item">
<input type="text" class="form-control" name="s_kb_index_popart" maxlength="2" value="<?php echo $hesk_settings['kb_index_popart']; ?>">
<?php echo $hesklang['s_onin']; ?>
</li>
<li style="display: list-item">
<input type="text" class="form-control" name="s_kb_popart" maxlength="2" value="<?php echo $hesk_settings['kb_popart']; ?>">
<?php echo $hesklang['s_onkb']; ?>
</li>
</ul>
</div>
<div class="form-group short list">
<label>
<span><?php echo $hesklang['s_slat']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#31','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<ul class="input-list">
<li style="display: list-item">
<input type="text" class="form-control" name="s_kb_index_latest" maxlength="2" value="<?php echo $hesk_settings['kb_index_latest']; ?>">
<?php echo $hesklang['s_onin']; ?>
</li>
<li style="display: list-item">
<input type="text" class="form-control" name="s_kb_latest" maxlength="2" value="<?php echo $hesk_settings['kb_latest']; ?>">
<?php echo $hesklang['s_onkb']; ?>
</li>
</ul>
</div>
<div class="form-group short">
<label>
<span><?php echo $hesklang['s_relart']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>knowledgebase.html#60','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_kb_related" maxlength="2" value="<?php echo $hesk_settings['kb_related']; ?>">
</div>
</section>
<div class="settings__form_submit">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input type="hidden" name="section" value="KNOWLEDGEBASE">
<button id="submitbutton" style="display: inline-flex" type="submit" class="btn btn-full" ripple="ripple"
<?php echo $enable_save_settings ? '' : 'disabled'; ?>>
<?php echo $hesklang['save_changes']; ?>
</button>
<?php if (!$enable_save_settings): ?>
<div class="error"><?php echo $hesklang['e_save_settings']; ?></div>
<?php endif; ?>
</div>
</div>
</form>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
function hesk_checkVersion()
{
global $hesk_settings;
if ($latest = hesk_getLatestVersion() )
{
if ( strlen($latest) > 12 )
{
return -1;
}
elseif ($latest == $hesk_settings['hesk_version'])
{
return true;
}
else
{
return $latest;
}
}
else
{
return -1;
}
} // END hesk_checkVersion()
function hesk_getLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if ( file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt') )
{
if ( preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600 )
{
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'http://hesk.com/version';
// Try using cURL
if ( function_exists('curl_init') )
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($hesk_version_url) )
{
return hesk_cacheLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
} // END hesk_getLatestVersion()
function hesk_cacheLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest);
return $latest;
} // END hesk_cacheLatestVersion()
?>

View File

@@ -0,0 +1,431 @@
<?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','../');
define('LOAD_TABS',1);
// Make sure the install folder is deleted
if (is_dir(HESK_PATH . 'install')) {die('Please delete the <b>install</b> folder from your server for security reasons then refresh this page!');}
// Get all the required files and functions
require(HESK_PATH . 'hesk_settings.inc.php');
// Save the default language for the settings page before choosing user's preferred one
$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');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
$help_folder = '../language/' . $hesk_settings['languages'][$hesk_settings['language']]['folder'] . '/help_files/';
$enable_save_settings = 0;
$enable_use_attachments = 0;
// Print header
require_once(HESK_PATH . 'inc/header.inc.php');
// Print main manage users page
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
// Demo mode? Hide values of sensitive settings
if ( defined('HESK_DEMO') )
{
$hesk_settings['db_host'] = $hesklang['hdemo'];
$hesk_settings['db_name'] = $hesklang['hdemo'];
$hesk_settings['db_user'] = $hesklang['hdemo'];
$hesk_settings['db_pass'] = $hesklang['hdemo'];
$hesk_settings['db_pfix'] = $hesklang['hdemo'];
$hesk_settings['smtp_host_name'] = $hesklang['hdemo'];
$hesk_settings['smtp_user'] = $hesklang['hdemo'];
$hesk_settings['smtp_password'] = $hesklang['hdemo'];
$hesk_settings['pop3_host_name'] = $hesklang['hdemo'];
$hesk_settings['pop3_user'] = $hesklang['hdemo'];
$hesk_settings['pop3_password'] = $hesklang['hdemo'];
$hesk_settings['imap_host_name'] = $hesklang['hdemo'];
$hesk_settings['imap_user'] = $hesklang['hdemo'];
$hesk_settings['imap_password'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_public_key'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_private_key'] = $hesklang['hdemo'];
}
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content settings">
<div class="settings__status">
<h3><?php echo $hesklang['check_status']; ?></h3>
<ul class="settings__status_list">
<li>
<div class="list--name"><?php echo $hesklang['v']; ?></div>
<div class="list--status">
<?php echo $hesk_settings['hesk_version']; ?>
<?php
if ($hesk_settings['check_updates']) {
$latest = hesk_checkVersion();
if ($latest === true) {
echo ' - <span style="color:green">' . $hesklang['hud'] . '</span> ';
} elseif ($latest != -1) {
// Is this a beta/dev version?
if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) {
echo ' <span style="color:darkorange">' . $hesklang['beta'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
} else {
echo ' - <span style="color:darkorange;font-weight:bold">' . $hesklang['hnw'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['getup']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
?>
</div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['phpv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : PHP_VERSION . ' ' . (function_exists('mysqli_connect') ? '(MySQLi)' : '(MySQL)'); ?></div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['mysqlv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : hesk_dbResult( hesk_dbQuery('SELECT VERSION() AS version') ); ?></div>
</li>
<li>
<div class="list--name">/hesk_settings.inc.php</div>
<div class="list--status">
<?php
if (is_writable(HESK_PATH . 'hesk_settings.inc.php')) {
$enable_save_settings = 1;
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_settings'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['attach_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['attach_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['attach_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['cache_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['cache_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['cache_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
?>
</div>
</li>
</ul>
</div>
<script language="javascript" type="text/javascript"><!--
function hesk_checkFields() {
var d = document.form1;
// DISABLE SUBMIT BUTTON
d.submitbutton.disabled=true;
return true;
}
function hesk_toggleLayer(nr,setto) {
if (document.all)
document.all[nr].style.display = setto;
else if (document.getElementById)
document.getElementById(nr).style.display = setto;
}
//-->
</script>
<form method="post" action="admin_settings_save.php" name="form1" onsubmit="return hesk_checkFields()">
<div class="settings__form form">
<section class="settings__form_block">
<h3><?php echo $hesklang['dat']; ?></h3>
<div class="form-group timezone">
<label>
<span><?php echo $hesklang['TZ']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#63','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<?php
// 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 name="s_timezone" id="timezone-select">
<?php
foreach ($timezone_list as $timezone => $description)
{
echo '<option value="' . $timezone . '"' . ($hesk_settings['timezone'] == $timezone ? ' selected' : '') . '>' . $description . '</option>';
}
?>
</select>
</div>
<div class="form-group">
<label>
<span><?php echo $hesklang['tfor']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#20','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_timeformat" maxlength="255" value="<?php echo $hesk_settings['timeformat']; ?>">
</div>
</section>
<section class="settings__form_block">
<h3><?php echo $hesklang['other']; ?></h3>
<div class="form-group">
<label>
<span><?php echo $hesklang['ip_whois']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#61','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</label>
<input type="text" class="form-control" name="s_ip_whois_url" maxlength="255" value="<?php echo $hesk_settings['ip_whois']; ?>">
</div>
<tr>
<td><label> </label></td>
</tr>
<div class="checkbox-group">
<h5>
<span><?php echo $hesklang['mms']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#62','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="checkbox-custom">
<input type="checkbox" id="s_maintenance_mode1" name="s_maintenance_mode" value="1" <?php if ($hesk_settings['maintenance_mode']) {echo 'checked';} ?>>
<label for="s_maintenance_mode1"><?php echo $hesklang['mmd']; ?></label>
</div>
</div>
<div class="checkbox-group">
<h5>
<span><?php echo $hesklang['al']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#21','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="checkbox-custom">
<input type="checkbox" id="s_alink1" name="s_alink" value="1" <?php if ($hesk_settings['alink']) {echo 'checked';} ?>/>
<label for="s_alink1"><?php echo $hesklang['dap']; ?></label>
</div>
</div>
<div class="checkbox-group">
<h5>
<span><?php echo $hesklang['subnot']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#48','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="checkbox-custom">
<input type="checkbox" id="s_submit_notice1" name="s_submit_notice" value="1" <?php if ($hesk_settings['submit_notice']) {echo 'checked';} ?>/>
<label for="s_submit_notice1"><?php echo $hesklang['subnot2']; ?></label>
</div>
</div>
<div class="checkbox-group multiple-emails">
<h5>
<span><?php echo $hesklang['sonline']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#56','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="checkbox-custom">
<input type="checkbox" id="s_online1" name="s_online" value="1" <?php if ($hesk_settings['online']) {echo 'checked';} ?>>
<label for="s_online1"><?php echo $hesklang['sonline2']; ?></label>
<div class="form-group">
<input type="text" name="s_online_min" class="form-control" maxlength="4" value="<?php echo $hesk_settings['online_min']; ?>">
</div>
</div>
</div>
<div class="checkbox-group">
<h5>
<span><?php echo $hesklang['updates']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>misc.html#59','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="checkbox-custom">
<input type="checkbox" id="s_check_updates1" name="s_check_updates" value="1" <?php if ($hesk_settings['check_updates']) {echo 'checked';} ?>>
<label for="s_check_updates1"><?php echo $hesklang['updates2']; ?></label>
</div>
</div>
</section>
<div class="settings__form_submit">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input type="hidden" name="section" value="MISC">
<button id="submitbutton" style="display: inline-flex" type="submit" class="btn btn-full" ripple="ripple"
<?php echo $enable_save_settings ? '' : 'disabled'; ?>>
<?php echo $hesklang['save_changes']; ?>
</button>
<?php if (!$enable_save_settings): ?>
<div class="error"><?php echo $hesklang['e_save_settings']; ?></div>
<?php endif; ?>
</div>
</div>
</form>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
function hesk_checkVersion()
{
global $hesk_settings;
if ($latest = hesk_getLatestVersion() )
{
if ( strlen($latest) > 12 )
{
return -1;
}
elseif ($latest == $hesk_settings['hesk_version'])
{
return true;
}
else
{
return $latest;
}
}
else
{
return -1;
}
} // END hesk_checkVersion()
function hesk_getLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if ( file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt') )
{
if ( preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600 )
{
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'http://hesk.com/version';
// Try using cURL
if ( function_exists('curl_init') )
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($hesk_version_url) )
{
return hesk_cacheLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
} // END hesk_getLatestVersion()
function hesk_cacheLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest);
return $latest;
} // END hesk_cacheLatestVersion()
?>

View File

@@ -0,0 +1,961 @@
<?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','../');
// Make sure OPcache is reset when modifying settings
if ( function_exists('opcache_reset') )
{
opcache_reset();
}
/* 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/email_functions.inc.php');
require(HESK_PATH . 'inc/setup_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// A security check
hesk_token_check('POST');
$section = hesk_input(hesk_POST('section'));
if (!in_array($section, array('GENERAL', 'HELP_DESK', 'KNOWLEDGEBASE', 'EMAIL', 'TICKET_LIST', 'MISC'))) {
hesk_process_messages($hesklang['err_no_settings_section'], 'admin_settings_general.php');
}
// Demo mode
if ( defined('HESK_DEMO') )
{
hesk_process_messages($hesklang['sdemo'], 'admin_settings_' . strtolower($section) . '.php');
}
$set=array();
$smtp_OK = true;
$pop3_OK = true;
if ($section === 'GENERAL') {
/* --> General settings */
$set['site_title'] = hesk_input( hesk_POST('s_site_title'), $hesklang['err_sname']);
$set['site_title'] = str_replace('\\&quot;','&quot;',$set['site_title']);
$set['site_url'] = hesk_input( hesk_POST('s_site_url'), $hesklang['err_surl']);
$set['hesk_title'] = hesk_input( hesk_POST('s_hesk_title'), $hesklang['err_htitle']);
$set['hesk_title'] = str_replace('\\&quot;','&quot;',$set['hesk_title']);
$set['hesk_url'] = rtrim( hesk_input( hesk_POST('s_hesk_url'), $hesklang['err_hurl']), '/');
$set['webmaster_mail'] = hesk_validateEmail( hesk_POST('s_webmaster_mail'), $hesklang['err_wmmail']);
$set['noreply_mail'] = hesk_validateEmail( hesk_POST('s_noreply_mail'), $hesklang['err_nomail']);
$set['noreply_name'] = hesk_input( hesk_POST('s_noreply_name') );
$set['noreply_name'] = str_replace(array('\\&quot;','&lt;','&gt;'),'',$set['noreply_name']);
$set['noreply_name'] = trim( preg_replace('/\s{2,}/', ' ', $set['noreply_name']) );
$set['noreply_name'] = preg_replace("/\n|\r|\t|%0A|%0D|%08|%09/", '', $set['noreply_name']);
$valid_themes = hesk_getValidThemes();
$theme = hesk_input(hesk_POST('s_site_theme'));
if (isset($theme) && in_array($theme, $valid_themes)) {
$set['site_theme'] = $theme;
} else {
hesk_error($hesklang['err_site_theme']);
}
/* --> Language settings */
$set['can_sel_lang'] = empty($_POST['s_can_sel_lang']) ? 0 : 1;
$set['languages'] = hesk_getLanguagesArray();
$lang = explode('|', hesk_input( hesk_POST('s_language') ) );
if (isset($lang[1]) && in_array($lang[1],hesk_getLanguagesArray(1) ))
{
$set['language'] = $lang[1];
}
else
{
hesk_error($hesklang['err_lang']);
}
/* --> Database settings */
hesk_dbClose();
if ( hesk_testMySQL() )
{
// Database connection OK
}
elseif ($mysql_log)
{
hesk_error($mysql_error . '<br /><br /><b>' . $hesklang['mysql_said'] . ':</b> ' . $mysql_log);
}
else
{
hesk_error($mysql_error);
}
} elseif ($section === 'HELP_DESK') {
// ---> check admin folder
$set['admin_dir'] = isset($_POST['s_admin_dir']) && ! is_array($_POST['s_admin_dir']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['s_admin_dir']) : 'admin';
/*
if ( ! is_dir(HESK_PATH . $set['admin_dir']) )
{
hesk_error( sprintf($hesklang['err_adf'], $set['admin_dir']) );
}
*/
// ---> check attachments folder
$set['attach_dir'] = isset($_POST['s_attach_dir']) && ! is_array($_POST['s_attach_dir']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['s_attach_dir']) : 'attachments';
/*
if ( ! is_dir(HESK_PATH . $set['attach_dir']) )
{
hesk_error( sprintf($hesklang['err_atf'], $set['attach_dir']) );
}
if ( ! is_writable(HESK_PATH . $set['attach_dir']) )
{
hesk_error( sprintf($hesklang['err_atr'], $set['attach_dir']) );
}
*/
// ---> check cache folder
$set['cache_dir'] = isset($_POST['s_cache_dir']) && ! is_array($_POST['s_cache_dir']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['s_cache_dir']) : 'cache';
$set['max_listings'] = hesk_checkMinMax( intval( hesk_POST('s_max_listings') ) , 1, 999, 10);
$set['print_font_size'] = hesk_checkMinMax( intval( hesk_POST('s_print_font_size') ) , 1, 99, 12);
$set['autoclose'] = hesk_checkMinMax( intval( hesk_POST('s_autoclose') ) , 0, 999, 7);
$set['max_open'] = hesk_checkMinMax( intval( hesk_POST('s_max_open') ) , 0, 999, 0);
$set['new_top'] = empty($_POST['s_new_top']) ? 0 : 1;
$set['reply_top'] = empty($_POST['s_reply_top']) ? 0 : 1;
/* --> Features */
$set['autologin'] = empty($_POST['s_autologin']) ? 0 : 1;
$set['autoassign'] = empty($_POST['s_autoassign']) ? 0 : 1;
$set['require_email'] = empty($_POST['s_require_email']) ? 0 : 1;
$set['require_owner'] = empty($_POST['s_require_owner']) ? 0 : 1;
$set['require_subject'] = hesk_checkMinMax( intval( hesk_POST('s_require_subject') ) , -1, 1, 1);
$set['require_message'] = hesk_checkMinMax( intval( hesk_POST('s_require_message') ) , -1, 1, 1);
$set['custclose'] = empty($_POST['s_custclose']) ? 0 : 1;
$set['custopen'] = empty($_POST['s_custopen']) ? 0 : 1;
$set['rating'] = empty($_POST['s_rating']) ? 0 : 1;
$set['cust_urgency'] = empty($_POST['s_cust_urgency']) ? 0 : 1;
$set['sequential'] = empty($_POST['s_sequential']) ? 0 : 1;
$set['time_worked'] = empty($_POST['s_time_worked']) ? 0 : 1;
$set['spam_notice'] = empty($_POST['s_spam_notice']) ? 0 : 1;
$set['list_users'] = empty($_POST['s_list_users']) ? 0 : 1;
$set['debug_mode'] = empty($_POST['s_debug_mode']) ? 0 : 1;
$set['short_link'] = empty($_POST['s_short_link']) ? 0 : 1;
$set['select_cat'] = empty($_POST['s_select_cat']) ? 0 : 1;
$set['select_pri'] = empty($_POST['s_select_pri']) ? 0 : 1;
$set['cat_show_select'] = hesk_checkMinMax( intval( hesk_POST('s_cat_show_select') ) , 0, 999, 10);
/* --> SPAM prevention */
$set['secimg_use'] = empty($_POST['s_secimg_use']) ? 0 : ( hesk_POST('s_secimg_use') == 2 ? 2 : 1);
$set['secimg_sum'] = '';
for ($i=1;$i<=10;$i++)
{
$set['secimg_sum'] .= substr('AEUYBDGHJLMNPQRSTVWXZ123456789', rand(0,29), 1);
}
$set['recaptcha_use'] = hesk_checkMinMax( intval( hesk_POST('s_recaptcha_use') ) , 0, 2, 0);
$set['recaptcha_public_key'] = hesk_input( hesk_POST('s_recaptcha_public_key') );
$set['recaptcha_private_key'] = hesk_input( hesk_POST('s_recaptcha_private_key') );
$set['question_use'] = empty($_POST['s_question_use']) ? 0 : 1;
$set['question_ask'] = hesk_getHTML( hesk_POST('s_question_ask') ) or hesk_error($hesklang['err_qask']);
$set['question_ans'] = hesk_input( hesk_POST('s_question_ans'), $hesklang['err_qans']);
/* --> Security */
$set['attempt_limit'] = hesk_checkMinMax( intval( hesk_POST('s_attempt_limit') ) , 0, 999, 5);
if ($set['attempt_limit'] > 0)
{
$set['attempt_limit']++;
}
$set['attempt_banmin'] = hesk_checkMinMax( intval( hesk_POST('s_attempt_banmin') ) , 5, 99999, 60);
$set['reset_pass'] = empty($_POST['s_reset_pass']) ? 0 : 1;
$set['email_view_ticket'] = ($set['require_email'] == 0) ? 0 : (empty($_POST['s_email_view_ticket']) ? 0 : 1);
$set['x_frame_opt'] = empty($_POST['s_x_frame_opt']) ? 0 : 1;
$set['force_ssl'] = HESK_SSL && isset($_POST['s_force_ssl']) && $_POST['s_force_ssl'] == 1 ? 1 : 0;
// Make sure help desk URL starts with https if forcing SSL
if ($set['force_ssl'])
{
$set['hesk_url'] = preg_replace('/^http:/i', 'https:', hesk_getProperty($set, 'hesk_url') );
}
/* --> Attachments */
$set['attachments']['use'] = empty($_POST['s_attach_use']) ? 0 : 1;
if ($set['attachments']['use'])
{
$set['attachments']['max_number'] = intval( hesk_POST('s_max_number', 2) );
$size = floatval( hesk_POST('s_max_size', '1.0') );
$unit = hesk_htmlspecialchars( hesk_POST('s_max_unit', 'MB') );
$set['attachments']['max_size'] = hesk_formatUnits($size . ' ' . $unit);
$set['attachments']['allowed_types'] = isset($_POST['s_allowed_types']) && ! is_array($_POST['s_allowed_types']) && strlen($_POST['s_allowed_types']) ? explode(',', strtolower( preg_replace('/[^a-zA-Z0-9,]/', '', $_POST['s_allowed_types']) ) ) : array();
$set['attachments']['allowed_types'] = array_diff($set['attachments']['allowed_types'], array('php', 'php4', 'php3', 'php5', 'phps', 'phtml', 'shtml', 'shtm', 'cgi', 'pl') );
if (count($set['attachments']['allowed_types']))
{
$keep_these = array();
foreach ($set['attachments']['allowed_types'] as $ext)
{
if (strlen($ext) > 1)
{
$keep_these[] = '.' . $ext;
}
}
$set['attachments']['allowed_types'] = $keep_these;
}
else
{
$set['attachments']['allowed_types'] = array('.gif','.jpg','.png','.zip','.rar','.csv','.doc','.docx','.xls','.xlsx','.txt','.pdf');
}
}
else
{
$set['attachments']['max_number']=2;
$set['attachments']['max_size']=1048576;
$set['attachments']['allowed_types']=array('.gif','.jpg','.png','.zip','.rar','.csv','.doc','.docx','.xls','.xlsx','.txt','.pdf');
}
} elseif ($section === 'KNOWLEDGEBASE') {
/* --> Knowledgebase settings */
$set['kb_enable'] = hesk_checkMinMax( intval( hesk_POST('s_kb_enable') ) , 0, 2, 1);
$set['kb_wysiwyg'] = empty($_POST['s_kb_wysiwyg']) ? 0 : 1;
$set['kb_search'] = empty($_POST['s_kb_search']) ? 0 : ( hesk_POST('s_kb_search') == 2 ? 2 : 1);
$set['kb_recommendanswers'] = empty($_POST['s_kb_recommendanswers']) ? 0 : 1;
$set['kb_views'] = empty($_POST['s_kb_views']) ? 0 : 1;
$set['kb_date'] = empty($_POST['s_kb_date']) ? 0 : 1;
$set['kb_rating'] = empty($_POST['s_kb_rating']) ? 0 : 1;
$set['kb_search_limit'] = hesk_checkMinMax( intval( hesk_POST('s_kb_search_limit') ) , 1, 99, 10);
$set['kb_substrart'] = hesk_checkMinMax( intval( hesk_POST('s_kb_substrart') ) , 20, 9999, 200);
$set['kb_cols'] = hesk_checkMinMax( intval( hesk_POST('s_kb_cols') ) , 1, 5, 2);
$set['kb_numshow'] = intval( hesk_POST('s_kb_numshow') ); // Popular articles on subcat listing
$set['kb_popart'] = intval( hesk_POST('s_kb_popart') ); // Popular articles on main category page
$set['kb_latest'] = intval( hesk_POST('s_kb_latest') ); // Popular articles on main category page
$set['kb_index_popart'] = intval( hesk_POST('s_kb_index_popart') );
$set['kb_index_latest'] = intval( hesk_POST('s_kb_index_latest') );
$set['kb_related'] = intval( hesk_POST('s_kb_related') );
} elseif ($section === 'EMAIL') {
/* --> Email sending */
$set['smtp'] = empty($_POST['s_smtp']) ? 0 : 1;
if ($set['smtp'])
{
// Test SMTP connection
$smtp_OK = hesk_testSMTP(true);
// If SMTP not working, disable it
if ( ! $smtp_OK)
{
$set['smtp'] = 0;
}
}
else
{
$set['smtp_host_name'] = hesk_input( hesk_POST('tmp_smtp_host_name', 'mail.example.com') );
$set['smtp_host_port'] = intval( hesk_POST('tmp_smtp_host_port', 25) );
$set['smtp_timeout'] = intval( hesk_POST('tmp_smtp_timeout', 10) );
$set['smtp_ssl'] = empty($_POST['tmp_smtp_ssl']) ? 0 : 1;
$set['smtp_tls'] = empty($_POST['tmp_smtp_tls']) ? 0 : 1;
$set['smtp_user'] = hesk_input( hesk_POST('tmp_smtp_user') );
$set['smtp_password'] = hesk_input( hesk_POST('tmp_smtp_password') );
}
/* --> Email piping */
$set['email_piping'] = empty($_POST['s_email_piping']) ? 0 : 1;
/* --> POP3 fetching */
$set['pop3'] = empty($_POST['s_pop3']) ? 0 : 1;
if ($set['pop3'])
{
// Get POP3 fetching timeout
$set['pop3_job_wait'] = hesk_checkMinMax( intval( hesk_POST('s_pop3_job_wait') ) , 0, 1440, 15);
// Test POP3 connection
$pop3_OK = hesk_testPOP3(true);
// If POP3 not working, disable it
if ( ! $pop3_OK)
{
$set['pop3'] = 0;
}
}
else
{
$set['pop3_job_wait'] = intval( hesk_POST('s_pop3_job_wait', 15) );
$set['pop3_host_name'] = hesk_input( hesk_POST('tmp_pop3_host_name', 'mail.example.com') );
$set['pop3_host_port'] = intval( hesk_POST('tmp_pop3_host_port', 110) );
$set['pop3_tls'] = empty($_POST['tmp_pop3_tls']) ? 0 : 1;
$set['pop3_keep'] = empty($_POST['tmp_pop3_keep']) ? 0 : 1;
$set['pop3_user'] = hesk_input( hesk_POST('tmp_pop3_user') );
$set['pop3_password'] = hesk_input( hesk_POST('tmp_pop3_password') );
}
/* --> IMAP fetching */
$imap_OK = true;
$set['imap'] = function_exists('imap_open') ? (empty($_POST['s_imap']) ? 0 : 1) : 0;
if ($set['imap'])
{
// Get IMAP fetching timeout
$set['imap_job_wait'] = hesk_checkMinMax( intval( hesk_POST('s_imap_job_wait') ) , 0, 1440, 15);
// Test IMAP connection
$imap_OK = hesk_testIMAP(true);
// If IMAP not working, disable it
if ( ! $imap_OK)
{
$set['imap'] = 0;
}
}
else
{
$set['imap_job_wait'] = intval( hesk_POST('s_imap_job_wait', 15) );
$set['imap_host_name'] = hesk_input( hesk_POST('tmp_imap_host_name', 'mail.example.com') );
$set['imap_host_port'] = intval( hesk_POST('tmp_imap_host_port', 110) );
$set['imap_enc'] = hesk_POST('tmp_imap_enc');
$set['imap_enc'] = ($set['imap_enc'] == 'ssl' || $set['imap_enc'] == 'tls') ? $set['imap_enc'] : '';
$set['imap_keep'] = empty($_POST['tmp_imap_keep']) ? 0 : 1;
$set['imap_user'] = hesk_input( hesk_POST('tmp_imap_user') );
$set['imap_password'] = hesk_input( hesk_POST('tmp_imap_password') );
}
/* --> Email loops */
$set['loop_hits'] = hesk_checkMinMax( intval( hesk_POST('s_loop_hits') ) , 0, 999, 5);
$set['loop_time'] = hesk_checkMinMax( intval( hesk_POST('s_loop_time') ) , 1, 86400, 300);
/* --> Detect email typos */
$set['detect_typos'] = empty($_POST['s_detect_typos']) ? 0 : 1;
$set['email_providers'] = array();
if ( ! empty($_POST['s_email_providers']) && ! is_array($_POST['s_email_providers']) )
{
$lines = preg_split('/$\R?^/m', hesk_input($_POST['s_email_providers']) );
foreach ($lines as $domain)
{
$domain = trim($domain);
$domain = str_replace('@', '', $domain);
$domainLen = strlen($domain);
/* Check domain part length */
if ($domainLen < 1 || $domainLen > 254)
{
continue;
}
/* Check domain part characters */
if ( ! preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain) )
{
continue;
}
/* Domain part mustn't have two consecutive dots */
if ( strpos($domain, '..') !== false )
{
continue;
}
$set['email_providers'][] = $domain;
}
}
if ( ! $set['detect_typos'] || count($set['email_providers']) < 1 )
{
$set['detect_typos'] = 0;
$set['email_providers']=array('aim.com','aol.co.uk','aol.com','att.net','bellsouth.net','blueyonder.co.uk','bt.com','btinternet.com','btopenworld.com','charter.net','comcast.net','cox.net','earthlink.net','email.com','facebook.com','fastmail.fm','free.fr','freeserve.co.uk','gmail.com','gmx.at','gmx.ch','gmx.com','gmx.de','gmx.fr','gmx.net','gmx.us','googlemail.com','hotmail.be','hotmail.co.uk','hotmail.com','hotmail.com.ar','hotmail.com.mx','hotmail.de','hotmail.es','hotmail.fr','hushmail.com','icloud.com','inbox.com','laposte.net','lavabit.com','list.ru','live.be','live.co.uk','live.com','live.com.ar','live.com.mx','live.de','live.fr','love.com','lycos.com','mac.com','mail.com','mail.ru','me.com','msn.com','nate.com','naver.com','neuf.fr','ntlworld.com','o2.co.uk','online.de','orange.fr','orange.net','outlook.com','pobox.com','prodigy.net.mx','qq.com','rambler.ru','rocketmail.com','safe-mail.net','sbcglobal.net','t-online.de','talktalk.co.uk','tiscali.co.uk','verizon.net','virgin.net','virginmedia.com','wanadoo.co.uk','wanadoo.fr','yahoo.co.id','yahoo.co.in','yahoo.co.jp','yahoo.co.kr','yahoo.co.uk','yahoo.com','yahoo.com.ar','yahoo.com.mx','yahoo.com.ph','yahoo.com.sg','yahoo.de','yahoo.fr','yandex.com','yandex.ru','ymail.com');
}
$set['email_providers'] = count($set['email_providers']) ? "'" . implode("','", array_unique($set['email_providers'])) . "'" : '';
/* --> Notify customer when */
$set['notify_new'] = empty($_POST['s_notify_new']) ? 0 : 1;
$set['notify_closed'] = empty($_POST['s_notify_closed']) ? 0 : 1;
// SPAM tags
$set['notify_skip_spam'] = empty($_POST['s_notify_skip_spam']) ? 0 : 1;
$set['notify_spam_tags'] = array();
if ( ! empty($_POST['s_notify_spam_tags']) && ! is_array($_POST['s_notify_spam_tags']) )
{
$lines = preg_split('/$\R?^/m', $_POST['s_notify_spam_tags']);
foreach ($lines as $tag)
{
// Remove dangerous tags just as an extra precaution
$tag = str_replace( array('<?php', '<?', '<%', '<script'), '', $tag);
// Remove excess spaces
$tag = trim($tag);
// Remove anything not utf-8
$tag = hesk_clean_utf8($tag);
// Limit tag length
if ( strlen($tag) < 1 || strlen($tag) > 50)
{
continue;
}
// Escape single quotes and backslashes
$set['notify_spam_tags'][] = str_replace( array("\\", "'"), array("\\\\", "\\'"), $tag); // '
}
}
if ( count($set['notify_spam_tags']) < 1 )
{
$set['notify_skip_spam'] = 0;
$set['notify_spam_tags'] = array('Spam?}','***SPAM***','[SPAM]','SPAM-LOW:','SPAM-MED:');
}
$set['notify_spam_tags'] = count($set['notify_spam_tags']) ? "'" . implode("','", $set['notify_spam_tags']) . "'" : '';
/* --> Other */
$set['strip_quoted'] = empty($_POST['s_strip_quoted']) ? 0 : 1;
$set['eml_req_msg'] = empty($_POST['s_eml_req_msg']) ? 0 : 1;
$set['save_embedded'] = empty($_POST['s_save_embedded']) ? 0 : 1;
$set['multi_eml'] = empty($_POST['s_multi_eml']) ? 0 : 1;
$set['confirm_email'] = empty($_POST['s_confirm_email']) ? 0 : 1;
$set['open_only'] = empty($_POST['s_open_only']) ? 0 : 1;
} elseif ($section === 'TICKET_LIST') {
$set['ticket_list'] = array();
foreach ($hesk_settings['possible_ticket_list'] as $key => $title)
{
if ( hesk_POST('s_tl_'.$key, 0) == 1)
{
$set['ticket_list'][] = $key;
}
}
// We need at least one of these: id, trackid, subject
if ( ! in_array('id', $set['ticket_list']) && ! in_array('trackid', $set['ticket_list']) && ! in_array('subject', $set['ticket_list']) )
{
// Non of the required fields are there, add "trackid" as the first one
array_unshift($set['ticket_list'], 'trackid');
}
$set['ticket_list'] = count($set['ticket_list']) ? "'" . implode("','", $set['ticket_list']) . "'" : 'trackid';
/* --> Other */
$set['submittedformat'] = hesk_checkMinMax( intval( hesk_POST('s_submittedformat') ) , 0, 2, 2);
$set['updatedformat'] = hesk_checkMinMax( intval( hesk_POST('s_updatedformat') ) , 0, 2, 2);
} elseif ($section === 'MISC') {
/* --> Date & Time */
$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 */
$set['ip_whois'] = hesk_input( hesk_POST('s_ip_whois_url', 'https://whois.domaintools.com/{IP}') );
// If no {IP} tag append it to the end
if ( strlen($set['ip_whois']) == 0 )
{
$set['ip_whois'] = 'http://whois.domaintools.com/{IP}';
}
elseif ( strpos($set['ip_whois'], '{IP}') === false )
{
$set['ip_whois'] .= '{IP}';
}
$set['maintenance_mode']= empty($_POST['s_maintenance_mode']) ? 0 : 1;
$set['alink'] = empty($_POST['s_alink']) ? 0 : 1;
$set['submit_notice'] = empty($_POST['s_submit_notice']) ? 0 : 1;
$set['online'] = empty($_POST['s_online']) ? 0 : 1;
$set['online_min'] = hesk_checkMinMax( intval( hesk_POST('s_online_min') ) , 1, 999, 10);
$set['check_updates'] = empty($_POST['s_check_updates']) ? 0 : 1;
}
$set['hesk_version'] = $hesk_settings['hesk_version'];
// Prepare settings file and save it
$settings_file_content='<?php
// Settings file for HESK ' . $set['hesk_version'] . '
// ==> GENERAL
// --> General settings
$hesk_settings[\'site_title\']=\'' . hesk_getProperty($set, 'site_title') . '\';
$hesk_settings[\'site_url\']=\'' . hesk_getProperty($set, 'site_url') . '\';
$hesk_settings[\'hesk_title\']=\'' . hesk_getProperty($set, 'hesk_title') . '\';
$hesk_settings[\'hesk_url\']=\'' . hesk_getProperty($set, 'hesk_url') . '\';
$hesk_settings[\'webmaster_mail\']=\'' . hesk_getProperty($set, 'webmaster_mail') . '\';
$hesk_settings[\'noreply_mail\']=\'' . hesk_getProperty($set, 'noreply_mail') . '\';
$hesk_settings[\'noreply_name\']=\'' . hesk_getProperty($set, 'noreply_name') . '\';
$hesk_settings[\'site_theme\']=\'' . hesk_getProperty($set, 'site_theme') . '\';
// --> Language settings
$hesk_settings[\'can_sel_lang\']=' . hesk_getProperty($set, 'can_sel_lang') . ';
$hesk_settings[\'language\']=\'' . hesk_getProperty($set, 'language') . '\';
$hesk_settings[\'languages\']=array(
'.hesk_getLanguageForFile($set, 'languages').');
// --> Database settings
$hesk_settings[\'db_host\']=\'' . hesk_getProperty($set, 'db_host') . '\';
$hesk_settings[\'db_name\']=\'' . hesk_getProperty($set, 'db_name') . '\';
$hesk_settings[\'db_user\']=\'' . hesk_getProperty($set, 'db_user') . '\';
$hesk_settings[\'db_pass\']=\'' . hesk_getProperty($set, 'db_pass') . '\';
$hesk_settings[\'db_pfix\']=\'' . hesk_getProperty($set, 'db_pfix') . '\';
$hesk_settings[\'db_vrsn\']=' . hesk_getProperty($set, 'db_vrsn') . ';
// ==> HELP DESK
// --> Help desk settings
$hesk_settings[\'admin_dir\']=\'' . hesk_getProperty($set, 'admin_dir') . '\';
$hesk_settings[\'attach_dir\']=\'' . hesk_getProperty($set, 'attach_dir') . '\';
$hesk_settings[\'cache_dir\']=\'' . hesk_getProperty($set, 'cache_dir') . '\';
$hesk_settings[\'max_listings\']=' . hesk_getProperty($set, 'max_listings') . ';
$hesk_settings[\'print_font_size\']=' . hesk_getProperty($set, 'print_font_size') . ';
$hesk_settings[\'autoclose\']=' . hesk_getProperty($set, 'autoclose') . ';
$hesk_settings[\'max_open\']=' . hesk_getProperty($set, 'max_open') . ';
$hesk_settings[\'new_top\']=' . hesk_getProperty($set, 'new_top') . ';
$hesk_settings[\'reply_top\']=' . hesk_getProperty($set, 'reply_top') . ';
// --> Features
$hesk_settings[\'autologin\']=' . hesk_getProperty($set, 'autologin') . ';
$hesk_settings[\'autoassign\']=' . hesk_getProperty($set, 'autoassign') . ';
$hesk_settings[\'require_email\']=' . hesk_getProperty($set, 'require_email') . ';
$hesk_settings[\'require_owner\']=' . hesk_getProperty($set, 'require_owner') . ';
$hesk_settings[\'require_subject\']=' . hesk_getProperty($set, 'require_subject') . ';
$hesk_settings[\'require_message\']=' . hesk_getProperty($set, 'require_message') . ';
$hesk_settings[\'custclose\']=' . hesk_getProperty($set, 'custclose') . ';
$hesk_settings[\'custopen\']=' . hesk_getProperty($set, 'custopen') . ';
$hesk_settings[\'rating\']=' . hesk_getProperty($set, 'rating') . ';
$hesk_settings[\'cust_urgency\']=' . hesk_getProperty($set, 'cust_urgency') . ';
$hesk_settings[\'sequential\']=' . hesk_getProperty($set, 'sequential') . ';
$hesk_settings[\'time_worked\']=' . hesk_getProperty($set, 'time_worked') . ';
$hesk_settings[\'spam_notice\']=' . hesk_getProperty($set, 'spam_notice') . ';
$hesk_settings[\'list_users\']=' . hesk_getProperty($set, 'list_users') . ';
$hesk_settings[\'debug_mode\']=' . hesk_getProperty($set, 'debug_mode') . ';
$hesk_settings[\'short_link\']=' . hesk_getProperty($set, 'short_link') . ';
$hesk_settings[\'select_cat\']=' . hesk_getProperty($set, 'select_cat') . ';
$hesk_settings[\'select_pri\']=' . hesk_getProperty($set, 'select_pri') . ';
$hesk_settings[\'cat_show_select\']=' . hesk_getProperty($set, 'cat_show_select') . ';
// --> SPAM Prevention
$hesk_settings[\'secimg_use\']=' . hesk_getProperty($set, 'secimg_use') . ';
$hesk_settings[\'secimg_sum\']=\'' . hesk_getProperty($set, 'secimg_sum') . '\';
$hesk_settings[\'recaptcha_use\']=' . hesk_getProperty($set, 'recaptcha_use') . ';
$hesk_settings[\'recaptcha_public_key\']=\'' . hesk_getProperty($set, 'recaptcha_public_key') . '\';
$hesk_settings[\'recaptcha_private_key\']=\'' . hesk_getProperty($set, 'recaptcha_private_key') . '\';
$hesk_settings[\'question_use\']=' . hesk_getProperty($set, 'question_use') . ';
$hesk_settings[\'question_ask\']=\'' . hesk_getProperty($set, 'question_ask') . '\';
$hesk_settings[\'question_ans\']=\'' . hesk_getProperty($set, 'question_ans') . '\';
// --> Security
$hesk_settings[\'attempt_limit\']=' . hesk_getProperty($set, 'attempt_limit') . ';
$hesk_settings[\'attempt_banmin\']=' . hesk_getProperty($set, 'attempt_banmin') . ';
$hesk_settings[\'reset_pass\']=' . hesk_getProperty($set, 'reset_pass') . ';
$hesk_settings[\'email_view_ticket\']=' . hesk_getProperty($set, 'email_view_ticket') . ';
$hesk_settings[\'x_frame_opt\']=' . hesk_getProperty($set, 'x_frame_opt') . ';
$hesk_settings[\'force_ssl\']=' . hesk_getProperty($set, 'force_ssl') . ';
// --> Attachments
$hesk_settings[\'attachments\']=array (
\'use\' => ' . (isset($set['attachments']) ? $set['attachments']['use'] : $hesk_settings['attachments']['use']) . ',
\'max_number\' => ' . (isset($set['attachments']) ? $set['attachments']['max_number'] : $hesk_settings['attachments']['max_number']) . ',
\'max_size\' => ' . (isset($set['attachments']) ? $set['attachments']['max_size'] : $hesk_settings['attachments']['max_size']) . ',
\'allowed_types\' => array(\'' . implode('\',\'',hesk_getAllowedAttachmentTypes($set)) . '\')
);
// ==> KNOWLEDGEBASE
// --> Knowledgebase settings
$hesk_settings[\'kb_enable\']=' . hesk_getProperty($set, 'kb_enable') . ';
$hesk_settings[\'kb_wysiwyg\']=' . hesk_getProperty($set, 'kb_wysiwyg') . ';
$hesk_settings[\'kb_search\']=' . hesk_getProperty($set, 'kb_search') . ';
$hesk_settings[\'kb_search_limit\']=' . hesk_getProperty($set, 'kb_search_limit') . ';
$hesk_settings[\'kb_views\']=' . hesk_getProperty($set, 'kb_views') . ';
$hesk_settings[\'kb_date\']=' . hesk_getProperty($set, 'kb_date') . ';
$hesk_settings[\'kb_recommendanswers\']=' . hesk_getProperty($set, 'kb_recommendanswers') . ';
$hesk_settings[\'kb_rating\']=' . hesk_getProperty($set, 'kb_rating') . ';
$hesk_settings[\'kb_substrart\']=' . hesk_getProperty($set, 'kb_substrart') . ';
$hesk_settings[\'kb_cols\']=' . hesk_getProperty($set, 'kb_cols') . ';
$hesk_settings[\'kb_numshow\']=' . hesk_getProperty($set, 'kb_numshow') . ';
$hesk_settings[\'kb_popart\']=' . hesk_getProperty($set, 'kb_popart') . ';
$hesk_settings[\'kb_latest\']=' . hesk_getProperty($set, 'kb_latest') . ';
$hesk_settings[\'kb_index_popart\']=' . hesk_getProperty($set, 'kb_index_popart') . ';
$hesk_settings[\'kb_index_latest\']=' . hesk_getProperty($set, 'kb_index_latest') . ';
$hesk_settings[\'kb_related\']=' . hesk_getProperty($set, 'kb_related') . ';
// ==> EMAIL
// --> Email sending
$hesk_settings[\'smtp\']=' . hesk_getProperty($set, 'smtp') . ';
$hesk_settings[\'smtp_host_name\']=\'' . hesk_getProperty($set, 'smtp_host_name') . '\';
$hesk_settings[\'smtp_host_port\']=' . hesk_getProperty($set, 'smtp_host_port') . ';
$hesk_settings[\'smtp_timeout\']=' . hesk_getProperty($set, 'smtp_timeout') . ';
$hesk_settings[\'smtp_ssl\']=' . hesk_getProperty($set, 'smtp_ssl') . ';
$hesk_settings[\'smtp_tls\']=' . hesk_getProperty($set, 'smtp_tls') . ';
$hesk_settings[\'smtp_user\']=\'' . hesk_getProperty($set, 'smtp_user') . '\';
$hesk_settings[\'smtp_password\']=\'' . hesk_getProperty($set, 'smtp_password') . '\';
// --> Email piping
$hesk_settings[\'email_piping\']=' . hesk_getProperty($set, 'email_piping') . ';
// --> POP3 Fetching
$hesk_settings[\'pop3\']=' . hesk_getProperty($set, 'pop3') . ';
$hesk_settings[\'pop3_job_wait\']=' . hesk_getProperty($set, 'pop3_job_wait') . ';
$hesk_settings[\'pop3_host_name\']=\'' . hesk_getProperty($set, 'pop3_host_name') . '\';
$hesk_settings[\'pop3_host_port\']=' . hesk_getProperty($set, 'pop3_host_port') . ';
$hesk_settings[\'pop3_tls\']=' . hesk_getProperty($set, 'pop3_tls') . ';
$hesk_settings[\'pop3_keep\']=' . hesk_getProperty($set, 'pop3_keep') . ';
$hesk_settings[\'pop3_user\']=\'' . hesk_getProperty($set, 'pop3_user') . '\';
$hesk_settings[\'pop3_password\']=\'' . hesk_getProperty($set, 'pop3_password') . '\';
// --> IMAP Fetching
$hesk_settings[\'imap\']=' . hesk_getProperty($set, 'imap') . ';
$hesk_settings[\'imap_job_wait\']=' . hesk_getProperty($set, 'imap_job_wait') . ';
$hesk_settings[\'imap_host_name\']=\'' . hesk_getProperty($set, 'imap_host_name') . '\';
$hesk_settings[\'imap_host_port\']=' . hesk_getProperty($set, 'imap_host_port') . ';
$hesk_settings[\'imap_enc\']=\'' . hesk_getProperty($set, 'imap_enc') . '\';
$hesk_settings[\'imap_keep\']=' . hesk_getProperty($set, 'imap_keep') . ';
$hesk_settings[\'imap_user\']=\'' . hesk_getProperty($set, 'imap_user') . '\';
$hesk_settings[\'imap_password\']=\'' . hesk_getProperty($set, 'imap_password') . '\';
// --> Email loops
$hesk_settings[\'loop_hits\']=' . hesk_getProperty($set, 'loop_hits') . ';
$hesk_settings[\'loop_time\']=' . hesk_getProperty($set, 'loop_time') . ';
// --> Detect email typos
$hesk_settings[\'detect_typos\']=' . hesk_getProperty($set, 'detect_typos') . ';
$hesk_settings[\'email_providers\']=array(' . hesk_getProperty($set, 'email_providers') . ');
// --> Notify customer when
$hesk_settings[\'notify_new\']=' . hesk_getProperty($set, 'notify_new') . ';
$hesk_settings[\'notify_skip_spam\']=' . hesk_getProperty($set, 'notify_skip_spam') . ';
$hesk_settings[\'notify_spam_tags\']=array(' . hesk_getProperty($set, 'notify_spam_tags') . ');
$hesk_settings[\'notify_closed\']=' . hesk_getProperty($set, 'notify_closed') . ';
// --> Other
$hesk_settings[\'strip_quoted\']=' . hesk_getProperty($set, 'strip_quoted') . ';
$hesk_settings[\'eml_req_msg\']=' . hesk_getProperty($set, 'eml_req_msg') . ';
$hesk_settings[\'save_embedded\']=' . hesk_getProperty($set, 'save_embedded') . ';
$hesk_settings[\'multi_eml\']=' . hesk_getProperty($set, 'multi_eml') . ';
$hesk_settings[\'confirm_email\']=' . hesk_getProperty($set, 'confirm_email') . ';
$hesk_settings[\'open_only\']=' . hesk_getProperty($set, 'open_only') . ';
// ==> TICKET LIST
$hesk_settings[\'ticket_list\']=array(' . hesk_getProperty($set, 'ticket_list') . ');
// --> Other
$hesk_settings[\'submittedformat\']=' . hesk_getProperty($set, 'submittedformat') . ';
$hesk_settings[\'updatedformat\']=' . hesk_getProperty($set, 'updatedformat') . ';
// ==> MISC
// --> Date & Time
$hesk_settings[\'timezone\']=\'' . hesk_getProperty($set, 'timezone') . '\';
$hesk_settings[\'timeformat\']=\'' . hesk_getProperty($set, 'timeformat') . '\';
// --> Other
$hesk_settings[\'ip_whois\']=\'' . hesk_getProperty($set, 'ip_whois') . '\';
$hesk_settings[\'maintenance_mode\']=' . hesk_getProperty($set, 'maintenance_mode') . ';
$hesk_settings[\'alink\']=' . hesk_getProperty($set, 'alink') . ';
$hesk_settings[\'submit_notice\']=' . hesk_getProperty($set, 'submit_notice') . ';
$hesk_settings[\'online\']=' . hesk_getProperty($set, 'online') . ';
$hesk_settings[\'online_min\']=' . hesk_getProperty($set, 'online_min') . ';
$hesk_settings[\'check_updates\']=' . hesk_getProperty($set, 'check_updates') . ';
#############################
# DO NOT EDIT BELOW #
#############################
$hesk_settings[\'hesk_version\']=\'' . $set['hesk_version'] . '\';
if ($hesk_settings[\'debug_mode\'])
{
error_reporting(E_ALL);
}
else
{
error_reporting(0);
}
if (!defined(\'IN_SCRIPT\')) {die(\'Invalid attempt!\');}';
// Write to the settings file
if ( ! file_put_contents(HESK_PATH . 'hesk_settings.inc.php', $settings_file_content) )
{
hesk_error($hesklang['err_openset']);
}
// Any settings problems?
$tmp = array();
if ( ! $smtp_OK)
{
$tmp[] = '<span style="color:red; font-weight:bold">'.$hesklang['sme'].':</span> '.$smtp_error.'<br /><br /><a href="Javascript:void(0)" onclick="Javascript:hesk_toggleLayerDisplay(\'smtplog\')">'.$hesklang['scl'].'</a><div id="smtplog" style="display:none">&nbsp;<br /><textarea name="log" rows="10" cols="60">'.$smtp_log.'</textarea></div>';
}
if ( ! $pop3_OK)
{
$tmp[] = '<span style="color:red; font-weight:bold">'.$hesklang['pop3e'].':</span> '.$pop3_error.'<br /><br /><a href="Javascript:void(0)" onclick="Javascript:hesk_toggleLayerDisplay(\'pop3log\')">'.$hesklang['pop3log'].'</a><div id="pop3log" style="display:none">&nbsp;<br /><textarea name="log" rows="10" cols="60">'.$pop3_log.'</textarea></div>';
}
// Clear the cache folder
hesk_purge_cache('kb');
hesk_purge_cache('cf');
hesk_purge_cache('export', 14400);
hesk_purge_cache('status');
// Show the settings page and display any notices or success
$return_location = 'admin_settings_' . strtolower($section) . '.php';
if ( count($tmp) )
{
$errors = implode('<br /><br />', $tmp);
hesk_process_messages( $hesklang['sns'] . '<br /><br />' . $errors,$return_location,'NOTICE');
}
else
{
hesk_process_messages($hesklang['set_were_saved'],$return_location,'SUCCESS');
}
exit();
/** FUNCTIONS **/
function hesk_getLanguagesArray($returnArray=0)
{
global $hesk_settings, $hesklang;
/* Get a list of valid emails */
$hesk_settings['smtp'] = 0;
$valid_emails = array_keys( hesk_validEmails() );
$dir = HESK_PATH . 'language/';
$path = opendir($dir);
$code = '';
$langArray = array();
/* Test all folders inside the language folder */
while (false !== ($subdir = readdir($path)))
{
if ($subdir == "." || $subdir == "..")
{
continue;
}
if (filetype($dir . $subdir) == 'dir')
{
$add = 1;
$langu = $dir . $subdir . '/text.php';
$email = $dir . $subdir . '/emails';
/* Check the text.php */
if (file_exists($langu))
{
$tmp = file_get_contents($langu);
// Some servers add slashes to file_get_contents output
if ( strpos ($tmp, '[\\\'LANGUAGE\\\']') !== false )
{
$tmp = stripslashes($tmp);
}
$err = '';
if ( ! preg_match('/\$hesklang\[\'LANGUAGE\'\]\=\'(.*)\'\;/', $tmp, $l) )
{
$add = 0;
}
elseif ( ! preg_match('/\$hesklang\[\'ENCODING\'\]\=\'(.*)\'\;/', $tmp) )
{
$add = 0;
}
elseif ( ! preg_match('/\$hesklang\[\'_COLLATE\'\]\=\'(.*)\'\;/', $tmp) )
{
$add = 0;
}
elseif ( ! preg_match('/\$hesklang\[\'EMAIL_HR\'\]\=\'(.*)\'\;/', $tmp, $hr) )
{
$add = 0;
}
elseif ( ! preg_match('/\$hesklang\[\'team\'\]/', $tmp) )
{
$add = 0;
}
}
else
{
$add = 0;
}
/* Check emails folder */
if (file_exists($email) && filetype($email) == 'dir')
{
foreach ($valid_emails as $eml)
{
if (!file_exists($email.'/'.$eml.'.txt'))
{
$add = 0;
}
}
}
else
{
$add = 0;
}
/* Add an option for the <select> if needed */
if ($add)
{
$code .= "'".addslashes($l[1])."' => array('folder'=>'".$subdir."','hr'=>'".addslashes($hr[1])."'),\n";
$langArray[] = $l[1];
}
}
}
closedir($path);
if ($returnArray)
{
return $langArray;
}
else
{
return $code;
}
} // END hesk_getLanguagesArray()
function hesk_getValidThemes() {
global $hesk_settings, $hesklang;
$dir = HESK_PATH . 'theme/';
$path = opendir($dir);
$valid_themes = array();
/* Test all folders inside the theme folder */
while (false !== ($subdir = readdir($path))) {
if ($subdir === '.' || $subdir === '..') {
continue;
}
if (filetype($dir . $subdir) === 'dir') {
$add = 1;
//region Create Ticket
$files_to_test = array('category-select.php', 'create-ticket.php', 'create-ticket-confirmation.php');
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/create-ticket/' . $test_file)) {
$add = 0;
}
}
//endregion
//region Knowledgebase
$files_to_test = array('search-results.php', 'view-article.php', 'view-category.php');
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/knowledgebase/' . $test_file)) {
$add = 0;
}
}
//endregion
//region View Ticket
$files_to_test = array('form.php', 'view-ticket.php');
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/view-ticket/' . $test_file)) {
$add = 0;
}
}
//endregion
//region Solo files
$files_to_test = array('error.php', 'index.php', 'maintenance.php');
foreach ($files_to_test as $test_file) {
if (!file_exists($dir . $subdir . '/customer/' . $test_file)) {
$add = 0;
}
}
//endregion
if (!file_exists($dir . $subdir . '/print-ticket.php')) {
$add = 0;
}
if (!file_exists($dir . $subdir . '/config.json')) {
$add = 0;
}
}
// Build markup
if ($add) {
// Pull the name from config.json
$config = file_get_contents($dir . $subdir . '/config.json');
$config_json = json_decode($config, true);
$valid_themes[] = $subdir;
}
}
return $valid_themes;
}
function hesk_formatUnits($size)
{
$units = array(
'GB' => 1073741824,
'MB' => 1048576,
'kB' => 1024,
'B' => 1
);
list($size, $suffix) = explode(' ', $size);
if ( isset($units[$suffix]) )
{
return round( $size * $units[$suffix] );
}
return false;
} // End hesk_formatBytes()
function hesk_getProperty($set, $property) {
global $hesk_settings;
if (isset($set[$property])) {
return $set[$property];
}
if (is_array($hesk_settings[$property])) {
return "'" . implode('\',\'', $hesk_settings[$property]) . "'";
}
return isset($set[$property]) ? $set[$property] : $hesk_settings[$property];
}
function hesk_getLanguageForFile($set) {
global $hesk_settings;
if (isset($set['languages'])) {
return $set['languages'];
}
$languages = '';
foreach ($hesk_settings['languages'] as $name => $info) {
$languages .= "'".addslashes($name)."' => array('folder'=>'".$info['folder']."','hr'=>'".addslashes($info['hr'])."'),\n";
}
return $languages;
}
function hesk_getAllowedAttachmentTypes($set) {
global $hesk_settings;
return isset($set['attachments']) ? $set['attachments']['allowed_types'] : $hesk_settings['attachments']['allowed_types'];
}

View File

@@ -0,0 +1,358 @@
<?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','../');
define('LOAD_TABS',1);
// Make sure the install folder is deleted
if (is_dir(HESK_PATH . 'install')) {die('Please delete the <b>install</b> folder from your server for security reasons then refresh this page!');}
// Get all the required files and functions
require(HESK_PATH . 'hesk_settings.inc.php');
// Save the default language for the settings page before choosing user's preferred one
$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');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
$help_folder = '../language/' . $hesk_settings['languages'][$hesk_settings['language']]['folder'] . '/help_files/';
$enable_save_settings = 0;
$enable_use_attachments = 0;
// Print header
require_once(HESK_PATH . 'inc/header.inc.php');
// Print main manage users page
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
// Demo mode? Hide values of sensitive settings
if ( defined('HESK_DEMO') )
{
$hesk_settings['db_host'] = $hesklang['hdemo'];
$hesk_settings['db_name'] = $hesklang['hdemo'];
$hesk_settings['db_user'] = $hesklang['hdemo'];
$hesk_settings['db_pass'] = $hesklang['hdemo'];
$hesk_settings['db_pfix'] = $hesklang['hdemo'];
$hesk_settings['smtp_host_name'] = $hesklang['hdemo'];
$hesk_settings['smtp_user'] = $hesklang['hdemo'];
$hesk_settings['smtp_password'] = $hesklang['hdemo'];
$hesk_settings['pop3_host_name'] = $hesklang['hdemo'];
$hesk_settings['pop3_user'] = $hesklang['hdemo'];
$hesk_settings['pop3_password'] = $hesklang['hdemo'];
$hesk_settings['imap_host_name'] = $hesklang['hdemo'];
$hesk_settings['imap_user'] = $hesklang['hdemo'];
$hesk_settings['imap_password'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_public_key'] = $hesklang['hdemo'];
$hesk_settings['recaptcha_private_key'] = $hesklang['hdemo'];
}
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content settings">
<div class="settings__status">
<h3><?php echo $hesklang['check_status']; ?></h3>
<ul class="settings__status_list">
<li>
<div class="list--name"><?php echo $hesklang['v']; ?></div>
<div class="list--status">
<?php echo $hesk_settings['hesk_version']; ?>
<?php
if ($hesk_settings['check_updates']) {
$latest = hesk_checkVersion();
if ($latest === true) {
echo ' - <span style="color:green">' . $hesklang['hud'] . '</span> ';
} elseif ($latest != -1) {
// Is this a beta/dev version?
if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) {
echo ' <span style="color:darkorange">' . $hesklang['beta'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
} else {
echo ' - <span style="color:darkorange;font-weight:bold">' . $hesklang['hnw'] . '</span> '; ?><br><a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['getup']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
} else {
?> - <a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>" target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
?>
</div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['phpv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : PHP_VERSION . ' ' . (function_exists('mysqli_connect') ? '(MySQLi)' : '(MySQL)'); ?></div>
</li>
<li>
<div class="list--name"><?php echo $hesklang['mysqlv']; ?></div>
<div class="list--status"><?php echo defined('HESK_DEMO') ? $hesklang['hdemo'] : hesk_dbResult( hesk_dbQuery('SELECT VERSION() AS version') ); ?></div>
</li>
<li>
<div class="list--name">/hesk_settings.inc.php</div>
<div class="list--status">
<?php
if (is_writable(HESK_PATH . 'hesk_settings.inc.php')) {
$enable_save_settings = 1;
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="success">'.$hesklang['exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_settings'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['attach_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['attach_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['attach_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_attdir'];
}
?>
</div>
</li>
<li>
<div class="list--name">/<?php echo $hesk_settings['cache_dir']; ?></div>
<div class="list--status">
<?php
if (is_dir(HESK_PATH . $hesk_settings['cache_dir'])) {
echo '<span class="success">'.$hesklang['exists'].'</span>, ';
if (is_writable(HESK_PATH . $hesk_settings['cache_dir'])) {
$enable_use_attachments = 1;
echo '<span class="success">'.$hesklang['writable'].'</span>';
} else {
echo '<span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
} else {
echo '<span class="error">'.$hesklang['no_exists'].'</span>, <span class="error">'.$hesklang['not_writable'].'</span><br>'.$hesklang['e_cdir'];
}
?>
</div>
</li>
</ul>
</div>
<script language="javascript" type="text/javascript"><!--
function hesk_checkFields() {
var d = document.form1;
// DISABLE SUBMIT BUTTON
d.submitbutton.disabled=true;
return true;
}
function hesk_toggleLayer(nr,setto) {
if (document.all)
document.all[nr].style.display = setto;
else if (document.getElementById)
document.getElementById(nr).style.display = setto;
}
//-->
</script>
<form method="post" action="admin_settings_save.php" name="form1" onsubmit="return hesk_checkFields()">
<section class="settings__form">
<h3>
<?php echo $hesklang['fitl']; ?>
<a onclick="hesk_window('<?php echo $help_folder; ?>ticket_list.html#1','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h3>
<div class="checkbox-group list">
<?php foreach ($hesk_settings['possible_ticket_list'] as $key => $title): ?>
<div class="checkbox-custom">
<input type="checkbox" name="s_tl_<?php echo $key; ?>" id="s_tl_<?php echo $key; ?>1" value="1" <?php echo in_array($key, $hesk_settings['ticket_list']) ? 'checked' : ''; ?>>
<label for="s_tl_<?php echo $key; ?>1"><?php echo $title; ?></label>
</div>
<?php endforeach; ?>
</div>
</section>
<section class="settings__form">
<h3><?php echo $hesklang['other']; ?></h3>
<div class="radio-group">
<h5>
<span><?php echo $hesklang['sdf']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>ticket_list.html#2','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="radio-list">
<div class="radio-custom">
<input type="radio" id="s_submittedformat2" name="s_submittedformat" value="2" <?php echo $hesk_settings['submittedformat'] == 2 ? 'checked' : ''; ?>>
<label for="s_submittedformat2"><?php echo $hesklang['lcf2']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_submittedformat1" name="s_submittedformat" value="1" <?php echo $hesk_settings['submittedformat'] == 1 ? 'checked' : ''; ?>>
<label for="s_submittedformat1"><?php echo $hesklang['lcf1']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_submittedformat0" name="s_submittedformat" value="0" <?php echo $hesk_settings['submittedformat'] == 0 ? 'checked' : ''; ?>>
<label for="s_submittedformat0"><?php echo $hesklang['lcf0']; ?></label>
</div>
</div>
</div>
<div class="radio-group">
<h5>
<span><?php echo $hesklang['lcf']; ?></span>
<a onclick="hesk_window('<?php echo $help_folder; ?>ticket_list.html#2','400','500')">
<div class="tooltype right">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
</div>
</a>
</h5>
<div class="radio-list">
<div class="radio-custom">
<input type="radio" id="s_updatedformat2" name="s_updatedformat" value="2" <?php echo $hesk_settings['updatedformat'] == 2 ? 'checked' : ''; ?>>
<label for="s_updatedformat2"><?php echo $hesklang['lcf2']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_updatedformat1" name="s_updatedformat" value="1" <?php echo $hesk_settings['updatedformat'] == 1 ? 'checked' : ''; ?>>
<label for="s_updatedformat1"><?php echo $hesklang['lcf1']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" id="s_updatedformat0" name="s_updatedformat" value="0" <?php echo $hesk_settings['updatedformat'] == 0 ? 'checked' : ''; ?>>
<label for="s_updatedformat0"><?php echo $hesklang['lcf0']; ?></label>
</div>
</div>
</div>
</section>
<div class="settings__form form" style="padding-top: 30px">
<div class="settings__form_submit">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input type="hidden" name="section" value="TICKET_LIST">
<button id="submitbutton" style="display: inline-flex" type="submit" class="btn btn-full" ripple="ripple"
<?php echo $enable_save_settings ? '' : 'disabled'; ?>>
<?php echo $hesklang['save_changes']; ?>
</button>
<?php if (!$enable_save_settings): ?>
<div class="error"><?php echo $hesklang['e_save_settings']; ?></div>
<?php endif; ?>
</div>
</div>
</form>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
function hesk_checkVersion()
{
global $hesk_settings;
if ($latest = hesk_getLatestVersion() )
{
if ( strlen($latest) > 12 )
{
return -1;
}
elseif ($latest == $hesk_settings['hesk_version'])
{
return true;
}
else
{
return $latest;
}
}
else
{
return -1;
}
} // END hesk_checkVersion()
function hesk_getLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if ( file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt') )
{
if ( preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600 )
{
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'http://hesk.com/version';
// Try using cURL
if ( function_exists('curl_init') )
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($hesk_version_url) )
{
return hesk_cacheLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
} // END hesk_getLatestVersion()
function hesk_cacheLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest);
return $latest;
} // END hesk_cacheLatestVersion()
?>

View File

@@ -0,0 +1,426 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
// Get all the required files and functions
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/email_functions.inc.php');
require(HESK_PATH . 'inc/posting_functions.inc.php');
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// We only allow POST requests from the HESK form to this file
if ( $_SERVER['REQUEST_METHOD'] != 'POST' )
{
header('Location: admin_main.php');
exit();
}
// Check for POST requests larger than what the server can handle
if ( empty($_POST) && ! empty($_SERVER['CONTENT_LENGTH']) )
{
hesk_error($hesklang['maxpost']);
}
$hesk_error_buffer = array();
$tmpvar['name'] = hesk_input( hesk_POST('name') ) or $hesk_error_buffer['name']=$hesklang['enter_your_name'];
$email_available = true;
if ($hesk_settings['require_email'])
{
$tmpvar['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer['email']=$hesklang['enter_valid_email'];
}
else
{
$tmpvar['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0);
// Not required, but must be valid if it is entered
if ($tmpvar['email'] == '')
{
$email_available = false;
if (strlen(hesk_POST('email')))
{
$hesk_error_buffer['email'] = $hesklang['not_valid_email'];
}
}
}
$tmpvar['category'] = intval( hesk_POST('category') ) or $hesk_error_buffer['category']=$hesklang['sel_app_cat'];
$tmpvar['priority'] = hesk_POST('priority');
$tmpvar['priority'] = strlen($tmpvar['priority']) ? intval($tmpvar['priority']) : -1;
if ($tmpvar['priority'] < 0 || $tmpvar['priority'] > 3)
{
// If we are showing "Click to select" priority needs to be selected
if ($hesk_settings['select_pri'])
{
$tmpvar['priority'] = -1;
$hesk_error_buffer['priority'] = $hesklang['select_priority'];
}
else
{
$tmpvar['priority'] = 3;
}
}
$tmpvar['subject'] = hesk_input( hesk_POST('subject') );
if ($hesk_settings['require_subject'] == 1 && $tmpvar['subject'] == '')
{
$hesk_error_buffer['subject'] = $hesklang['enter_ticket_subject'];
}
$tmpvar['message'] = hesk_input( hesk_POST('message') );
if ($hesk_settings['require_message'] == 1 && $tmpvar['message'] == '')
{
$hesk_error_buffer['message'] = $hesklang['enter_message'];
}
// Is category a valid choice?
if ($tmpvar['category'])
{
if ( ! hesk_checkPermission('can_submit_any_cat', 0) && ! hesk_okCategory($tmpvar['category'], 0) )
{
hesk_process_messages($hesklang['noauth_submit'],'new_ticket.php');
}
hesk_verifyCategory(1);
// Is auto-assign of tickets disabled in this category?
if ( empty($hesk_settings['category_data'][$tmpvar['category']]['autoassign']) )
{
$hesk_settings['autoassign'] = false;
}
}
// Custom fields
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'] && hesk_is_custom_field_in_category($k, $tmpvar['category']))
{
if ($v['type'] == 'checkbox')
{
$tmpvar[$k]='';
if (isset($_POST[$k]) && is_array($_POST[$k]))
{
foreach ($_POST[$k] as $myCB)
{
$tmpvar[$k] .= ( is_array($myCB) ? '' : hesk_input($myCB) ) . '<br />';;
}
$tmpvar[$k]=substr($tmpvar[$k],0,-6);
}
else
{
if ($v['req'] == 2)
{
$hesk_error_buffer[$k]=$hesklang['fill_all'].': '.$v['name'];
}
$_POST[$k] = '';
}
}
elseif ($v['type'] == 'date')
{
$tmpvar[$k] = hesk_POST($k);
$_SESSION["as_$k"] = '';
if (preg_match("/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/", $tmpvar[$k]))
{
$date = strtotime($tmpvar[$k] . ' t00:00:00 UTC');
$dmin = strlen($v['value']['dmin']) ? strtotime($v['value']['dmin'] . ' t00:00:00 UTC') : false;
$dmax = strlen($v['value']['dmax']) ? strtotime($v['value']['dmax'] . ' t00:00:00 UTC') : false;
$_SESSION["as_$k"] = $tmpvar[$k];
if ($dmin && $dmin > $date)
{
$hesk_error_buffer[$k] = sprintf($hesklang['d_emin'], $v['name'], hesk_custom_date_display_format($dmin, $v['value']['date_format']));
}
elseif ($dmax && $dmax < $date)
{
$hesk_error_buffer[$k] = sprintf($hesklang['d_emax'], $v['name'], hesk_custom_date_display_format($dmax, $v['value']['date_format']));
}
else
{
$tmpvar[$k] = $date;
}
}
else
{
$tmpvar[$k] = '';
if ($v['req'] == 2)
{
$hesk_error_buffer[$k]=$hesklang['fill_all'].': '.$v['name'];
}
}
}
elseif ($v['type'] == 'email')
{
$tmp = $hesk_settings['multi_eml'];
$hesk_settings['multi_eml'] = $v['value']['multiple'];
$tmpvar[$k] = hesk_validateEmail( hesk_POST($k), 'ERR', 0);
$hesk_settings['multi_eml'] = $tmp;
if ($tmpvar[$k] != '')
{
$_SESSION["as_$k"] = hesk_input($tmpvar[$k]);
}
else
{
$_SESSION["as_$k"] = '';
if ($v['req'] == 2)
{
$hesk_error_buffer[$k] = $v['value']['multiple'] ? sprintf($hesklang['cf_noem'], $v['name']) : sprintf($hesklang['cf_noe'], $v['name']);
}
}
}
elseif ($v['req'] == 2)
{
$tmpvar[$k]=hesk_makeURL(nl2br(hesk_input( hesk_POST($k) )));
if ($tmpvar[$k] == '')
{
$hesk_error_buffer[$k]=$hesklang['fill_all'].': '.$v['name'];
}
}
else
{
$tmpvar[$k]=hesk_makeURL(nl2br(hesk_input(hesk_POST($k))));
}
}
else
{
$tmpvar[$k] = '';
}
}
// Generate tracking ID
$tmpvar['trackid'] = hesk_createID();
// Log who submitted ticket
$tmpvar['history'] = sprintf($hesklang['thist7'], hesk_date(), $_SESSION['name'].' ('.$_SESSION['user'].')');
$tmpvar['openedby'] = $_SESSION['id'];
// Owner
$tmpvar['owner'] = 0;
if (hesk_checkPermission('can_assign_others',0))
{
$tmpvar['owner'] = intval( hesk_POST('owner') );
// If ID is -1 the ticket will be unassigned
if ($tmpvar['owner'] == -1)
{
$tmpvar['owner'] = 0;
}
// Automatically assign owner?
elseif ($tmpvar['owner'] == -2 && $hesk_settings['autoassign'] == 1)
{
$autoassign_owner = hesk_autoAssignTicket($tmpvar['category']);
if ($autoassign_owner)
{
$tmpvar['owner'] = intval($autoassign_owner['id']);
$tmpvar['history'] .= sprintf($hesklang['thist10'],hesk_date(),$autoassign_owner['name'].' ('.$autoassign_owner['user'].')');
}
else
{
$tmpvar['owner'] = 0;
}
}
// Check for invalid owner values
elseif ($tmpvar['owner'] < 1)
{
$tmpvar['owner'] = 0;
}
else
{
// Has the new owner access to the selected category?
$res = hesk_dbQuery("SELECT `name`,`isadmin`,`categories` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='{$tmpvar['owner']}' LIMIT 1");
if (hesk_dbNumRows($res) == 1)
{
$row = hesk_dbFetchAssoc($res);
if (!$row['isadmin'])
{
$row['categories']=explode(',',$row['categories']);
if (!in_array($tmpvar['category'],$row['categories']))
{
$_SESSION['isnotice'][] = 'category';
$hesk_error_buffer['owner']=$hesklang['onasc'];
}
}
}
else
{
$_SESSION['isnotice'][] = 'category';
$hesk_error_buffer['owner']=$hesklang['onasc'];
}
}
}
elseif (hesk_checkPermission('can_assign_self',0) && hesk_okCategory($tmpvar['category'],0) && !empty($_POST['assing_to_self']))
{
$tmpvar['owner'] = intval($_SESSION['id']);
}
// Notify customer of the ticket?
$notify = ! empty($_POST['notify']) ? 1 : 0;
// Show ticket after submission?
$show = ! empty($_POST['show']) ? 1 : 0;
// Attachments
if ($hesk_settings['attachments']['use'])
{
require_once(HESK_PATH . 'inc/attachments.inc.php');
$attachments = array();
$trackingID = $tmpvar['trackid'];
for ($i=1;$i<=$hesk_settings['attachments']['max_number'];$i++)
{
$att = hesk_uploadFile($i);
if ($att !== false && !empty($att))
{
$attachments[$i] = $att;
}
}
}
$tmpvar['attachments'] = '';
// If we have any errors lets store info in session to avoid re-typing everything
if (count($hesk_error_buffer)!=0)
{
$_SESSION['iserror'] = array_keys($hesk_error_buffer);
$_SESSION['as_name'] = hesk_POST('name');
$_SESSION['as_email'] = hesk_POST('email');
$_SESSION['as_priority'] = $tmpvar['priority'];
$_SESSION['as_subject'] = hesk_POST('subject');
$_SESSION['as_message'] = hesk_POST('message');
$_SESSION['as_owner'] = $tmpvar['owner'];
$_SESSION['as_notify'] = $notify;
$_SESSION['as_show'] = $show;
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'] && ! in_array($v['type'], array('date', 'email')))
{
$_SESSION["as_$k"] = ($v['type'] == 'checkbox') ? hesk_POST_array($k) : hesk_POST($k);
}
}
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
// Remove any successfully uploaded attachments
if ($hesk_settings['attachments']['use'])
{
hesk_removeAttachments($attachments);
}
$hesk_error_buffer = $hesklang['pcer'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'new_ticket.php?category='.$tmpvar['category']);
}
if ($hesk_settings['attachments']['use'] && !empty($attachments))
{
foreach ($attachments as $myatt)
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES ('".hesk_dbEscape($tmpvar['trackid'])."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."')");
$tmpvar['attachments'] .= hesk_dbInsertID() . '#' . $myatt['real_name'] .',';
}
}
$tmpvar['message']=hesk_makeURL($tmpvar['message']);
$tmpvar['message']=nl2br($tmpvar['message']);
// Track who assigned the ticket
if ($tmpvar['owner'] > 0)
{
$tmpvar['assignedby'] = ! empty($autoassign_owner) ? -1 : $_SESSION['id'];
}
// Insert ticket to database
$ticket = hesk_newTicket($tmpvar);
// Notify the customer about the ticket?
if ($notify && $email_available)
{
hesk_notifyCustomer();
}
// If ticket is assigned to someone notify them?
if ($ticket['owner'] && $ticket['owner'] != intval($_SESSION['id']))
{
// If we don't have info from auto-assign get it from database
if ( ! isset($autoassign_owner['email']) )
{
hesk_notifyAssignedStaff(false, 'ticket_assigned_to_you');
}
else
{
hesk_notifyAssignedStaff($autoassign_owner, 'ticket_assigned_to_you');
}
}
// Ticket unassigned, notify everyone that selected to be notified about unassigned tickets
elseif ( ! $ticket['owner'])
{
hesk_notifyStaff('new_ticket_staff', " `id` != ".intval($_SESSION['id'])." AND `notify_new_unassigned` = '1' ");
}
// Unset temporary variables
unset($tmpvar);
hesk_cleanSessionVars('tmpvar');
hesk_cleanSessionVars('as_name');
hesk_cleanSessionVars('as_email');
hesk_cleanSessionVars('as_category');
hesk_cleanSessionVars('as_priority');
hesk_cleanSessionVars('as_subject');
hesk_cleanSessionVars('as_message');
hesk_cleanSessionVars('as_owner');
hesk_cleanSessionVars('as_notify');
hesk_cleanSessionVars('as_show');
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
hesk_cleanSessionVars("as_$k");
}
// If ticket has been assigned to the person submitting it lets show a message saying so
if ($ticket['owner'] && $ticket['owner'] == intval($_SESSION['id']))
{
$hesklang['new_ticket_submitted'] .= '<br />&nbsp;<br />
<b>' . (isset($autoassign_owner) ? $hesklang['taasy'] : $hesklang['tasy']) . '</b>';
}
// Show the ticket or just the success message
if ($show)
{
hesk_process_messages($hesklang['new_ticket_submitted'],'admin_ticket.php?track=' . $ticket['trackid'] . '&Refresh=' . mt_rand(10000,99999), 'SUCCESS');
}
else
{
hesk_process_messages($hesklang['new_ticket_submitted'].'. <a href="admin_ticket.php?track=' . $ticket['trackid'] . '&Refresh=' . mt_rand(10000,99999) . '">' . $hesklang['view_ticket'] . '</a>', 'new_ticket.php', 'SUCCESS');
}

View File

@@ -0,0 +1,79 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Print XML header */
header('Content-Type: text/html; charset='.$hesklang['ENCODING']);
/* Get the search query composed of the subject and message */
$query = hesk_REQUEST('q') or die('');
/* Get relevant articles from the database, include private ones */
$res = hesk_dbQuery("SELECT `id`, `subject`, `content` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` WHERE `type` IN ('0','1') AND MATCH(`subject`,`content`,`keywords`) AGAINST ('".hesk_dbEscape($query)."') LIMIT ".intval($hesk_settings['kb_search_limit']));
$num = hesk_dbNumRows($res);
/* Solve some spacing issues */
if ( hesk_isREQUEST('p') )
{
echo '&nbsp;<br />';
}
/* Return found articles */
?>
<div class="main__content notice-flash" style="padding: 0">
<div class="notification-bar white notice-flash" style="display: block; border-left: solid 1px #d4d6e3; border-right: solid 1px #d4d6e3">
<div class="notification--text" style="display: block; margin: 10px">
<div>
<b><?php echo $hesklang['sc']; ?></b>
</div>
<span>
<?php
if (!$num)
{
echo '<i>'.$hesklang['nsfo'].'</i>';
}
else
{
while ($article = hesk_dbFetchAssoc($res))
{
$txt = strip_tags($article['content']);
if (hesk_mb_strlen($txt) > $hesk_settings['kb_substrart'])
{
$txt = hesk_mb_substr($txt, 0, $hesk_settings['kb_substrart']).'...';
}
echo '
<a class="link" href="knowledgebase_private.php?article='.$article['id'].'&amp;suggest=1" target="_blank">'.$article['subject'].'</a>
<br />'.$txt.'<br /><br />';
}
}
?>
</span>
</div>
</div>
</div>
<?php
exit();
?>

2082
hesk/admin/admin_ticket.php Normal file

File diff suppressed because it is too large Load Diff

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

54
hesk/admin/archive.php Normal file
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');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
hesk_checkPermission('can_add_archive');
/* A security check */
hesk_token_check();
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
/* New archived status */
if (empty($_GET['archived']))
{
$status = 0;
$tmp = $hesklang['removedfromarchive'];
}
else
{
$status = 1;
$tmp = $hesklang['added2archive'];
}
/* Update database */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `archive`='$status' WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
/* Back to ticket page and show a success message */
hesk_process_messages($tmp,'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');
?>

171
hesk/admin/assign_owner.php Normal file
View File

@@ -0,0 +1,171 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/email_functions.inc.php');
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
$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);
}
/* A security check */
hesk_token_check();
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($res);
$_SERVER['PHP_SELF'] = 'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999);
/* New owner ID */
$owner = intval( hesk_REQUEST('owner') );
/* If ID is -1 the ticket will be unassigned */
if ($owner == -1)
{
$revision = sprintf($hesklang['thist2'],hesk_date(),'<i>'.$hesklang['unas'].'</i>',$_SESSION['name'].' ('.$_SESSION['user'].')');
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`=0, `assignedby`=NULL, `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
hesk_process_messages($hesklang['tunasi2'],$_SERVER['PHP_SELF'],'SUCCESS');
}
elseif ($owner < 1)
{
hesk_process_messages($hesklang['nose'],$_SERVER['PHP_SELF'],'NOTICE');
}
/* Verify the new owner and permissions */
$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");
$row = hesk_dbFetchAssoc($res);
/* Has new owner access to the category? */
if ( ! $row['isadmin'])
{
$row['categories']=explode(',',$row['categories']);
if (!in_array($ticket['category'],$row['categories']))
{
hesk_error($hesklang['unoa']);
}
}
// Make sure two people don't assign a ticket to a different user at the same time
if ($ticket['owner'] && $ticket['owner'] != $owner && hesk_REQUEST('unassigned') && hesk_GET('confirm') != 'Y')
{
$new_owner = ($owner == $_SESSION['id']) ? $hesklang['scoy'] : sprintf($hesklang['scot'], $row['name']);
$res = hesk_dbQuery("SELECT `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='{$ticket['owner']}' LIMIT 1");
if (hesk_dbNumRows($res) == 1)
{
$row = hesk_dbFetchAssoc($res);
hesk_process_messages(
sprintf($hesklang['taat'], $row['name']) .
'<br /><br />' .
$new_owner .
'<br /><br />' .
'<a href="assign_owner.php?track='.$ticket['trackid'].'&amp;owner='.$owner.'&amp;token='.hesk_token_echo(0).'&amp;unassigned=1&amp;confirm=Y">'.$hesklang['ycto'].'</a> | ' .
'<a href="admin_ticket.php?track='.$ticket['trackid'].'">'.$hesklang['ncto'].'</a>',
$_SERVER['PHP_SELF'], 'NOTICE'
);
}
}
/* Assigning to self? */
if ($can_assign_others || ($owner == $_SESSION['id'] && $can_assign_self))
{
$assignedby = intval(hesk_SESSION('id'));
if ($assignedby > 0)
{
$assignedby = ',`assignedby`=' . $assignedby;
}
else
{
$assignedby = '';
}
$revision = sprintf($hesklang['thist2'],hesk_date(),$row['name'].' ('.$row['user'].')',$_SESSION['name'].' ('.$_SESSION['user'].')');
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`={$owner} {$assignedby}, `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
if ($owner != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others',0))
{
$_SERVER['PHP_SELF']='admin_main.php';
}
}
else
{
hesk_error($hesklang['no_permission']);
}
$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');
}
$tmp = ($owner == $_SESSION['id']) ? $hesklang['tasy'] : $hesklang['taso'];
hesk_process_messages($tmp,$_SERVER['PHP_SELF'],'SUCCESS');
?>

View File

@@ -0,0 +1,240 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_ban_emails');
$can_unban = hesk_checkPermission('can_unban_emails', 0);
// Define required constants
define('LOAD_TABS',1);
// What should we do?
if ( $action = hesk_REQUEST('a') )
{
if ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'banned_emails.php', 'NOTICE');}
elseif ($action == 'ban') {ban_email();}
elseif ($action == 'unban' && $can_unban) {unban_email();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content tools">
<h2><?php echo $hesklang['banemail']; ?></h2>
<form action="banned_emails.php" method="post" name="form1">
<div class="tools__add-mail form">
<div class="form-group">
<input type="text" name="email" class="form-control" maxlength="255" placeholder="<?php echo htmlspecialchars($hesklang['bananemail']); ?>">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<input type="hidden" name="a" value="ban" />
<button type="submit" class="btn btn--blue-border" ripple="ripple"><?php echo $hesklang['savebanemail']; ?></button>
</div>
<div class="mail--examples"><?php echo $hesklang['banex']; ?>: john@example.com, @example.com</div>
</div>
</form>
<?php
// Get banned emails from database
$res = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'banned_emails` ORDER BY `email` ASC');
$num = hesk_dbNumRows($res);
?>
<div class="table-wrapper email">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['email']; ?></th>
<th><?php echo $hesklang['banby']; ?></th>
<th><?php echo $hesklang['date']; ?></th>
<?php if ($can_unban): ?>
<th><?php echo $hesklang['opt']; ?></th>
<?php endif; ?>
</tr>
</thead>
<tbody>
<?php if ($num < 1): ?>
<tr>
<td colspan="<?php echo $can_unban ? 4 : 3; ?>"><?php echo $hesklang['no_banemails']; ?></td>
</tr>
<?php
else:
// List of staff
if ( ! isset($admins) )
{
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users`");
while ($row=hesk_dbFetchAssoc($res2))
{
$admins[$row['id']]=$row['name'];
}
}
while ($ban = hesk_dbFetchAssoc($res)):
$table_row = '';
if (isset($_SESSION['ban_email']['id']) && $ban['id'] == $_SESSION['ban_email']['id'])
{
$table_row = 'class="ticket-new"';
unset($_SESSION['ban_email']['id']);
}
?>
<tr <?php echo $table_row; ?>>
<td><?php echo $ban['email']; ?></td>
<td><?php echo isset($admins[$ban['banned_by']]) ? $admins[$ban['banned_by']] : $hesklang['e_udel']; ?></td>
<td><?php echo $ban['dt']; ?></td>
<?php if ($can_unban): ?>
<td class="unban">
<?php $modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['delban_confirm'],
'banned_emails.php?a=unban&amp;id='. $ban['id'] .'&amp;token='. hesk_token_echo(0)); ?>
<a title="<?php echo $hesklang['delban']; ?>" href="javascript:" data-modal="[data-modal-id='<?php echo $modal_id; ?>']">
<?php echo $hesklang['delban']; ?>
</a>
</td>
<?php endif; ?>
</tr>
<?php endwhile;
endif; ?>
</tbody>
</table>
</div>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function ban_email()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get the email
$email = hesk_emailCleanup( strtolower( hesk_input( hesk_REQUEST('email') ) ) );
// Nothing entered?
if ( ! strlen($email) )
{
hesk_process_messages($hesklang['enterbanemail'],'banned_emails.php');
}
// Only allow one email to be entered
$email = ($index = strpos($email, ',')) ? substr($email, 0, $index) : $email;
$email = ($index = strpos($email, ';')) ? substr($email, 0, $index) : $email;
// Validate email address
$hesk_settings['multi_eml'] = 0;
if ( ! hesk_validateEmail($email, '', 0) && ! verify_email_domain($email) )
{
hesk_process_messages($hesklang['validbanemail'],'banned_emails.php');
}
// Redirect either to banned emails or ticket page from now on
$redirect_to = ($trackingID = hesk_cleanID()) ? 'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999) : 'banned_emails.php';
// Prevent duplicate rows
if ( $_SESSION['ban_email']['id'] = hesk_isBannedEmail($email) )
{
hesk_process_messages( sprintf($hesklang['emailbanexists'], $email) ,$redirect_to,'NOTICE');
}
// Insert the email address into database
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."banned_emails` (`email`,`banned_by`) VALUES ('".hesk_dbEscape($email)."','".intval($_SESSION['id'])."')");
// Remember email that got banned
$_SESSION['ban_email']['id'] = hesk_dbInsertID();
// Show success
hesk_process_messages( sprintf($hesklang['email_banned'], $email) ,$redirect_to,'SUCCESS');
} // End ban_email()
function unban_email()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Delete from bans
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."banned_emails` WHERE `id`=" . intval( hesk_GET('id') ) );
// Redirect either to banned emails or ticket page from now on
$redirect_to = ($trackingID = hesk_cleanID()) ? 'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999) : 'banned_emails.php';
// Show success
hesk_process_messages($hesklang['email_unbanned'],$redirect_to,'SUCCESS');
} // End unban_email()
function verify_email_domain($domain)
{
// Does it start with an @?
$atIndex = strrpos($domain, "@");
if ($atIndex !== 0)
{
return false;
}
// Get the domain and domain length
$domain = substr($domain, 1);
$domainLen = strlen($domain);
// Check domain part length
if ($domainLen < 1 || $domainLen > 254)
{
return false;
}
// Check domain part characters
if ( ! preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain) )
{
return false;
}
// Domain part mustn't have two consecutive dots
if ( strpos($domain, '..') !== false )
{
return false;
}
// All OK
return true;
} // END verify_email_domain()
?>

348
hesk/admin/banned_ips.php Normal file
View File

@@ -0,0 +1,348 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_ban_ips');
$can_unban = hesk_checkPermission('can_unban_ips', 0);
// Define required constants
define('LOAD_TABS',1);
// What should we do?
if ( $action = hesk_REQUEST('a') )
{
if ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'banned_ips.php', 'NOTICE');}
elseif ($action == 'ban') {ban_ip();}
elseif ($action == 'unban' && $can_unban) {unban_ip();}
elseif ($action == 'unbantemp' && $can_unban) {unban_temp_ip();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content tools">
<h2><?php echo $hesklang['banip']; ?></h2>
<form action="banned_ips.php" method="post" name="form1">
<div class="tools__add-mail form">
<div class="form-group">
<input type="text" name="ip" maxlength="255" placeholder="<?php echo $hesklang['bananip']; ?>" class="form-control">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<input type="hidden" name="a" value="ban" />
<button type="submit" class="btn btn--blue-border" ripple="ripple"><?php echo $hesklang['savebanip']; ?></button>
</div>
<div class="mail--examples"><?php echo $hesklang['banex']; ?></div>
<ul style="margin-left: 10px">
<li>123.0.0.0</li>
<li>123.0.0.1 - 123.0.0.53</li>
<li>123.0.0.0/24</li>
<li>123.0.*.*</li>
</ul>
</div>
</form>
<?php
// Get login failures
$res = hesk_dbQuery("SELECT `ip`, TIMESTAMPDIFF(MINUTE, NOW(), DATE_ADD(`last_attempt`, INTERVAL ".intval($hesk_settings['attempt_banmin'])." MINUTE) ) AS `minutes` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."logins` WHERE `number` >= ".intval($hesk_settings['attempt_limit'])." AND `last_attempt` > (NOW() - INTERVAL ".intval($hesk_settings['attempt_banmin'])." MINUTE)");
$num = hesk_dbNumRows($res);
if ($num > 0):
?>
<h3><?php echo $hesklang['iptemp']; ?></h3>
<div class="table-wrapper ips">
<table id="temporary-bans-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['ip']; ?></th>
<th><?php echo $hesklang['m2e']; ?></th>
<?php if ($can_unban): ?>
<th><?php echo $hesklang['opt']; ?></th>
<?php endif; ?>
</tr>
</thead>
<tbody>
<?php while ($ban = hesk_dbFetchAssoc($res)): ?>
<tr>
<td><?php echo $ban['ip']; ?></td>
<td><?php echo $ban['minutes']; ?></td>
<?php if ($can_unban): ?>
<td>
<a href="banned_ips.php?a=ban&amp;ip=<?php echo urlencode($ban['ip']); ?>&amp;token=<?php hesk_token_echo(); ?>"><?php echo $hesklang['ippermban']; ?></a>
<a href="banned_ips.php?a=unbantemp&amp;ip=<?php echo urlencode($ban['ip']); ?>&amp;token=<?php hesk_token_echo(); ?>"><?php echo $hesklang['delban']; ?></a>
</td>
<?php endif; ?>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<h3><?php echo $hesklang['ipperm']; ?></h3>
<div class="table-wrapper ips">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['ip']; ?></th>
<th><?php echo $hesklang['iprange']; ?></th>
<th><?php echo $hesklang['banby']; ?></th>
<th><?php echo $hesklang['date']; ?></th>
<?php if ($can_unban): ?>
<th><?php echo $hesklang['opt']; ?></th>
<?php endif; ?>
</tr>
</thead>
<tbody>
<?php
// Get banned ips from database
$res = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'banned_ips` ORDER BY `ip_from` ASC');
$num = hesk_dbNumRows($res);
if ($num < 1):
?>
<tr>
<td colspan="<?php echo $can_unban ? 5 : 4; ?>"><?php echo $hesklang['no_banips']; ?></td>
</tr>
<?php
else:
// List of staff
if ( ! isset($admins) )
{
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users`");
while ($row=hesk_dbFetchAssoc($res2))
{
$admins[$row['id']]=$row['name'];
}
}
$i = 1;
while ($ban = hesk_dbFetchAssoc($res)):
$table_row = '';
if (isset($_SESSION['ban_ip']['id']) && $ban['id'] == $_SESSION['ban_ip']['id'])
{
$table_row = 'class="ticket-new"';
unset($_SESSION['ban_ip']['id']);
}
?>
<tr <?php echo $table_row; ?>>
<td><?php echo $ban['ip_display']; ?></td>
<td><?php echo $ban['ip_to'] == $ban['ip_from'] ? long2ip($ban['ip_to']) : long2ip($ban['ip_from']) . ' - ' . long2ip($ban['ip_to']); ?></td>
<td><?php echo isset($admins[$ban['banned_by']]) ? $admins[$ban['banned_by']] : $hesklang['e_udel']; ?></td>
<td><?php echo $ban['dt']; ?></td>
<?php if ($can_unban): ?>
<td class="unban">
<?php $modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['delban_confirm'],
'banned_ips.php?a=unban&amp;id='. $ban['id'] .'&amp;token='. hesk_token_echo(0)); ?>
<a href="javascript:" data-modal="[data-modal-id='<?php echo $modal_id; ?>']">
<?php echo $hesklang['delban']; ?>
</a>
</td>
<?php endif; ?>
</tr>
<?php
endwhile;
endif; ?>
</tbody>
</table>
</div>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function ban_ip()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get the ip
$ip = preg_replace('/[^0-9\.\-\/\*]/', '', hesk_REQUEST('ip') );
$ip_display = str_replace('-', ' - ', $ip);
// Nothing entered?
if ( ! strlen($ip) )
{
hesk_process_messages($hesklang['enterbanip'],'banned_ips.php');
}
// Convert asterisk to ranges
if ( strpos($ip, '*') !== false )
{
$ip = str_replace('*', '0', $ip) . '-' . str_replace('*', '255', $ip);
}
$ip_regex = '(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])';
// Is this a single IP address?
if ( preg_match('/^'.$ip_regex.'$/', $ip) )
{
$ip_from = ip2long($ip);
$ip_to = $ip_from;
}
// Is this an IP range?
elseif ( preg_match('/^'.$ip_regex.'\-'.$ip_regex.'$/', $ip) )
{
list($ip_from, $ip_to) = explode('-', $ip);
$ip_from = ip2long($ip_from);
$ip_to = ip2long($ip_to);
}
// Is this an IP with CIDR?
elseif ( preg_match('/^'.$ip_regex.'\/([0-9]{1,2})$/', $ip, $matches) && $matches[4] >= 0 && $matches[4] <= 32)
{
list($ip_from, $ip_to) = hesk_cidr_to_range($ip);
}
// Not a valid input
else
{
hesk_process_messages($hesklang['validbanip'],'banned_ips.php');
}
if ($ip_from === false || $ip_to === false)
{
hesk_process_messages($hesklang['validbanip'],'banned_ips.php');
}
// Make sure we have valid ranges
if ($ip_from < 0)
{
$ip_from += 4294967296;
}
elseif ($ip_from > 4294967296)
{
$ip_from = 4294967296;
}
if ($ip_to < 0)
{
$ip_to += 4294967296;
}
elseif ($ip_to > 4294967296)
{
$ip_to = 4294967296;
}
// Make sure $ip_to is not lower that $ip_from
if ($ip_to < $ip_from)
{
$tmp = $ip_to;
$ip_to = $ip_from;
$ip_from = $tmp;
}
// Is this IP address already banned?
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."banned_ips` WHERE {$ip_from} BETWEEN `ip_from` AND `ip_to` AND {$ip_to} BETWEEN `ip_from` AND `ip_to` LIMIT 1");
if ( hesk_dbNumRows($res) == 1 )
{
$_SESSION['ban_ip']['id'] = hesk_dbResult($res);
$hesklang['ipbanexists'] = ($ip_to == $ip_from) ? sprintf($hesklang['ipbanexists'], long2ip($ip_to) ) : sprintf($hesklang['iprbanexists'], long2ip($ip_from).' - '.long2ip($ip_to) );
hesk_process_messages($hesklang['ipbanexists'],'banned_ips.php','NOTICE');
}
// Delete any duplicate banned IP or ranges that are within the new banned range
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."banned_ips` WHERE `ip_from` >= {$ip_from} AND `ip_to` <= {$ip_to}");
// Delete temporary bans from logins table
if ($ip_to == $ip_from)
{
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."logins` WHERE `ip`='".hesk_dbEscape($ip_display)."'");
}
// Redirect either to banned ips or ticket page from now on
$redirect_to = ($trackingID = hesk_cleanID()) ? 'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999) : 'banned_ips.php';
// Insert the ip address into database
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."banned_ips` (`ip_from`,`ip_to`,`ip_display`,`banned_by`) VALUES ({$ip_from}, {$ip_to},'".hesk_dbEscape($ip_display)."','".intval($_SESSION['id'])."')");
// Remember ip that got banned
$_SESSION['ban_ip']['id'] = hesk_dbInsertID();
// Generate success message
$hesklang['ip_banned'] = ($ip_to == $ip_from) ? sprintf($hesklang['ip_banned'], long2ip($ip_to) ) : sprintf($hesklang['ip_rbanned'], long2ip($ip_from).' - '.long2ip($ip_to) );
// Show success
hesk_process_messages( sprintf($hesklang['ip_banned'], $ip) ,$redirect_to,'SUCCESS');
} // End ban_ip()
function unban_temp_ip()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get the ip
$ip = preg_replace('/[^0-9\.\-\/\*]/', '', hesk_REQUEST('ip') );
// Delete from bans
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."logins` WHERE `ip`='" . hesk_dbEscape($ip) . "'");
// Show success
hesk_process_messages($hesklang['ip_tempun'],'banned_ips.php','SUCCESS');
} // End unban_temp_ip()
function unban_ip()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Delete from bans
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."banned_ips` WHERE `id`=" . intval( hesk_GET('id') ) );
// Redirect either to banned ips or ticket page from now on
$redirect_to = ($trackingID = hesk_cleanID()) ? 'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999) : 'banned_ips.php';
// Show success
hesk_process_messages($hesklang['ip_unbanned'],$redirect_to,'SUCCESS');
} // End unban_ip()
function hesk_cidr_to_range($cidr)
{
$range = array();
$cidr = explode('/', $cidr);
$range[0] = (ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1])));
$range[1] = (ip2long($cidr[0])) + pow(2, (32 - (int)$cidr[1])) - 1;
return $range;
} // END hesk_cidr_to_range()
?>

View File

@@ -0,0 +1,116 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
/* A security check */
hesk_token_check();
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
// Load statuses
require_once(HESK_PATH . 'inc/statuses.inc.php');
/* New status */
$status = intval( hesk_REQUEST('s') );
if ( ! isset($hesk_settings['statuses'][$status]))
{
hesk_process_messages($hesklang['instat'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'NOTICE');
}
// We need can_reply_tickets permission unless we are closing a ticket
if ($status != 3)
{
hesk_checkPermission('can_reply_tickets');
}
$locked = 0;
if ($status == 3) // Closed
{
if ( ! hesk_checkPermission('can_resolve', 0))
{
hesk_process_messages($hesklang['noauth_resolve'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'NOTICE');
}
$action = $hesklang['ticket_been'] . ' ' . $hesklang['closed'];
$revision = sprintf($hesklang['thist3'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')');
if ($hesk_settings['custopen'] != 1)
{
$locked = 1;
}
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed'])
{
// Get ticket info
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$ticket = hesk_ticketToPlain($ticket, 1, 0);
// Notify customer
require(HESK_PATH . 'inc/email_functions.inc.php');
hesk_notifyCustomer('ticket_closed');
}
// Log who marked the ticket resolved
$closedby_sql = ' , `closedat`=NOW(), `closedby`='.intval($_SESSION['id']).' ';
}
elseif ($status != 0)
{
$status_name = hesk_get_status_name($status);
$action = sprintf($hesklang['tsst'], $status_name);
$revision = sprintf($hesklang['thist9'],hesk_date(),$status_name,$_SESSION['name'].' ('.$_SESSION['user'].')');
// Ticket is not resolved
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
}
else // Opened
{
$action = $hesklang['ticket_been'] . ' ' . $hesklang['opened'];
$revision = sprintf($hesklang['thist4'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')');
// Ticket is not resolved
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
}
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_error("$hesklang[int_error]: $hesklang[trackID_not_found].");
}
hesk_process_messages($action,'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');

1246
hesk/admin/custom_fields.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,572 @@
<?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','../');
define('LOAD_TABS',1);
// Get all the req 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/setup_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// Load statuses
require_once(HESK_PATH . 'inc/statuses.inc.php');
// What should we do?
if ( $action = hesk_REQUEST('a') )
{
if ($action == 'edit_status') {edit_status();}
elseif ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'custom_statuses.php', 'NOTICE');}
elseif ($action == 'new_status') {new_status();}
elseif ($action == 'save_status') {save_status();}
elseif ($action == 'remove_status') {remove_status();}
}
// Print header
require_once(HESK_PATH . 'inc/header.inc.php');
// Print main manage users page
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
if (!hesk_SESSION('edit_status') && !hesk_SESSION(array('new_status','errors'))) {
hesk_handle_messages();
}
// Number of custom statuses
$hesk_settings['num_custom_statuses'] = count($hesk_settings['statuses']) - 6;
$reached_status_limit = $hesk_settings['num_custom_statuses'] >= 100;
// Did we reach the custom statuses limit?
if ($reached_status_limit && $action !== 'edit_status') {
hesk_show_info($hesklang['status_limit']);
}
?>
<div class="main__content tools">
<section class="tools__between-head">
<h2><?php echo $hesklang['statuses']; ?></h2>
<?php if (!$reached_status_limit && $action !== 'edit_status'): ?>
<div class="btn btn--blue-border" ripple="ripple" data-action="create-custom-status">
<?php echo $hesklang['new_status']; ?>
</div>
<?php endif; ?>
</section>
<div class="table-wrapper status">
<div class="table">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['status']; ?></th>
<th><?php echo $hesklang['csscl']; ?></th>
<th><?php echo $hesklang['tickets']; ?></th>
<th><?php echo $hesklang['cbc']; ?></th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="title">
<td colspan="5"><?php echo $hesklang['status_hesk']; ?></td>
</tr>
<?php
// Number of tickets per status
$tickets_all = array();
$res = hesk_dbQuery('SELECT COUNT(*) AS `cnt`, `status` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'tickets` GROUP BY `status`');
while ($tmp = hesk_dbFetchAssoc($res)) {
$tickets_all[$tmp['status']] = $tmp['cnt'];
}
$is_custom = false;
$i = 1;
foreach ($hesk_settings['statuses'] as $tmp_id => $status) {
$status['span'] = isset($status['class']) ? '<span class="' . $status['class'] . '">' : '<span style="color: ' . $status['color'] . '">';
$status['color'] = isset($status['class']) ? $status['span'] . '.' . $status['class'] . '</span>' : $status['span'] . $status['color'] . '</span>';
$status['tickets'] = isset($tickets_all[$tmp_id]) ? $tickets_all[$tmp_id] : 0;
$status['can_customers_change'] = ! isset($status['can_customers_change']) ? '' : ($status['can_customers_change'] == 1 ? $hesklang['yes'] : $hesklang['no']);
if (!$is_custom && $tmp_id > 5) {
$is_custom = true;
echo '
<tr class="title">
<td colspan="5">' . $hesklang['status_custom'] . '</td>
</tr>
';
}
$table_row = '';
if (isset($_SESSION['statusord']) && $_SESSION['statusord'] == $tmp_id) {
$table_row = 'class="ticket-new"';
unset($_SESSION['statusord']);
}
?>
<tr <?php echo $table_row; ?>>
<td><?php echo $status['name']; ?></td>
<td><?php echo $status['color']; ?></td>
<td><a href="show_tickets.php?<?php echo 's'.$tmp_id.'=1'; ?>&amp;s_my=1&amp;s_ot=1&amp;s_un=1" alt="<?php echo $hesklang['list_tkt_status']; ?>" title="<?php echo $hesklang['list_tkt_status']; ?>"><?php echo $status['tickets']; ?></a></td>
<td><?php echo $status['can_customers_change']; ?></td>
<td class="nowrap buttons">
<?php $modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['confirm_delete_status'],
'custom_statuses.php?a=remove_status&amp;id='. $tmp_id .'&amp;token='. hesk_token_echo(0)); ?>
<p>
<?php if ($is_custom): ?>
<a href="custom_statuses.php?a=edit_status&amp;id=<?php echo $tmp_id; ?>" class="edit" title="<?php echo $hesklang['edit']; ?>">
<svg class="icon icon-edit-ticket">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-edit-ticket"></use>
</svg>
</a>
<?php if ($status['tickets'] > 0): ?>
<a onclick="alert('<?php echo hesk_makeJsString($hesklang['status_not_empty']); ?>');"
style="cursor: not-allowed"
class="delete"
title="<?php echo $hesklang['status_not_empty']; ?>">
<svg class="icon icon-delete">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-delete"></use>
</svg>
</a>
<?php else: ?>
<a class="delete" href="javascript:" data-modal="[data-modal-id='<?php echo $modal_id; ?>']">
<svg class="icon icon-delete">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-delete"></use>
</svg>
</a>
<?php
endif;
endif;
?>
</p>
</td>
</tr>
<?php
} // End foreach
if ($hesk_settings['num_custom_statuses'] == 0):
?>
<tr class="title">
<td colspan="5"><?php echo $hesklang['status_custom']; ?></td>
</tr>
<tr>
<td colspan="5"><?php echo $hesklang['status_custom_none']; ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript" src="<?php echo HESK_PATH; ?>inc/jscolor/jscolor.min.js"></script>
<script type="text/javascript">
function hesk_preview(jscolor) {
document.getElementById('color_preview').style.color = "#" + jscolor;
}
</script>
<div class="right-bar create-status" <?php echo hesk_SESSION('edit_status') || hesk_SESSION(array('new_status','errors')) ? 'style="display: block"' : ''; ?>>
<form action="custom_statuses.php" method="post" name="form1" class="form <?php echo hesk_SESSION(array('new_status','errors')) ? 'invalid' : ''; ?>">
<div class="right-bar__body form">
<h3>
<a href="<?php echo hesk_SESSION('edit_status') ? 'custom_statuses.php' : 'javascript:'; ?>">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span><?php echo hesk_SESSION('edit_status') ? $hesklang['edit_status'] : $hesklang['new_status']; ?></span>
</a>
</h3>
<?php
/* This will handle error, success and notice messages */
if (hesk_SESSION(array('new_status', 'errors'))) {
echo '<div style="margin: -24px -24px 10px -16px;">';
hesk_handle_messages();
echo '</div>';
}
$names = hesk_SESSION(array('new_status','names'));
$errors = hesk_SESSION(array('new_status','errors'));
$errors = is_array($errors) ? $errors : array();
if ($hesk_settings['can_sel_lang'] && count($hesk_settings['languages']) > 1) {
echo '<h4>' . $hesklang['status'] . '</h4>';
foreach ($hesk_settings['languages'] as $lang => $info) { ?>
<div class="form-group">
<label><?php echo $lang; ?></label>
<input type="text" class="form-control <?php echo in_array('names', $errors) ? 'isError' : ''; ?>" name="name[<?php echo $lang; ?>" value="<?php echo (isset($names[$lang]) ? $names[$lang] : ''); ?>">
</div>
<?php }
} else { ?>
<div class="form-group">
<label><?php echo $hesklang['status']; ?></label>
<input type="text" class="form-control <?php echo in_array('names', $errors) ? 'isError' : ''; ?>" name="name[<?php echo $hesk_settings['language']; ?>]"
value="<?php echo isset($names[$hesk_settings['language']]) ? $names[$hesk_settings['language']] : ''; ?>">
</div>
<?php } ?>
<div class="form-group color">
<?php $color = hesk_validate_color_hex(hesk_SESSION(array('new_status','color'))); ?>
<label><?php echo $hesklang['color']; ?></label>
<input type="text" class="form-control jscolor {hash:true, uppercase:false, onFineChange:'hesk_preview(this)'}" name="color" value="<?php echo $color; ?>">
<span id="color_preview" style="color:<?php echo $color; ?>"><?php echo $hesklang['clr_view']; ?></span>
</div>
<div class="form-switcher">
<?php $can_customers_change = hesk_SESSION(array('new_status','can_customers_change'), 0); ?>
<label class="switch-checkbox">
<input type="checkbox" name="can_customers_change" <?php if ($can_customers_change) {echo 'checked';} ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
<span><?php echo $hesklang['ccc']; ?></span>
</label>
</div>
<?php if (isset($_SESSION['edit_status'])): ?>
<input type="hidden" name="a" value="save_status">
<input type="hidden" name="id" value="<?php echo intval($_SESSION['new_status']['id']); ?>">
<?php else: ?>
<input type="hidden" name="a" value="new_status">
<?php endif; ?>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<button type="submit" class="btn btn-full save" ripple="ripple"><?php echo $hesklang['status_save']; ?></button>
</div>
</form>
</div>
<?php
hesk_cleanSessionVars( array('new_status', 'edit_status') );
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function save_status()
{
global $hesk_settings, $hesklang;
global $hesk_error_buffer;
// A security check
# hesk_token_check('POST');
// Get custom status ID
$id = intval( hesk_POST('id') ) or hesk_error($hesklang['status_e_id']);
// Validate inputs
if (($status = status_validate()) == false)
{
$_SESSION['edit_status'] = true;
$_SESSION['new_status']['id'] = $id;
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'custom_statuses.php');
}
// Remove # from color
$color = str_replace('#', '', $status['color']);
// Add custom status data into database
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` SET
`name` = '".hesk_dbEscape($status['names'])."',
`color` = '{$color}',
`can_customers_change` = '{$status['can_customers_change']}'
WHERE `id`={$id}");
// Clear cache
hesk_purge_cache('status');
// Show success
$_SESSION['statusord'] = $id;
hesk_process_messages($hesklang['status_mdf'],'custom_statuses.php','SUCCESS');
} // End save_status()
function edit_status()
{
global $hesk_settings, $hesklang;
// Get custom status ID
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['status_e_id']);
// Get details from the database
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` WHERE `id`={$id} LIMIT 1");
if ( hesk_dbNumRows($res) != 1 )
{
hesk_error($hesklang['status_not_found']);
}
$status = hesk_dbFetchAssoc($res);
$status['names'] = json_decode($status['name'], true);
unset($status['name']);
$status['color'] = '#'.$status['color'];
$_SESSION['new_status'] = $status;
$_SESSION['edit_status'] = true;
} // End edit_status()
function update_status_order()
{
global $hesk_settings, $hesklang;
// Get list of current custom statuses
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` ORDER BY `order` ASC");
// Update database
$i = 10;
while ( $status = hesk_dbFetchAssoc($res) )
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` SET `order`=".intval($i)." WHERE `id`='".intval($status['id'])."'");
$i += 10;
}
return true;
} // END update_status_order()
function remove_status()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get ID
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['status_e_id']);
// Any tickets with this status?
$res = hesk_dbQuery("SELECT COUNT(*) AS `cnt`, `status` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `status` = {$id}");
if (hesk_dbResult($res) > 0)
{
hesk_process_messages($hesklang['status_not_empty'],'./custom_statuses.php');
}
// Reset the custom status
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` WHERE `id`={$id}");
// Were we successful?
if ( hesk_dbAffectedRows() == 1 )
{
// Update order
update_status_order();
// Clear cache
hesk_purge_cache('status');
// Delete custom status data from tickets
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `custom{$id}`=''");
// Show success message
hesk_process_messages($hesklang['status_deleted'],'./custom_statuses.php','SUCCESS');
}
else
{
hesk_process_messages($hesklang['status_not_found'],'./custom_statuses.php');
}
} // End remove_status()
function status_validate()
{
global $hesk_settings, $hesklang;
global $hesk_error_buffer;
$hesk_error_buffer = array();
// Get names
$status['names'] = hesk_POST_array('name');
// Make sure only valid names pass
foreach ($status['names'] as $key => $name)
{
if ( ! isset($hesk_settings['languages'][$key]))
{
unset($status['names'][$key]);
}
else
{
$name = is_array($name) ? '' : hesk_input($name, 0, 0, HESK_SLASH);
if (strlen($name) < 1)
{
unset($status['names'][$key]);
}
else
{
$status['names'][$key] = stripslashes($name);
}
}
}
// No name entered?
$errors = array();
if ( ! count($status['names']))
{
$hesk_error_buffer[] = $hesklang['err_status'];
$errors[] = 'names';
}
// Color
$status['color'] = hesk_validate_color_hex(hesk_POST('color'));
// Can customers change it?
$status['can_customers_change'] = hesk_POST('can_customers_change') ? 1 : 0;
// Any errors?
if (count($hesk_error_buffer))
{
$_SESSION['new_status'] = $status;
$_SESSION['new_status']['errors'] = $errors;
return false;
}
$status['names'] = addslashes(json_encode($status['names']));
return $status;
} // END status_validate()
function new_status()
{
global $hesk_settings, $hesklang;
global $hesk_error_buffer;
// A security check
# hesk_token_check('POST');
// Validate inputs
if (($status = status_validate()) == false)
{
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'custom_statuses.php');
}
// Did we reach status limit?
if (count($hesk_settings['statuses']) >= 100)
{
hesk_process_messages($hesklang['status_limit'],'custom_statuses.php');
}
// Lowest available ID for custom statuses is 6
$next_id = 6;
// Any existing statuses?
if (count($hesk_settings['statuses']) > 6)
{
// The lowest currently used ID
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` ORDER BY `id` ASC LIMIT 1");
$lowest_id = hesk_dbResult($res);
if ($lowest_id > 6)
{
$next_id = 6;
}
else
{
// Minimum next ID
$res = hesk_dbQuery("
SELECT MIN(`t1`.`id` + 1) FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` AS `t1`
LEFT JOIN `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` AS `t2`
ON `t1`.`id` + 1 = `t2`.`id`
WHERE `t2`.`id` IS NULL"
);
$next_id = hesk_dbResult($res);
}
}
// Remove # from color
$color = str_replace('#', '', $status['color']);
// Insert custom status into database
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_statuses` (`id`, `name`, `color`, `can_customers_change`, `order`) VALUES (".intval($next_id).", '".hesk_dbEscape($status['names'])."', '{$color}', '{$status['can_customers_change']}', 990)");
// Update order
update_status_order();
// Clear cache
hesk_purge_cache('status');
$_SESSION['statusord'] = $next_id;
// Show success
hesk_process_messages($hesklang['status_added'],'custom_statuses.php','SUCCESS');
} // End new_status()
function hesk_validate_color_hex($hex, $def = '#000000')
{
$hex = strtolower($hex);
return preg_match('/^\#[a-f0-9]{6}$/', $hex) ? $hex : $def;
} // END hesk_validate_color_hex()
function hesk_get_text_color($bg_color)
{
// Get RGB values
list($r, $g, $b) = sscanf($bg_color, "#%02x%02x%02x");
// Is Black a good text color?
if (hesk_color_diff($r, $g, $b, 0, 0, 0) >= 500)
{
return '#000000';
}
// Use white instead
return '#ffffff';
} // END hesk_get_text_color()
function hesk_color_diff($R1,$G1,$B1,$R2,$G2,$B2)
{
return max($R1,$R2) - min($R1,$R2) +
max($G1,$G2) - min($G1,$G2) +
max($B1,$B2) - min($B1,$B2);
} // END hesk_color_diff()

View File

@@ -0,0 +1,637 @@
<?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');
define('TEMPLATE_PATH', HESK_PATH . "theme/{$hesk_settings['site_theme']}/");
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Set correct return URL */
if (isset($_SERVER['HTTP_REFERER']))
{
$url = hesk_input($_SERVER['HTTP_REFERER']);
$url = str_replace('&amp;','&',$url);
if ($tmp = strstr($url,'show_tickets.php'))
{
$referer = $tmp;
}
elseif ($tmp = strstr($url,'find_tickets.php'))
{
$referer = $tmp;
}
elseif ($tmp = strstr($url,'admin_main.php'))
{
$referer = $tmp;
}
else
{
$referer = 'admin_main.php';
}
}
else
{
$referer = 'admin_main.php';
}
/* Is this a delete ticket request from within a ticket ("delete" icon)? */
if ( isset($_GET['delete_ticket']) )
{
/* Check permissions for this feature */
hesk_checkPermission('can_del_tickets');
/* A security check */
hesk_token_check();
// Tracking ID
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
/* Get ticket info */
$result = hesk_dbQuery("SELECT `id`,`trackid`,`category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
/* Is this user allowed to delete tickets inside this category? */
hesk_okCategory($ticket['category']);
hesk_fullyDeleteTicket();
hesk_process_messages(sprintf($hesklang['num_tickets_deleted'],1),$referer,'SUCCESS');
}
/* This is a request from ticket list. Must be POST and id must be an array */
if ( ! isset($_POST['id']) || ! is_array($_POST['id']) )
{
hesk_process_messages($hesklang['no_selected'], $referer, 'NOTICE');
}
/* If not, then needs an action (a) POST variable set */
elseif ( ! isset($_POST['a']) )
{
hesk_process_messages($hesklang['invalid_action'], $referer);
}
$i=0;
// Possible priorities
$priorities = array(
'critical' => array('value' => 0, 'text' => $hesklang['critical'], 'formatted' => $hesklang['critical']),
'high' => array('value' => 1, 'text' => $hesklang['high'], 'formatted' => $hesklang['high']),
'medium' => array('value' => 2, 'text' => $hesklang['medium'], 'formatted' => $hesklang['medium']),
'low' => array('value' => 3, 'text' => $hesklang['low'], 'formatted' => $hesklang['low']),
);
// Assign tickets to
if ( isset($_POST['action-type']) && $_POST['action-type'] == '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']);
$revision = sprintf($hesklang['thist2'],hesk_date(),'<i>'.$hesklang['unas'].'</i>',$_SESSION['name'].' ('.$_SESSION['user'].')');
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`=0 , `assignedby`=NULL , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `id`={$this_id} LIMIT 1");
$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']))
{
$revision = sprintf($hesklang['thist2'],hesk_date(),$owner_data['name'].' ('.$owner_data['user'].')',$_SESSION['name'].' ('.$_SESSION['user'].')');
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`={$owner} , `assignedby`=".intval($_SESSION['id']).", `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `id`={$this_id} LIMIT 1");
$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');
}
}
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
hesk_token_check('POST');
// Priority info
$priority = $priorities[$_POST['a']];
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 `priority`, `category` 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['priority'] == $priority['value'])
{
continue;
}
hesk_okCategory($ticket['category']);
$revision = sprintf($hesklang['thist8'],hesk_date(),$priority['formatted'],$_SESSION['name'].' ('.$_SESSION['user'].')');
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `priority`='{$priority['value']}', `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `id`={$this_id}");
$i++;
}
hesk_process_messages($hesklang['pri_set_to'].' '.$priority['formatted'],$referer,'SUCCESS');
}
/* DELETE */
elseif ($_POST['a']=='delete')
{
/* Check permissions for this feature */
hesk_checkPermission('can_del_tickets');
/* A security check */
hesk_token_check('POST');
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`,`category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($this_id)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
continue;
}
$ticket = hesk_dbFetchAssoc($result);
hesk_okCategory($ticket['category']);
hesk_fullyDeleteTicket();
$i++;
}
hesk_process_messages(sprintf($hesklang['num_tickets_deleted'],$i),$referer,'SUCCESS');
}
/* MERGE TICKETS */
elseif ($_POST['a']=='merge')
{
/* Check permissions for this feature */
hesk_checkPermission('can_merge_tickets');
/* A security check */
hesk_token_check('POST');
/* Sort IDs, tickets will be merged to the lowest ID */
sort($_POST['id'], SORT_NUMERIC);
/* Select lowest ID as the target ticket */
$merge_into = array_shift($_POST['id']);
/* Merge tickets or throw an error */
if ( hesk_mergeTickets( $_POST['id'] , $merge_into ) )
{
hesk_process_messages($hesklang['merged'],$referer,'SUCCESS');
}
else
{
$hesklang['merge_err'] .= ' ' . $_SESSION['error'];
hesk_cleanSessionVars($_SESSION['error']);
hesk_process_messages($hesklang['merge_err'],$referer);
}
}
/* TAG/UNTAG TICKETS */
elseif ($_POST['a']=='tag' || $_POST['a']=='untag')
{
/* Check permissions for this feature */
hesk_checkPermission('can_add_archive');
/* A security check */
hesk_token_check('POST');
if ($_POST['a']=='tag')
{
$archived = 1;
$action = $hesklang['num_tickets_tag'];
}
else
{
$archived = 0;
$action = $hesklang['num_tickets_untag'];
}
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`,`category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($this_id)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
continue;
}
$ticket = hesk_dbFetchAssoc($result);
hesk_okCategory($ticket['category']);
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `archive`='$archived' WHERE `id`='".intval($this_id)."'");
$i++;
}
hesk_process_messages(sprintf($action,$i),$referer,'SUCCESS');
}
/* 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_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 > 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');
// Load statuses
require_once(HESK_PATH . 'inc/statuses.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');
$tickets = array();
// 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 * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($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");
$ticket['replies'] = $res;
$ticket['categoryName'] = $category['name'];
$tickets[] = $ticket;
}
// Print tickets
require(HESK_PATH . 'inc/print_template.inc.php');
flush();
exit();
}
/* JUST CLOSE */
else
{
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
hesk_checkPermission('can_resolve');
/* A security check */
hesk_token_check('POST');
// Will we need ticket notifications?
if ($hesk_settings['notify_closed'])
{
require(HESK_PATH . 'inc/email_functions.inc.php');
}
$revision = sprintf($hesklang['thist3'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')');
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 " . ($hesk_settings['notify_closed'] ? '*' : '`category`') . " FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($this_id)."' LIMIT 1");
$ticket = hesk_dbFetchAssoc($result);
hesk_okCategory($ticket['category']);
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='3', `closedat`=NOW(), `closedby`=".intval($_SESSION['id']).", `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `id`='".intval($this_id)."'");
$i++;
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed'])
{
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$ticket = hesk_ticketToPlain($ticket, 1, 0);
hesk_notifyCustomer('ticket_closed');
}
}
hesk_process_messages(sprintf($hesklang['num_tickets_closed'],$i),$referer,'SUCCESS');
}
/*** START FUNCTIONS ***/
function hesk_fullyDeleteTicket()
{
global $hesk_settings, $hesklang, $ticket;
/* 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'])."'");
/* Delete the ticket */
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($ticket['id'])."'");
/* Delete replies to the ticket */
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` 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;
}
?>

115
hesk/admin/edit_note.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
// Ticket ID
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
// Note ID
$noteID = intval( hesk_REQUEST('note') ) or die($hesklang['int_error'].': '.$hesklang['mis_note']);
// Get ticket info
$result = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
// Get note info
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` WHERE `id`={$noteID}");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['no_note']);
}
$note = hesk_dbFetchAssoc($result);
// Make sure the note matches the ticket and the user has permission to edit it
if ($note['ticket'] != $ticket['id'] || ( ! hesk_checkPermission('can_del_notes',0) && $note['who'] != $_SESSION['id']) )
{
hesk_error($hesklang['perm_deny']);
}
// Save changes?
if (isset($_POST['save']))
{
// A security check
hesk_token_check('POST');
// Get message
$tmpvar['message'] = nl2br( hesk_makeURL( hesk_input( hesk_POST('message') ) ) );
// If we have message or attachments do the update
if ( strlen($tmpvar['message']) || strlen($note['attachments']) )
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` SET `message`='".hesk_dbEscape($tmpvar['message'])."' WHERE `id`={$noteID}");
hesk_process_messages($hesklang['ednote2'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
}
// If not, delete the note
else
{
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` WHERE `id`={$noteID}");
header('Location: admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999));
exit();
}
}
$note['message'] = hesk_msgToPlain($note['message'],0,0);
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<div class="main__content categories">
<div class="table-wrap">
<h3 style="font-size: 1.3rem; margin-top: 10px"><?php echo $hesklang['ednote']; ?></h3>
<form method="post" action="edit_note.php" name="form1" class="form">
<div class="form-group">
<label for="edit_message"><?php echo $hesklang['message']; ?></label>
<textarea style="height: inherit" name="message" class="form-control" rows="12" cols="60"><?php echo $note['message']; ?></textarea>
</div>
<div class="form-group">
<input type="hidden" name="save" value="1" /><input type="hidden" name="track" value="<?php echo $trackingID; ?>">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input type="hidden" name="note" value="<?php echo $noteID; ?>">
<button type="submit" class="btn btn-full"><?php echo $hesklang['save_changes']; ?></button>
</div>
</form>
</div>
</div>
<p style="text-align:center"><a href="javascript:history.go(-1)"><?php echo $hesklang['back']; ?></a></p>
<p>&nbsp;</p>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
?>

605
hesk/admin/edit_post.php Normal file
View File

@@ -0,0 +1,605 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/posting_functions.inc.php');
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
hesk_checkPermission('can_edit_tickets');
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// Load calendar JS and CSS
define('CALENDAR',1);
$is_reply = 0;
$tmpvar = array();
if (!isset($_SESSION['iserror']))
{
$_SESSION['iserror'] = array();
}
/* Get ticket info */
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
// Demo mode
if ( defined('HESK_DEMO') )
{
$ticket['email'] = 'hidden@demo.com';
}
/* Is this user allowed to view tickets inside this category? */
hesk_okCategory($ticket['category']);
if ( hesk_isREQUEST('reply') )
{
$tmpvar['id'] = intval( hesk_REQUEST('reply') ) or die($hesklang['id_not_valid']);
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `id`='{$tmpvar['id']}' AND `replyto`='".intval($ticket['id'])."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['id_not_valid']);
}
$reply = hesk_dbFetchAssoc($result);
$ticket['message'] = $reply['message'];
$is_reply = 1;
}
// Count number of existing attachments for this post
$number_of_attachments = $is_reply ? hesk_countAttachments($reply['attachments']) : hesk_countAttachments($ticket['attachments']);
if (isset($_POST['save']))
{
/* A security check */
hesk_token_check('POST');
$hesk_error_buffer = array();
// Add attachments?
if ($hesk_settings['attachments']['use'] && $number_of_attachments < $hesk_settings['attachments']['max_number'])
{
require(HESK_PATH . 'inc/attachments.inc.php');
$attachments = array();
for ($i=$number_of_attachments+1;$i<=$hesk_settings['attachments']['max_number'];$i++)
{
$att = hesk_uploadFile($i);
if ($att !== false && !empty($att))
{
$attachments[$i] = $att;
}
}
}
$myattachments = '';
if ($is_reply)
{
$tmpvar['message'] = hesk_input( hesk_POST('message') ) or $hesk_error_buffer[]=$hesklang['enter_message'];
if (count($hesk_error_buffer))
{
// Remove any successfully uploaded attachments
if ($hesk_settings['attachments']['use'] && isset($attachments))
{
hesk_removeAttachments($attachments);
}
$myerror = '<ul>';
foreach ($hesk_error_buffer as $error)
{
$myerror .= "<li>$error</li>\n";
}
$myerror .= '</ul>';
hesk_error($myerror);
}
$tmpvar['message'] = hesk_makeURL($tmpvar['message']);
$tmpvar['message'] = nl2br($tmpvar['message']);
if ($hesk_settings['attachments']['use'] && !empty($attachments))
{
foreach ($attachments as $myatt)
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES ('".hesk_dbEscape($trackingID)."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."')");
$myattachments .= hesk_dbInsertID() . '#' . $myatt['real_name'] .',';
}
}
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` SET `message`='".hesk_dbEscape($tmpvar['message'])."', `attachments`=CONCAT(`attachments`, '".hesk_dbEscape($myattachments)."') WHERE `id`='".intval($tmpvar['id'])."' AND `replyto`='".intval($ticket['id'])."'");
}
else
{
$tmpvar['name'] = hesk_input( hesk_POST('name') ) or $hesk_error_buffer[]=$hesklang['enter_your_name'];
if ($hesk_settings['require_email'])
{
$tmpvar['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer['email']=$hesklang['enter_valid_email'];
}
else
{
$tmpvar['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0);
// Not required, but must be valid if it is entered
if ($tmpvar['email'] == '')
{
if (strlen(hesk_POST('email')))
{
$hesk_error_buffer['email'] = $hesklang['not_valid_email'];
}
}
}
$tmpvar['subject'] = hesk_input( hesk_POST('subject') ) or $hesk_error_buffer[]=$hesklang['enter_ticket_subject'];
$tmpvar['message'] = hesk_input( hesk_POST('message') );
if ($hesk_settings['require_message'] == 1 && $tmpvar['message'] == '')
{
$hesk_error_buffer[] = $hesklang['enter_message'];
}
// Demo mode
if ( defined('HESK_DEMO') )
{
$tmpvar['email'] = 'hidden@demo.com';
}
// Custom fields
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'] && hesk_is_custom_field_in_category($k, $ticket['category']))
{
if ($v['type'] == 'checkbox')
{
$tmpvar[$k]='';
if (isset($_POST[$k]) && is_array($_POST[$k]))
{
foreach ($_POST[$k] as $myCB)
{
$tmpvar[$k] .= ( is_array($myCB) ? '' : hesk_input($myCB) ) . '<br />';;
}
$tmpvar[$k]=substr($tmpvar[$k],0,-6);
}
else
{
if ($v['req'] == 2)
{
$hesk_error_buffer[$k]=$hesklang['fill_all'].': '.$v['name'];
}
$_POST[$k] = '';
}
}
elseif ($v['type'] == 'date')
{
$tmpvar[$k] = hesk_POST($k);
$_SESSION["as_$k"] = '';
if (preg_match("/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/", $tmpvar[$k]))
{
$date = strtotime($tmpvar[$k] . ' t00:00:00 UTC');
$dmin = strlen($v['value']['dmin']) ? strtotime($v['value']['dmin'] . ' t00:00:00 UTC') : false;
$dmax = strlen($v['value']['dmax']) ? strtotime($v['value']['dmax'] . ' t00:00:00 UTC') : false;
$_SESSION["as_$k"] = $tmpvar[$k];
if ($dmin && $dmin > $date)
{
$hesk_error_buffer[$k] = sprintf($hesklang['d_emin'], $v['name'], hesk_custom_date_display_format($dmin, $v['value']['date_format']));
}
elseif ($dmax && $dmax < $date)
{
$hesk_error_buffer[$k] = sprintf($hesklang['d_emax'], $v['name'], hesk_custom_date_display_format($dmax, $v['value']['date_format']));
}
else
{
$tmpvar[$k] = $date;
}
}
else
{
if ($v['req'] == 2)
{
$hesk_error_buffer[$k]=$hesklang['fill_all'].': '.$v['name'];
}
}
}
elseif ($v['type'] == 'email')
{
$tmp = $hesk_settings['multi_eml'];
$hesk_settings['multi_eml'] = $v['value']['multiple'];
$tmpvar[$k] = hesk_validateEmail( hesk_POST($k), 'ERR', 0);
$hesk_settings['multi_eml'] = $tmp;
if ($tmpvar[$k] != '')
{
$_SESSION["as_$k"] = hesk_input($tmpvar[$k]);
}
else
{
$_SESSION["as_$k"] = '';
if ($v['req'] == 2)
{
$hesk_error_buffer[$k] = $v['value']['multiple'] ? sprintf($hesklang['cf_noem'], $v['name']) : sprintf($hesklang['cf_noe'], $v['name']);
}
}
}
elseif ($v['req'] == 2)
{
$tmpvar[$k]=hesk_makeURL(nl2br(hesk_input( hesk_POST($k) )));
if ($tmpvar[$k] == '')
{
$hesk_error_buffer[$k]=$hesklang['fill_all'].': '.$v['name'];
}
}
else
{
$tmpvar[$k]=hesk_makeURL(nl2br(hesk_input(hesk_POST($k))));
}
}
else
{
$tmpvar[$k] = '';
}
}
if (count($hesk_error_buffer))
{
// Remove any successfully uploaded attachments
if ($hesk_settings['attachments']['use'] && isset($attachments))
{
hesk_removeAttachments($attachments);
}
$myerror = '<ul>';
foreach ($hesk_error_buffer as $error)
{
$myerror .= "<li>$error</li>\n";
}
$myerror .= '</ul>';
hesk_error($myerror);
}
$tmpvar['message'] = hesk_makeURL($tmpvar['message']);
$tmpvar['message'] = nl2br($tmpvar['message']);
if ($hesk_settings['attachments']['use'] && !empty($attachments))
{
foreach ($attachments as $myatt)
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES ('".hesk_dbEscape($trackingID)."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."')");
$myattachments .= hesk_dbInsertID() . '#' . $myatt['real_name'] .',';
}
}
$custom_SQL = '';
for ($i=1; $i<=50; $i++)
{
$custom_SQL .= '`custom'.$i.'`=' . (isset($tmpvar['custom'.$i]) ? "'".hesk_dbEscape($tmpvar['custom'.$i])."'" : "''") . ',';
}
$custom_SQL = rtrim($custom_SQL, ',');
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET
`name`='".hesk_dbEscape( hesk_mb_substr($tmpvar['name'], 0, 255) )."',
`email`='".hesk_dbEscape( hesk_mb_substr($tmpvar['email'], 0, 1000) )."',
`subject`='".hesk_dbEscape( hesk_mb_substr($tmpvar['subject'], 0, 255) )."',
`message`='".hesk_dbEscape($tmpvar['message'])."',
`attachments`=CONCAT(`attachments`, '".hesk_dbEscape($myattachments)."'),
$custom_SQL
WHERE `id`='".intval($ticket['id'])."'");
}
unset($tmpvar);
hesk_cleanSessionVars('tmpvar');
hesk_process_messages($hesklang['edt2'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
}
$ticket['message'] = hesk_msgToPlain($ticket['message'],0,0);
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<div class="main__content categories ticket-create">
<div class="table-wrap">
<h3 style="margin-bottom: 20px"><?php echo $hesklang['edtt']; ?></h3>
<form method="post" class="form" action="edit_post.php" name="form1" enctype="multipart/form-data">
<?php
/* If it's not a reply edit all the fields */
if (!$is_reply)
{
?>
<div class="form-group">
<label for="edit_subject"><?php echo $hesklang['subject']; ?></label>
<input type="text" class="form-control" id="edit_subject" name="subject" maxlength="70" value="<?php echo $ticket['subject'];?>">
</div>
<div class="form-group">
<label for="edit_name"><?php echo $hesklang['name']; ?></label>
<input type="text" name="name" id="edit_name" class="form-control" maxlength="50" value="<?php echo $ticket['name'];?>">
</div>
<div class="form-group">
<label for="edit_email"><?php echo $hesklang['email']; ?></label>
<input type="email" name="email" class="form-control" id="edit_email" maxlength="1000" value="<?php echo $ticket['email'];?>">
</div>
<?php
foreach ($hesk_settings['custom_fields'] as $k=>$v) {
if ($v['use'] && hesk_is_custom_field_in_category($k, $ticket['category']) ) {
$k_value = $ticket[$k];
if ($v['type'] == 'checkbox') {
$k_value = explode('<br />',$k_value);
}
$v['req'] = $v['req']==2 ? '<span class="important">*</span>' : '';
switch ($v['type']) {
/* Radio box */
case 'radio':
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<div class="radio-list">';
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
$index = 0;
foreach ($v['value']['radio_options'] as $option)
{
if (strlen($k_value) == 0)
{
$k_value = $option;
$checked = empty($v['value']['no_default']) ? 'checked' : '';
}
elseif ($k_value == $option)
{
$k_value = $option;
$checked = 'checked';
}
else
{
$checked = '';
}
echo '
<div class="radio-custom" style="margin-bottom: 5px">
<input type="radio" id="edit_'.$k.$index.'" name="'.$k.'" value="'.$option.'" '.$checked.' '.$cls.'>
<label for="edit_'.$k.$index.'">'.$option.'</label>
</div>';
$index++;
}
echo '</div>
</div>';
break;
/* Select drop-down box */
case 'select':
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
echo '
<div class="form-group">
<label for="edit_">'.$v['name'].' '.$v['req'].'</label>
<div class="dropdown-select center out-close">
<select name="'.$k.'" '.$cls.'>';
// Show "Click to select"?
if ( ! empty($v['value']['show_select']))
{
echo '<option value="">'.$hesklang['select'].'</option>';
}
foreach ($v['value']['select_options'] as $option)
{
if ($k_value == $option)
{
$k_value = $option;
$selected = 'selected';
}
else
{
$selected = '';
}
echo '<option '.$selected.'>'.$option.'</option>';
}
echo '</select>
</div>
</div>';
break;
/* Checkbox */
case 'checkbox':
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>';
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
$index = 0;
foreach ($v['value']['checkbox_options'] as $option)
{
if (in_array($option,$k_value))
{
$checked = 'checked';
}
else
{
$checked = '';
}
echo '
<div class="checkbox-custom">
<input type="checkbox" id="edit_'.$k.$index.'" name="'.$k.'[]" value="'.$option.'" '.$checked.' '.$cls.'>
<label for="edit_'.$k.$index.'"> '.$option.'</label>
</div>';
$index++;
}
echo '</div>';
break;
/* Large text box */
case 'textarea':
$cls = in_array($k,$_SESSION['iserror']) ? ' isError" ' : '';
$k_value = hesk_msgToPlain($k_value,0,0);
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<textarea name="'.$k.'" class="form-control'.$cls.'" style="height: inherit" rows="'.intval($v['value']['rows']).'" cols="'.intval($v['value']['cols']).'" >'.$k_value.'</textarea>
</div>';
break;
// Date
case 'date':
$k_value = hesk_custom_date_display_format($k_value, 'm/d/Y');
echo '
<section class="param calendar">
<label>'.$v['name'].' '.$v['req'].'</label>
<div class="calendar--button">
<button type="button">
<svg class="icon icon-calendar">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="'. $k .'"
value="'. $k_value .'"
type="text" class="datepicker">
</div>
<div class="calendar--value" '. ($k_value ? 'style="display: block"' : '') . '>
<span>'. $k_value .'</span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>';
break;
// Email
case 'email':
$cls = in_array($k,$_SESSION['iserror']) ? 'isError' : '';
$suggest = $hesk_settings['detect_typos'] ? 'onblur="Javascript:hesk_suggestEmail(\''.$k.'\', \''.$k.'_suggestions\', 0, 1'.($v['value']['multiple'] ? ',1' : '').')"' : '';
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<input class="form-control '.$cls.'" type="email" name="'.$k.'" id="'.$k.'" value="'.$k_value.'" size="40" '.$suggest.'>
</div>
<div id="'.$k.'_suggestions"></div>';
break;
// Hidden
// Handle as text fields for staff
/* Default text input */
default:
$k_value = hesk_msgToPlain($k_value,0,0);
$cls = in_array($k,$_SESSION['iserror']) ? 'isError' : '';
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<input class="form-control '.$cls.'" type="text" name="'.$k.'" size="40" maxlength="'.intval($v['value']['max_length']).'" value="'.$k_value.'">
</div>';
}
}
}
?>
<?php
}
?>
<div class="form-group">
<label for="edit_message"><?php echo $hesklang['message']; ?></label>
<textarea style="height: inherit" class="form-control" id="edit_message" name="message" rows="12" cols="60"><?php echo $ticket['message']; ?></textarea>
</div>
<?php
// attachments
if ($hesk_settings['attachments']['use'] && $number_of_attachments < $hesk_settings['attachments']['max_number'])
{
echo '<div class="form-group">';
echo '<label>' . $hesklang['attachments'] . ' (<a class="link" href="javascript:" onclick="hesk_window(\'../file_limits.php\',250,500);return false;">' . $hesklang['ful'] . '</a>)</label>';
for ($i=$number_of_attachments+1;$i<=$hesk_settings['attachments']['max_number'];$i++)
{
echo '<input type="file" name="attachment['.$i.']" size="50" /><br />';
}
echo '</div>';
}
?>
<input type="hidden" name="save" value="1">
<input type="hidden" name="track" value="<?php echo $trackingID; ?>">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<?php
if ($is_reply)
{
?>
<input type="hidden" name="reply" value="<?php echo $tmpvar['id']; ?>" />
<?php
}
?>
<button type="submit" class="btn btn-full" style="display: inline-flex; height: 48px">
<?php echo $hesklang['save_changes']; ?>
</button>
<a href="javascript:history.go(-1)" class="btn btn--blue-border"><?php echo $hesklang['back']; ?></a>
</form>
</div>
</div>
<p style="text-align:center"></p>
<p>&nbsp;</p>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
function hesk_countAttachments($attachments_string)
{
if ( ! strlen($attachments_string) || strpos($attachments_string, ',') === false)
{
return 0;
}
$att = explode(',', substr($attachments_string, 0, -1));
return count($att);
} // END hesk_countAttachments()

View File

@@ -0,0 +1,427 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_email_tpl');
// Define required constants
define('LOAD_TABS',1);
// Get valid email templates
require(HESK_PATH . 'inc/email_functions.inc.php');
$emails = array_keys(hesk_validEmails());
// Which language are we editing?
if ($hesk_settings['can_sel_lang'])
{
$hesk_settings['edit_language'] = hesk_REQUEST('edit_language');
if ( ! isset($hesk_settings['languages'][$hesk_settings['edit_language']]) )
{
$hesk_settings['edit_language'] = $hesk_settings['language'];
}
}
else
{
$hesk_settings['edit_language'] = $hesk_settings['language'];
}
// What should we do?
if ( $action = hesk_REQUEST('a') )
{
if ($action == 'edit') {}
elseif ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'email_templates.php', 'NOTICE');}
elseif ($action == 'save') {save_et();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
if ($action != 'edit') {
hesk_handle_messages();
}
?>
<div class="main__content tools">
<section class="tools__between-head fw">
<div class="head--tooltip">
<h2><?php echo $hesklang['et_title']; ?></h2>
<span><?php echo $hesklang['et_intro']; ?></span>
</div>
<?php if ($hesk_settings['can_sel_lang'] && count($hesk_settings['languages']) > 1): ?>
<form method="get" action="email_templates.php">
<div class="dropdown-select center out-close">
<select name="edit_language" onchange="this.form.submit()">
<?php foreach ($hesk_settings['languages'] as $lang => $info): ?>
<option value="<?php echo $lang; ?>" <?php if ($lang === $hesk_settings['edit_language']): ?>selected<?php endif; ?>>
<?php echo $lang; ?>
</option>
<?php endforeach; ?>
</select>
</div>
</form>
<?php endif; ?>
</section>
<div class="table-wrapper email-templates">
<div class="table">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['email_tpl_title']; ?></th>
<th><?php echo $hesklang['rdesc']; ?></th>
<th></th>
</tr>
</thead>
<tbody>
<?php
$all_files = true;
$all_writable = true;
foreach ($emails as $email):
$eml_file = et_file_path($email);
?>
<tr>
<td><?php echo $email; ?>.txt</td>
<td><?php echo $hesklang['desc_'.$email]; ?></td>
<td class="buttons">
<?php
if (!file_exists($eml_file)) {
$all_files = false;
echo '<span style="color:red">'.$hesklang['no_exists'].'</span>';
} elseif (!is_writable($eml_file)) {
$all_writable = false;
echo '<span style="color:red">'.$hesklang['not_writable'].'</span>';
} else {
?>
<a title="<?php echo $hesklang['edit']; ?>" href="email_templates.php?a=edit&amp;id=<?php echo $email; ?>&amp;edit_language=<?php echo urlencode($hesk_settings['edit_language']); ?>" class="edit">
<svg class="icon icon-edit-ticket">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-edit-ticket"></use>
</svg>
</a>
<?php
}
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php
// Any template missing?
if (!$all_files)
{
hesk_show_error(sprintf($hesklang['etfm'], $hesk_settings['languages'][$hesk_settings['edit_language']]['folder']));
}
// Any template not writable?
if (!$all_writable)
{
hesk_show_error(sprintf($hesklang['etfw'], $hesk_settings['languages'][$hesk_settings['edit_language']]['folder']));
}
?>
</div>
</div>
</div>
<?php
// EDIT
if ($action == 'edit')
{
// Get email ID
$email = hesk_GET('id');
// Get file path
$eml_file = et_file_path($email);
// Make sure the file exists and is writable
if ( ! file_exists($eml_file))
{
hesk_error($hesklang['et_fm']);
}
elseif ( ! is_writable($eml_file))
{
hesk_error($hesklang['et_fw']);
}
// Start the edit form
?>
<div class="right-bar tools-email-template-edit" style="display: block">
<div class="right-bar__body form">
<h3>
<a href="email_templates.php">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span><?php echo $hesklang['edit_email_template']; ?></span>
</a>
</h3>
<?php
/* This will handle error, success and notice messages */
echo '<div style="margin: -24px -24px 10px -16px;">';
hesk_handle_messages();
echo '</div>';
?>
<section class="param">
<span><?php echo $hesklang['efile']; ?></span>
<form method="get" action="email_templates.php">
<div class="dropdown-select center out-close">
<select name="id" onchange="this.form.submit()">
<?php
foreach ($emails as $email_tmp) {
$eml_file_tmp = et_file_path($email_tmp);
if (!file_exists($eml_file_tmp) || !is_writable($eml_file_tmp)) {
continue;
}
if ($email_tmp === $email) {
echo '<option value="'.$email_tmp.'" selected>' . $hesklang['desc_'.$email_tmp].'</option>';
} else {
echo '<option value="'.$email_tmp.'">' . $hesklang['desc_'.$email_tmp].'</option>';
}
}
?>
</select>
<input type="hidden" name="a" value="edit">
<input type="hidden" name="edit_language" value="<?php echo hesk_htmlspecialchars($hesk_settings['edit_language']); ?>">
</div>
</form>
</section>
<?php if ($hesk_settings['can_sel_lang'] && count($hesk_settings['languages']) > 1): ?>
<section class="param">
<form method="get" action="email_templates.php">
<span><?php echo $hesklang['lgs']; ?></span>
<div class="dropdown-select center out-close">
<select name="edit_language" onchange="this.form.submit()">
<?php foreach ($hesk_settings['languages'] as $lang => $info): ?>
<option value="<?php echo $lang; ?>" <?php if ($lang === $hesk_settings['edit_language']) { ?>selected<?php } ?>>
<?php echo $lang; ?>
</option>
<?php endforeach; ?>
</select>
<input type="hidden" name="a" value="edit" />
<input type="hidden" name="id" value="<?php echo $email; ?>" />
</div>
</form>
</section>
<?php endif; ?>
<form action="email_templates.php" method="post" name="form1">
<div class="form-group">
<label for="message"><?php echo $hesklang['source'] . ': ' . substr($eml_file, 2); ?></label>
<span id="HeskMsg">
<textarea class="form-control" name="msg" rows="35" cols="100"><?php echo hesk_htmlspecialchars(file_get_contents($eml_file)); ?></textarea>
</span>
</div>
<div class="template--tags">
<label><?php echo $hesklang['insert_special']; ?></label>
<div class="tag-list">
<?php if ($email == 'forgot_ticket_id'): ?>
<a href="javascript:" title="%%NAME%%" onclick="hesk_insertTag('NAME')">
<?php echo $hesklang['name']; ?>
</a>
<a href="javascript:" title="%%FIRST_NAME%%" onclick="hesk_insertTag('FIRST_NAME')">
<?php echo $hesklang['fname']; ?>
</a>
<a href="javascript:" title="%%NUM%%" onclick="hesk_insertTag('NUM')">
<?php echo $hesklang['et_num']; ?>
</a>
<a href="javascript:" title="%%LIST_TICKETS%%" onclick="hesk_insertTag('LIST_TICKETS')">
<?php echo $hesklang['et_list']; ?>
</a>
<a href="javascript:" title="%%SITE_TITLE%%" onclick="hesk_insertTag('SITE_TITLE')">
<?php echo $hesklang['wbst_title']; ?>
</a>
<a href="javascript:" title="%%SITE_URL%%" onclick="hesk_insertTag('SITE_URL')">
<?php echo $hesklang['wbst_url']; ?>
</a>
<?php elseif ($email == 'new_pm'): ?>
<a href="javascript:" title="%%NAME%%" onclick="hesk_insertTag('NAME')">
<?php echo $hesklang['name']; ?>
</a>
<a href="javascript:" title="%%FIRST_NAME%%" onclick="hesk_insertTag('FIRST_NAME')">
<?php echo $hesklang['fname']; ?>
</a>
<a href="javascript:" title="%%SUBJECT%%" onclick="hesk_insertTag('SUBJECT')">
<?php echo $hesklang['subject']; ?>
</a>
<a href="javascript:" title="%%MESSAGE%%" onclick="hesk_insertTag('MESSAGE')">
<?php echo $hesklang['message']; ?>
</a>
<a href="javascript:" title="%%TRACK_URL%%" onclick="hesk_insertTag('TRACK_URL')">
<?php echo $hesklang['pm_url']; ?>
</a>
<a href="javascript:" title="%%SITE_TITLE%%" onclick="hesk_insertTag('SITE_TITLE')">
<?php echo $hesklang['wbst_title']; ?>
</a>
<a href="javascript:" title="%%SITE_URL%%" onclick="hesk_insertTag('SITE_URL')">
<?php echo $hesklang['wbst_url']; ?>
</a>
<?php else: ?>
<a href="javascript:" title="%%NAME%%" onclick="hesk_insertTag('NAME')">
<?php echo $hesklang['name']; ?>
</a>
<a href="javascript:" title="%%FIRST_NAME%%" onclick="hesk_insertTag('FIRST_NAME')">
<?php echo $hesklang['fname']; ?>
</a>
<a href="javascript:" title="%%EMAIL%%" onclick="hesk_insertTag('EMAIL')">
<?php echo $hesklang['email']; ?>
</a>
<a href="javascript:" title="%%CATEGORY%%" onclick="hesk_insertTag('CATEGORY')">
<?php echo $hesklang['category']; ?>
</a>
<a href="javascript:" title="%%PRIORITY%%" onclick="hesk_insertTag('PRIORITY')">
<?php echo $hesklang['priority']; ?>
</a>
<a href="javascript:" title="%%STATUS%%" onclick="hesk_insertTag('STATUS')">
<?php echo $hesklang['status']; ?>
</a>
<a href="javascript:" title="%%SUBJECT%%" onclick="hesk_insertTag('SUBJECT')">
<?php echo $hesklang['subject']; ?>
</a>
<a href="javascript:" title="%%MESSAGE%%" onclick="hesk_insertTag('MESSAGE')">
<?php echo $hesklang['message']; ?>
</a>
<a href="javascript:" title="%%CREATED%%" onclick="hesk_insertTag('CREATED')">
<?php echo $hesklang['created_on']; ?>
</a>
<a href="javascript:" title="%%UPDATED%%" onclick="hesk_insertTag('UPDATED')">
<?php echo $hesklang['updated_on']; ?>
</a>
<a href="javascript:" title="%%OWNER%%" onclick="hesk_insertTag('OWNER')">
<?php echo $hesklang['owner']; ?>
</a>
<a href="javascript:" title="%%LAST_REPLY_BY%%" onclick="hesk_insertTag('LAST_REPLY_BY')">
<?php echo $hesklang['last_replier']; ?>
</a>
<a href="javascript:" title="%%TIME_WORKED%%" onclick="hesk_insertTag('TIME_WORKED')">
<?php echo $hesklang['ts']; ?>
</a>
<a href="javascript:" title="%%TRACK_ID%%" onclick="hesk_insertTag('TRACK_ID')">
<?php echo $hesklang['trackID']; ?>
</a>
<a href="javascript:" title="%%ID%%" onclick="hesk_insertTag('ID')">
<?php echo $hesklang['seqid']; ?>
</a>
<a href="javascript:" title="%%TRACK_URL%%" onclick="hesk_insertTag('TRACK_URL')">
<?php echo $hesklang['ticket_url']; ?>
</a>
<a href="javascript:" title="%%SITE_TITLE%%" onclick="hesk_insertTag('SITE_TITLE')">
<?php echo $hesklang['wbst_title']; ?>
</a>
<a href="javascript:" title="%%SITE_URL%%" onclick="hesk_insertTag('SITE_URL')">
<?php echo $hesklang['wbst_url']; ?>
</a>
<?php
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'])
{
echo '<a href="javascript:" title="%%'.strtoupper($k).'%%" onclick="hesk_insertTag(\''.strtoupper($k).'\')">'.$v['name'].'</a>';
}
}
endif;
?>
</div>
</div>
<div class="right-bar__footer">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<input type="hidden" name="a" value="save" />
<input type="hidden" name="edit_language" value="<?php echo hesk_htmlspecialchars($hesk_settings['edit_language']); ?>" />
<input type="hidden" name="id" value="<?php echo $email; ?>" />
<button type="submit" class="btn btn-full save" ripple="ripple"><?php echo $hesklang['et_save']; ?></button>
</div>
</form>
</div>
</div>
<?php
} // END EDIT
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function save_et()
{
global $hesk_settings, $hesklang;
// A security check
# hesk_token_check('POST');
// Get email ID
$email = hesk_POST('id');
// Get file path
$eml_file = et_file_path($email);
// Make sure the file exists and is writable
if ( ! file_exists($eml_file))
{
hesk_error($hesklang['et_fm']);
}
elseif ( ! is_writable($eml_file))
{
hesk_error($hesklang['et_fw']);
}
// Get message
$message = trim(hesk_POST('msg'));
// Do we need to remove backslashes from the message?
if ( ! HESK_SLASH)
{
$message = stripslashes($message);
}
// We won't accept an empty message
if ( ! strlen($message))
{
hesk_process_messages($hesklang['et_empty'],'email_templates.php?a=edit&id=' . $email . '&edit_language='.$hesk_settings['edit_language']);
}
// Save to the file
file_put_contents($eml_file, $message);
// Show success
$_SESSION['et_id'] = $email;
hesk_process_messages($hesklang['et_saved'],'email_templates.php?edit_language='.$hesk_settings['edit_language'],'SUCCESS');
} // End save_et()
function et_file_path($id)
{
global $hesk_settings, $hesklang, $emails;
if ( ! in_array($id, $emails))
{
hesk_error($hesklang['inve']);
}
return HESK_PATH . 'language/' . $hesk_settings['languages'][$hesk_settings['edit_language']]['folder'] . '/emails/' . $id . '.txt';
} // END et_file_path()

557
hesk/admin/export.php Normal file
View File

@@ -0,0 +1,557 @@
<?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/reporting_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_export');
// Just a delete file action?
$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'], hesk_verifyGoto(), 'SUCCESS');
}
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// Load statuses
require_once(HESK_PATH . 'inc/statuses.inc.php');
// Set default values
define('CALENDAR',1);
define('MAIN_PAGE',1);
define('LOAD_TABS',1);
$selected = array(
'w' => array(0=>'',1=>''),
'time' => array(1=>'',2=>'',3=>'',4=>'',5=>'',6=>'',7=>'',8=>'',9=>'',10=>'',11=>'',12=>''),
);
$is_all_time = 0;
// Default this month to date
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m"), 1, date("Y")));
$date_to = date('Y-m-d');
$input_datefrom = date('m/d/Y', strtotime('last month'));
$input_dateto = date('m/d/Y');
/* Date */
if (!empty($_GET['w']))
{
$df = preg_replace('/[^0-9]/','', hesk_GET('datefrom') );
if (strlen($df) == 8)
{
$date_from = substr($df,4,4) . '-' . substr($df,0,2) . '-' . substr($df,2,2);
$input_datefrom = substr($df,0,2) . '/' . substr($df,2,2) . '/' . substr($df,4,4);
}
else
{
$date_from = date('Y-m-d', strtotime('last month') );
}
$dt = preg_replace('/[^0-9]/','', hesk_GET('dateto') );
if (strlen($dt) == 8)
{
$date_to = substr($dt,4,4) . '-' . substr($dt,0,2) . '-' . substr($dt,2,2);
$input_dateto = substr($dt,0,2) . '/' . substr($dt,2,2) . '/' . substr($dt,4,4);
}
else
{
$date_to = date('Y-m-d');
}
if ($date_from > $date_to)
{
$tmp = $date_from;
$tmp2 = $input_datefrom;
$date_from = $date_to;
$input_datefrom = $input_dateto;
$date_to = $tmp;
$input_dateto = $tmp2;
$note_buffer = $hesklang['datetofrom'];
}
if ($date_to > date('Y-m-d'))
{
$date_to = date('Y-m-d');
$input_dateto = date('m/d/Y');
}
$selected['w'][1]='checked="checked"';
$selected['time'][3]='selected="selected"';
}
else
{
$selected['w'][0]='checked="checked"';
$_GET['time'] = intval( hesk_GET('time', 3) );
switch ($_GET['time'])
{
case 1:
/* Today */
$date_from = date('Y-m-d');
$date_to = $date_from;
$selected['time'][1]='selected="selected"';
$is_all_time = 1;
break;
case 2:
/* Yesterday */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m"), date("d")-1, date("Y")));
$date_to = $date_from;
$selected['time'][2]='selected="selected"';
$is_all_time = 1;
break;
case 4:
/* Last month */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m")-1, 1, date("Y")));
$date_to = date('Y-m-d',mktime(0, 0, 0, date("m"), 0, date("Y")));
$selected['time'][4]='selected="selected"';
break;
case 5:
/* Last 30 days */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m")-1, date("d"), date("Y")));
$date_to = date('Y-m-d');
$selected['time'][5]='selected="selected"';
break;
case 6:
/* This week */
list($date_from,$date_to)=dateweek(0);
$date_to = date('Y-m-d');
$selected['time'][6]='selected="selected"';
break;
case 7:
/* Last week */
list($date_from,$date_to)=dateweek(-1);
$selected['time'][7]='selected="selected"';
break;
case 8:
/* This business week */
list($date_from,$date_to)=dateweek(0,1);
$date_to = date('Y-m-d');
$selected['time'][8]='selected="selected"';
break;
case 9:
/* Last business week */
list($date_from,$date_to)=dateweek(-1,1);
$selected['time'][9]='selected="selected"';
break;
case 10:
/* This year */
$date_from = date('Y').'-01-01';
$date_to = date('Y-m-d');
$selected['time'][10]='selected="selected"';
break;
case 11:
/* Last year */
$date_from = date('Y')-1 . '-01-01';
$date_to = date('Y')-1 . '-12-31';
$selected['time'][11]='selected="selected"';
break;
case 12:
/* All time */
$date_from = hesk_getOldestDate();
$date_to = date('Y-m-d');
$selected['time'][12]='selected="selected"';
$is_all_time = 1;
break;
default:
$_GET['time'] = 3;
$selected['time'][3]='selected="selected"';
}
}
unset($tmp);
// Start SQL statement for selecting tickets
$sql = "SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE ";
// Some default settings
$archive = array(1=>0,2=>0);
$s_my = array(1=>1,2=>1);
$s_ot = array(1=>1,2=>1);
$s_un = array(1=>1,2=>1);
// --> TICKET CATEGORY
$category = intval( hesk_GET('category', 0) );
// Make sure user has access to this category
if ($category && hesk_okCategory($category, 0) )
{
$sql .= " `category`='{$category}' ";
}
// No category selected, show only allowed categories
else
{
$sql .= hesk_myCategories();
}
// Show only tagged tickets?
if ( ! empty($_GET['archive']) )
{
$archive[1]=1;
$sql .= " AND `archive`='1' ";
}
// Ticket owner preferences
$fid = 1;
require(HESK_PATH . 'inc/assignment_search.inc.php');
// --> TICKET STATUS
$status = $hesk_settings['statuses'];
foreach ($status as $k => $v)
{
if (empty($_GET['s'.$k]))
{
unset($status[$k]);
}
}
// How many statuses are we pulling out of the database?
$tmp = count($status);
// Do we need to search by status?
if ( $tmp < 6 )
{
// If no statuses selected, show all
if ($tmp == 0)
{
$status = $hesk_settings['statuses'];
}
else
{
// Add to the SQL
$sql .= " AND `status` IN ('" . implode("','", array_keys($status) ) . "') ";
}
}
// --> TICKET PRIORITY
$possible_priority = array(
0 => 'CRITICAL',
1 => 'HIGH',
2 => 'MEDIUM',
3 => 'LOW',
);
$priority = $possible_priority;
foreach ($priority as $k => $v)
{
if (empty($_GET['p'.$k]))
{
unset($priority[$k]);
}
}
// How many priorities are we pulling out of the database?
$tmp = count($priority);
// Create the SQL based on the number of priorities we need
if ($tmp == 0 || $tmp == 4)
{
// Nothing or all selected, no need to modify the SQL code
$priority = $possible_priority;
}
else
{
// A custom selection of priorities
$sql .= " AND `priority` IN ('" . implode("','", array_keys($priority) ) . "') ";
}
// Prepare variables used in search and forms
require_once(HESK_PATH . 'inc/prepare_ticket_export.inc.php');
////////////////////////////////////////////////////////////////////////////////
// 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);
// Category options
$category_options = '';
$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);
$row['name'] = (hesk_mb_strlen($row['name']) > 50) ? hesk_mb_substr($row['name'],0,50) . '...' : $row['name'];
$cat_selected = ($row['id'] == $category) ? 'selected="selected"' : '';
$category_options .= '<option value="'.$row['id'].'" '.$cat_selected.'>'.$row['name'].'</option>';
}
// Generate export file
if (isset($_GET['w']))
{
require_once(HESK_PATH . 'inc/export_functions.inc.php');
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql);
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
hesk_handle_messages();
// If an export was generated, show the link to download
if (isset($success_msg))
{
if ($tickets_exported > 0)
{
hesk_show_success($success_msg);
}
else
{
hesk_show_notice($hesklang['n2ex']);
}
}
?>
<div class="main__content reports">
<h2>
<?php echo $hesklang['export']; ?>
<div class="tooltype right out-close">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
<div class="tooltype__content">
<div class="tooltype__wrapper">
<?php echo $hesklang['export_intro']; ?>
</div>
</div>
</div>
</h2>
<form name="showt" action="export.php" method="get">
<div class="reports__range pl0">
<h4><?php echo $hesklang['dtrg']; ?></h4>
<div class="reports__range_form form">
<div class="radio-list">
<div class="radio-custom">
<input type="radio" name="w" value="0" id="w0" <?php echo $selected['w'][0]; ?>>
<label for="w0">&nbsp;</label>
<div class="dropdown-select center out-close">
<select name="time" onclick="document.getElementById('w0').checked = true" onchange="document.getElementById('w0').checked = true" style="margin-top:5px;margin-bottom:5px;">
<option value="1" <?php echo $selected['time'][1]; ?>><?php echo $hesklang['r1']; ?> (<?php echo $hesklang['d'.date('w')]; ?>)</option>
<option value="2" <?php echo $selected['time'][2]; ?>><?php echo $hesklang['r2']; ?> (<?php echo $hesklang['d'.date('w',mktime(0, 0, 0, date('m'), date('d')-1, date('Y')))]; ?>)</option>
<option value="3" <?php echo $selected['time'][3]; ?>><?php echo $hesklang['r3']; ?> (<?php echo $hesklang['m'.date('n')]; ?>)</option>
<option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?> (<?php echo $hesklang['m'.date('n',mktime(0, 0, 0, date('m')-1, 1, date('Y')))]; ?>)</option>
<option value="5" <?php echo $selected['time'][5]; ?>><?php echo $hesklang['r5']; ?></option>
<option value="6" <?php echo $selected['time'][6]; ?>><?php echo $hesklang['r6']; ?></option>
<option value="7" <?php echo $selected['time'][7]; ?>><?php echo $hesklang['r7']; ?></option>
<option value="8" <?php echo $selected['time'][8]; ?>><?php echo $hesklang['r8']; ?></option>
<option value="9" <?php echo $selected['time'][9]; ?>><?php echo $hesklang['r9']; ?></option>
<option value="10" <?php echo $selected['time'][10]; ?>><?php echo $hesklang['r10']; ?> (<?php echo date('Y'); ?>)</option>
<option value="11" <?php echo $selected['time'][11]; ?>><?php echo $hesklang['r11']; ?> (<?php echo date('Y',mktime(0, 0, 0, date('m'), date('d'), date('Y')-1)); ?>)</option>
<option value="12" <?php echo $selected['time'][12]; ?>><?php echo $hesklang['r12']; ?></option>
</select>
</div>
</div>
<div class="radio-custom">
<input type="radio" name="w" value="1" id="w1" <?php echo $selected['w'][1]; ?>>
<label for="w1">&nbsp;</label>
<?php echo $hesklang['from']; ?>
<section class="param calendar" style="margin-left: 10px; margin-right: 10px">
<div class="calendar--button">
<button type="button" onclick="document.getElementById('w1').checked = true">
<svg class="icon icon-calendar">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="datefrom"
id="datefrom"
<?php if ($input_datefrom) {echo 'value="'.$input_datefrom.'"';} ?>
type="text" class="datepicker">
</div>
<div class="calendar--value" <?php echo ($input_datefrom ? 'style="display: block"' : ''); ?>>
<span><?php echo $input_datefrom; ?></span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>
<?php echo $hesklang['to']; ?>
<section class="param calendar" style="margin-left: 10px;">
<div class="calendar--button">
<button type="button" onclick="document.getElementById('w1').checked = true">
<svg class="icon icon-calendar">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="dateto"
id="dateto"
<?php if ($input_dateto) {echo 'value="'.$input_dateto.'"';} ?>
type="text" class="datepicker">
</div>
<div class="calendar--value" <?php echo ($input_dateto ? 'style="display: block"' : ''); ?>>
<span><?php echo $input_dateto; ?></span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>
</div>
</div>
</div>
</div>
<section class="reports__checkbox">
<h3><?php echo $hesklang['status']; ?></h3>
<?php
hesk_get_status_checkboxes($status);
?>
</section>
<section class="reports__checkbox">
<h3><?php echo $hesklang['priority']; ?></h3>
<div class="checkbox-custom">
<input type="checkbox" name="p0" id="p0" value="1" <?php if (isset($priority[0])) {echo 'checked';} ?>>
<label for="p0"><?php echo $hesklang['critical']; ?></label>
</div>
<div class="checkbox-custom">
<input type="checkbox" name="p1" id="p1" value="1" <?php if (isset($priority[1])) {echo 'checked';} ?>>
<label for="p1"><?php echo $hesklang['high']; ?></label>
</div>
<div class="checkbox-custom">
<input type="checkbox" name="p2" id="p2" value="1" <?php if (isset($priority[2])) {echo 'checked';} ?>>
<label for="p2"><?php echo $hesklang['medium']; ?></label>
</div>
<div class="checkbox-custom">
<input type="checkbox" name="p3" id="p3" value="1" <?php if (isset($priority[3])) {echo 'checked';} ?>>
<label for="p3"><?php echo $hesklang['low']; ?></label>
</div>
</section>
<section class="reports__checkbox">
<h3><?php echo $hesklang['assigned_to']; ?></h3>
<div class="checkbox-custom">
<input type="checkbox" name="s_my" id="s_my" value="1" <?php if ($s_my[1]) echo 'checked'; ?>>
<label for="s_my"><?php echo $hesklang['s_my']; ?></label>
</div>
<?php
if ($can_view_unassigned)
{
?>
<div class="checkbox-custom">
<input type="checkbox" name="s_un" id="s_un" value="1" <?php if ($s_un[1]) echo 'checked'; ?>>
<label for="s_un"><?php echo $hesklang['s_un']; ?></label>
</div>
<?php
}
if ($can_view_ass_others)
{
?>
<div class="checkbox-custom">
<input type="checkbox" name="s_ot" id="s_ot" value="1" <?php if ($s_ot[1]) echo 'checked'; ?>>
<label for="reportCheck14"><?php echo $hesklang['s_ot']; ?></label>
</div>
<?php
}
?>
<div class="checkbox-custom">
<input type="checkbox" name="archive" id="archive" value="1" <?php if ($archive[1]) echo 'checked'; ?>>
<label for="archive"><?php echo $hesklang['disp_only_archived']; ?></label>
</div>
</section>
<section class="reports__checkbox">
<h3><?php echo $hesklang['sort_by']; ?></h3>
<div class="radio-list">
<div class="radio-custom">
<input type="radio" name="sort" id="sort_priority" value="priority" <?php if ($sort == 'priority') {echo 'checked';} ?>>
<label for="sort_priority"><?php echo $hesklang['priority']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" name="sort" id="sort_lastchange" value="lastchange" <?php if ($sort == 'lastchange') {echo 'checked';} ?>>
<label for="sort_lastchange"><?php echo $hesklang['last_update']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" name="sort" id="sort_name" value="name" <?php if ($sort == 'name') {echo 'checked';} ?>>
<label for="sort_name"><?php echo $hesklang['name']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" name="sort" id="sort_subject" value="subject" <?php if ($sort == 'subject') {echo 'checked';} ?>>
<label for="sort_subject"><?php echo $hesklang['subject']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" name="sort" id="sort_status" value="status" <?php if ($sort == 'status') {echo 'checked';} ?>>
<label for="sort_status"><?php echo $hesklang['status']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" name="sort" id="sort_id" value="id" <?php if ($sort == 'id') {echo 'checked';} ?>>
<label for="sort_id"><?php echo $hesklang['sequentially']; ?></label>
</div>
</div>
</section>
<section class="reports__checkbox">
<h3><?php echo $hesklang['category']; ?></h3>
<div class="dropdown-select center out-close">
<select name="category">
<option value="0" ><?php echo $hesklang['any_cat']; ?></option>
<?php echo $category_options; ?>
</select>
</div>
</section>
<section class="reports__checkbox">
<h3><?php echo $hesklang['order']; ?></h3>
<div class="radio-list">
<div class="radio-custom">
<input type="radio" name="asc" id="asc_1" value="1" <?php if ($asc) {echo 'checked';} ?>>
<label for="asc_1"><?php echo $hesklang['ascending']; ?></label>
</div>
<div class="radio-custom">
<input type="radio" name="asc" id="asc_0" value="0" <?php if (!$asc) {echo 'checked';} ?>>
<label for="asc_0"><?php echo $hesklang['descending']; ?></label>
</div>
</div>
</section>
<div class="reports__export">
<input type="hidden" name="cot" value="1">
<button class="btn btn-full" ripple="ripple" data-action="reports-export"><?php echo $hesklang['export_btn']; ?></button>
</div>
</form>
</div>
<?php
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
?>

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

290
hesk/admin/find_tickets.php Normal file
View File

@@ -0,0 +1,290 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
define('CALENDAR',1);
$_SESSION['hide']['ticket_list'] = true;
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
$_SERVER['PHP_SELF'] = './admin_main.php';
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// Load statuses
require_once(HESK_PATH . 'inc/statuses.inc.php');
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<div class="main__content tickets">
<div style="margin-left: -16px; margin-right: -24px;">
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
</div>
<?php
$header_text = '
<section style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px">
<h2 style="font-size: 18px; font-weight: bold">'. $hesklang['tickets_found'] .' (%%HESK_TICKET_COUNT%%)</h2>
</section>';
// This SQL code will be used to retrieve results
$sql_final = "SELECT
`id`,
`trackid`,
`name`,
`email`,
`category`,
`priority`,
`subject`,
LEFT(`message`, 400) AS `message`,
`dt`,
`lastchange`,
`firstreply`,
`closedat`,
`status`,
`openedby`,
`firstreplyby`,
`closedby`,
`replies`,
`staffreplies`,
`owner`,
`time_worked`,
`lastreplier`,
`replierid`,
`archive`,
`locked`
";
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'])
{
$sql_final .= ", `".$k."`";
}
}
$sql_final.= " FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE ";
// This code will be used to count number of results
$sql_count = "SELECT COUNT(*) FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE ";
// This is common SQL for both queries
$sql = "";
// Some default settings
$archive = array(1=>0,2=>0);
$s_my = array(1=>1,2=>1);
$s_ot = array(1=>1,2=>1);
$s_un = array(1=>1,2=>1);
// --> TICKET CATEGORY
$category = intval( hesk_GET('category', 0) );
// Make sure user has access to this category
if ($category && hesk_okCategory($category, 0) )
{
$sql .= " `category`='{$category}' ";
}
// No category selected, show only allowed categories
else
{
$sql .= hesk_myCategories();
}
// Show only tagged tickets?
if ( ! empty($_GET['archive']) )
{
$archive[2]=1;
$sql .= " AND `archive`='1' ";
}
// Ticket owner preferences
$fid = 2;
require(HESK_PATH . 'inc/assignment_search.inc.php');
$hesk_error_buffer = '';
$no_query = 0;
// Search query
$q = hesk_input( hesk_GET('q', '') );
// No query entered?
if ( ! strlen($q) )
{
$hesk_error_buffer .= $hesklang['fsq'];
$no_query = 1;
}
// What field are we searching in
$what = hesk_GET('what', '') or $hesk_error_buffer .= '<br />' . $hesklang['wsel'];
// Sequential ID supported?
if ($what == 'seqid' && ! $hesk_settings['sequential'])
{
$what = 'trackid';
}
// Setup SQL based on searching preferences
if ( ! $no_query)
{
$sql .= " AND ";
switch ($what)
{
case 'trackid':
$sql .= " ( `trackid` = '".hesk_dbEscape($q)."' OR `merged` LIKE '%#".hesk_dbEscape($q)."#%' ) ";
break;
case 'name':
$sql .= "`name` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' ";
break;
case 'email':
$sql .= "`email` LIKE '%".hesk_dbEscape($q)."%' ";
break;
case 'subject':
$sql .= "`subject` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' ";
break;
case 'message':
$sql .= " ( `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "'
OR
`id` IN (
SELECT DISTINCT `replyto`
FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies`
WHERE `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' )
)
";
break;
case 'seqid':
$sql .= "`id` = '".intval($q)."' ";
break;
case 'notes':
$sql .= "`id` IN (
SELECT DISTINCT `ticket`
FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."notes`
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() . "' ";
}
else
{
$hesk_error_buffer .= '<br />' . $hesklang['invalid_search'];
}
}
}
// Owner
if ( $tmp = intval( hesk_GET('owner', 0) ) )
{
$sql .= " AND `owner`={$tmp} ";
$owner_input = $tmp;
$hesk_error_buffer = str_replace($hesklang['fsq'],'',$hesk_error_buffer);
}
else
{
$owner_input = 0;
}
/* Date */
/* -> Check for compatibility with old date format */
if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", hesk_GET('dt'), $m))
{
$_GET['dt']=$m[2].$m[3].$m[1];
}
/* -> Now process the date value */
$dt = preg_replace('/[^0-9]/','', hesk_GET('dt') );
if (strlen($dt) == 8)
{
$date = substr($dt,4,4) . '-' . substr($dt,0,2) . '-' . substr($dt,2,2);
$date_input= substr($dt,0,2) . '/' . substr($dt,2,2) . '/' . substr($dt,4,4);
/* This search is valid even if no query is entered */
if ($no_query)
{
$hesk_error_buffer = str_replace($hesklang['fsq'],'',$hesk_error_buffer);
}
$sql .= " AND `dt` BETWEEN '{$date} 00:00:00' AND '{$date} 23:59:59' ";
}
else
{
$date = '';
$date_input = '';
}
/* Any errors? */
if (strlen($hesk_error_buffer))
{
hesk_process_messages($hesk_error_buffer,'NOREDIRECT');
}
/* This will handle error, success and notice messages */
$handle = hesk_handle_messages();
# echo "$sql<br/>";
// That's all the SQL we need for count
$sql_count .= $sql;
$sql = $sql_final . $sql;
// Strip extra slashes
$q = stripslashes($q);
/* Prepare variables used in search and forms */
require_once(HESK_PATH . 'inc/prepare_ticket_search.inc.php');
/* If there has been an error message skip searching for tickets */
if ($handle !== FALSE)
{
$href = 'find_tickets.php';
require_once(HESK_PATH . 'inc/ticket_list.inc.php');
}
/* Clean unneeded session variables */
hesk_cleanSessionVars('hide');
/* Show the search form */
require_once(HESK_PATH . 'inc/show_search_form.inc.php');
/* Print footer */
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
?>

View File

@@ -0,0 +1,46 @@
<?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/setup_functions.inc.php');
$spam_question = hesk_generate_SPAM_question();
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Content-type: text/plain; charset=utf-8');
?>
<div class="form-group">
<h5></h5>
<button style="margin-left: 24px" type="button" class="btn btn--blue-border" onclick="Javascript:hesk_rate('generate_spam_question.php','question')">
<?php echo $hesklang['genq']; ?>
</button>
</div>
<div class="form-group">
<h5><span><?php echo $hesklang['q_q']; ?></span></h5>
<textarea style="margin-left: 24px;" name="s_question_ask" class="form-control" rows="3" cols="40"><?php echo addslashes(hesk_htmlspecialchars($spam_question[0])); ?></textarea>
</div>
<div class="form-group">
<h5><span><?php echo $hesklang['q_a']; ?></span></h5>
<input class="form-control" type="text" name="s_question_ans" value="<?php echo addslashes(hesk_htmlspecialchars($spam_question[1])); ?>">
</div>
<?php
exit();
?>

489
hesk/admin/index.php Normal file
View File

@@ -0,0 +1,489 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
/* What should we do? */
$action = hesk_REQUEST('a');
switch ($action)
{
case 'do_login':
do_login();
break;
case 'login':
print_login();
break;
case 'logout':
logout();
break;
default:
hesk_autoLogin();
print_login();
}
/* Print footer */
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function do_login()
{
global $hesk_settings, $hesklang;
$hesk_error_buffer = array();
$user = hesk_input( hesk_POST('user') );
if (empty($user))
{
$myerror = $hesk_settings['list_users'] ? $hesklang['select_username'] : $hesklang['enter_username'];
$hesk_error_buffer['user'] = $myerror;
}
define('HESK_USER', $user);
$pass = hesk_input( hesk_POST('pass') );
if (empty($pass))
{
$hesk_error_buffer['pass'] = $hesklang['enter_pass'];
}
if ($hesk_settings['secimg_use'] == 2 && !isset($_SESSION['img_a_verified']))
{
// Using reCAPTCHA?
if ($hesk_settings['recaptcha_use'])
{
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
$resp = null;
$reCaptcha = new ReCaptcha($hesk_settings['recaptcha_private_key']);
// Was there a reCAPTCHA response?
if ( isset($_POST["g-recaptcha-response"]) )
{
$resp = $reCaptcha->verifyResponse(hesk_getClientIP(), hesk_POST("g-recaptcha-response") );
}
if ($resp != null && $resp->success)
{
$_SESSION['img_a_verified']=true;
}
else
{
$hesk_error_buffer['mysecnum']=$hesklang['recaptcha_error'];
}
}
// Using PHP generated image
else
{
$mysecnum = intval( hesk_POST('mysecnum', 0) );
if ( empty($mysecnum) )
{
$hesk_error_buffer['mysecnum'] = $hesklang['sec_miss'];
}
else
{
require(HESK_PATH . 'inc/secimg.inc.php');
$sc = new PJ_SecurityImage($hesk_settings['secimg_sum']);
if ( isset($_SESSION['checksum']) && $sc->checkCode($mysecnum, $_SESSION['checksum']) )
{
$_SESSION['img_a_verified'] = true;
}
else
{
$hesk_error_buffer['mysecnum'] = $hesklang['sec_wrng'];
}
}
}
}
/* Any missing fields? */
if (count($hesk_error_buffer)!=0)
{
$_SESSION['a_iserror'] = array_keys($hesk_error_buffer);
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['pcer'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'NOREDIRECT');
print_login();
exit();
}
elseif (isset($_SESSION['img_a_verified']))
{
unset($_SESSION['img_a_verified']);
}
/* User entered all required info, now lets limit brute force attempts */
hesk_limitBfAttempts();
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `user` = '".hesk_dbEscape($user)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_session_stop();
$_SESSION['a_iserror'] = array('user','pass');
hesk_process_messages($hesklang['wrong_user'],'NOREDIRECT');
print_login();
exit();
}
$res=hesk_dbFetchAssoc($result);
foreach ($res as $k=>$v)
{
$_SESSION[$k]=$v;
}
/* Check password */
if (hesk_Pass2Hash($pass) != $_SESSION['pass'])
{
hesk_session_stop();
$_SESSION['a_iserror'] = array('pass');
hesk_process_messages($hesklang['wrong_pass'],'NOREDIRECT');
print_login();
exit();
}
$pass_enc = hesk_Pass2Hash($_SESSION['pass'].hesk_mb_strtolower($user).$_SESSION['pass']);
/* Check if default password */
if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079')
{
hesk_process_messages($hesklang['chdp'],'NOREDIRECT','NOTICE');
}
// Set a tag that will be used to expire sessions after username or password change
$_SESSION['session_verify'] = hesk_activeSessionCreateTag($user, $_SESSION['pass']);
// We don't need the password hash anymore
unset($_SESSION['pass']);
/* Login successful, clean brute force attempts */
hesk_cleanBfAttempts();
/* Regenerate session ID (security) */
hesk_session_regenerate_id();
/* Remember username? */
if ($hesk_settings['autologin'] && hesk_POST('remember_user') == 'AUTOLOGIN')
{
hesk_setcookie('hesk_username', "$user", strtotime('+1 year'));
hesk_setcookie('hesk_p', "$pass_enc", strtotime('+1 year'));
}
elseif ( hesk_POST('remember_user') == 'JUSTUSER')
{
hesk_setcookie('hesk_username', "$user", strtotime('+1 year'));
hesk_setcookie('hesk_p', '');
}
else
{
// Expire cookie if set otherwise
hesk_setcookie('hesk_username', '');
hesk_setcookie('hesk_p', '');
}
/* Close any old tickets here so Cron jobs aren't necessary */
if ($hesk_settings['autoclose'])
{
$revision = sprintf($hesklang['thist3'],hesk_date(),$hesklang['auto']);
$dt = date('Y-m-d H:i:s',time() - $hesk_settings['autoclose']*86400);
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed'])
{
// Get list of tickets
$result = hesk_dbQuery("SELECT * FROM `".$hesk_settings['db_pfix']."tickets` WHERE `status` = '2' AND `lastchange` <= '".hesk_dbEscape($dt)."' ");
if (hesk_dbNumRows($result) > 0)
{
global $ticket;
// Load required functions?
if ( ! function_exists('hesk_notifyCustomer') )
{
require(HESK_PATH . 'inc/email_functions.inc.php');
}
while ($ticket = hesk_dbFetchAssoc($result))
{
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$ticket = hesk_ticketToPlain($ticket, 1, 0);
hesk_notifyCustomer('ticket_closed');
}
}
}
// Update ticket statuses and history in database
hesk_dbQuery("UPDATE `".$hesk_settings['db_pfix']."tickets` SET `status`='3', `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `status` = '2' AND `lastchange` <= '".hesk_dbEscape($dt)."' ");
}
/* Redirect to the destination page */
header('Location: ' . hesk_verifyGoto() );
exit();
} // End do_login()
function print_login()
{
global $hesk_settings, $hesklang;
// Tell header to load reCaptcha API if needed
if ($hesk_settings['recaptcha_use'])
{
define('RECAPTCHA',1);
}
$hesk_settings['tmp_title'] = $hesk_settings['hesk_title'] . ' - ' .$hesklang['admin_login'];
require_once(HESK_PATH . 'inc/header.inc.php');
if ( hesk_isREQUEST('notice') )
{
hesk_process_messages($hesklang['session_expired'],'NOREDIRECT');
}
if (!isset($_SESSION['a_iserror']))
{
$_SESSION['a_iserror'] = array();
}
$login_wrapper = true;
?>
<div class="wrapper login">
<main class="main">
<div class="reg__wrap">
<div class="reg__image">
<div class="bg-absolute"><img src="<?php echo HESK_PATH; ?>img/hero-bg.png" alt="Hesk" /></div>
</div>
<div class="reg__section">
<div class="reg__box">
<h2 class="reg__heading"><?php echo $hesklang['admin_login']; ?></h2>
<div style="margin-right: -24px; margin-left: -16px">
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
</div>
<form action="index.php" class="form <?php echo isset($_SESSION['a_iserror']) && count($_SESSION['a_iserror']) ? 'invalid' : ''; ?>" id="form1" method="post" name="form1" novalidate>
<div class="form-group">
<label for="regInputUsername"><?php echo $hesklang['username']; ?></label>
<?php
$cls = in_array('user',$_SESSION['a_iserror']) ? ' class="isError" ' : '';
if ( defined('HESK_DEMO')) {
$savedUser = 'Demo';
} elseif (defined('HESK_USER')) {
$savedUser = HESK_USER;
} else {
$savedUser = hesk_htmlspecialchars(hesk_COOKIE('hesk_username'));
}
$is_1 = '';
$is_2 = '';
$is_3 = '';
$remember_user = hesk_POST('remember_user');
if ($hesk_settings['autologin'] && (isset($_COOKIE['hesk_p']) || $remember_user == 'AUTOLOGIN') )
{
$is_1 = 'checked';
}
elseif (isset($_COOKIE['hesk_username']) || $remember_user == 'JUSTUSER' )
{
$is_2 = 'checked';
}
else
{
$is_3 = 'checked';
}
if ($hesk_settings['list_users']) {
echo '<select name="user" '.$cls.'>';
$res = hesk_dbQuery('SELECT `user` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'users` ORDER BY `user` ASC');
while ($row=hesk_dbFetchAssoc($res))
{
$sel = (hesk_mb_strtolower($savedUser) == hesk_mb_strtolower($row['user'])) ? 'selected="selected"' : '';
echo '<option value="'.$row['user'].'" '.$sel.'>'.$row['user'].'</option>';
}
echo '</select>';
} else {
echo '<input type="text" class="form-control" id="regInputUsername" name="user" value="'.$savedUser.'" '.$cls.' required>';
}
?>
<div class="form-control__error"><?php echo $hesklang['this_field_is_required']; ?></div>
</div>
<div class="form-group">
<label for="regInputPassword"><?php echo $hesklang['pass']; ?></label>
<div class="input-group">
<?php
$class = 'class="form-control';
if (in_array('pass',$_SESSION['a_iserror'])) {
$class .= ' isError';
}
$class .= '"';
?>
<input type="password" name="pass" id="regInputPassword" <?php echo $class; ?>
<?php if (defined('HESK_DEMO')) {echo ' value="demo1"';} ?>>
<div class="input-group-append--icon passwordIsHidden">
<svg class="icon icon-eye-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-eye-close"></use>
</svg>
</div>
</div>
<div class="form-control__error"><?php echo $hesklang['this_field_is_required']; ?></div>
</div>
<?php if ($hesk_settings['secimg_use'] == 2 && $hesk_settings['recaptcha_use'] != 1): ?>
<div>
<?php
// SPAM prevention verified for this session
if (isset($_SESSION['img_a_verified']))
{
//-- No-op
}
// Use reCaptcha API v2?
elseif ($hesk_settings['recaptcha_use'] == 2)
{
?>
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>"></div>
<?php
}
// At least use some basic PHP generated image (better than nothing)
else
{
$cls = in_array('mysecnum',$_SESSION['a_iserror']) ? ' class="form-control isError" ' : ' class="form-control" ';
echo '<div class="form-group"><label>'.$hesklang['sec_enter'].'</label><img src="'.HESK_PATH.'print_sec_img.php?'.rand(10000,99999).'" width="150" height="40" alt="'.$hesklang['sec_img'].'" title="'.$hesklang['sec_img'].'" border="1" name="secimg" style="vertical-align:middle" /> '.
'<a style="vertical-align: middle; display: inline" class="btn btn-refresh" href="javascript:" onclick="document.form1.secimg.src=\''.HESK_PATH.'print_sec_img.php?\'+ ( Math.floor((90000)*Math.random()) + 10000);">
<svg class="icon icon-refresh">
<use xlink:href="' . HESK_PATH . 'img/sprite.svg#icon-refresh"></use>
</svg>
</a>'.
'<br><br><input type="text" name="mysecnum" size="20" maxlength="5" '.$cls.'></div>';
}
?>
</div>
<?php
endif;
if ($hesk_settings['autologin']):
?>
<div class="radio-group">
<div class="radio-list">
<div class="radio-custom" style="margin-top: 5px;">
<input type="radio" id="remember_userAUTOLOGIN" name="remember_user" value="AUTOLOGIN" <?php echo $is_1; ?>>
<label for="remember_userAUTOLOGIN"><?php echo $hesklang['autologin']; ?></label>
</div>
<div class="radio-custom" style="margin-top: 5px;">
<input type="radio" id="remember_userJUSTUSER" name="remember_user" value="JUSTUSER" <?php echo $is_2; ?>>
<label for="remember_userJUSTUSER"><?php echo $hesklang['just_user']; ?></label>
</div>
<div class="radio-custom" style="margin-top: 5px;">
<input type="radio" id="remember_userNOTHANKS" name="remember_user" value="NOTHANKS" <?php echo $is_3; ?>>
<label for="remember_userNOTHANKS"><?php echo $hesklang['nothx']; ?></label>
</div>
</div>
</div>
<?php else: ?>
<div class="reg__checkboxes">
<div class="form-group">
<div class="checkbox-custom">
<input type="checkbox" id="tableCheckboxId2" name="remember_user" value="JUSTUSER" <?php echo $is_2; ?> />
<label for="tableCheckboxId2"><?php echo $hesklang['remember_user']; ?></label>
</div>
</div>
</div>
<?php endif; ?>
<div class="form__submit">
<button class="btn btn-full" ripple="ripple" type="submit" id="recaptcha-submit">
<?php echo $hesklang['click_login']; ?>
</button>
<input type="hidden" name="a" value="do_login">
<?php
if (hesk_isREQUEST('goto') && $url=hesk_REQUEST('goto'))
{
echo '<input type="hidden" name="goto" value="'.$url.'">';
}
?>
</div>
<?php if ($hesk_settings['reset_pass']): ?>
<div class="reg__footer">
<a href="password.php" class="link"><?php echo $hesklang['fpass']; ?></a>
</div>
<?php
endif;
// 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 endif; ?>
</form>
</div>
</div>
</div>
<?php
hesk_cleanSessionVars('a_iserror');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
} // End print_login()
function logout() {
global $hesk_settings, $hesklang;
if ( ! hesk_token_check('GET', 0))
{
print_login();
exit();
}
/* Delete from Who's online database */
if ($hesk_settings['online'])
{
require(HESK_PATH . 'inc/users_online.inc.php');
hesk_setOffline($_SESSION['id']);
}
/* Destroy session and cookies */
hesk_session_stop();
/* If we're using the security image for admin login start a new session */
if ($hesk_settings['secimg_use'] == 2)
{
hesk_session_start();
}
/* Show success message and reset the cookie */
hesk_process_messages($hesklang['logout_success'],'NOREDIRECT','SUCCESS');
hesk_setcookie('hesk_p', '');
/* Print the login form */
print_login();
exit();
} // End logout()
?>

View File

@@ -0,0 +1,495 @@
<?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/knowledgebase_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Is Knowledgebase enabled? */
if ( ! $hesk_settings['kb_enable'])
{
hesk_error($hesklang['kbdis']);
}
/* Can this user manage Knowledgebase or just view it? */
$can_man_kb = hesk_checkPermission('can_man_kb',0);
/* Any category ID set? */
$catid = intval( hesk_GET('category', 1) );
$artid = intval( hesk_GET('article', 0) );
if (isset($_GET['search']))
{
$query = hesk_input( hesk_GET('search') );
}
else
{
$query = 0;
}
$hesk_settings['kb_link'] = ($artid || $catid != 1 || $query) ? '<a href="knowledgebase_private.php" class="smaller">'.$hesklang['gopr'].'</a>' : ($can_man_kb ? $hesklang['gopr'] : '');
if ($hesk_settings['kb_search'] && $query)
{
hesk_kb_search($query);
}
elseif ($artid)
{
// Show drafts only to staff who can manage knowledgebase
if ($can_man_kb)
{
$result = hesk_dbQuery("SELECT t1.*, t2.`name` AS `cat_name`
FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` AS `t1`
LEFT JOIN `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` AS `t2` ON `t1`.`catid` = `t2`.`id`
WHERE `t1`.`id` = '{$artid}'
");
}
else
{
$result = hesk_dbQuery("SELECT t1.*, t2.`name` AS `cat_name`
FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` AS `t1`
LEFT JOIN `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` AS `t2` ON `t1`.`catid` = `t2`.`id`
WHERE `t1`.`id` = '{$artid}' AND `t1`.`type` IN ('0', '1')
");
}
$article = hesk_dbFetchAssoc($result) or hesk_error($hesklang['kb_art_id']);
hesk_show_kb_article($artid);
}
else
{
hesk_show_kb_category($catid);
}
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function hesk_kb_header()
{
// They may be unused here, but they're used down the line. Don't delete
global $hesk_settings, $hesklang, $can_man_kb;
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
hesk_kbSearchLarge(1);
} // END hesk_kb_header()
function hesk_kb_search($query)
{
global $hesk_settings, $hesklang;
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
hesk_kb_header();
$res = hesk_dbQuery('SELECT t1.`id`, t1.`subject`, LEFT(`t1`.`content`, '.max(200, $hesk_settings['kb_substrart'] * 2).') AS `content`, t1.`rating` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'kb_articles` AS t1 LEFT JOIN `'.hesk_dbEscape($hesk_settings['db_pfix']).'kb_categories` AS t2 ON t1.`catid` = t2.`id` '." WHERE t1.`type` IN ('0','1') AND MATCH(`subject`,`content`,`keywords`) AGAINST ('".hesk_dbEscape($query)."') LIMIT ".intval($hesk_settings['kb_search_limit']));
$num = hesk_dbNumRows($res);
?>
<?php
if ($num == 0)
{
hesk_show_info($hesklang['nosr']);
hesk_show_kb_category(1,1);
}
else
{
?>
<div class="main__content categories">
<div class="table-wrap">
<h3 style="font-size: 1.3rem"><?php echo $hesklang['sr']; ?> (<?php echo $num; ?>)</h3>
<?php
while ($article = hesk_dbFetchAssoc($res))
{
$txt = hesk_kbArticleContentPreview($article['content']);
if ($hesk_settings['kb_rating'])
{
$alt = $article['rating'] ? sprintf($hesklang['kb_rated'], sprintf("%01.1f", $article['rating'])) : $hesklang['kb_not_rated'];
$rat = '<td width="1" valign="top">
'.hesk3_get_rating($article['rating']).'
</td>';
}
else
{
$rat = '';
}
echo '
<div>
<div>
<svg class="icon icon-note" style="fill: #9c9c9c">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-note"></use>
</svg>
<a class="link" href="knowledgebase_private.php?article='.$article['id'].'">'.$article['subject'].'</a>
'.$rat.'
</div>
<div>
<svg class="icon icon-note" style="visibility: hidden">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-note"></use>
</svg>
<span class="article_list">'.$txt.'</span>
</div>
</div>';
}
?>
<div style="padding-top: 20px">
<a href="javascript:history.go(-1)">
<svg class="icon icon-back" style="width: 20px">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<?php echo $hesklang['back']; ?>
</a>
</div>
</div>
</div>
<?php
} // END else
} // END hesk_kb_search()
function hesk_show_kb_article($artid)
{
global $hesk_settings, $hesklang, $article;
// Print header
$hesk_settings['tmp_title'] = $article['subject'];
require_once(HESK_PATH . 'inc/header.inc.php');
hesk_kb_header();
// Update views by 1
hesk_dbQuery('UPDATE `'.hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` SET `views`=`views`+1 WHERE `id`={$artid}");
?>
<div class="main__content knowledge article">
<div class="article__detalies">
<div class="article__detalies_head">
<h3><?php echo $hesklang['ad']; ?></h3>
<?php
if ($article['catid']==1)
{
$link = 'knowledgebase_private.php';
}
else
{
$link = 'knowledgebase_private.php?category='.$article['catid'];
}
?>
</div>
<ul class="article__detalies_list">
<li>
<div class="name"><?php echo $hesklang['aid']; ?></div>
<div class="descr">
<?php echo $article['id']; ?>
<?php
if ($article['type'] == 0)
{
echo '<a href="' . $hesk_settings['hesk_url'] . '/knowledgebase.php?article=' . $article['id'] . '">' . $hesklang['public_link'] . '</a>';
}
?>
</div>
</li>
<li>
<div class="name"><?php echo $hesklang['category']; ?></div>
<div class="descr">
<a style="margin-left: 0" href="<?php echo $link; ?>"><?php echo $article['cat_name']; ?></a>
</div>
</li>
<li>
<div class="name"><?php echo $hesklang['dta']; ?></div>
<div class="descr">
<?php echo hesk_date($article['dt'], true); ?>
</div>
</li>
<li>
<div class="name"><?php echo $hesklang['views']; ?></div>
<div class="descr"><?php echo (isset($_GET['rated']) ? $article['views'] : $article['views']+1); ?></div>
</li>
<?php
if ($hesk_settings['kb_rating']) {
?>
<li>
<div class="name"><?php echo $hesklang['rating']; ?></div>
<div class="descr"><?php echo hesk3_get_rating($article['rating']); ?></div>
</li>
<?php
}
?>
</ul>
</div>
<div class="article__body">
<?php
if (!isset($_GET['back']))
{
?>
<div class="article__back">
<a href="javascript:history.go(-1)">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<?php echo $hesklang['back']; ?>
</a>
</div>
<?php
}
?>
<h2><?php echo $article['subject']; ?></h2>
<div class="article__description">
<?php echo $article['content']; ?>
</div>
<div class="article__attachments" style="margin-top: 20px">
<?php
if (!empty($article['attachments']))
{
$att=explode(',',substr($article['attachments'], 0, -1));
foreach ($att as $myatt)
{
list($att_id, $att_name) = explode('#', $myatt);
echo '
<svg class="icon icon-attach" style="fill: #9c9c9c">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-attach"></use>
</svg>
<a class="link" href="../download_attachment.php?kb_att='.$att_id.'" rel="nofollow">
'.$att_name.'
</a><br>';
}
}
?>
</div>
<?php
// Related articles
if ($hesk_settings['kb_related'])
{
require(HESK_PATH . 'inc/mail/email_parser.php');
$query = hesk_dbEscape( $article['subject'] . ' ' . convert_html_to_text($article['content']) );
// Get relevant articles from the database
$res = hesk_dbQuery("SELECT `id`, `subject`, MATCH(`subject`,`content`,`keywords`) AGAINST ('{$query}') AS `score` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` WHERE `type` IN ('0','1') AND MATCH(`subject`,`content`,`keywords`) AGAINST ('{$query}') LIMIT ".intval($hesk_settings['kb_related']+1));
// Array with related articles
$related_articles = array();
while ($related = hesk_dbFetchAssoc($res))
{
// Get base match score from the first article
if ( ! isset($base_score) )
{
$base_score = $related['score'];
}
// Ignore this article
if ( $related['id'] == $artid )
{
continue;
}
// Stop when articles reach less than 10% of base score
if ($related['score'] / $base_score < 0.10)
{
break;
}
// This is a valid related article
$related_articles[$related['id']] = $related['subject'];
}
// Print related articles if we have any valid matches
if ( count($related_articles) )
{
echo '<div class="article__related">';
echo '<h4>'.$hesklang['relart'].'</h4>';
foreach ($related_articles as $id => $subject)
{
echo '<p><a href="knowledgebase_private.php?article='.$id.'">'.$subject.'</a></p>';
}
echo '</div>';
}
}
?>
</div>
</div>
<?php
} // END hesk_show_kb_article()
function hesk_show_kb_category($catid, $is_search = 0) {
global $hesk_settings, $hesklang;
if ($is_search == 0)
{
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
hesk_kb_header();
if ($catid == 1)
{
echo '<span style="padding-left: 16px">' . $hesklang['priv'] . '</span>';
}
}
$res = hesk_dbQuery("SELECT `name`,`parent` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` WHERE `id`='".intval($catid)."' LIMIT 1");
$thiscat = hesk_dbFetchAssoc($res) or hesk_error($hesklang['kb_cat_inv']);
if ($thiscat['parent'])
{
$link = ($thiscat['parent'] == 1) ? 'knowledgebase_private.php' : 'knowledgebase_private.php?category='.$thiscat['parent'];
echo '<span class="homepageh3" style="font-size: 1.4rem; padding-left: 16px">'.$hesklang['kb_cat'].': '.$thiscat['name'].'
&nbsp;(<a style="display: inline" class="link" href="javascript:history.go(-1)">'.$hesklang['back'].'</a>)</span>
';
}
?>
<div class="main__content knowledge">
<h3 style="font-size: 1.3rem"><?php echo $hesklang['kb_cat_sub']; ?></h3>
<div class="knowledge__tabs">
<div class="knowledge__tabs_tab" style="display: flex">
<?php
$result = hesk_dbQuery("SELECT `id`,`name`,`articles`,`type` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` WHERE `parent`='".intval($catid)."' ORDER BY `parent` ASC, `cat_order` ASC");
if (hesk_dbNumRows($result) > 0)
{
$i = 1;
while ($cat = hesk_dbFetchAssoc($result))
{
$private = ($cat['type'] == 1) ? ' *' : '';
?>
<div class="knowledge__list">
<div class="knowledge__list_item">
<div class="item--head">
<a class="link not-underlined" href="knowledgebase_private.php?category=<?php echo $cat['id']; ?>">
<h3>
<svg class="icon icon-knowledge" style="fill: #9c9c9c">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-knowledge"></use>
</svg>
<?php echo $cat['name'].$private; ?>
</h3>
</a>
</div>
<ul class="item--list">
<?php
if (!$hesk_settings['kb_numshow'] || !$cat['articles']) {
echo '<li><h5>'.$hesklang['noac'].'</h5></li>';
}
/* Print most popular/sticky articles */
if ($hesk_settings['kb_numshow'] && $cat['articles'])
{
$res = hesk_dbQuery("SELECT `id`,`subject`,`type` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` WHERE `catid`='".intval($cat['id'])."' AND `type` IN ('0','1') ORDER BY `sticky` DESC, `views` DESC, `art_order` ASC LIMIT " . (intval($hesk_settings['kb_numshow']) + 1) );
$num = 1;
while ($art = hesk_dbFetchAssoc($res))
{
$private = ($art['type'] == 1) ? ' *' : '';
?>
<li>
<h5>
<a href="knowledgebase_private.php?article=<?php echo $art['id']; ?>" class="article">
<svg class="icon icon-note">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-note"></use>
</svg>
<?php echo $art['subject']; ?>
<?php echo $private; ?>
</a>
</h5>
</li>
<?php
if ($num == $hesk_settings['kb_numshow'])
{
break;
}
else
{
$num++;
}
}
if (hesk_dbNumRows($res) > $hesk_settings['kb_numshow'])
{
echo '
<div class="all">
<a class="link" href="knowledgebase_private.php?category='. $cat['id'] .'">'.$hesklang['m'].'</a>
</div>
';
}
}
?>
</ul>
</div>
</div>
<?php
}
?>
<?php
} // END if NumRows > 0
?>
</div>
</div>
<div class="table-wrap" style="margin-top: 20px">
<h3 style="font-size: 1.3rem"><?php echo $hesklang['ac']; ?></h3>
<?php
$res = hesk_dbQuery("SELECT `id`, `subject`, LEFT(`content`, ".max(200, $hesk_settings['kb_substrart'] * 2).") AS `content`, `rating`, `type` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` WHERE `catid`='".intval($catid)."' AND `type` IN ('0','1') ORDER BY `sticky` DESC, `art_order` ASC");
if (hesk_dbNumRows($res) == 0)
{
echo '<p><i>'.$hesklang['noac'].'</i></p>';
}
else
{
while ($article = hesk_dbFetchAssoc($res))
{
$private = ($article['type'] == 1) ? ' *' : '';
$txt = hesk_kbArticleContentPreview($article['content']);
echo '
<div style="margin: 10px 0">
<svg class="icon icon-note" style="fill: #9c9c9c">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-note"></use>
</svg>
<a class="link" href="knowledgebase_private.php?article='.$article['id'].'">'.$article['subject'].'</a>'.$private.'
<br>
<svg class="icon icon-note" style="visibility: hidden">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-note"></use>
</svg>
<span class="article_list">'.$txt.'</span>
</div>';
}
}
?>
</div>
</div>
<?php
} // END hesk_show_kb_category()
?>

82
hesk/admin/lock.php Normal file
View File

@@ -0,0 +1,82 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
hesk_checkPermission('can_reply_tickets');
hesk_checkPermission('can_edit_tickets');
hesk_checkPermission('can_resolve');
/* A security check */
hesk_token_check();
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
/* New locked status */
if (empty($_GET['locked']))
{
$status = 0;
$tmp = $hesklang['tunlock'];
$revision = sprintf($hesklang['thist6'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')');
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
}
else
{
$status = 1;
$tmp = $hesklang['tlock'];
$revision = sprintf($hesklang['thist5'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')');
$closedby_sql = ' , `closedat`=NOW(), `closedby`='.intval($_SESSION['id']).' ';
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed'])
{
// Get ticket info
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($result);
// Notify customer, but only if ticket is not already closed
if ($ticket['status'] != 3)
{
require(HESK_PATH . 'inc/email_functions.inc.php');
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
hesk_notifyCustomer('ticket_closed');
}
}
}
/* Update database */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='3',`locked`='{$status}' $closedby_sql , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
/* Back to ticket page and show a success message */
hesk_process_messages($tmp,'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');
?>

735
hesk/admin/mail.php Normal file
View File

@@ -0,0 +1,735 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/email_functions.inc.php');
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* List of staff */
$admins = array();
$res = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `name` ASC");
while ($row=hesk_dbFetchAssoc($res))
{
$admins[$row['id']]=$row['name'];
}
/* What folder are we in? */
$hesk_settings['mailtmp']['inbox'] = '
<a href="mail.php">
<li>
<span>' . $hesklang['inbox'] . '</span>
</li>
</a>';
$hesk_settings['mailtmp']['outbox'] = '
<a href="mail.php?folder=outbox">
<li>
<span>' . $hesklang['outbox'] . '</span>
</li>
</a>';
$hesk_settings['mailtmp']['new'] = '
<a href="mail.php?a=new" class="email--new">
<svg class="icon icon-add">
<use xlink:href="' . HESK_PATH . 'img/sprite.svg#icon-add"></use>
</svg>
'.$hesklang['m_new'].'
</a>';
/* Get action */
if ( $action = hesk_REQUEST('a') )
{
if ( defined('HESK_DEMO') && $action != 'new' && $action != 'read' )
{
hesk_process_messages($hesklang['ddemo'], 'mail.php', 'NOTICE');
}
}
/* Sub-page specific settings */
if (isset($_GET['folder']) && hesk_GET('folder') == 'outbox')
{
$hesk_settings['mailtmp']['this'] = 'from';
$hesk_settings['mailtmp']['other'] = 'to';
$hesk_settings['mailtmp']['m_from'] = $hesklang['m_to'];
$hesk_settings['mailtmp']['outbox'] = '
<li class="current">
<span>' . $hesklang['outbox'] . '</span>
</li>';
$hesk_settings['mailtmp']['folder'] = 'outbox';
}
elseif ($action == 'new')
{
$hesk_settings['mailtmp']['new'] = '
<a href="mail.php?a=new" class="email--new">
<svg class="icon icon-add">
<use xlink:href="' . HESK_PATH . 'img/sprite.svg#icon-add"></use>
</svg>
'.$hesklang['m_new'].'
</a>';
$_SESSION['hide']['list'] = 1;
/* Do we have a recipient selected? */
if (!isset($_SESSION['mail']['to']) && isset($_GET['id']))
{
$_SESSION['mail']['to'] = intval( hesk_GET('id') );
}
}
else
{
$hesk_settings['mailtmp']['this'] = 'to';
$hesk_settings['mailtmp']['other'] = 'from';
$hesk_settings['mailtmp']['m_from'] = $hesklang['m_from'];
if ($action != 'read')
{
$hesk_settings['mailtmp']['inbox'] = '
<li class="current">
<span>' . $hesklang['inbox'] . '</span>
</li>';
$hesk_settings['mailtmp']['folder'] = '';
}
}
/* What should we do? */
switch ($action)
{
case 'send':
mail_send();
break;
case 'mark_read':
mail_mark_read();
break;
case 'mark_unread':
mail_mark_unread();
break;
case 'delete':
mail_delete();
break;
}
if ($action == 'read') {
show_message(false);
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<script language="javascript" type="text/javascript"><!--
function confirm_delete()
{
if (confirm('<?php echo addslashes($hesklang['delete_saved']); ?>')) {return true;}
else {return false;}
}
//-->
</script>
<div class="main__content emails">
<h2><?php echo $hesklang['m_h']; ?></h2>
<div class="emails__head">
<ul class="emails__head_tabs">
<?php
echo $hesk_settings['mailtmp']['inbox'] . $hesk_settings['mailtmp']['outbox'];
?>
</ul>
<?php echo $hesk_settings['mailtmp']['new']; ?>
</div>
<?php
/* Show a message? */
if ($action == 'read')
{
show_message();
}
/* Hide list of messages? */
if (!isset($_SESSION['hide']['list']))
{
mail_list_messages();
} // END hide list of messages
/* Show new message form */
show_new_form();
?>
</div>
<?php
/* Clean unneeded session variables */
hesk_cleanSessionVars('hide');
hesk_cleanSessionVars('mail');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function mail_delete()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$ids = mail_get_ids();
if ($ids)
{
foreach ($ids as $id)
{
/* If both correspondents deleted the mail remove it from database, otherwise mark as deleted by this user */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` SET `deletedby`='".intval($_SESSION['id'])."' WHERE `id`='".intval($id)."' AND (`to`='".intval($_SESSION['id'])."' OR `from`='".intval($_SESSION['id'])."') AND `deletedby`=0");
if (hesk_dbAffectedRows() != 1)
{
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` WHERE `id`='".intval($id)."' AND (`to`='".intval($_SESSION['id'])."' OR `from`='".intval($_SESSION['id'])."') AND `deletedby`!=0");
}
}
hesk_process_messages($hesklang['smdl'],'NOREDIRECT','SUCCESS');
}
return true;
} // END mail_mark_unread()
function mail_mark_unread()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$ids = mail_get_ids();
if ($ids)
{
foreach ($ids as $id)
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` SET `read`='0' WHERE `id`='".intval($id)."' AND `to`='".intval($_SESSION['id'])."'");
}
hesk_process_messages($hesklang['smmu'],'NOREDIRECT','SUCCESS');
}
return true;
} // END mail_mark_unread()
function mail_mark_read()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$ids = mail_get_ids();
if ($ids)
{
foreach ($ids as $id)
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` SET `read`='1' WHERE `id`='".intval($id)."' AND `to`='".intval($_SESSION['id'])."'");
}
hesk_process_messages($hesklang['smmr'],'NOREDIRECT','SUCCESS');
}
return true;
} // END mail_mark_read()
function mail_get_ids()
{
global $hesk_settings, $hesklang;
// Mail id as a query parameter?
if ( $id = hesk_GET('id', false) )
{
return array($id);
}
// Mail id as a post array?
elseif ( isset($_POST['id']) && is_array($_POST['id']) )
{
return array_map('intval', $_POST['id']);
}
// No valid ID parameter
else
{
hesk_process_messages($hesklang['nms'],'NOREDIRECT','NOTICE');
return false;
}
} // END mail_get_ids()
function mail_send()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$hesk_error_buffer = '';
/* Recipient */
$_SESSION['mail']['to'] = intval( hesk_POST('to') );
/* Valid recipient? */
if (empty($_SESSION['mail']['to']))
{
$hesk_error_buffer .= '<li>' . $hesklang['m_rec'] . '</li>';
}
elseif ($_SESSION['mail']['to'] == $_SESSION['id'])
{
$hesk_error_buffer .= '<li>' . $hesklang['m_inr'] . '</li>';
}
else
{
$res = hesk_dbQuery("SELECT `name`,`email`,`notify_pm` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='".intval($_SESSION['mail']['to'])."' LIMIT 1");
$num = hesk_dbNumRows($res);
if (!$num)
{
$hesk_error_buffer .= '<li>' . $hesklang['m_inr'] . '</li>';
}
else
{
$pm_recipient = hesk_dbFetchAssoc($res);
}
}
/* Subject */
$_SESSION['mail']['subject'] = hesk_input( hesk_POST('subject') ) or $hesk_error_buffer .= '<li>' . $hesklang['m_esu'] . '</li>';
/* Message */
$_SESSION['mail']['message'] = hesk_input( hesk_POST('message') ) or $hesk_error_buffer .= '<li>' . $hesklang['enter_message'] . '</li>';
// Attach signature to the message?
if ( ! empty($_POST['signature']))
{
$_SESSION['mail']['message'] .= "\n\n" . addslashes($_SESSION['signature']) . "\n";
}
/* Any errors? */
if (strlen($hesk_error_buffer))
{
$_SESSION['hide']['list'] = 1;
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'NOREDIRECT');
}
else
{
$_SESSION['mail']['message'] = hesk_makeURL($_SESSION['mail']['message']);
$_SESSION['mail']['message'] = nl2br($_SESSION['mail']['message']);
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` (`from`,`to`,`subject`,`message`,`dt`,`read`) VALUES ('".intval($_SESSION['id'])."','".intval($_SESSION['mail']['to'])."','".hesk_dbEscape($_SESSION['mail']['subject'])."','".hesk_dbEscape($_SESSION['mail']['message'])."',NOW(),'0')");
/* Notify receiver via e-mail? */
if (isset($pm_recipient) && $pm_recipient['notify_pm'])
{
$pm_id = hesk_dbInsertID();
$pm = array(
'name' => hesk_msgToPlain( addslashes($_SESSION['name']) ,1,1),
'subject' => hesk_msgToPlain($_SESSION['mail']['subject'],1,1),
'message' => hesk_msgToPlain($_SESSION['mail']['message'],1,1),
'id' => $pm_id,
);
/* Format email subject and message for recipient */
$subject = hesk_getEmailSubject('new_pm',$pm,0);
$message = hesk_getEmailMessage('new_pm',$pm,1,0);
/* Send e-mail */
hesk_mail($pm_recipient['email'], $subject, $message);
}
unset($_SESSION['mail']);
hesk_process_messages($hesklang['m_pms'],'./mail.php','SUCCESS');
}
} // END mail_send()
function show_message($actually_show = true)
{
global $hesk_settings, $hesklang, $admins;
$id = intval( hesk_GET('id') );
/* Get the message details */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` WHERE `id`='".intval($id)."' AND `deletedby`!='".intval($_SESSION['id'])."' LIMIT 1");
$num = hesk_dbNumRows($res);
if ($num)
{
$pm = hesk_dbFetchAssoc($res);
/* Allowed to read the message? */
if ($pm['to'] == $_SESSION['id'])
{
if (!isset($_SESSION['mail']['subject']))
{
$_SESSION['mail']['subject'] = $hesklang['m_re'] . ' ' . $pm['subject'];
}
if (!isset($_SESSION['mail']['to']))
{
$_SESSION['mail']['to'] = $pm['from'];
}
}
elseif ($pm['from'] == $_SESSION['id'])
{
if (!isset($_SESSION['mail']['subject']))
{
$_SESSION['mail']['subject'] = $hesklang['m_fwd'] . ' ' . $pm['subject'];
}
if (!isset($_SESSION['mail']['to']))
{
$_SESSION['mail']['to'] = $pm['to'];
}
$hesk_settings['mailtmp']['this'] = 'from';
$hesk_settings['mailtmp']['other'] = 'to';
$hesk_settings['mailtmp']['m_from'] = $hesklang['m_to'];
$hesk_settings['mailtmp']['outbox'] = '<b>'.$hesklang['outbox'].'</b>';
$hesk_settings['mailtmp']['inbox'] = '<a href="mail.php">'.$hesklang['inbox'].'</a>';
$hesk_settings['mailtmp']['outbox'] = '<a href="mail.php?folder=outbox">'.$hesklang['outbox'].'</a>';
}
else
{
hesk_process_message($hesklang['m_ena'],'mail.php');
}
/* Mark as read */
if ($hesk_settings['mailtmp']['this'] == 'to' && !$pm['read'])
{
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` SET `read`='1' WHERE `id`='".intval($id)."'");
}
$pm['name'] = isset($admins[$pm[$hesk_settings['mailtmp']['other']]]) ? '<a href="mail.php?a=new&amp;id='.$pm[$hesk_settings['mailtmp']['other']].'">'.$admins[$pm[$hesk_settings['mailtmp']['other']]].'</a>' : (($pm['from'] == 9999) ? '<a href="https://www.hesk.com" target="_blank">HESK.com</a>' : $hesklang['e_udel']);
$pm['dt'] = hesk_dateToString($pm['dt'],0,1,0,true);
if ($actually_show) {
?>
<div class="email__list_article"
style="background: #fff; margin-top: 24px; border-radius: 2px; box-shadow: 0 2px 8px 0 rgba(38,40,42,.1)">
<div class="email__list_descr">
<div class="head">
<button type="button" class="btn btn-empty btn-hide-article">
<svg class="icon icon-back">
<use xlink:href="./img/sprite.svg#icon-back"></use>
</svg>
</button>
<div>
<h4><?php echo $pm['name']; ?></h4>
<h3><?php echo $pm['subject']; ?></h3>
</div>
<time><?php echo $pm['dt']; ?></time>
</div>
<div class="body">
<?php echo $pm['message']; ?>
</div>
<div class="form">
<?php
$folder = '&amp;folder=outbox';
if ($pm['to'] == $_SESSION['id']) {
echo '<a class="btn btn--blue-border" href="mail.php?a=mark_unread&amp;id=' . $id . '&amp;token=' . hesk_token_echo(0) . '">' . $hesklang['mau'] . '</a> ';
$folder = '';
}
echo '<a class="btn btn-full inline-flex next" ripple="ripple" href="mail.php?a=delete&amp;id=' . $id . '&amp;token=' . hesk_token_echo(0) . $folder . '" onclick="return hesk_confirmExecute(\'' . hesk_makeJsString($hesklang['delm']) . '?\');">' . $hesklang['delm'] . '</a>';
?>
</div>
</div>
</div>
<?php
}
} // END if $num
$_SESSION['hide']['list'] = 1;
} // END show_message()
function mail_list_messages()
{
global $hesk_settings, $hesklang, $admins;
$href = 'mail.php';
$query = '';
if ($hesk_settings['mailtmp']['folder'] == 'outbox')
{
$query .= 'folder=outbox&amp;';
}
$query .= 'page=';
$maxresults = 30;
$tmp = intval( hesk_GET('page', 1) );
$page = ($tmp > 1) ? $tmp : 1;
/* List of private messages */
$res = hesk_dbQuery("SELECT COUNT(*) FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` WHERE `".hesk_dbEscape($hesk_settings['mailtmp']['this'])."`='".intval($_SESSION['id'])."' AND `deletedby`!='".intval($_SESSION['id'])."'");
$total = hesk_dbResult($res,0,0);
if ($total > 0)
{
$pages = ceil($total/$maxresults) or $pages = 1;
if ($page > $pages)
{
$page = $pages;
}
$limit_down = ($page * $maxresults) - $maxresults;
// Get messages from the database
$res = hesk_dbQuery("SELECT `id`, `from`, `to`, `subject`, `dt`, `read` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` WHERE `".hesk_dbEscape($hesk_settings['mailtmp']['this'])."`='".intval($_SESSION['id'])."' AND `deletedby`!='".intval($_SESSION['id'])."' ORDER BY `id` DESC LIMIT ".intval($limit_down)." , ".intval($maxresults)." ");
?>
<form action="mail.php<?php if ($hesk_settings['mailtmp']['folder'] == 'outbox') {echo '?folder=outbox';} ?>" name="form1" method="post">
<div style="margin: 16px">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th class="table__first_th sindu_handle">
<div class="checkbox-custom">
<input type="checkbox" id="checkbox_selectall" name="checkall" value="2" onclick="hesk_changeAll(this)">
<label for="checkbox_selectall"></label>
</div>
</th>
<th style="border: none"><?php echo $hesklang['m_sub']; ?></th>
<th><?php echo $hesk_settings['mailtmp']['m_from']; ?></th>
<th><?php echo $hesklang['date']; ?></th>
</tr>
</thead>
<tbody>
<?php
while ($pm=hesk_dbFetchAssoc($res))
{
$pm['subject'] = '<a href="mail.php?a=read&amp;id='.$pm['id'].'">'.$pm['subject'].'</a>';
if ($hesk_settings['mailtmp']['this'] == 'to' && !$pm['read'])
{
$pm['subject'] = '<b>'.$pm['subject'].'</b>';
}
$pm['name'] = isset($admins[$pm[$hesk_settings['mailtmp']['other']]]) ? '<a href="mail.php?a=new&amp;id='.$pm[$hesk_settings['mailtmp']['other']].'">'.$admins[$pm[$hesk_settings['mailtmp']['other']]].'</a>' : (($pm['from'] == 9999) ? '<a href="https://www.hesk.com" target="_blank">HESK.com</a>' : $hesklang['e_udel']);
$pm['dt'] = hesk_dateToString($pm['dt'],0,0,0,true);
$css_class = !$pm['read'] && $pm['to'] == $_SESSION['id'] ? 'class="new"' : '';
echo <<<EOC
<tr $css_class>
<td class="table__first_td">
<div class="checkbox-custom">
<input type="checkbox" id="$pm[id]" name="id[]" value="$pm[id]">
<label for="$pm[id]"></label>
</div>
</td>
<td style="border: none">$pm[subject]</td>
<td>$pm[name]</td>
<td>$pm[dt]</td>
</tr>
EOC;
} // End while
?>
</tbody>
</table>
<?php
$prev_page = ($page - 1 <= 0) ? 0 : $page - 1;
$next_page = ($page + 1 > $pages) ? 0 : $page + 1;
if ($pages > 1): ?>
<div class="pagination-wrap">
<div class="pagination">
<?php
/* List pages */
if ($pages >= 7)
{
if ($page > 2) { ?>
<a href="<?php echo $href.'?'.$query.'1'; ?>" class="btn pagination__nav-btn">
<svg class="icon icon-chevron-left">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-left"></use>
</svg>
<svg class="icon icon-chevron-left">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-left"></use>
</svg>
<span><?php echo $hesklang['pager_first']; ?></span>
</a>
<?php }
if ($prev_page) { ?>
<a href="<?php echo $href.'?'.$query.$prev_page; ?>" class="btn pagination__nav-btn">
<svg class="icon icon-chevron-left">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-left"></use>
</svg>
<span><?php echo $hesklang['pager_previous']; ?></span>
</a>
<?php }
}
echo '<ul class="pagination__list">';
for ($i=1; $i<=$pages; $i++)
{
if ($i <= ($page+5) && $i >= ($page-5))
{
if ($i == $page) {
echo '
<li class="pagination__item is-current">
<a href="#" class="pagination__link">' . $i . '</a>
</li>';
}
else
{
echo '
<li class="pagination__item ">
<a href="'.$href.'?'.$query.$i.'" class="pagination__link">' . $i . '</a>';
}
}
}
echo '</ul>';
if ($pages >= 7) {
if ($next_page) { ?>
<a href="<?php echo $href.'?'.$query.$next_page; ?>" class="btn pagination__nav-btn">
<span><?php echo $hesklang['pager_next']; ?></span>
<svg class="icon icon-chevron-right">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-right"></use>
</svg>
</a>
<?php }
if ($page < ($pages - 1)) { ?>
<a href="<?php echo $href.'?'.$query.$pages; ?>" class="btn pagination__nav-btn">
<span><?php echo $hesklang['pager_last']; ?></span>
<svg class="icon icon-chevron-right">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-right"></use>
</svg>
<svg class="icon icon-chevron-right">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-right"></use>
</svg>
</a>
<?php }
}
echo '<br />&nbsp;
</div>
</div>
';
endif; // end PAGES > 1
?>
<div class="actions" style="display: flex">
<select name="a" id="email-batch-process" autocomplete="off">
<?php
if ($hesk_settings['mailtmp']['this'] == 'to')
{
?>
<option value="mark_read" selected="selected"><?php echo $hesklang['mo1']; ?></option>
<option value="mark_unread"><?php echo $hesklang['mo2']; ?></option>
<?php
}
?>
<option value="delete"><?php echo $hesklang['mo3']; ?></option>
</select>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<button style="margin-top: 16px; margin-left: 5px" class="btn btn-full" ripple="ripple" type="submit" onclick="Javascript:if (document.form1.a.value=='delete') return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['mo3']); ?>?');">
<?php echo $hesklang['execute']; ?>
</button>
</div>
</div>
</form>
<?php
} // END if total > 0
else
{
echo '<i>' . $hesklang['npm'] . '</i> <p>&nbsp;</p>';
}
} // END mail_list_messages()
function show_new_form()
{
global $hesk_settings, $hesklang, $admins;
?>
<h2 style="margin-top: 20px"><?php echo $hesklang['new_mail']; ?></h2>
<div class="new-message" style="background: #fff; margin-top: 24px; border-radius: 2px; box-shadow: 0 2px 8px 0 rgba(38,40,42,.1)">
<form action="mail.php" method="post" name="form2" class="form">
<div class="form-group">
<label for="email-create-destination"><?php echo $hesklang['m_to']; ?></label>
<select name="to" id="email-create-destination" autocomplete="off">
<option value="" selected="selected"><?php echo $hesklang['select']; ?></option>
<?php
foreach ($admins as $k=>$v) {
if ($k != $_SESSION['id']) {
if (isset($_SESSION['mail']) && $k == $_SESSION['mail']['to']) {
echo '<option value="'.$k.'" selected>'.$v.'</option>';
} else {
echo '<option value="'.$k.'">'.$v.'</option>';
}
}
}
?>
</select>
</div>
<div class="form-group">
<label for="m_subject"><?php echo $hesklang['m_sub']; ?></label>
<input type="text" class="form-control" name="subject" id="m_subject" maxlength="50"
<?php
if (isset($_SESSION['mail']['subject'])) {
echo ' value="'.stripslashes($_SESSION['mail']['subject']).'" ';
}
?>
>
</div>
<div class="form-group">
<label for="m_message"><?php echo $hesklang['message']; ?></label>
<textarea style="height: inherit" class="form-control" id="m_message" name="message" rows="15" cols="70"><?php
if (isset($_SESSION['mail']['message']))
{
echo stripslashes($_SESSION['mail']['message']);
}
?></textarea>
</div>
<div class="checkbox-custom">
<input type="checkbox" id="m_signature" name="signature" value="1" checked="checked" />
<label for="m_signature"><?php echo $hesklang['attach_sign']; ?></label>&nbsp;(<a href="profile.php"><?php echo $hesklang['profile_settings']; ?></a>)
</div>
<div style="margin-top: 10px">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<input type="hidden" name="a" value="send" />
<button class="btn btn-full" type="submit"><?php echo $hesklang['m_send']; ?></button>
</div>
</form>
</div>
<?php
} // END show_new_form()
?>

View File

@@ -0,0 +1,502 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_man_canned');
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// Define required constants
define('LOAD_TABS',1);
/* What should we do? */
if ( $action = hesk_REQUEST('a') )
{
if ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'manage_canned.php', 'NOTICE');}
elseif ($action == 'new') {new_saved();}
elseif ($action == 'edit') {edit_saved();}
elseif ($action == 'remove') {remove();}
elseif ($action == 'order') {order_saved();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<script language="javascript" type="text/javascript"><!--
function confirm_delete()
{
if (confirm('<?php echo hesk_makeJsString($hesklang['delete_saved']); ?>')) {return true;}
else {return false;}
}
function hesk_insertTag(tag) {
var text_to_insert = '%%'+tag+'%%';
hesk_insertAtCursor(document.form1.msg, text_to_insert);
document.form1.msg.focus();
}
function hesk_insertAtCursor(myField, myValue) {
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
} else {
myField.value += myValue;
}
}
//-->
</script>
<?php
/* This will handle error, success and notice messages */
if (!isset($_SESSION['canned']['what'])) {
hesk_handle_messages();
}
// Get canned responses from database
$result = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'std_replies` ORDER BY `reply_order` ASC');
$options='';
$javascript_messages='';
$javascript_titles='';
$i=1;
$j=0;
$num = hesk_dbNumRows($result);
?>
<div class="main__content templates">
<section class="templates__head">
<h2>
<?php echo $hesklang['manage_saved']; ?>
<div class="tooltype right out-close">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
<div class="tooltype__content">
<div class="tooltype__wrapper">
<?php echo $hesklang['manage_intro']; ?>
</div>
</div>
</div>
</h2>
<div class="btn btn--blue-border" ripple="ripple" data-action="create-template" onclick="diplayAddTitle()"><?php echo $hesklang['canned_add']; ?></div>
</section>
<ul class="response__list">
<?php if ($num < 1): ?>
<li><h3><?php echo $hesklang['no_saved']; ?></h3></li>
<?php
endif;
while ($mysaved=hesk_dbFetchAssoc($result))
{
$j++;
$table_row = '';
if (isset($_SESSION['canned']['selcat2']) && $mysaved['id'] == $_SESSION['canned']['selcat2']) {
$table_row = 'class="ticket-new"';
unset($_SESSION['canned']['selcat2']);
}
$options .= '<option value="'.$mysaved['id'].'"';
$options .= (isset($_SESSION['canned']['id']) && $_SESSION['canned']['id'] == $mysaved['id']) ? ' selected="selected" ' : '';
$options .= '>'.$mysaved['title'].'</option>';
$javascript_messages.='myMsgTxt['.$mysaved['id'].']=\''.str_replace("\r\n","\\r\\n' + \r\n'", addslashes($mysaved['message']) )."';\n";
$javascript_titles.='myTitle['.$mysaved['id'].']=\''.addslashes($mysaved['title'])."';\n";
echo '
<li '.$table_row.'>
<h3>'.$mysaved['title'].'</h3>
';
if ($num > 1)
{
if ($j == 1)
{
echo'
<a href="#" style="visibility: hidden">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a title="'.$hesklang['move_dn'].'" href="manage_canned.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>';
}
elseif ($j == $num)
{
echo'
<a title="'.$hesklang['move_up'].'" href="manage_canned.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=-15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-up">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="#" style="visibility: hidden">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>';
}
else
{
echo'
<a title="'.$hesklang['move_up'].'" href="manage_canned.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=-15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-up">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a title="'.$hesklang['move_dn'].'" href="manage_canned.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>';
}
}
else
{
echo '';
}
$modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['delete_saved'],
'manage_canned.php?a=remove&amp;id='.$mysaved['id'].'&amp;token='.hesk_token_echo(0));
echo '
<a title="'.$hesklang['edit'].'" href="javascript:setMessage(' . $mysaved['id'] . ')">
<svg class="icon icon-edit-ticket">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-edit-ticket"></use>
</svg>
</a>
<a title="'.$hesklang['remove'].'" href="javascript:" data-modal="[data-modal-id=\''.$modal_id.'\']">
<svg class="icon icon-delete">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-delete"></use>
</svg>
</a>
</li>
';
} // End while
?>
</ul>
</div>
<div class="right-bar template-create" <?php if (isset($_SESSION['canned']['what'])) { echo 'style="display: block"'; } ?>>
<div class="right-bar__body template-create__body">
<h3>
<a href="javascript:">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span <?php if (isset($_SESSION['canned']['what']) && $_SESSION['canned']['what'] !== 'NEW') { echo 'style="display: none"'; } ?> id="add-title"><?php echo $hesklang['canned_add']; ?></span>
<span <?php if (isset($_SESSION['canned']['what']) && $_SESSION['canned']['what'] !== 'EDIT') { echo 'style="display: none"'; } ?> id="edit-title"><?php echo $hesklang['canned_edit']; ?></span>
</a>
</h3>
<div class="form">
<?php
/* This will handle error, success and notice messages */
if (isset($_SESSION['canned']['what'])) {
echo '<div style="margin: -24px -24px 10px -16px;">';
hesk_handle_messages();
echo '</div>';
}
$errors = hesk_SESSION(array('canned', 'errors'));
$errors = is_array($errors) ? $errors : array();
?>
<form action="manage_canned.php" method="post" name="form1" class="form <?php echo hesk_SESSION(array('canned', 'errors')) ? 'invalid' : ''; ?>">
<div class="form-group">
<label for="canned_title"><?php echo $hesklang['saved_title']; ?></label>
<span id="HeskTitle">
<input type="text" class="form-control <?php echo in_array('name', $errors) ? 'isError' : ''; ?>" id="canned_title" name="name" maxlength="50"
<?php if (isset($_SESSION['canned']['name'])) {echo ' value="'.stripslashes($_SESSION['canned']['name']).'" ';} ?>>
</span>
</div>
<div class="form-group">
<label for="canned_message"><?php echo $hesklang['message']; ?></label>
<span id="HeskMsg">
<textarea class="form-control <?php echo in_array('msg', $errors) ? 'isError' : ''; ?>" name="msg" rows="15" cols="70" id="canned_message"><?php
if (isset($_SESSION['canned']['msg'])) {
echo stripslashes($_SESSION['canned']['msg']);
}
?></textarea>
</span>
</div>
<div class="template--tags">
<label><?php echo $hesklang['insert_special']; ?></label>
<div class="tag-list">
<a href="javascript:" onclick="hesk_insertTag('HESK_ID')">
<?php echo $hesklang['seqid']; ?>
</a>
<a href="javascript:" onclick="hesk_insertTag('HESK_TRACK_ID')">
<?php echo $hesklang['trackID']; ?>
</a>
<a href="javascript:" onclick="hesk_insertTag('HESK_NAME')">
<?php echo $hesklang['name']; ?>
</a>
<a href="javascript:" onclick="hesk_insertTag('HESK_FIRST_NAME')">
<?php echo $hesklang['fname']; ?>
</a>
<a href="javascript:" onclick="hesk_insertTag('HESK_EMAIL')">
<?php echo $hesklang['email']; ?>
</a>
<a href="javascript:" onclick="hesk_insertTag('HESK_OWNER')">
<?php echo $hesklang['owner']; ?>
</a>
<?php
foreach ($hesk_settings['custom_fields'] as $k=>$v) {
if ($v['use']) {
echo '<a href="javascript:" onclick="hesk_insertTag(\'HESK_'.$k.'\')">'.$v['name'].'</a>';
}
}
?>
</div>
</div>
<div class="template--submit">
<?php if(isset($_SESSION['canned']['what']) && $_SESSION['canned']['what'] == 'EDIT'): ?>
<input type="hidden" name="a" value="edit">
<input type="hidden" name="saved_replies" value="<?php echo $_SESSION['canned']['id']; ?>">
<?php else: ?>
<input type="hidden" name="a" value="new">
<input type="hidden" name="saved_replies" value="0">
<?php endif; ?>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<button class="btn btn-full" ripple="ripple"><?php echo $hesklang['save_reply']; ?></button>
</div>
</form>
</div>
</div>
</div>
<script language="javascript" type="text/javascript"><!--
var myMsgTxt = new Array();
myMsgTxt[0]='';
var myTitle = new Array();
myTitle[0]='';
<?php
echo $javascript_titles;
echo $javascript_messages;
?>
function setMessage(msgid) {
if (document.getElementById) {
document.getElementById('HeskMsg').innerHTML='<textarea class="form-control" id="canned_message" name="msg" rows="15" cols="70">'+myMsgTxt[msgid]+'</textarea>';
document.getElementById('HeskTitle').innerHTML='<input type="text" class="form-control" id="canned_title" name="name" maxlength="50" value="'+myTitle[msgid]+'">';
} else {
document.form1.msg.value=myMsgTxt[msgid];
document.form1.name.value=myTitle[msgid];
}
document.form1.a.value = 'edit';
document.form1.saved_replies.value = msgid;
document.getElementById('add-title').style.display = 'none';
document.getElementById('edit-title').style.display = 'block';
document.getElementsByClassName('template-create')[0].style.display = 'block';
}
function diplayAddTitle() {
document.form1.msg.value = '';
document.form1.name.value = '';
document.form1.saved_replies.value = 0;
document.form1.a.value = 'new';
document.getElementById('add-title').style.display = 'block';
document.getElementById('edit-title').style.display = 'none';
}
//-->
</script>
<?php
hesk_cleanSessionVars('canned');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function edit_saved()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$hesk_error_buffer = '';
$errors = array();
$id = intval(hesk_POST('saved_replies'));
if (!$id) {
$hesk_error_buffer .= '<li>' . $hesklang['selcan'] . '</li>';
$errors[] = 'saved_replies';
}
$savename = hesk_input( hesk_POST('name') );
if (!$savename) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_saved_title'] . '</li>';
$errors[] = 'name';
}
$msg = hesk_input( hesk_POST('msg') );
if (!$msg) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_saved_msg'] . '</li>';
$errors[] = 'msg';
}
// Avoid problems with utf-8 newline chars in Javascript code, detect and remove them
$msg = preg_replace('/\R/u', "\r\n", $msg);
$_SESSION['canned']['what'] = 'EDIT';
$_SESSION['canned']['id'] = $id;
$_SESSION['canned']['name'] = $savename;
$_SESSION['canned']['msg'] = $msg;
$_SESSION['canned']['errors'] = $errors;
/* Any errors? */
if (strlen($hesk_error_buffer))
{
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'manage_canned.php?saved_replies='.$id);
}
$result = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."std_replies` SET `title`='".hesk_dbEscape($savename)."',`message`='".hesk_dbEscape($msg)."' WHERE `id`='".intval($id)."'");
unset($_SESSION['canned']['what']);
unset($_SESSION['canned']['id']);
unset($_SESSION['canned']['name']);
unset($_SESSION['canned']['msg']);
unset($_SESSION['canned']['errors']);
hesk_process_messages($hesklang['your_saved'],'manage_canned.php?saved_replies='.$id,'SUCCESS');
} // End edit_saved()
function new_saved()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$hesk_error_buffer = '';
$errors = array();
$savename = hesk_input( hesk_POST('name') );
if (!$savename) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_saved_title'] . '</li>';
$errors[] = 'name';
}
$msg = hesk_input( hesk_POST('msg') );
if (!$msg) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_saved_msg'] . '</li>';
$errors[] = 'msg';
}
// Avoid problems with utf-8 newline chars in Javascript code, detect and remove them
$msg = preg_replace('/\R/u', "\r\n", $msg);
$_SESSION['canned']['what'] = 'NEW';
$_SESSION['canned']['name'] = $savename;
$_SESSION['canned']['msg'] = $msg;
$_SESSION['canned']['errors'] = $errors;
/* Any errors? */
if (strlen($hesk_error_buffer))
{
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'manage_canned.php');
}
/* Get the latest reply_order */
$result = hesk_dbQuery('SELECT `reply_order` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'std_replies` ORDER BY `reply_order` DESC LIMIT 1');
$row = hesk_dbFetchRow($result);
$my_order = isset($row[0]) ? intval($row[0]) + 10 : 10;
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."std_replies` (`title`,`message`,`reply_order`) VALUES ('".hesk_dbEscape($savename)."','".hesk_dbEscape($msg)."','".intval($my_order)."')");
unset($_SESSION['canned']['what']);
unset($_SESSION['canned']['name']);
unset($_SESSION['canned']['msg']);
unset($_SESSION['canned']['errors']);
hesk_process_messages($hesklang['your_saved'],'manage_canned.php','SUCCESS');
} // End new_saved()
function remove()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$mysaved = intval( hesk_GET('id') ) or hesk_error($hesklang['id_not_valid']);
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."std_replies` WHERE `id`='".intval($mysaved)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_error("$hesklang[int_error]: $hesklang[reply_not_found].");
}
hesk_process_messages($hesklang['saved_rem_full'],'manage_canned.php','SUCCESS');
} // End remove()
function order_saved()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$replyid = intval( hesk_GET('replyid') ) or hesk_error($hesklang['reply_move_id']);
$_SESSION['canned']['selcat2'] = $replyid;
$reply_move = intval( hesk_GET('move') );
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."std_replies` SET `reply_order`=`reply_order`+".intval($reply_move)." WHERE `id`='".intval($replyid)."'");
if (hesk_dbAffectedRows() != 1) {hesk_error("$hesklang[int_error]: $hesklang[reply_not_found].");}
/* Update all category fields with new order */
$result = hesk_dbQuery('SELECT `id` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'std_replies` ORDER BY `reply_order` ASC');
$i = 10;
while ($myreply=hesk_dbFetchAssoc($result))
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."std_replies` SET `reply_order`=".intval($i)." WHERE `id`='".intval($myreply['id'])."'");
$i += 10;
}
header('Location: manage_canned.php');
exit();
} // End order_saved()
?>

View File

@@ -0,0 +1,689 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_man_cat');
// Possible priorities
$priorities = array(
'low' => array('id' => 3, 'value' => 'low', 'text' => $hesklang['low'], 'formatted' => $hesklang['low']),
'medium' => array('id' => 2, 'value' => 'medium', 'text' => $hesklang['medium'], 'formatted' => $hesklang['medium']),
'high' => array('id' => 1, 'value' => 'high', 'text' => $hesklang['high'], 'formatted' => $hesklang['high']),
'critical' => array('id' => 0, 'value' => 'critical', 'text' => $hesklang['critical'], 'formatted' => $hesklang['critical']),
);
/* What should we do? */
if ( $action = hesk_REQUEST('a') )
{
if ($action == 'linkcode') {generate_link_code();}
elseif ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'manage_categories.php', 'NOTICE');}
elseif ($action == 'new') {new_cat();}
elseif ($action == 'rename') {rename_cat();}
elseif ($action == 'remove') {remove();}
elseif ($action == 'order') {order_cat();}
elseif ($action == 'autoassign') {toggle_autoassign();}
elseif ($action == 'type') {toggle_type();}
elseif ($action == 'priority') {change_priority();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
if (!hesk_SESSION('error')) {
hesk_handle_messages();
}
?>
<div class="main__content categories">
<section class="categories__head">
<h2><?php echo $hesklang['menu_cat']; ?></h2>
<button class="btn btn btn--blue-border" ripple="ripple" data-action="category-create">
<?php echo $hesklang['add_cat']; ?>
</button>
</section>
<div class="table-wrap">
<div class="table">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['cat_name']; ?></th>
<th>
<span><?php echo $hesklang['priority']; ?></span>
<?php if ($hesk_settings['cust_urgency']): ?>
<div class="tooltype right out-close">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
<div class="tooltype__content">
<div class="tooltype__wrapper">
<?php echo $hesklang['cat_pri_info'] . ' <a href="#">' . $hesklang['cpri'] . '</a>'; ?>
</div>
</div>
</div>
<?php endif; ?>
</th>
<th>
<span><?php echo $hesklang['not']; ?></span>
</th>
<th>
<span><?php echo $hesklang['cat_type']; ?></span>
</th>
<?php if ($hesk_settings['autoassign']): ?>
<th><?php echo $hesklang['aass']; ?></th>
<?php endif; ?>
<th></th>
</tr>
</thead>
<tbody>
<?php
/* Get number of tickets per category */
$tickets_all = array();
$tickets_total = 0;
$res = hesk_dbQuery('SELECT COUNT(*) AS `cnt`, `category` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'tickets` GROUP BY `category`');
while ($tmp = hesk_dbFetchAssoc($res))
{
$tickets_all[$tmp['category']] = $tmp['cnt'];
$tickets_total += $tmp['cnt'];
}
/* Get list of categories */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC");
$options='';
$i=1;
$j=0;
$num = hesk_dbNumRows($res);
while ($mycat=hesk_dbFetchAssoc($res))
{
$j++;
$table_row = '';
if (isset($_SESSION['selcat2']) && $mycat['id'] == $_SESSION['selcat2'])
{
$table_row = 'class="ticket-new"';
unset($_SESSION['selcat2']);
}
else
{
$color = $i ? 'admin_white' : 'admin_gray';
}
$tmp = $i ? 'White' : 'Blue';
$style = 'class="option'.$tmp.'OFF" onmouseover="this.className=\'option'.$tmp.'ON\'" onmouseout="this.className=\'option'.$tmp.'OFF\'"';
$i = $i ? 0 : 1;
/* Number of tickets and graph width */
$all = isset($tickets_all[$mycat['id']]) ? $tickets_all[$mycat['id']] : 0;
$width_all = 0;
if ($tickets_total && $all)
{
$width_all = round(($all / $tickets_total) * 100);
}
$options .= '<option value="'.$mycat['id'].'" ';
$options .= (isset($_SESSION['selcat']) && $mycat['id'] == $_SESSION['selcat']) ? ' selected="selected" ' : '';
$options .= '>'.$mycat['name'].'</option>';
?>
<tr <?php echo $table_row; ?> data-category-id="<?php echo $mycat['id']; ?>">
<td>
<span class="category-name"><?php echo $mycat['name']; ?></span>
<div class="rename-link tooltype right out-close" data-modal=".rename-category" data-callback="initRenameCategoryModal">
<svg class="icon icon-edit">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-edit"></use>
</svg>
<div class="tooltype__content">
<div class="tooltype__wrapper">
<?php echo $hesklang['ren_cat']; ?>
</div>
</div>
</div>
</td>
<td>
<div class="dropdown-select center out-close priority" data-type="form-submit-change">
<form action="manage_categories.php" method="post">
<select name="priority" onchange="this.form.submit()">
<?php foreach ($priorities as $id => $priority): ?>
<option value="<?php echo $priority['value']; ?>"
<?php if ($priority['id'] === intval($mycat['priority'])): ?>selected<?php endif; ?>>
<?php echo $priority['text']; ?>
</option>
<?php endforeach; ?>
</select>
<input type="hidden" name="a" value="priority" />
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<input type="hidden" name="catid" value="<?php echo $mycat['id']; ?>" />
</form>
</div>
</td>
<td>
<?php
$tickets_url = 'show_tickets.php?category='.$mycat['id'].'&amp;s_all=1&amp;s_my=1&amp;s_ot=1&amp;s_un=1';
?>
<a href="<?php echo $tickets_url; ?>" title="<?php $hesklang['list_tickets_cat']; ?>">
<?php echo $all; ?>
(<?php echo $width_all; ?>%)
</a>
</td>
<td>
<div class="dropdown-select center out-close">
<form action="manage_categories.php" method="get">
<select name="s" onchange="this.form.submit()">
<option value="0" <?php if ($mycat['type']): ?>selected<?php endif; ?>>
<?php echo $hesklang['cat_public']; ?>
</option>
<option value="1" <?php if ($mycat['type']): ?>selected<?php endif; ?>>
<?php echo $hesklang['cat_private']; ?>
</option>
</select>
<input type="hidden" name="a" value="type">
<input type="hidden" name="catid" value="<?php echo $mycat['id']; ?>">
<input type="hidden" name="token" value="<?php echo hesk_token_echo(); ?>">
</form>
</div>
</td>
<?php if ($hesk_settings['autoassign']): ?>
<td class="assign">
<form action="manage_categories.php" method="get">
<label class="switch-checkbox">
<input type="checkbox" onchange="this.form.submit()" name="s" <?php if ($mycat['autoassign']): ?>checked<?php endif; ?> />
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
</label>
<input type="hidden" name="a" value="autoassign">
<input type="hidden" name="catid" value="<?php echo $mycat['id']; ?>">
<input type="hidden" name="token" value="<?php echo hesk_token_echo(); ?>">
</form>
</td>
<?php endif; ?>
<td class="nowrap generate">
<a href="javascript:" data-action="generate-link" data-link="<?php echo htmlspecialchars($hesk_settings['hesk_url']) . '/index.php?a=add&catid=' . intval($mycat['id']); ?>">Generate link</a>
<?php
if ($num > 1) {
if ($j == 1) {
?>
<a href="#" style="visibility: hidden">
<svg class="icon icon-chevron-up">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="manage_categories.php?a=order&amp;catid=<?php echo $mycat['id']; ?>&amp;move=15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_dn']; ?>">
<svg class="icon icon-chevron-down">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<?php
echo'';
} elseif ($j == $num) {
?>
<a href="manage_categories.php?a=order&amp;catid=<?php echo $mycat['id']; ?>&amp;move=-15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_up']; ?>">
<svg class="icon icon-chevron-up">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="#" style="visibility: hidden"
title="<?php echo $hesklang['move_dn']; ?>">
<svg class="icon icon-chevron-down">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<?php
} else {
?>
<a href="manage_categories.php?a=order&amp;catid=<?php echo $mycat['id']; ?>&amp;move=-15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_up']; ?>">
<svg class="icon icon-chevron-up">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="manage_categories.php?a=order&amp;catid=<?php echo $mycat['id']; ?>&amp;move=15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_dn']; ?>">
<svg class="icon icon-chevron-down">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<?php
}
}
?>
<?php
if ($mycat['id'] != 1):
$modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['confirm_del_cat'],
'manage_categories.php?a=remove&catid='. $mycat['id'] .'&token='. hesk_token_echo(0));
?>
<a href="javascript:" class="delete" data-modal="[data-modal-id='<?php echo $modal_id; ?>']">
<svg class="icon icon-delete">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-delete"></use>
</svg>
</a>
<?php
endif;
?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
<div class="notification-flash green" data-type="link-generate-message">
<i class="close">
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
</i>
<div class="notification--title"><?php echo $hesklang['genl']; ?></div>
<div class="notification--text"><?php echo $hesklang['genl2']; ?></div>
</div>
<div class="modal rename-category">
<div class="modal__body">
<form action="manage_categories.php" method="post">
<i class="modal__close" data-action="modal-close">
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
</i>
<h3><?php echo $hesklang['ren_cat']; ?></h3>
<div class="modal__description form">
<div class="form-group">
<label style="text-align: left"><?php echo $hesklang['cat_name']; ?> (<?php echo $hesklang['max_chars']; ?>):</label>
<input type="text"
name="name"
id="renamecat"
class="form-control"
size="40"
maxlength="40"
<?php if (isset($_SESSION['catname2'])): ?>value="<?php echo $_SESSION['catname2']; ?>"<?php endif; ?>>
<input type="hidden" name="catid">
<input type="hidden" name="a" value="rename">
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
</div>
</div>
<div class="modal__buttons">
<button class="btn btn-border" ripple="ripple" data-action="cancel"><?php echo $hesklang['cancel']; ?></button>
<button class="btn btn-full" ripple="ripple" type="submit"><?php echo $hesklang['ren_cat']; ?></button>
</div>
</form>
</div>
</div>
<div class="right-bar category-create" <?php echo hesk_SESSION('error') ? 'style="display: block"' : ''; ?>>
<form action="manage_categories.php" method="post">
<div class="right-bar__body form">
<h3>
<a href="javascript:">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span><?php echo $hesklang['add_cat']; ?></span>
</a>
</h3>
<?php
if (hesk_SESSION('error')) {
echo '<div style="margin: -24px -24px 0 -16px;">';
hesk_handle_messages();
echo '</div>';
}
?>
<div class="form-group">
<label><?php echo $hesklang['cat_name']; ?> (<?php echo $hesklang['max_chars']; ?>):</label>
<input type="text"
name="name"
class="form-control"
<?php if (isset($_SESSION['catname'])): ?>value="<?php echo $_SESSION['catname']; ?>"<?php endif; ?>>
</div>
<?php
if (!isset($_SESSION['cat_priority'])) {
$_SESSION['cat_priority'] = 3;
}
?>
<div class="category-create__select">
<span><?php echo $hesklang['def_pri']; ?></span>
<div class="dropdown-select center out-close">
<select name="priority">
<?php foreach ($priorities as $id => $priority): ?>
<option value="<?php echo $priority['value']; ?>" <?php if ($_SESSION['cat_priority'] == $id): ?>selected<?php endif; ?>>
<?php echo $priority['text']; ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<?php if ($hesk_settings['autoassign']): ?>
<div class="category-create__autoassign">
<label class="switch-checkbox">
<input value="Y" name="autoassign" type="checkbox" id="autoassign" <?php if (!isset($_SESSION['cat_autoassign']) || $_SESSION['cat_autoassign'] == 1) { echo 'checked'; } ?>>
<div class="switch-checkbox__bullet">
<i>
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
</i>
</div>
<span><?php echo $hesklang['cat_aa']; ?></span>
</label>
</div>
<?php endif; ?>
<div class="category-create__select">
<span><?php echo $hesklang['cat_type']; ?>:</span>
<div class="dropdown-select center out-close">
<select name="type" id="category-create-type">
<option value="0" <?php if (!isset($_SESSION['cat_type']) || $_SESSION['cat_type'] == 0) {echo 'checked';} ?>><?php echo $hesklang['cat_public']; ?></option>
<option value="1" <?php if (isset($_SESSION['cat_type']) && $_SESSION['cat_type'] == 1) {echo 'checked';} ?>><?php echo $hesklang['cat_private']; ?></option>
</select>
</div>
</div>
<input type="hidden" name="a" value="new" />
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<button class="btn btn-full" type="submit" ripple="ripple"><?php echo $hesklang['create_cat']; ?></button>
</div>
</form>
</div>
<script language="Javascript" type="text/javascript"><!--
function initRenameCategoryModal($clickedElement) {
$('.rename-category')
.find('input[name="name"]').val($clickedElement.parent().find('.category-name').text()).end()
.find('input[name="catid"]').val($clickedElement.parent().parent().attr('data-category-id')).end();
}
//-->
</script>
<?php
hesk_cleanSessionVars('error');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function change_priority()
{
global $hesk_settings, $hesklang, $priorities;
/* A security check */
hesk_token_check('POST');
$_SERVER['PHP_SELF'] = 'manage_categories.php?catid='.intval( hesk_POST('catid') );
$catid = hesk_isNumber( hesk_POST('catid'), $hesklang['choose_cat_ren'], $_SERVER['PHP_SELF']);
$_SESSION['selcat'] = $catid;
$_SESSION['selcat2'] = $catid;
$priority = hesk_POST('priority', 'low');
if ( ! array_key_exists($priority, $priorities) )
{
$priority = 'low';
}
$priority_id = $priorities[$priority]['id'];
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` SET `priority`='{$priority_id}' WHERE `id`='".intval($catid)."'");
hesk_cleanSessionVars('cat_ch_priority');
hesk_process_messages($hesklang['cat_pri_ch'].' '.$priorities[$priority]['formatted'],$_SERVER['PHP_SELF'],'SUCCESS');
} // END change_priority()
function new_cat()
{
global $hesk_settings, $hesklang, $priorities;
/* A security check */
hesk_token_check('POST');
/* Options */
$_SESSION['cat_autoassign'] = hesk_POST('autoassign') == 'Y' ? 1 : 0;
$_SESSION['cat_type'] = hesk_POST('type') === '1' ? 1 : 0;
// Default priority
$_SESSION['cat_priority'] = hesk_POST('priority', 'low');
if ( ! array_key_exists($_SESSION['cat_priority'], $priorities) )
{
$_SESSION['cat_priority'] = 'low';
}
$priority_id = $priorities[$_SESSION['cat_priority']]['id'];
/* Category name */
$catname = hesk_input(hesk_POST('name'));
if ($catname == '') {
$_SESSION['error'] = 1;
}
$catname = hesk_input( hesk_POST('name') , $hesklang['enter_cat_name'], 'manage_categories.php');
/* Do we already have a category with this name? */
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE `name` LIKE '".hesk_dbEscape( hesk_dbLike($catname) )."' LIMIT 1");
if (hesk_dbNumRows($res) != 0)
{
$_SESSION['catname'] = stripslashes($catname);
hesk_process_messages($hesklang['cndupl'],'manage_categories.php');
}
/* Get the latest cat_order */
$res = hesk_dbQuery("SELECT `cat_order` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` DESC LIMIT 1");
$row = hesk_dbFetchRow($res);
$my_order = isset($row[0]) ? intval($row[0]) + 10 : 10;
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` (`name`,`cat_order`,`autoassign`,`type`, `priority`) VALUES ('".hesk_dbEscape($catname)."','".intval($my_order)."','".intval($_SESSION['cat_autoassign'])."','".intval($_SESSION['cat_type'])."','{$priority_id}')");
hesk_cleanSessionVars('catname');
hesk_cleanSessionVars('cat_autoassign');
hesk_cleanSessionVars('cat_type');
hesk_cleanSessionVars('cat_priority');
hesk_cleanSessionVars('error');
$_SESSION['selcat2'] = hesk_dbInsertID();
hesk_process_messages(sprintf($hesklang['cat_name_added'],'<i>'.stripslashes($catname).'</i>'),'manage_categories.php','SUCCESS');
} // End new_cat()
function rename_cat()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$_SERVER['PHP_SELF'] = 'manage_categories.php?catid='.intval( hesk_POST('catid') );
$catid = hesk_isNumber( hesk_POST('catid'), $hesklang['choose_cat_ren'], $_SERVER['PHP_SELF']);
$_SESSION['selcat'] = $catid;
$_SESSION['selcat2'] = $catid;
$catname = hesk_input( hesk_POST('name'), $hesklang['cat_ren_name'], $_SERVER['PHP_SELF']);
$_SESSION['catname2'] = stripslashes($catname);
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE `name` LIKE '".hesk_dbEscape( hesk_dbLike($catname) )."' LIMIT 1");
if (hesk_dbNumRows($res) != 0)
{
$old = hesk_dbFetchAssoc($res);
if ($old['id'] == $catid)
{
hesk_process_messages($hesklang['noch'],$_SERVER['PHP_SELF'],'NOTICE');
}
else
{
hesk_process_messages($hesklang['cndupl'],$_SERVER['PHP_SELF']);
}
}
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` SET `name`='".hesk_dbEscape($catname)."' WHERE `id`='".intval($catid)."'");
unset($_SESSION['selcat']);
unset($_SESSION['catname2']);
hesk_process_messages($hesklang['cat_renamed_to'].' <i>'.stripslashes($catname).'</i>',$_SERVER['PHP_SELF'],'SUCCESS');
} // End rename_cat()
function remove()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$_SERVER['PHP_SELF'] = 'manage_categories.php';
$mycat = intval( hesk_GET('catid') ) or hesk_error($hesklang['no_cat_id']);
if ($mycat == 1)
{
hesk_process_messages($hesklang['cant_del_default_cat'],$_SERVER['PHP_SELF']);
}
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE `id`='".intval($mycat)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_error("$hesklang[int_error]: $hesklang[cat_not_found].");
}
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `category`=1 WHERE `category`='".intval($mycat)."'");
hesk_process_messages($hesklang['cat_removed_db'],$_SERVER['PHP_SELF'],'SUCCESS');
} // End remove()
function order_cat()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$catid = intval( hesk_GET('catid') ) or hesk_error($hesklang['cat_move_id']);
$_SESSION['selcat2'] = $catid;
$cat_move=intval( hesk_GET('move') );
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` SET `cat_order`=`cat_order`+".intval($cat_move)." WHERE `id`='".intval($catid)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_error("$hesklang[int_error]: $hesklang[cat_not_found].");
}
/* Update all category fields with new order */
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC");
$i = 10;
while ($mycat=hesk_dbFetchAssoc($res))
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` SET `cat_order`=".intval($i)." WHERE `id`='".intval($mycat['id'])."'");
$i += 10;
}
header('Location: manage_categories.php');
exit();
} // End order_cat()
function toggle_autoassign()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$catid = intval( hesk_GET('catid') ) or hesk_error($hesklang['cat_move_id']);
$_SESSION['selcat2'] = $catid;
if (hesk_GET('s') === 'on')
{
$autoassign = 1;
$tmp = $hesklang['caaon'];
}
else
{
$autoassign = 0;
$tmp = $hesklang['caaoff'];
}
/* Update auto-assign settings */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` SET `autoassign`='".intval($autoassign)."' WHERE `id`='".intval($catid)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_process_messages($hesklang['int_error'].': '.$hesklang['cat_not_found'],'./manage_categories.php');
}
hesk_process_messages($tmp,'./manage_categories.php','SUCCESS');
} // End toggle_autoassign()
function toggle_type()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$catid = intval( hesk_GET('catid') ) or hesk_error($hesklang['cat_move_id']);
$_SESSION['selcat2'] = $catid;
if ( intval( hesk_GET('s') ) )
{
$type = 1;
$tmp = $hesklang['cpriv'];
}
else
{
$type = 0;
$tmp = $hesklang['cpub'];
}
/* Update auto-assign settings */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` SET `type`='{$type}' WHERE `id`='".intval($catid)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_process_messages($hesklang['int_error'].': '.$hesklang['cat_not_found'],'./manage_categories.php');
}
hesk_process_messages($tmp,'./manage_categories.php','SUCCESS');
} // End toggle_type()
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,437 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_man_ticket_tpl');
// Define required constants
define('LOAD_TABS',1);
/* What should we do? */
if ( $action = hesk_REQUEST('a') )
{
if ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'manage_ticket_templates.php', 'NOTICE');}
elseif ($action == 'new') {new_saved();}
elseif ($action == 'edit') {edit_saved();}
elseif ($action == 'remove') {remove();}
elseif ($action == 'order') {order_saved();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<script language="javascript" type="text/javascript"><!--
function confirm_delete()
{
if (confirm('<?php echo hesk_makeJsString($hesklang['delete_tpl']); ?>')) {return true;}
else {return false;}
}
//-->
</script>
<?php
/* This will handle error, success and notice messages */
if (!isset($_SESSION['canned']['what'])) {
hesk_handle_messages();
}
// Get canned responses from database
$result = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'ticket_templates` ORDER BY `tpl_order` ASC');
$javascript_messages='';
$javascript_titles='';
$i=1;
$j=0;
$num = hesk_dbNumRows($result);
?>
<div class="main__content templates">
<section class="templates__head">
<h2>
<?php echo $hesklang['ticket_tpl']; ?>
<div class="tooltype right out-close">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
<div class="tooltype__content">
<div class="tooltype__wrapper">
<?php echo $hesklang['ticket_tpl_intro']; ?>
</div>
</div>
</div>
</h2>
<div class="btn btn--blue-border" ripple="ripple" data-action="create-template" onclick="diplayAddTitle()"><?php echo $hesklang['ticket_tpl_add']; ?></div>
</section>
<ul class="response__list">
<?php if ($num < 1): ?>
<li><h3><?php echo $hesklang['no_ticket_tpl']; ?></h3></li>
<?php
endif;
while ($mysaved=hesk_dbFetchAssoc($result))
{
$j++;
$table_row = '';
if (isset($_SESSION['canned']['selcat2']) && $mysaved['id'] == $_SESSION['canned']['selcat2']) {
$table_row = 'class="ticket-new"';
unset($_SESSION['canned']['selcat2']);
}
$javascript_messages.='myMsgTxt['.$mysaved['id'].']=\''.str_replace("\r\n","\\r\\n' + \r\n'", addslashes($mysaved['message']) )."';\n";
$javascript_titles.='myTitle['.$mysaved['id'].']=\''.addslashes($mysaved['title'])."';\n";
echo '
<li ' . $table_row . '>
<h3>'.$mysaved['title'].'</h3>
';
if ($num > 1)
{
if ($j == 1)
{
echo'
<a href="#" style="visibility: hidden">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a title="'.$hesklang['move_dn'].'" href="manage_ticket_templates.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>';
}
elseif ($j == $num)
{
echo'
<a title="'.$hesklang['move_up'].'" href="manage_ticket_templates.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=-15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-up">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="#" style="visibility: hidden">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>';
}
else
{
echo'
<a title="'.$hesklang['move_up'].'" href="manage_ticket_templates.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=-15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-up">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a title="'.$hesklang['move_dn'].'" href="manage_ticket_templates.php?a=order&amp;replyid='.$mysaved['id'].'&amp;move=15&amp;token='.hesk_token_echo(0).'">
<svg class="icon icon-chevron-down">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>';
}
}
else
{
echo '';
}
$modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['delete_tpl'],
'manage_ticket_templates.php?a=remove&amp;id='.$mysaved['id'].'&amp;token='.hesk_token_echo(0));
echo '
<a title="'.$hesklang['edit'].'" href="javascript:setMessage(' . $mysaved['id'] . ')">
<svg class="icon icon-edit-ticket">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-edit-ticket"></use>
</svg>
</a>
<a title="'.$hesklang['remove'].'" href="javascript:" data-modal="[data-modal-id=\''.$modal_id.'\']">
<svg class="icon icon-delete">
<use xlink:href="'.HESK_PATH.'img/sprite.svg#icon-delete"></use>
</svg>
</a>
</li>
';
} // End while
?>
</ul>
</div>
<div class="right-bar template-create" <?php if (isset($_SESSION['canned']['what'])) { echo 'style="display: block"'; } ?>>
<div class="right-bar__body template-create__body">
<h3>
<a href="javascript:">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span <?php if (isset($_SESSION['canned']['what']) && $_SESSION['canned']['what'] !== 'NEW') { echo 'style="display: none"'; } ?> id="add-title"><?php echo $hesklang['ticket_tpl_add']; ?></span>
<span <?php if (isset($_SESSION['canned']['what']) && $_SESSION['canned']['what'] !== 'EDIT') { echo 'style="display: none"'; } ?> id="edit-title"><?php echo $hesklang['ticket_tpl_edit']; ?></span>
</a>
</h3>
<div class="form">
<?php
/* This will handle error, success and notice messages */
if (isset($_SESSION['canned']['what'])) {
echo '<div style="margin: -24px -24px 10px -16px;">';
hesk_handle_messages();
echo '</div>';
}
$errors = hesk_SESSION(array('canned', 'errors'));
$errors = is_array($errors) ? $errors : array();
?>
<form action="manage_ticket_templates.php" method="post" name="form1" class="form <?php echo hesk_SESSION(array('canned', 'errors')) ? 'invalid' : ''; ?>">
<div class="form-group">
<label for="canned_title"><?php echo $hesklang['saved_title']; ?></label>
<span id="HeskTitle">
<input type="text" class="form-control <?php echo in_array('name', $errors) ? 'isError' : ''; ?>" id="canned_title" name="name" maxlength="50"
<?php if (isset($_SESSION['canned']['name'])) {echo ' value="'.stripslashes($_SESSION['canned']['name']).'" ';} ?>>
</span>
</div>
<div class="form-group">
<label for="canned_message"><?php echo $hesklang['message']; ?></label>
<span id="HeskMsg">
<textarea class="form-control <?php echo in_array('msg', $errors) ? 'isError' : ''; ?>" name="msg" rows="15" cols="70" id="canned_message"><?php
if (isset($_SESSION['canned']['msg'])) {
echo stripslashes($_SESSION['canned']['msg']);
}
?></textarea>
</span>
</div>
<div class="template--submit">
<?php if(isset($_SESSION['canned']['what']) && $_SESSION['canned']['what'] == 'EDIT'): ?>
<input type="hidden" name="a" value="edit">
<input type="hidden" name="saved_replies" value="<?php echo $_SESSION['canned']['id']; ?>">
<?php else: ?>
<input type="hidden" name="a" value="new">
<input type="hidden" name="saved_replies" value="0">
<?php endif; ?>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<button class="btn btn-full" ripple="ripple"><?php echo $hesklang['save_ticket_tpl']; ?></button>
</div>
</form>
</div>
</div>
</div>
<script language="javascript" type="text/javascript"><!--
var myMsgTxt = new Array();
myMsgTxt[0]='';
var myTitle = new Array();
myTitle[0]='';
<?php
echo $javascript_titles;
echo $javascript_messages;
?>
function setMessage(msgid) {
if (document.getElementById) {
document.getElementById('HeskMsg').innerHTML='<textarea class="form-control" id="canned_message" name="msg" rows="15" cols="70">'+myMsgTxt[msgid]+'</textarea>';
document.getElementById('HeskTitle').innerHTML='<input type="text" class="form-control" id="canned_title" name="name" maxlength="50" value="'+myTitle[msgid]+'">';
} else {
document.form1.msg.value=myMsgTxt[msgid];
document.form1.name.value=myTitle[msgid];
}
document.form1.a.value = 'edit';
document.form1.saved_replies.value = msgid;
document.getElementById('add-title').style.display = 'none';
document.getElementById('edit-title').style.display = 'block';
document.getElementsByClassName('template-create')[0].style.display = 'block';
}
function diplayAddTitle() {
document.form1.msg.value = '';
document.form1.name.value = '';
document.form1.saved_replies.value = 0;
document.form1.a.value = 'new';
document.getElementById('add-title').style.display = 'block';
document.getElementById('edit-title').style.display = 'none';
}
//-->
</script>
<?php
hesk_cleanSessionVars('canned');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function edit_saved()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$hesk_error_buffer = '';
$errors = array();
$id = intval( hesk_POST('saved_replies') );
if (!$id) {
$hesk_error_buffer .= '<li>' . $hesklang['sel_ticket_tpl'] . '</li>';
$errors[] = 'id';
}
$savename = hesk_input( hesk_POST('name') );
if (!$savename) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_ticket_tpl_title'] . '</li>';
$errors[] = 'name';
}
$msg = hesk_input( hesk_POST('msg') );
if (!$msg) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_ticket_tpl_msg'] . '</li>';
$errors[] = 'msg';
}
// Avoid problems with utf-8 newline chars in Javascript code, detect and remove them
$msg = preg_replace('/\R/u', "\r\n", $msg);
$_SESSION['canned']['what'] = 'EDIT';
$_SESSION['canned']['id'] = $id;
$_SESSION['canned']['name'] = $savename;
$_SESSION['canned']['msg'] = $msg;
$_SESSION['canned']['errors'] = $errors;
/* Any errors? */
if (strlen($hesk_error_buffer))
{
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'manage_ticket_templates.php?saved_replies='.$id);
}
$result = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."ticket_templates` SET `title`='".hesk_dbEscape($savename)."',`message`='".hesk_dbEscape($msg)."' WHERE `id`='".intval($id)."'");
unset($_SESSION['canned']['what']);
unset($_SESSION['canned']['id']);
unset($_SESSION['canned']['name']);
unset($_SESSION['canned']['msg']);
unset($_SESSION['canned']['errors']);
hesk_process_messages($hesklang['ticket_tpl_saved'],'manage_ticket_templates.php?saved_replies='.$id,'SUCCESS');
} // End edit_saved()
function new_saved()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check('POST');
$hesk_error_buffer = '';
$errors = array();
$savename = hesk_input( hesk_POST('name') );
if (!$savename) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_ticket_tpl_title'] . '</li>';
$errors[] = 'name';
}
$msg = hesk_input( hesk_POST('msg') );
if (!$msg) {
$hesk_error_buffer .= '<li>' . $hesklang['ent_ticket_tpl_msg'] . '</li>';
$errors[] = 'msg';
}
// Avoid problems with utf-8 newline chars in Javascript code, detect and remove them
$msg = preg_replace('/\R/u', "\r\n", $msg);
$_SESSION['canned']['what'] = 'NEW';
$_SESSION['canned']['name'] = $savename;
$_SESSION['canned']['msg'] = $msg;
$_SESSION['canned']['errors'] = $errors;
/* Any errors? */
if (strlen($hesk_error_buffer))
{
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'manage_ticket_templates.php');
}
/* Get the latest tpl_order */
$result = hesk_dbQuery('SELECT `tpl_order` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'ticket_templates` ORDER BY `tpl_order` DESC LIMIT 1');
$row = hesk_dbFetchRow($result);
$my_order = isset($row[0]) ? intval($row[0]) + 10 : 10;
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."ticket_templates` (`title`,`message`,`tpl_order`) VALUES ('".hesk_dbEscape($savename)."','".hesk_dbEscape($msg)."','".intval($my_order)."')");
unset($_SESSION['canned']['what']);
unset($_SESSION['canned']['name']);
unset($_SESSION['canned']['msg']);
unset($_SESSION['canned']['errors']);
hesk_process_messages($hesklang['ticket_tpl_saved'],'manage_ticket_templates.php','SUCCESS');
} // End new_saved()
function remove()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$mysaved = intval( hesk_GET('id') ) or hesk_error($hesklang['id_not_valid']);
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."ticket_templates` WHERE `id`='".intval($mysaved)."'");
if (hesk_dbAffectedRows() != 1)
{
hesk_error("$hesklang[int_error]: $hesklang[ticket_tpl_not_found].");
}
hesk_process_messages($hesklang['ticket_tpl_removed'],'manage_ticket_templates.php','SUCCESS');
} // End remove()
function order_saved()
{
global $hesk_settings, $hesklang;
/* A security check */
hesk_token_check();
$tplid = intval( hesk_GET('replyid') ) or hesk_error($hesklang['ticket_tpl_id']);
$_SESSION['canned']['selcat2'] = $tplid;
$tpl_move = intval( hesk_GET('move') );
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."ticket_templates` SET `tpl_order`=`tpl_order`+".intval($tpl_move)." WHERE `id`='".intval($tplid)."'");
if (hesk_dbAffectedRows() != 1) {hesk_error("$hesklang[int_error]: $hesklang[ticket_tpl_not_found].");}
/* Update all category fields with new order */
$result = hesk_dbQuery('SELECT `id` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'ticket_templates` ORDER BY `tpl_order` ASC');
$i = 10;
while ($mytpl=hesk_dbFetchAssoc($result))
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."ticket_templates` SET `tpl_order`=".intval($i)." WHERE `id`='".intval($mytpl['id'])."'");
$i += 10;
}
header('Location: manage_ticket_templates.php');
exit();
} // End order_saved()
?>

1018
hesk/admin/manage_users.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,200 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/email_functions.inc.php');
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
if ( ! hesk_checkPermission('can_change_cat', 0))
{
hesk_checkPermission('can_change_own_cat');
}
/* A security check */
hesk_token_check('POST');
/* Ticket ID */
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
/* Category ID */
$category = intval( hesk_POST('category', -1) );
if ($category < 1)
{
hesk_process_messages($hesklang['incat'],'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'NOTICE');
}
/* Get new category details */
$res = hesk_dbQuery("SELECT `name`,`autoassign` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE `id`='{$category}' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error("$hesklang[int_error]: $hesklang[kb_cat_inv].");
}
$row = hesk_dbFetchAssoc($res);
/* Should tickets in new category be auto-assigned if necessary? */
if ( ! $row['autoassign'])
{
$hesk_settings['autoassign'] = false;
}
/* Is user allowed to view tickets in new category? */
$category_ok = hesk_okCategory($category,0);
// Is user allowed to move tickets to this category?
if ( ! $category_ok && ! hesk_checkPermission('can_change_cat', 0) )
{
hesk_process_messages($hesklang['noauth_move'],'admin_main.php');
}
/* Get details about the original ticket */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($res);
/* Log that ticket is being moved */
$history = sprintf($hesklang['thist1'],hesk_date(),$row['name'],$_SESSION['name'].' ('.$_SESSION['user'].')');
/* Is the ticket assigned to someone? If yes, check that the user has access to category or change to unassigned */
$need_to_reassign = 0;
if ($ticket['owner'])
{
if ($ticket['owner'] == $_SESSION['id'] && ! $category_ok )
{
$need_to_reassign = 1;
}
else
{
$res = hesk_dbQuery("SELECT `isadmin`,`categories` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='".intval($ticket['owner'])."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
$need_to_reassign = 1;
}
else
{
$tmp = hesk_dbFetchAssoc($res);
if ( ! hesk_okCategory($category,0,$tmp['isadmin'], explode(',',$tmp['categories']) ) )
{
$need_to_reassign = 1;
}
}
}
}
/* Reassign automatically if possible */
if ($need_to_reassign || ! $ticket['owner'])
{
$need_to_reassign = 1;
$autoassign_owner = hesk_autoAssignTicket($category);
if ($autoassign_owner)
{
$ticket['owner'] = $autoassign_owner['id'];
$history .= sprintf($hesklang['thist10'],hesk_date(),$autoassign_owner['name'].' ('.$autoassign_owner['user'].')');
}
else
{
$ticket['owner'] = 0;
}
}
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `category`='".intval($category)."', `owner`='".intval($ticket['owner'])."' , `history`=CONCAT(`history`,'".hesk_dbEscape($history)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
$ticket['category'] = $category;
/* --> 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);
/* Need to notify any staff? */
/* --> From autoassign? */
if ($need_to_reassign && ! empty($autoassign_owner['email']) )
{
hesk_notifyAssignedStaff($autoassign_owner, 'ticket_assigned_to_you');
}
/* --> No autoassign, find and notify appropriate staff */
elseif ( ! $ticket['owner'] )
{
hesk_notifyStaff('category_moved', "`notify_new_unassigned`='1' AND `id`!=".intval($_SESSION['id']) );
}
/* Is the user allowed to view tickets in the new category? */
if ($category_ok)
{
/* Ticket has an owner */
if ($ticket['owner'])
{
/* Staff is owner or can view tickets assigned to others */
if ($ticket['owner'] == $_SESSION['id'] || hesk_checkPermission('can_view_ass_others',0) )
{
hesk_process_messages($hesklang['moved_to'],'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');
}
else
{
hesk_process_messages($hesklang['moved_to'],'admin_main.php','SUCCESS');
}
}
/* Ticket is unassigned, staff can view unassigned tickets */
elseif (hesk_checkPermission('can_view_unassigned',0))
{
hesk_process_messages($hesklang['moved_to'],'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');
}
/* Ticket is unassigned, staff cannot view unassigned tickets */
else
{
hesk_process_messages($hesklang['moved_to'],'admin_main.php','SUCCESS');
}
}
else
{
hesk_process_messages($hesklang['moved_to'],'admin_main.php','SUCCESS');
}
?>

961
hesk/admin/new_ticket.php Normal file
View File

@@ -0,0 +1,961 @@
<?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','../');
// Auto-focus first empty or error field
define('AUTOFOCUS', true);
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Load custom fields
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
// Load calendar JS and CSS
define('CALENDAR',1);
// Pre-populate fields
// Customer name
if (isset($_REQUEST['name'])) {
$_SESSION['as_name'] = $_REQUEST['name'];
}
// Customer email address
if (isset($_REQUEST['email'])) {
$_SESSION['as_email'] = $_REQUEST['email'];
$_SESSION['as_email2'] = $_REQUEST['email'];
}
// Category ID
if (isset($_REQUEST['catid'])) {
$_SESSION['as_category'] = intval($_REQUEST['catid']);
}
if (isset($_REQUEST['category'])) {
$_SESSION['as_category'] = intval($_REQUEST['category']);
}
// Priority
if (isset($_REQUEST['priority'])) {
$_SESSION['as_priority'] = intval($_REQUEST['priority']);
}
// Subject
if (isset($_REQUEST['subject'])) {
$_SESSION['as_subject'] = $_REQUEST['subject'];
}
// Message
if (isset($_REQUEST['message'])) {
$_SESSION['as_message'] = $_REQUEST['message'];
}
// Custom fields
foreach ($hesk_settings['custom_fields'] as $k=>$v) {
if ($v['use'] && isset($_REQUEST[$k]) ) {
$_SESSION['as_'.$k] = $_REQUEST[$k];
}
}
/* Varibles for coloring the fields in case of errors */
if (!isset($_SESSION['iserror'])) {
$_SESSION['iserror'] = array();
}
if (!isset($_SESSION['isnotice'])) {
$_SESSION['isnotice'] = array();
}
/* List of users */
$admins = array();
$result = hesk_dbQuery("SELECT `id`,`name`,`isadmin`,`categories`,`heskprivileges` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `name` ASC");
while ($row=hesk_dbFetchAssoc($result))
{
/* Is this an administrator? */
if ($row['isadmin'])
{
$admins[$row['id']]=$row['name'];
continue;
}
/* Not admin, is user allowed to view tickets? */
if (strpos($row['heskprivileges'], 'can_view_tickets') !== false)
{
$admins[$row['id']]=$row['name'];
continue;
}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
// Get categories
$hesk_settings['categories'] = array();
if (hesk_checkPermission('can_submit_any_cat', 0))
{
$res = hesk_dbQuery("SELECT `id`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC");
}
else
{
$res = 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($res))
{
$hesk_settings['categories'][$row['id']] = $row['name'];
}
$number_of_categories = count($hesk_settings['categories']);
if ($number_of_categories == 0)
{
$category = 1;
}
elseif ($number_of_categories == 1)
{
$category = current(array_keys($hesk_settings['categories']));
}
else
{
$category = isset($_GET['catid']) ? hesk_REQUEST('catid'): hesk_REQUEST('category');
// Force the customer to select a category?
if (! isset($hesk_settings['categories'][$category]) )
{
return print_select_category($number_of_categories);
}
}
?>
<div class="main__content categories ticket-create">
<div class="table-wrap">
<?php
if ( ! isset($_SESSION['HESK_ERROR']))
{
hesk_show_info($hesklang['nti3']);
}
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<h3 style="font-size: 1.3rem; margin-top: 10px"><?php echo $hesklang['nti2']; ?></h3>
<h4><?php echo $hesklang['req_marked_with']; ?> <span class="important">*</span></h4>
<form method="post" class="form <?php echo isset($_SESSION['iserror']) && count($_SESSION['iserror']) ? 'invalid' : ''; ?>" action="admin_submit_ticket.php" name="form1" enctype="multipart/form-data">
<div class="form-group">
<label for="create_name">
<?php echo $hesklang['name']; ?> <span class="important">*</span>
</label>
<input type="text" id="create_name" name="name" class="form-control <?php if (in_array('name',$_SESSION['iserror'])) {echo 'isError';} ?>" maxlength="50" value="<?php if (isset($_SESSION['as_name'])) {echo stripslashes(hesk_input($_SESSION['as_name']));} ?>">
</div>
<div class="form-group">
<label for="email">
<?php echo $hesklang['email'] . ($hesk_settings['require_email'] ? ' <span class="important">*</span>' : '') ; ?>
</label>
<input type="text"
class="form-control <?php if (in_array('email',$_SESSION['iserror'])) {echo 'isError';} elseif (in_array('email',$_SESSION['isnotice'])) {echo 'isNotice';} ?>"
name="email" id="email" maxlength="1000"
value="<?php if (isset($_SESSION['as_email'])) {echo stripslashes(hesk_input($_SESSION['as_email']));} ?>"
<?php if($hesk_settings['detect_typos']) { echo ' onblur="Javascript:hesk_suggestEmail(\'email\', \'email_suggestions\', 1, 1)"'; } ?>>
</div>
<div id="email_suggestions"></div>
<div class="form-group">
<label><?php echo $hesklang['priority']; ?> <span class="important">*</span></label>
<div class="dropdown-select center out-close">
<select name="priority" <?php if (in_array('priority',$_SESSION['iserror'])) {echo ' class="isError" ';} ?> >
<?php
// Show the "Click to select"?
if ($hesk_settings['select_pri'])
{
echo '<option value="">'.$hesklang['select'].'</option>';
}
?>
<option value="3" <?php if(isset($_SESSION['as_priority']) && $_SESSION['as_priority']==3) {echo 'selected';} ?>><?php echo $hesklang['low']; ?></option>
<option value="2" <?php if(isset($_SESSION['as_priority']) && $_SESSION['as_priority']==2) {echo 'selected';} ?>><?php echo $hesklang['medium']; ?></option>
<option value="1" <?php if(isset($_SESSION['as_priority']) && $_SESSION['as_priority']==1) {echo 'selected';} ?>><?php echo $hesklang['high']; ?></option>
<option value="0" <?php if(isset($_SESSION['as_priority']) && $_SESSION['as_priority']==0) {echo 'selected';} ?>><?php echo $hesklang['critical']; ?></option>
</select>
</div>
</div>
<!-- START CUSTOM BEFORE -->
<?php
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'] && $v['place']==0 && hesk_is_custom_field_in_category($k, $category) )
{
$v['req'] = $v['req']==2 ? '<span class="important">*</span>' : '';
if ($v['type'] == 'checkbox')
{
$k_value = array();
if (isset($_SESSION["as_$k"]) && is_array($_SESSION["as_$k"]))
{
foreach ($_SESSION["as_$k"] as $myCB)
{
$k_value[] = stripslashes(hesk_input($myCB));
}
}
}
elseif (isset($_SESSION["as_$k"]))
{
$k_value = stripslashes(hesk_input($_SESSION["as_$k"]));
}
else
{
$k_value = '';
}
switch ($v['type'])
{
/* Radio box */
case 'radio':
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<div class="radio-list">';
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
$index = 0;
foreach ($v['value']['radio_options'] as $option)
{
if (strlen($k_value) == 0)
{
$k_value = $option;
$checked = empty($v['value']['no_default']) ? 'checked' : '';
}
elseif ($k_value == $option)
{
$k_value = $option;
$checked = 'checked';
}
else
{
$checked = '';
}
echo '
<div class="radio-custom" style="margin-bottom: 5px">
<input type="radio" id="edit_'.$k.$index.'" name="'.$k.'" value="'.$option.'" '.$checked.' '.$cls.'>
<label for="edit_'.$k.$index.'">'.$option.'</label>
</div>';
$index++;
}
echo '</div>
</div>';
break;
/* Select drop-down box */
case 'select':
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
echo '
<div class="form-group">
<label for="edit_">'.$v['name'].' '.$v['req'].'</label>
<div class="dropdown-select center out-close">
<select name="'.$k.'" '.$cls.'>';
// Show "Click to select"?
if ( ! empty($v['value']['show_select']))
{
echo '<option value="">'.$hesklang['select'].'</option>';
}
foreach ($v['value']['select_options'] as $option)
{
if ($k_value == $option)
{
$k_value = $option;
$selected = 'selected';
}
else
{
$selected = '';
}
echo '<option '.$selected.'>'.$option.'</option>';
}
echo '</select>
</div>
</div>';
break;
/* Checkbox */
case 'checkbox':
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>';
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
$index = 0;
foreach ($v['value']['checkbox_options'] as $option)
{
if (in_array($option,$k_value))
{
$checked = 'checked';
}
else
{
$checked = '';
}
echo '
<div class="checkbox-custom">
<input type="checkbox" id="edit_'.$k.$index.'" name="'.$k.'[]" value="'.$option.'" '.$checked.' '.$cls.'>
<label for="edit_'.$k.$index.'"> '.$option.'</label>
</div>';
$index++;
}
echo '</div>';
break;
/* Large text box */
case 'textarea':
$cls = in_array($k,$_SESSION['iserror']) ? ' isError" ' : '';
$k_value = hesk_msgToPlain($k_value,0,0);
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<textarea name="'.$k.'" class="form-control'.$cls.'" style="height: inherit" rows="'.intval($v['value']['rows']).'" cols="'.intval($v['value']['cols']).'" >'.$k_value.'</textarea>
</div>';
break;
// Date
case 'date':
echo '
<section class="param calendar">
<label>'.$v['name'].' '.$v['req'].'</label>
<div class="calendar--button">
<button type="button">
<svg class="icon icon-calendar">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="'. $k .'"
value="'. $k_value .'"
type="text" class="datepicker">
</div>
<div class="calendar--value" '. ($k_value ? 'style="display: block"' : '') . '>
<span>'. $k_value .'</span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>';
break;
// Email
case 'email':
$cls = in_array($k,$_SESSION['iserror']) ? 'isError' : '';
$suggest = $hesk_settings['detect_typos'] ? 'onblur="Javascript:hesk_suggestEmail(\''.$k.'\', \''.$k.'_suggestions\', 0, 1'.($v['value']['multiple'] ? ',1' : '').')"' : '';
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<input class="form-control '.$cls.'" type="email" name="'.$k.'" id="'.$k.'" value="'.$k_value.'" size="40" '.$suggest.'>
</div>
<div id="'.$k.'_suggestions"></div>';
break;
// Hidden
// Handle as text fields for staff
/* Default text input */
default:
$k_value = hesk_msgToPlain($k_value,0,0);
$cls = in_array($k,$_SESSION['iserror']) ? 'isError' : '';
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<input class="form-control '.$cls.'" type="text" name="'.$k.'" size="40" maxlength="'.intval($v['value']['max_length']).'" value="'.$k_value.'">
</div>';
}
}
}
?>
<!-- END CUSTOM BEFORE -->
<?php
// Lets handle ticket templates
$can_options = '';
// Get ticket templates from the database
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."ticket_templates` ORDER BY `tpl_order` ASC");
// If we have any templates print them out
if ( hesk_dbNumRows($res) )
{
?>
<script language="javascript" type="text/javascript"><!--
// -->
var myMsgTxt = new Array();
var mySubjectTxt = new Array();
myMsgTxt[0]='';
mySubjectTxt[0]='';
<?php
while ($mysaved = hesk_dbFetchRow($res))
{
$can_options .= '<option value="' . $mysaved[0] . '">' . $mysaved[1]. "</option>\n";
echo 'myMsgTxt['.$mysaved[0].']=\''.str_replace("\r\n","\\r\\n' + \r\n'", addslashes($mysaved[2]))."';\n";
echo 'mySubjectTxt['.$mysaved[0].']=\''.str_replace("\r\n","\\r\\n' + \r\n'", addslashes($mysaved[1]))."';\n";
}
?>
function setMessage(msgid)
{
var myMsg=myMsgTxt[msgid];
var mySubject=mySubjectTxt[msgid];
if (myMsg == '')
{
if (document.form1.mode[1].checked)
{
document.getElementById('message').value = '';
document.getElementById('subject').value = '';
}
return true;
}
if (document.getElementById)
{
if (document.getElementById('moderep').checked)
{
document.getElementById('HeskMsg').innerHTML='<textarea name="message" id="message" rows="12" cols="60">'+myMsg+'</textarea>';
document.getElementById('HeskSub').innerHTML='<input type="text" name="subject" id="subject" size="40" maxlength="70" value="'+mySubject+'" />';
}
else
{
var oldMsg = document.getElementById('message').value;
document.getElementById('HeskMsg').innerHTML='<textarea name="message" id="message" rows="12" cols="60">'+oldMsg+myMsg+'</textarea>';
if (document.getElementById('subject').value == '')
{
document.getElementById('HeskSub').innerHTML='<input type="text" name="subject" id="subject" size="40" maxlength="70" value="'+mySubject+'" />';
}
}
}
else
{
if (document.form1.mode[0].checked)
{
document.form1.message.value=myMsg;
document.form1.subject.value=mySubject;
}
else
{
var oldMsg = document.form1.message.value;
document.form1.message.value=oldMsg+myMsg;
if (document.form1.subject.value == '')
{
document.form1.subject.value=mySubject;
}
}
}
}
//-->
</script>
<?php
} // END fetchrows
// Print templates
if ( strlen($can_options) )
{
?>
<div class="form-group">
<label>
<?php echo $hesklang['ticket_tpl']; ?>
<?php echo hesk_checkPermission('can_man_ticket_tpl', 0) ? '(<a class="link" href="manage_ticket_templates.php">' . $hesklang['ticket_tpl_man'] . '</a>)' : ''; ?>
</label>
<div class="radio-list">
<div class="radio-custom" style="margin-bottom: 5px">
<input type="radio" name="mode" id="modeadd" value="1" checked="checked">
<label for="modeadd"><?php echo $hesklang['madd']; ?></label>
</div>
<div class="radio-custom" style="margin-bottom: 5px">
<input type="radio" name="mode" id="moderep" value="0">
<label for="moderep"><?php echo $hesklang['mrep']; ?></label>
</div>
</div>
</div>
<div class="form-group">
<label><?php echo $hesklang['select_ticket_tpl']; ?></label>
<div class="dropdown-select center out-close">
<select name="saved_replies" onchange="setMessage(this.value)">
<option value="0"> - <?php echo $hesklang['select_empty']; ?> - </option>
<?php echo $can_options; ?>
</select>
</div>
</div>
<?php
} // END printing templates
elseif ( hesk_checkPermission('can_man_ticket_tpl', 0) )
{
?>
<div class="form-group">
<label><a href="manage_ticket_templates.php" class="link"><?php echo $hesklang['ticket_tpl_man']; ?></a></label>
</div>
<?php
}
?>
<div class="form-group">
<label><?php echo $hesklang['subject'] . ' ' . ($hesk_settings['require_subject']==1 ? '<span class="important">*</span>' : '') ; ?></label>
<span id="HeskSub"><input class="form-control <?php if (in_array('subject',$_SESSION['iserror'])) {echo 'isError';} ?>" type="text" name="subject" id="subject" maxlength="70" value="<?php if (isset($_SESSION['as_subject'])) {echo stripslashes(hesk_input($_SESSION['as_subject']));} ?>"></span>
</div>
<div class="form-group">
<label><?php echo $hesklang['message'] . ' ' . ($hesk_settings['require_message']==1 ? '<span class="important">*</span>' : '') ; ?></label>
<span id="HeskMsg">
<textarea style="height: inherit" class="form-control <?php if (in_array('message',$_SESSION['iserror'])) {echo 'isError';} ?>"
name="message" id="message" rows="12" cols="60"><?php if (isset($_SESSION['as_message'])) {echo stripslashes(hesk_input($_SESSION['as_message']));} ?></textarea>
</span>
</div>
<!-- START CUSTOM AFTER -->
<?php
/* custom fields AFTER comments */
foreach ($hesk_settings['custom_fields'] as $k=>$v)
{
if ($v['use'] && $v['place']==1 && hesk_is_custom_field_in_category($k, $category) )
{
$v['req'] = $v['req']==2 ? '<span class="important">*</span>' : '';
if ($v['type'] == 'checkbox')
{
$k_value = array();
if (isset($_SESSION["as_$k"]) && is_array($_SESSION["as_$k"]))
{
foreach ($_SESSION["as_$k"] as $myCB)
{
$k_value[] = stripslashes(hesk_input($myCB));
}
}
}
elseif (isset($_SESSION["as_$k"]))
{
$k_value = stripslashes(hesk_input($_SESSION["as_$k"]));
}
else
{
$k_value = '';
}
switch ($v['type'])
{
/* Radio box */
case 'radio':
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<div class="radio-list">';
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
$index = 0;
foreach ($v['value']['radio_options'] as $option)
{
if (strlen($k_value) == 0)
{
$k_value = $option;
$checked = empty($v['value']['no_default']) ? 'checked' : '';
}
elseif ($k_value == $option)
{
$k_value = $option;
$checked = 'checked';
}
else
{
$checked = '';
}
echo '
<div class="radio-custom" style="margin-bottom: 5px">
<input type="radio" id="edit_'.$k.$index.'" name="'.$k.'" value="'.$option.'" '.$checked.' '.$cls.'>
<label for="edit_'.$k.$index.'">'.$option.'</label>
</div>';
$index++;
}
echo '</div>
</div>';
break;
/* Select drop-down box */
case 'select':
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
echo '
<div class="form-group">
<label for="edit_">'.$v['name'].' '.$v['req'].'</label>
<div class="dropdown-select center out-close">
<select name="'.$k.'" '.$cls.'>';
// Show "Click to select"?
if ( ! empty($v['value']['show_select']))
{
echo '<option value="">'.$hesklang['select'].'</option>';
}
foreach ($v['value']['select_options'] as $option)
{
if ($k_value == $option)
{
$k_value = $option;
$selected = 'selected';
}
else
{
$selected = '';
}
echo '<option '.$selected.'>'.$option.'</option>';
}
echo '</select>
</div>
</div>';
break;
/* Checkbox */
case 'checkbox':
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>';
$cls = in_array($k,$_SESSION['iserror']) ? ' class="isError" ' : '';
$index = 0;
foreach ($v['value']['checkbox_options'] as $option)
{
if (in_array($option,$k_value))
{
$checked = 'checked';
}
else
{
$checked = '';
}
echo '
<div class="checkbox-custom">
<input type="checkbox" id="edit_'.$k.$index.'" name="'.$k.'[]" value="'.$option.'" '.$checked.' '.$cls.'>
<label for="edit_'.$k.$index.'"> '.$option.'</label>
</div>';
$index++;
}
echo '</div>';
break;
/* Large text box */
case 'textarea':
$cls = in_array($k,$_SESSION['iserror']) ? ' isError" ' : '';
$k_value = hesk_msgToPlain($k_value,0,0);
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<textarea name="'.$k.'" class="form-control'.$cls.'" style="height: inherit" rows="'.intval($v['value']['rows']).'" cols="'.intval($v['value']['cols']).'" >'.$k_value.'</textarea>
</div>';
break;
// Date
case 'date':
echo '
<section class="param calendar">
<label>'.$v['name'].' '.$v['req'].'</label>
<div class="calendar--button">
<button type="button">
<svg class="icon icon-calendar">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="'. $k .'"
value="'. $k_value .'"
type="text" class="datepicker">
</div>
<div class="calendar--value" '. ($k_value ? 'style="display: block"' : '') . '>
<span>'. $k_value .'</span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="'. HESK_PATH .'img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>';
break;
// Email
case 'email':
$cls = in_array($k,$_SESSION['iserror']) ? 'isError' : '';
$suggest = $hesk_settings['detect_typos'] ? 'onblur="Javascript:hesk_suggestEmail(\''.$k.'\', \''.$k.'_suggestions\', 0, 1'.($v['value']['multiple'] ? ',1' : '').')"' : '';
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<input class="form-control '.$cls.'" type="email" name="'.$k.'" id="'.$k.'" value="'.$k_value.'" size="40" '.$suggest.'>
</div>
<div id="'.$k.'_suggestions"></div>';
break;
// Hidden
// Handle as text fields for staff
/* Default text input */
default:
$k_value = hesk_msgToPlain($k_value,0,0);
$cls = in_array($k,$_SESSION['iserror']) ? 'isError' : '';
echo '
<div class="form-group">
<label>'.$v['name'].' '.$v['req'].'</label>
<input class="form-control '.$cls.'" type="text" name="'.$k.'" size="40" maxlength="'.intval($v['value']['max_length']).'" value="'.$k_value.'">
</div>';
}
}
}
?>
<!-- END CUSTOM AFTER -->
<?php
/* attachments */
if ($hesk_settings['attachments']['use']) {
?>
<div class="block--attach">
<svg class="icon icon-attach">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-attach"></use>
</svg>
<div>
<?php echo $hesklang['attachments']; ?>
</div>
</div>
<?php
for ($i=1;$i<=$hesk_settings['attachments']['max_number'];$i++)
{
$cls = ($i == 1 && in_array('attachments',$_SESSION['iserror'])) ? ' class="isError" ' : '';
echo '<input type="file" name="attachment['.$i.']" size="50" '.$cls.' /><br />';
}
?>
<a class="link" href="javascript:" onclick="hesk_window('../file_limits.php',250,500);return false;"><?php echo $hesklang['ful']; ?></a>
<?php
}
// Admin options
if ( ! isset($_SESSION['as_notify']) )
{
$_SESSION['as_notify'] = $_SESSION['notify_customer_new'] ? 1 : 0;
}
?>
<div class="form-group" style="margin-top: 20px">
<label><?php echo $hesklang['addop']; ?></label>
<div class="checkbox-list">
<div class="checkbox-custom">
<input type="checkbox" id="create_notify1" name="notify" value="1" <?php echo empty($_SESSION['as_notify']) ? '' : 'checked'; ?>>
<label for="create_notify1"><?php echo $hesklang['seno']; ?></label>
</div>
<div class="checkbox-custom">
<input type="checkbox" id="create_show1" name="show" value="1" <?php echo (!isset($_SESSION['as_show']) || !empty($_SESSION['as_show'])) ? 'checked' : ''; ?>>
<label for="create_show1"><?php echo $hesklang['otas']; ?></label>
</div>
</div>
</div>
<?php if (hesk_checkPermission('can_assign_others',0)) { ?>
<div class="form-group">
<label><?php echo $hesklang['asst2']; ?></label>
<div class="dropdown-select center out-close">
<select name="owner" <?php if (in_array('owner',$_SESSION['iserror'])) {echo ' class="isError" ';} ?>>
<option value="-1"> &gt; <?php echo $hesklang['unas']; ?> &lt; </option>
<?php
if ($hesk_settings['autoassign'])
{
echo '<option value="-2"> &gt; ' . $hesklang['aass'] . ' &lt; </option>';
}
$owner = isset($_SESSION['as_owner']) ? intval($_SESSION['as_owner']) : 0;
foreach ($admins as $k=>$v)
{
if ($k == $owner)
{
echo '<option value="'.$k.'" selected="selected">'.$v.'</option>';
}
else
{
echo '<option value="'.$k.'">'.$v.'</option>';
}
}
?>
</select>
</div>
</div>
<?php
}
elseif (hesk_checkPermission('can_assign_self',0))
{
$checked = (!isset($_SESSION['as_owner']) || !empty($_SESSION['as_owner'])) ? 'checked' : '';
?>
<div class="form-group">
<label><?php echo $hesklang['owner']; ?></label>
<div class="checkbox-custom">
<input type="checkbox" id="create_assing_to_self1" name="assing_to_self" value="1" <?php echo $checked; ?>>
<label for="create_assing_to_self1"><?php echo $hesklang['asss2']; ?></label>
</div>
</div>
<?php
}
?>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
<input type="hidden" name="category" value="<?php echo $category; ?>">
<button type="submit" class="btn btn-full"><?php echo $hesklang['sub_ticket']; ?></button>
</form>
</div>
</div>
<?php
hesk_cleanSessionVars('iserror');
hesk_cleanSessionVars('isnotice');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function print_select_category($number_of_categories)
{
global $hesk_settings, $hesklang;
// A categoy needs to be selected
if (isset($_GET['category']) && empty($_GET['category']))
{
hesk_process_messages($hesklang['sel_app_cat'],'NOREDIRECT','NOTICE');
}
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content categories">
<div class="table-wrap">
<h3><?php echo $hesklang['select_category_staff']; ?></h3>
<div class="select_category">
<?php
// Print a select box if number of categories is large
if ($number_of_categories > $hesk_settings['cat_show_select']) {
?>
<form action="new_ticket.php" method="get" class="form">
<select class="form-control" name="category" id="select_category">
<?php
if ($hesk_settings['select_cat'])
{
echo '<option value="">'.$hesklang['select'].'</option>';
}
foreach ($hesk_settings['categories'] as $k=>$v)
{
echo '<option value="'.$k.'">'.$v.'</option>';
}
?>
</select>
<button style="margin-top: 10px" type="submit" class="btn btn-full"><?php echo $hesklang['c2c']; ?></button>
</form>
<script>
$(document).ready(function() {
$('#select_category').selectize();
});
</script>
<?php
}
// Otherwise print quick links
else
{
?>
<ul id="ul_category">
<?php
foreach ($hesk_settings['categories'] as $k=>$v)
{
echo '<li><a ripple="ripple" href="new_ticket.php?a=add&amp;category='.$k.'">'.$v.'</a></li>';
}
?>
</ul>
<?php
}
?>
</div>
</div>
</div>
<style>
#ul_category {
list-style-type: none;
margin: 0;
padding: 0;
margin-top: 10px;
}
#ul_category li:first-child {
border-top: 1px solid #d1d5d7;
}
#ul_category li {
border: 1px solid #d1d5d7;
border-top: none;
border-radius: 2px;
}
#ul_category li:hover {
background: rgba(0,0,0,.05);
}
#ul_category li a {
display: block;
font-size: 14px;
padding: 0.75em 0.75em;
text-decoration: none;
transition: all 0.12s ease;
word-wrap: break-word;
}
</style>
<?php
hesk_cleanSessionVars('iserror');
hesk_cleanSessionVars('isnotice');
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
} // END print_select_category()

327
hesk/admin/password.php Normal file
View File

@@ -0,0 +1,327 @@
<?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');
// Is the password reset function enabled?
if ( ! $hesk_settings['reset_pass'])
{
die($hesklang['attempt']);
}
// Allow additional 5 attempts in case the user is already blocked
$hesk_settings['attempt_limit'] += 5;
$show_sent_email_message = false;
// Start session
hesk_session_start();
if (!isset($_SESSION['a_iserror']))
{
$_SESSION['a_iserror'] = array();
}
$hesk_error_buffer = array();
// If this is a POST method, check input
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
// Verify security image
if ($hesk_settings['secimg_use'])
{
// Using reCAPTCHA?
if ($hesk_settings['recaptcha_use'])
{
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
$resp = null;
$reCaptcha = new ReCaptcha($hesk_settings['recaptcha_private_key']);
// Was there a reCAPTCHA response?
if ( isset($_POST["g-recaptcha-response"]) )
{
$resp = $reCaptcha->verifyResponse(hesk_getClientIP(), hesk_POST("g-recaptcha-response") );
}
if ($resp != null && $resp->success)
{
//$_SESSION['img_a_verified']=true;
}
else
{
$hesk_error_buffer['mysecnum']=$hesklang['recaptcha_error'];
}
}
// Using PHP generated image
else
{
$mysecnum = intval( hesk_POST('mysecnum', 0) );
if ( empty($mysecnum) )
{
$hesk_error_buffer['mysecnum'] = $hesklang['sec_miss'];
}
else
{
require(HESK_PATH . 'inc/secimg.inc.php');
$sc = new PJ_SecurityImage($hesk_settings['secimg_sum']);
if ( isset($_SESSION['checksum']) && $sc->checkCode($mysecnum, $_SESSION['checksum']) )
{
//$_SESSION['img_a_verified'] = true;
}
else
{
$hesk_error_buffer['mysecnum'] = $hesklang['sec_wrng'];
}
}
}
}
// Connect to database and check for brute force attempts
hesk_load_database_functions();
hesk_dbConnect();
hesk_limitBfAttempts();
// Get email
$email = hesk_validateEmail( hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer['email']=$hesklang['enter_valid_email'];
// Any errors?
if (count($hesk_error_buffer)!=0)
{
$_SESSION['a_iserror'] = array_keys($hesk_error_buffer);
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['pcer'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'NOREDIRECT');
}
elseif( defined('HESK_DEMO') )
{
hesk_process_messages($hesklang['ddemo'],'NOREDIRECT');
}
else
{
// Get user data from the database
$res = hesk_dbQuery("SELECT `id`, `name`, `pass` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($email)."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_process_messages($hesklang['noace'],'NOREDIRECT');
}
else
{
$row = hesk_dbFetchAssoc($res);
$hash = sha1(microtime() . hesk_getClientIP() . mt_rand() . $row['id'] . $row['name'] . $row['pass']);
// Insert the verification hash into the database
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."reset_password` (`user`, `hash`, `ip`) VALUES (".intval($row['id']).", '{$hash}', '".hesk_dbEscape(hesk_getClientIP())."') ");
// Prepare and send email
require(HESK_PATH . 'inc/email_functions.inc.php');
// Get the email message
$msg = hesk_getEmailMessage('reset_password',array(),1,0,1);
// Replace message special tags
$msg = str_replace('%%NAME%%', hesk_msgToPlain($row['name'],1,1), $msg);
$msg = str_replace('%%SITE_URL%%', $hesk_settings['site_url'], $msg);
$msg = str_replace('%%SITE_TITLE%%', $hesk_settings['site_title'], $msg);
$msg = str_replace('%%PASSWORD_RESET%%', $hesk_settings['hesk_url'].'/'.$hesk_settings['admin_dir'].'/password.php?h='.$hash, $msg);
// Send email
hesk_mail($email, $hesklang['reset_password'], $msg);
// Show success
$show_sent_email_message = true;
}
}
}
// If the "h" parameter is set verify it and reset the password
elseif ( isset($_GET['h']) )
{
// Get the hash
$hash = preg_replace('/[^a-zA-Z0-9]/', '', $_GET['h']);
// Connect to database
hesk_load_database_functions();
hesk_dbConnect();
// Expire verification hashes older than 2 hours
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."reset_password` WHERE `dt` < (NOW() - INTERVAL 2 HOUR)");
// Verify the hash exists
$res = hesk_dbQuery("SELECT `user`, `ip` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."reset_password` WHERE `hash` = '{$hash}' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
// Not a valid hash
hesk_limitBfAttempts();
hesk_process_messages($hesklang['ehash'],'NOREDIRECT');
}
else
{
// Get info from database
$row = hesk_dbFetchAssoc($res);
// Only allow resetting password from the same IP address that submitted password reset request
if ($row['ip'] != hesk_getClientIP())
{
hesk_limitBfAttempts();
hesk_process_messages($hesklang['ehaip'],'NOREDIRECT');
}
else
{
// Expire all verification hashes for this user
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."reset_password` WHERE `user`=".intval($row['user']));
// Load additional required functions
require(HESK_PATH . 'inc/admin_functions.inc.php');
// Get user details
$res = hesk_dbQuery('SELECT * FROM `'.$hesk_settings['db_pfix']."users` WHERE `id`=".intval($row['user'])." LIMIT 1");
$row = hesk_dbFetchAssoc($res);
foreach ($row as $k=>$v)
{
$_SESSION[$k]=$v;
}
// Set a tag that will be used to expire sessions after username or password change
$_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['user'], $_SESSION['pass']);
// We don't need the password hash anymore
unset($_SESSION['pass']);
// Clean brute force attempts
hesk_cleanBfAttempts();
// Regenerate session ID (security)
hesk_session_regenerate_id();
// Get allowed categories
if (empty($_SESSION['isadmin']))
{
$_SESSION['categories']=explode(',',$_SESSION['categories']);
}
// Redirect to the profile page
hesk_process_messages($hesklang['resim'],'profile.php','NOTICE');
exit();
} // End IP matches
}
}
// Tell header to load reCaptcha API if needed
if ($hesk_settings['recaptcha_use'])
{
define('RECAPTCHA',1);
}
$hesk_settings['tmp_title'] = $hesk_settings['hesk_title'] . ' - ' .$hesklang['passr'];
require_once(HESK_PATH . 'inc/header.inc.php');
$login_wrapper = true;
?>
<div class="wrapper login">
<main class="main">
<div class="reg__wrap">
<div class="reg__image">
<div class="bg-absolute"><img src="<?php echo HESK_PATH; ?>img/hero-bg.png" alt="Hesk" /></div>
</div>
<div class="reg__section reset-password">
<div class="reg__box">
<?php if ($show_sent_email_message): ?>
<h2 class="reg__heading delete">
<?php echo $hesklang['password_reset_check_your_email']; ?>
</h2>
<div class="reset-password__text">
<?php echo $hesklang['password_reset_link_sent']; ?>
</div>
<?php else: ?>
<h2 class="reg__heading delete">
<?php echo $hesklang['reset_your_password']; ?>
</h2>
<div class="reset-password__text"><?php echo $hesklang['reset_password_instructions']; ?></div>
<div style="margin-right: -24px; margin-left: -16px">
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
</div>
<!-- To activate the error add the class "invalid" to the form -->
<form action="password.php" class="form <?php echo isset($_SESSION['a_iserror']) && count($_SESSION['a_iserror']) ? 'invalid' : ''; ?>" method="post" name="form1" id="form1" novalidate>
<div class="form-group">
<label for="regInputUsername"><?php echo $hesklang['email']; ?></label>
<input type="email"
name="email"
class="form-control<?php echo in_array('email',$_SESSION['a_iserror']) ? ' isError' : ''; ?>"
id="regInputUsername"
placeholder="<?php echo htmlspecialchars($hesklang['enter_email']); ?>"
value="<?php if (isset($email)) {echo stripslashes(hesk_input($email));} ?>">
<div class="form-control__error"><?php echo $hesklang['this_field_is_required']; ?></div>
</div>
<?php if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] != 1) {
if ($hesk_settings['recaptcha_use'] == 2) { ?>
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>"></div>
<?php } else {
$cls = in_array('mysecnum',$_SESSION['a_iserror']) ? ' class="form-control isError" ' : ' class="form-control" ';
/*echo $hesklang['sec_enter'].'<br>&nbsp;<br><img src="'.HESK_PATH.'print_sec_img.php?'.rand(10000,99999).'" width="150" height="40" alt="'.$hesklang['sec_img'].'" title="'.$hesklang['sec_img'].'" border="1" name="secimg" style="vertical-align:text-bottom"> '.
'<a href="javascript:void(0)" onclick="javascript:document.form1.secimg.src=\''.HESK_PATH.'print_sec_img.php?\'+ ( Math.floor((90000)*Math.random()) + 10000);"><img src="'.HESK_PATH.'img/reload.png" height="24" width="24" alt="'.$hesklang['reload'].'" title="'.$hesklang['reload'].'" border="0" style="vertical-align:text-bottom"></a>'.
'<br>&nbsp;<br><input type="text" name="mysecnum" size="20" maxlength="5" '.$cls.'>';*/
echo '<div class="form-group"><label>'.$hesklang['sec_enter'].'</label><img src="'.HESK_PATH.'print_sec_img.php?'.rand(10000,99999).'" width="150" height="40" alt="'.$hesklang['sec_img'].'" title="'.$hesklang['sec_img'].'" border="1" name="secimg" style="vertical-align:middle" /> '.
'<a style="vertical-align: middle; display: inline" class="btn btn-refresh" href="javascript:" onclick="document.form1.secimg.src=\''.HESK_PATH.'print_sec_img.php?\'+ ( Math.floor((90000)*Math.random()) + 10000);">
<svg class="icon icon-refresh">
<use xlink:href="' . HESK_PATH . 'img/sprite.svg#icon-refresh"></use>
</svg>
</a>'.
'<br><br><input type="text" name="mysecnum" size="20" maxlength="5" '.$cls.'></div>';
}
} ?>
<div class="form__submit">
<button class="btn btn-full" type="submit" id="recaptcha-submit"><?php echo $hesklang['passs']; ?></button>
</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>
<?php endif; ?>
<div class="reg__footer">
<a href="index.php" class="link"><?php echo $hesklang['back_to_login']; ?></a>
</div>
</div>
</div>
</div>
<?php
// Clean session errors
hesk_cleanSessionVars('a_iserror');
hesk_cleanSessionVars('img_a_verified');
// Print footer
require_once(HESK_PATH . 'inc/footer.inc.php');
?>

59
hesk/admin/priority.php Normal file
View File

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

391
hesk/admin/profile.php Normal file
View File

@@ -0,0 +1,391 @@
<?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','../');
define('LOAD_TABS',1);
/* 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/profile_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions */
$can_view_tickets = hesk_checkPermission('can_view_tickets',0);
$can_reply_tickets = hesk_checkPermission('can_reply_tickets',0);
$can_view_unassigned = hesk_checkPermission('can_view_unassigned',0);
/* Update profile? */
if ( ! empty($_POST['action']))
{
// Demo mode
if ( defined('HESK_DEMO') )
{
hesk_process_messages($hesklang['sdemo'], 'profile.php', 'NOTICE');
}
// Update profile
update_profile();
}
else
{
$res = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1");
$tmp = hesk_dbFetchAssoc($res);
foreach ($tmp as $k=>$v)
{
if ($k == 'pass')
{
if ($v == '499d74967b28a841c98bb4baaabaad699ff3c079')
{
define('WARN_PASSWORD',true);
}
continue;
}
elseif ($k == 'categories')
{
continue;
}
$_SESSION['new'][$k]=$v;
}
}
if ( ! isset($_SESSION['new']['username']))
{
$_SESSION['new']['username'] = '';
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
if (!hesk_SESSION(array('new', 'errors'))) {
hesk_handle_messages();
}
if (defined('WARN_PASSWORD'))
{
hesk_show_notice($hesklang['chdp2'],'<span class="important">'.$hesklang['security'].'</span>');
}
?>
<div class="main__content profile">
<article class="profile__wrapper">
<div class="profile__info">
<div class="profile__info_list">
<h3><?php echo $_SESSION['new']['name']; ?></h3>
<div class="info--mail">
<a href="mailto:<?php echo $_SESSION['new']['email']; ?>"><?php echo $_SESSION['new']['email']; ?></a>
</div>
</div>
</div>
<div class="profile__control">
<div class="profile__edit">
<button class="btn btn--blue-border" data-action="profile-edit"><?php echo $hesklang['edit_profile']; ?></button>
</div>
<a href="index.php?a=logout&token=<?php hesk_token_echo(); ?>" class="profile-log-out">
<svg class="icon icon-log-out">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-log-out"></use>
</svg>
<span><?php echo $hesklang['logout']; ?></span>
</a>
</div>
</article>
</div>
<div class="right-bar profile-edit" <?php echo hesk_SESSION(array('new','errors')) ? 'style="display: block"' : ''; ?>>
<div class="right-bar__body form" data-step="1">
<h3>
<a href="javascript:">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span><?php echo $hesklang['profile_for'].' <b>'.$_SESSION['new']['user']; ?></span>
</a>
</h3>
<?php
/* This will handle error, success and notice messages */
if (hesk_SESSION(array('new', 'errors'))) {
hesk_handle_messages();
}
if ($hesk_settings['can_sel_lang'])
{
/* Update preferred language in the database? */
if (isset($_GET['save_language']) )
{
$newlang = hesk_input( hesk_GET('language') );
/* Only update if it's a valid language */
if ( isset($hesk_settings['languages'][$newlang]) )
{
$newlang = ($newlang == HESK_DEFAULT_LANGUAGE) ? "NULL" : "'" . hesk_dbEscape($newlang) . "'";
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` SET `language`=$newlang WHERE `id`='".intval($_SESSION['id'])."'");
}
}
$str = '<form method="get" class="form" action="profile.php" style="margin:10px 0 0 0;padding:0;border:0;white-space:nowrap;">';
$str .= '<input type="hidden" name="save_language" value="1" />';
$str .= '<div class="form-group"><label for="prof_language">'.$hesklang['chol'].'</label>';
if ( ! isset($_GET) )
{
$_GET = array();
}
foreach ($_GET as $k => $v)
{
if ($k == 'language' || $k == 'save_language')
{
continue;
}
$str .= '<input type="hidden" name="'.htmlentitieshesk_htmlentities($k).'" value="'.hesk_htmlentities($v).'" />';
}
$str .= '<div class="dropdown-select center out-close"><select class="form-control" name="language" onchange="this.form.submit()">';
$str .= hesk_listLanguages(0);
$str .= '</select></div></div>';
?>
<script language="javascript" type="text/javascript">
document.write('<?php echo str_replace(array('"','<','=','>',"'"),array('\42','\74','\75','\76','\47'),$str . '</p></form>'); ?>');
</script>
<noscript>
<?php
echo $str . '<input type="submit" value="'.$hesklang['go'].'" /></p></form>';
?>
</noscript>
<?php
}
?>
<form name="form1" method="post" action="profile.php" class="form <?php echo hesk_SESSION(array('new','errors')) ? 'invalid' : ''; ?>">
<?php hesk_profile_tab(); ?>
<!-- Submit -->
<div class="right-bar__footer">
<input type="hidden" name="action" value="update" />
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
<button type="submit" class="btn btn-full save" data-action="save" ripple="ripple"><?php echo $hesklang['update_profile']; ?></button>
</div>
</form>
</div>
</div>
<?php
unset($_SESSION['new']['errors']);
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function update_profile() {
global $hesk_settings, $hesklang, $can_view_unassigned;
/* A security check */
hesk_token_check('POST');
$sql_pass = '';
$sql_username = '';
$hesk_error_buffer = '';
$errors = array();
$_SESSION['new']['name'] = hesk_input( hesk_POST('name') );
if (!$_SESSION['new']['name']) {
$hesk_error_buffer .= '<li>' . $hesklang['enter_your_name'] . '</li>';
$errors[] = 'name';
}
$_SESSION['new']['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0);
if (!$_SESSION['new']['email']) {
$hesk_error_buffer .= '<li>' . $hesklang['enter_valid_email'] . '</li>';
$errors[] = 'email';
}
$_SESSION['new']['signature'] = hesk_input( hesk_POST('signature') );
/* Signature */
if (hesk_mb_strlen($_SESSION['new']['signature'])>1000)
{
$hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>';
$errors[] = 'signature';
}
/* Admins can change username */
if ($_SESSION['isadmin'])
{
$_SESSION['new']['user'] = hesk_input( hesk_POST('user') ) or $hesk_error_buffer .= '<li>' . $hesklang['enter_username'] . '</li>';
/* Check for duplicate usernames */
$result = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `user`='".hesk_dbEscape($_SESSION['new']['user'])."' AND `id`!='".intval($_SESSION['id'])."' LIMIT 1");
if (hesk_dbNumRows($result) != 0)
{
$hesk_error_buffer .= '<li>' . $hesklang['duplicate_user'] . '</li>';
$errors[] = 'user';
}
else
{
$sql_username = ",`user`='" . hesk_dbEscape($_SESSION['new']['user']) . "'";
}
}
/* Change password? */
$newpass = hesk_input( hesk_POST('newpass') );
$passlen = strlen($newpass);
if ($passlen > 0)
{
/* At least 5 chars? */
if ($passlen < 5)
{
$hesk_error_buffer .= '<li>' . $hesklang['password_not_valid'] . '</li>';
$errors[] = 'passwords';
}
/* Check password confirmation */
else
{
$newpass2 = hesk_input( hesk_POST('newpass2') );
if ($newpass != $newpass2)
{
$hesk_error_buffer .= '<li>' . $hesklang['passwords_not_same'] . '</li>';
$errors[] = 'passwords';
}
else
{
$newpass_hash = hesk_Pass2Hash($newpass);
if ($newpass_hash == '499d74967b28a841c98bb4baaabaad699ff3c079')
{
define('WARN_PASSWORD',true);
}
$sql_pass = ',`pass`=\''.$newpass_hash.'\'';
}
}
}
/* After reply */
$_SESSION['new']['afterreply'] = intval( hesk_POST('afterreply') );
if ($_SESSION['new']['afterreply'] != 1 && $_SESSION['new']['afterreply'] != 2)
{
$_SESSION['new']['afterreply'] = 0;
}
// Defaults
$_SESSION['new']['autostart'] = isset($_POST['autostart']) ? 1 : 0;
$_SESSION['new']['notify_customer_new'] = isset($_POST['notify_customer_new']) ? 1 : 0;
$_SESSION['new']['notify_customer_reply'] = isset($_POST['notify_customer_reply']) ? 1 : 0;
$_SESSION['new']['show_suggested'] = isset($_POST['show_suggested']) ? 1 : 0;
$_SESSION['new']['autoreload'] = isset($_POST['autoreload']) ? 1 : 0;
if ($_SESSION['new']['autoreload'])
{
$_SESSION['new']['autoreload'] = intval(hesk_POST('reload_time'));
if (hesk_POST('secmin') == 'min')
{
$_SESSION['new']['autoreload'] *= 60;
}
if ($_SESSION['new']['autoreload'] < 0 || $_SESSION['new']['autoreload'] > 65535)
{
$_SESSION['new']['autoreload'] = 30;
}
}
else
{
hesk_setcookie('autorefresh', '');
}
/* Notifications */
$_SESSION['new']['notify_new_unassigned'] = empty($_POST['notify_new_unassigned']) || ! $can_view_unassigned ? 0 : 1;
$_SESSION['new']['notify_new_my'] = empty($_POST['notify_new_my']) ? 0 : 1;
$_SESSION['new']['notify_reply_unassigned'] = empty($_POST['notify_reply_unassigned']) || ! $can_view_unassigned ? 0 : 1;
$_SESSION['new']['notify_reply_my'] = empty($_POST['notify_reply_my']) ? 0 : 1;
$_SESSION['new']['notify_assigned'] = empty($_POST['notify_assigned']) ? 0 : 1;
$_SESSION['new']['notify_note'] = empty($_POST['notify_note']) ? 0 : 1;
$_SESSION['new']['notify_pm'] = empty($_POST['notify_pm']) ? 0 : 1;
/* Any errors? */
if (strlen($hesk_error_buffer))
{
/* Process the session variables */
$_SESSION['new'] = hesk_stripArray($_SESSION['new']);
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
$_SESSION['new']['errors'] = $errors;
hesk_process_messages($hesk_error_buffer,'NOREDIRECT');
}
else
{
/* Update database */
hesk_dbQuery(
"UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` SET
`name`='".hesk_dbEscape($_SESSION['new']['name'])."',
`email`='".hesk_dbEscape($_SESSION['new']['email'])."',
`signature`='".hesk_dbEscape($_SESSION['new']['signature'])."'
$sql_username
$sql_pass ,
`afterreply`='".($_SESSION['new']['afterreply'])."' ,
".($hesk_settings['time_worked'] ? "`autostart`='".($_SESSION['new']['autostart'])."'," : '')."
`autoreload`='".($_SESSION['new']['autoreload'])."' ,
`notify_customer_new`='".($_SESSION['new']['notify_customer_new'])."' ,
`notify_customer_reply`='".($_SESSION['new']['notify_customer_reply'])."' ,
`show_suggested`='".($_SESSION['new']['show_suggested'])."' ,
`notify_new_unassigned`='".($_SESSION['new']['notify_new_unassigned'])."' ,
`notify_new_my`='".($_SESSION['new']['notify_new_my'])."' ,
`notify_reply_unassigned`='".($_SESSION['new']['notify_reply_unassigned'])."' ,
`notify_reply_my`='".($_SESSION['new']['notify_reply_my'])."' ,
`notify_assigned`='".($_SESSION['new']['notify_assigned'])."' ,
`notify_pm`='".($_SESSION['new']['notify_pm'])."',
`notify_note`='".($_SESSION['new']['notify_note'])."'
WHERE `id`='".intval($_SESSION['id'])."'"
);
/* Process the session variables */
$_SESSION['new'] = hesk_stripArray($_SESSION['new']);
// Do we need a new session_veify tag?
if ( strlen($sql_username) && strlen($sql_pass) )
{
$_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['new']['user'], $newpass_hash);
}
elseif ( strlen($sql_pass) )
{
$_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['user'], $newpass_hash);
}
elseif ( strlen($sql_username) )
{
$res = hesk_dbQuery('SELECT `pass` FROM `'.hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1");
$_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['new']['user'], hesk_dbResult($res) );
}
/* Update session variables */
foreach ($_SESSION['new'] as $k => $v)
{
$_SESSION[$k] = $v;
}
unset($_SESSION['new']);
hesk_cleanSessionVars('as_notify');
hesk_process_messages($hesklang['profile_updated_success'],'profile.php','SUCCESS');
}
} // End update_profile()
?>

993
hesk/admin/reports.php Normal file
View File

@@ -0,0 +1,993 @@
<?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/reporting_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_run_reports');
// Should reports be full or limited to own tickets?
$can_run_reports_full = hesk_checkPermission('can_run_reports_full', 0);
// Set default values
define('CALENDAR',1);
define('MAIN_PAGE',1);
define('LOAD_TABS',1);
$selected = array(
'w' => array(0=>'',1=>''),
'time' => array(1=>'',2=>'',3=>'',4=>'',5=>'',6=>'',7=>'',8=>'',9=>'',10=>'',11=>'',12=>''),
'type' => array(1=>'',2=>'',3=>'',4=>''),
);
$is_all_time = 0;
/* Default this month to date */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m"), 1, date("Y")));
$date_to = date('Y-m-d');
$input_datefrom = date('m/d/Y', strtotime('last month'));
$input_dateto = date('m/d/Y');
/* Date */
if (!empty($_GET['w']))
{
$df = preg_replace('/[^0-9]/','', hesk_GET('datefrom') );
if (strlen($df) == 8)
{
$date_from = substr($df,4,4) . '-' . substr($df,0,2) . '-' . substr($df,2,2);
$input_datefrom = substr($df,0,2) . '/' . substr($df,2,2) . '/' . substr($df,4,4);
}
else
{
$date_from = date('Y-m-d', strtotime('last month') );
}
$dt = preg_replace('/[^0-9]/','', hesk_GET('dateto') );
if (strlen($dt) == 8)
{
$date_to = substr($dt,4,4) . '-' . substr($dt,0,2) . '-' . substr($dt,2,2);
$input_dateto = substr($dt,0,2) . '/' . substr($dt,2,2) . '/' . substr($dt,4,4);
}
else
{
$date_to = date('Y-m-d');
}
if ($date_from > $date_to)
{
$tmp = $date_from;
$tmp2 = $input_datefrom;
$date_from = $date_to;
$input_datefrom = $input_dateto;
$date_to = $tmp;
$input_dateto = $tmp2;
$note_buffer = $hesklang['datetofrom'];
}
if ($date_to > date('Y-m-d'))
{
$date_to = date('Y-m-d');
$input_dateto = date('m/d/Y');
}
$query_string = 'reports.php?w=1&amp;datefrom='.urlencode($input_datefrom).'&amp;dateto='.urlencode($input_dateto);
$selected['w'][1]='checked="checked"';
$selected['time'][3]='selected="selected"';
}
else
{
$selected['w'][0]='checked="checked"';
$_GET['time'] = intval( hesk_GET('time', 3) );
switch ($_GET['time'])
{
case 1:
/* Today */
$date_from = date('Y-m-d');
$date_to = $date_from;
$selected['time'][1]='selected="selected"';
$is_all_time = 1;
break;
case 2:
/* Yesterday */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m"), date("d")-1, date("Y")));
$date_to = $date_from;
$selected['time'][2]='selected="selected"';
$is_all_time = 1;
break;
case 4:
/* Last month */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m")-1, 1, date("Y")));
$date_to = date('Y-m-d',mktime(0, 0, 0, date("m"), 0, date("Y")));
$selected['time'][4]='selected="selected"';
break;
case 5:
/* Last 30 days */
$date_from = date('Y-m-d',mktime(0, 0, 0, date("m")-1, date("d"), date("Y")));
$date_to = date('Y-m-d');
$selected['time'][5]='selected="selected"';
break;
case 6:
/* This week */
list($date_from,$date_to)=dateweek(0);
$date_to = date('Y-m-d');
$selected['time'][6]='selected="selected"';
break;
case 7:
/* Last week */
list($date_from,$date_to)=dateweek(-1);
$selected['time'][7]='selected="selected"';
break;
case 8:
/* This business week */
list($date_from,$date_to)=dateweek(0,1);
$date_to = date('Y-m-d');
$selected['time'][8]='selected="selected"';
break;
case 9:
/* Last business week */
list($date_from,$date_to)=dateweek(-1,1);
$selected['time'][9]='selected="selected"';
break;
case 10:
/* This year */
$date_from = date('Y').'-01-01';
$date_to = date('Y-m-d');
$selected['time'][10]='selected="selected"';
break;
case 11:
/* Last year */
$date_from = date('Y')-1 . '-01-01';
$date_to = date('Y')-1 . '-12-31';
$selected['time'][11]='selected="selected"';
break;
case 12:
/* All time */
$date_from = hesk_getOldestDate();
$date_to = date('Y-m-d');
$selected['time'][12]='selected="selected"';
$is_all_time = 1;
break;
default:
$_GET['time'] = 3;
$selected['time'][3]='selected="selected"';
}
$query_string = 'reports.php?w=0&amp;time='.$_GET['time'];
}
unset($tmp);
/* Type */
$type = intval( hesk_GET('type', 1) );
if (isset($selected['type'][$type]))
{
$selected['type'][$type] = 'selected="selected"';
}
// Setup date SQL so we don't have to call functions several times
$hesk_settings['dt_sql'] = " `dt` BETWEEN '" . hesk_dbEscape($date_from) . " 00:00:00' AND '" . hesk_dbEscape($date_to) . " 23:59:59' ";
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
<div class="main__content reports">
<form action="reports.php" method="get" name="form1">
<div class="reports__head">
<h2>
<?php echo $hesklang['reports_tab']; ?>
<div class="tooltype right out-close">
<svg class="icon icon-info">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-info"></use>
</svg>
<div class="tooltype__content">
<div class="tooltype__wrapper">
<?php echo $hesklang['reports_intro']; ?>
</div>
</div>
</div>
</h2>
</div>
<div class="reports__range">
<h4><?php echo $hesklang['dtrg']; ?></h4>
<div class="reports__range_form form">
<div class="radio-list">
<div class="radio-custom">
<input type="radio" name="w" value="0" id="w0" <?php echo $selected['w'][0]; ?>>
<label for="w0">&nbsp;</label>
<div class="dropdown-select center out-close">
<select name="time" onclick="document.getElementById('w0').checked = true" onchange="document.getElementById('w0').checked = true" style="margin-top:5px;margin-bottom:5px;">
<option value="1" <?php echo $selected['time'][1]; ?>><?php echo $hesklang['r1']; ?> (<?php echo $hesklang['d'.date('w')]; ?>)</option>
<option value="2" <?php echo $selected['time'][2]; ?>><?php echo $hesklang['r2']; ?> (<?php echo $hesklang['d'.date('w',mktime(0, 0, 0, date('m'), date('d')-1, date('Y')))]; ?>)</option>
<option value="3" <?php echo $selected['time'][3]; ?>><?php echo $hesklang['r3']; ?> (<?php echo $hesklang['m'.date('n')]; ?>)</option>
<option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?> (<?php echo $hesklang['m'.date('n',mktime(0, 0, 0, date('m')-1, 1, date('Y')))]; ?>)</option>
<option value="5" <?php echo $selected['time'][5]; ?>><?php echo $hesklang['r5']; ?></option>
<option value="6" <?php echo $selected['time'][6]; ?>><?php echo $hesklang['r6']; ?></option>
<option value="7" <?php echo $selected['time'][7]; ?>><?php echo $hesklang['r7']; ?></option>
<option value="8" <?php echo $selected['time'][8]; ?>><?php echo $hesklang['r8']; ?></option>
<option value="9" <?php echo $selected['time'][9]; ?>><?php echo $hesklang['r9']; ?></option>
<option value="10" <?php echo $selected['time'][10]; ?>><?php echo $hesklang['r10']; ?> (<?php echo date('Y'); ?>)</option>
<option value="11" <?php echo $selected['time'][11]; ?>><?php echo $hesklang['r11']; ?> (<?php echo date('Y',mktime(0, 0, 0, date('m'), date('d'), date('Y')-1)); ?>)</option>
<option value="12" <?php echo $selected['time'][12]; ?>><?php echo $hesklang['r12']; ?></option>
</select>
</div>
</div>
<div class="radio-custom">
<input type="radio" name="w" value="1" id="w1" <?php echo $selected['w'][1]; ?>>
<label for="w1">&nbsp;</label>
<?php echo $hesklang['from']; ?>
<section class="param calendar" style="margin-left: 10px; margin-right: 10px">
<div class="calendar--button">
<button type="button" onclick="document.getElementById('w1').checked = true">
<svg class="icon icon-calendar">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="datefrom"
id="datefrom"
<?php if ($input_datefrom) {echo 'value="'.$input_datefrom.'"';} ?>
type="text" class="datepicker">
</div>
<div class="calendar--value" <?php echo ($input_datefrom ? 'style="display: block"' : ''); ?>>
<span><?php echo $input_datefrom; ?></span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>
<?php echo $hesklang['to']; ?>
<section class="param calendar" style="margin-left: 10px;">
<div class="calendar--button">
<button type="button" onclick="document.getElementById('w1').checked = true">
<svg class="icon icon-calendar">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-calendar"></use>
</svg>
</button>
<input name="dateto"
id="dateto"
<?php if ($input_dateto) {echo 'value="'.$input_dateto.'"';} ?>
type="text" class="datepicker">
</div>
<div class="calendar--value" <?php echo ($input_dateto ? 'style="display: block"' : ''); ?>>
<span><?php echo $input_dateto; ?></span>
<i class="close">
<svg class="icon icon-close">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-close"></use>
</svg>
</i>
</div>
</section>
</div>
</div>
</div>
</div>
<div class="reports__type">
<h4><?php echo $hesklang['crt']; ?></h4>
<div class="dropdown-select center out-close">
<select name="type">
<option value="1" <?php echo $selected['type'][1]; ?>><?php echo $hesklang['t1']; ?></option>
<option value="2" <?php echo $selected['type'][2]; ?>><?php echo $hesklang['t2']; ?></option>
<option value="3" <?php echo $selected['type'][3]; ?>><?php echo $hesklang['t3']; ?></option>
<option value="4" <?php echo $selected['type'][4]; ?>><?php echo $hesklang['t4']; ?></option>
</select>
</div>
</div>
<div class="reports__type">
<button class="btn btn-full" ripple="ripple"><?php echo $hesklang['dire']; ?></button>
</div>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>">
</form>
<?php
if ($date_from == $date_to)
{
?>
<h2 style="margin-top: 20px; margin-bottom: 20px"><?php echo hesk_dateToString($date_from,0); ?></h2>
<?php
}
else
{
?>
<h2 style="margin-top: 20px; margin-bottom: 20px"><?php echo hesk_dateToString($date_from,0); ?> - <?php echo hesk_dateToString($date_to,0); ?></h2>
<?php
}
// Show a note if reports are limited
if ( ! $can_run_reports_full)
{
echo "<p>{$hesklang['roo']}</p>";
}
/* Report type */
switch ($type)
{
case 2:
hesk_ticketsByMonth();
break;
case 3:
hesk_ticketsByUser();
break;
case 4:
hesk_ticketsByCategory();
break;
default:
hesk_ticketsByDay();
}
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function hesk_ticketsByCategory()
{
global $hesk_settings, $hesklang, $date_from, $date_to, $can_run_reports_full;
/* List of categories */
$cat = array();
$res = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE " . ( $can_run_reports_full ? '1' : hesk_myCategories('id') ) . " ORDER BY `id` ASC");
while ($row=hesk_dbFetchAssoc($res))
{
$cat[$row['id']]=$row['name'];
}
$tickets = array();
$totals = array('num_tickets' => 0, 'resolved' => 0, 'all_replies' => 0, 'staff_replies' => 0, 'worked' => 0);
/* Populate category counts */
foreach ($cat as $id => $name)
{
$tickets[$id] = array(
'num_tickets' => 0,
'resolved' => 0,
'all_replies' => 0,
'staff_replies' => 0,
'worked' => '',
);
}
/* SQL query for category stats */
$res = hesk_dbQuery("SELECT `category`, COUNT(*) AS `num_tickets`, ".($hesk_settings['time_worked'] ? "SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`," : '')." SUM(`replies`) AS `all_replies`, SUM(staffreplies) AS `staff_replies` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE {$hesk_settings['dt_sql']} " . ( $can_run_reports_full ? "" : " AND `t1`.`owner` = '" . intval($_SESSION['id']) . "'" ) . " GROUP BY `category`");
/* Update ticket values */
while ($row = hesk_dbFetchAssoc($res))
{
if ( ! $hesk_settings['time_worked'])
{
$row['seconds_worked'] = 0;
}
if (isset($cat[$row['category']]))
{
$tickets[$row['category']]['num_tickets'] += $row['num_tickets'];
$tickets[$row['category']]['all_replies'] += $row['all_replies'];
$tickets[$row['category']]['staff_replies'] += $row['staff_replies'];
$tickets[$row['category']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
}
else
{
/* Category deleted */
if ( ! isset($tickets[9999]) )
{
$cat[9999] = $hesklang['catd'];
$tickets[9999] = array('num_tickets' => $row['num_tickets'], 'resolved' => 0, 'all_replies' => $row['all_replies'], 'staff_replies' => $row['staff_replies'], 'worked' => $row['seconds_worked']);
}
else
{
$tickets[9999]['num_tickets'] += $row['num_tickets'];
$tickets[9999]['all_replies'] += $row['all_replies'];
$tickets[9999]['staff_replies'] += $row['staff_replies'];
$tickets[9999]['worked'] += $row['seconds_worked'];
}
}
$totals['num_tickets'] += $row['num_tickets'];
$totals['all_replies'] += $row['all_replies'];
$totals['staff_replies'] += $row['staff_replies'];
$totals['worked'] += $row['seconds_worked'];
}
// Get number of resolved tickets
$res = hesk_dbQuery("SELECT COUNT(*) AS `num_tickets` , `category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `status` = '3' " . ( $can_run_reports_full ? "" : " AND `owner` = '" . intval($_SESSION['id']) . "'" ) . " AND {$hesk_settings['dt_sql']} GROUP BY `category`");
// Update number of open and resolved tickets
while ($row = hesk_dbFetchAssoc($res))
{
if (isset($cat[$row['category']]))
{
$tickets[$row['category']]['resolved'] += $row['num_tickets'];
}
else
{
// Category deleted
$tickets[9999]['resolved'] += $row['num_tickets'];
}
$totals['resolved'] += $row['num_tickets'];
}
// Convert total seconds worked to HH:MM:SS
$totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
if ( isset($tickets[9999]) )
{
$tickets[9999]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($tickets[9999]['worked']) : 0;
}
?>
<div class="reports__table">
<table id="default-table" class="table sindu-table sindu_origin_table">
<thead>
<tr>
<th><?php echo $hesklang['category']; ?></th>
<th><?php echo $hesklang['tickets']; ?></th>
<th><?php echo $hesklang['topen']; ?></th>
<th><?php echo $hesklang['closed']; ?></th>
<th><?php echo $hesklang['replies'] . ' (' . $hesklang['all'] .')'; ?></th>
<th><?php echo $hesklang['replies'] . ' (' . $hesklang['staff'] .')'; ?></th>
<?php
if ($hesk_settings['time_worked'])
{
echo '<th>'.$hesklang['ts'].'</th>';
}
?>
</tr>
</thead>
<?php
$num_tickets = count($tickets);
if ($num_tickets > 10)
{
?>
<tr>
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['num_tickets']; ?></b></td>
<td><b><?php echo $totals['num_tickets'] - $totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<td><b><?php echo $totals['all_replies']; ?></b></td>
<td><b><?php echo $totals['staff_replies']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
<?php
}
foreach ($tickets as $k => $d)
{
?>
<tr>
<td><?php echo $cat[$k]; ?></td>
<td><?php echo $d['num_tickets']; ?></td>
<td><?php echo $d['num_tickets']-$d['resolved']; ?></td>
<td><?php echo $d['resolved']; ?></td>
<td><?php echo $d['all_replies']; ?></td>
<td><?php echo $d['staff_replies']; ?></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td>'.$d['worked'].'</td>';
}
?>
</tr>
<?php
}
?>
<tr class="total">
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['num_tickets']; ?></b></td>
<td><b><?php echo $totals['num_tickets'] - $totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<td><b><?php echo $totals['all_replies']; ?></b></td>
<td><b><?php echo $totals['staff_replies']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
</table>
</div>
<?php
} // END hesk_ticketsByCategory
function hesk_ticketsByUser()
{
global $hesk_settings, $hesklang, $date_from, $date_to;
// Some variables we will need
$tickets = array();
$totals = array('asstickets' => 0, 'resolved' => 0, 'tickets' => 0, 'replies' => 0, 'worked' => 0, 'openedby' => 0);
// Get list of users
$admins = array();
// I. ADMINISTRATORS can view all users
if ($_SESSION['isadmin'] || hesk_checkPermission('can_run_reports_full', 0) )
{
// -> get list of users
$res = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `name` ASC");
// -> populate $admins and $tickets arrays
while ($row=hesk_dbFetchAssoc($res))
{
$admins[$row['id']] = $row['name'];
$tickets[$row['id']] = array(
'asstickets' => 0,
'resolved' => 0,
'tickets' => 0,
'replies' => 0,
'worked' => '',
'openedby' => 0,
);
}
// -> get list of tickets
$res = hesk_dbQuery("SELECT `owner`, COUNT(*) AS `cnt`".($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '')." FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` IN ('" . implode("','", array_keys($admins) ) . "') AND {$hesk_settings['dt_sql']} GROUP BY `owner`");
// -> update ticket list values
while ($row = hesk_dbFetchAssoc($res))
{
if ( ! $hesk_settings['time_worked'])
{
$row['seconds_worked'] = 0;
}
$tickets[$row['owner']]['asstickets'] += $row['cnt'];
$totals['asstickets'] += $row['cnt'];
$tickets[$row['owner']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
$totals['worked'] += $row['seconds_worked'];
}
// -> get list of resolved tickets
$res = hesk_dbQuery("SELECT `owner`, COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` IN ('" . implode("','", array_keys($admins) ) . "') AND `status`='3' AND {$hesk_settings['dt_sql']} GROUP BY `owner`");
// -> update resolved ticket list values
while ($row = hesk_dbFetchAssoc($res))
{
$tickets[$row['owner']]['resolved'] += $row['cnt'];
$totals['resolved'] += $row['cnt'];
}
// -> get number of replies
$res = hesk_dbQuery("SELECT `staffid`, COUNT(*) AS `cnt`, COUNT(DISTINCT `replyto`) AS `tcnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `staffid` IN ('" . implode("','", array_keys($admins) ) . "') AND {$hesk_settings['dt_sql']} GROUP BY `staffid`");
// -> update number of replies values
while ($row = hesk_dbFetchAssoc($res))
{
$tickets[$row['staffid']]['tickets'] += $row['tcnt'];
$tickets[$row['staffid']]['replies'] += $row['cnt'];
$totals['tickets'] += $row['tcnt'];
$totals['replies'] += $row['cnt'];
}
}
// II. OTHER STAFF may only see their own stats
else
{
$admins[$_SESSION['id']] = $_SESSION['name'];
// -> get list of tickets
$res = hesk_dbQuery("SELECT COUNT(*) AS `cnt`".($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '')." FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` = '" . intval($_SESSION['id']) . "' AND {$hesk_settings['dt_sql']}");
$row = hesk_dbFetchAssoc($res);
// -> update ticket values
$tickets[$_SESSION['id']]['asstickets'] = $row['cnt'];
$totals['asstickets'] = $row['cnt'];
$tickets[$_SESSION['id']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
$totals['worked'] += $row['seconds_worked'];
// -> get list of resolved tickets
$res = hesk_dbQuery("SELECT COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` = '" . intval($_SESSION['id']) . "' AND `status`='3' AND {$hesk_settings['dt_sql']}");
$row = hesk_dbFetchAssoc($res);
// -> update resolved ticket values
$tickets[$_SESSION['id']]['resolved'] = $row['cnt'];
$totals['resolved'] = $row['cnt'];
// -> get number of replies
$res = hesk_dbQuery("SELECT COUNT(*) AS `cnt`, COUNT(DISTINCT `replyto`) AS `tcnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `staffid` = '" . intval($_SESSION['id']) . "' AND {$hesk_settings['dt_sql']}");
$row = hesk_dbFetchAssoc($res);
$tickets[$_SESSION['id']]['tickets'] = $row['tcnt'];
$tickets[$_SESSION['id']]['replies'] = $row['cnt'];
$totals['tickets'] = $row['tcnt'];
$totals['replies'] = $row['cnt'];
}
// Convert total seconds worked to HH:MM:SS
$totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
// Get total opened by tickets
$res = hesk_dbQuery("SELECT `openedby`, COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `openedby` IN ('" . implode("','", array_keys($admins) ) . "') AND DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `openedby`");
// -> update ticket list values
while ($row = hesk_dbFetchAssoc($res))
{
$tickets[$row['openedby']]['openedby'] += $row['cnt'];
$totals['openedby'] += $row['cnt'];
}
?>
<div class="reports__table">
<table id="default-table" class="table sindu-table sindu_origin_table">
<thead>
<tr>
<th><?php echo $hesklang['user']; ?></th>
<th><?php echo $hesklang['numsub']; ?></th>
<th><?php echo $hesklang['ticass']; ?></th>
<th><?php echo $hesklang['topen']; ?></th>
<th><?php echo $hesklang['closed']; ?></th>
<th><?php echo $hesklang['ticall']; ?></th>
<th><?php echo $hesklang['replies']; ?></th>
<?php
if ($hesk_settings['time_worked'])
{
echo '<th>'.$hesklang['ts'].'</th>';
}
?>
</tr>
</thead>
<?php
$num_tickets = count($tickets);
if ($num_tickets > 10)
{
?>
<tr>
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['openedby']; ?></b></td>
<td><b><?php echo $totals['asstickets']; ?></b></td>
<td><b><?php echo $totals['asstickets']-$totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<td><b><?php echo $totals['tickets']; ?></b></td>
<td><b><?php echo $totals['replies']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
<?php
}
foreach ($tickets as $k => $d)
{
?>
<tr>
<td><?php echo $admins[$k]; ?></td>
<td><?php echo $d['openedby']; ?></td>
<td><?php echo $d['asstickets']; ?></td>
<td><?php echo $d['asstickets']-$d['resolved']; ?></td>
<td><?php echo $d['resolved']; ?></td>
<td><?php echo $d['tickets']; ?></td>
<td><?php echo $d['replies']; ?></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td>'.$d['worked'].'</td>';
}
?>
</tr>
<?php
}
?>
<tr class="total">
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['openedby']; ?></b></td>
<td><b><?php echo $totals['asstickets']; ?></b></td>
<td><b><?php echo $totals['asstickets']-$totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<td><b><?php echo $totals['tickets']; ?></b></td>
<td><b><?php echo $totals['replies']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
</table>
</div>
<?php
} // END hesk_ticketsByUser
function hesk_ticketsByMonth()
{
global $hesk_settings, $hesklang, $date_from, $date_to, $can_run_reports_full;
$tickets = array();
$totals = array('all' => 0, 'resolved' => 0, 'worked' => 0);
$dt = MonthsArray($date_from,$date_to);
// Pre-populate date values
foreach ($dt as $month)
{
$tickets[$month] = array(
'all' => 0,
'resolved' => 0,
'worked' => '',
);
}
// SQL query for all
$res = hesk_dbQuery("SELECT YEAR(`dt`) AS `myyear`, MONTH(`dt`) AS `mymonth`, COUNT(*) AS `cnt`".($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '')." FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE " . ( $can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'" ) . " AND {$hesk_settings['dt_sql']} GROUP BY `myyear`,`mymonth`");
// Update ticket values
while ($row = hesk_dbFetchAssoc($res))
{
if ( ! $hesk_settings['time_worked'])
{
$row['seconds_worked'] = 0;
}
$row['mymonth'] = sprintf('%02d',$row['mymonth']);
$tickets[$row['myyear'].'-'.$row['mymonth'].'-01']['all'] += $row['cnt'];
$tickets[$row['myyear'].'-'.$row['mymonth'].'-01']['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
$totals['all'] += $row['cnt'];
$totals['worked'] += $row['seconds_worked'];
}
// SQL query for resolved
$res = hesk_dbQuery("SELECT YEAR(`dt`) AS `myyear`, MONTH(`dt`) AS `mymonth`, COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE " . ( $can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'" ) . " AND `status` = '3' AND {$hesk_settings['dt_sql']} GROUP BY `myyear`,`mymonth`");
// Update ticket values
while ($row = hesk_dbFetchAssoc($res))
{
$row['mymonth'] = sprintf('%02d',$row['mymonth']);
$tickets[$row['myyear'].'-'.$row['mymonth'].'-01']['resolved'] += $row['cnt'];
$totals['resolved'] += $row['cnt'];
}
// Convert total seconds worked to HH:MM:SS
$totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
?>
<div class="reports__table">
<table id="default-table" class="table sindu-table sindu_origin_table">
<thead>
<tr>
<th><?php echo $hesklang['month']; ?></th>
<th><?php echo $hesklang['atik']; ?></th>
<th><?php echo $hesklang['topen']; ?></th>
<th><?php echo $hesklang['closed']; ?></th>
<?php
if ($hesk_settings['time_worked'])
{
echo '<th>'.$hesklang['ts'].'</th>';
}
?>
</tr>
</thead>
<?php
$num_tickets = count($tickets);
if ($num_tickets > 10)
{
?>
<tr>
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['all']; ?></b></td>
<td><b><?php echo $totals['all']-$totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
<?php
}
foreach ($tickets as $k => $d)
{
?>
<tr>
<td><?php echo hesk_dateToString($k,0,0,1); ?></td>
<td><?php echo $d['all']; ?></td>
<td><?php echo $d['all']-$d['resolved']; ?></td>
<td><?php echo $d['resolved']; ?></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td>'.$d['worked'].'</td>';
}
?>
</tr>
<?php
}
?>
<tr class="total">
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['all']; ?></b></td>
<td><b><?php echo $totals['all']-$totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
</table>
</div>
<?php
} // END hesk_ticketsByMonth
function hesk_ticketsByDay()
{
global $hesk_settings, $hesklang, $date_from, $date_to, $can_run_reports_full;
$tickets = array();
$totals = array('all' => 0, 'resolved' => 0, 'worked' => 0);
$dt = DateArray($date_from,$date_to);
// Pre-populate date values
foreach ($dt as $day)
{
$tickets[$day] = array(
'all' => 0,
'resolved' => 0,
'worked' => '',
);
}
// SQL query for all
$res = hesk_dbQuery("SELECT DATE(`dt`) AS `mydt`, COUNT(*) AS `cnt`".($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '')." FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE " . ( $can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'" ) . " AND {$hesk_settings['dt_sql']} GROUP BY `mydt`");
// Update ticket values
while ($row = hesk_dbFetchAssoc($res))
{
if ( ! $hesk_settings['time_worked'])
{
$row['seconds_worked'] = 0;
}
$tickets[$row['mydt']]['all'] += $row['cnt'];
$tickets[$row['mydt']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
$totals['all'] += $row['cnt'];
$totals['worked'] += $row['seconds_worked'];
}
// SQL query for resolved
$res = hesk_dbQuery("SELECT DATE(`dt`) AS `mydt`, COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE " . ( $can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'" ) . " AND `status`='3' AND {$hesk_settings['dt_sql']} GROUP BY `mydt`");
// Update ticket values
while ($row = hesk_dbFetchAssoc($res))
{
$tickets[$row['mydt']]['resolved'] += $row['cnt'];
$totals['resolved'] += $row['cnt'];
}
// Convert total seconds worked to HH:MM:SS
$totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
?>
<div class="reports__table">
<table id="default-table" class="table sindu-table sindu_origin_table">
<thead>
<tr>
<th><?php echo $hesklang['date']; ?></th>
<th><?php echo $hesklang['atik']; ?></th>
<th><?php echo $hesklang['topen']; ?></th>
<th><?php echo $hesklang['closed']; ?></th>
<?php
if ($hesk_settings['time_worked'])
{
echo '<th>'.$hesklang['ts'].'</th>';
}
?>
</tr>
</thead>
<?php
$num_tickets = count($tickets);
if ($num_tickets > 10)
{
?>
<tr>
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['all']; ?></b></td>
<td><b><?php echo $totals['all']-$totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
<?php
}
foreach ($tickets as $k => $d)
{
?>
<tr>
<td><?php echo hesk_dateToString($k); ?></td>
<td><?php echo $d['all']; ?></td>
<td><?php echo $d['all']-$d['resolved']; ?></td>
<td><?php echo $d['resolved']; ?></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td>'.$d['worked'].'</td>';
}
?>
</tr>
<?php
}
?>
<tr class="total">
<td><b><?php echo $hesklang['totals']; ?></b></td>
<td><b><?php echo $totals['all']; ?></b></td>
<td><b><?php echo $totals['all']-$totals['resolved']; ?></b></td>
<td><b><?php echo $totals['resolved']; ?></b></td>
<?php
if ($hesk_settings['time_worked'])
{
echo '<td><b>'.$totals['worked'].'</b></td>';
}
?>
</tr>
</table>
</div>
<?php
} // END hesk_ticketsByDay
?>
</div>

View File

@@ -0,0 +1,144 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'inc/email_functions.inc.php');
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_view_tickets');
// A security check
hesk_token_check('POST');
// Ticket ID
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
// Ticket details
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['ticket_not_found']);
}
$ticket = hesk_dbFetchAssoc($res);
// Do we have permission to view this ticket?
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'] && ! hesk_checkPermission('can_view_unassigned',0))
{
hesk_error($hesklang['ycovtay']);
}
// Is this user allowed to view tickets inside this category?
hesk_okCategory($ticket['category']);
// Reply or original message?
$reply_id = intval( hesk_GET('reply', 0) );
if ($reply_id > 0)
{
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `id`={$reply_id} AND `replyto`=".intval($ticket['id'])." LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['ernf']);
}
$reply = hesk_dbFetchAssoc($result);
$ticket['message'] = $reply['message'];
}
/* --> 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);
// Notification of a reply
if ($reply_id > 0)
{
// Reply by staff, send notification to customer
if ($reply['staffid'])
{
hesk_notifyCustomer('new_reply_by_staff');
}
// Reply by customer, notify assigned staff?
elseif ($ticket['owner'])
{
hesk_notifyAssignedStaff(false, 'new_reply_by_customer', 'notify_reply_my');
}
// Reply by customer, notify staff
else
{
hesk_notifyStaff('new_reply_by_customer',"`notify_reply_unassigned`='1'");
}
hesk_process_messages($hesklang['rns'],'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');
}
// Notification of the original ticket
hesk_notifyCustomer();
// Notify staff?
if ($ticket['owner'])
{
hesk_notifyAssignedStaff(false, 'ticket_assigned_to_you');
}
else
{
hesk_notifyStaff('new_ticket_staff', "`notify_new_unassigned`='1'");
}
hesk_process_messages($hesklang['tns'],'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS');

View File

@@ -0,0 +1,663 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
/* Check permissions for this feature */
hesk_checkPermission('can_service_msg');
// Define required constants
define('LOAD_TABS',1);
define('WYSIWYG',1);
// Do we need to show the language options?
$hesk_settings['show_language'] = (count($hesk_settings['languages']) > 1);
// What should we do?
if ( $action = hesk_REQUEST('a') )
{
if ($action == 'edit_sm') {edit_sm();}
elseif ( defined('HESK_DEMO') ) {hesk_process_messages($hesklang['ddemo'], 'service_messages.php', 'NOTICE');}
elseif ($action == 'new_sm') {new_sm();}
elseif ($action == 'save_sm') {save_sm();}
elseif ($action == 'order_sm') {order_sm();}
elseif ($action == 'remove_sm') {remove_sm();}
}
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print main manage users page */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
/* This will handle error, success and notice messages */
if (!hesk_SESSION(array('new_sm', 'errors'))) {
hesk_handle_messages();
}
// Get service messages from database
$res = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'service_messages` ORDER BY `order` ASC');
$num = hesk_dbNumRows($res);
?>
<div class="main__content tools">
<section class="tools__between-head">
<h2><?php echo $hesklang['sm_title']; ?></h2>
<?php if ($action !== 'edit_sm' && !isset($_SESSION['preview_sm'])): ?>
<div class="btn btn--blue-border" ripple="ripple" data-action="create-service-message"><?php echo $hesklang['new_sm']; ?></div>
<?php endif;?>
</section>
<div class="table-wrapper service-message">
<div class="table">
<table id="default-table" class="table sindu-table">
<thead>
<tr>
<th><?php echo $hesklang['sm_mtitle']; ?></th>
<th><?php echo $hesklang['sm_style']; ?></th>
<?php
if ($hesk_settings['show_language'])
{
?>
<th><?php echo $hesklang['lgs']; ?></th>
<?php
}
?>
<th><?php echo $hesklang['sm_author']; ?></th>
<th><?php echo $hesklang['sm_type']; ?></th>
<th></th>
</tr>
</thead>
<tbody>
<?php if ($num < 1): ?>
<tr>
<td colspan="<?php echo $hesk_settings['show_language'] ? 2 : 1; ?>">
<?php echo $hesklang['no_sm']; ?>
</td>
</tr>
<?php
else:
// List of staff
if (!isset($admins)) {
$admins = array();
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users`");
while ($row=hesk_dbFetchAssoc($res2))
{
$admins[$row['id']]=$row['name'];
}
}
$k = 1;
while ($sm=hesk_dbFetchAssoc($res)) {
switch ($sm['style']) {
case 1:
$sm_style = "success";
break;
case 2:
$sm_style = "info";
break;
case 3:
$sm_style = "notice";
break;
case 4:
$sm_style = "error";
break;
default:
$sm_style = "none";
}
$table_row = '';
if (isset($_SESSION['smord']) && $_SESSION['smord'] == $sm['id']) {
$table_row = 'class="ticket-new"';
unset($_SESSION['smord']);
}
$type = $sm['type'] ? $hesklang['sm_draft']: $hesklang['sm_published'];
?>
<tr <?php echo $table_row; ?>>
<td><?php echo $sm['title']; ?></td>
<td>
<div class="style <?php echo $sm_style; ?>">
<?php echo $hesklang['sm_' . $sm_style]; ?>
</div>
</td>
<?php
if ($hesk_settings['show_language'])
{
?>
<td><?php echo strlen($sm['language']) ? $sm['language'] : $hesklang['all']; ?></td>
<?php
}
?>
<td><?php echo (isset($admins[$sm['author']]) ? $admins[$sm['author']] : $hesklang['e_udel']); ?></td>
<td><?php echo $type; ?></td>
<td class="nowrap buttons">
<?php $modal_id = hesk_generate_delete_modal($hesklang['confirm_deletion'],
$hesklang['del_sm'],
'service_messages.php?a=remove_sm&amp;id='. $sm['id'] .'&amp;token='. hesk_token_echo(0)); ?>
<p>
<?php
if ($num > 1)
{
if ($k == 1)
{
?>
<a href="#" style="visibility: hidden">
<svg class="icon icon-chevron-up">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_dn']; ?>">
<svg class="icon icon-chevron-down">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<?php
}
elseif ($k == $num)
{
?>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=-15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_up']; ?>">
<svg class="icon icon-chevron-up">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="#" style="visibility: hidden"
title="<?php echo $hesklang['move_dn']; ?>">
<svg class="icon icon-chevron-down">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<?php
}
else
{
?>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=-15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_up']; ?>">
<svg class="icon icon-chevron-up">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<a href="service_messages.php?a=order_sm&amp;id=<?php echo $sm['id']; ?>&amp;move=15&amp;token=<?php hesk_token_echo(); ?>"
title="<?php echo $hesklang['move_dn']; ?>">
<svg class="icon icon-chevron-down">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-chevron-down"></use>
</svg>
</a>
<?php
}
}
?>
<a href="service_messages.php?a=edit_sm&amp;id=<?php echo $sm['id']; ?>" class="edit" title="<?php echo $hesklang['edit']; ?>">
<svg class="icon icon-edit-ticket">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-edit-ticket"></use>
</svg>
</a>
<a href="javascript:" class="delete" title="<?php echo $hesklang['delete']; ?>" data-modal="[data-modal-id='<?php echo $modal_id; ?>']">
<svg class="icon icon-delete">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-delete"></use>
</svg>
</a>
</p>
</td>
</tr>
<?php
$k++;
} // End while
?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php
if ($hesk_settings['kb_wysiwyg'])
{
?>
<script>
tinymce.init({
selector: '#content',
convert_urls: false,
branding: false,
browser_spellcheck: true,
toolbar: 'undo redo | styleselect fontselect fontsizeselect | bold italic underline | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist outdent indent | link unlink image codesample code',
plugins: 'charmap code codesample image link lists table',
});
</script>
<?php
}
?>
<div class="right-bar service-message-create" <?php if ($action === 'edit_sm' || isset($_SESSION['preview_sm']) || hesk_SESSION(array('new_sm','errors'))) {echo 'style="display: block"';} ?>>
<div class="right-bar__body form" data-step="1">
<h3 class="">
<a href="<?php echo $action === 'edit_sm' || isset($_SESSION['preview_sm']) ? 'service_messages.php' : 'javascript:' ?>">
<svg class="icon icon-back">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-back"></use>
</svg>
<span><?php echo hesk_SESSION('edit_sm') ? $hesklang['edit_sm'] : $hesklang['new_sm']; ?></span>
</a>
</h3>
<?php
if (hesk_SESSION(array('new_sm', 'errors'))) {
hesk_handle_messages();
}
/* Do we have a service message to preview? */
if (isset($_SESSION['preview_sm'])) {
hesk_service_message($_SESSION['new_sm']);
}
?>
<ul class="step-bar">
<li data-link="1" data-all="2"><?php echo $hesklang['sm_content']; ?></li>
<li data-link="2" data-all="2"><?php echo $hesklang['sm_settings']; ?></li>
</ul>
<form action="service_messages.php" method="post" name="form1" class="form <?php echo hesk_SESSION(array('new_sm','errors')) ? 'invalid' : ''; ?>">
<div class="step-slider">
<div class="step-item step-1">
<div class="form-group">
<label for="sm-title"><?php echo $hesklang['sm_mtitle']; ?></label>
<input id="sm-title" type="text" name="title" class="form-control <?php echo in_array('title', hesk_SESSION(array('new_sm','errors'))) ? 'isError' : ''; ?>" maxlength="255" <?php if (isset($_SESSION['new_sm']['title'])) {echo 'value="'.$_SESSION['new_sm']['title'].'"';} ?>>
</div>
<div class="form-group" style="width: 100%">
<label for="content"><?php echo $hesklang['sm_msg']; ?></label>
<textarea class="form-control" name="message" id="content" style="height: 300px;"><?php if (isset($_SESSION['new_sm']['message'])) {echo $_SESSION['new_sm']['message'];} ?></textarea>
</div>
</div>
<div class="step-item step-2">
<h4><?php echo $hesklang['sm_style']; ?></h4>
<div class="styles__radio">
<label class="none">
<input type="radio" value="0" name="style" <?php if (!isset($_SESSION['new_sm']['style']) || (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 0) ) {echo 'checked';} ?>>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
<span><?php echo $hesklang['sm_none']; ?></span>
</label>
<label class="success">
<input type="radio" value="1" name="style" <?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 1 ) {echo 'checked';} ?>>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
<span><?php echo $hesklang['sm_success']; ?></span>
</label>
<label class="info">
<input type="radio" value="2" name="style" <?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 2) {echo 'checked';} ?>>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
<span><?php echo $hesklang['sm_info']; ?></span>
</label>
<label class="notice">
<input type="radio" value="3" name="style" <?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 3) {echo 'checked';} ?>>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
<span><?php echo $hesklang['sm_notice']; ?></span>
</label>
<label class="error">
<input type="radio" value="4" name="style" <?php if (isset($_SESSION['new_sm']['style']) && $_SESSION['new_sm']['style'] == 4) {echo 'checked';} ?>>
<svg class="icon icon-tick">
<use xlink:href="<?php echo HESK_PATH; ?>img/sprite.svg#icon-tick"></use>
</svg>
<span><?php echo $hesklang['sm_error']; ?></span>
</label>
</div>
<section class="param">
<span><?php echo $hesklang['sm_type']; ?></span>
<div class="dropdown-select center out-close">
<select name="type">
<option value="0" <?php if (!isset($_SESSION['new_sm']['type']) || (isset($_SESSION['new_sm']['type']) && $_SESSION['new_sm']['type'] == 0) ) {echo 'selected="selected"';} ?>>
<?php echo $hesklang['sm_published']; ?>
</option>
<option value="1" <?php if (isset($_SESSION['new_sm']['type']) && $_SESSION['new_sm']['type'] == 1) {echo 'selected="selected"';} ?>>
<?php echo $hesklang['sm_draft']; ?>
</option>
</select>
</div>
</section>
<?php if ($hesk_settings['show_language']): ?>
<section class="param">
<span><?php echo $hesklang['lgs']; ?></span>
<div class="dropdown-select center out-close">
<select name="language">
<option value=""><?php echo $hesklang['all']; ?></option>
<?php foreach ($hesk_settings['languages'] as $lang => $v): ?>
<option <?php echo (isset($_SESSION['new_sm']['language']) && $_SESSION['new_sm']['language'] == $lang ? 'selected="selected"' : ''); ?>>
<?php echo $lang; ?>
</option>
<?php endforeach; ?>
</select>
</div>
</section>
<?php endif; ?>
</div>
</div>
<div class="right-bar__footer">
<button type="button" class="btn btn-border" ripple="ripple" data-action="back"><?php echo $hesklang['wizard_back']; ?></button>
<button type="button" class="btn btn-full next" data-action="next" ripple="ripple"><?php echo $hesklang['sm_go_to_settings']; ?></button>
<?php if (isset($_SESSION['edit_sm'])): ?>
<input type="hidden" name="a" value="save_sm" />
<input type="hidden" name="id" value="<?php echo intval($_SESSION['new_sm']['id']); ?>" />
<?php else: ?>
<input type="hidden" name="a" value="new_sm" />
<?php endif; ?>
<button type="submit" name="sm_preview" class="btn btn-border preview" ripple="ripple"><?php echo $hesklang['sm_preview']; ?></button>
<button type="submit" name="sm_save" class="btn btn-full save" ripple="ripple"><?php echo $hesklang['sm_save']; ?></button>
<input type="hidden" name="token" value="<?php hesk_token_echo(); ?>" />
</div>
</form>
</div>
</div>
<?php
if ( isset($_SESSION['new_sm']) && ! isset($_SESSION['edit_sm']) )
{
$_SESSION['new_sm'] = hesk_stripArray($_SESSION['new_sm']);
}
hesk_cleanSessionVars( array('new_sm', 'preview_sm', 'edit_sm') );
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
/*** START FUNCTIONS ***/
function save_sm()
{
global $hesk_settings, $hesklang, $listBox;
global $hesk_error_buffer;
// A security check
# hesk_token_check('POST');
$hesk_error_buffer = array();
// Get service messageID
$id = intval( hesk_POST('id') ) or hesk_error($hesklang['sm_e_id']);
$style = intval( hesk_POST('style', 0) );
if ($style > 4 || $style < 0)
{
$style = 0;
}
$type = empty($_POST['type']) ? 0 : 1;
$title = hesk_input( hesk_POST('title') ) or $hesk_error_buffer[] = $hesklang['sm_e_title'];
$message = hesk_getHTML( hesk_POST('message') );
// Clean the HTML code
require(HESK_PATH . 'inc/htmlpurifier/HeskHTMLPurifier.php');
$purifier = new HeskHTMLPurifier($hesk_settings['cache_dir']);
$message = $purifier->heskPurify($message);
// Any errors?
if (count($hesk_error_buffer))
{
$_SESSION['edit_sm'] = true;
$_SESSION['new_sm'] = array(
'id' => $id,
'style' => $style,
'type' => $type,
'title' => $title,
'message' => hesk_input( hesk_POST('message') ),
'errors' => array('title')
);
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'service_messages.php');
}
// Just preview the message?
if ( isset($_POST['sm_preview']) )
{
$_SESSION['preview_sm'] = true;
$_SESSION['edit_sm'] = true;
$_SESSION['new_sm'] = array(
'id' => $id,
'style' => $style,
'type' => $type,
'title' => $title,
'message' => $message
);
header('Location: service_messages.php');
exit;
}
// Update the service message in the database
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` SET
`author` = '".intval($_SESSION['id'])."',
`title` = '".hesk_dbEscape($title)."',
`message` = '".hesk_dbEscape($message)."',
`style` = '{$style}',
`type` = '{$type}'
WHERE `id`={$id}");
$_SESSION['smord'] = $id;
hesk_process_messages($hesklang['sm_mdf'],'service_messages.php','SUCCESS');
} // End save_sm()
function edit_sm()
{
global $hesk_settings, $hesklang;
// Get service messageID
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['sm_e_id']);
// Get details from the database
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` WHERE `id`={$id} LIMIT 1");
if ( hesk_dbNumRows($res) != 1 )
{
hesk_error($hesklang['sm_not_found']);
}
$sm = hesk_dbFetchAssoc($res);
$_SESSION['smord'] = $id;
$_SESSION['new_sm'] = $sm;
$_SESSION['edit_sm'] = true;
} // End edit_sm()
function order_sm()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get ID and move parameters
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['sm_e_id']);
$move = intval( hesk_GET('move') );
$_SESSION['smord'] = $id;
// Update article details
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` SET `order`=`order`+".intval($move)." WHERE `id`={$id}");
// Update order of all service messages
update_sm_order();
$_SESSION['smord'] = $id;
// Finish
header('Location: service_messages.php');
exit();
} // End order_sm()
function update_sm_order()
{
global $hesk_settings, $hesklang;
// Get list of current service messages
$res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` ORDER BY `order` ASC");
// Update database
$i = 10;
while ( $sm = hesk_dbFetchAssoc($res) )
{
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` SET `order`=".intval($i)." WHERE `id`='".intval($sm['id'])."'");
$i += 10;
}
return true;
} // END update_sm_order()
function remove_sm()
{
global $hesk_settings, $hesklang;
// A security check
hesk_token_check();
// Get ID
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['sm_e_id']);
// Delete the service message
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` WHERE `id`={$id}");
// Were we successful?
if ( hesk_dbAffectedRows() == 1 )
{
hesk_process_messages($hesklang['sm_deleted'],'./service_messages.php','SUCCESS');
}
else
{
hesk_process_messages($hesklang['sm_not_found'],'./service_messages.php');
}
} // End remove_sm()
function new_sm()
{
global $hesk_settings, $hesklang, $listBox;
global $hesk_error_buffer;
// A security check
# hesk_token_check('POST');
$hesk_error_buffer = array();
$style = intval( hesk_POST('style', 0) );
if ($style > 4 || $style < 0)
{
$style = 0;
}
$type = empty($_POST['type']) ? 0 : 1;
$language = hesk_input( hesk_POST('language') );
if ( ! isset($hesk_settings['languages'][$language]))
{
$language = '';
}
$title = hesk_input( hesk_POST('title') ) or $hesk_error_buffer[] = $hesklang['sm_e_title'];
$message = hesk_getHTML( hesk_POST('message') );
// Clean the HTML code
require(HESK_PATH . 'inc/htmlpurifier/HeskHTMLPurifier.php');
$purifier = new HeskHTMLPurifier($hesk_settings['cache_dir']);
$message = $purifier->heskPurify($message);
// Any errors?
if (count($hesk_error_buffer))
{
$_SESSION['new_sm'] = array(
'style' => $style,
'type' => $type,
'language' => $language,
'title' => $title,
'message' => hesk_input( hesk_POST('message') ),
'errors' => array('title')
);
$tmp = '';
foreach ($hesk_error_buffer as $error)
{
$tmp .= "<li>$error</li>\n";
}
$hesk_error_buffer = $tmp;
$hesk_error_buffer = $hesklang['rfm'].'<br /><br /><ul>'.$hesk_error_buffer.'</ul>';
hesk_process_messages($hesk_error_buffer,'service_messages.php');
}
// Just preview the message?
if ( isset($_POST['sm_preview']) )
{
$_SESSION['preview_sm'] = true;
$_SESSION['new_sm'] = array(
'style' => $style,
'type' => $type,
'language' => $language,
'title' => $title,
'message' => $message,
);
header('Location: service_messages.php');
exit;
}
// Get the latest service message order
$res = hesk_dbQuery("SELECT `order` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` ORDER BY `order` DESC LIMIT 1");
$row = hesk_dbFetchRow($res);
$my_order = isset($row[0]) ? intval($row[0]) + 10 : 10;
// Insert service message into database
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` (`author`,`title`,`message`,`language`,`style`,`type`,`order`) VALUES (
'".intval($_SESSION['id'])."',
'".hesk_dbEscape($title)."',
'".hesk_dbEscape($message)."',
".(strlen($language) ? "'".hesk_dbEscape($language)."'" : 'NULL').",
'{$style}',
'{$type}',
'{$my_order}'
)");
$_SESSION['smord'] = hesk_dbInsertID();
hesk_process_messages($hesklang['sm_added'],'service_messages.php','SUCCESS');
} // End new_sm()
?>

View File

@@ -0,0 +1,84 @@
<?php
/**
*
* This file is part of HESK - PHP Help Desk Software.
*
* (c) Copyright Klemen Stirn. All rights reserved.
* https://www.hesk.com
*
* For the full copyright and license agreement information visit
* https://www.hesk.com/eula.php
*
*/
define('IN_SCRIPT',1);
define('HESK_PATH','../');
/* Get all the required files and functions */
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
define('CALENDAR',1);
define('AUTO_RELOAD',1);
/* Check permissions for this feature */
hesk_checkPermission('can_view_tickets');
/* Print header */
require_once(HESK_PATH . 'inc/header.inc.php');
/* Print admin navigation */
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
?>
<div class="main__content tickets">
<div style="margin-left: -16px; margin-right: -24px;">
<?php
/* This will handle error, success and notice messages */
hesk_handle_messages();
?>
</div>
<?php
$header_text = '
<section style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px">
<h2 style="font-size: 18px; font-weight: bold">'. $hesklang['tickets'] .' (%%HESK_TICKET_COUNT%%)</h2>
<div class="checkbox-custom">
<input type="checkbox" id="reloadCB" onclick="toggleAutoRefresh(this);">
<label for="reloadCB">'. $hesklang['arp'] .'</label>&nbsp;<span id="timer"></span>
<script type="text/javascript">heskCheckReloading();</script>
</div>
</section>';
/* Print the list of tickets */
$is_search = 1;
require_once(HESK_PATH . 'inc/print_tickets.inc.php');
/* Update staff default settings? */
if ( ! empty($_GET['def']))
{
hesk_updateStaffDefaults();
}
?>
&nbsp;<br />
<?php
/* Print forms for listing and searching tickets */
require_once(HESK_PATH . 'inc/show_search_form.inc.php');
?>
<p>&nbsp;</p>
<?php
/* Print footer */
require_once(HESK_PATH . 'inc/footer.inc.php');
exit();
?>

View File

@@ -0,0 +1,110 @@
<?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/setup_functions.inc.php');
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_load_database_functions();
hesk_session_start();
hesk_dbConnect();
hesk_isLoggedIn();
// Check permissions for this feature
hesk_checkPermission('can_man_settings');
// Demo mode?
if ( defined('HESK_DEMO') )
{
hesk_show_notice($hesklang['ddemo']);
exit();
}
// Test type?
$test_type = hesk_POST('test');
// Test MySQL connection
if ($test_type == 'mysql')
{
if ( hesk_testMySQL() )
{
hesk_show_success($hesklang['conok']);
}
elseif ( ! empty($mysql_log) )
{
hesk_show_error($mysql_error . '<br /><br /><b>' . $hesklang['mysql_said'] . ':</b> ' . $mysql_log);
}
else
{
hesk_show_error($mysql_error);
}
}
// Test POP3 connection
elseif ($test_type == 'pop3')
{
if ( hesk_testPOP3() )
{
hesk_show_success($hesklang['conok']);
}
else
{
hesk_show_error( $pop3_error . '<br /><br /><textarea name="pop3_log" rows="10" cols="60">' . $pop3_log . '</textarea>' );
}
}
// Test SMTP connection
elseif ($test_type == 'smtp')
{
if ( hesk_testSMTP() )
{
// If no username/password add a notice
if ($set['smtp_user'] == '' && $set['smtp_user'] == '')
{
$hesklang['conok'] .= '<br /><br />' . $hesklang['conokn'];
}
hesk_show_success($hesklang['conok']);
}
else
{
hesk_show_error( $smtp_error . '<br /><br /><textarea name="smtp_log" rows="10" cols="60">' . $smtp_log . '</textarea>' );
}
}
// Test IMAP connection
elseif ($test_type == 'imap')
{
if ( hesk_testIMAP() )
{
hesk_show_success($hesklang['conok']);
}
else
{
hesk_show_error( $imap_error . '<br /><br /><textarea name="imap_log" rows="10" cols="60">' . $imap_log . '</textarea>' );
}
}
// Not a valid test...
else
{
die($hesklang['attempt']);
}
exit();
?>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>403 Forbidden</TITLE>
</HEAD><BODY>
<H1>Forbidden</H1>
You don't have permission to access this folder.<P>
<hr />
</BODY></HTML>

8
hesk/cache/index.htm vendored Normal file
View File

@@ -0,0 +1,8 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>403 Forbidden</TITLE>
</HEAD><BODY>
<H1>Forbidden</H1>
You don't have permission to access this folder.<P>
<hr />
</BODY></HTML>

132
hesk/change_status.php Normal file
View File

@@ -0,0 +1,132 @@
<?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');
// Are we in maintenance mode?
hesk_check_maintenance();
hesk_load_database_functions();
hesk_session_start();
// A security check
hesk_token_check();
// Get the tracking ID
$trackingID = hesk_cleanID() or die("$hesklang[int_error]: $hesklang[no_trackID]");
// Get new status
$status = intval( hesk_GET('s', 0) );
$locked = 0;
if ($status == 3) // Closed
{
// Is customer closing tickets enabled?
if ( ! $hesk_settings['custclose'])
{
hesk_error($hesklang['attempt']);
}
$action = $hesklang['closed'];
$revision = sprintf($hesklang['thist3'],hesk_date(),$hesklang['customer']);
if ($hesk_settings['custopen'] != 1)
{
$locked = 1;
}
// Mark that customer resolved the ticket
$closedby_sql = ' , `closedat`=NOW(), `closedby`=0 ';
}
elseif ($status == 2) // Opened
{
// Is customer reopening tickets enabled?
if ( ! $hesk_settings['custopen'])
{
hesk_error($hesklang['attempt']);
}
$action = $hesklang['opened'];
$revision = sprintf($hesklang['thist4'],hesk_date(),$hesklang['customer']);
// We will ask the customer why is the ticket being reopened
$_SESSION['force_form_top'] = true;
// Ticket is not resolved
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
}
else
{
die("$hesklang[int_error]: $hesklang[status_not_valid].");
}
// Connect to database
hesk_dbConnect();
// Verify email address match if needed
hesk_verifyEmailMatch($trackingID);
// Setup required session vars
$_SESSION['t_track'] = $trackingID;
$_SESSION['t_email'] = $hesk_settings['e_email'];
// Load statuses
require_once(HESK_PATH . 'inc/statuses.inc.php');
// Is current ticket status even changeable by customers?
$ticket = hesk_dbFetchAssoc( hesk_dbQuery( "SELECT `status`, `staffreplies`, `lastreplier` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1") );
if ( ! hesk_can_customer_change_status($ticket['status']))
{
hesk_process_messages($hesklang['scno'],'ticket.php');
}
// Lets make status assignment a bit smarter when reopening tickets
if ($status == 2)
{
// If ticket has no staff replies set the status to "New"
if ($ticket['staffreplies'] < 1)
{
$status = 0;
}
// If last reply was by customer set status to "Waiting reply from staff"
elseif ($ticket['lastreplier'] == 0)
{
$status = 1;
}
// If nothing matches: last reply was from staff, keep status "Waiting reply from customer"
}
// Modify values in the database
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."' AND `locked` != '1'");
// Did we modify anything*
if (hesk_dbAffectedRows() != 1)
{
hesk_process_messages($hesklang['elocked'],'ticket.php');
}
// Show success message
if ($status != 3)
{
hesk_process_messages($hesklang['wrepo'],'ticket.php','NOTICE');
}
else
{
hesk_process_messages($hesklang['your_ticket_been'].' '.$action,'ticket.php','SUCCESS');
}

13363
hesk/css/app.css Normal file

File diff suppressed because it is too large Load Diff

1
hesk/css/app.min.css vendored Normal file

File diff suppressed because one or more lines are too long

655
hesk/docs/changelog.html Normal file
View File

@@ -0,0 +1,655 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>HESK - Changelog</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="docs_style.css" />
</head>
<body>
<div id="wrapper">
<div id="main">
<h1><span class="dest">HESK&trade;</span> PHP Help Desk Software</h1>
<table width="100%">
<tr>
<td width="50%" style="text-align:left;vertical-align:top">
<ul class="nobullets">
<li>Version: 3.0.0 from 17th February 2020</li>
<li>Developed by: Klemen Stirn, Mike Koch</li>
<li><a href="https://www.hesk.com">Help Desk Software HESK</a></li>
<li><a href="https://www.phpjunkyard.com">Free PHP Scripts</a></li>
</ul>
</td>
<td width="50%" style="text-align:right;vertical-align:top">
<ul class="nobullets">
<li><a href="index.html">HESK documentation</a></li>
<li><a href="step-by-step-guide.html">Step by step guide</a></li>
<li><a href="quick-guide.html">Quick guide</a></li>
<li><b>Changelog</b></li>
</ul>
</td>
</tr>
</table>
<div class="notice">
<p><b>Hey, you should probably read this...</b><p>
<p>HESK version 3 features a brand new user interface. While we consider it stable enough for use it is likely that we didn't spot all the errors across various browsers and devices.</p>
<p>We encourage you to report any problems and user-experience suggestions to our <a href="https://developers.phpjunkyard.com">support forum</a>.</p>
</div>
<h2>HESK CHANGELOG</h2>
<p><b>Changes in 3.0.0</b> - 17th February 2020<br />
- a brand new mobile-friendly user interface<br />
- built-in theme support for the public (customer) interface<br />
- fix: SQL error when trying to ban an invalid IP<br />
</p>
<p><b>Changes in 2.8.5</b> - 6th January 2020<br />
- PHP 7.4 compatibility<br />
- MySQL 8.0.13 compatibility<br />
- users with no can_reply_tickets permission can now create ticket notes<br />
- updated third party libraries to the latest version<br />
- fix: respect article order in Knowledgebase<br />
- fix: save email attachments sent as message content type<br />
- fix: better handle can_resolve and can_reply_tickets permissions<br />
</p>
<p><b>Changes in 2.8.4</b> - 17th August 2019<br />
- fix: modified the HTMLPurifier library to be compatible with PHP 5.3<br />
</p>
<p><b>Changes in 2.8.3</b> - 16th August 2019<br />
- fix: break long words when bulk printing tickets<br />
- fix: HTML-encoded chars can cause MySQL truncate error<br />
- fix: parse links with single quotes in HTML email to ticket<br />
- fix: wrong option for staff re-send notification of an assigned ticket<br />
- fix: in email to ticket inline attachments with no message are not imported correctly<br />
- fix: descriptive error message when post_max_size is exceeded for customer interface<br />
- fix: link to embedded image tags rather than deleting them<br />
- fix: no image in service messages list for style &quot;None&quot;<br >
- fix: pagination does not work when searching for tickets by owner<br />
- fix: workaround for a Microsoft DKIM verification bug<br />
</p>
<p><b>Changes in 2.8.2</b> - 5th July 2018<br />
- service messages can be set to display for a specific language only<br />
- fix: use div instead of span in print template for better browser compatibility<br />
- fix: double escaping in hesk_dbLike function may cause failed lookups<br />
- fix: some queries don't work in MySQL ONLY_FULL_GROUP_BY mode<br />
- fix: POP3 fetching EOF detection unreliable in newer PHP versions<br />
- fix: Message-ID header missing host name over CLI<br />
- fix: force hesk_mb_strtolower function to use UTF-8<br />
</p>
<p><b>Changes in 2.8.1</b> - 18th May 2018<br />
- fix: update assignedby column when doing bulk assignments<br />
- fix: add a unique Message-ID header to outgoing emails<br />
</p>
<p><b>Changes in 2.8.0</b> - 14th May 2018<br />
- removed PHP 7.2 depreciated functions<br />
- minimum required PHP version increased to 5.3<br />
- bulk assign tickets form the ticket list<br />
- bulk print tickets form the ticket list<br />
- added tools for anonymizing tickets<br />
- find tickets by customer IP address<br />
- added support for Invisible reCAPTCHA<br />
- removed reCAPTCHA V1 (discontinued by Google)<br />
- staff can re-send email notifications for tickets<br />
- dropped time difference calculation, using timezones<br />
- new staff permission: can view tickets he/she assigned others<br />
- export to Excel now works for individual and selected tickets<br />
- fix: IMAP fetching ticket history log shows POP3 fetching<br />
- fix: IMAP connection test fails if the password contains a backslash<br />
- disable IMAP fetching if PHP was compiled without IMAP support<br />
- warn if a user's email address matches the POP3/IMAP fetching address<br />
- notice if &quot;From:&quot; email doesn't match SMTP sever email address<br />
- new &quot;First name&quot; tag for email templates and canned responses<br />
- minor UI improvements (ticket action buttons)<br />
</p>
<p><b>Changes in 2.7.6</b> - 1st March 2018<br />
- improved handling of multiple emails in a ticket<br />
- changed a setting field name to avoid a mod_security false positive<br />
- fix: when editing a ticket, empty values should not be replaced with defaults<br />
- fix: URL in a custom text field breaks HTML on the edit ticket page<br />
- fix: removing duplicate recipients creates an issue in SMTP library<br />
- fix: knowledgebase category shouldn't have its child set as parent<br />
- fix: use multibyte functions for checking and limiting string length<br />
- fix: (strict mode) only variables should be passed by reference<br />
- fix: a non well formed numeric value notice in settings<br />
- updated third party libraries to the latest version<br />
</p>
<p><b>Changes in 2.7.5</b> - 25th November 2017<br />
- fix: old name and subject length limits in &quot;Edit ticket&quot;<br />
</p>
<p><b>Changes in 2.7.4</b> - 21st November 2017<br />
- new email tag %%TIME_WORKED%% shows time staff worked on a ticket<br />
- new email tag %%LAST_REPLY_BY%% shows name of the person who posted last ticket message<br />
- increased maxlength attribute for ticket name and subject to max supported in database (50 and 70)<br />
- improved few default email messages to avoid some spam filters marking them as &quot;linkbait&quot;<br />
- fix: move category not working correctly for users with no global submit permission<br />
- fix: if iconv is not available, attempt to use utf8_encode instead in email to ticket<br />
- fix: don't encode email headers if ascii only, it triggers some spam filters<br />
- fix: backslash not escaped properly in several functions<br />
- fix: remove duplicate recipients in hesk_mail() function<br />
- fix: missing name error message in profile<br />
- fix: don't allow newlines in email headers<br />
- fix: duplicate language string, IP WHOIS case<br />
- fix: use multibyte strtolower for strings where needed<br />
- fix: possible wrong previous month name in reports/exports<br />
- updated several third party libraries to the latest version<br />
</p>
<p><b>Changes in 2.7.3</b> - 10th April 2017<br />
- added meta robots &quot;noindex, nofollow&quot; tag to admin pages<br />
- hide KB functionality from customer side if no public articles<br />
- upload additional attachments when editing a ticket (up to allowed limit)<br />
- modified client IP detection to enable detecting proxy connections<br />
- improved display logic for top and latest public KB articles<br />
- improved handling of PHP/MySQL timezone difference<br />
- added new pages to allowed admin panel redirects<br />
- updated HTML Purifier and allowed URI Schemes<br />
- delete some cached files when saving settings<br />
- fix: missing collations in MySQL prior to 5.6<br />
- fix: missing statuses in ticket ID reminder email<br />
- fix: issues with emails that contain a single quote<br />
- fix: wrong custom date field value saved in some timezones<br />
- fix: extra line when using a hidden custom field after message<br />
- fix: session expired issue in very old PHP versions with register_globals on<br />
</p>
<p><b>Changes in 2.7.2</b> - 2nd January 2017<br />
- fix: suppress warnings when check for update without cURL fails<br />
- fix: MySQL strict mode issue when upgrading an old Hesk version<br />
- fix: Content-Security-Policy flags setTimeout string as unsafe-eval<br />
- fix: searching tickets disabled status New in show tickets form<br />
- fix: do not overwrite the text/javascript header in tcal.php<br />
- detect additional &quot;noreply&quot; addresses<br />
- respect category order in ticket list group/order by category<br />
- don't list KB articles under &quot;latest&quot; if they are already listed under &quot;top&quot;<br />
- moved help desk title/URL under general settings to avoid confusion<br />
- modified some default settings (does not affect updates)<br />
</p>
<p><b>Changes in 2.7.1</b> - 19th November 2016<br />
- fix: don't modify ticket &quot;Last updated&quot; when updating HESK to 2.7.x<br />
</p>
<p><b>Changes in 2.7.0</b> - 19th November 2016<br />
- custom fields have been improved significantly:<br />
&nbsp;&nbsp;&nbsp;&raquo; translate title<br />
&nbsp;&nbsp;&nbsp;&raquo; change display order<br />
&nbsp;&nbsp;&nbsp;&raquo; tie them to specific categories<br />
&nbsp;&nbsp;&nbsp;&raquo; private (staff only) custom fields supported<br />
&nbsp;&nbsp;&nbsp;&raquo; mark as required for everyone or just for customers<br />
&nbsp;&nbsp;&nbsp;&raquo; checkboxes now require only a single option (before: two)<br />
&nbsp;&nbsp;&nbsp;&raquo; increased number of available custom fields to 50<br />
&nbsp;&nbsp;&nbsp;&raquo; improved interface and moved under &quot;Tools&quot;<br />
&nbsp;&nbsp;&nbsp;&raquo; do not show double punctuation in forms<br />
&nbsp;&nbsp;&nbsp;&raquo; new types: date, email, hidden<br />
- you can now create custom ticket statuses<br />
- improved language loading (fallback if not found, custom text)<br />
- automatically reload pages with list of tickets every X seconds/minutes<br />
- require tickets to be assigned before staff is able to reply to them (option)<br />
- implemented IMAP fetching (import emails to tickets from an IMAP email server)<br />
- email templates can now be modified from the Admin panel (Tools &gt; Email templates)<br />
- removed LIMIT 1 from SQL UPDATE/DELETE statements to avoid replication warnings<br />
- in &quot;Tickets per user&quot; report show how many tickets a user has submitted <br />
- in admin panel show a link to the public knowledgebase article location<br />
- added head.txt for custom code to be included before &lt;/head&gt; tag<br />
- delete knowledgebase articles from the &quot;Edit article&quot; page<br />
- moved temporary files out of attachments folder<br />
- new staff permissions:<br />
&nbsp;&nbsp;&nbsp;&raquo; can resolve tickets<br />
&nbsp;&nbsp;&nbsp;&raquo; can submit tickets to any category<br />
&nbsp;&nbsp;&nbsp;&raquo; can move tickets to any category<br />
- ticket message can be set to not required<br />
- ticket subject can be set to not required<br />
- ticket email can be set to not required<br />
- HESK can now force SSL connections<br />
- fix: JS function argument default values are not available before ES6<br />
- fix: wrong order of ticket list column titles when a required column is missing<br />
- fix: return back to the previous page after editing KB articles from List private/draft articles<br />
- fix: remember opened ticket when changing display language in customer ticket view<br />
</p>
<p><b>Changes in 2.6.8</b> - 10th August 2016<br />
- fix: wrong form title when editing service messages<br />
- fix: removed some missing and/or mismatched HTML tags<br />
- fix: modify SQL database table structure to work with strict mode<br />
- security: fixed an issue, reported by Sven Morgenroth from Netsparker (<a href="https://www.netsparker.com">www</a>)<br />
- security: various security improvements, reported by Mohammed Abdulqader Abobaker Al-saggaf (<a href="https://www.linkedin.com/pub/mohammed-al-saggaf/9b/934/15a" rel="nofollow">www</a>)<br />
- misc: updated few third party libraries<br />
</p>
<p><b>Changes in 2.6.7</b> - 18th April 2016<br />
- changed email piping and pop3 fetching files line endings to Unix format for compatibility<br />
- security: removed private info from query string, reported by Alec Broughton (<a href="https://www.noodleman.co.uk">www</a>)<br />
- security: require email to view tickets setting is now enabled by default<br />
- fix: pagination in private staff messages not working<br />
- fix: wrong links to index and KB page in help files<br />
- in customer side emails are now shown as a link<br />
</p>
<p><b>Changes in 2.6.6</b> - 2nd February 2016<br />
- improved reCaptcha library to work with cURL<br />
- verify MySQL privileges before installing/upgrading<br />
- fix: respect attachments settings in KB form (minimum 3 if enabled)<br />
- fix: always checking for maintenance mode when downloading attachments<br />
- fix: missing &lt;tr&gt; tag in Reports<br />
</p>
<p><b>Changes in 2.6.5</b> - 28th August 2015<br />
- HESK now supports Zend OPcache enabled<br />
- modified PHP7 depreciated class constructors<br />
- improved handling of values/options when changing custom field type<br />
- simple anti-SPAM image now uses PNG or GIF support if JPEG is not enabled<br />
- trim &quot;Help Desk URL&quot; trailing slash when saving settings<br />
- fix: send customer notification of a new staff reply in the correct language<br />
- fix: merging tickets could hide old replies until a new reply is posted<br />
- fix: preserve table prefix in installation script on connection error<br />
- fix: session expired error when trying to reset password<br />
- fix: don't send out content-type headers for CLI scripts<br />
</p>
<p><b>Changes in 2.6.4</b> - 22nd June 2015<br />
- fix: session expired error if username case doesn't match exactly the one in database<br />
</p>
<p><b>Changes in 2.6.3</b> - 20th June 2015<br />
- update unknown IP address to the IP address of the first ticket visitor from customer interface<br />
- &quot;last modified&quot; value will now be preserved during hesk_tickets table update<br />
- staff private messages can now have signatures attached<br />
- added three new special tags to canned responses<br />
- improved status assignment logic when customer reopens a closed ticket<br />
- removed execution time limit in installation script to handle large database updates<br />
- updated inline URL regex to not process emails in URLs containing not encoded emails<br />
- fix: existing sessions should expire after changing credentials, reported by Indrajith.AN (<a href="https://www.facebook.com/indrajith.cyberXdestroyer">www</a>)<br />
- fix: missing a day in the DateArray() function when passing daylight saving time adjustments<br />
- fix: force content type header charset to utf-8 (override PHP 5.6+ default_charset)<br />
- fix: status change not logged in ticket history when staff inserting customer reply<br />
- fix: email to ticket: accept email if no message required but attachment exists<br />
- fix: email confirmation not working properly when multiple emails are allowed<br />
- fix: non-default MySQL ports ignored during upgrade using mysqli library<br />
- fix: &quot;Small box&quot; setting disables knowledgebase search in admin panel<br />
- fix: null attachment name length after removing non-ascii chars<br />
- fix: grammar error in English language file<br />
</p>
<p><b>Changes in 2.6.2</b> - 18th March 2015<br />
- fix: \0 converted to null byte in XML export<br />
- fix: closedby column in hesk_tickets table must accept signed values<br />
</p>
<p><b>Changes in 2.6.1</b> - 26th February 2015<br />
- fix: POP3 fetching task timeout can be disabled<br />
- fix: security issue reported by Michał Bentkowski (<a href="http://www.securitum.pl">www</a>)<br />
</p>
<p><b>Changes in 2.6.0</b> - 22nd February 2015<br />
- HESK is now compatible with PHP 5.6<br />
- minimum MySQL server version is 5.0.7<br />
- select which columns to display in ticket list<br />
- staff can now manage notifications and preferences for other users<br />
- option to disable email notifications to customer when they submit a new support ticket<br />
- notify customer when a ticket is marked Resolved (by staff without replying or automatically)<br />
- track what knowledgebase articles were suggested to the customer when submitting a new ticket<br />
- remind customer to check SPAM box for confirmation emails after submitting ticket<br />
- existing staff responses will be marked as read when customer replies over email<br />
- ticket templates for faster submitting of common tickets from admin interface<br />
- additional buttons to easily submit responses with different ticket statuses<br />
- improved handling of the goto parameter in admin panel (Lisandro Ubiedo)<br />
- require access control when testing connections (Lisandro Ubiedo)<br />
- don't start a new POP3 fetching task if the previous is still running<br />
- fix: fieldset legend element not aligned properly in most browsers<br />
- fix: set correct MIME type for servers sending nosniff header<br />
- fix: adjust MySQL time in legacy hesk_formatDate() function<br />
- fix: remove all non-ascii chars from attachment names<br />
- fix: custom checkbox fields not staying selected<br />
- staff can indicate a reply as a reply from the customer<br />
- use HESK knowledgebase only (no help desk)<br />
- allow staff to reset forgotten passwords<br />
- HESK can be put in maintenance mode<br />
- ability to find tickets by Owner<br />
- added support for reCAPTCHA API v2<br />
- the &quot;Time worked&quot; feature can be disabled<br />
- HESK width increased of 960 pixel by default<br />
- show service messages on help desk homepage<br />
- option to prevent customers from resolving tickets<br />
- link customer IP addresses to an IP whois service<br />
- new email tag %%ID%% prints sequential ticket ID<br />
- save ticket response message for later without replying<br />
- set default customer notification box selection in Profile<br />
- ticket notes now allow attachments and can be modified<br />
- staff members are now ordered by name for easier selection<br />
- customers can select email reminder to list all or open tickets<br />
- three time formats available for the &quot;Updated&quot; column in ticket list<br />
- &quot;Submit a ticket&quot; form fields can now be populated using GET and POST<br />
- when saving settings don't test SMTP and POP3 connection if no changes<br />
- optionally show &quot;Click to select&quot; for ticket category, priority and custom fields<br />
- skip customer notification of new ticket if a SPAM tag is in email subject<br />
- customer email and staff signature field length increased to 1000 chars<br />
- accept or reject emails with no message (email piping/POP3 fetching)<br />
- on Categories page added links to list all tickets in each category<br />
- when listing knowledgebase articles verify the category exists<br />
- show related knowledgebase articles when viewing an article<br />
- when creating tickets from emails respect the Reply-To: tag<br />
- change ticket priority for selected tickets in ticket list<br />
- set default priority for ticket categories<br />
- minor changes to the interface<br />
- ban email addresses<br />
- ban IP addresses<br />
</p>
<p><b>Changes in 2.5.5</b> - 5th August 2014<br />
- fix: correct TinyMCE update to 3.5.11 from version 2.5.4<br />
</p>
<p><b>Changes in 2.5.4</b> - 4th August 2014<br />
- fix: MySQL test ignoring new database name when verifying tables<br />
- fix: adjust time if MySQL and PHP use different time zone setting<br />
- fix: single quotes not escaped properly in Javascript (Lisandro Ubiedo)<br />
- updated TinyMCE to 3.5.11<br />
</p>
<p><b>Changes in 2.5.3</b> - 16th March 2014<br />
- Firefox built-in spell check is now enabled when creating/editing knowledgebase articles<br />
- rephrased few commands in the interface for better understanding and consistency<br />
- fix: some Javascript not working if translated command contains a single quote<br />
- fix: line separator chars causing Javascript syntax errors in canned responses<br />
- fix: Hotmail breaks ticket tracking ID in email reply subject by adding spaces<br />
- fix: define dt and lastchange variables for emails when adding a ticket note<br />
- fix: email date should be in RFC2822 format (no manual time adjustment)<br />
- fix: allow upgrading from 2.5.x series without patch files<br />
- updated pop3.php to avoid a strict standards warning<br />
- improved and simplified installation/update script<br />
- added .header a:visited to hesk_style.css<br />
- user password length is no longer limited<br />
- updated TinyMCE to 3.5.10<br />
</p>
<p><b>Changes in 2.5.2</b> - 13th October 2013<br />
- reports now include &quot;Time worked&quot; summary<br />
- modified sorting by &quot;Last Replier&quot; field. Staff will be sorted first (by ID), then customers by name<br />
- fix: toggling limit of categories and features for users should be controlled by selected admin value<br />
- fix: checking if temporary file exists may cause problems with open_basedir in effect<br />
- fix: disabled attachments in version 2.5.x don't load all required functions<br />
- fix: knowledgebase categories have problems with % char in their name<br />
- fix: anti-SPAM question doesn't accept 0 as a valid answer<br />
- updated TinyMCE to 3.5.9<br />
</p>
<p><b>Changes in 2.5.1</b> - 8th August 2013<br />
- added &quot;Updated&quot; value to the export of tickets to Excel<br />
- added support for exporting tickets in Zip without Zip library enabled<br />
- added two new email template tags: %%CREATED%% and %%UPDATED%%<br />
- reduced memory usage in knowledgebase article suggestion, search and display<br />
- set last replier name to the email sender name with email piping/POP3 fetching<br />
- show &quot;Open&quot; and &quot;Resolved&quot; ticket count in reports by user and by category<br />
- fixed HTML quoted printable chars causing problems in non UTF-8 emails<br />
- fixed Javascript encoding of UTF-8 URL query parts<br />
- fixed behavior of hesk_isEmailLoop() function<br />
- remove invalid UTF-8 bytes from submitted text<br />
- improved parsing of incoming email messages<br />
- delete temporary email files on errors
</p>
<p><b>Changes in 2.5.0</b> - 2nd July 2013<br />
- HESK is now fully compatible with PHP 5.5<br />
- export tickets into Excel (XML spreadsheet)<br />
- knowledgebase categories can now be ordered<br />
- show number of private and draft articles in the Knowledgebase categories list<br />
- new SPAM prevention option built-in: ReCaptcha<br />
- new special tag for use in email templates: %%EMAIL%%<br />
- support for %%MESSAGE%% tag in private messages<br />
- in email piping/pop3 fetching show notice what attachments were removed and why<br />
- if email contains message add direct links to any attachments at the bottom<br />
- add the &quot;Reply above this line&quot; tag only if email contains message<br />
- in emails make sure all fields have HTML special chars properly formatted<br />
- pop3 fetching now has an option to keep copy of emails on the server<br />
- pop3 fetching change verify sender name encoding<br />
- use <i>mysqli</i> extension instead of <i>mysql</i> if available<br />
- if customer reopens ticket change status to waiting reply from customer and remind customer to add a reply<br />
- it's now easy to change the name of admin and attachments folders<br />
- disallow uploads of some file types: .php, .phtml, .php3, .php4, .php5, .phps, .pl, .cgi, .shtm, .shtml<br />
- optimized several SQL statements for better performance<br />
- staff can now only run reports for categories they have access to and (by user) only for themselves.<br />
- option to give staff permission to run full reports<br />
- removed duplicates from text.php<br />
- when grouping tickets by owner show current user's on top<br />
- improved URL parsing to detect all schemes (http, https, ftp, sftp, file, ...)<br />
- when replying as staff give an option to not send email notification<br />
- in options.php urldecode $query<br />
- On Hold and In Progress statuses not cleared from the &quot;Change status to&quot; box<br />
- empty category value in submit ticket form if no public categories<br />
- work-around for a bug in older versions of Internet Explorer not allowing https downloads<br />
- long URLs in messages can be automatically shortened<br />
- session names shouldn't collide with multiple copies installed<br />
- email piping limit length of name and subject<br />
- detect if an attachment file has been deleted<br />
- show replier first name when printing tickets<br />
- do not allow rating replies of third party tickets<br />
- wrong status in email if status changes when replying<br />
- make &quot;Add to the bottom&quot; default selection for adding canned responses<br />
- &quot;last changed&quot; sometimes not updating correctly<br />
- remove the need for server path setting<br />
- forms need to allow longer emails (now 255 chars)<br />
- if a customer replies to a ticket with status &quot;New&quot; don't change status<br />
- &quot;Show newest on top&quot; setting now affects notes as well<br />
- custom fields need to be converted into plain text before sending in emails<br />
- hesk_makeURL should detect localhost addresses<br />
- decode XHTML reserved entities to UTF-8 in emails<br />
- prevent &amp; in &quot;Site title&quot; setting from becoming &amp;amp; in emails<br />
- modified knowledgebase search form to make it clearer what the form does (search help)<br />
- detect if someone tries to post more data than what the server allows (PHP post_max_size limit)<br />
- expired sessions in admin panel may cause an &quot;Invalid Request&quot; error<br />
- reloading the page after submitting a KB article creates a new (duplicate) article<br />
- fix category name and email problems due to MySQL wildcard match<br />
- for customers, auto-focus first required field when &quot;Submit a ticket&quot; form loads<br />
- prevent caching of session pages by sending session_cache_limiter nocache<br />
- private and draft article list showing only 1 draft per category<br />
- limiting failed login attempts can now be disabled in settings<br />
- modified the simple anti-spam image a bit<br />
- count views of private articles<br />
- when deleting knowledgebase category also delete/move subcategories and attachments<br />
- fixed an error that can occur when merging tickets in strict MySQL mode<br />
- if one attachment fails delete others as well<br />
- fixed problems with \ &quot; &lt; &gt; &amp; in pop3/smtp passwords<br />
- removed support email variable (not used anymore)<br />
- removed Connection and Content-length HTTP headers from AJAX posts<br />
- cache check for updates to 1 per hour<br />
- updated TinyMCE to 3.5.8<br />
- updated mime_parser class to 1.85<br />
- few minor user interface changes
</p>
<p><b>Changes in 2.4.2</b> - 30th December 2012<br />
- verify that a valid version of HESK has been installed</p>
<p><b>Changes in 2.4.1</b> - 18th August 2012<br />
- fixed comment URL parsing issues when replying to a ticket as staff<br />
- fixed Knowledgebase file uploads not working on some installations of 2.4<br />
- with auto-login set to OFF and Debug mode set to ON, notices were shown after staff login<br />
- knowledgebase attachments on private and draft articles cannot be downloaded<br />
- lastchange not updated when deleting ticket posts without status change<br />
- some servers add slashes to file_get_contents(), detect and remove them<br />
- some servers may report maximum file size in lowercase letters<br />
- column hits in table hesk_pipe_loops didn't have a default value<br />
- merge tickets option not showing on some installations of 2.4<br />
- if a POP3 stream wrapper is already registered remove it<br />
- improved detection of returned emails</p>
<p><b>Changes in 2.4</b> - 9th August 2012<br />
- encoding changed to UTF-8 for all languages<br />
- time spent on ticket<br />
- POP3 fetching (connect to an email account and convert emails into tickets)<br />
- customers may reply to tickets by replying to notification emails<br />
- detect and correct mistyped email addresses<br />
- detect email piping loops<br />
- enable/disable autoassign per category<br />
- private ticket categories (for use by staff only)<br />
- merge several tickets into one<br />
- sticky knowledgebase articles<br />
- keywords for knowledgebase articles<br />
- hide date and views from knowledgebase articles<br />
- set email &quot;From:&quot; name in HESK settings<br />
- fixed bug: when moving ticket category an autoassign email wasn't sent<br />
- fixed bug: reopen link still showed to customer when it should be disabled<br />
- fixed bug: misplaced quote in users online list HTML code<br />
- fixed bug: close ticket selection missing in new statuses<br />
- fixed bug: staff should not be able to create new accounts with more features<br />
- fixed broken Javascript code if language file uses single quotes<br />
- fixed typos in some variable names<br />
- fixed email date issues<br />
- fixed email notifications should be sent in preferred language<br />
- improved permission checking for access to attachments and tickets<br />
- updated calendar to latest version<br />
- updated WYSIWYG text editor to latest version<br />
- updated mime_decode to latest version<br />
- filter ticket ID for ugly words<br />
- delete individual attachments from tickets<br />
- new special tag for email templates: %%STATUS%%<br />
- search ticket notes<br />
- forgot ticket ID lists open and most recent tickets first<br />
- forgot ticket ID can list open tickets only<br />
- limit maximum open tickets per client (web form only)<br />
- new replies can now be shown on top of the page<br />
- reply box can be moved to the top of the page<br />
- when showing next ticket that needs attention don't show tickets assigned to someone else<br />
- searching tickets by message now also searches replies<br />
- email when note is added to ticket assigned to me<br />
- email subjects changed to include ticket subject and tracking ID<br />
- improved email syntax validation<br />
- moved less common functions from common.inc.php<br />
- modified admin header to show nicely in non-English versions<br />
- mark replies read by customer<br />
- automatically check for updates<br />
- a number of other minor changes and fixes.</p>
<p><b>Changes in 2.3</b> - 15th September 2011<br />
- a &quot;What You See is What You Get&quot; (WYSIWYG) editor for Knowledgebase articles<br />
- import tickets into Knowledgebase articles<br />
- automatically assign tickets to appropriate staff<br />
- staff can change status of tickets<br />
- two new ticket status options: On Hold, In Progress<br />
- staff can set ticket priority to &quot;Critical&quot;<br />
- view what staff is currently online<br />
- create tickets from email (email piping)<br />
- support for sending emails using a SMTP server rather than PHP mail()<br />
- improved ticket sorting algorithm and new sorting options.<br />
- change default ticket display and sorting in the admin homepage<br />
- find tickets by email and sequential ticket ID<br />
- brute force protection for both ticket view and staff login<br />
- Hesk is now IPv6 ready<br />
- fixed bug where required custom fields with value 0 would return an error<br />
- fixed bug where emails were sometimes not sent to all staff when changing ticket category<br />
- fixed bug where knowledgebase article count wasn't updated properly<br />
- fixed a potential security issue on servers with PHP register_globals enabled<br />
- renamed &quot;Close ticket&quot; to &quot;Mark as Resolved&quot; for clarity<br />
- renamed &quot;Archived&quot; to &quot;Tagged&quot; for clarity<br />
- you can require customers to enter both ticket ID and email to view a ticket<br />
- modified ticket ID format so it is easier to read and repeat<br />
- limit view of unassigned tickets to staff<br />
- a number of error-handling and interface changes to make Hesk even more user friendly<br />
- a number of minor changes and fixes.</p>
<p><b>Changes in 2.2</b> - 9th June 2010<br />
- assign owners to tickets (assign tickets to individual staff members)<br />
- admin panel shows last repliers' name<br />
- more information can be entered into e-mails (category, message, ticket owner, custom fields)<br />
- staff can now submit tickets<br />
- added reporting features<br />
- added staff private messages<br />
- check for duplicate tracking ID<br />
- improved ticket searching<br />
- fixed bug where edit_post rewrites session variables when register_globals is enabled<br />
- fixed bug where e-mails and URLs don't show correctly when editing ticket<br />
- fixed bug where last replier didn't show correctly after deleting a post<br />
- lock/unlock individual tickets<br />
- new way of suggesting KB articles<br />
- ticket history log (who closed, opened, locked or unlocked a ticket)<br />
- more user-friendly error and success message handling<br />
- added checks to fight CSRF-type attacks<br />
- generate URLs that will pre-load category selection when submitting new tickets<br />
- settings will now accept localhost URLs<br />
- purge attachments when the ticket is deleted<br />
- disable customer setting ticket priority level<br />
- a number of minor changes and fixes.</p>
<p><b>Changes in 2.1</b> - 7th August 2009<br />
- Full support for multiple languages<br />
- Knowledgebase articles can now have attachments<br />
- Increased custom fields number to 20<br />
- Checkboxes now supported as custom fields<br />
- Autologin feature<br />
- Staff can edit all ticket details<br />
- New redirect options after replying to a ticket (settable in Profile)<br />
- Canned responses can be appended to the message instead of replacing it<br />
- A read-only access to private knowledgebase by all staff<br />
- Fixed numerous small bugs and issues thanks to large code testing and screening<br />
- Improved security<br />
- HESK moved to <a href="https://www.hesk.com">www.hesk.com</a> Web site, links within the script updated accordingly</p>
<p><b>Changes in 2.0</b> - 24th January 2009<br />
- Updated user interface<br />
- Fully featured knowledge base (categories, articles (counting views, able to rate), search, ...)<br />
- Display of latest and top articles<br />
- Before a ticket is submitted HESK will suggest matching Knowledgebase articles<br />
- You can add notes to tickets (hidden from customer, viewable by staff)<br />
- Limit features for staff (not just Administrator/Staff, now you can enable/disable individual features for individual users)<br />
- Rating of staff replies (Helpful/Not helpful)<br />
- Up to 10 custom field now<br />
- Custom fields can be text, textarea, select or radio button<br />
- Disable list users in admin<br />
- Remember staff username<br />
- Default ticket listing by status (new, waiting reply first) then priority<br />
- Staff passwords encrypted - not simple SHA1, but multiple times<br />
- Admin files moved to &quot;admin&quot; folder<br />
- Added prefix to database names<br />
- Autoclose tickets after X days<br />
- Adjust server time to match your local time<br />
- Updated anti-SPAM features<br />
- And many other changes</p>
<p><b>Changes in 0.94.1</b> - 25th April 2007<br />
- Fixed an XSS vulnerability on some servers (reported by Nemanja Avramovic)<br />
- Changed the way file uploads are handled</p>
<p><b>Changes in 0.94</b> - 23rd April 2007<br />
- Added support for custom fields (up to 5)<br />
- Added file attachments<br />
- Added anti-SPAM security image<br />
- Added canned responses<br />
- Settings are now edited from the admin panel<br />
- New ticket statuses (New, Replied, Waiting Reply, Resolved)<br />
- Ticket ID reminder<br />
- And many other changes (too many to list here)</p>
<p><b>Changes in 0.93.1</b> - 17th September 2005<br />
- Fixed a security issue reported by OS2A team</p>
<p><b>Version 0.93</b> - 3rd July 2005<br />
</p>
<p><b>Version 0.92</b> - 28th May 2005<br />
</p>
<p><b>Version 0.91</b> - 4th May 2005<br />
</p>
<p><b>Initial release 0.90</b> - 23rd April 2005</p>
<p>&nbsp;</p>
<p style="text-align:center">&copy; Copyright <a href="https://www.hesk.com">HESK.COM</a> 2005-2020. All rights reserved.</p>
</div>
</div>
</body>
</html>

144
hesk/docs/docs_style.css Normal file
View File

@@ -0,0 +1,144 @@
/* Style sheet and XHTML code
Author: Mauricio Samy Silva http://www.maujor.com/ A Web Standard evangelist site
City: Rio de Janeiro - Brazil
Contact: maujorcss[at]maujor[dot]com
Date: 2006-05-11
*/
body
{
margin:5px 0;
padding:0;
background:#eee;
color: black;
font : 68.8%/1.5 Verdana, Geneva, Arial, Helvetica, sans-serif;
text-align:center;
}
#wrapper
{
width:700px;
background:#fff;
margin:0 auto;
text-align:left;
border:1px solid #ccc;
padding:10px 20px;
}
h1 {font-size:1.5em;}
h2
{
font-size:1.2em;
border-top:1px solid #999;
padding-top:1.8em;
}
h2.title
{
font-size:1.2em;
border-top:1px solid #999;
padding-top:1.8em;
color: green;
}
h3 {font-size:1.0em;}
span.dest {color:#f00;}
span.tip {color:#008000; font-weight:bold;}
p
{
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.0em;
}
address
{
font-weight:bold;
font-style:normal;
}
ul.nobullets
{
margin:0 0 1.0em;
padding:0;
list-style:none;
}
ol li {margin-bottom:1.0em;}
samp, code
{
font-size:1.3em;
font-weight:bold;
}
a:hover
{
color : red;
background:#ccc;
text-decoration : none;
}
table#installation
{
border-collapse:collapse;
margin: 5px 15px 10px -25px;
border: 2px solid #999;
}
table#installation thead
{
text-align:center;
text-transform:uppercase;
}
table#installation tr td, table#installation tr th
{
padding: 2px 5px;
border: 1px solid #ccc;
}
table#installation tr th
{
border-bottom-width:2px;
border-bottom-color:#999;
}
table#installation tr td var
{
font-weight:bold;
font-style:normal;
}
table#installation tr.odd
{
background: #fafafa;
}
div.error
{
border: 1px solid #cd0a0a;
background: #fef1ec;
color: #cd0a0a;
padding-left:10px;
padding-right:5px;
}
div.success
{
border: 1px solid #18760f;
background: #e9ffdb;
color: #363636;
padding-left:10px;
padding-right:5px;
}
div.notice
{
border: 1px solid #fcefa1;
background: #fff9de;
color: #363636;
padding-left:10px;
padding-right:5px;
}

85
hesk/docs/index.html Normal file
View File

@@ -0,0 +1,85 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>HESK - Documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="docs_style.css" />
</head>
<body>
<div id="wrapper">
<div id="main">
<h1><span class="dest">HESK&trade;</span> PHP Help Desk Software</h1>
<table width="100%">
<tr>
<td width="50%" style="text-align:left;vertical-align:top">
<ul class="nobullets">
<li>Version: 3.0.0 from 17th February 2020</li>
<li>Developed by: Klemen Stirn, Mike Koch</li>
<li><a href="https://www.hesk.com">Help Desk Software HESK</a></li>
<li><a href="https://www.phpjunkyard.com">Free PHP Scripts</a></li>
</ul>
</td>
<td width="50%" style="text-align:right;vertical-align:top">
<ul class="nobullets">
<li><b>HESK documentation</b></li>
<li><a href="step-by-step-guide.html">Step by step guide</a></li>
<li><a href="quick-guide.html">Quick guide</a></li>
<li><a href="changelog.html">Changelog</a></li>
</ul>
</td>
</tr>
</table>
<div class="notice">
<p><b>Hey, you should probably read this...</b><p>
<p>HESK version 3 features a brand new user interface. While we consider it stable enough for use it is likely that we didn't spot all the errors across various browsers and devices.</p>
<p>We encourage you to report any problems and user-experience suggestions to our <a href="https://developers.phpjunkyard.com">support forum</a>.</p>
</div>
<h2 class="title" style="padding-left:20px;">Thank you for downloading HESK!</h2>
<span style="padding-left:20px;">Select one of the two HESK guides based on your experience level:<br />&nbsp;</span>
<ol>
<table id="installation" width="100%">
<thead>
<tr>
<th width="50%"><a href="step-by-step-guide.html">STEP BY STEP GUIDE</a></th>
<th width="50%"><a href="quick-guide.html">QUICK START GUIDE</a></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>
<br />
<ul>
<li>An easy <b>step-by-step</b> guide <b>for anyone</b></li>
<li>Detailed explanations and examples</li>
<li><a href="step-by-step-guide.html">Click here to start</a></li>
</ul>
</td>
<td>
<br />
<ul>
<li>Best for <b>experienced webmasters</b></li>
<li>Short and to the point</li>
<li><a href="quick-guide.html">Open quick guide</a></li>
</ul>
</td>
</tr>
</tbody>
</table>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align:center">&copy; Copyright <a href="https://www.hesk.com">HESK.COM</a> 2005-2020. All rights reserved.</p>
</div>
</div>
</body>
</html>

146
hesk/docs/license.html Normal file
View File

@@ -0,0 +1,146 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>HESK Software End User License Agreement</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="docs_style.css" />
</head>
<body>
<div id="wrapper">
<div id="main" style="text-align:justify">
<div class="notice">
<p><b>Notice:</b> The latest version of this agreement is published at <a href="https://www.hesk.com/eula.php" target="_blank">HESK.com EULA webpage</a></p>
</div>
<h1>HESK Software End User License Agreement</h1>
<p>This End-User License Agreement (EULA) is a legal agreement between either and individual or a legal entity or association intending to use the Software (&quot;You&quot; or &quot;Customer&quot;) and HESK.COM. By installing, copying, or otherwise using the Software, You represent, warrant, and agree that You have read, understood, and agree to be bound by the terms of the EULA. If You do not agree to be bound of the EULA, or You do not have authority to bind Customer to the EULA, You may not use the Software.</p>
<h2>1. Definitions</h2>
<p><b>&quot;Copyright headers&quot;</b> means a written copyright notice by HESK.COM located in Software source code and normally not visible to Web Users.</p>
<p><b>&quot;HESK.COM&quot;</b> (&quot;Author&quot;, &quot;We&quot;, &quot;Us&quot;) means Klemen Stirn, the author and copyrights owner of the Software, his employees, representatives and contractors.</p>
<p><b>&quot;License Key&quot;</b> means the key that is used to activate special Software functions, such as the removal of Powered by links, in one or more installed copies of Software.</p>
<p><b>&quot;License Manager&quot;</b> means an online tool provided by HESK.COM to holders of a valid License Key, where copies of the Software are registered for Powered by links removal.</p>
<p><b>&quot;Powered by links&quot;</b> means built-in text with one or more anchor links pointing to HESK.COM website and/or website of HESK.COM contractors located at the bottom of the Software and visible to Web Users of the Software without viewing source code.</p>
<p><b>&quot;Software&quot;</b> (&quot;HESK&quot;, &quot;HESK Software&quot;) means the Software that accompanies this EULA.</b></p>
<p><b>&quot;Web Users&quot;</b> means individuals using or viewing the Software with a Web browser.</p>
<h2>2. Grant of License</h2>
<p>The EULA grants You the following rights: Installation and Use. You may install and use an unlimited number of copies of the Software.</p>
<p>You may also modify the Software to fit Your specific needs as long as all parts of the EULA are adhered to (pay special attention to &quot;Conditions and Limitations&quot; and &quot;Removing Powered by links&quot;) and the modified Software is still considered HESK Software.</p>
<h2>3. Conditions and Limitations</h2>
<p><b>Distribution.</b><br />
Obtain permission before redistributing this Software over the Internet or in any other medium.</p>
<p><b>Separation of Components.</b><br />
The Software is licensed as a single product. Its component parts may not be separated for other use.</p>
<p><b>Software Transfer.</b><br />
You may permanently transfer all of Your rights under this EULA, provided the recipient agrees to the terms of this EULA.</p>
<p><b>Source code</b><br />
Using the Software source code, in part or full, to create derivative work, new softwares or products is expressly forbidden. Under no circumstance is the removal of Copyright headers from the Software source code permitted.</p>
<p><b>Termination.</b><br />
Without prejudice to any other rights, the Author of the Software may terminate the EULA if You fail to comply with the terms and conditions of the EULA. In such event, You must destroy all copies of the Software and all of its component parts.</p>
<p><b>Third party components.</b><br />
The Software may contain certain components provided by third parties and released under a different license agreement. You acknowledge and agree to the terms and conditions in each such license agreement and that You are solely responsible for complying with such terms and conditions.</p>
<h2>4. Removing Powered by links</h2>
<p>You are not allowed to remove or modify the Powered by links in the Software without a valid License Key.</p>
<p>Removing or modifying Powered by links without a valid a License Key means You are in a direct violation of the EULA and You may not use the Software.</p>
<p>A single License Key can cover one or more copies of the Software installed, all of which must be registered in the License Manager. Access to the License Manager is provided along with a License Key.</p>
<p>A License Key to remove Powered by links can be purchased here: <a href="https://www.hesk.com/buy.php">Buy a HESK License Key</a>.</p>
<h2>5. Copyright</h2>
<p>&copy; Copyright 2020 Klemen Stirn. All rights reserved.</p>
<p>Some components may be copyrighted by third parties. See component source code and/or included license agreements for details. Trademarks are property of their respective owners.</p>
<h2>6. Trademark Policy</h2>
<p>HESK is a registered trademark of Klemen Stirn. Certain usages of the Trademark are fine and no specific permission from the Author is needed:</p>
<ul>
<li>there is no commercial intent behind the use,</li>
<li>what You are referring to is in fact HESK. If someone is confused into thinking that what isn't HESK is in fact HESK, You are probably doing something wrong,</li>
<li>there is no suggestion (through words or appearance) that Your project is approved, sponsored, or affiliated with HESK or its related projects unless it actually has been approved by and is accountable to the Author.</li>
</ul>
<p>Permission from the Author is necessary to use the HESK trademark under any circumstances other than those specifically permitted above. These include:</p>
<ul>
<li>any commercial use,</li>
<li>use on or in relation to a Software product that includes or is built on top of a product supplied by Author, if there is any commercial intent associated with that product,</li>
<li>use in a domain name or URL,</li>
<li>use for merchandising purposes, e.g. on t-shirts and the like,</li>
<li>use of a name which includes the letters HESK in relation to computer hardware or Software,</li>
<li>services relating to any of the above.</li>
</ul>
<p>If You wish to have permission for any of the uses above or for any other use which is not specifically referred to in this policy, please contact HESK.COM to verify if Your proposed use is permissible. Permission may only be granted subject to certain conditions and these may include the requirement that You enter into an agreement with me to maintain the quality of the product and/or service which You intend to supply at a prescribed level.</p>
<p>While there may be exceptions, it is very unlikely that HESK.COM will approve Trademark use in the following cases:</p>
<ul>
<li>use of a Trademark in a company name,</li>
<li>use of a Trademark in a domain name which has a commercial intent. The commercial intent can range from promotion of a company or product, to collecting revenue generated by advertising,</li>
<li>the calling of any Software or product by the name HESK (or another related Trademark), unless that Software or product is a substantially unmodified HESK product,</li>
<li>use in combination with any other marks or logos. This include use of a Trademark in a manner that creates a "combined mark," or use that integrates other wording with the Trademark in a way that the public may think of the use as a new mark (for example Club HESK or HESKBooks, or in a way that by use of special fonts or presentation with nearby words or images conveys an impression that the two are tied in some way),</li>
<li>use in combination with any product or service which is presented as being Certified or Official or formally associated with me or my products or services,</li>
<li>use in a way which implies an endorsement where that doesn't exist, or which attempts to unfairly or confusingly capitalise on the goodwill or brand of the project,</li>
<li>use of a Trademark in a manner that disparages HESK and is not clearly third-party parody,</li>
<li>on or in relation to a Software product which constitutes a substantially modified version of a product supplied by HESK.com, that is to say with material changes to the code, or services relating to such a product,</li>
<li>in a title or metatag of a web page whose sole intention or result is to influence search engine rankings or result listings, rather than for discussion, development or advocacy of the Trademarks.</li>
</ul>
<h2>7. Disclaimer of Warranty</h2>
<p>THE PRODUCT IS PROVIDED &quot;AS IS&quot; WITH ALL FAULTS. TO THE EXTENT PERMITTED BY LAW, HESK.COM AND HESK.COM'S DISTRIBUTORS, AND LICENSORS HEREBY DISCLAIM ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES THAT THE PRODUCT IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE AND NON-INFRINGING. YOU BEAR THE ENTIRE RISK AS TO SELECTING THE PRODUCT FOR YOUR PURPOSES AND AS TO THE QUALITY AND PERFORMANCE OF THE PRODUCT. THIS LIMITATION WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY.</p>
<h2>8. Limitation of Liability</h2>
<p>EXCEPT AS REQUIRED BY LAW, HESK.COM AND ITS DISTRIBUTORS, DIRECTORS, LICENSORS, CONTRIBUTORS AND AGENTS WILL NOT BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES ARISING OUT OF OR IN ANY WAY RELATING TO THE EULA OR THE USE OF OR INABILITY TO USE THE PRODUCT, INCLUDING WITHOUT LIMITATION DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, LOST PROFITS, LOSS OF DATA, AND COMPUTER FAILURE OR MALFUNCTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH SUCH CLAIM IS BASED. THE HESK.COM COLLECTIVE LIABILITY UNDER THE EULA WILL NOT EXCEED THE FEES PAID BY YOU UNDER THE EULA (IF ANY).</p>
<h2>9. Modification</h2>
<p>The EULA may be modified by HESK.com at any time. The new version of the EULA becomes valid when published on HESK.COM website. You are encouraged to regularly check back for updates.</p>
<h2>10. Other</h2>
<p>The EULA is governed by the laws of Slovenia, European Union. Both You and HESK.COM submit to the jurisdiction of the courts of Slovenia. Both You and HESK.COM agree to commence any litigation that may arise hereunder in the courts located in Slovenia.</p>
<p>If any provision hereof shall be held illegal, invalid or unenforceable, in whole or in part, such provision shall be modified to the minimum extent necessary to make it legal, valid and enforceable, and the legality, validity and enforceability of all other provisions of the EULA shall not be affected thereby. No delay or failure by either party to exercise or enforce at any time any right or provision hereof shall be considered a waiver thereof or of such party's right thereafter to exercise or enforce each and every right and provision of this Agreement.</p>
</div>
</div>
</body>
</html>

131
hesk/docs/quick-guide.html Normal file
View File

@@ -0,0 +1,131 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>HESK quick start guide</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="docs_style.css" />
</head>
<body>
<div id="wrapper">
<div id="main">
<h1><span class="dest">HESK&trade;</span> PHP Help Desk Software</h1>
<table width="100%">
<tr>
<td width="50%" style="text-align:left;vertical-align:top">
<ul class="nobullets">
<li>Version: 3.0.0 from 17th February 2020</li>
<li>Developed by: Klemen Stirn, Mike Koch</li>
<li><a href="https://www.hesk.com">Help Desk Software HESK</a></li>
<li><a href="https://www.phpjunkyard.com">Free PHP Scripts</a></li>
</ul>
</td>
<td width="50%" style="text-align:right;vertical-align:top">
<ul class="nobullets">
<li><a href="index.html">HESK documentation</a></li>
<li><a href="step-by-step-guide.html">Step by step guide</a></li>
<li><b>Quick guide</b></li>
<li><a href="changelog.html">Changelog</a></li>
</ul>
</td>
</tr>
</table>
<div class="notice">
<p><b>Hey, you should probably read this...</b><p>
<p>HESK version 3 features a brand new user interface. While we consider it stable enough for use it is likely that we didn't spot all the errors across various browsers and devices.</p>
<p>We encourage you to report any problems and user-experience suggestions to our <a href="https://developers.phpjunkyard.com">support forum</a>.</p>
</div>
<h2>HESK QUICK START GUIDE</h2>
<ul class="nobullets">
<li><a href="#install"><b>Install HESK</b></a></li>
<li><a href="#upgrade">Upgrade from old HESK version</a></li>
<li><a href="#help">Help &amp; Support</a></li>
</ul>
<h2 id="install">&raquo; Install HESK</h2>
<ol>
<li><p>Upload HESK files to your server (https://www.example.com/helpdesk)</p></li>
<li><p>Open <b>install</b> directory in your browser (https://www.example.com/helpdesk/install)</p></li>
<li><p>Click <b>INSTALL HESK</b> and follow the steps to check requirements and setup MySQL</p></li>
<li><p>Delete the <b>install</b> directory.</p></li>
<li><p>Open <b>admin</b> directory (https://www.example.com/helpdesk/admin)</p></li>
<li><p>The customer interface is at https://www.example.com/helpdesk</p></li>
<li>
<p>Things to do next:</p>
<ul>
<li><b>Profile</b> - set your name, email, signature, and a new password.</li>
<li><b>Settings</b> - set website URL, title and get familiar with HESK settings.</li>
<li><b>Categories</b> - create help desk categories/departments.</li>
<li><b>Users</b> - create new staff accounts.</li>
<li><b>Knowledgebase</b> - create knowledgebase (FAQ) categories and articles.</li>
<li><b>Canned</b> - set reply templates (canned responses).<br />&nbsp;</li>
</ul>
</li>
<li><p>Support HESK development by <a href="https://www.hesk.com/buy.php">purchasing a license</a></p></li>
<li><p>Good luck with using HESK!<br />&nbsp;</p></li>
</ol>
<h2 id="upgrade">&raquo; Upgrade from old HESK version</h2>
<p><b>Known upgrade issues:</b></p>
<ul>
<li>HESK language may be reset to English if new text was added.</li>
<li>Passwords may not work after upgrade from very old versions (<a href="https://www.hesk.com/knowledgebase/?article=22">reset password</a>).</li>
<li>If you purchased a license you may need to <a href="https://www.hesk.com/license">download a new license</a>.</li>
</ul>
<p style="font-weight:bold">Upgrade steps:</p>
<ol>
<li><p><span class="dest" style="font-weight:bold">BACKUP YOUR EXISTING HESK DATABASE AND FILES</span><br />... or don't blame me if something goes wrong.</p></li>
<li>
<p>Upload all HESK files to your server <b>EXCEPT</b> these (do NOT upload these files):<br />
- hesk_settings.inc.php<br />
- head.txt<br />
- header.txt<br />
- footer.txt</p>
</li>
<li><p>Open <b>install</b> directory in your browser (https://www.example.com/helpdesk/install)</p></li>
<li><p>Click <b>UPDATE HESK</b> and follow instructions to update MySQL tables.</p></li>
<li><p>Delete the <b>install</b> directory.</p></li>
<li><p>Open the admin panel (https://www.example.com/helpdesk/admin) and log in with your username. If the password doesn't work anymore try <a href="https://www.hesk.com/knowledgebase/?article=22">resetting it</a>.</p></li>
<li><p>Test HESK to make sure the upgrade was successful and everything works. You may need to modify your Help Desk title and Custom field settings if they are not displaying correctly.</p></li>
<li>
<p>If you own a HESK license you might need to <a href="https://www.hesk.com/license">download a new one</a>.</p>
<p>If not, consider supporting HESK by <a href="https://www.hesk.com/buy.php">purchasing a license</a>.</p></li>
<li><p>Good luck with using HESK!<br />&nbsp;</p></li>
</ol>
<h2 id="help">&raquo; Help &amp; Support</h2>
<div class="notice" style="font-size:15px">
<p style="text-align:center">For comprehensive and up-to-date help and troubleshooting guides please visit:<br />
<a href="https://www.hesk.com/knowledgebase/"><b>HESK Knowledgebase</b></a></p>
</div>
<h2 id="translate">&raquo; Translate HESK to your language</h2>
<p>Thanks to our users, who help translate HESK free of charge, multiple languages are available for HESK:</p>
<p><a href="https://www.hesk.com/language/">HESK language packs</a><br />&nbsp;</p>
<h2 id="other">&raquo; More FREE PHP Scripts</h2>
<p>Get more FREE PHP scripts here: <a href="https://www.phpjunkyard.com/">PHP Scripts</a>.</p>
<p>&nbsp;</p>
<p style="text-align:center">&copy; Copyright <a href="https://www.hesk.com">HESK.COM</a> 2005-2020. All rights reserved.</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,228 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>HESK step by step guide</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="docs_style.css" />
</head>
<body>
<div id="wrapper">
<div id="main">
<h1><span class="dest">HESK&trade;</span> PHP Help Desk Software</h1>
<table width="100%">
<tr>
<td width="50%" style="text-align:left;vertical-align:top">
<ul class="nobullets">
<li>Version: 3.0.0 from 17th February 2020</li>
<li>Developed by: Klemen Stirn, Mike Koch</li>
<li><a href="https://www.hesk.com">Help Desk Software HESK</a></li>
<li><a href="https://www.phpjunkyard.com">Free PHP Scripts</a></li>
</ul>
</td>
<td width="50%" style="text-align:right;vertical-align:top">
<ul class="nobullets">
<li><a href="index.html">HESK documentation</a></li>
<li><b>Step by step guide</b></li>
<li><a href="quick-guide.html">Quick guide</a></li>
<li><a href="changelog.html">Changelog</a></li>
</ul>
</td>
</tr>
</table>
<div class="notice">
<p><b>Hey, you should probably read this...</b><p>
<p>HESK version 3 features a brand new user interface. While we consider it stable enough for use it is likely that we didn't spot all the errors across various browsers and devices.</p>
<p>We encourage you to report any problems and user-experience suggestions to our <a href="https://developers.phpjunkyard.com">support forum</a>.</p>
</div>
<h2>HESK STEP BY STEP GUIDE</h2>
<ul class="nobullets">
<li><a href="#install"><b>Install HESK</b></a></li>
<li><a href="#upgrade">Upgrade from old HESK version</a></li>
<li><a href="#help">Help &amp; Support</a></li>
</ul>
<h2 id="install">&raquo; Install HESK</h2>
<div class="error">
<p style="font-weight:bold">Please take 5 minutes to read the installation instructions carefully and completely! This will ensure a proper and easy installation.</p>
</div>
&nbsp;
<div class="notice">
<p>Before installing HESK you will need to obtain your MySQL database information, such as <b>database name</b>, <b>database user</b> and <b>password</b>.
You need to get this information from your HOSTING COMPANY, HESK CANNOT help you find it.</p>
</div>
<p>&nbsp;<br /><span class="tip">TIP:</span> Want a hassle-free help desk working in minutes? Sign up for <a href="https://www.hesk.com/remote-help-desk.php"><b>HESK Cloud</b></a> instead.<br />&nbsp;</p>
<p style="font-weight:bold">Installation steps:</p>
<ol>
<li><p>Connect with FTP to the <i>public folder</i> of your server where the rest of your Web site is.</p>
<p><span class="tip">TIP:</span> The public folder is usually called &quot;<b>public_html</b>&quot;, &quot;www&quot;, &quot;site&quot; or &quot;htdocs&quot;.</p>
<p><span class="tip">TIP:</span> Learn how to FTP files, read my simple <a href="https://www.phpjunkyard.com/tutorials/ftp-chmod-tutorial.php">FTP and CHMOD tutorial</a></p>
</li>
<li><p>Create a new folder where you will install HESK. Name it anything you like, for example, &quot;helpdesk&quot; or &quot;support&quot;.<br />
Example: /public_html/helpdesk<br />
Corresponding URL: https://www.example.com/helpdesk</p></li>
<li><p>Upload all HESK files to your server. PHP files must be transferred in ASCII mode and images in BINARY mode.</p>
<p><span class="tip">TIP:</span> Most FTP clients will select the proper transfer mode automatically so you needn't worry about this.</li>
<li>
<p>Open <b>hesk/install</b> in your browser, for example (modify to your URL):<br />
https://www.example.com/helpdesk/install</p>
</li>
<li>
<p>The HESK setup script will run. Click <b>INSTALL HESK</b> and follow instructions through 4 steps:</p>
<ul>
<li><b>STEP 1: License agreement</b> - read the HESK License agreement and confirm that you agree with the terms.</li>
<li><b>STEP 2: Check setup</b> - the script will test your server to see if all required settings are correct and advise solutions to any problems.</li>
<li><b>STEP 3: Database settings</b> - enter your MySQL database settings and the setup script will test them.<br />
<span class="dest">You need to get the correct MySQL database information from your hosting company!</span></li>
<li><b>STEP 4: Setup database tables</b> - everything OK, the script will install MySQL tables.<br />&nbsp;</li>
</ul>
</li>
<li>
<p style="font-weight:bold">Before closing the upgrade script <span class="dest">DELETE the &quot;install&quot; directory from your server!</span></p>
</li>
<li>
<p>Well done, now it's time to set up your help desk! Click the Continue link in the install script or open the <b>admin</b> folder in your browser, for example:<br />
https://www.example.com/helpdesk/admin/</p>
<p><span class="tip">TIP:</span> HESK passwords are CaSe SeNSiTiVe (&quot;ABCD&quot; is not the same as &quot;abcd&quot;) while usernames are not.</p>
</li>
<li><p>Click the <b>Settings</b> link in the top menu to get to the settings page (if not there already)</p></li>
<li>
<p>Take some time and get familiar with all the available settings. Most should be self-explanatory, for additional information
about each setting click the [<a href="Javascript:void(0)"><b>?</b></a>] link for help about the current setting.</p>
<p>Don't forget to click the <b>Save changes</b> button at the bottom of the settings page to save your settings!</p>
</li>
<li>
<p>Things to do next</p>
<ul>
<li><p>Click the &quot;Profile&quot; link to set your name, e-mail, signature, and password.</p></li>
<li><p>Add new categories (departments) on the &quot;Categories&quot; page. The default category cannot be deleted, but it can be renamed.</p></li>
<li><p>To create additional staff accounts visit the &quot;Users&quot; page. The default user (Administrator) cannot be deleted.</p></li>
<li><p>You can create canned responses on the &quot;Canned&quot; page. These are pre-written replies to common support questions.</p></li>
<li><p>To access and manage your knowledgebase click the &quot;Knowledgebase&quot; link.</p>
<p>The knowledgebase is a collection of answers to frequently asked questions (FAQ) and articles which provide self-help resources to your customers. You can arrange articles into categories and subcategories.</p>
<p>A comprehensive and well-written knowledgebase can drastically reduce the number of support tickets you receive and save a lot of your time.</p></li>
</ul>
&nbsp;
</li>
<li><p>Customers can submit tickets and browse knowledgebase by visiting the main HESK folder, for example:<br />
<b>https://www.example.com/helpdesk</b></p></li>
<li><p style="font-weight:bold"><span class="dest">If you have problems/questions see the &quot;HELP and Troubleshooting&quot; section further down.</span></p></li>
<li><p>Support HESK development by <a href="https://www.hesk.com/buy.php">purchasing a license</a></p></li>
<li><p>Good luck with using HESK!<br />&nbsp;</p></li>
</ol>
<h2 id="upgrade">&raquo; Upgrading from old versions</h2>
<div class="error">
<p style="font-weight:bold">Please take 5 minutes to read the upgrade instructions carefully and completely! This will ensure a proper and easy upgrade.</p>
</div>
<p><b>Known upgrade issues</b></p>
<ul>
<li>HESK language may be reset to English if new text was added.</li>
<li>Passwords may not work after upgrade from very old versions (<a href="https://www.hesk.com/knowledgebase/?article=22">reset password</a>).</li>
<li>If you purchased a license you may need to <a href="https://www.hesk.com/license">download a new license</a>.</li>
</ul>
<p><span class="tip">TIP:</span> Perform the upgrade in low-traffic hours when your Web site receives the least amount of visits.</p>
<div class="notice">
<p>Your existing HESK files are contained in a single directory on your server. You will be replacing most of the contents of this directory with the contents of the folder you downloaded containing the new version of HESK.</p>
</div>
<p style="font-weight:bold">Upgrade steps:</p>
<ol>
<li>
<p><span class="dest" style="font-weight:bold">BACKUP YOUR EXISTING HESK DATABASE AND FILES</span><br />... or don't blame me if something goes wrong.</p>
<p><span class="tip">TIP:</span> Most hosting companies allow you to backup files and databases from the web hosting control panel. Contact your host if not sure how to do that.</p>
</li>
<li>
<p>Upload and place all of the new HESK files you downloaded into your existing HESK directory on your server <b>EXCEPT</b> these (do NOT upload these files):<br />
- hesk_settings.inc.php<br />
- head.txt<br />
- header.txt<br />
- footer.txt</p>
<p>Your HESK directory now contains the updated files you require for updating your copy of HESK.</p>
<p><span class="tip">TIP:</span> Images must be transferred to your server in binary mode and all other HESK files in ASCII mode. Most FTP clients will select the correct transfer mode automatically.</p>
</li>
<li>
<p>Open <b>hesk/install</b> in your browser, for example:<br />
https://www.example.com/helpdesk/install</p>
</li>
<li>
<p>HESK setup script will show up on the install URL. Click <b>UPDATE HESK</b> and follow instructions. The update consists of 4 steps:</p>
<ul>
<li><b>STEP 1: License agreement</b> - read the HESK License agreement and confirm that you agree with the terms.</li>
<li><b>STEP 2: Check setup</b> - the script will test your server to see if all required settings are correct and advise solutions to any problems.</li>
<li><b>STEP 3: Database settings</b> - check your MySQL database settings and the script will test them.<br />
<span class="dest">The settings must be the same as with your old HESK installation</span></li>
<li><b>STEP 4: Update database tables</b> - everything OK, the script will update existing MySQL tables.<br />&nbsp;</li>
</ul>
</li>
<li>
<p style="font-weight:bold">Before closing the upgrade script, <span class="dest">DELETE the &quot;install&quot; directory on your server!</span></p>
</li>
<li><p>Open the admin panel (https://www.example.com/helpdesk/admin) and log in with your username. If the password doesn't work anymore try <a href="https://www.hesk.com/knowledgebase/?article=22">resetting it</a>.</p></li>
<li><p>Test HESK to make sure the upgrade was successful and everything works. You may need to modify your Help Desk title and Custom field settings if they are not displaying correctly.</p></li>
<li>
<p>If you own a HESK license you might need to <a href="https://www.hesk.com/license">download a new one</a>.</p>
<p>If not, consider supporting HESK by <a href="https://www.hesk.com/buy.php">purchasing a license</a>.</p></li>
<li><p>Good luck with using HESK!<br />&nbsp;</p></li>
</ol>
<h2 id="help">&raquo; HELP and Troubleshooting</h2>
<div class="notice" style="font-size:15px">
<p style="text-align:center">For comprehensive and up-to-date help and troubleshooting guides please visit:<br />
<a href="https://www.hesk.com/knowledgebase/"><b>HESK Knowledgebase</b></a></p>
</div>
<h2 id="translate">&raquo; Translate HESK to your language</h2>
<p>Thanks to our users, who help translate HESK free of charge, multiple languages are available for HESK:</p>
<p><a href="https://www.hesk.com/language/">HESK language packs</a><br />&nbsp;</p>
<h2 id="other">&raquo; More FREE PHP Scripts</h2>
<p>Get more FREE PHP scripts here: <a href="https://www.phpjunkyard.com/">PHP Scripts</a>.</p>
<p>&nbsp;</p>
<p style="text-align:center">&copy; Copyright <a href="https://www.hesk.com">HESK.COM</a> 2005-2020. All rights reserved.</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,154 @@
<?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');
hesk_load_database_functions();
hesk_session_start();
// Are we in maintenance mode? (check customers only)
if ( empty($_SESSION['id']) )
{
hesk_check_maintenance();
}
// Knowledgebase attachments
if ( isset($_GET['kb_att']) )
{
// Attachment ID
$att_id = intval( hesk_GET('kb_att') ) or hesk_error($hesklang['id_not_valid']);
// Connect to database
hesk_dbConnect();
// Get attachment info
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_attachments` WHERE `att_id`='{$att_id}' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['id_not_valid'].' (att_id)');
}
$file = hesk_dbFetchAssoc($res);
// Is this person allowed access to this attachment?
$res = hesk_dbQuery("SELECT `t1`.`type` as `cat_type`, `t2`.`type` as `art_type`
FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` AS `t2`
JOIN `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` AS `t1`
ON `t2`.`catid` = `t1`.`id`
WHERE (`t2`.`attachments` LIKE '{$att_id}#%' OR `t2`.`attachments` LIKE '%,{$att_id}#%' )
LIMIT 1");
// If no attachment found, throw an error
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['id_not_valid'].' (no_art)');
}
$row = hesk_dbFetchAssoc($res);
// Private or draft article or category?
if ($row['cat_type'] || $row['art_type'])
{
if ( empty($_SESSION['id']) )
{
// This is a staff-only attachment
hesk_error($hesklang['attpri']);
}
elseif ($row['art_type'] == 2)
{
// Need permission to manage KB to access draft attachments
require(HESK_PATH . 'inc/admin_functions.inc.php');
hesk_checkPermission('can_man_kb');
}
}
}
// Ticket attachments
else
{
// Attachmend ID and ticket tracking ID
$att_id = intval( hesk_GET('att_id', 0) ) or die($hesklang['id_not_valid']);
$tic_id = hesk_cleanID() or die("$hesklang[int_error]: $hesklang[no_trackID]");
// Connect to database
hesk_dbConnect();
// Get attachment info
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` WHERE `att_id`='{$att_id}' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
hesk_error($hesklang['id_not_valid'].' (att_id)');
}
$file = hesk_dbFetchAssoc($res);
// Is ticket ID valid for this attachment?
if ($file['ticket_id'] != $tic_id)
{
hesk_error($hesklang['trackID_not_found']);
}
// Verify email address match if needed
if ( empty($_SESSION['id']) )
{
hesk_verifyEmailMatch($tic_id);
// Only staff may download attachments to notes
if ($file['type'])
{
hesk_error($hesklang['perm_deny']);
}
}
}
// Path of the file on the server
$realpath = $hesk_settings['attach_dir'] . '/' . $file['saved_name'];
// Perhaps the file has been deleted?
if ( ! file_exists($realpath))
{
hesk_error($hesklang['attdel']);
}
// Send the file as an attachment to prevent malicious code from executing
header("Pragma: "); # To fix a bug in IE when running https
header("Cache-Control: "); # To fix a bug in IE when running https
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $file['size']);
header('Content-Disposition: attachment; filename=' . $file['real_name']);
// For larger files use chunks, smaller ones can be read all at once
$chunksize = 1048576; // = 1024 * 1024 (1 Mb)
if ($file['size'] > $chunksize)
{
$handle = fopen($realpath, 'rb');
$buffer = '';
while ( ! feof($handle))
{
set_time_limit(300);
$buffer = fread($handle, $chunksize);
echo $buffer;
flush();
}
fclose($handle);
}
else
{
readfile($realpath);
}
exit();
?>

80
hesk/file_limits.php Normal file
View File

@@ -0,0 +1,80 @@
<?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');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML; 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title><?php echo $hesklang['ful']; ?></title>
<meta http-equiv="Content-Type" content="text/html;charset=<?php echo $hesklang['ENCODING']; ?>" />
<style type="text/css">
body
{
margin:5px 5px;
padding:0;
background:#fff;
color: black;
font : 68.8%/1.5 Verdana, Geneva, Arial, Helvetica, sans-serif;
text-align:left;
}
p
{
color : black;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.0em;
}
h3
{
color : #AF0000;
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 1.0em;
text-align:left;
}
</style>
</head>
<body>
<h3><?php echo $hesklang['ful']; ?></h3>
<table border="0" cellspacing="1" cellpadding="3">
<tr>
<td valign="top">&raquo;</td>
<td valign="top"><?php echo $hesklang['nat']; ?> <b><?php echo $hesk_settings['attachments']['max_number']; ?></b></td>
</tr>
<tr>
<td valign="top">&raquo;</td>
<td valign="top"><?php echo $hesklang['mfs']; ?> <b><?php echo hesk_formatBytes($hesk_settings['attachments']['max_size']); ?></b></td>
</tr>
<tr>
<td valign="top">&raquo;</td>
<td valign="top"><?php echo $hesklang['ufl']; ?>
<p><?php echo implode(', ', $hesk_settings['attachments']['allowed_types']); ?></p>
</td>
</tr>
</table>
<p align="center"><a href="#" onclick="Javascript:window.close()"><?php echo $hesklang['cwin']; ?></a></p>
<p>&nbsp;</p>
</body>
</html>

BIN
hesk/fonts/Lato-Bold.eot Normal file

Binary file not shown.

BIN
hesk/fonts/Lato-Bold.ttf Normal file

Binary file not shown.

BIN
hesk/fonts/Lato-Bold.woff Normal file

Binary file not shown.

BIN
hesk/fonts/Lato-Bold.woff2 Normal file

Binary file not shown.

BIN
hesk/fonts/Lato-Regular.eot Normal file

Binary file not shown.

BIN
hesk/fonts/Lato-Regular.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
hesk/footer.txt Normal file
View File

@@ -0,0 +1 @@
<!-- Custom code to be included before </body> tag -->

1
hesk/head.txt Normal file
View File

@@ -0,0 +1 @@
<!-- Custom code to be included before </head> tag -->

1
hesk/header.txt Normal file
View File

@@ -0,0 +1 @@
<!-- Custom code to be included after <body> tag -->

208
hesk/hesk_settings.inc.php Normal file
View File

@@ -0,0 +1,208 @@
<?php
// Settings file for HESK 3.0.0
// ==> GENERAL
// --> General settings
$hesk_settings['site_title']='Website';
$hesk_settings['site_url']='http://www.example.com';
$hesk_settings['hesk_title']='Help Desk';
$hesk_settings['hesk_url']='http://www.example.com/helpdesk';
$hesk_settings['webmaster_mail']='support@example.com';
$hesk_settings['noreply_mail']='support@example.com';
$hesk_settings['noreply_name']='Help Desk';
$hesk_settings['site_theme']='hesk3';
// --> Language settings
$hesk_settings['can_sel_lang']=0;
$hesk_settings['language']='English';
$hesk_settings['languages']=array(
'English' => array('folder'=>'en','hr'=>'------ Reply above this line ------'),
);
// --> Database settings
$hesk_settings['db_host']='localhost';
$hesk_settings['db_name']='hesk';
$hesk_settings['db_user']='test';
$hesk_settings['db_pass']='test';
$hesk_settings['db_pfix']='hesk_';
$hesk_settings['db_vrsn']=0;
// ==> HELP DESK
// --> Help desk settings
$hesk_settings['admin_dir']='admin';
$hesk_settings['attach_dir']='attachments';
$hesk_settings['cache_dir']='cache';
$hesk_settings['max_listings']=20;
$hesk_settings['print_font_size']=12;
$hesk_settings['autoclose']=0;
$hesk_settings['max_open']=0;
$hesk_settings['new_top']=0;
$hesk_settings['reply_top']=0;
// --> Features
$hesk_settings['autologin']=1;
$hesk_settings['autoassign']=1;
$hesk_settings['require_email']=1;
$hesk_settings['require_owner']=0;
$hesk_settings['require_subject']=1;
$hesk_settings['require_message']=1;
$hesk_settings['custclose']=1;
$hesk_settings['custopen']=1;
$hesk_settings['rating']=1;
$hesk_settings['cust_urgency']=1;
$hesk_settings['sequential']=1;
$hesk_settings['time_worked']=1;
$hesk_settings['spam_notice']=1;
$hesk_settings['list_users']=0;
$hesk_settings['debug_mode']=0;
$hesk_settings['short_link']=0;
$hesk_settings['select_cat']=0;
$hesk_settings['select_pri']=0;
$hesk_settings['cat_show_select']=15;
// --> SPAM prevention
$hesk_settings['secimg_use']=1;
$hesk_settings['secimg_sum']='13N4BRS4WW';
$hesk_settings['recaptcha_use']=0;
$hesk_settings['recaptcha_public_key']='';
$hesk_settings['recaptcha_private_key']='';
$hesk_settings['question_use']=0;
$hesk_settings['question_ask']='Type <i>PB6YM</i> here to fight SPAM:';
$hesk_settings['question_ans']='PB6YM';
// --> Security
$hesk_settings['attempt_limit']=6;
$hesk_settings['attempt_banmin']=60;
$hesk_settings['reset_pass']=1;
$hesk_settings['email_view_ticket']=1;
$hesk_settings['x_frame_opt']=1;
$hesk_settings['force_ssl']=0;
// --> Attachments
$hesk_settings['attachments']=array (
'use' => 1,
'max_number' => 2,
'max_size' => 2097152,
'allowed_types' => array('.gif','.jpg','.png','.zip','.rar','.csv','.doc','.docx','.xls','.xlsx','.txt','.pdf')
);
// ==> KNOWLEDGEBASE
// --> Knowledgebase settings
$hesk_settings['kb_enable']=1;
$hesk_settings['kb_wysiwyg']=1;
$hesk_settings['kb_search']=2;
$hesk_settings['kb_search_limit']=10;
$hesk_settings['kb_views']=0;
$hesk_settings['kb_date']=0;
$hesk_settings['kb_recommendanswers']=1;
$hesk_settings['kb_rating']=1;
$hesk_settings['kb_substrart']=200;
$hesk_settings['kb_cols']=2;
$hesk_settings['kb_numshow']=3;
$hesk_settings['kb_popart']=6;
$hesk_settings['kb_latest']=6;
$hesk_settings['kb_index_popart']=6;
$hesk_settings['kb_index_latest']=0;
$hesk_settings['kb_related']=5;
// ==> EMAIL
// --> Email sending
$hesk_settings['smtp']=0;
$hesk_settings['smtp_host_name']='mail.example.com';
$hesk_settings['smtp_host_port']=25;
$hesk_settings['smtp_timeout']=20;
$hesk_settings['smtp_ssl']=0;
$hesk_settings['smtp_tls']=0;
$hesk_settings['smtp_user']='';
$hesk_settings['smtp_password']='';
// --> Email piping
$hesk_settings['email_piping']=0;
// --> POP3 Fetching
$hesk_settings['pop3']=0;
$hesk_settings['pop3_job_wait']=15;
$hesk_settings['pop3_host_name']='mail.example.com';
$hesk_settings['pop3_host_port']=110;
$hesk_settings['pop3_tls']=0;
$hesk_settings['pop3_keep']=0;
$hesk_settings['pop3_user']='';
$hesk_settings['pop3_password']='';
// --> IMAP Fetching
$hesk_settings['imap']=0;
$hesk_settings['imap_job_wait']=15;
$hesk_settings['imap_host_name']='mail.example.com';
$hesk_settings['imap_host_port']=993;
$hesk_settings['imap_enc']='ssl';
$hesk_settings['imap_keep']=0;
$hesk_settings['imap_user']='';
$hesk_settings['imap_password']='';
// --> Email loops
$hesk_settings['loop_hits']=5;
$hesk_settings['loop_time']=300;
// --> Detect email typos
$hesk_settings['detect_typos']=1;
$hesk_settings['email_providers']=array('aim.com','aol.co.uk','aol.com','att.net','bellsouth.net','blueyonder.co.uk','bt.com','btinternet.com','btopenworld.com','charter.net','comcast.net','cox.net','earthlink.net','email.com','facebook.com','fastmail.fm','free.fr','freeserve.co.uk','gmail.com','gmx.at','gmx.ch','gmx.com','gmx.de','gmx.fr','gmx.net','gmx.us','googlemail.com','hotmail.be','hotmail.co.uk','hotmail.com','hotmail.com.ar','hotmail.com.mx','hotmail.de','hotmail.es','hotmail.fr','hushmail.com','icloud.com','inbox.com','laposte.net','lavabit.com','list.ru','live.be','live.co.uk','live.com','live.com.ar','live.com.mx','live.de','live.fr','love.com','lycos.com','mac.com','mail.com','mail.ru','me.com','msn.com','nate.com','naver.com','neuf.fr','ntlworld.com','o2.co.uk','online.de','orange.fr','orange.net','outlook.com','pobox.com','prodigy.net.mx','qq.com','rambler.ru','rocketmail.com','safe-mail.net','sbcglobal.net','t-online.de','talktalk.co.uk','tiscali.co.uk','verizon.net','virgin.net','virginmedia.com','wanadoo.co.uk','wanadoo.fr','yahoo.co.id','yahoo.co.in','yahoo.co.jp','yahoo.co.kr','yahoo.co.uk','yahoo.com','yahoo.com.ar','yahoo.com.mx','yahoo.com.ph','yahoo.com.sg','yahoo.de','yahoo.fr','yandex.com','yandex.ru','ymail.com');
// --> Notify customer when
$hesk_settings['notify_new']=1;
$hesk_settings['notify_skip_spam']=1;
$hesk_settings['notify_spam_tags']=array('Spam?}','***SPAM***','[SPAM]','SPAM-LOW:','SPAM-MED:');
$hesk_settings['notify_closed']=1;
// --> Other
$hesk_settings['strip_quoted']=1;
$hesk_settings['eml_req_msg']=0;
$hesk_settings['save_embedded']=1;
$hesk_settings['multi_eml']=0;
$hesk_settings['confirm_email']=0;
$hesk_settings['open_only']=1;
// ==> TICKET LIST
$hesk_settings['ticket_list']=array('trackid','lastchange','name','subject','status','lastreplier');
// --> Other
$hesk_settings['submittedformat']=2;
$hesk_settings['updatedformat']=2;
// ==> MISC
// --> Date & Time
$hesk_settings['timezone']='UTC';
$hesk_settings['timeformat']='Y-m-d H:i:s';
// --> Other
$hesk_settings['ip_whois']='https://whois.domaintools.com/{IP}';
$hesk_settings['maintenance_mode']=0;
$hesk_settings['alink']=1;
$hesk_settings['submit_notice']=0;
$hesk_settings['online']=0;
$hesk_settings['online_min']=10;
$hesk_settings['check_updates']=1;
#############################
# DO NOT EDIT BELOW #
#############################
$hesk_settings['hesk_version']='3.0.0';
if ($hesk_settings['debug_mode'])
{
error_reporting(E_ALL);
}
else
{
error_reporting(0);
}
if (!defined('IN_SCRIPT')) {die('Invalid attempt!');}

BIN
hesk/img/branch.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 B

BIN
hesk/img/branchbottom.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 B

BIN
hesk/img/branchtop.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="6" viewBox="0 0 8 6">
<path fill="#26282A" fill-rule="evenodd" d="M4.303 5.07l3.553-3.552a.434.434 0 0 0 .128-.309A.434.434 0 0 0 7.856.9L7.595.64a.437.437 0 0 0-.618 0L3.994 3.622 1.007.635a.434.434 0 0 0-.618 0L.128.897A.434.434 0 0 0 0 1.206c0 .117.045.226.128.309L3.684 5.07a.434.434 0 0 0 .31.127.434.434 0 0 0 .31-.127z"/>
</svg>

After

Width:  |  Height:  |  Size: 398 B

BIN
hesk/img/hero-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

8
hesk/img/index.htm Normal file
View File

@@ -0,0 +1,8 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>403 Forbidden</TITLE>
</HEAD><BODY>
<H1>Forbidden</H1>
You don't have permission to access this folder.<P>
<hr />
</BODY></HTML>

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="12" viewBox="0 0 16 12">
<path fill="#e64342" fill-rule="nonzero" d="M12.992 6L16 12H1.719C.769 12 0 11.232 0 10.286V1.714C0 .768.77 0 1.719 0H16l-3.008 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 229 B

3
hesk/img/label-high.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="12" viewBox="0 0 16 12">
<path fill="#ffc200" fill-rule="nonzero" d="M12.992 6L16 12H1.719C.769 12 0 11.232 0 10.286V1.714C0 .768.77 0 1.719 0H16l-3.008 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 229 B

3
hesk/img/label-low.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="12" viewBox="0 0 16 12">
<path fill="#959EB0" fill-rule="nonzero" d="M12.992 6L16 12H1.719C.769 12 0 11.232 0 10.286V1.714C0 .768.77 0 1.719 0H16l-3.008 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 229 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="12" viewBox="0 0 16 12">
<path fill="#38bc7d" fill-rule="nonzero" d="M12.992 6L16 12H1.719C.769 12 0 11.232 0 10.286V1.714C0 .768.77 0 1.719 0H16l-3.008 6z"/>
</svg>

After

Width:  |  Height:  |  Size: 229 B

BIN
hesk/img/line.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 B

BIN
hesk/img/linebottom.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 B

BIN
hesk/img/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
hesk/img/minus.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

BIN
hesk/img/minusbottom.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

BIN
hesk/img/minustop.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 B

BIN
hesk/img/plus.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

BIN
hesk/img/plusbottom.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

BIN
hesk/img/plustop.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

162
hesk/img/sprite.svg Normal file
View File

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-01-normal-knowledge-b" viewBox="0 0 24 20">
<g fill-rule="evenodd">
<path d="M0-2h24v24H0z"/>
<path fill-opacity=".5" d="M22.978 4.004H19.98V.008c-3.12 0-5.947 1.266-7.993 3.313A11.266 11.266 0 0 0 3.996.008v3.996H.999c-.55 0-.999.45-.999.999V16.99c0 .55.45 1 .999 1H9.99a1.997 1.997 0 1 0 3.996 0h8.992c.549 0 .999-.45.999-1V5.003c0-.548-.45-1-1-1zm-9.99 1.143l.413-.414a9.238 9.238 0 0 1 4.581-2.512v8.61a13.158 13.158 0 0 0-4.995 1.858V5.147zM5.993 2.221a9.231 9.231 0 0 1 4.581 2.513l.414.414v7.54a13.148 13.148 0 0 0-4.995-1.857v-8.61zm15.984 13.771H1.998v-9.99h1.998v6.679c3.12 0 5.946 1.266 7.992 3.311a11.273 11.273 0 0 1 7.993-3.311V6.002h1.997v9.99z"/>
</g>
</symbol><symbol id="icon-01-normal-team" viewBox="0 0 24 17">
<path fill-opacity=".5" fill-rule="evenodd" d="M16.079 9.659a8.437 8.437 0 0 0-2.294-1.496c.311-.31.58-.663.796-1.048a2.677 2.677 0 0 0 3.768-2.44 2.677 2.677 0 0 0-3.866-2.395A4.818 4.818 0 0 0 12.91.707 4.752 4.752 0 0 1 15.41 0a4.786 4.786 0 0 1 4.78 4.78c0 1.32-.537 2.517-1.405 3.383 2.962 1.303 5.035 4.265 5.035 7.702 0 .582-.472 1.053-1.054 1.053h-5c.582 0 1.054-.471 1.054-1.053 0-.343-.021-.682-.061-1.015h2.672a6.318 6.318 0 0 0-5.352-5.191zm-4.294-1.496c2.962 1.303 5.035 4.265 5.035 7.702 0 .582-.472 1.053-1.054 1.053H1.053A1.053 1.053 0 0 1 0 15.865c0-3.437 2.073-6.399 5.034-7.702A4.766 4.766 0 0 1 3.63 4.781 4.786 4.786 0 0 1 8.409 0a4.786 4.786 0 0 1 4.782 4.78c0 1.32-.538 2.517-1.406 3.383zM8.375 2A2.677 2.677 0 0 0 5.7 4.674C5.7 6.15 6.9 7.35 8.374 7.35c1.475 0 2.675-1.2 2.675-2.675C11.049 3.2 9.849 2 8.374 2zM2.1 14.95h12.43A6.313 6.313 0 0 0 8.316 9.7 6.313 6.313 0 0 0 2.1 14.95z"/>
</symbol><symbol id="icon-01-normal-tickets" viewBox="0 0 18 22">
<path fill-opacity=".5" fill-rule="evenodd" d="M15 3h1a2 2 0 0 1 2 2v15a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h1a2 2 0 0 1 2-2h.996C6.748.363 7.839 0 9 0c1.16 0 2.252.363 3.004 1H13a2 2 0 0 1 2 2zM3.268 5H2v15h14V5h-1.268A2 2 0 0 1 13 6H5a2 2 0 0 1-1.732-1zm3.889-2.345l-.3.345H5v1h8V3h-1.858l-.299-.345C10.515 2.277 9.811 2 9 2c-.81 0-1.515.277-1.843.655zM5 15v-2h6v2H5zm0-4V9h8v2H5z"/>
</symbol><symbol id="icon-actions" viewBox="0 0 16 13">
<path d="M5.818 7.273h8.727V5.09H5.818v2.182zm-1.454 0V5.09h-2.91v2.182h2.91zm1.454-5.818v2.181h8.727V1.455H5.818zm-1.454 0h-2.91v2.181h2.91V1.455zm1.454 9.454h8.727V8.727H5.818v2.182zm-1.454 0V8.727h-2.91v2.182h2.91zM1.454 0h13.091C15.35 0 16 .651 16 1.455v9.454c0 .803-.651 1.455-1.455 1.455H1.455A1.455 1.455 0 0 1 0 10.909V1.455C0 .65.651 0 1.455 0z"/>
</symbol><symbol id="icon-add" viewBox="0 0 16 16">
<path d="M8.727 7.273h2.182a.727.727 0 0 1 0 1.454H8.727v2.182a.727.727 0 0 1-1.454 0V8.727H5.09a.727.727 0 1 1 0-1.454h2.182V5.09a.727.727 0 1 1 1.454 0v2.182zM8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm0-1.455a6.545 6.545 0 1 0 0-13.09 6.545 6.545 0 0 0 0 13.09z"/>
</symbol><symbol id="icon-anonymize" viewBox="0 0 14 16">
<path fill-rule="evenodd" d="M7.045 16C2.682 14.056.5 12.117.5 10.182V2.909c0-.727.364-.727 1.455-1.454C2.072 1.376 4.546 0 7.045 0c2.179 0 4 .727 5.091 1.455 1.091.727 1.455.727 1.455 1.454.02.212 0 6.182 0 7.273 0 1.94-2.182 3.879-6.546 5.818zm5.091-5.818l.002-.906.003-1.42.002-1.23a898.03 898.03 0 0 0 0-3.448c-.24-.15-.616-.381-.813-.513-1.074-.716-2.64-1.21-4.285-1.21-1.572 0-3.615.764-4.284 1.21-.196.13-.566.359-.806.508v7.009c0 1.097 1.62 2.595 5.091 4.22 3.47-1.621 5.09-3.119 5.09-4.22zM6.318 8.426L9.44 5.304l1.029 1.028-4.15 4.151-2.697-2.696 1.029-1.029 1.667 1.668z"/>
</symbol><symbol id="icon-assign-no" viewBox="0 0 23 24">
<path fill-rule="evenodd" d="M5.74 12.815a6.97 6.97 0 0 1-2.342-5.532A6.983 6.983 0 0 1 10.02 0a6.983 6.983 0 0 1 6.62 7.283 6.984 6.984 0 0 1-6.62 7.283c-3.65 0-6.62 2.375-6.62 5.296a1.324 1.324 0 0 1-2.649 0c0-3.06 2.028-5.72 4.99-7.047zm4.28-10.167a4.347 4.347 0 0 0-3.972 4.635 4.347 4.347 0 0 0 3.972 4.634 4.347 4.347 0 0 0 3.972-4.634 4.347 4.347 0 0 0-3.972-4.635zm7.945 17.763l-2.926 2.926-1.873-1.873 2.926-2.926-2.926-2.926 1.873-1.873 2.926 2.926 2.926-2.926 1.872 1.873-2.926 2.926 2.926 2.926-1.872 1.873-2.926-2.926z"/>
</symbol><symbol id="icon-assign-plus" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M11.093 13.241H8.334v-1.765h2.76V8.717h1.765v2.759h2.758v1.765H12.86V16h-1.766v-2.759zM3.827 8.544a4.647 4.647 0 0 1-1.561-3.689A4.656 4.656 0 0 1 6.679 0a4.656 4.656 0 0 1 4.414 4.855A4.656 4.656 0 0 1 6.68 9.71c-2.434 0-4.413 1.584-4.413 3.531a.883.883 0 0 1-1.766 0c0-2.04 1.352-3.813 3.327-4.697zm2.852-6.778a2.898 2.898 0 0 0-2.648 3.09 2.898 2.898 0 0 0 2.648 3.089 2.898 2.898 0 0 0 2.649-3.09 2.898 2.898 0 0 0-2.649-3.09z"/>
</symbol><symbol id="icon-assign" viewBox="0 0 19 22">
<path fill-rule="evenodd" d="M13.566 12.8c2.983 1.32 5.027 3.99 5.027 7.062a1.324 1.324 0 0 1-2.648 0c0-2.921-2.97-5.296-6.62-5.296a1.35 1.35 0 0 1-.056 0c-3.65 0-6.62 2.375-6.62 5.296a1.324 1.324 0 0 1-2.649 0c0-3.06 2.028-5.72 4.99-7.047a6.97 6.97 0 0 1-2.342-5.532A6.983 6.983 0 0 1 9.27 0a6.983 6.983 0 0 1 6.62 7.283 6.97 6.97 0 0 1-2.323 5.516zM9.269 2.647a4.347 4.347 0 0 0-3.972 4.635 4.347 4.347 0 0 0 3.972 4.634 4.347 4.347 0 0 0 3.972-4.634A4.347 4.347 0 0 0 9.27 2.648z"/>
</symbol><symbol id="icon-attach" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M9.074 3.635l1.14 1.123L5.16 9.89a.669.669 0 0 0 0 .934c.24.246.642.245.88 0l5.562-5.65a2.137 2.137 0 0 0 0-2.988c-.775-.79-2.145-.773-2.905.002L2.627 8.35a3.604 3.604 0 0 0 0 5.04c1.331 1.358 3.617 1.335 4.927-.001l7.08-7.19 1.14 1.123-7.078 7.188c-1.931 1.97-5.248 2.003-7.21 0a5.204 5.204 0 0 1 0-7.282l6.07-6.162c1.379-1.406 3.78-1.437 5.188 0a3.737 3.737 0 0 1 0 5.229l-5.559 5.646a2.217 2.217 0 0 1-3.168.003 2.27 2.27 0 0 1 .001-3.175l5.056-5.134z"/>
</symbol><symbol id="icon-back" viewBox="0 0 20 6">
<path fill-rule="evenodd" d="M4 4v2L0 3l4-3v2h16v2H4z"/>
</symbol><symbol id="icon-calendar" viewBox="0 0 20 20">
<path d="M18 6V3h-2v1h-2V3H6v1H4V3H2v3h16zm0 2H2v10h16V8zm-2-7h2a2 2 0 0 1 2 2v15a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h2V0h2v1h8V0h2v1zM7 12H5v-2h2v2zm4 0H9v-2h2v2zm4 0h-2v-2h2v2zm-8 4H5v-2h2v2zm4 0H9v-2h2v2z"/>
</symbol><symbol id="icon-categories" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M0 0v5.455h5.455V0H0zm1.818 1.818h1.818v1.818H1.818V1.818zm5.455 0v1.818H20V1.818H7.273zM0 7.273v5.455h5.455V7.271H0zM1.818 9.09h1.818v1.818H1.818V9.091zm5.455 0v1.818H20V9.091H7.273zM0 14.545V20h5.455v-5.455H0zm1.818 1.819h1.818v1.818H1.818v-1.818zm5.455 0v1.818H20v-1.818H7.273z"/>
</symbol><symbol id="icon-chevron-down" viewBox="0 0 8 6">
<path fill-rule="evenodd" d="M4.303 5.07l3.553-3.552a.434.434 0 0 0 .128-.309A.434.434 0 0 0 7.856.9L7.595.64a.437.437 0 0 0-.618 0L3.994 3.622 1.007.635a.434.434 0 0 0-.618 0L.128.897A.434.434 0 0 0 0 1.206c0 .117.045.226.128.309L3.684 5.07a.434.434 0 0 0 .31.127.434.434 0 0 0 .31-.127z"/>
</symbol><symbol id="icon-chevron-left" viewBox="0 0 20 20">
<title>
chevron-thin-left
</title>
<path d="M13.891 17.418c.268.272.268.709 0 .979s-.701.271-.969 0l-7.83-7.908a.697.697 0 0 1 0-.979l7.83-7.908c.268-.27.701-.27.969 0s.268.709 0 .979L6.75 10l7.141 7.418z"/>
</symbol><symbol id="icon-chevron-right" viewBox="0 0 20 20">
<title>
chevron-thin-right
</title>
<path d="M13.25 10L6.109 2.58a.697.697 0 0 1 0-.979.68.68 0 0 1 .969 0l7.83 7.908a.697.697 0 0 1 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0s-.268-.707 0-.979L13.25 10z"/>
</symbol><symbol id="icon-close-mobile" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.414 15.414L0 14l6.293-6.293L0 1.414 1.414 0l6.293 6.293L14 0l1.414 1.414-6.293 6.293L15.414 14 14 15.414 7.707 9.121z"/>
</symbol><symbol id="icon-close" viewBox="0 0 6 6">
<path fill-rule="evenodd" d="M5.828 4.996L3.833 3l1.995-1.996a.589.589 0 0 0-.832-.832L3 2.167 1.004.172a.589.589 0 0 0-.832.832L2.167 3 .172 4.996a.589.589 0 0 0 .832.832L3 3.833l1.996 1.995a.589.589 0 0 0 .832-.832z"/>
</symbol><symbol id="icon-cross" viewBox="0 0 6 6">
<path d="M3.938 2.91l1.667 1.667a.727.727 0 0 1-1.028 1.028L2.909 3.938 1.242 5.605A.727.727 0 0 1 .213 4.577l1.668-1.668L.213 1.242A.727.727 0 1 1 1.242.213l1.667 1.668L4.577.213a.727.727 0 0 1 1.028 1.029L3.938 2.909z"/>
</symbol><symbol id="icon-delete" viewBox="0 0 15 16">
<path fill-rule="evenodd" d="M3.636 2.182v-.727C3.636.65 4.288 0 5.091 0h4.364c.803 0 1.454.651 1.454 1.455v.727h2.182c.803 0 1.454.651 1.454 1.454v1.455c0 .803-.65 1.454-1.454 1.454h-.058l-.67 8c0 .804-.65 1.455-1.454 1.455H3.636c-.803 0-1.454-.651-1.452-1.394l-.671-8.06h-.058A1.455 1.455 0 0 1 0 5.09V3.636c0-.803.651-1.454 1.455-1.454h2.181zm0 1.454H1.455v1.455H13.09V3.636H3.636zm-.664 2.91l.664 8h7.273l.003-.06.661-7.94H2.972zm6.483-4.364v-.727H5.09v.727h4.364z"/>
</symbol><symbol id="icon-dismiss" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm0-1.455a6.545 6.545 0 1 0 0-13.09 6.545 6.545 0 0 0 0 13.09zm0-7.574L9.543 5.43a.727.727 0 0 1 1.028 1.028L9.03 8l1.542 1.543a.727.727 0 1 1-1.028 1.028L8 9.03l-1.543 1.54A.727.727 0 1 1 5.43 9.543L6.97 8 5.43 6.457A.727.727 0 0 1 6.457 5.43L8 6.97z"/>
</symbol><symbol id="icon-document" viewBox="0 0 20 24">
<path d="M13.793 0l6.093 6.094v15.724A2.182 2.182 0 0 1 17.705 24H2.432A2.182 2.182 0 0 1 .25 21.818V2.182C.25.977 1.227 0 2.432 0h11.36zm-2.634 2.181H2.432v19.637h15.273l-.001-13.091h-4.363a2.182 2.182 0 0 1-2.182-2.182V2.181zm1.091 13.092v2.182H5.705v-2.182h6.545zm2.182-4.364v2.182H5.705v-2.182h8.727zM13.34 2.632v3.913h3.912L13.34 2.632z"/>
</symbol><symbol id="icon-down" viewBox="0 0 8 6">
<path fill-rule="evenodd" d="M4.303 5.07l3.553-3.552a.434.434 0 0 0 .128-.309A.434.434 0 0 0 7.856.9L7.595.64a.437.437 0 0 0-.618 0L3.994 3.622 1.007.635a.434.434 0 0 0-.618 0L.128.897A.434.434 0 0 0 0 1.206c0 .117.045.226.128.309L3.684 5.07a.434.434 0 0 0 .31.127.434.434 0 0 0 .31-.127z"/>
</symbol><symbol id="icon-edit-ticket" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10.242 3.556L5.357 8.44c-.324.286-.525.687-.557 1.054v1.708l1.651.002c.428-.03.825-.23 1.145-.595l4.85-4.85-2.204-2.203zm1.131-1.131l2.204 2.203.715-.715a.37.37 0 0 0 0-.522l-1.683-1.683a.365.365 0 0 0-.518 0l-.718.717zM16 8.8v5.6a1.6 1.6 0 0 1-1.6 1.6H1.6A1.6 1.6 0 0 1 0 14.4V1.6A1.6 1.6 0 0 1 1.6 0h5.6v1.6H1.6v12.8h12.8V8.8H16zM12.35 0c.524 0 1.026.21 1.392.579l1.681 1.68a1.97 1.97 0 0 1 0 2.786l-6.657 6.654c-.559.645-1.35 1.04-2.258 1.103H3.2v-.8l.003-2.572A3.238 3.238 0 0 1 4.26 7.275L10.956.58c.37-.371.87-.58 1.394-.58z"/>
</symbol><symbol id="icon-edit" viewBox="0 0 16 16">
<path d="M8.727 1.756L1.455 9.029v1.88h1.88l7.273-7.273-1.88-1.88zM9.242.213l2.909 2.91a.727.727 0 0 1 0 1.028l-8 8a.727.727 0 0 1-.515.213H.727A.727.727 0 0 1 0 11.636V8.727c0-.193.077-.378.213-.514l8-8a.727.727 0 0 1 1.029 0zM.8 16c-.442 0-.8-.326-.8-.727 0-.402.358-.728.8-.728h14.4c.442 0 .8.326.8.728 0 .401-.358.727-.8.727H.8z"/>
</symbol><symbol id="icon-export" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M16 11.2v3.2a1.6 1.6 0 0 1-1.6 1.6H1.6A1.6 1.6 0 0 1 0 14.4v-3.2h1.6v3.2h12.8v-3.2H16zm-8.512-.015L4.229 7.927a.817.817 0 0 1 1.155-1.155l1.872 1.872V.817a.817.817 0 0 1 1.633 0v7.827l1.873-1.872a.817.817 0 0 1 1.155 1.155l-3.26 3.258a.814.814 0 0 1-1.17 0z"/>
</symbol><symbol id="icon-eye-close" viewBox="0 0 16 12">
<path fill-rule="evenodd" d="M.07 5.702c.094-.188.27-.5.526-.897.424-.657.925-1.313 1.501-1.928C3.774 1.088 5.747 0 8 0c2.253 0 4.226 1.088 5.903 2.877a13.596 13.596 0 0 1 2.027 2.825.667.667 0 0 1 0 .596c-.094.188-.27.5-.526.897a13.661 13.661 0 0 1-1.501 1.928C12.226 10.912 10.253 12 8 12c-2.253 0-4.226-1.088-5.903-2.877a13.661 13.661 0 0 1-1.5-1.928 9.934 9.934 0 0 1-.527-.897.667.667 0 0 1 0-.596zm1.646.77c.383.593.836 1.187 1.354 1.739 1.447 1.544 3.1 2.456 4.93 2.456 1.83 0 3.483-.912 4.93-2.456A12.342 12.342 0 0 0 14.573 6a12.342 12.342 0 0 0-1.643-2.21C11.483 2.244 9.83 1.332 8 1.332c-1.83 0-3.483.912-4.93 2.456A12.342 12.342 0 0 0 1.427 6c.084.145.18.303.29.472zM8 8.667a2.667 2.667 0 1 1 0-5.334 2.667 2.667 0 0 1 0 5.334zm0-1.334a1.333 1.333 0 1 0 0-2.666 1.333 1.333 0 0 0 0 2.666z"/>
</symbol><symbol id="icon-eye-open" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.187 3.13C5.351 2.407 6.623 2 8 2c2.253 0 4.226 1.088 5.903 2.877a13.596 13.596 0 0 1 2.027 2.825.667.667 0 0 1 0 .596c-.094.188-.27.5-.526.897a13.661 13.661 0 0 1-1.501 1.928 11.81 11.81 0 0 1-.877.846L16 14.943 14.943 16l-3.13-3.13C10.649 13.593 9.377 14 8 14c-2.253 0-4.226-1.088-5.903-2.877a13.661 13.661 0 0 1-1.5-1.928 9.934 9.934 0 0 1-.527-.897.667.667 0 0 1 0-.596c.094-.188.27-.5.526-.897.424-.657.925-1.313 1.501-1.928.284-.303.576-.585.877-.846L0 1.057 1.057 0l3.13 3.13zm.975.975l1.556 1.556a2.667 2.667 0 0 1 3.62 3.62l1.742 1.742c.29-.246.574-.518.85-.812A12.342 12.342 0 0 0 14.573 8a12.342 12.342 0 0 0-1.643-2.21C11.483 4.244 9.83 3.332 8 3.332c-1 0-1.948.273-2.838.772zm2.585 2.586L9.31 8.253A1.333 1.333 0 0 0 7.747 6.69zm3.091 5.204l-1.556-1.556a2.667 2.667 0 0 1-3.62-3.62L3.92 4.976c-.29.246-.574.518-.85.812A12.342 12.342 0 0 0 1.427 8a12.342 12.342 0 0 0 1.643 2.21c1.447 1.545 3.1 2.457 4.93 2.457 1 0 1.948-.273 2.838-.772zM8.253 9.309L6.69 7.747A1.333 1.333 0 0 0 8.253 9.31z"/>
</symbol><symbol id="icon-filters" viewBox="0 0 16 16">
<path d="M9.237 8.404l4.2-4.584H2.563l4.2 4.584h2.474zM8.8 9.932H7.2v3.863l1.6-.573v-3.29zm-7.2-7.64h12.8v-.764H1.6v.764zm4 7.163L0 3.343V1.528C0 .684.716 0 1.6 0h12.8c.884 0 1.6.684 1.6 1.528v1.815l-5.6 6.112v4.826L5.6 16V9.455z"/>
</symbol><symbol id="icon-folder" viewBox="0 0 22 18">
<path d="M8 0c1.12 0 1.833.475 2.549 1.379.048.06.261.337.313.402.158.195.19.219.14.219H18a2 2 0 0 1 2 2v1a2 2 0 0 1 2 2l-.024.217-1.98 8.91A2 2 0 0 1 18 18H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h6zm11.976 7H4.036a4.6 4.6 0 0 0-.06.217L2.024 16H18l.024-.217L19.976 7zM8 2H2v4.89l.03-.13C2.31 5.621 2.832 5 4 5h14V4h-7.005c-.719-.004-1.186-.34-1.69-.963-.069-.086-.29-.373-.323-.416C8.607 2.15 8.384 2 8 2z" fill-rule="evenodd"/>
</symbol><symbol id="icon-info" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 14.5a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13zM8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm1-4H7V7h2v5zM7.997 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol><symbol id="icon-inquiries" viewBox="0 0 40 40">
<path fill-rule="evenodd" d="M39.275 4.563l-4.687 2.344-1.049-2.096 4.688-2.344 1.048 2.096zm-1.048 18.752l-4.688-2.344 1.048-2.096 4.688 2.344-1.048 2.096zm-2.993-11.596H40v2.344h-4.766v-2.344zM1.774 2.467l4.687 2.344-1.048 2.096L.726 4.564l1.048-2.097zm0 20.847l-1.05-2.096 4.688-2.344L6.46 20.97l-4.688 2.344zM0 11.719h4.766v2.344H0v-2.344zm16.484 25.937h7.032V40h-7.032v-2.344zm16.407-24.765c0 4.846-2.736 9.266-7.032 11.465v3.769h2.344v2.344H25.86v4.843H14.141V30.47h-2.344v-2.344h2.344v-3.769c-4.296-2.199-7.032-6.619-7.032-11.465C7.11 5.783 12.892 0 20 0s12.89 5.783 12.89 12.89zm-9.375 20.078v-2.5h-7.032v2.5h7.032zm-4.688-17.735c0 .646.526 1.172 1.172 1.172.646 0 1.172-.526 1.172-1.172a1.173 1.173 0 0 0-2.344 0zm2.344 12.891h2.344v-5.274l.7-.308c3.846-1.688 6.33-5.477 6.33-9.652 0-5.816-4.73-10.547-10.546-10.547-5.815 0-10.547 4.731-10.547 10.547 0 4.175 2.485 7.964 6.33 9.652l.701.308v5.274h2.344v-9.576a3.521 3.521 0 0 1-2.344-3.315A3.52 3.52 0 0 1 20 11.72a3.52 3.52 0 0 1 3.516 3.515c0 1.528-.98 2.83-2.344 3.315v9.576z"/>
</symbol><symbol id="icon-knowledge" viewBox="0 0 24 20">
<path fill-rule="evenodd" d="M22.978 4.004H19.98V.008c-3.12 0-5.947 1.266-7.993 3.313A11.266 11.266 0 0 0 3.996.008v3.996H.999c-.55 0-.999.45-.999.999V16.99c0 .55.45 1 .999 1H9.99a1.997 1.997 0 1 0 3.996 0h8.992c.549 0 .999-.45.999-1V5.003c0-.548-.45-1-1-1zm-9.99 1.143l.413-.414a9.238 9.238 0 0 1 4.581-2.512v8.61a13.158 13.158 0 0 0-4.995 1.858V5.147zM5.993 2.221a9.231 9.231 0 0 1 4.581 2.513l.414.414v7.54a13.148 13.148 0 0 0-4.995-1.857v-8.61zm15.984 13.771H1.998v-9.99h1.998v6.679c3.12 0 5.946 1.266 7.992 3.311a11.273 11.273 0 0 1 7.993-3.311V6.002h1.997v9.99z"/>
</symbol><symbol id="icon-label" viewBox="0 0 16 12">
<path d="M12.992 6L16 12H1.719C.769 12 0 11.232 0 10.286V1.714C0 .768.77 0 1.719 0H16l-3.008 6z"/>
</symbol><symbol id="icon-lock" viewBox="0 0 14 16">
<path fill-rule="evenodd" d="M3 6.4V4a4 4 0 1 1 8 0v2.4h.8c.855 0 1.6.621 1.6 1.467v6.666c0 .846-.745 1.467-1.6 1.467H2.2c-.855 0-1.6-.621-1.6-1.467V7.867C.6 7.02 1.345 6.4 2.2 6.4H3zm1.6 0h4.8V4a2.4 2.4 0 1 0-4.8 0v2.4zM2.2 8v6.4h9.6V8H2.2zm5 4.4a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol><symbol id="icon-log-out" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.864 16H1.621A1.61 1.61 0 0 1 0 14.4V1.6C0 .716.726 0 1.621 0h3.243v1.6H1.621v12.8h3.243V16zm10.813-7.691l-3.259 3.302a.809.809 0 0 1-1.145-.01.835.835 0 0 1-.01-1.16l1.873-1.897H5.308a.822.822 0 0 1-.817-.828c0-.457.366-.827.817-.827h7.828L11.263 4.99a.835.835 0 0 1 .01-1.16.809.809 0 0 1 1.145-.01l3.259 3.302a.83.83 0 0 1 .247.593.83.83 0 0 1-.247.593z"/>
</symbol><symbol id="icon-mail-small" viewBox="0 0 16 14">
<path fill-rule="evenodd" d="M14.545 3.787V2.055H1.455v1.732L8 7.06l6.545-3.273zm0 1.626L8 8.686 1.455 5.413v6.823h13.09V5.413zM1.455.6h13.09C15.35.6 16 1.251 16 2.055v10.181c0 .804-.651 1.455-1.455 1.455H1.455A1.455 1.455 0 0 1 0 12.236V2.055C0 1.25.651.6 1.455.6z"/>
</symbol><symbol id="icon-mail" viewBox="0 0 22 18">
<path fill-rule="evenodd" d="M20 4.382V2H2v2.382l9 4.5 9-4.5zm0 2.237l-9 4.5-9-4.5V16h18V6.619zM2 0h18a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2z"/>
</symbol><symbol id="icon-menu-mobile" viewBox="0 0 16 14">
<path fill-rule="evenodd" d="M16 12v2H0v-2h16zm0-6v2H0V6h16zm0-6v2H0V0h16z"/>
</symbol><symbol id="icon-menu" viewBox="0 0 20 14">
<path fill-rule="evenodd" d="M4 8v2L0 7l4-3v2h16v2H4zm16 4v2H6v-2h14zm0-12v2H6V0h14z"/>
</symbol><symbol id="icon-merge" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10.967 10.667v3.81c0 .877-.646 1.523-1.524 1.523h-7.62C.947 16 .3 15.354.3 14.476V6.857c0-.878.646-1.524 1.524-1.524H5.11v-3.81C5.11.647 5.755 0 6.633 0h7.62c.877 0 1.523.646 1.523 1.524v7.619c0 .878-.646 1.524-1.524 1.524h-3.285zm-1.524 0h-2.81c-.878 0-1.523-.646-1.523-1.524V6.857H1.824v7.62h7.619v-3.81zm1.524-1.524h3.285v-7.62H6.633v3.81h2.81c.878 0 1.524.646 1.524 1.524v2.286zm-1.524 0V6.857h-2.81v2.286h2.81z"/>
</symbol><symbol id="icon-move-to" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M11.227 1.756v2.608h2.608l-2.608-2.608zm2.909 4.062h-2.909a1.454 1.454 0 0 1-1.454-1.454V1.455H1.955v13.091h12.181V5.818zM1.955 0h9.573l4.063 4.063v10.483c0 .803-.652 1.454-1.455 1.454H1.955A1.454 1.454 0 0 1 .5 14.546V1.455C.5.652 1.151 0 1.955 0zm7.366 9.831H4.32a.335.335 0 0 1-.334-.334v-.786c0-.184.15-.334.334-.334h5.001l-.941-.941 1.029-1.028 2.342 2.342a.5.5 0 0 1 0 .708L9.409 11.8 8.38 10.772l.941-.941z"/>
</symbol><symbol id="icon-no-photo" viewBox="0 0 78 115">
<path d="M76.141 115H1.857A1.859 1.859 0 0 1 0 113.142V68.955c0-2.721 1.839-5.175 4.685-6.247l20.146-7.589a1.857 1.857 0 0 1 2.27.82l10.746 18.876c.33.58.966.624 1.154.624.188 0 .822-.045 1.152-.623l10.75-18.876a1.857 1.857 0 0 1 2.33-.794l20.36 8.522c2.676 1.12 4.407 3.53 4.407 6.136v43.338A1.86 1.86 0 0 1 76.141 115zm-72.427-3.715h70.57V69.804c0-1.122-.813-2.16-2.126-2.709l-18.843-7.888-9.937 17.448c-.89 1.565-2.527 2.5-4.377 2.5-1.852 0-3.49-.933-4.38-2.5l-9.965-17.497-18.661 7.03c-1.386.52-2.28 1.606-2.28 2.767v42.33zM39 52c-13.233 0-24-10.118-24-22.554v-6.892C15 10.118 25.767 0 39 0c13.23 0 24 10.118 24 22.554v6.892C63 41.883 52.231 52 39 52zm0-48.247c-11.146 0-20.212 8.435-20.212 18.8v6.893c0 10.366 9.068 18.801 20.211 18.801 11.143 0 20.213-8.435 20.213-18.8v-6.893c0-10.366-9.068-18.801-20.213-18.801z"/>
</symbol><symbol id="icon-note" viewBox="0 0 16 16">
<path d="M14.4 10.4V1.6H1.6v12.8h8.8V12a1.6 1.6 0 0 1 1.6-1.6h2.4zm-.331 1.6H12v2.069L14.069 12zM1.6 16A1.6 1.6 0 0 1 0 14.4V1.6A1.6 1.6 0 0 1 1.6 0h12.8A1.6 1.6 0 0 1 16 1.6v10.731L12.331 16H1.6zM4 12v-1.6h4.8V12H4zm0-3.2V7.2h8v1.6H4zm0-3.2V4h8v1.6H4z" fill-rule="evenodd"/>
</symbol><symbol id="icon-notes-2" viewBox="0 0 16 16">
<g fill-rule="evenodd">
<path d="M0 0h16v16H0z"/>
<path d="M14.4 10.4V1.6H1.6v12.8h8.8V12a1.6 1.6 0 0 1 1.6-1.6h2.4zm-.331 1.6H12v2.069L14.069 12zM1.6 16A1.6 1.6 0 0 1 0 14.4V1.6A1.6 1.6 0 0 1 1.6 0h12.8A1.6 1.6 0 0 1 16 1.6v10.731L12.331 16H1.6zM4 12v-1.6h4.8V12H4zm0-3.2V7.2h8v1.6H4zm0-3.2V4h8v1.6H4z"/>
</g>
</symbol><symbol id="icon-notification" viewBox="0 0 20 22">
<path fill-rule="evenodd" d="M8.135 1.276a2 2 0 0 1 3.73.002C14.762 2.123 17 4.94 17 9c0 2.625.532 4.102 1.515 5.177.244.266 1.101 1.038 1.197 1.135l.288.292v3.41h-6.126a3.941 3.941 0 0 1-1.786 2.409 4.008 4.008 0 0 1-4.176 0c-1.042-.636-1.618-1.347-1.824-2.409H0v-3.41l.288-.292c.104-.105.956-.87 1.198-1.133C2.469 13.11 3 11.634 3 9c0-4.07 2.235-6.882 5.135-7.724zm.044 17.738c.14.263.382.461.775.701.642.392 1.45.392 2.092 0 .297-.181.53-.421.69-.7H8.18zM18 16.452c-.298-.275-.75-.695-.96-.925C15.706 14.07 15 12.107 15 9c0-3.769-2.34-5.988-5-5.988C7.333 3.012 5 5.22 5 9c0 3.118-.706 5.08-2.042 6.533-.21.228-.662.648-.958.92v.561h16v-.562z"/>
</symbol><symbol id="icon-pause" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm0-1.455a6.545 6.545 0 1 0 0-13.09 6.545 6.545 0 0 0 0 13.09zM5.818 4.364h1.455v7.272H5.818V4.364zm2.91 0h1.454v7.272H8.727V4.364z"/>
</symbol><symbol id="icon-pin" viewBox="0 0 10 16">
<path fill-rule="evenodd" d="M8 8V1.6h.8V0h-8v1.6h.8V8L0 9.6v1.6h4.16V16h1.28v-4.8H9.6V9.6L8 8zM2.24 9.6l.96-.96V1.6h3.2v7.04l.96.96H2.24z"/>
</symbol><symbol id="icon-print" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M3.2 13.6H1.6A1.6 1.6 0 0 1 0 12V5.6A1.6 1.6 0 0 1 1.6 4h1.6V0h9.6v4h1.6A1.6 1.6 0 0 1 16 5.6V12a1.6 1.6 0 0 1-1.6 1.6h-1.6V16H3.2v-2.4zm0-1.6v-1.6h9.6V12h1.6V5.6H1.6V12h1.6zm1.6-8h6.4V1.6H4.8V4zm6.4 8H4.8v2.4h6.4V12zm1.6-5.6a.8.8 0 1 1 0 1.6.8.8 0 0 1 0-1.6z"/>
</symbol><symbol id="icon-priority" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M3.498 15.396L.239 12.137a.817.817 0 0 1 1.155-1.155l1.872 1.873V5.027a.817.817 0 0 1 1.634 0v7.828l1.872-1.873a.817.817 0 0 1 1.155 1.155l-3.26 3.259a.814.814 0 0 1-1.169 0zM10.796.246a.814.814 0 0 1 1.17 0l3.258 3.26A.817.817 0 0 1 14.07 4.66l-1.873-1.872v7.828a.817.817 0 0 1-1.633 0V2.788L8.692 4.66a.817.817 0 0 1-1.155-1.154l3.259-3.26z"/>
</symbol><symbol id="icon-refresh" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M12.646 4C11.557 2.463 9.915 1.6 8 1.6A6.4 6.4 0 0 0 1.6 8H0a8 8 0 0 1 8-8c2.243 0 4.22.946 5.6 2.616V0h1.6v5.6H9.6V4h3.046zm-9.292 8C4.443 13.537 6.085 14.4 8 14.4A6.4 6.4 0 0 0 14.4 8H16a8 8 0 0 1-8 8c-2.243 0-4.22-.946-5.6-2.616V16H.8v-5.6h5.6V12H3.354z"/>
</symbol><symbol id="icon-reports" viewBox="0 0 22 18">
<path fill-rule="evenodd" d="M2 0h18a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm0 2v14h18V2H2zm6 12H6V8h2v6zm4 0h-2V4h2v10zm4 0h-2V7h2v7z"/>
</symbol><symbol id="icon-search-type-knowledge" viewBox="0 0 24 20">
<path d="M22.978 4.004H19.98V.008c-3.12 0-5.947 1.266-7.993 3.313A11.266 11.266 0 0 0 3.996.008v3.996H.999c-.55 0-.999.45-.999.999V16.99c0 .55.45 1 .999 1H9.99a1.997 1.997 0 1 0 3.996 0h8.992c.549 0 .999-.45.999-1V5.003c0-.548-.45-1-1-1zm-9.99 1.143l.413-.414a9.238 9.238 0 0 1 4.581-2.512v8.61a13.158 13.158 0 0 0-4.995 1.858V5.147zM5.993 2.221a9.231 9.231 0 0 1 4.581 2.513l.414.414v7.54a13.148 13.148 0 0 0-4.995-1.857v-8.61zm15.984 13.771H1.998v-9.99h1.998v6.679c3.12 0 5.946 1.266 7.992 3.311a11.273 11.273 0 0 1 7.993-3.311V6.002h1.997v9.99z" fill-rule="evenodd"/>
</symbol><symbol id="icon-search-type-team" viewBox="0 0 24 17">
<path fill-rule="evenodd" d="M16.079 9.659a8.437 8.437 0 0 0-2.294-1.496c.311-.31.58-.663.796-1.048a2.677 2.677 0 0 0 3.768-2.44 2.677 2.677 0 0 0-3.866-2.395A4.818 4.818 0 0 0 12.91.707 4.752 4.752 0 0 1 15.41 0a4.786 4.786 0 0 1 4.78 4.78c0 1.32-.537 2.517-1.405 3.383 2.962 1.303 5.035 4.265 5.035 7.702 0 .582-.472 1.053-1.054 1.053h-5c.582 0 1.054-.471 1.054-1.053 0-.343-.021-.682-.061-1.015h2.672a6.318 6.318 0 0 0-5.352-5.191zm-4.294-1.496c2.962 1.303 5.035 4.265 5.035 7.702 0 .582-.472 1.053-1.054 1.053H1.053A1.053 1.053 0 0 1 0 15.865c0-3.437 2.073-6.399 5.034-7.702A4.766 4.766 0 0 1 3.63 4.781 4.786 4.786 0 0 1 8.409 0a4.786 4.786 0 0 1 4.782 4.78c0 1.32-.538 2.517-1.406 3.383zM8.375 2A2.677 2.677 0 0 0 5.7 4.674C5.7 6.15 6.9 7.35 8.374 7.35c1.475 0 2.675-1.2 2.675-2.675C11.049 3.2 9.849 2 8.374 2zM2.1 14.95h12.43A6.313 6.313 0 0 0 8.316 9.7 6.313 6.313 0 0 0 2.1 14.95z"/>
</symbol><symbol id="icon-search-type-templates" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M17.852 8l1.356.753c1.056.587 1.056 1.907 0 2.494L17.852 12l1.356.753c1.056.587 1.056 1.907 0 2.494l-8.051 4.473c-.673.373-1.641.373-2.314 0l-8.05-4.473c-1.057-.587-1.057-1.907 0-2.494L2.147 12l-1.356-.753c-1.056-.587-1.056-1.907 0-2.494L2.148 8 .792 7.247C-.264 6.66-.264 5.34.792 4.753L8.843.28c.673-.373 1.641-.373 2.314 0l8.05 4.473c1.057.587 1.057 1.907 0 2.494L17.853 8zm-2.059 1.144l-4.636 2.576c-.673.373-1.641.373-2.314 0L4.207 9.144 2.667 10l7.148 3.971a.616.616 0 0 0 .37 0L17.334 10l-1.541-.856zm0 4l-4.636 2.576c-.673.373-1.641.373-2.314 0l-4.636-2.576-1.54.856 7.148 3.971a.616.616 0 0 0 .37 0L17.334 14l-1.541-.856zM10.185 2.029a.616.616 0 0 0-.37 0L2.666 6l7.149 3.971a.616.616 0 0 0 .37 0L17.334 6l-7.149-3.971z"/>
</symbol><symbol id="icon-search-type-tickets" viewBox="0 0 18 22">
<path fill-rule="evenodd" d="M15 3h1a2 2 0 0 1 2 2v15a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h1a2 2 0 0 1 2-2h.996C6.748.363 7.839 0 9 0c1.16 0 2.252.363 3.004 1H13a2 2 0 0 1 2 2zM3.268 5H2v15h14V5h-1.268A2 2 0 0 1 13 6H5a2 2 0 0 1-1.732-1zm3.889-2.345l-.3.345H5v1h8V3h-1.858l-.299-.345C10.515 2.277 9.811 2 9 2c-.81 0-1.515.277-1.843.655zM5 15v-2h6v2H5zm0-4V9h8v2H5z"/>
</symbol><symbol id="icon-search" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M14.32 12.906l5.387 5.387-1.414 1.414-5.387-5.387a8 8 0 1 1 1.414-1.414zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"/>
</symbol><symbol id="icon-select" viewBox="0 0 6 12">
<path d="M3 12l3-4H0zM3 0l3 4H0z" fill-rule="evenodd"/>
</symbol><symbol id="icon-settings" viewBox="0 0 22 22">
<path fill-rule="evenodd" d="M19.873 17.68l-2.217 2.217-2.838-.79-.811.334L12.55 22H9.415l-1.449-2.567-.81-.34-2.838.781-2.216-2.216.79-2.838-.334-.811L0 12.55V9.415l2.568-1.449.34-.81-.781-2.838 2.215-2.215 2.838.791.81-.334L9.446 0h3.136l1.449 2.568.81.34 2.837-.781 2.22 2.215-.792 2.839.335.81L22 9.447v3.136l-2.567 1.448-.34.813.78 2.837zm-2.892-2.972l.872-2.082L20 11.414v-.804l-2.147-1.22-.859-2.083.662-2.375-.569-.568-2.383.655-2.08-.872L11.413 2h-.804L9.39 4.147l-2.083.859-2.376-.663-.566.566.655 2.383-.872 2.08L2 10.583v.805l2.145 1.222.859 2.083-.662 2.376.567.567 2.383-.655 2.08.872 1.21 2.146h.805l1.222-2.145 2.083-.859 2.376.662.568-.568-.655-2.381zM11 15a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-2a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
</symbol><symbol id="icon-star-filled" viewBox="0 0 84 15">
<path d="M8 12.438L3.056 15 4 9.573 0 5.729l5.528-.791L8 0l2.472 4.938L16 5.729l-4 3.844.944 5.427zm17 0L20.056 15 21 9.573l-4-3.844 5.528-.791L25 0l2.472 4.938L33 5.729l-4 3.844.944 5.427zm17 0L37.056 15 38 9.573l-4-3.844 5.528-.791L42 0l2.472 4.938L50 5.729l-4 3.844.944 5.427zm17 0L54.056 15 55 9.573l-4-3.844 5.528-.791L59 0l2.472 4.938L67 5.729l-4 3.844.944 5.427zm17 0L71.056 15 72 9.573l-4-3.844 5.528-.791L76 0l2.472 4.938L84 5.729l-4 3.844.944 5.427z" fill-rule="evenodd"/>
</symbol><symbol id="icon-star-half" viewBox="0 0 16 15">
<g fill-rule="evenodd">
<path d="M8 0l2.472 4.938L16 5.729l-4 3.844.944 5.427L8 12.438 3.056 15 4 9.573 0 5.729l5.528-.791L8 0zm0 3.057L6.44 6.174l-3.491.5 2.525 2.427-.596 3.426L8 10.91l3.122 1.618-.596-3.426 2.525-2.427-3.49-.5L8 3.057z"/>
<path d="M8 12.438L3.056 15 4 9.573 0 5.729l5.528-.791L8 0z"/>
</g>
</symbol><symbol id="icon-star-stroke" viewBox="0 0 84 15">
<path d="M76 12.438L71.056 15 72 9.573l-4-3.844 5.528-.791L76 0l2.472 4.938L84 5.729l-4 3.844.944 5.427L76 12.438zm0-1.529l3.122 1.618-.596-3.426 2.525-2.427-3.49-.5L76 3.057l-1.56 3.117-3.491.5 2.525 2.427-.596 3.426L76 10.91zm-17 1.529L54.056 15 55 9.573l-4-3.844 5.528-.791L59 0l2.472 4.938L67 5.729l-4 3.844.944 5.427L59 12.438zm0-1.529l3.122 1.618-.596-3.426 2.525-2.427-3.49-.5L59 3.057l-1.56 3.117-3.491.5 2.525 2.427-.596 3.426L59 10.91zm-17 1.529L37.056 15 38 9.573l-4-3.844 5.528-.791L42 0l2.472 4.938L50 5.729l-4 3.844.944 5.427L42 12.438zm0-1.529l3.122 1.618-.596-3.426 2.525-2.427-3.49-.5L42 3.057l-1.56 3.117-3.491.5 2.525 2.427-.596 3.426L42 10.91zm-17 1.529L20.056 15 21 9.573l-4-3.844 5.528-.791L25 0l2.472 4.938L33 5.729l-4 3.844.944 5.427L25 12.438zm0-1.529l3.122 1.618-.596-3.426 2.525-2.427-3.49-.5L25 3.057l-1.56 3.117-3.491.5 2.525 2.427-.596 3.426L25 10.91zM8 12.438L3.056 15 4 9.573 0 5.729l5.528-.791L8 0l2.472 4.938L16 5.729l-4 3.844.944 5.427L8 12.438zm0-1.529l3.122 1.618-.596-3.426 2.525-2.427-3.49-.5L8 3.057 6.44 6.174l-3.491.5 2.525 2.427-.596 3.426L8 10.91z" fill-rule="evenodd"/>
</symbol><symbol id="icon-status" viewBox="0 0 14 16">
<path fill-rule="evenodd" d="M1.527 14.545V0h1.455v.727h10.272l-2.18 4.364 2.181 4.364H2.982v5.09h.727V16H.8v-1.455h.727zM2.982 8h7.92L9.447 5.091l1.454-2.91h-7.92V8z"/>
</symbol><symbol id="icon-submit-ticket" viewBox="0 0 19 23">
<path d="M12.508.5l5.628 5.628v14.524a2.015 2.015 0 0 1-2.015 2.015H2.015A2.015 2.015 0 0 1 0 20.652V2.515C0 1.402.902.5 2.015.5h10.493zm-2.433 2.015h-8.06v18.137h14.106V8.56h-4.03a2.015 2.015 0 0 1-2.015-2.015l-.001-4.03zm0 7.053v3.023h3.023v2.015h-3.022v3.023H8.06v-3.023H5.038v-2.015H8.06V9.568h2.015zm2.015-6.636v3.613h3.614L12.09 2.932z"/>
</symbol><symbol id="icon-support" viewBox="0 0 40 40">
<path fill-rule="evenodd" d="M25.014 22.049h2.159v5.224h-2.159V22.05zm1.08-.42c-.793 0-1.3-.478-1.3-1.099 0-.62.507-1.098 1.3-1.098.792 0 1.299.44 1.299 1.06 0 .66-.507 1.137-1.3 1.137zM13.825 9.705c.745 0 1.26.487 1.26 1.127 0 .63-.515 1.146-1.26 1.146s-1.261-.516-1.261-1.146c0-.64.516-1.127 1.26-1.127zm-.392-2.913c-.41 0-.793.248-.993.65l-1.7-.85c.487-.918 1.451-1.548 2.98-1.548 1.499 0 2.617.63 2.617 1.824 0 1.461-1.529 1.72-1.529 2.455h-1.967c0-1.156 1.232-1.5 1.232-2.082 0-.296-.286-.449-.64-.449zm14.498 6.928H40v19.335h-4.312V40l-7.857-6.945H12.068V19.423L4.312 26.28v-6.946H0V0h27.932v13.72zm-16.65 3.27h.786v-3.27h13.52V2.344H2.344V16.99h4.312v4.088l4.625-4.088zm26.374 13.721V16.064H14.412v14.647H28.72l4.625 4.089v-4.09h4.312z"/>
</symbol><symbol id="icon-tag" viewBox="0 0 16 12">
<path fill-rule="evenodd" d="M5.238.3h9.327C15.358.3 16 .942 16 1.735v8.61c0 .792-.642 1.434-1.435 1.434H5.238c-.362 0-.525-.134-.858-.49a7.035 7.035 0 0 1-.41-.486L0 6.04l.383-.459 3.551-4.258a5.836 5.836 0 0 1 .475-.584C4.686.45 4.891.3 5.24.3zm.108 1.541a5.826 5.826 0 0 0-.274.353L1.868 6.04 5.09 9.908a6.324 6.324 0 0 0 .37.436h9.104v-8.61H5.441c-.029.032-.061.067-.095.107zm3.32 4.546L11.753 3.3l1.017 1.017-4.104 4.104L6 5.755l1.017-1.017 1.649 1.65z"/>
</symbol><symbol id="icon-team" viewBox="0 0 24 17">
<path fill-rule="evenodd" d="M16.079 9.659a8.437 8.437 0 0 0-2.294-1.496c.311-.31.58-.663.796-1.048a2.677 2.677 0 0 0 3.768-2.44 2.677 2.677 0 0 0-3.866-2.395A4.818 4.818 0 0 0 12.91.707 4.752 4.752 0 0 1 15.41 0a4.786 4.786 0 0 1 4.78 4.78c0 1.32-.537 2.517-1.405 3.383 2.962 1.303 5.035 4.265 5.035 7.702 0 .582-.472 1.053-1.054 1.053h-5c.582 0 1.054-.471 1.054-1.053 0-.343-.021-.682-.061-1.015h2.672a6.318 6.318 0 0 0-5.352-5.191zm-4.294-1.496c2.962 1.303 5.035 4.265 5.035 7.702 0 .582-.472 1.053-1.054 1.053H1.053A1.053 1.053 0 0 1 0 15.865c0-3.437 2.073-6.399 5.034-7.702A4.766 4.766 0 0 1 3.63 4.781 4.786 4.786 0 0 1 8.409 0a4.786 4.786 0 0 1 4.782 4.78c0 1.32-.538 2.517-1.406 3.383zM8.375 2A2.677 2.677 0 0 0 5.7 4.674C5.7 6.15 6.9 7.35 8.374 7.35c1.475 0 2.675-1.2 2.675-2.675C11.049 3.2 9.849 2 8.374 2zM2.1 14.95h12.43A6.313 6.313 0 0 0 8.316 9.7 6.313 6.313 0 0 0 2.1 14.95z"/>
</symbol><symbol id="icon-templates" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M17.852 8l1.356.753c1.056.587 1.056 1.907 0 2.494L17.852 12l1.356.753c1.056.587 1.056 1.907 0 2.494l-8.051 4.473c-.673.373-1.641.373-2.314 0l-8.05-4.473c-1.057-.587-1.057-1.907 0-2.494L2.147 12l-1.356-.753c-1.056-.587-1.056-1.907 0-2.494L2.148 8 .792 7.247C-.264 6.66-.264 5.34.792 4.753L8.843.28c.673-.373 1.641-.373 2.314 0l8.05 4.473c1.057.587 1.057 1.907 0 2.494L17.853 8zm-2.059 1.144l-4.636 2.576c-.673.373-1.641.373-2.314 0L4.207 9.144 2.667 10l7.148 3.971a.616.616 0 0 0 .37 0L17.334 10l-1.541-.856zm0 4l-4.636 2.576c-.673.373-1.641.373-2.314 0l-4.636-2.576-1.54.856 7.148 3.971a.616.616 0 0 0 .37 0L17.334 14l-1.541-.856zM10.185 2.029a.616.616 0 0 0-.37 0L2.666 6l7.149 3.971a.616.616 0 0 0 .37 0L17.334 6l-7.149-3.971z"/>
</symbol><symbol id="icon-tick" viewBox="0 0 11 8">
<path fill-rule="evenodd" d="M9.043 0L3.246 5.128 1.623 3.692 0 5.128 3.246 8l7.42-6.564z"/>
</symbol><symbol id="icon-tickets" viewBox="0 0 18 22">
<path fill-rule="evenodd" d="M15 3h1a2 2 0 0 1 2 2v15a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h1a2 2 0 0 1 2-2h.996C6.748.363 7.839 0 9 0c1.16 0 2.252.363 3.004 1H13a2 2 0 0 1 2 2zM3.268 5H2v15h14V5h-1.268A2 2 0 0 1 13 6H5a2 2 0 0 1-1.732-1zm3.889-2.345l-.3.345H5v1h8V3h-1.858l-.299-.345C10.515 2.277 9.811 2 9 2c-.81 0-1.515.277-1.843.655zM5 15v-2h6v2H5zm0-4V9h8v2H5z"/>
</symbol><symbol id="icon-tools" viewBox="0 0 22 22">
<path fill-rule="evenodd" d="M19.566 13.369a.856.856 0 0 0-.607-.254h-.002a.856.856 0 0 0-.607.252l-2.09 2.097a.86.86 0 0 0 .001 1.216.856.856 0 0 0 1.213-.001l1.481-1.487.799.806c.664.668.665 1.755.003 2.424l-1.339 1.351a1.701 1.701 0 0 1-1.214.509h-.003c-.459 0-.89-.18-1.213-.504l-3.782-3.785 8.481-8.48A4.376 4.376 0 0 0 21.974 4.4c0-1.176-.457-2.28-1.287-3.112A4.358 4.358 0 0 0 17.582 0a4.359 4.359 0 0 0-3.106 1.29l-3.483 3.489-3.754-3.766A3.404 3.404 0 0 0 4.812.003h-.003A3.4 3.4 0 0 0 2.384 1.01L1.026 2.37a3.445 3.445 0 0 0 0 4.86l3.762 3.766L2.2 13.588a.857.857 0 0 0-.22.377l-1.928 6.94a.86.86 0 0 0 1.06 1.057l6.744-1.919a.853.853 0 0 0 .547-.249l2.588-2.587 3.783 3.786A3.403 3.403 0 0 0 17.2 22h.007a3.403 3.403 0 0 0 2.429-1.016l1.338-1.352a3.449 3.449 0 0 0-.004-4.845l-1.404-1.418zm-5.348-9.391l3.784 3.792-1.232 1.232-3.784-3.79 1.232-1.234zm3.364-2.26c.715 0 1.387.28 1.893.786a2.67 2.67 0 0 1 .784 1.897c0 .716-.279 1.39-.784 1.896l-.259.26-3.786-3.794.259-.259a2.657 2.657 0 0 1 1.893-.786zM2.239 6.015a1.723 1.723 0 0 1 0-2.43l1.358-1.36a1.702 1.702 0 0 1 1.212-.504h.002c.458 0 .89.18 1.214.506l.814.818-1.508 1.511a.86.86 0 0 0 .606 1.467c.22 0 .44-.084.607-.252l1.507-1.51L9.78 5.993 6 9.781 2.24 6.015zm-.124 13.876l1.136-4.088 2.919 2.934-4.055 1.154zm5.7-1.934l-3.769-3.788 7.728-7.742 3.782 3.79-7.741 7.74z"/>
</symbol><symbol id="icon-warning" viewBox="0 0 486.463 486.463">
<path d="M243.225 333.382c-13.6 0-25 11.4-25 25s11.4 25 25 25c13.1 0 25-11.4 24.4-24.4.6-14.3-10.7-25.6-24.4-25.6z"/>
<path d="M474.625 421.982c15.7-27.1 15.8-59.4.2-86.4l-156.6-271.2c-15.5-27.3-43.5-43.5-74.9-43.5s-59.4 16.3-74.9 43.4l-156.8 271.5c-15.6 27.3-15.5 59.8.3 86.9 15.6 26.8 43.5 42.9 74.7 42.9h312.8c31.3 0 59.4-16.3 75.2-43.6zm-34-19.6c-8.7 15-24.1 23.9-41.3 23.9h-312.8c-17 0-32.3-8.7-40.8-23.4-8.6-14.9-8.7-32.7-.1-47.7l156.8-271.4c8.5-14.9 23.7-23.7 40.9-23.7 17.1 0 32.4 8.9 40.9 23.8l156.7 271.4c8.4 14.6 8.3 32.2-.3 47.1z"/>
<path d="M237.025 157.882c-11.9 3.4-19.3 14.2-19.3 27.3.6 7.9 1.1 15.9 1.7 23.8 1.7 30.1 3.4 59.6 5.1 89.7.6 10.2 8.5 17.6 18.7 17.6s18.2-7.9 18.7-18.2c0-6.2 0-11.9.6-18.2 1.1-19.3 2.3-38.6 3.4-57.9.6-12.5 1.7-25 2.3-37.5 0-4.5-.6-8.5-2.3-12.5-5.1-11.2-17-16.9-28.9-14.1z"/>
</symbol></svg>

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,913 @@
<?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');}
// Possible fields to be displayed in ticket list
$hesk_settings['possible_ticket_list'] = array(
'id' => $hesklang['id'],
'trackid' => $hesklang['trackID'],
'dt' => $hesklang['submitted'],
'lastchange' => $hesklang['last_update'],
'category' => $hesklang['category'],
'name' => $hesklang['name'],
'email' => $hesklang['email'],
'subject' => $hesklang['subject'],
'status' => $hesklang['status'],
'owner' => $hesklang['owner'],
'replies' => $hesklang['replies'],
'staffreplies' => $hesklang['replies'] . ' (' . $hesklang['staff'] .')',
'lastreplier' => $hesklang['last_replier'],
'time_worked' => $hesklang['ts'],
);
define('HESK_NO_ROBOTS', true);
/*** FUNCTIONS ***/
function hesk_show_column($column)
{
global $hesk_settings;
return in_array($column, $hesk_settings['ticket_list']) ? true : false;
} // END hesk_show_column()
function hesk_getHHMMSS($in)
{
$in = hesk_getTime($in);
return explode(':', $in);
} // END hesk_getHHMMSS();
function hesk_getTime($in)
{
$in = trim($in);
/* If everything is OK this simple check should return true */
if ( preg_match('/^([0-9]{2,3}):([0-5][0-9]):([0-5][0-9])$/', $in) )
{
return $in;
}
/* No joy, let's try to figure out the correct values to use... */
$h = 0;
$m = 0;
$s = 0;
/* How many parts do we have? */
$parts = substr_count($in, ':');
switch ($parts)
{
/* Only two parts, let's assume minutes and seconds */
case 1:
list($m, $s) = explode(':', $in);
break;
/* Three parts, so explode to hours, minutes and seconds */
case 2:
list($h, $m, $s) = explode(':', $in);
break;
/* Something other was entered, let's assume just minutes */
default:
$m = $in;
}
/* Make sure all inputs are integers */
$h = intval($h);
$m = intval($m);
$s = intval($s);
/* Convert seconds to minutes if 60 or more seconds */
if ($s > 59)
{
$m = floor($s / 60) + $m;
$s = intval($s % 60);
}
/* Convert minutes to hours if 60 or more minutes */
if ($m > 59)
{
$h = floor($m / 60) + $h;
$m = intval($m % 60);
}
/* MySQL accepts max time value of 838:59:59 */
if ($h > 838)
{
return '838:59:59';
}
/* That's it, let's send out formatted time string */
return str_pad($h, 2, "0", STR_PAD_LEFT) . ':' . str_pad($m, 2, "0", STR_PAD_LEFT) . ':' . str_pad($s, 2, "0", STR_PAD_LEFT);
} // END hesk_getTime();
function hesk_mergeTickets($merge_these, $merge_into)
{
global $hesk_settings, $hesklang, $hesk_db_link;
/* Target ticket must not be in the "merge these" list */
if ( in_array($merge_into, $merge_these) )
{
$merge_these = array_diff($merge_these, array( $merge_into ) );
}
/* At least 1 ticket needs to be merged with target ticket */
if ( count($merge_these) < 1 )
{
$_SESSION['error'] = $hesklang['merr1'];
return false;
}
/* Make sure target ticket exists */
$res = hesk_dbQuery("SELECT `id`,`trackid`,`category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($merge_into)."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
$_SESSION['error'] = $hesklang['merr2'];
return false;
}
$ticket = hesk_dbFetchAssoc($res);
/* Make sure user has access to ticket category */
if ( ! hesk_okCategory($ticket['category'], 0) )
{
$_SESSION['error'] = $hesklang['merr3'];
return false;
}
/* Set some variables for later */
$merge['attachments'] = '';
$merge['replies'] = array();
$merge['notes'] = array();
$sec_worked = 0;
$history = '';
$merged = '';
/* Get messages, replies, notes and attachments of tickets that will be merged */
foreach ($merge_these as $this_id)
{
/* Validate ID */
if ( is_array($this_id) )
{
continue;
}
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
/* Get required ticket information */
$res = hesk_dbQuery("SELECT `id`,`trackid`,`category`,`name`,`message`,`dt`,`time_worked`,`attachments` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($this_id)."' LIMIT 1");
if (hesk_dbNumRows($res) != 1)
{
continue;
}
$row = hesk_dbFetchAssoc($res);
/* Has this user access to the ticket category? */
if ( ! hesk_okCategory($row['category'], 0) )
{
continue;
}
/* Insert ticket message as a new reply to target ticket */
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` (`replyto`,`name`,`message`,`dt`,`attachments`) VALUES ('".intval($ticket['id'])."','".hesk_dbEscape($row['name'])."','".hesk_dbEscape($row['message'])."','".hesk_dbEscape($row['dt'])."','".hesk_dbEscape($row['attachments'])."')");
/* Update attachments */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` SET `ticket_id`='".hesk_dbEscape($ticket['trackid'])."' WHERE `ticket_id`='".hesk_dbEscape($row['trackid'])."'");
/* Get old ticket replies and insert them as new replies */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`='".intval($row['id'])."' ORDER BY `id` ASC");
while ( $reply = hesk_dbFetchAssoc($res) )
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`,`rating`,`read`) VALUES ('".intval($ticket['id'])."','".hesk_dbEscape($reply['name'])."','".hesk_dbEscape($reply['message'])."','".hesk_dbEscape($reply['dt'])."','".hesk_dbEscape($reply['attachments'])."','".intval($reply['staffid'])."','".intval($reply['rating'])."','".intval($reply['read'])."')");
}
/* Delete replies to the old ticket */
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`='".intval($row['id'])."'");
/* Get old ticket notes and insert them as new notes */
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` WHERE `ticket`='".intval($row['id'])."' ORDER BY `id` ASC");
while ( $note = hesk_dbFetchAssoc($res) )
{
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` (`ticket`,`who`,`dt`,`message`,`attachments`) VALUES ('".intval($ticket['id'])."','".intval($note['who'])."','".hesk_dbEscape($note['dt'])."','".hesk_dbEscape($note['message'])."','".hesk_dbEscape($note['attachments'])."')");
}
/* Delete replies to the old ticket */
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` WHERE `ticket`='".intval($row['id'])."'");
/* Delete old ticket */
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($row['id'])."'");
/* Log that ticket has been merged */
$history .= sprintf($hesklang['thist13'],hesk_date(),$row['trackid'],$_SESSION['name'].' ('.$_SESSION['user'].')');
/* Add old ticket ID to target ticket "merged" field */
$merged .= '#' . $row['trackid'];
/* Convert old ticket "time worked" to seconds and add to $sec_worked variable */
list ($hr, $min, $sec) = explode(':', $row['time_worked']);
$sec_worked += (((int)$hr) * 3600) + (((int)$min) * 60) + ((int)$sec);
}
/* Convert seconds to HHH:MM:SS */
$sec_worked = hesk_getTime('0:'.$sec_worked);
// Get number of replies
$total = 0;
$staffreplies = 0;
$res = hesk_dbQuery("SELECT COUNT(*) as `cnt`, (CASE WHEN `staffid` = 0 THEN 0 ELSE 1 END) AS `staffcnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`=".intval($ticket['id'])." GROUP BY `staffcnt`");
while ( $row = hesk_dbFetchAssoc($res) )
{
$total += $row['cnt'];
$staffreplies += ($row['staffcnt'] ? $row['cnt'] : 0);
}
$replies_sql = " `replies`={$total}, `staffreplies`={$staffreplies} , ";
// Get first staff reply
if ($staffreplies)
{
$res = hesk_dbQuery("SELECT `dt`, `staffid` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`=".intval($ticket['id'])." AND `staffid`>0 ORDER BY `dt` ASC LIMIT 1");
$reply = hesk_dbFetchAssoc($res);
$replies_sql .= " `firstreply`='".hesk_dbEscape($reply['dt'])."', `firstreplyby`=".intval($reply['staffid'])." , ";
}
/* Update history (log) and merged IDs of target ticket */
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET $replies_sql `time_worked`=ADDTIME(`time_worked`, '".hesk_dbEscape($sec_worked)."'), `merged`=CONCAT(`merged`,'".hesk_dbEscape($merged . '#')."'), `history`=CONCAT(`history`,'".hesk_dbEscape($history)."') WHERE `id`='".intval($merge_into)."'");
return true;
} // END hesk_mergeTickets()
function hesk_updateStaffDefaults()
{
global $hesk_settings, $hesklang;
// Demo mode
if ( defined('HESK_DEMO') )
{
return true;
}
// Remove the part that forces saving as default - we don't need it every time
$default_list = str_replace('&def=1','',$_SERVER['QUERY_STRING']);
// Update database
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` SET `default_list`='".hesk_dbEscape($default_list)."' WHERE `id`='".intval($_SESSION['id'])."'");
// Update session values so the changes take effect immediately
$_SESSION['default_list'] = $default_list;
return true;
} // END hesk_updateStaffDefaults()
function hesk_makeJsString($in)
{
return addslashes(preg_replace("/\s+/",' ',$in));
} // END hesk_makeJsString()
function hesk_checkNewMail()
{
global $hesk_settings, $hesklang;
$res = hesk_dbQuery("SELECT COUNT(*) FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."mail` WHERE `to`='".intval($_SESSION['id'])."' AND `read`='0' AND `deletedby`!='".intval($_SESSION['id'])."' ");
$num = hesk_dbResult($res,0,0);
return $num;
} // END hesk_checkNewMail()
function hesk_dateToString($dt, $returnName=1, $returnTime=0, $returnMonth=0, $from_database=false)
{
global $hesk_settings, $hesklang;
$dt = strtotime($dt);
// Adjust MySQL time if different from PHP time
if ($from_database)
{
if ( ! defined('MYSQL_TIME_DIFF') )
{
define('MYSQL_TIME_DIFF', time()-hesk_dbTime() );
}
if (MYSQL_TIME_DIFF != 0)
{
$dt += MYSQL_TIME_DIFF;
}
}
list($y,$m,$n,$d,$G,$i,$s) = explode('-', date('Y-n-j-w-G-i-s', $dt) );
$m = $hesklang['m'.$m];
$d = $hesklang['d'.$d];
if ($returnName)
{
return "$d, $m $n, $y";
}
if ($returnTime)
{
return "$d, $m $n, $y $G:$i:$s";
}
if ($returnMonth)
{
return "$m $y";
}
return "$m $n, $y";
} // End hesk_dateToString()
function hesk_getCategoriesArray($kb = 0) {
global $hesk_settings, $hesklang, $hesk_db_link;
$categories = array();
if ($kb)
{
$result = hesk_dbQuery('SELECT `id`, `name` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'kb_categories` ORDER BY `cat_order` ASC');
}
else
{
$result = hesk_dbQuery('SELECT `id`, `name` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'categories` ORDER BY `cat_order` ASC');
}
while ($row=hesk_dbFetchAssoc($result))
{
$categories[$row['id']] = $row['name'];
}
return $categories;
} // END hesk_getCategoriesArray()
function hesk_getHTML($in)
{
global $hesk_settings, $hesklang;
$replace_from = array("\t","<?","?>","$","<%","%>");
$replace_to = array("","&lt;?","?&gt;","\$","&lt;%","%&gt;");
$in = trim($in);
$in = str_replace($replace_from,$replace_to,$in);
$in = preg_replace('/\<script(.*)\>(.*)\<\/script\>/Uis',"<script$1></script>",$in);
$in = preg_replace('/\<\!\-\-(.*)\-\-\>/Uis',"<!-- comments have been removed -->",$in);
if (HESK_SLASH === true)
{
$in = addslashes($in);
}
$in = str_replace('\"','"',$in);
return $in;
} // END hesk_getHTML()
function hesk_activeSessionValidate($username, $password_hash, $tag)
{
// Salt and hash need to be separated by a |
if ( ! strpos($tag, '|') )
{
return false;
}
// Get two parts of the tag
list($salt, $hash) = explode('|', $tag, 2);
// Make sure the hash matches existing username and password
if ($hash == sha1($salt . hesk_mb_strtolower($username) . $password_hash) )
{
return true;
}
return false;
} // hesk_activeSessionValidate
function hesk_activeSessionCreateTag($username, $password_hash)
{
$salt = uniqid(mt_rand(), true);
return $salt . '|' . sha1($salt . hesk_mb_strtolower($username) . $password_hash);
} // END hesk_activeSessionCreateTag()
function hesk_autoLogin($noredirect=0)
{
global $hesk_settings, $hesklang, $hesk_db_link;
if (!$hesk_settings['autologin'])
{
return false;
}
$user = hesk_htmlspecialchars( hesk_COOKIE('hesk_username') );
$hash = hesk_htmlspecialchars( hesk_COOKIE('hesk_p') );
define('HESK_USER', $user);
if (empty($user) || empty($hash))
{
return false;
}
/* Login cookies exist, now lets limit brute force attempts */
hesk_limitBfAttempts();
// Admin login URL
$url = $hesk_settings['hesk_url'] . '/' . $hesk_settings['admin_dir'] . '/index.php?a=login&notice=1';
/* Check username */
$result = hesk_dbQuery('SELECT * FROM `'.$hesk_settings['db_pfix']."users` WHERE `user` = '".hesk_dbEscape($user)."' LIMIT 1");
if (hesk_dbNumRows($result) != 1)
{
hesk_setcookie('hesk_username', '');
hesk_setcookie('hesk_p', '');
header('Location: '.$url);
exit();
}
$res=hesk_dbFetchAssoc($result);
/* Check password */
if ($hash != hesk_Pass2Hash($res['pass'] . hesk_mb_strtolower($user) . $res['pass']) )
{
hesk_setcookie('hesk_username', '');
hesk_setcookie('hesk_p', '');
header('Location: '.$url);
exit();
}
// Set user details
foreach ($res as $k=>$v)
{
$_SESSION[$k]=$v;
}
/* Check if default password */
if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079')
{
hesk_process_messages($hesklang['chdp'],'NOREDIRECT','NOTICE');
}
// Set a tag that will be used to expire sessions after username or password change
$_SESSION['session_verify'] = hesk_activeSessionCreateTag($user, $_SESSION['pass']);
// We don't need the password hash anymore
unset($_SESSION['pass']);
/* Login successful, clean brute force attempts */
hesk_cleanBfAttempts();
/* Regenerate session ID (security) */
hesk_session_regenerate_id();
/* Get allowed categories */
if (empty($_SESSION['isadmin']))
{
$_SESSION['categories']=explode(',',$_SESSION['categories']);
}
/* Renew cookies */
hesk_setcookie('hesk_username', "$user", strtotime('+1 year'));
hesk_setcookie('hesk_p', "$hash", strtotime('+1 year'));
/* Close any old tickets here so Cron jobs aren't necessary */
if ($hesk_settings['autoclose'])
{
$revision = sprintf($hesklang['thist3'],hesk_date(),$hesklang['auto']);
$dt = date('Y-m-d H:i:s',time() - $hesk_settings['autoclose']*86400);
// Notify customer of closed ticket?
if ($hesk_settings['notify_closed'])
{
// Get list of tickets
$result = hesk_dbQuery("SELECT * FROM `".$hesk_settings['db_pfix']."tickets` WHERE `status` = '2' AND `lastchange` <= '".hesk_dbEscape($dt)."' ");
if (hesk_dbNumRows($result) > 0)
{
global $ticket;
// Load required functions?
if ( ! function_exists('hesk_notifyCustomer') )
{
require(HESK_PATH . 'inc/email_functions.inc.php');
}
while ($ticket = hesk_dbFetchAssoc($result))
{
$ticket['dt'] = hesk_date($ticket['dt'], true);
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
$ticket = hesk_ticketToPlain($ticket, 1, 0);
hesk_notifyCustomer('ticket_closed');
}
}
}
// Update ticket statuses and history in database
hesk_dbQuery("UPDATE `".$hesk_settings['db_pfix']."tickets` SET `status`='3', `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `status` = '2' AND `lastchange` <= '".hesk_dbEscape($dt)."' ");
}
/* If session expired while a HESK page is open just continue using it, don't redirect */
if ($noredirect)
{
return true;
}
/* Redirect to the destination page */
header('Location: ' . hesk_verifyGoto() );
exit();
} // END hesk_autoLogin()
function hesk_isLoggedIn()
{
global $hesk_settings;
$referer = hesk_input($_SERVER['REQUEST_URI']);
$referer = str_replace('&amp;','&',$referer);
// Admin login URL
$url = $hesk_settings['hesk_url'] . '/' . $hesk_settings['admin_dir'] . '/index.php?a=login&notice=1&goto='.urlencode($referer);
if ( empty($_SESSION['id']) || empty($_SESSION['session_verify']) )
{
if ($hesk_settings['autologin'] && hesk_autoLogin(1) )
{
// Users online
if ($hesk_settings['online'])
{
require(HESK_PATH . 'inc/users_online.inc.php');
hesk_initOnline($_SESSION['id']);
}
return true;
}
hesk_session_stop();
header('Location: '.$url);
exit();
}
else
{
hesk_session_regenerate_id();
// Let's make sure access data is up-to-date
$res = hesk_dbQuery( "SELECT `user`, `pass`, `isadmin`, `categories`, `heskprivileges` FROM `".$hesk_settings['db_pfix']."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1" );
// Exit if user not found
if (hesk_dbNumRows($res) != 1)
{
hesk_session_stop();
header('Location: '.$url);
exit();
}
// Fetch results from database
$me = hesk_dbFetchAssoc($res);
// Verify this session is still valid
if ( ! hesk_activeSessionValidate($me['user'], $me['pass'], $_SESSION['session_verify']) )
{
hesk_session_stop();
header('Location: '.$url);
exit();
}
// Update session variables as needed
if ($me['isadmin'] == 1)
{
$_SESSION['isadmin'] = 1;
}
else
{
$_SESSION['isadmin'] = 0;
$_SESSION['categories'] = explode(',', $me['categories']);
$_SESSION['heskprivileges'] = $me['heskprivileges'];
}
// Users online
if ($hesk_settings['online'])
{
require(HESK_PATH . 'inc/users_online.inc.php');
hesk_initOnline($_SESSION['id']);
}
return true;
}
} // END hesk_isLoggedIn()
function hesk_verifyGoto()
{
// Default redirect URL
$url_default = 'admin_main.php';
// If no "goto" parameter is set, redirect to the default page
if ( ! hesk_isREQUEST('goto') )
{
return $url_default;
}
// Get the "goto" parameter
$url = hesk_REQUEST('goto');
// Fix encoded "&"
$url = str_replace('&amp;', '&', $url);
// Parse the URL for verification
$url_parts = parse_url($url);
// The "path" part is required
if ( ! isset($url_parts['path']) )
{
return $url_default;
}
// Extract the file name from path
$url = basename($url_parts['path']);
// Allowed files for redirect
$OK_urls = array(
'admin_main.php' => '',
'admin_settings_general.php' => '',
'admin_settings_help_desk.php' => '',
'admin_settings_knowledgebase.php' => '',
'admin_settings_email.php' => '',
'admin_settings_ticket_list.php' => '',
'admin_settings_misc.php' => '',
'admin_settings_save.php' => 'admin_settings_general.php',
'admin_ticket.php' => '',
'archive.php' => '',
'assign_owner.php' => '',
'banned_emails.php' => '',
'banned_ips.php' => '',
'change_status.php' => '',
'custom_fields.php' => '',
'custom_statuses.php' => '',
'edit_post.php' => '',
'email_templates.php' => '',
'export.php' => '',
'find_tickets.php' => '',
'generate_spam_question.php' => '',
'knowledgebase_private.php' => '',
'lock.php' => '',
'mail.php' => '',
'mail.php?a=read&id=1' => '',
'manage_canned.php' => '',
'manage_categories.php' => '',
'manage_knowledgebase.php' => '',
'manage_ticket_templates.php' => '',
'manage_users.php' => '',
'new_ticket.php' => '',
'profile.php' => '',
'reports.php' => '',
'service_messages.php' => '',
'show_tickets.php' => '',
);
// URL must match one of the allowed ones
if ( ! isset($OK_urls[$url]) )
{
return $url_default;
}
// Modify redirect?
if ( strlen($OK_urls[$url]) )
{
$url = $OK_urls[$url];
}
// All OK, return the URL with query if set
return isset($url_parts['query']) ? $url.'?'.$url_parts['query'] : $url;
} // END hesk_verifyGoto()
function hesk_Pass2Hash($plaintext) {
$majorsalt = '';
$len = strlen($plaintext);
for ($i=0;$i<$len;$i++)
{
$majorsalt .= sha1(substr($plaintext,$i,1));
}
$corehash = sha1($majorsalt);
return $corehash;
} // END hesk_Pass2Hash()
function hesk_formatDate($dt, $from_database=true)
{
$dt=hesk_date($dt, $from_database);
$dt=str_replace(' ','<br />',$dt);
return $dt;
} // End hesk_formatDate()
function hesk_jsString($str)
{
$str = addslashes($str);
$str = str_replace('<br />' , '' , $str);
$from = array("/\r\n|\n|\r/", '/\<a href="mailto\:([^"]*)"\>([^\<]*)\<\/a\>/i', '/\<a href="([^"]*)" target="_blank"\>([^\<]*)\<\/a\>/i');
$to = array("\\r\\n' + \r\n'", "$1", "$1");
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')
{
if ( ! empty($_SESSION['isadmin']) )
{
return '1';
}
else
{
return " `".hesk_dbEscape($what)."` IN ('" . implode("','", array_map('intval', $_SESSION['categories']) ) . "')";
}
} // END hesk_myCategories()
function hesk_okCategory($cat,$error=1,$user_isadmin=false,$user_cat=false)
{
global $hesklang;
/* Checking for current user or someone else? */
if ($user_isadmin === false)
{
$user_isadmin = $_SESSION['isadmin'];
}
if ($user_cat === false)
{
$user_cat = $_SESSION['categories'];
}
/* Is admin? */
if ($user_isadmin)
{
return true;
}
/* Staff with access? */
elseif (in_array($cat,$user_cat))
{
return true;
}
/* No access */
else
{
if ($error)
{
hesk_error($hesklang['not_authorized_tickets']);
}
else
{
return false;
}
}
} // END hesk_okCategory()
function hesk_checkPermission($feature,$showerror=1) {
global $hesklang;
/* Admins have full access to all features */
if ( isset($_SESSION['isadmin']) && $_SESSION['isadmin'])
{
return true;
}
/* Check other staff for permissions */
if ( isset($_SESSION['heskprivileges']) && strpos($_SESSION['heskprivileges'], $feature) === false)
{
if ($showerror)
{
hesk_error($hesklang['no_permission'].'<p>&nbsp;</p><p align="center"><a href="index.php">'.$hesklang['click_login'].'</a>');
}
else
{
return false;
}
}
else
{
return true;
}
} // END hesk_checkPermission()
function hesk_purge_cache($type = '', $expire_after_seconds = 0)
{
global $hesk_settings;
$cache_dir = dirname(dirname(__FILE__)).'/'.$hesk_settings['cache_dir'].'/';
if ( ! is_dir($cache_dir))
{
return false;
}
switch ($type)
{
case 'export':
$files = glob($cache_dir.'hesk_export_*', GLOB_NOSORT);
break;
case 'status':
$files = glob($cache_dir.'status_*', GLOB_NOSORT);
break;
case 'cf':
$files = glob($cache_dir.'cf_*', GLOB_NOSORT);
break;
case 'kb':
$files = array($cache_dir.'kb.cache.php');
break;
default:
hesk_rrmdir(trim($cache_dir, '/'), true);
return true;
}
if (is_array($files))
{
array_walk($files, 'hesk_unlink_callable', $expire_after_seconds);
}
return true;
} // END hesk_purge_cache()
function hesk_rrmdir($dir, $keep_top_level=false)
{
$files = $keep_top_level ? array_diff(scandir($dir), array('.','..','index.htm')) : array_diff(scandir($dir), array('.','..'));
foreach ($files as $file)
{
(is_dir("$dir/$file")) ? hesk_rrmdir("$dir/$file") : @unlink("$dir/$file");
}
return $keep_top_level ? true : @rmdir($dir);
} // END hesk_rrmdir()

View File

@@ -0,0 +1,109 @@
<?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');}
/* Assignment */
// -> SELF
$s_my[$fid] = empty($_GET['s_my']) ? 0 : 1;
// -> OTHERS
$s_ot[$fid] = empty($_GET['s_ot']) ? 0 : 1;
// -> UNASSIGNED
$s_un[$fid] = empty($_GET['s_un']) ? 0 : 1;
// -> Setup SQL based on selected ticket assignments
/* Make sure at least one is chosen */
if ( ! $s_my[$fid] && ! $s_ot[$fid] && ! $s_un[$fid])
{
$s_my[$fid] = 1;
$s_ot[$fid] = 1;
$s_un[$fid] = 1;
if (!defined('MAIN_PAGE'))
{
hesk_show_notice($hesklang['e_nose']);
}
}
// Can view tickets assigned by him/her?
$s_by[$fid] = hesk_checkPermission('can_view_ass_by',0) ? $s_ot[$fid] : 0;
/* If the user doesn't have permission to view assigned to others block those */
if ( ! hesk_checkPermission('can_view_ass_others',0))
{
$s_ot[$fid] = 0;
}
/* If the user doesn't have permission to view unassigned tickets block those */
if ( ! hesk_checkPermission('can_view_unassigned',0))
{
$s_un[$fid] = 0;
}
/* Process assignments */
if ( ! $s_my[$fid] || ! $s_ot[$fid] || ! $s_un[$fid])
{
if ($s_my[$fid] && $s_ot[$fid])
{
// All but unassigned
$sql .= " AND `owner` > 0 ";
}
elseif ( ! $s_ot[$fid] && $s_by[$fid])
{
// Can't view tickets assigned to others, but can see tickets he/she assigned to someone
if ($s_my[$fid] && $s_un[$fid])
{
$sql .= " AND (`owner` IN ('0', '" . intval($_SESSION['id']) . "') OR `assignedby` = " . intval($_SESSION['id']) . ") ";
}
elseif($s_my[$fid])
{
$sql .= " AND (`owner` = '" . intval($_SESSION['id']) . "' OR `assignedby` = " . intval($_SESSION['id']) . ") ";
}
elseif($s_un[$fid])
{
$sql .= " AND (`owner` = 0 OR `assignedby` = " . intval($_SESSION['id']) . ") ";
}
else
{
$sql .= " AND `assignedby` = " . intval($_SESSION['id']) . " ";
}
$s_ot[$fid] = 1;
}
elseif ($s_my[$fid] && $s_un[$fid])
{
// My tickets + unassigned
$sql .= " AND `owner` IN ('0', '" . intval($_SESSION['id']) . "') ";
}
elseif ($s_ot[$fid] && $s_un[$fid])
{
// Assigned to others + unassigned
$sql .= " AND `owner` != '" . intval($_SESSION['id']) . "' ";
}
elseif ($s_my[$fid])
{
// Assigned to me only
$sql .= " AND `owner` = '" . intval($_SESSION['id']) . "' ";
}
elseif ($s_ot[$fid])
{
// Assigned to others
$sql .= " AND `owner` NOT IN ('0', '" . intval($_SESSION['id']) . "') ";
}
elseif ($s_un[$fid])
{
// Only unassigned
$sql .= " AND `owner` = 0 ";
}
}

View File

@@ -0,0 +1,112 @@
<?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');}
/***************************
Function hesk_uploadFiles()
***************************/
function hesk_uploadFile($i)
{
global $hesk_settings, $hesklang, $trackingID, $hesk_error_buffer;
/* Return if name is empty */
if (empty($_FILES['attachment']['name'][$i])) {return '';}
/* Parse the name */
$file_realname = hesk_cleanFileName($_FILES['attachment']['name'][$i]);
/* Check file extension */
$ext = strtolower(strrchr($file_realname, "."));
if ( ! in_array($ext,$hesk_settings['attachments']['allowed_types']))
{
return hesk_fileError(sprintf($hesklang['type_not_allowed'], $ext, $file_realname));
}
/* Check file size */
if ($_FILES['attachment']['size'][$i] > $hesk_settings['attachments']['max_size'])
{
return hesk_fileError(sprintf($hesklang['file_too_large'], $file_realname));
}
else
{
$file_size = $_FILES['attachment']['size'][$i];
}
/* Generate a random file name */
$useChars='AEUYBDGHJLMNPQRSTVWXZ123456789';
$tmp = uniqid();
for($j=1;$j<10;$j++)
{
$tmp .= $useChars[mt_rand(0,29)];
}
if (defined('KB'))
{
$file_name = substr(md5($tmp . $file_realname), 0, 200) . $ext;
}
else
{
$file_name = substr($trackingID . '_' . md5($tmp . $file_realname), 0, 200) . $ext;
}
// Does the temporary file exist? If not, probably server-side configuration limits have been reached
// Uncomment this for debugging purposes
/*
if ( ! file_exists($_FILES['attachment']['tmp_name'][$i]) )
{
return hesk_fileError($hesklang['fnuscphp']);
}
*/
/* If upload was successful let's create the headers */
if ( ! move_uploaded_file($_FILES['attachment']['tmp_name'][$i], dirname(dirname(__FILE__)).'/'.$hesk_settings['attach_dir'].'/'.$file_name))
{
return hesk_fileError($hesklang['cannot_move_tmp']);
}
$info = array(
'saved_name'=> $file_name,
'real_name' => $file_realname,
'size' => $file_size
);
return $info;
} // End hesk_uploadFile()
function hesk_fileError($error)
{
global $hesk_settings, $hesklang, $trackingID;
global $hesk_error_buffer;
$hesk_error_buffer['attachments'] = $error;
return false;
} // End hesk_fileError()
function hesk_removeAttachments($attachments)
{
global $hesk_settings, $hesklang;
$hesk_settings['server_path'] = dirname(dirname(__FILE__)).'/'.$hesk_settings['attach_dir'].'/';
foreach ($attachments as $myatt)
{
hesk_unlink($hesk_settings['server_path'].$myatt['saved_name']);
}
return true;
} // End hesk_removeAttachments()

2394
hesk/inc/common.inc.php Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,247 @@
<?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');}
// Get and append custom fields setup to the settings
hesk_load_custom_fields();
// Save number of custom fields
$hesk_settings['num_custom_fields'] = count($hesk_settings['custom_fields']);
// Load custom fields for admin functions
if (function_exists('hesk_checkPermission'))
{
foreach ($hesk_settings['custom_fields'] as $k => $v)
{
$hesk_settings['possible_ticket_list'][$k] = $hesk_settings['custom_fields'][$k]['title'];
}
}
/*** FUNCTIONS ***/
function hesk_load_custom_fields($category=0, $use_cache=1)
{
global $hesk_settings, $hesklang;
// Do we have a cached version available
$cache_dir = dirname(dirname(__FILE__)).'/'.$hesk_settings['cache_dir'].'/';
$cache_file = $cache_dir . 'cf_' . sha1($hesk_settings['language']).'.cache.php';
if ($use_cache && file_exists($cache_file))
{
require($cache_file);
return true;
}
// Get custom fields from the database
$hesk_settings['custom_fields'] = array();
// Make sure we have database connection
hesk_load_database_functions();
hesk_dbConnect();
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_fields` WHERE `use` IN ('1', '2') ORDER BY `place` ASC, `order` ASC");
while ($row = hesk_dbFetchAssoc($res))
{
$id = 'custom' . $row['id'];
unset($row['id']);
// Let's set field name for current language (or the first one we find)
$names = json_decode($row['name'], true);
$row['name'] = (isset($names[$hesk_settings['language']])) ? $names[$hesk_settings['language']] : reset($names);
// Name for display in ticket list; punctuation removed and shortened
$row['title'] = hesk_remove_punctuation($row['name']);
$row['title'] = hesk_mb_strlen($row['title']) > 30 ? hesk_mb_substr($row['title'], 0, 30) . '...' : $row['title'];
// A version with forced punctuation
$row['name:'] = in_array(substr($row['name'], -1), array(':', '?', '!', '.') ) ? $row['name'] : $row['name'] . ':';
// Decode categories
$row['category'] = strlen($row['category']) ? json_decode($row['category'], true) : array();
// Decode options
$row['value'] = json_decode($row['value'], true);
// Add to custom_fields array
$hesk_settings['custom_fields'][$id] = $row;
}
// Try to cache results
if ($use_cache && (is_dir($cache_dir) || ( @mkdir($cache_dir, 0777) && is_writable($cache_dir) ) ) )
{
// Is there an index.htm file?
if ( ! file_exists($cache_dir.'index.htm'))
{
@file_put_contents($cache_dir.'index.htm', '');
}
// Write data
@file_put_contents($cache_file, '<?php if (!defined(\'IN_SCRIPT\')) {die();} $hesk_settings[\'custom_fields\']=' . var_export($hesk_settings['custom_fields'], true) . ';' );
}
return true;
} // END hesk_load_custom_fields()
function hesk_is_custom_field_in_category($custom_id, $category_id)
{
global $hesk_settings;
return (
empty($hesk_settings['custom_fields'][$custom_id]['category']) ||
in_array($category_id, $hesk_settings['custom_fields'][$custom_id]['category'])
) ? true : false;
} // END hesk_is_custom_field_in_category()
function hesk_custom_field_type($type)
{
global $hesklang;
switch ($type)
{
case 'text':
return $hesklang['stf'];
case 'textarea':
return $hesklang['stb'];
case 'radio':
return $hesklang['srb'];
case 'select':
return $hesklang['ssb'];
case 'checkbox':
return $hesklang['scb'];
case 'email':
return $hesklang['email'];
case 'date':
return $hesklang['date'];
case 'hidden':
return $hesklang['sch'];
default:
return false;
}
} // END hesk_custom_field_type()
function hesk_custom_date_display_format($timestamp, $format = 'F j, Y')
{
global $hesklang;
if ($timestamp == '')
{
return '';
}
if ( ! is_int($timestamp))
{
$timestamp = $timestamp * 1;
}
if ($hesklang['LANGUAGE']=='English')
{
return gmdate($format, $timestamp);
}
// Attempt to translate date for non-English users
$translate_months = array(
'January' => $hesklang['m1'],
'February' => $hesklang['m2'],
'March' => $hesklang['m3'],
'April' => $hesklang['m4'],
'May' => $hesklang['m5'],
'June' => $hesklang['m6'],
'July' => $hesklang['m7'],
'August' => $hesklang['m8'],
'September' => $hesklang['m9'],
'October' => $hesklang['m10'],
'November' => $hesklang['m11'],
'December' => $hesklang['m12']
);
$translate_months_short = array(
'Jan' => $hesklang['ms01'],
'Feb' => $hesklang['ms02'],
'Mar' => $hesklang['ms03'],
'Apr' => $hesklang['ms04'],
'May' => $hesklang['ms05'],
'Jun' => $hesklang['ms06'],
'Jul' => $hesklang['ms07'],
'Aug' => $hesklang['ms08'],
'Sep' => $hesklang['ms09'],
'Oct' => $hesklang['ms10'],
'Nov' => $hesklang['ms11'],
'Dec' => $hesklang['ms12']
);
$translate_days = array(
'Monday' => $hesklang['d1'],
'Tuesday' => $hesklang['d2'],
'Wednesday' => $hesklang['d3'],
'Thursday' => $hesklang['d4'],
'Friday' => $hesklang['d5'],
'Saturday' => $hesklang['d6'],
'Sunday' => $hesklang['d0']
);
$translate_days_short = array(
'Mon' => $hesklang['mo'],
'Tuw' => $hesklang['tu'],
'Wes' => $hesklang['we'],
'Thu' => $hesklang['th'],
'Fri' => $hesklang['fr'],
'Sat' => $hesklang['sa'],
'Sun' => $hesklang['su']
);
$date_translate = array();
if (strpos($format, 'F') !== false)
{
$date_translate = array_merge($date_translate, $translate_months);
}
if (strpos($format, 'M') !== false)
{
$date_translate = array_merge($date_translate, $translate_months_short);
}
if (strpos($format, 'l') !== false)
{
$date_translate = array_merge($date_translate, $translate_days);
}
if (strpos($format, 'D') !== false)
{
$date_translate = array_merge($date_translate, $translate_days_short);
}
if (count($date_translate))
{
return str_replace( array_keys($date_translate), array_values($date_translate), gmdate($format, $timestamp));
}
return gmdate($format, $timestamp);
} // END hesk_custom_date_display_format()
function hesk_remove_punctuation($in)
{
return rtrim($in, ':?!.');
} // END hesk_remove_punctuation()

259
hesk/inc/database.inc.php Normal file
View File

@@ -0,0 +1,259 @@
<?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');}
function hesk_dbCollate()
{
global $hesklang;
// MySQL vesions prior to 5.6 don't support some collations
if ( in_array($hesklang['_COLLATE'], array('utf8_croatian_ci', 'utf8_german2_ci', 'utf8_vietnamese_ci')) )
{
if ( version_compare( hesk_dbResult( hesk_dbQuery('SELECT VERSION() AS version') ), '5.6', '<') )
{
$hesklang['_COLLATE'] = 'utf8_general_ci';
}
}
return hesk_dbEscape($hesklang['_COLLATE']);
} // END hesk_dbCollate()
function hesk_dbSetNames()
{
global $hesk_settings, $hesk_db_link;
if ($hesk_settings['db_vrsn'])
{
mysql_set_charset('utf8', $hesk_db_link);
}
else
{
hesk_dbQuery("SET NAMES 'utf8'");
}
} // END hesk_dbSetNames()
function hesk_dbFormatEmail($email, $field = 'email')
{
global $hesk_settings;
$email = hesk_dbLike($email);
if ($hesk_settings['multi_eml'])
{
return " (`".hesk_dbEscape($field)."` LIKE '".hesk_dbEscape($email)."' OR `".hesk_dbEscape($field)."` LIKE '%,".hesk_dbEscape($email)."' OR `".hesk_dbEscape($field)."` LIKE '".hesk_dbEscape($email).",%' OR `".hesk_dbEscape($field)."` LIKE '%,".hesk_dbEscape($email).",%') ";
}
else
{
return " `".hesk_dbEscape($field)."` LIKE '".hesk_dbEscape($email)."' ";
}
} // END hesk_dbFormatEmail()
function hesk_dbTime()
{
$res = hesk_dbQuery("SELECT NOW()");
return strtotime(hesk_dbResult($res,0,0));
} // END hesk_dbTime()
function hesk_dbSetTimezone()
{
global $hesk_settings;
hesk_dbQuery('SET time_zone = "'.hesk_timeToHHMM(date('Z')).'"');
return true;
} // END hesk_dbSetTimezone()
function hesk_dbEscape($in)
{
global $hesk_db_link;
$in = mysql_real_escape_string(stripslashes($in), $hesk_db_link);
$in = str_replace('`','&#96;',$in);
return $in;
} // END hesk_dbEscape()
function hesk_dbLike($in)
{
return str_replace( array('\\', '_', '%'), array('\\\\', '\\\\_', '\\\\%'), $in); // '
} // END hesk_dbLike()
function hesk_dbConnect()
{
global $hesk_settings;
global $hesk_db_link;
global $hesklang;
// Do we have an existing active link?
if ($hesk_db_link)
{
return $hesk_db_link;
}
// Is mysql supported?
if ( ! function_exists('mysql_connect') )
{
die($hesklang['emp']);
}
// Connect to the database
$hesk_db_link = @mysql_connect($hesk_settings['db_host'], $hesk_settings['db_user'], $hesk_settings['db_pass']);
// Errors?
if ( ! $hesk_db_link)
{
if ($hesk_settings['debug_mode'])
{
hesk_error("$hesklang[cant_connect_db]</p><p>$hesklang[mysql_said]:<br />".mysql_error()."</p>");
}
else
{
hesk_error("$hesklang[cant_connect_db]</p><p>$hesklang[contact_webmsater] <a href=\"mailto:$hesk_settings[webmaster_mail]\">$hesk_settings[webmaster_mail]</a></p>");
}
}
if ( ! @mysql_select_db($hesk_settings['db_name'], $hesk_db_link))
{
if ($hesk_settings['debug_mode'])
{
hesk_error("$hesklang[cant_connect_db]</p><p>$hesklang[mysql_said]:<br />".mysql_error()."</p>");
}
else
{
hesk_error("$hesklang[cant_connect_db]</p><p>$hesklang[contact_webmsater] <a href=\"mailto:$hesk_settings[webmaster_mail]\">$hesk_settings[webmaster_mail]</a></p>");
}
}
// Check MySQL/PHP version and set encoding to utf8
hesk_dbSetNames();
// Set the correct timezone
hesk_dbSetTimezone();
return $hesk_db_link;
} // END hesk_dbConnect()
function hesk_dbClose()
{
global $hesk_db_link;
return @mysql_close($hesk_db_link);
} // END hesk_dbClose()
function hesk_dbQuery($query)
{
global $hesk_last_query;
global $hesk_db_link;
global $hesklang, $hesk_settings;
if ( ! $hesk_db_link && ! hesk_dbConnect())
{
return false;
}
$hesk_last_query = $query;
#echo "<p>EXPLAIN $query</p>\n";
if ($res = @mysql_query($query, $hesk_db_link))
{
return $res;
}
elseif ($hesk_settings['debug_mode'])
{
hesk_error("$hesklang[cant_sql]: $query</p><p>$hesklang[mysql_said]:<br />".mysql_error()."</p>");
}
else
{
hesk_error("$hesklang[cant_sql]</p><p>$hesklang[contact_webmsater] <a href=\"mailto:$hesk_settings[webmaster_mail]\">$hesk_settings[webmaster_mail]</a></p>");
}
} // END hesk_dbQuery()
function hesk_dbFetchAssoc($res)
{
return @mysql_fetch_assoc($res);
} // END hesk_FetchAssoc()
function hesk_dbFetchRow($res)
{
return @mysql_fetch_row($res);
} // END hesk_FetchRow()
function hesk_dbResult($res, $row = 0, $column = 0)
{
return @mysql_result($res, $row, $column);
} // END hesk_dbResult()
function hesk_dbInsertID()
{
global $hesk_db_link;
if ($lastid = @mysql_insert_id($hesk_db_link))
{
return $lastid;
}
} // END hesk_dbInsertID()
function hesk_dbFreeResult($res)
{
return mysql_free_result($res);
} // END hesk_dbFreeResult()
function hesk_dbNumRows($res)
{
return @mysql_num_rows($res);
} // END hesk_dbNumRows()
function hesk_dbAffectedRows()
{
global $hesk_db_link;
return @mysql_affected_rows($hesk_db_link);
} // END hesk_dbAffectedRows()

View File

@@ -0,0 +1,266 @@
<?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');}
function hesk_dbCollate()
{
global $hesklang;
// MySQL vesions prior to 5.6 don't support some collations
if ( in_array($hesklang['_COLLATE'], array('utf8_croatian_ci', 'utf8_german2_ci', 'utf8_vietnamese_ci')) )
{
if ( version_compare( hesk_dbResult( hesk_dbQuery('SELECT VERSION() AS version') ), '5.6', '<') )
{
$hesklang['_COLLATE'] = 'utf8_general_ci';
}
}
return hesk_dbEscape($hesklang['_COLLATE']);
} // END hesk_dbCollate()
function hesk_dbSetNames()
{
global $hesk_settings, $hesk_db_link;
if ($hesk_settings['db_vrsn'])
{
mysqli_set_charset($hesk_db_link, 'utf8');
}
else
{
hesk_dbQuery("SET NAMES 'utf8'");
}
} // END hesk_dbSetNames()
function hesk_dbFormatEmail($email, $field = 'email')
{
global $hesk_settings;
$email = hesk_dbLike($email);
if ($hesk_settings['multi_eml'])
{
return " (`".hesk_dbEscape($field)."` LIKE '".hesk_dbEscape($email)."' OR `".hesk_dbEscape($field)."` LIKE '%,".hesk_dbEscape($email)."' OR `".hesk_dbEscape($field)."` LIKE '".hesk_dbEscape($email).",%' OR `".hesk_dbEscape($field)."` LIKE '%,".hesk_dbEscape($email).",%') ";
}
else
{
return " `".hesk_dbEscape($field)."` LIKE '".hesk_dbEscape($email)."' ";
}
} // END hesk_dbFormatEmail()
function hesk_dbTime()
{
$res = hesk_dbQuery("SELECT NOW()");
return strtotime(hesk_dbResult($res,0,0));
} // END hesk_dbTime()
function hesk_dbSetTimezone()
{
global $hesk_settings;
hesk_dbQuery('SET time_zone = "'.hesk_timeToHHMM(date('Z')).'"');
return true;
} // END hesk_dbSetTimezone()
function hesk_dbEscape($in)
{
global $hesk_db_link;
$in = mysqli_real_escape_string($hesk_db_link, stripslashes($in));
$in = str_replace('`','&#96;',$in);
return $in;
} // END hesk_dbEscape()
function hesk_dbLike($in)
{
return str_replace( array('\\', '_', '%'), array('\\\\', '\\\\_', '\\\\%'), $in); // '
} // END hesk_dbLike()
function hesk_dbConnect()
{
global $hesk_settings;
global $hesk_db_link;
global $hesklang;
// Do we have an existing active link?
if ($hesk_db_link)
{
return $hesk_db_link;
}
// Is mysqli supported?
if ( ! function_exists('mysqli_connect') )
{
die($hesklang['emp']);
}
// Do we need a special port? Check and connect to the database
if ( strpos($hesk_settings['db_host'], ':') )
{
list($hesk_settings['db_host_no_port'], $hesk_settings['db_port']) = explode(':', $hesk_settings['db_host']);
$hesk_db_link = @mysqli_connect($hesk_settings['db_host_no_port'], $hesk_settings['db_user'], $hesk_settings['db_pass'], $hesk_settings['db_name'], intval($hesk_settings['db_port']) );
}
else
{
$hesk_db_link = @mysqli_connect($hesk_settings['db_host'], $hesk_settings['db_user'], $hesk_settings['db_pass'], $hesk_settings['db_name']);
}
// Errors?
if ( ! $hesk_db_link)
{
if ($hesk_settings['debug_mode'])
{
hesk_error("$hesklang[cant_connect_db]</p><p>$hesklang[mysql_said]:<br />(".mysqli_connect_errno().") ".mysqli_connect_error()."</p>");
}
else
{
hesk_error("$hesklang[cant_connect_db]</p><p>$hesklang[contact_webmsater] <a href=\"mailto:$hesk_settings[webmaster_mail]\">$hesk_settings[webmaster_mail]</a></p>");
}
}
// Check MySQL/PHP version and set encoding to utf8
hesk_dbSetNames();
// Set the correct timezone
hesk_dbSetTimezone();
return $hesk_db_link;
} // END hesk_dbConnect()
function hesk_dbClose()
{
global $hesk_db_link;
return @mysqli_close($hesk_db_link);
} // END hesk_dbClose()
function hesk_dbQuery($query)
{
global $hesk_last_query;
global $hesk_db_link;
global $hesklang, $hesk_settings;
if ( ! $hesk_db_link && ! hesk_dbConnect())
{
return false;
}
$hesk_last_query = $query;
# echo "<p>EXPLAIN $query</p>\n";
if ($res = @mysqli_query($hesk_db_link, $query))
{
return $res;
}
elseif ($hesk_settings['debug_mode'])
{
hesk_error("$hesklang[cant_sql]: $query</p><p>$hesklang[mysql_said]:<br />".mysqli_error($hesk_db_link)."</p>");
}
else
{
hesk_error("$hesklang[cant_sql]</p><p>$hesklang[contact_webmsater] <a href=\"mailto:$hesk_settings[webmaster_mail]\">$hesk_settings[webmaster_mail]</a></p>");
}
} // END hesk_dbQuery()
function hesk_dbFetchAssoc($res)
{
return @mysqli_fetch_assoc($res);
} // END hesk_FetchAssoc()
function hesk_dbFetchRow($res)
{
return @mysqli_fetch_row($res);
} // END hesk_FetchRow()
function hesk_dbResult($res, $row = 0, $column = 0)
{
$i=0;
$res->data_seek(0);
while ($tmp = @mysqli_fetch_array($res, MYSQLI_NUM))
{
if ($i==$row)
{
return $tmp[$column];
}
$i++;
}
return '';
} // END hesk_dbResult()
function hesk_dbInsertID()
{
global $hesk_db_link;
if ($lastid = @mysqli_insert_id($hesk_db_link))
{
return $lastid;
}
} // END hesk_dbInsertID()
function hesk_dbFreeResult($res)
{
return @mysqli_free_result($res);
} // END hesk_dbFreeResult()
function hesk_dbNumRows($res)
{
return @mysqli_num_rows($res);
} // END hesk_dbNumRows()
function hesk_dbAffectedRows()
{
global $hesk_db_link;
return @mysqli_affected_rows($hesk_db_link);
} // END hesk_dbAffectedRows()

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