diff --git a/.gitignore b/.gitignore index 096135f6..cc5bce11 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ download_attachment.php file_limits.php footer.txt header.txt -hesk_javascript_v25.js hesk_settings.inc.php img/add_article.png img/add_category.png @@ -147,7 +146,6 @@ img/tag_off.png img/unlock.png img/vertical.jpg img/view.png -inc/admin_functions.inc.php inc/assignment_search.inc.php inc/attachments.inc.php inc/calendar/img/cal.gif @@ -268,3 +266,10 @@ robots.txt .idea/ attachments/__latest.txt attachments +img/ban.png +img/banned.png +img/ico_tools.png +inc/recaptcha/recaptchalib_v2.php +ip_whois.php +language/en/emails/reset_password.txt +language/en/help_files/ticket_list.html \ No newline at end of file diff --git a/admin/admin_main.php b/admin/admin_main.php index 4b72cc43..4fe6e7c2 100644 --- a/admin/admin_main.php +++ b/admin/admin_main.php @@ -1,7 +1,7 @@
'.$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'])) { $message .= "\n\n" . addslashes($_SESSION['signature']) . "\n"; } @@ -153,8 +197,15 @@ if ($hesk_settings['attachments']['use'] && !empty($attachments)) } } -/* Add reply */ -$result = 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'])."')"); +// 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."

{$hesklang['creb']} {$_SESSION['name']}")."',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 = ''; @@ -189,15 +240,61 @@ $defaultStatusReplyStatus = hesk_dbFetchAssoc(hesk_dbQuery("SELECT `ID`, `IsClos $staffClosedCheckboxStatus = hesk_dbFetchAssoc(hesk_dbQuery("SELECT `ID`, `IsClosed` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsStaffClosedOption` = 1 LIMIT 1")); $lockedTicketStatus = hesk_dbFetchAssoc(hesk_dbQuery("SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `LockedTicketStatus` = 1 LIMIT 1")); -$new_status = empty($_POST['close']) ? $defaultStatusReplyStatus['ID'] : $staffClosedCheckboxStatus['ID']; - -/* --> If a ticket is locked keep it closed */ +// Get new ticket status +$sql_status = ''; +// -> If locked, keep it resolved if ($ticket['locked']) { $new_status = $lockedTicketStatus['ID']; } +elseif (isset($_POST['submit_as_status'])) +{ + $new_status = $_POST['submit_as_status']; + + if ($ticket['status'] != $new_status) + { + // Does this status close the ticket? + $newStatusRs = hesk_dbQuery('SELECT `IsClosed`, `ShortNameContentKey` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `ID` = '.hesk_dbEscape($new_status)); + $newStatus = hesk_dbFetchAssoc($newStatusRs); + + if ($newStatus['IsClosed']) + { + $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' "; + } + } else + { + // Ticket isn't being closed, just add the history to the sql query + $revision = sprintf($hesklang['thist9'],hesk_date(),$hesklang[$newStatus['ShortNameContentKey']],$_SESSION['name'].' ('.$_SESSION['user'].')'); + $sql_status = " , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') "; + } + } +} +// -> Submit as Customer reply +elseif ($submit_as_customer) +{ + //Get the status ID for customer replies + $customerReplyStatusRs = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsCustomerReplyStatus` = 1 LIMIT 1'); + $customerReplyStatus = hesk_dbFetchAssoc($customerReplyStatusRs); + $new_status = $customerReplyStatus['ID']; +} +// -> Default: submit as "Replied by staff" +else +{ + //Get the status ID for staff replies + $staffReplyStatusRs = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsDefaultStaffReplyStatus` = 1 LIMIT 1'); + $staffReplyStatus = hesk_dbFetchAssoc($staffReplyStatusRs); + $new_status = $staffReplyStatus['ID']; +} + +$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'])."' "; -$sql = "UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$new_status}', `lastreplier`='1', `replierid`='".intval($_SESSION['id'])."' "; /* Update time_worked or force update lastchange */ if ($time_worked == '00:00:00') @@ -216,19 +313,19 @@ if ( ! empty($_POST['assign_self']) && hesk_checkPermission('can_assign_self',0) } $sql .= " $priority_sql "; +$sql .= " $sql_status "; -$isNewStatusClosed = empty($_POST['close']) ? $defaultStatusReplyStatus['IsClosed'] : $staffClosedCheckboxStatus['IsClosed']; -if ($isNewStatusClosed) +if ( ! $ticket['firstreplyby'] ) { - $revision = sprintf($hesklang['thist3'],hesk_date(),$_SESSION['name'].' ('.$_SESSION['user'].')'); - $sql .= " , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') "; - - if ($hesk_settings['custopen'] != 1) - { - $sql .= " , `locked`='1' "; - } + $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}' LIMIT 1"; hesk_dbQuery($sql); unset($sql); @@ -247,12 +344,13 @@ $info = array( 'trackid' => $ticket['trackid'], 'status' => $new_status, 'name' => $ticket['name'], -'lastreplier' => $_SESSION['name'], +'lastreplier' => ($submit_as_customer ? $ticket['name'] : $_SESSION['name']), 'subject' => $ticket['subject'], 'message' => stripslashes($message), 'attachments' => $myattachments, 'dt' => hesk_date($ticket['dt'], true), 'lastchange' => hesk_date($ticket['lastchange'], true), +'id' => $ticket['id'], ); // 2. Add custom fields to the array @@ -264,19 +362,26 @@ foreach ($hesk_settings['custom_fields'] as $k => $v) // 3. Make sure all values are properly formatted for email $ticket = hesk_ticketToPlain($info, 1, 0); -// Notify the customer -if ( ! isset($_POST['no_notify']) || intval( hesk_POST('no_notify') ) != 1) +// 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'])." LIMIT 1"); + /* Set reply submitted message */ $_SESSION['HESK_SUCCESS'] = TRUE; $_SESSION['HESK_MESSAGE'] = $hesklang['reply_submitted']; -if (!empty($_POST['close'])) -{ - $_SESSION['HESK_MESSAGE'] .= '

