Ticketing updates - guest view & resolved vs closed

- Swap autclose for resolved to allow temporarily re-opening resolved tickets for 72 hrs after closure
- Add guest view URL for tickets
This commit is contained in:
wrongecho
2024-08-17 23:24:15 +01:00
parent d9316233bb
commit d80334a7cf
24 changed files with 738 additions and 204 deletions

View File

@@ -23,13 +23,14 @@ function verifyContactTicketAccess($requested_ticket_id, $expected_ticket_state)
}
// Verify the contact has access to the provided ticket ID
$sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = $requested_ticket_id AND $ticket_state_snippet AND ticket_client_id = $session_client_id LIMIT 1");
$row = mysqli_fetch_array($sql);
$ticket_id = $row['ticket_id'];
$row = mysqli_fetch_array(mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = $requested_ticket_id AND $ticket_state_snippet AND ticket_client_id = $session_client_id LIMIT 1"));
if ($row) {
$ticket_id = $row['ticket_id'];
if (intval($ticket_id) && ($session_contact_id == $row['ticket_contact_id'] || $session_contact_primary == 1 || $session_contact_is_technical_contact)) {
// Client is ticket owner, primary contact, or a technical contact
return true;
if (intval($ticket_id) && ($session_contact_id == $row['ticket_contact_id'] || $session_contact_primary == 1 || $session_contact_is_technical_contact)) {
// Client is ticket owner, primary contact, or a technical contact
return true;
}
}
// Client is NOT ticket owner or primary/tech contact

View File

@@ -12,7 +12,7 @@ if (isset($_POST['add_ticket'])) {
$client_id = intval($session_client_id);
$contact = intval($session_contact_id);
$subject = sanitizeInput($_POST['subject']);
$details = mysqli_real_escape_string($mysqli,($_POST['details']));
$details = mysqli_real_escape_string($mysqli, ($_POST['details']));
// Get settings from get_settings.php
$config_ticket_prefix = sanitizeInput($config_ticket_prefix);
@@ -21,6 +21,9 @@ if (isset($_POST['add_ticket'])) {
$config_base_url = sanitizeInput($config_base_url);
$config_ticket_new_ticket_notification_email = filter_var($config_ticket_new_ticket_notification_email, FILTER_VALIDATE_EMAIL);
//Generate a unique URL key for clients to access
$url_key = randomString(156);
// Ensure priority is low/med/high (as can be user defined)
if ($_POST['priority'] !== "Low" && $_POST['priority'] !== "Medium" && $_POST['priority'] !== "High") {
$priority = "Low";
@@ -33,7 +36,7 @@ if (isset($_POST['add_ticket'])) {
$new_config_ticket_next_number = $config_ticket_next_number + 1;
mysqli_query($mysqli, "UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = 1");
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 1, ticket_created_by = 0, ticket_contact_id = $contact, ticket_client_id = $client_id");
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 1, ticket_created_by = 0, ticket_contact_id = $contact, ticket_url_key = '$url_key', ticket_client_id = $client_id");
$id = mysqli_insert_id($mysqli);
// Notify agent DL of the new ticket, if populated with a valid email
@@ -194,20 +197,66 @@ if (isset($_POST['add_ticket_feedback'])) {
}
if (isset($_GET['resolve_ticket'])) {
$ticket_id = intval($_GET['resolve_ticket']);
// Verify the contact has access to the provided ticket ID
if (verifyContactTicketAccess($ticket_id, "Open")) {
// Resolve the ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 4, ticket_resolved_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket resolved by $session_contact_name.', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");
//Logging
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Resolved', log_description = '$ticket_id resolved by client', log_ip = '$session_ip', log_user_agent = '$session_user_agent'");
header("Location: ticket.php?id=" . $ticket_id);
} else {
// The client does not have access to this ticket - send them home
header("Location: index.php");
exit();
}
}
if (isset($_GET['reopen_ticket'])) {
$ticket_id = intval($_GET['reopen_ticket']);
// Verify the contact has access to the provided ticket ID
if (verifyContactTicketAccess($ticket_id, "Open")) {
// Re-open ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 2, ticket_resolved_at = NULL WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket reopened by $session_contact_name.', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");
//Logging
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Replied', log_description = '$ticket_id reopened by client', log_ip = '$session_ip', log_user_agent = '$session_user_agent'");
header("Location: ticket.php?id=" . $ticket_id);
} else {
// The client does not have access to this ticket - send them home
header("Location: index.php");
exit();
}
}
if (isset($_GET['close_ticket'])) {
$ticket_id = intval($_GET['close_ticket']);
// Verify the contact has access to the provided ticket ID
if (verifyContactTicketAccess($ticket_id, "Open")) {
// Close ticket
// Fully close ticket
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 5, ticket_closed_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id");
// Add reply
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = 'Ticket closed by $session_contact_name.', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");
//Logging
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Closed', log_description = '$ticket_id Closed by client', log_ip = '$session_ip', log_user_agent = '$session_user_agent'");
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Ticket', log_action = 'Closed', log_description = '$ticket_id closed by client', log_ip = '$session_ip', log_user_agent = '$session_user_agent'");
header("Location: ticket.php?id=" . $ticket_id);
} else {

View File

@@ -48,9 +48,23 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
$ticket_subject = nullable_htmlentities($ticket_row['ticket_subject']);
$ticket_details = $purifier->purify($ticket_row['ticket_details']);
$ticket_assigned_to = nullable_htmlentities($ticket_row['user_name']);
$ticket_resolved_at = nullable_htmlentities($ticket_row['ticket_resolved_at']);
$ticket_closed_at = nullable_htmlentities($ticket_row['ticket_closed_at']);
$ticket_feedback = nullable_htmlentities($ticket_row['ticket_feedback']);
// Get Tasks
$sql_tasks = mysqli_query( $mysqli, "SELECT * FROM tasks WHERE task_ticket_id = $ticket_id ORDER BY task_order ASC, task_id ASC");
$task_count = mysqli_num_rows($sql_tasks);
// Get Completed Task Count
$sql_tasks_completed = mysqli_query($mysqli,
"SELECT * FROM tasks
WHERE task_ticket_id = $ticket_id
AND task_completed_at IS NOT NULL"
);
$completed_task_count = mysqli_num_rows($sql_tasks_completed);
?>
<ol class="breadcrumb d-print-none">
@@ -60,7 +74,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<li class="breadcrumb-item">
<a href="tickets.php">Tickets</a>
</li>
<li class="breadcrumb-item active">Ticket <?php echo $ticket_number; ?></li>
<li class="breadcrumb-item active">Ticket <?php echo $ticket_prefix . $ticket_number; ?></li>
</ol>
<div class="card">
@@ -68,8 +82,8 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<h4 class="mt-1">
Ticket <?php echo $ticket_prefix, $ticket_number ?>
<?php
if (empty($ticket_closed_at)) { ?>
<a href="portal_post.php?close_ticket=<?php echo $ticket_id; ?>" class="btn btn-sm btn-outline-success float-right text-white confirm-link"><i class="fas fa-fw fa-check text-success"></i> Close ticket</a>
if (empty($ticket_resolved_at) && $task_count == $completed_task_count) { ?>
<a href="portal_post.php?resolve_ticket=<?php echo $ticket_id; ?>" class="btn btn-sm btn-outline-success float-right text-white confirm-link"><i class="fas fa-fw fa-check text-success"></i> Resolve ticket</a>
<?php } ?>
</h4>
</div>
@@ -82,7 +96,12 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<br>
<strong>Priority:</strong> <?php echo $ticket_priority ?>
<br>
<?php if (empty($ticket_closed_at)) { ?>
<?php if ($task_count) { ?>
<strong>Tasks: </strong> <?php echo $completed_task_count . " / " .$task_count ?>
<br>
<?php } ?>
<strong>Assigned to: </strong> <?php echo $ticket_assigned_to ?>
<?php } ?>
</p>
@@ -90,10 +109,12 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
</div>
</div>
<hr>
<!-- Either show the reply comments box, ticket smiley feedback, or thanks for feedback -->
<!-- Either show the reply comments box, option to re-open ticket, show ticket smiley feedback or thanks for feedback -->
<?php if (empty($ticket_closed_at)) { ?>
<?php if (empty($ticket_resolved_at)) { ?>
<!-- Reply -->
<form action="portal_post.php" enctype="multipart/form-data" method="post">
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id ?>">
@@ -106,9 +127,27 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<button type="submit" class="btn btn-primary" name="add_ticket_comment">Reply</button>
</form>
<?php } elseif (empty($ticket_closed_at)) { ?>
<!-- Re-open -->
<h4>Your ticket has been resolved</h4>
<div class="col-6">
<div class="row">
<div class="col">
<a href="portal_post.php?reopen_ticket=<?php echo $ticket_id; ?>" class="btn btn-secondary btn-lg"><i class="fas fa-fw fa-redo text-white"></i> Reopen ticket</a>
</div>
<div class="col">
<a href="portal_post.php?close_ticket=<?php echo $ticket_id; ?>" class="btn btn-success btn-lg confirm-link"><i class="fas fa-fw fa-gavel text-white"></i> Close ticket</a>
</div>
</div>
</div>
<br>
<?php } elseif (empty($ticket_feedback)) { ?>
<h4>Rate your ticket</h4>
<h4>Ticket closed. Please rate your ticket</h4>
<form action="portal_post.php" method="post">
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id ?>">
@@ -128,7 +167,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<?php } ?>
<!-- End comments/feedback -->
<!-- End comments/reopen/feedback -->
<hr>
<br>

View File

@@ -90,7 +90,7 @@ $total_tickets = intval($row['total_tickets']);
<a href="?status=Open" class="btn btn-danger btn-block p-3 mb-3 text-left">My Open tickets | <strong><?php echo $total_tickets_open ?></strong></a>
<a href="?status=Closed" class="btn btn-success btn-block p-3 mb-3 text-left">Resolved tickets | <strong><?php echo $total_tickets_closed ?></strong></a>
<a href="?status=Closed" class="btn btn-success btn-block p-3 mb-3 text-left">Closed tickets | <strong><?php echo $total_tickets_closed ?></strong></a>
<a href="?status=%" class="btn btn-secondary btn-block p-3 mb-3 text-left">All my tickets | <strong><?php echo $total_tickets ?></strong></a>
<?php