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; }
$_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}' "; } 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 $possible_status = array(0 => 'NEW', 1 => 'WAITING REPLY', 2 => 'REPLIED', 3 => 'RESOLVED (CLOSED)', 4 => 'IN PROGRESS', 5 => 'ON HOLD'); $status = $possible_status;
/* Ticket ID */ $trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']); $is_reply = 0; $tmpvar = 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'] = '*****@*****.**'; } /* 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; } if (isset($_POST['save'])) { /* A security check */ hesk_token_check('POST'); $hesk_error_buffer = array(); if ($is_reply) {
function import_article() { global $hesk_settings, $hesklang, $listBox; $_SESSION['hide'] = array('treemenu' => 1, 'new_category' => 1); $_SESSION['KB_CATEGORY'] = 1; // Get ticket ID $trackingID = hesk_cleanID(); if (empty($trackingID)) { return false; } // Get ticket info $res = hesk_dbQuery("SELECT `id`,`category`,`subject`,`message`,`owner` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1"); if (hesk_dbNumRows($res) != 1) { return false; } $ticket = hesk_dbFetchAssoc($res); // Permission to view this ticket? if ($ticket['owner'] && $ticket['owner'] != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others', 0)) { return false; } if (!$ticket['owner'] && !hesk_checkPermission('can_view_unassigned', 0)) { return false; } // Is this user allowed to view tickets inside this category? if (!hesk_okCategory($ticket['category'], 0)) { return false; } // Set article contents if ($hesk_settings['kb_wysiwyg']) { // With WYSIWYG editor $_SESSION['new_article'] = array('html' => 1, 'subject' => $ticket['subject'], 'content' => hesk_htmlspecialchars($ticket['message'])); } else { // Without WYSIWYG editor * $_SESSION['new_article'] = array('html' => 0, 'subject' => $ticket['subject'], 'content' => hesk_msgToPlain($ticket['message'])); } // Get messages from replies to the ticket $res = hesk_dbQuery("SELECT `message` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`='" . intval($ticket['id']) . "' ORDER BY `id` ASC"); while ($reply = hesk_dbFetchAssoc($res)) { if ($hesk_settings['kb_wysiwyg']) { $_SESSION['new_article']['content'] .= "<br /><br />" . hesk_htmlspecialchars($reply['message']); } else { $_SESSION['new_article']['content'] .= "\n\n" . hesk_msgToPlain($reply['message']); } } hesk_process_messages($hesklang['import'], 'NOREDIRECT', 'NOTICE'); }
$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;
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_users'); /* Possible user features */ $hesk_settings['features'] = array('can_view_tickets', 'can_reply_tickets', 'can_del_tickets', 'can_edit_tickets', 'can_merge_tickets', 'can_del_notes', 'can_change_cat', 'can_man_kb', 'can_man_users', 'can_man_cat', 'can_man_canned', 'can_man_settings', 'can_add_archive', 'can_assign_self', 'can_assign_others', 'can_view_unassigned', 'can_view_ass_others', 'can_run_reports', 'can_run_reports_full', 'can_export', 'can_view_online'); /* Set default values */ $default_userdata = array('name' => '', 'email' => '', 'user' => '', 'signature' => '', 'isadmin' => 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' => ''); /* A list of all categories */ $hesk_settings['categories'] = array(); $res = hesk_dbQuery('SELECT `id`,`name` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'categories` ORDER BY `cat_order` ASC'); while ($row = hesk_dbFetchAssoc($res)) { if (hesk_okCategory($row['id'], 0)) { $hesk_settings['categories'][$row['id']] = $row['name']; } } /* Non-admin users may not create users with more permissions than they have */ if (!$_SESSION['isadmin']) { /* Can't create admin users */ $_POST['isadmin'] = 0; /* Can only add features he/she has access to */ $hesk_settings['features'] = array_intersect(explode(',', $_SESSION['heskprivileges']), $hesk_settings['features']); /* Can user modify auto-assign setting? */ if ($hesk_settings['autoassign'] && (!hesk_checkPermission('can_assign_self', 0) || !hesk_checkPermission('can_assign_others', 0))) { $hesk_settings['autoassign'] = 0; } } /* Use any set values, default otherwise */
if ($ticket['lastreplier']) { if (empty($ticket['repliername'])) { $ticket['repliername'] = $hesklang['staff']; } } else { $ticket['repliername'] = $ticket['name']; } /* Get category name and ID */ $result = hesk_dbQuery("SELECT `id`, `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE `id`='" . intval($ticket['category']) . "' LIMIT 1"); /* If this category has been deleted use the default category with ID 1 */ if (hesk_dbNumRows($result) != 1) { $result = hesk_dbQuery("SELECT `id`, `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE `id`='1' LIMIT 1"); } $category = hesk_dbFetchAssoc($result); /* Is this user allowed to view tickets inside this category? */ hesk_okCategory($category['id']); /* Delete post action */ if (isset($_GET['delete_post']) && $can_delete && hesk_token_check()) { $n = intval(hesk_GET('delete_post')); if ($n) { /* Get last reply ID, we'll need it later */ $res = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `replyto`='" . intval($ticket['id']) . "' ORDER BY `id` DESC LIMIT 1"); $last_reply_id = hesk_dbResult($res, 0, 0); // Was this post submitted by staff and does it have any attachments? $res = hesk_dbQuery("SELECT `dt`, `staffid`, `attachments` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `id`='" . intval($n) . "' AND `replyto`='" . intval($ticket['id']) . "' LIMIT 1"); $reply = hesk_dbFetchAssoc($res); // If the reply was by a staff member update the appropriate columns if ($reply['staffid']) { // Is this the only staff reply? Delete "firstreply" and "firstreplyby" columns if ($ticket['staffreplies'] <= 1) { $staffreplies_sql = ' , `firstreply`=NULL, `firstreplyby`=NULL, `staffreplies`=0 ';
} $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; }