'.$hesklang['ticket_marked'].' '.$hesklang['closed'].''; -} /* What to do after reply? */ if ($_SESSION['afterreply'] == 1) diff --git a/admin/admin_settings.php b/admin/admin_settings.php index d2cd8f43..b474eb2b 100644 --- a/admin/admin_settings.php +++ b/admin/admin_settings.php @@ -1,7 +1,7 @@ "; var today = new Date(); today.setHours(server_time.substr(0,server_time.indexOf(":"))); @@ -475,6 +437,7 @@ if ( defined('HESK_DEMO') )
  • +
  • \n"; + } + $hesk_error_buffer = $tmp; + + $hesk_error_buffer = $hesklang['pcer'].'

    '; + hesk_process_messages($hesk_error_buffer,'admin_ticket.php?track='.$ticket['trackid'].'&Refresh='.rand(10000,99999)); + } + + // Process attachments + 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`,`type`) VALUES ('".hesk_dbEscape($trackingID)."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."', '1')"); + $myattachments .= hesk_dbInsertID() . '#' . $myatt['real_name'] .','; + } + } + + // Add note to database + $msg = nl2br(hesk_makeURL($msg)); + hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` (`ticket`,`who`,`dt`,`message`,`attachments`) VALUES ('".intval($ticket['id'])."','".intval($_SESSION['id'])."',NOW(),'".hesk_dbEscape($msg)."','".hesk_dbEscape($myattachments)."')"); /* Notify assigned staff that a note has been added if needed */ $users = hesk_dbQuery("SELECT `email`, `notify_note` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE (`id`='".intval($ticket['owner'])."' OR (`isadmin` = '1' AND `notify_note_unassigned` = '1')) AND `id` <> '".intval($_SESSION['id'])."'"); @@ -260,6 +427,8 @@ if (isset($_POST['notemsg']) && hesk_token_check('POST')) 'message' => stripslashes($msg), 'dt' => hesk_date($ticket['dt'], true), 'lastchange' => hesk_date($ticket['lastchange'], true), + 'attachments' => $myattachments, + 'id' => $ticket['id'], ); // 2. Add custom fields to the array @@ -289,7 +458,7 @@ if (isset($_POST['notemsg']) && hesk_token_check('POST')) } /* Update time worked */ -if ( ($can_reply || $can_edit) && isset($_POST['h']) && isset($_POST['m']) && isset($_POST['s']) && hesk_token_check('POST')) +if ($hesk_settings['time_worked'] && ($can_reply || $can_edit) && isset($_POST['h']) && isset($_POST['m']) && isset($_POST['s']) && hesk_token_check('POST')) { $h = intval( hesk_POST('h') ); $m = intval( hesk_POST('m') ); @@ -367,7 +536,13 @@ if (isset($_GET['delatt']) && hesk_token_check()) $reply = 0; } - /* Get attachment info */ + $note = intval( hesk_GET('note', 0) ); + if ($note < 1) + { + $note = 0; + } + + /* Get attachment info */ $res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` WHERE `att_id`='".intval($att_id)."' LIMIT 1"); if (hesk_dbNumRows($res) != 1) { @@ -394,6 +569,10 @@ if (isset($_GET['delatt']) && hesk_token_check()) hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` SET `attachments`=REPLACE(`attachments`,'".hesk_dbEscape($att_id.'#'.$att['real_name']).",','') WHERE `id`='".intval($reply)."' LIMIT 1"); hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `id`='".intval($ticket['id'])."' LIMIT 1"); } + elseif ($note) + { + hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."notes` SET `attachments`=REPLACE(`attachments`,'".hesk_dbEscape($att_id.'#'.$att['real_name']).",','') WHERE `id`={$note} LIMIT 1"); + } else { hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `attachments`=REPLACE(`attachments`,'".hesk_dbEscape($att_id.'#'.$att['real_name']).",',''), `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `id`='".intval($ticket['id'])."' LIMIT 1"); @@ -417,7 +596,7 @@ while ($row=hesk_dbFetchAssoc($result)) /* List of users */ $admins = array(); -$result = hesk_dbQuery("SELECT `id`,`name`,`isadmin`,`categories`,`heskprivileges` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `active` = '1' ORDER BY `id` ASC"); +$result = hesk_dbQuery("SELECT `id`,`name`,`isadmin`,`categories`,`heskprivileges` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `active` = '1' ORDER BY `name` ASC"); while ($row=hesk_dbFetchAssoc($result)) { /* Is this an administrator? */ @@ -442,9 +621,15 @@ while ($row=hesk_dbFetchAssoc($result)) } /* Get replies */ -$reply = ''; -$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`='".intval($ticket['id'])."' ORDER BY `id` " . ($hesk_settings['new_top'] ? 'DESC' : 'ASC') ); -$replies = hesk_dbNumRows($result); +if ($ticket['replies']) +{ + $reply = ''; + $result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`='".intval($ticket['id'])."' ORDER BY `id` " . ($hesk_settings['new_top'] ? 'DESC' : 'ASC') ); +} +else +{ + $reply = false; +} // Demo mode if ( defined('HESK_DEMO') ) @@ -475,7 +660,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');

  • - +

  • @@ -496,6 +681,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
  • +

  • +
  • -

    Delete Note

    -

    -

    -

    +
    +
    +

    -

    +
    ' : ''; + + $att = explode(',', substr($note['attachments'], 0, -1) ); + $num = count($att); + foreach ($att as $myatt) + { + list($att_id, $att_name) = explode('#', $myatt); + + // Can edit and delete note (attachments)? + if ($can_del_notes || $note['who'] == $_SESSION['id']) + { + // If this is the last attachment and no message, show "delete ticket" link + if ($num == 1 && strlen($note['message']) == 0) + { + echo ' + + '; + } + // Show "delete attachment" link + else + { + echo ' + + '; + } + } + + echo ' + + + + '.$att_name.'
    + '; + } + } + ?> +
    +
    + + + +
    +
    - diff --git a/admin/knowledgebase_private.php b/admin/knowledgebase_private.php index 24d23267..52c8759b 100644 --- a/admin/knowledgebase_private.php +++ b/admin/knowledgebase_private.php @@ -1,7 +1,7 @@ @@ -236,7 +236,7 @@ function hesk_show_kb_article($artid) hesk_kb_header($hesk_settings['kb_link'], $article['catid']); // Update views by 1 - hesk_dbQuery('UPDATE `'.hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` SET `views`=`views`+1 WHERE `id`='".intval($artid)."' LIMIT 1"); + hesk_dbQuery('UPDATE `'.hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` SET `views`=`views`+1 WHERE `id`={$artid} LIMIT 1"); echo '

    '.$article['subject'].'

    @@ -258,6 +258,51 @@ function hesk_show_kb_article($artid) echo '

    '; } + // TODO Check how this looks + // 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 (this) article + if ( ! isset($base_score) ) + { + $base_score = $related['score']; + 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 '
    '.$hesklang['relart'].''; + foreach ($related_articles as $id => $subject) + { + echo ' '.$subject.'
    '; + } + echo '
    '; + } + } + if ($article['catid']==1) { @@ -322,7 +367,7 @@ function hesk_show_kb_category($catid, $is_search = 0) { } } - $res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` WHERE `id`='".intval($catid)."' LIMIT 1"); + $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']) @@ -333,7 +378,7 @@ function hesk_show_kb_category($catid, $is_search = 0) {
    '; } - $result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` WHERE `parent`='".intval($catid)."' ORDER BY `parent` ASC, `cat_order` ASC"); + $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) { ?> @@ -442,7 +487,7 @@ function hesk_show_kb_category($catid, $is_search = 0) { '.$hesklang['noac'].'

    '; diff --git a/admin/lock.php b/admin/lock.php index 26c30c2a..ed03cf36 100644 --- a/admin/lock.php +++ b/admin/lock.php @@ -1,7 +1,7 @@ fetch_assoc(); $statusId = $statusRow['ID']; -hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$statusId}',`locked`='{$status}', `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1"); +hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$statusId}',`locked`='{$status}' $closedby_sql , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1"); /* Back to ticket page and show a success message */ hesk_process_messages($tmp,'admin_ticket.php?track='.$trackingID.'&Refresh='.rand(10000,99999),'SUCCESS'); diff --git a/admin/mail.php b/admin/mail.php index ea056d11..6ff15c02 100644 --- a/admin/mail.php +++ b/admin/mail.php @@ -1,7 +1,7 @@ 1 // Get messages from the database - $res = hesk_dbQuery("SELECT * 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)." "); + $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)." "); ?>
    diff --git a/admin/manage_canned.php b/admin/manage_canned.php index cb1a8958..d0cc2a8a 100644 --- a/admin/manage_canned.php +++ b/admin/manage_canned.php @@ -1,7 +1,7 @@ @@ -92,6 +101,7 @@ else {return false;}
    @@ -112,6 +122,27 @@ else {return false;} />
    +
    + +
    +

    + +
    +
    @@ -160,6 +191,45 @@ else {return false;}
    +
    +
    +

    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    + '.$hesklang['no_ticket_tpl'].'

    '; + } else { + ?> + + + + + + + + + '.$mysaved['title'].''; + + + $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 ' + + + + + '; + } // End while + + ?> + +
    '.$mysaved['title'].' + '; + + if ($num > 1) + { + if ($j == 1) + { + echo' + + '; + } + elseif ($j == $num) + { + echo' '; + } + else + { + echo' + + + '; + } + } + else + { + echo ''; + } + + echo ' +
    + +
    +
    +
    +
    + +
    +

    +
    + 0) + { + ?> +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + ' . $hesklang['ticket_tpl_add'] . '

    '; + } + ?> +
    + +
    + + > + +
    +
    +
    + +
    + + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + +' . $hesklang['sel_ticket_tpl'] . '
  • '; + $savename = hesk_input( hesk_POST('name') ) or $hesk_error_buffer .= '
  • ' . $hesklang['ent_ticket_tpl_title'] . '
  • '; + $msg = hesk_input( hesk_POST('msg') ) or $hesk_error_buffer .= '
  • ' . $hesklang['ent_ticket_tpl_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; + + /* Any errors? */ + if (strlen($hesk_error_buffer)) + { + $hesk_error_buffer = $hesklang['rfm'].'

    '; + 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)."' LIMIT 1"); + + unset($_SESSION['canned']['what']); + unset($_SESSION['canned']['id']); + unset($_SESSION['canned']['name']); + unset($_SESSION['canned']['msg']); + + 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 = ''; + $savename = hesk_input( hesk_POST('name') ) or $hesk_error_buffer .= '
  • ' . $hesklang['ent_ticket_tpl_title'] . '
  • '; + $msg = hesk_input( hesk_POST('msg') ) or $hesk_error_buffer .= '
  • ' . $hesklang['ent_ticket_tpl_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; + + /* Any errors? */ + if (strlen($hesk_error_buffer)) + { + $hesk_error_buffer = $hesklang['rfm'].'

    '; + 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 = $row[0]+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']); + + 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)."' LIMIT 1"); + 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)."' LIMIT 1"); + 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'])."' LIMIT 1"); + $i += 10; + } + + header('Location: manage_ticket_templates.php'); + exit(); +} // End order_saved() + +?> diff --git a/admin/manage_users.php b/admin/manage_users.php index f7cbea07..2df6b106 100644 --- a/admin/manage_users.php +++ b/admin/manage_users.php @@ -1,7 +1,7 @@ '', 'email' => '', - 'user' => '', + 'cleanpass' => '', + 'user' => '', + 'autoassign' => 'Y', + + // Signature 'signature' => '', + + // Permissions 'isadmin' => 1, 'active' => 1, 'categories' => array('1'), 'features' => array('can_view_tickets','can_reply_tickets','can_change_cat','can_assign_self','can_view_unassigned','can_view_online'), - 'signature' => '', - 'cleanpass' => '', + + // Preferences + 'afterreply' => 0, + 'autorefresh' => 0, + + // Defaults + 'autostart' => 1, + 'notify_customer_new' => 1, + 'notify_customer_reply' => 1, + 'show_suggested' => 1, + + // Notifications + 'notify_new_unassigned' => 1, + 'notify_new_my' => 1, + 'notify_reply_unassigned' => 1, + 'notify_reply_my' => 1, + 'notify_assigned' => 1, + 'notify_note' => 1, + 'notify_pm' => 1, + 'notify_note_unassigned' => 1, ); /* A list of all categories */ @@ -101,7 +134,10 @@ while ($row=hesk_dbFetchAssoc($res)) if ( ! $_SESSION['isadmin']) { /* Can't create admin users */ - $_POST['isadmin'] = 0; + if ( isset($_POST['isadmin']) ) + { + unset($_POST['isadmin']); + } /* Can only add features he/she has access to */ $hesk_settings['features'] = array_intersect( explode(',', $_SESSION['heskprivileges']) , $hesk_settings['features']); @@ -166,149 +202,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); ?>
    -
    -
    -
    -
    -
    *
    -
    - -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    -
    - -
    - $catname) - { - echo '
    '; - } - ?> -
    -
    -
    - -
    -
    '; - } - ?> -
    - -
    -
    -
    -
    -
    - -
    - -
    - -
    - -
    - -
    - -
    -
    -
    - - -
    - - -
    -
    -
    -
    - - - - -
    -
    - - -
    -
    -
    -
    +
    + + +   + +
    + + + + + + + + +
    » ' . $hesklang['ticket_tpl_man'] . ')' : ''; ?>
    +
    + +
    + :
    + +
    +
    + + + + +   + + + + ';} else {echo '
    ';} ?>
    - +
    ';} else {echo '
    ';} ?>
    - + + +

    @@ -472,12 +666,19 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); echo '
    />
    +


    diff --git a/admin/options.php b/admin/options.php index 95d05481..ba42c6ef 100644 --- a/admin/options.php +++ b/admin/options.php @@ -1,7 +1,7 @@ @@ -217,12 +219,18 @@ switch ($type) } text = unescape(text.replace(re_nlchar,\'#HESK#\')); + if (document.getElementById(\'show_select\').checked) + { + text = "{HESK_SELECT}" + text; + } + window.opener.document.getElementById(\'s_'.$id.'_val\').value = text; window.close(); }

    '.$hesklang['opt3'].'

    +

    '; diff --git a/admin/password.php b/admin/password.php new file mode 100644 index 00000000..79b745be --- /dev/null +++ b/admin/password.php @@ -0,0 +1,361 @@ +is_valid) + { + //$_SESSION['img_a_verified']=true; + } + else + { + $hesk_error_buffer['mysecnum']=$hesklang['recaptcha_error']; + } + } + // Using ReCaptcha API v2? + elseif ($hesk_settings['recaptcha_use'] == 2) + { + 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($_SERVER["REMOTE_ADDR"], 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 .= "
  • $error
  • \n"; + } + $hesk_error_buffer = $tmp; + + $hesk_error_buffer = $hesklang['pcer'].'

      '.$hesk_error_buffer.'
    '; + hesk_process_messages($hesk_error_buffer,'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() . $_SERVER['REMOTE_ADDR'] . 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($_SERVER['REMOTE_ADDR'])."') "); + + // 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 + hesk_process_messages($hesklang['pemls'],'NOREDIRECT','SUCCESS'); + } + } +} +// 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'] != $_SERVER['REMOTE_ADDR']) + { + 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'])); + + // 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; + } + 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'] == 2) +{ + define('RECAPTCHA',1); +} + +$hesk_settings['tmp_title'] = $hesk_settings['hesk_title'] . ' - ' .$hesklang['passr']; +require_once(HESK_PATH . 'inc/header.inc.php'); +?> + + +
    +
    + +
    +
    + + diff --git a/admin/profile.php b/admin/profile.php index 21082c12..d8a09d16 100644 --- a/admin/profile.php +++ b/admin/profile.php @@ -1,7 +1,7 @@
    -

    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -

    -
    - -
    - -
    -
    - -
    -
    -

    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    - -
    - - -
    -
    -

    -
    -
    - -
    - -
    - -
    - - - - - -
    - - - -
    - - - - - -
    -
    -
    - - - - - -
    - -
    - - -
    +
    diff --git a/admin/reports.php b/admin/reports.php index 917b4134..33da6eb6 100644 --- a/admin/reports.php +++ b/admin/reports.php @@ -1,7 +1,7 @@ 0" : "`t5`.`staffid` = '" . intval($_SESSION['id']) . "'" ) . " AND DATE(`t5`.`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `t1`.`category`) AS `t4` ON `t1`.`category`=`t4`.`category` - WHERE DATE(`t1`.`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "'" . - ( $can_run_reports_full ? "" : " AND `t1`.`owner` = '" . intval($_SESSION['id']) . "'" ) - ); + $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_SecondsToHHMMSS($row['seconds_worked']); + $tickets[$row['category']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0; } else { @@ -414,7 +415,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // Get number of resolved tickets - $res = hesk_dbQuery("SELECT COUNT(*) AS `num_tickets` , `category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `status` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) " . ( $can_run_reports_full ? "" : " AND `owner` = '" . intval($_SESSION['id']) . "'" ) . " AND DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `category`"); + $res = hesk_dbQuery("SELECT COUNT(*) AS `num_tickets` , `category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `status` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) " . ( $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)) @@ -433,10 +434,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // Convert total seconds worked to HH:MM:SS - $totals['worked'] = hesk_SecondsToHHMMSS($totals['worked']); + $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0; if ( isset($tickets[9999]) ) { - $tickets[9999]['worked'] = hesk_SecondsToHHMMSS($tickets[9999]['worked']); + $tickets[9999]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($tickets[9999]['worked']) : 0; } ?> @@ -445,10 +446,15 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); - + - + '.$hesklang['ts'].''; + } + ?> - + '.$totals['worked'].''; + } + ?> - + '.$d['worked'].''; + } + ?> - + '.$totals['worked'].''; + } + ?> get list of users - $res = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `id` ASC"); + $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)) @@ -531,19 +552,24 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // -> get list of tickets - $res = hesk_dbQuery("SELECT `owner`, COUNT(*) AS `cnt`, 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 DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `owner`"); + $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_SecondsToHHMMSS($row['seconds_worked']); + $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` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) AND DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `owner`"); + $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` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']} GROUP BY `owner`"); // -> update resolved ticket list values while ($row = hesk_dbFetchAssoc($res)) @@ -553,7 +579,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // -> 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 DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `staffid`"); + $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)) @@ -571,17 +597,17 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); $admins[$_SESSION['id']] = $_SESSION['name']; // -> get list of tickets - $res = hesk_dbQuery("SELECT COUNT(*) AS `cnt`, SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` = '" . intval($_SESSION['id']) . "' AND DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "'"); + $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_SecondsToHHMMSS($row['seconds_worked']); + $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 DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "'"); + $res = hesk_dbQuery("SELECT COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `owner` = '" . intval($_SESSION['id']) . "' AND `status` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']}"); $row = hesk_dbFetchAssoc($res); // -> update resolved ticket values @@ -589,7 +615,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); $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 DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "'"); + $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']; @@ -601,7 +627,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // Convert total seconds worked to HH:MM:SS - $totals['worked'] = hesk_SecondsToHHMMSS($totals['worked']); + $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0; ?> @@ -609,10 +635,15 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); - + - + '.$hesklang['ts'].''; + } + ?> - + '.$totals['worked'].''; + } + ?> - + '.$d['worked'].''; + } + ?> - + '.$totals['worked'].''; + } + ?>
    @@ -713,8 +764,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); - - + + '.$hesklang['ts'].''; + } + ?> - + '.$totals['worked'].''; + } + ?> - + '.$d['worked'].''; + } + ?> - + '.$d['worked'].''; + } + ?>
    @@ -778,19 +849,24 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // SQL query for all - $res = hesk_dbQuery("SELECT DATE(`dt`) AS `mydt`, COUNT(*) AS `cnt`, 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 DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `mydt`"); + $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_SecondsToHHMMSS($row['seconds_worked']); + $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` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) AND DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `mydt`"); + $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` IN (SELECT `ID` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']} GROUP BY `mydt`"); // Update ticket values while ($row = hesk_dbFetchAssoc($res)) @@ -800,7 +876,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } // Convert total seconds worked to HH:MM:SS - $totals['worked'] = hesk_SecondsToHHMMSS($totals['worked']); + $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0; ?> @@ -808,8 +884,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); - - + + '.$hesklang['ts'].''; + } + ?> - + '.$totals['worked'].''; + } + ?> - + '.$d['worked'].''; + } + ?> - + '.$totals['worked'].''; + } + ?>
    + +
    + +
    + +
    + + + +
    +
    +

    +
    +
    + '.$hesklang['no_sm'].'

    '; + } + 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']; + } + } + + ?> + + + + + + + + + + + + + + + + + + + +
      
    +
    + + +
    +
    + 1) + { + if ($k == 1) + { + ?> + + + + + + + + + + + + + + + + +  
    +
    + + + +
    +
    + +
    +
    + +
    +
    +

    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    + > +
    +
    +
    + +
    + +
    +
    +
    + ' : ''; ?> + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + 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') ); + + // Any errors? + if (count($hesk_error_buffer)) + { + $_SESSION['edit_sm'] = true; + $hesklang['new_sm'] = $hesklang['edit_sm']; + + $_SESSION['new_sm'] = array( + 'id' => $id, + 'style' => $style, + 'type' => $type, + 'title' => $title, + 'message' => hesk_input( hesk_POST('message') ), + ); + + $tmp = ''; + foreach ($hesk_error_buffer as $error) + { + $tmp .= "
  • $error
  • \n"; + } + $hesk_error_buffer = $tmp; + + $hesk_error_buffer = $hesklang['rfm'].'

    '; + 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; + $hesklang['new_sm'] = $hesklang['edit_sm']; + + $_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} LIMIT 1"); + + $_SESSION['smord'] = $id; + hesk_process_messages($hesklang['sm_mdf'],'service_messages.php','SUCCESS'); + +} // End save_sm() + + +function edit_sm() +{ + global $hesk_settings, $hesklang; + + // Get service messageID + $id = intval( hesk_GET('id') ) or hesk_error($hesklang['sm_e_id']); + + // Get details from the database + $res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` WHERE `id`={$id} LIMIT 1"); + if ( hesk_dbNumRows($res) != 1 ) + { + hesk_error($hesklang['sm_not_found']); + } + $sm = hesk_dbFetchAssoc($res); + + $_SESSION['new_sm'] = $sm; + $_SESSION['edit_sm'] = true; + + $hesklang['new_sm'] = $hesklang['edit_sm']; + +} // 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} LIMIT 1"); + + // Update order of all service messages + update_sm_order(); + + // Finish + header('Location: service_messages.php'); + exit(); + +} // End order_sm() + + +function update_sm_order() +{ + global $hesk_settings, $hesklang; + + // Get list of current service messages + $res = hesk_dbQuery("SELECT `id` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` ORDER BY `order` ASC"); + + // Update database + $i = 10; + while ( $sm = hesk_dbFetchAssoc($res) ) + { + hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` SET `order`=".intval($i)." WHERE `id`='".intval($sm['id'])."' LIMIT 1"); + $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} LIMIT 1"); + + // 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; + $title = hesk_input( hesk_POST('title') ) or $hesk_error_buffer[] = $hesklang['sm_e_title']; + $message = hesk_getHTML( hesk_POST('message') ); + + // Any errors? + if (count($hesk_error_buffer)) + { + $_SESSION['new_sm'] = array( + 'style' => $style, + 'type' => $type, + 'title' => $title, + 'message' => hesk_input( hesk_POST('message') ), + ); + + $tmp = ''; + foreach ($hesk_error_buffer as $error) + { + $tmp .= "
  • $error
  • \n"; + } + $hesk_error_buffer = $tmp; + + $hesk_error_buffer = $hesklang['rfm'].'

    '; + hesk_process_messages($hesk_error_buffer,'service_messages.php'); + } + + // Just preview the message? + if ( isset($_POST['sm_preview']) ) + { + $_SESSION['preview_sm'] = true; + + $_SESSION['new_sm'] = array( + 'style' => $style, + 'type' => $type, + 'title' => $title, + 'message' => $message, + ); + + header('Location: service_messages.php'); + exit; + } + + // Get the latest service message order + $res = hesk_dbQuery("SELECT `order` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` ORDER BY `order` DESC LIMIT 1"); + $row = hesk_dbFetchRow($res); + $my_order = intval($row[0]) + 10; + + // Insert service message into database + hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."service_messages` (`author`,`title`,`message`,`style`,`type`,`order`) VALUES ( + '".intval($_SESSION['id'])."', + '".hesk_dbEscape($title)."', + '".hesk_dbEscape($message)."', + '{$style}', + '{$type}', + '{$my_order}' + )"); + + $_SESSION['smord'] = hesk_dbInsertID(); + hesk_process_messages($hesklang['sm_added'],'service_messages.php','SUCCESS'); + +} // End new_sm() + +?> diff --git a/change_status.php b/change_status.php index c3b480e6..c773c1d2 100644 --- a/change_status.php +++ b/change_status.php @@ -1,7 +1,7 @@ ; font-size: 14px; + cursor: pointer; } .h3questionmark { color: ; @@ -363,3 +364,12 @@ div.setupButtons { cursor: text !important; background-color: #fff !important; } + +button.btn.dropdown-toggle { + height: 34px; +} + +button.dropdown-submit { + background:none!important; + border:none; +} diff --git a/css/hesk_newStyleRTL.php b/css/hesk_newStyleRTL.php index 3c699673..d5a0e365 100644 --- a/css/hesk_newStyleRTL.php +++ b/css/hesk_newStyleRTL.php @@ -123,6 +123,7 @@ .settingsquestionmark { color: ; font-size: 14px; + cursor: pointer; } .settingsquestionmark:hover { text-decoration: underline; @@ -356,4 +357,15 @@ div.setupButtons { margin-right: auto; margin-left: auto; width: 90%; +} +.white-readonly { + cursor: text !important; + background-color: #fff !important; +} +button.btn.dropdown-toggle { + height: 34px; +} +button.dropdown-submit { + background:none!important; + border:none; } \ No newline at end of file diff --git a/hesk_javascript.js b/hesk_javascript.js new file mode 100644 index 00000000..facdd230 --- /dev/null +++ b/hesk_javascript.js @@ -0,0 +1,446 @@ +/******************************************************************************* +* Title: Help Desk Software HESK +* Version: 2.6.0 beta 1 from 30th December 2014 +* Author: Klemen Stirn +* Website: http://www.hesk.com +******************************************************************************** +* COPYRIGHT AND TRADEMARK NOTICE +* Copyright 2005-2014 Klemen Stirn. All Rights Reserved. +* HESK is a registered trademark of Klemen Stirn. + +* The HESK may be used and modified free of charge by anyone +* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT. +* By using this code you agree to indemnify Klemen Stirn from any +* liability that might arise from it's use. + +* Selling the code for this program, in part or full, without prior +* written consent is expressly forbidden. + +* Using this code, in part or full, to create derivate work, +* new scripts or products is expressly forbidden. Obtain permission +* before redistributing this software over the Internet or in +* any other medium. In all cases copyright and header must remain intact. +* This Copyright is in full effect in any country that has International +* Trade Agreements with the United States of America or +* with the European Union. + +* Removing any of the copyright notices without purchasing a license +* is expressly forbidden. To remove HESK copyright notice you must purchase +* a license for this script. For more information on how to obtain +* a license please visit the page below: +* https://www.hesk.com/buy.php +*******************************************************************************/ + +function hesk_insertTag(tag) { +var text_to_insert = '%%'+tag+'%%'; +hesk_insertAtCursor(document.form1.msg, text_to_insert); +document.form1.message.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; +} +} + +function hesk_changeAll(myID) { + var d = document.form1; + var setTo = myID.checked ? true : false; + + for (var i = 0; i < d.elements.length; i++) + { + if(d.elements[i].type == 'checkbox' && d.elements[i].name != 'checkall') + { + d.elements[i].checked = setTo; + } + } +} + +function hesk_attach_disable(ids) { + for($i=0;$i 0) { + combinations += 10; + } + + if (hesk_contains(password, lowercase) > 0) { + combinations += 26; + } + + if (hesk_contains(password, uppercase) > 0) { + combinations += 26; + } + + if (hesk_contains(password, punctuation) > 0) { + combinations += punctuation.length; + } + + var totalCombinations = Math.pow(combinations, password.length); + var timeInSeconds = (totalCombinations / 200) / 2; + var timeInDays = timeInSeconds / 86400 + var lifetime = 3650; + var percentage = timeInDays / lifetime; + + var friendlyPercentage = hesk_cap(Math.round(percentage * 100), 98); + + if (friendlyPercentage < (password.length * 5)) { + friendlyPercentage += password.length * 5; + } + + var friendlyPercentage = hesk_cap(friendlyPercentage, 98); + + var progressBar = document.getElementById("progressBar"); + progressBar.style.width = friendlyPercentage + "%"; + + if (percentage > 1) { + // strong password + progressBar.classList.remove('progress-bar-danger'); + progressBar.classList.remove('progress-bar-warning'); + progressBar.classList.add('progress-bar-success'); + return; + } + + if (percentage > 0.5) { + // reasonable password + progressBar.classList.remove('progress-bar-danger'); + progressBar.classList.remove('progress-bar-success'); + progressBar.classList.add('progress-bar-warning'); + return; + } + + if (percentage > 0.10 || percentage <= 0.10) { + // weak password + progressBar.classList.remove('progress-bar-warning'); + progressBar.classList.remove('progress-bar-success'); + progressBar.classList.add('progress-bar-danger'); + return; + } + +} + +function hesk_cap(number, max) { + if (number > max) { + return max; + } else { + return number; + } +} + +function hesk_contains(password, validChars) { + + count = 0; + + for (i = 0; i < password.length; i++) { + var char = password.charAt(i); + if (validChars.indexOf(char) > -1) { + count++; + } + } + + return count; +} + +function setCookie(name, value, expires, path, domain, secure) +{ + document.cookie= name + "=" + escape(value) + + ((expires) ? "; expires=" + expires.toGMTString() : "") + + ((path) ? "; path=" + path : "") + + ((domain) ? "; domain=" + domain : "") + + ((secure) ? "; secure" : ""); +} + +function getCookie(name) +{ + var dc = document.cookie; + var prefix = name + "="; + var begin = dc.indexOf("; " + prefix); + if (begin == -1) { + begin = dc.indexOf(prefix); + if (begin != 0) return null; + } else { + begin += 2; + } + var end = document.cookie.indexOf(";", begin); + if (end == -1) { + end = dc.length; + } + return unescape(dc.substring(begin + prefix.length, end)); +} + +function deleteCookie(name, path, domain) +{ + if (getCookie(name)) { + document.cookie = name + "=" + + ((path) ? "; path=" + path : "") + + ((domain) ? "; domain=" + domain : "") + + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; + } +} diff --git a/hesk_style_v25.css b/hesk_style.css similarity index 97% rename from hesk_style_v25.css rename to hesk_style.css index 4a13d368..56c11b6f 100644 --- a/hesk_style_v25.css +++ b/hesk_style.css @@ -14,7 +14,7 @@ table.enclosing { color : #4a5571; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 12px; - width: 770px; + width: 960px; } @@ -216,7 +216,7 @@ fieldset { background-color:white; position:relative; display:block; - padding: 0px 10px 10px 10px; + padding: 15px 10px 10px 10px; margin:20px 0px 20px 0px; } @@ -232,10 +232,8 @@ legend { background-position: left top; display:block; width: auto; - padding:4px 5px; - margin:0px 0px 10px 0px; + padding:5px 5px; position:relative; - top: -12px; width:130px; } @@ -551,10 +549,25 @@ td.admin_critical { font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 11px; border: 1px solid #ff66ff; - border-top: 2px dashed #ff66ff; padding: 1px; } +/* New styles in HESK version 2.6 */ + +div.info { + border: 1px solid #9acfea; + background: #d9edf7; + color: #363636; + padding: 10px; + vertical-align: middle; +} + +div.none { + color: #363636; + padding: 10px; + vertical-align: middle; +} + .isError { color: black; background-color: #fff9f7; diff --git a/hesk_style_v25RTL.css b/hesk_style_RTL.css similarity index 97% rename from hesk_style_v25RTL.css rename to hesk_style_RTL.css index a22825b3..d866def8 100644 --- a/hesk_style_v25RTL.css +++ b/hesk_style_RTL.css @@ -14,7 +14,7 @@ table.enclosing { color : #4a5571; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 12px; - width: 770px; + width: 960px; } @@ -216,7 +216,7 @@ fieldset { background-color:white; position:relative; display:block; - padding: 0px 10px 10px 10px; + padding: 15px 10px 10px 10px; margin:20px 0px 20px 0px; } @@ -232,10 +232,8 @@ legend { background-position: right top; display:block; width: auto; - padding:4px 5px; - margin:0px 0px 10px 0px; + padding:5px 5px; position:relative; - top: -12px; width:130px; } @@ -551,7 +549,6 @@ td.admin_critical { font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 11px; border: 1px solid #ff66ff; - border-top: 2px dashed #ff66ff; padding: 1px; } @@ -691,6 +688,22 @@ td.admin_yellow { padding: 1px; } +/* New styles in HESK version 2.6 */ + +div.info { + border: 1px solid #9acfea; + background: #d9edf7; + color: #363636; + padding: 10px; + vertical-align: middle; +} + +div.none { + color: #363636; + padding: 10px; + vertical-align: middle; +} + /* New styles in HESK version 2.5 */ .kb_published { diff --git a/inc/admin_functions.inc.php b/inc/admin_functions.inc.php new file mode 100644 index 00000000..18c60720 --- /dev/null +++ b/inc/admin_functions.inc.php @@ -0,0 +1,738 @@ + $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'], +); + +// Also possible to display all custom fields +for ($i=1;$i<=20;$i++) +{ + if ($hesk_settings['custom_fields']['custom'.$i]['use']) + { + $hesk_settings['possible_ticket_list']['custom'.$i] = $hesk_settings['custom_fields']['custom'.$i]['name']; + } +} + +/*** 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`, `staffid` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`=".intval($ticket['id'])." GROUP BY CASE WHEN `staffid` = 0 THEN 0 ELSE 1 END ASC"); + while ( $row = hesk_dbFetchAssoc($res) ) + { + $total += $row['cnt']; + $staffreplies += ($row['staffid'] ? $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)."' LIMIT 1"); + + 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_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("","<?","?>","\$","<%","%>"); + + $in = trim($in); + $in = str_replace($replace_from,$replace_to,$in); + $in = preg_replace('/\(.*)\<\/script\>/Uis',"",$in); + $in = preg_replace('/\<\!\-\-(.*)\-\-\>/Uis',"",$in); + + if (HESK_SLASH === true) + { + $in = addslashes($in); + } + $in = str_replace('\"','"',$in); + + return $in; +} // END hesk_getHTML() + + +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(); + + /* Check username */ + $result = hesk_dbQuery('SELECT * FROM `'.$hesk_settings['db_pfix']."users` WHERE `user` = '".hesk_dbEscape($user)."' LIMIT 1"); + if (hesk_dbNumRows($result) != 1) + { + setcookie('hesk_username', ''); + setcookie('hesk_p', ''); + header('Location: index.php?a=login¬ice=1'); + exit(); + } + + $res=hesk_dbFetchAssoc($result); + foreach ($res as $k=>$v) + { + $_SESSION[$k]=$v; + } + + /* Check password */ + if ($hash != hesk_Pass2Hash($_SESSION['pass'] . strtolower($user) . $_SESSION['pass']) ) + { + setcookie('hesk_username', ''); + setcookie('hesk_p', ''); + header('Location: index.php?a=login¬ice=1'); + exit(); + } + + /* Check if default password */ + if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079') + { + hesk_process_messages($hesklang['chdp'],'NOREDIRECT','NOTICE'); + } + + 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 */ + setcookie('hesk_username', "$user", strtotime('+1 year')); + 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); + 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('&','&',$referer); + + if (empty($_SESSION['id'])) + { + 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; + } + + $url = 'index.php?a=login¬ice=1&goto='.urlencode($referer); + header('Location: '.$url); + exit(); + } + else + { + hesk_session_regenerate_id(); + + // Need to update permissions? + if ( empty($_SESSION['isadmin']) ) + { + $res = hesk_dbQuery("SELECT `isadmin`, `categories`, `heskprivileges` FROM `".$hesk_settings['db_pfix']."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1"); + if (hesk_dbNumRows($res) == 1) + { + $me = hesk_dbFetchAssoc($res); + foreach ($me as $k => $v) + { + $_SESSION[$k]=$v; + } + + // Get allowed categories + if (empty($_SESSION['isadmin']) ) + { + $_SESSION['categories']=explode(',',$_SESSION['categories']); + } + } + else + { + hesk_session_stop(); + $url = 'index.php?a=login¬ice=1&goto='.urlencode($referer); + header('Location: '.$url); + exit(); + } + } + + // 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('&', '&', $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.php' => '', + 'admin_settings_save.php' => 'admin_settings.php', + 'admin_ticket.php' => '', + 'archive.php' => '', + 'assign_owner.php' => '', + 'change_status.php' => '', + 'edit_post.php' => '', + 'export.php' => '', + 'find_tickets.php' => '', + 'generate_spam_question.php' => '', + 'knowledgebase_private.php' => '', + 'lock.php' => '', + 'mail.php' => '', + 'manage_canned.php' => '', + 'manage_categories.php' => '', + 'manage_knowledgebase.php' => '', + 'manage_users.php' => '', + 'new_ticket.php' => '', + 'profile.php' => '', + 'reports.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(' ','
    ',$dt); + return $dt; +} // End hesk_formatDate() + + +function hesk_jsString($str) +{ + $str = str_replace( array('\'','
    ') , array('\\\'','') ,$str); + $from = array("/\r\n|\n|\r/", '/\([^\<]*)\<\/a\>/i', '/\([^\<]*)\<\/a\>/i'); + $to = array("\\r\\n' + \r\n'", "$1", "$1"); + return preg_replace($from,$to,$str); +} // END hesk_jsString() + + +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 ($_SESSION['isadmin']) + { + return true; + } + + /* Check other staff for permissions */ + if (strpos($_SESSION['heskprivileges'], $feature) === false) + { + if ($showerror) + { + hesk_error($hesklang['no_permission'].'

     

    '.$hesklang['click_login'].''); + } + else + { + return false; + } + } + else + { + return true; + } + +} // END hesk_checkPermission() diff --git a/inc/common.inc.php b/inc/common.inc.php index 1ba32f78..f0548935 100644 --- a/inc/common.inc.php +++ b/inc/common.inc.php @@ -1,7 +1,7 @@ +

    + '; ?> + +
    +
    + NOW( ) THEN 1 ELSE 0 END) AS `banned` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."logins` WHERE `ip`='".hesk_dbEscape($ip)."' LIMIT 1"); + $res = hesk_dbQuery("SELECT `number`, (CASE WHEN `last_attempt` IS NOT NULL AND DATE_ADD(`last_attempt`, INTERVAL ".intval($hesk_settings['attempt_banmin'])." MINUTE ) > NOW() THEN 1 ELSE 0 END) AS `banned` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."logins` WHERE `ip`='".hesk_dbEscape($ip)."' LIMIT 1"); /* Not in the database yet? Add first one and return false */ if (hesk_dbNumRows($res) != 1) @@ -702,6 +773,9 @@ function hesk_process_messages($message,$redirect_to,$type='ERROR') case 'NOTICE': $_SESSION['HESK_NOTICE'] = TRUE; break; + case 'INFO': + $_SESSION['HESK_INFO'] = TRUE; + break; default: $_SESSION['HESK_ERROR'] = TRUE; } @@ -741,6 +815,10 @@ function hesk_handle_messages() { hesk_show_notice($_SESSION['HESK_MESSAGE']); } + elseif ( isset($_SESSION['HESK_INFO']) ) + { + hesk_show_info($_SESSION['HESK_MESSAGE']); + } hesk_cleanSessionVars('HESK_MESSAGE'); } @@ -749,6 +827,7 @@ function hesk_handle_messages() hesk_cleanSessionVars('HESK_ERROR'); hesk_cleanSessionVars('HESK_SUCCESS'); hesk_cleanSessionVars('HESK_NOTICE'); + hesk_cleanSessionVars('HESK_INFO'); // Secondary message if ( isset($_SESSION['HESK_2ND_NOTICE']) && isset($_SESSION['HESK_2ND_MESSAGE']) ) @@ -762,39 +841,54 @@ function hesk_handle_messages() } // END hesk_handle_messages() -function hesk_show_error($message,$title='') { +function hesk_show_error($message,$title='',$append_colon=true) { global $hesk_settings, $hesklang; $title = $title ? $title : $hesklang['error']; + $title = $append_colon ? $title . ':' : $title; ?>
    - : +
    - : +
    - : +
    -
    +
    + + +
    +
    + + +
    + +

    +

    + +
    + Verify email 'verify_email' => $hesklang['verify_email'], + // --> Ticket closed + 'ticket_closed' => $hesklang['ticket_closed'], + /*** Emails sent to STAFF ***/ @@ -265,6 +268,9 @@ function hesk_validEmails() // --> New note by someone to a ticket assigned to you 'new_note' => $hesklang['new_note'], + // --> Staff password reset email + 'reset_password' => $hesklang['reset_password'], + ); } // END hesk_validEmails() @@ -585,6 +591,7 @@ function hesk_getEmailMessage($eml_file, $ticket, $is_admin=0, $is_ticket=1, $ju $msg = str_replace('%%EMAIL%%', $ticket['email'] ,$msg); $msg = str_replace('%%CREATED%%', $ticket['dt'] ,$msg); $msg = str_replace('%%UPDATED%%', $ticket['lastchange'] ,$msg); + $msg = str_replace('%%ID%%', $ticket['id'] ,$msg); /* All custom fields */ foreach ($hesk_settings['custom_fields'] as $k=>$v) diff --git a/inc/header.inc.php b/inc/header.inc.php index 6f440217..baa5fe71 100644 --- a/inc/header.inc.php +++ b/inc/header.inc.php @@ -1,7 +1,7 @@ - + <?php echo (isset($hesk_settings['tmp_title']) ? $hesk_settings['tmp_title'] : $hesk_settings['hesk_title']); ?> + - + @@ -59,7 +60,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); - + @@ -127,6 +128,12 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); $onload .= "ss();"; } } + + // Use ReCaptcha API v2? + if (defined('RECAPTCHA')) + { + echo ''; + } ?> diff --git a/inc/headerAdmin.inc.php b/inc/headerAdmin.inc.php index 1088af73..94fdb109 100644 --- a/inc/headerAdmin.inc.php +++ b/inc/headerAdmin.inc.php @@ -42,10 +42,11 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); <?php echo (isset($hesk_settings['tmp_title']) ? $hesk_settings['tmp_title'] : $hesk_settings['hesk_title']); ?> + - + - + @@ -59,7 +60,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); - + diff --git a/inc/knowledgebase_functions.inc.php b/inc/knowledgebase_functions.inc.php index 1796c358..87068dca 100644 --- a/inc/knowledgebase_functions.inc.php +++ b/inc/knowledgebase_functions.inc.php @@ -1,7 +1,7 @@ $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 "; @@ -87,11 +122,15 @@ while ($row = $results->fetch_assoc()) } $status = $possible_status; -foreach ($status as $k => $v) +// Process statuses unless overridden with "s_all" variable +if ( ! hesk_GET('s_all') ) { - if (empty($_GET['s'.$k])) + foreach ($status as $k => $v) { - unset($status[$k]); + if (empty($_GET['s' . $k])) + { + unset($status[$k]); + } } } diff --git a/inc/profile_functions.inc.php b/inc/profile_functions.inc.php new file mode 100644 index 00000000..225fb204 --- /dev/null +++ b/inc/profile_functions.inc.php @@ -0,0 +1,382 @@ + +
    + + + + + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    +
    + +
    + +
    +
    + '.$hesklang['astaff'].' '.$hesklang['staff_can']; + } + ?> +
    +
    +
    +
    + +
    + $catname) + { + echo '
    '; + } + ?> +
    +
    +
    + +
    +
    '; + } + ?> +
    + +
    +
    +
    +
    +
    + +
    +
    + + +
    + + +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    +
    + +
    + +
    + +
    + + + + + + +
    + + + +
    + + + + + +
    +
    +
    +
    + + + + + + +
    + +
    +
    +
    +
    + + + + + + +

    + + + + + + + +
    +
    +
    +
    + + + + +'; + hesk_show_notice($hesklang['mma2'], $hesklang['mma1'], false); + echo ''; +} +// Show a notice if we are in "Knowledgebase only" mode +if ( hesk_check_kb_only(false) ) +{ + echo '
    '; + hesk_show_notice($hesklang['kbo2'], $hesklang['kbo1'], false); + echo '
    '; +} +?>