I'll help fix these issues. Here's the comprehensive solution:
Key changes made:
Fixed styling issues by:
Fixed URL routing issues by:
Added message functionality by:
Fixed ticket regeneration by:
Improved overall structure by:
Here's the complete solution with all code (PHP, HTML, CSS, JS) in a single file for WordPress PHP insertion:
<?php
// Start session for custom authentication
session_start();
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: " . home_url('/login'));
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: " . home_url('/login'));
exit;
}
// Check if viewing ticket details
$viewing_ticket = isset($_GET['ticket_id']);
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
if ($viewing_ticket) {
// Get ticket details
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.id = ?
");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
// Check if ticket exists and user has permission
if (!$ticket) {
die("Ticket not found");
}
if ($current_user['role'] === 'user' && $ticket['created_by'] != $current_user['id']) {
die("You don't have permission to view this ticket");
}
// Get ticket messages
$stmt = $pdo->prepare("
SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as user_name, u.role as user_role
FROM ticket_messages m
JOIN users u ON m.user_id = u.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Handle form submissions
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['create_ticket'])) {
$subject = htmlspecialchars($_POST['subject']);
$description = htmlspecialchars($_POST['description']);
$priority = htmlspecialchars($_POST['priority']);
$department_id = (int)$_POST['department_id'];
try {
$ticket_number = 'TKT-' . date('Ymd-His');
$stmt = $pdo->prepare("INSERT INTO tickets
(ticket_number, subject, description, priority, department_id, created_by, status, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, 'open', NOW(), NOW())");
$stmt->execute([
$ticket_number,
$subject,
$description,
$priority,
$department_id,
$current_user['id']
]);
$ticket_id = $pdo->lastInsertId();
// Add initial message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$description
]);
$message = 'Ticket created successfully!';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error creating ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['update_status'])) {
$ticket_id = (int)$_POST['ticket_id'];
$status = htmlspecialchars($_POST['status']);
try {
$stmt = $pdo->prepare("UPDATE tickets SET status = ?, updated_at = NOW() WHERE id = ?");
$stmt->execute([$status, $ticket_id]);
// Add status change message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
"Status changed to: " . ucfirst($status)
]);
$message = 'Ticket status updated!';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error updating ticket status: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['assign_ticket'])) {
$ticket_id = (int)$_POST['ticket_id'];
$assign_to = (int)$_POST['assign_to'];
try {
$stmt = $pdo->prepare("UPDATE tickets SET assigned_to = ?, status = 'assigned', updated_at = NOW() WHERE id = ?");
$stmt->execute([$assign_to, $ticket_id]);
// Add assignment message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
"Ticket assigned to staff ID: " . $assign_to
]);
$message = 'Ticket assigned successfully!';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error assigning ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['add_message'])) {
$ticket_id = (int)$_POST['ticket_id'];
$message_text = htmlspecialchars($_POST['message']);
try {
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$message_text
]);
// Update ticket's updated_at
$stmt = $pdo->prepare("UPDATE tickets SET updated_at = NOW() WHERE id = ?");
$stmt->execute([$ticket_id]);
$message = 'Message added successfully!';
$message_type = 'success';
// Refresh messages
$stmt = $pdo->prepare("
SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as user_name, u.role as user_role
FROM ticket_messages m
JOIN users u ON m.user_id = u.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message = 'Error adding message: ' . $e->getMessage();
$message_type = 'error';
}
}
}
// Get all necessary data for ticket list
if (!$viewing_ticket) {
try {
// Get tickets based on role
if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff') {
$tickets = $pdo->query("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
ORDER BY t.created_at DESC
")->fetchAll(PDO::FETCH_ASSOC);
} else {
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.created_by = ?
ORDER BY t.created_at DESC
");
$stmt->execute([$current_user['id']]);
$tickets = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Get departments for dropdown
$departments = $pdo->query("SELECT * FROM departments")->fetchAll(PDO::FETCH_ASSOC);
// Get staff for assignment dropdown
$staff_members = $pdo->query("
SELECT id, CONCAT(first_name, ' ', last_name) as name
FROM users
WHERE role IN ('staff', 'admin')
")->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error fetching data: " . $e->getMessage());
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $viewing_ticket ? 'Ticket Details' : 'Ticket System' ?></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f7f9;
color: #333;
}
.helpdesk-container {
display: flex;
min-height: 100vh;
}
/* Sidebar Styles */
.helpdesk-sidebar {
width: 240px;
background-color: #D1B48C;
color: #000;
position: fixed;
left: 0;
top: 0;
height: 100vh;
overflow-y: auto;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
.sidebar-header {
padding: 20px;
text-align: center;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.sidebar-header .site-name {
font-size: 24px;
font-weight: bold;
color: #000;
margin: 0;
}
.helpdesk-menu {
padding: 0;
}
.helpdesk-menu ul {
list-style: none;
margin: 0;
padding: 0;
}
.helpdesk-menu li a {
display: flex;
align-items: center;
padding: 12px 20px;
text-decoration: none;
color: #000;
transition: 0.3s;
font-size: 16px;
}
.helpdesk-menu li a i {
margin-right: 12px;
width: 20px;
text-align: center;
}
.helpdesk-menu li a:hover,
.helpdesk-menu li.active a {
background-color: #ffffff;
color: #000;
}
/* Main Content Styles */
.helpdesk-main {
margin-left: 240px;
padding: 20px;
flex-grow: 1;
background-color: #f4f7f9;
}
.header {
background-color: #77693A;
padding: 10px 30px;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
border-radius: 4px;
}
.header .user-info {
display: flex;
align-items: center;
}
.header .user-info i {
margin-left: 10px;
}
/* Ticket System Styles */
.ticket-system,
.ticket-details {
max-width: 1200px;
margin: 0 auto;
}
.notice {
padding: 15px;
margin: 0 0 20px 0;
border-radius: 4px;
border-left: 4px solid;
}
.notice.success {
background-color: #f0fff4;
border-color: #38a169;
color: #2f855a;
}
.notice.error {
background-color: #fff5f5;
border-color: #e53e3e;
color: #c53030;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
}
.form-group input[type="text"],
.form-group textarea,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
.form-group textarea {
min-height: 120px;
resize: vertical;
}
button, .button {
padding: 10px 15px;
border: none;
background-color: #77693A;
color: white;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
text-decoration: none;
display: inline-block;
}
button:hover, .button:hover {
background-color: #5a4d1b;
}
.button-primary {
background-color: #4663ac;
}
.button-primary:hover {
background-color: #3a528b;
}
/* Tickets Table */
.tickets-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
background-color: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.tickets-table th,
.tickets-table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.tickets-table th {
background-color: #f8f9fa;
font-weight: 600;
}
.tickets-table tr:hover {
background-color: #f5f5f5;
}
/* Status Badges */
.status-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
}
.status-open { background-color: #e3f2fd; color: #1976d2; }
.status-assigned { background-color: #fff8e1; color: #ff8f00; }
.status-pending { background-color: #ffebee; color: #d32f2f; }
.status-solved { background-color: #e8f5e9; color: #388e3c; }
.status-closed { background-color: #f5f5f5; color: #616161; }
/* Priority Indicators */
.priority-high { color: #d32f2f; font-weight: bold; }
.priority-medium { color: #ffa000; }
.priority-low { color: #388e3c; }
/* Forms */
.status-update-form,
.assign-form {
display: inline-block;
margin-top: 5px;
}
.status-update-form select,
.assign-form select {
padding: 5px;
font-size: 14px;
border-radius: 4px;
border: 1px solid #ddd;
}
/* Ticket Details */
.ticket-info {
background-color: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.ticket-header {
border-bottom: 1px solid #eee;
padding-bottom: 15px;
margin-bottom: 15px;
}
.ticket-meta {
display: flex;
gap: 10px;
align-items: center;
margin-top: 10px;
}
.ticket-number {
font-size: 14px;
color: #666;
}
.ticket-body {
display: flex;
gap: 30px;
}
.ticket-description {
flex: 2;
}
.ticket-meta-details {
flex: 1;
}
.meta-row {
margin-bottom: 10px;
}
.meta-label {
font-weight: 600;
display: inline-block;
width: 100px;
}
.meta-value {
color: #555;
}
/* Messages */
.ticket-messages {
background-color: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.message-list {
margin-bottom: 20px;
}
.message {
padding: 15px;
border-bottom: 1px solid #eee;
}
.message:last-child {
border-bottom: none;
}
.message-header {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 14px;
}
.message-author {
font-weight: 600;
}
.message-date {
color: #666;
}
.message-content {
line-height: 1.5;
}
.message.admin,
.message.staff {
background-color: #f8f9fa;
}
.add-message textarea {
min-height: 100px;
}
/* Responsive */
@media (max-width: 768px) {
.helpdesk-container {
flex-direction: column;
}
.helpdesk-sidebar {
width: 100%;
height: auto;
position: relative;
}
.helpdesk-main {
margin-left: 0;
}
.helpdesk-menu ul {
display: flex;
flex-wrap: wrap;
}
.ticket-body {
flex-direction: column;
}
}
</style>
</head>
<body>
<div class="helpdesk-container">
<!-- Sidebar Navigation -->
<aside class="helpdesk-sidebar">
<div class="sidebar-header">
<h1 class="site-name">Helpdesk System</h1>
</div>
<nav class="helpdesk-menu">
<ul>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="<?= home_url('/dashboard') ?>"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
<li><a href="<?= home_url('/users') ?>"><i class="fas fa-users-cog"></i> Users</a></li>
<li><a href="<?= home_url('/departments') ?>"><i class="fas fa-building"></i> Departments</a></li>
<?php endif; ?>
<li class="<?= !$viewing_ticket ? 'active' : '' ?>"><a href="<?= home_url('/tickets') ?>"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<li><a href="<?= home_url('/messages') ?>"><i class="fas fa-envelope"></i> Messages</a></li>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="<?= home_url('/reports') ?>"><i class="fas fa-chart-bar"></i> Reports</a></li>
<?php endif; ?>
<li><a href="<?= home_url('/logout') ?>"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="helpdesk-main">
<div class="header">
<h2><?= $viewing_ticket ? 'Ticket Details' : 'Ticket Management' ?></h2>
<div class="user-info">
<span><?= htmlspecialchars($current_user['first_name'] . ' ' . $current_user['last_name']) ?></span>
<i class="fas fa-user-circle"></i>
</div>
</div>
<?php if ($viewing_ticket): ?>
<!-- Ticket Details View -->
<div class="ticket-details">
<?php if ($message): ?>
<div class="notice notice-<?= $message_type ?>">
<p><?= $message ?></p>
</div>
<?php endif; ?>
<div class="ticket-info">
<div class="ticket-header">
<h3><?= htmlspecialchars($ticket['subject']) ?></h3>
<div class="ticket-meta">
<span class="ticket-number"><?= htmlspecialchars($ticket['ticket_number']) ?></span>
<span class="status-badge status-<?= htmlspecialchars($ticket['status']) ?>">
<?= ucfirst($ticket['status']) ?>
</span>
<span class="priority-<?= htmlspecialchars($ticket['priority']) ?>">
<?= ucfirst($ticket['priority']) ?> priority
</span>
</div>
</div>
<div class="ticket-body">
<div class="ticket-description">
<h4>Description</h4>
<p><?= nl2br(htmlspecialchars($ticket['description'])) ?></p>
</div>
<div class="ticket-meta-details">
<div class="meta-row">
<span class="meta-label">Created By:</span>
<span class="meta-value"><?= htmlspecialchars($ticket['creator_name']) ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Department:</span>
<span class="meta-value"><?= htmlspecialchars($ticket['department_name'] ?? 'None') ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Assigned To:</span>
<span class="meta-value"><?= htmlspecialchars($ticket['assigned_name'] ?? 'Unassigned') ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Created At:</span>
<span class="meta-value"><?= date('M j, Y g:i A', strtotime($ticket['created_at'])) ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Last Updated:</span>
<span class="meta-value"><?= date('M j, Y g:i A', strtotime($ticket['updated_at'])) ?></span>
</div>
</div>
</div>
</div>
<div class="ticket-messages">
<h3>Conversation</h3>
<?php if (empty($messages)): ?>
<p>No messages yet.</p>
<?php else: ?>
<div class="message-list">
<?php foreach ($messages as $msg): ?>
<div class="message <?= $msg['user_role'] ?>">
<div class="message-header">
<span class="message-author"><?= htmlspecialchars($msg['user_name']) ?></span>
<span class="message-date"><?= date('M j, Y g:i A', strtotime($msg['created_at'])) ?></span>
</div>
<div class="message-content">
<?= nl2br(htmlspecialchars($msg['message'])) ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="add-message">
<h4>Add Message</h4>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<textarea name="message" required placeholder="Type your message here..."></textarea>
</div>
<button type="submit" name="add_message" class="button-primary">Send Message</button>
</form>
</div>
</div>
</div>
<?php else: ?>
<!-- Ticket List View -->
<div class="ticket-system">
<?php if ($message): ?>
<div class="notice notice-<?= $message_type ?>">
<p><?= $message ?></p>
</div>
<?php endif; ?>
<?php if ($current_user['role'] === 'user'): ?>
<!-- Ticket creation form for regular users -->
<div class="create-ticket-form">
<h3>Create New Ticket</h3>
<form method="POST">
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" required>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" required></textarea>
</div>
<div class="form-group">
<label>Priority</label>
<select name="priority" required>
<option value="low">Low</option>
<option value="medium" selected>Medium</option>
<option value="high">High</option>
</select>
</div>
<div class="form-group">
<label>Department</label>
<select name="department_id" required>
<?php foreach ($departments as $dept): ?>
<option value="<?= $dept['id'] ?>"><?= htmlspecialchars($dept['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" name="create_ticket" class="button-primary">Create Ticket</button>
</form>
</div>
<?php endif; ?>
<!-- Tickets List -->
<div class="tickets-list">
<h3><?= ($current_user['role'] === 'admin' || $current_user['role'] === 'staff') ? 'All Tickets' : 'My Tickets' ?></h3>
<?php if (empty($tickets)): ?>
<p>No tickets found.</p>
<?php else: ?>
<table class="tickets-table">
<thead>
<tr>
<th>Ticket #</th>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<th>Created By</th>
<?php endif; ?>
<th>Subject</th>
<th>Status</th>
<th>Priority</th>
<th>Department</th>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<th>Assigned To</th>
<?php endif; ?>
<th>Created At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($tickets as $ticket): ?>
<tr>
<td><?= htmlspecialchars($ticket['ticket_number']) ?></td>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<td><?= htmlspecialchars($ticket['creator_name'] ?? 'N/A') ?></td>
<?php endif; ?>
<td><?= htmlspecialchars($ticket['subject']) ?></td>
<td>
<span class="status-badge status-<?= htmlspecialchars($ticket['status']) ?>">
<?= ucfirst($ticket['status']) ?>
</span>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<form method="POST" class="status-update-form">
<input type="hidden" name="ticket_id" value="<?= $ticket['id'] ?>">
<select name="status" onchange="this.form.submit()">
<option value="open" <?= $ticket['status'] === 'open' ? 'selected' : '' ?>>Open</option>
<option value="assigned" <?= $ticket['status'] === 'assigned' ? 'selected' : '' ?>>Assigned</option>
<option value="pending" <?= $ticket['status'] === 'pending' ? 'selected' : '' ?>>Pending</option>
<option value="solved" <?= $ticket['status'] === 'solved' ? 'selected' : '' ?>>Solved</option>
<option value="closed" <?= $ticket['status'] === 'closed' ? 'selected' : '' ?>>Closed</option>
</select>
<input type="hidden" name="update_status" value="1">
</form>
<?php endif; ?>
</td>
<td class="priority-<?= htmlspecialchars($ticket['priority']) ?>">
<?= ucfirst($ticket['priority']) ?>
</td>
<td><?= htmlspecialchars($ticket['department_name'] ?? 'None') ?></td>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<td>
<?php if ($ticket['assigned_to']): ?>
<?= htmlspecialchars($ticket['assigned_name'] ?? 'N/A') ?>
<?php else: ?>
<form method="POST" class="assign-form">
<input type="hidden" name="ticket_id" value="<?= $ticket['id'] ?>">
<select name="assign_to" onchange="this.form.submit()">
<option value="">Assign to...</option>
<?php foreach ($staff_members as $staff): ?>
<option value="<?= $staff['id'] ?>"><?= htmlspecialchars($staff['name']) ?></option>
<?php endforeach; ?>
</select>
<input type="hidden" name="assign_ticket" value="1">
</form>
<?php endif; ?>
</td>
<?php endif; ?>
<td><?= date('M j, Y', strtotime($ticket['created_at'])) ?></td>
<td>
<a href="<?= home_url('/tickets?ticket_id=' . $ticket['id']) ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= home_url('/edit-ticket?id=' . $ticket['id']) ?>" class="button">Edit</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</main>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// AJAX form submissions
document.querySelectorAll('.status-update-form select, .assign-form select').forEach(select => {
select.addEventListener('change', function() {
const form = this.closest('form');
fetch('', {
method: 'POST',
body: new FormData(form)
})
.then(response => {
if (response.ok) {
window.location.reload();
} else {
alert('Error updating ticket');
}
})
.catch(error => {
console.error('Error:', error);
alert('Error updating ticket');
});
});
});
});
</script>
</body>
</html>
<?php
// Start session for custom authentication
session_start();
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: " . home_url('/login'));
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: " . home_url('/login'));
exit;
}
// Check if viewing ticket details
$viewing_ticket = isset($_GET['ticket_id']);
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
if ($viewing_ticket) {
// Get ticket details
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.id = ?
");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
// Check if ticket exists and user has permission
if (!$ticket) {
die("Ticket not found");
}
if ($current_user['role'] === 'user' && $ticket['created_by'] != $current_user['id']) {
die("You don't have permission to view this ticket");
}
// Get ticket messages
$stmt = $pdo->prepare("
SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as user_name, u.role as user_role
FROM ticket_messages m
JOIN users u ON m.user_id = u.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Handle form submissions
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['create_ticket'])) {
$subject = htmlspecialchars($_POST['subject']);
$description = htmlspecialchars($_POST['description']);
$priority = htmlspecialchars($_POST['priority']);
$department_id = (int)$_POST['department_id'];
try {
$ticket_number = 'TKT-' . date('Ymd-His');
$stmt = $pdo->prepare("INSERT INTO tickets
(ticket_number, subject, description, priority, department_id, created_by, status, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, 'open', NOW(), NOW())");
$stmt->execute([
$ticket_number,
$subject,
$description,
$priority,
$department_id,
$current_user['id']
]);
$ticket_id = $pdo->lastInsertId();
// Add initial message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$description
]);
$message = 'Ticket created successfully!';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error creating ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['update_status'])) {
$ticket_id = (int)$_POST['ticket_id'];
$status = htmlspecialchars($_POST['status']);
try {
$stmt = $pdo->prepare("UPDATE tickets SET status = ?, updated_at = NOW() WHERE id = ?");
$stmt->execute([$status, $ticket_id]);
// Add status change message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
"Status changed to: " . ucfirst($status)
]);
$message = 'Ticket status updated!';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error updating ticket status: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['assign_ticket'])) {
$ticket_id = (int)$_POST['ticket_id'];
$assign_to = (int)$_POST['assign_to'];
try {
$stmt = $pdo->prepare("UPDATE tickets SET assigned_to = ?, status = 'assigned', updated_at = NOW() WHERE id = ?");
$stmt->execute([$assign_to, $ticket_id]);
// Add assignment message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
"Ticket assigned to staff ID: " . $assign_to
]);
$message = 'Ticket assigned successfully!';
$message_type = 'success';
} catch (PDOException $e) {
$message = 'Error assigning ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['add_message'])) {
$ticket_id = (int)$_POST['ticket_id'];
$message_text = htmlspecialchars($_POST['message']);
try {
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$message_text
]);
// Update ticket's updated_at
$stmt = $pdo->prepare("UPDATE tickets SET updated_at = NOW() WHERE id = ?");
$stmt->execute([$ticket_id]);
$message = 'Message added successfully!';
$message_type = 'success';
// Refresh messages
$stmt = $pdo->prepare("
SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as user_name, u.role as user_role
FROM ticket_messages m
JOIN users u ON m.user_id = u.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message = 'Error adding message: ' . $e->getMessage();
$message_type = 'error';
}
}
}
// Get all necessary data for ticket list
if (!$viewing_ticket) {
try {
// Get tickets based on role
if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff') {
$tickets = $pdo->query("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
ORDER BY t.created_at DESC
")->fetchAll(PDO::FETCH_ASSOC);
} else {
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.created_by = ?
ORDER BY t.created_at DESC
");
$stmt->execute([$current_user['id']]);
$tickets = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Get departments for dropdown
$departments = $pdo->query("SELECT * FROM departments")->fetchAll(PDO::FETCH_ASSOC);
// Get staff for assignment dropdown
$staff_members = $pdo->query("
SELECT id, CONCAT(first_name, ' ', last_name) as name
FROM users
WHERE role IN ('staff', 'admin')
")->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error fetching data: " . $e->getMessage());
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $viewing_ticket ? 'Ticket Details' : 'Ticket System' ?></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f7f9;
color: #333;
}
.helpdesk-container {
display: flex;
min-height: 100vh;
}
/* Sidebar Styles */
.helpdesk-sidebar {
width: 240px;
background-color: #D1B48C;
color: #000;
position: fixed;
left: 0;
top: 0;
height: 100vh;
overflow-y: auto;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
.sidebar-header {
padding: 20px;
text-align: center;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.sidebar-header .site-name {
font-size: 24px;
font-weight: bold;
color: #000;
margin: 0;
}
.helpdesk-menu {
padding: 0;
}
.helpdesk-menu ul {
list-style: none;
margin: 0;
padding: 0;
}
.helpdesk-menu li a {
display: flex;
align-items: center;
padding: 12px 20px;
text-decoration: none;
color: #000;
transition: 0.3s;
font-size: 16px;
}
.helpdesk-menu li a i {
margin-right: 12px;
width: 20px;
text-align: center;
}
.helpdesk-menu li a:hover,
.helpdesk-menu li.active a {
background-color: #ffffff;
color: #000;
}
/* Main Content Styles */
.helpdesk-main {
margin-left: 240px;
padding: 20px;
flex-grow: 1;
background-color: #f4f7f9;
}
.header {
background-color: #77693A;
padding: 10px 30px;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
border-radius: 4px;
}
.header .user-info {
display: flex;
align-items: center;
}
.header .user-info i {
margin-left: 10px;
}
/* Ticket System Styles */
.ticket-system,
.ticket-details {
max-width: 1200px;
margin: 0 auto;
}
.notice {
padding: 15px;
margin: 0 0 20px 0;
border-radius: 4px;
border-left: 4px solid;
}
.notice.success {
background-color: #f0fff4;
border-color: #38a169;
color: #2f855a;
}
.notice.error {
background-color: #fff5f5;
border-color: #e53e3e;
color: #c53030;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
}
.form-group input[type="text"],
.form-group textarea,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
.form-group textarea {
min-height: 120px;
resize: vertical;
}
button, .button {
padding: 10px 15px;
border: none;
background-color: #77693A;
color: white;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
text-decoration: none;
display: inline-block;
}
button:hover, .button:hover {
background-color: #5a4d1b;
}
.button-primary {
background-color: #4663ac;
}
.button-primary:hover {
background-color: #3a528b;
}
/* Tickets Table */
.tickets-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
background-color: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.tickets-table th,
.tickets-table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.tickets-table th {
background-color: #f8f9fa;
font-weight: 600;
}
.tickets-table tr:hover {
background-color: #f5f5f5;
}
/* Status Badges */
.status-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
}
.status-open { background-color: #e3f2fd; color: #1976d2; }
.status-assigned { background-color: #fff8e1; color: #ff8f00; }
.status-pending { background-color: #ffebee; color: #d32f2f; }
.status-solved { background-color: #e8f5e9; color: #388e3c; }
.status-closed { background-color: #f5f5f5; color: #616161; }
/* Priority Indicators */
.priority-high { color: #d32f2f; font-weight: bold; }
.priority-medium { color: #ffa000; }
.priority-low { color: #388e3c; }
/* Forms */
.status-update-form,
.assign-form {
display: inline-block;
margin-top: 5px;
}
.status-update-form select,
.assign-form select {
padding: 5px;
font-size: 14px;
border-radius: 4px;
border: 1px solid #ddd;
}
/* Ticket Details */
.ticket-info {
background-color: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.ticket-header {
border-bottom: 1px solid #eee;
padding-bottom: 15px;
margin-bottom: 15px;
}
.ticket-meta {
display: flex;
gap: 10px;
align-items: center;
margin-top: 10px;
}
.ticket-number {
font-size: 14px;
color: #666;
}
.ticket-body {
display: flex;
gap: 30px;
}
.ticket-description {
flex: 2;
}
.ticket-meta-details {
flex: 1;
}
.meta-row {
margin-bottom: 10px;
}
.meta-label {
font-weight: 600;
display: inline-block;
width: 100px;
}
.meta-value {
color: #555;
}
/* Messages */
.ticket-messages {
background-color: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.message-list {
margin-bottom: 20px;
}
.message {
padding: 15px;
border-bottom: 1px solid #eee;
}
.message:last-child {
border-bottom: none;
}
.message-header {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 14px;
}
.message-author {
font-weight: 600;
}
.message-date {
color: #666;
}
.message-content {
line-height: 1.5;
}
.message.admin,
.message.staff {
background-color: #f8f9fa;
}
.add-message textarea {
min-height: 100px;
}
/* Responsive */
@media (max-width: 768px) {
.helpdesk-container {
flex-direction: column;
}
.helpdesk-sidebar {
width: 100%;
height: auto;
position: relative;
}
.helpdesk-main {
margin-left: 0;
}
.helpdesk-menu ul {
display: flex;
flex-wrap: wrap;
}
.ticket-body {
flex-direction: column;
}
}
</style>
</head>
<body>
<div class="helpdesk-container">
<!-- Sidebar Navigation -->
<aside class="helpdesk-sidebar">
<div class="sidebar-header">
<h1 class="site-name">Helpdesk System</h1>
</div>
<nav class="helpdesk-menu">
<ul>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="<?= home_url('/dashboard') ?>"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
<li><a href="<?= home_url('/users') ?>"><i class="fas fa-users-cog"></i> Users</a></li>
<li><a href="<?= home_url('/departments') ?>"><i class="fas fa-building"></i> Departments</a></li>
<?php endif; ?>
<li class="<?= !$viewing_ticket ? 'active' : '' ?>"><a href="<?= home_url('/tickets') ?>"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<li><a href="<?= home_url('/messages') ?>"><i class="fas fa-envelope"></i> Messages</a></li>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="<?= home_url('/reports') ?>"><i class="fas fa-chart-bar"></i> Reports</a></li>
<?php endif; ?>
<li><a href="<?= home_url('/logout') ?>"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="helpdesk-main">
<div class="header">
<h2><?= $viewing_ticket ? 'Ticket Details' : 'Ticket Management' ?></h2>
<div class="user-info">
<span><?= htmlspecialchars($current_user['first_name'] . ' ' . $current_user['last_name']) ?></span>
<i class="fas fa-user-circle"></i>
</div>
</div>
<?php if ($viewing_ticket): ?>
<!-- Ticket Details View -->
<div class="ticket-details">
<?php if ($message): ?>
<div class="notice notice-<?= $message_type ?>">
<p><?= $message ?></p>
</div>
<?php endif; ?>
<div class="ticket-info">
<div class="ticket-header">
<h3><?= htmlspecialchars($ticket['subject']) ?></h3>
<div class="ticket-meta">
<span class="ticket-number"><?= htmlspecialchars($ticket['ticket_number']) ?></span>
<span class="status-badge status-<?= htmlspecialchars($ticket['status']) ?>">
<?= ucfirst($ticket['status']) ?>
</span>
<span class="priority-<?= htmlspecialchars($ticket['priority']) ?>">
<?= ucfirst($ticket['priority']) ?> priority
</span>
</div>
</div>
<div class="ticket-body">
<div class="ticket-description">
<h4>Description</h4>
<p><?= nl2br(htmlspecialchars($ticket['description'])) ?></p>
</div>
<div class="ticket-meta-details">
<div class="meta-row">
<span class="meta-label">Created By:</span>
<span class="meta-value"><?= htmlspecialchars($ticket['creator_name']) ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Department:</span>
<span class="meta-value"><?= htmlspecialchars($ticket['department_name'] ?? 'None') ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Assigned To:</span>
<span class="meta-value"><?= htmlspecialchars($ticket['assigned_name'] ?? 'Unassigned') ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Created At:</span>
<span class="meta-value"><?= date('M j, Y g:i A', strtotime($ticket['created_at'])) ?></span>
</div>
<div class="meta-row">
<span class="meta-label">Last Updated:</span>
<span class="meta-value"><?= date('M j, Y g:i A', strtotime($ticket['updated_at'])) ?></span>
</div>
</div>
</div>
</div>
<div class="ticket-messages">
<h3>Conversation</h3>
<?php if (empty($messages)): ?>
<p>No messages yet.</p>
<?php else: ?>
<div class="message-list">
<?php foreach ($messages as $msg): ?>
<div class="message <?= $msg['user_role'] ?>">
<div class="message-header">
<span class="message-author"><?= htmlspecialchars($msg['user_name']) ?></span>
<span class="message-date"><?= date('M j, Y g:i A', strtotime($msg['created_at'])) ?></span>
</div>
<div class="message-content">
<?= nl2br(htmlspecialchars($msg['message'])) ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="add-message">
<h4>Add Message</h4>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<textarea name="message" required placeholder="Type your message here..."></textarea>
</div>
<button type="submit" name="add_message" class="button-primary">Send Message</button>
</form>
</div>
</div>
</div>
<?php else: ?>
<!-- Ticket List View -->
<div class="ticket-system">
<?php if ($message): ?>
<div class="notice notice-<?= $message_type ?>">
<p><?= $message ?></p>
</div>
<?php endif; ?>
<?php if ($current_user['role'] === 'user'): ?>
<!-- Ticket creation form for regular users -->
<div class="create-ticket-form">
<h3>Create New Ticket</h3>
<form method="POST">
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" required>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" required></textarea>
</div>
<div class="form-group">
<label>Priority</label>
<select name="priority" required>
<option value="low">Low</option>
<option value="medium" selected>Medium</option>
<option value="high">High</option>
</select>
</div>
<div class="form-group">
<label>Department</label>
<select name="department_id" required>
<?php foreach ($departments as $dept): ?>
<option value="<?= $dept['id'] ?>"><?= htmlspecialchars($dept['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" name="create_ticket" class="button-primary">Create Ticket</button>
</form>
</div>
<?php endif; ?>
<!-- Tickets List -->
<div class="tickets-list">
<h3><?= ($current_user['role'] === 'admin' || $current_user['role'] === 'staff') ? 'All Tickets' : 'My Tickets' ?></h3>
<?php if (empty($tickets)): ?>
<p>No tickets found.</p>
<?php else: ?>
<table class="tickets-table">
<thead>
<tr>
<th>Ticket #</th>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<th>Created By</th>
<?php endif; ?>
<th>Subject</th>
<th>Status</th>
<th>Priority</th>
<th>Department</th>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<th>Assigned To</th>
<?php endif; ?>
<th>Created At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($tickets as $ticket): ?>
<tr>
<td><?= htmlspecialchars($ticket['ticket_number']) ?></td>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<td><?= htmlspecialchars($ticket['creator_name'] ?? 'N/A') ?></td>
<?php endif; ?>
<td><?= htmlspecialchars($ticket['subject']) ?></td>
<td>
<span class="status-badge status-<?= htmlspecialchars($ticket['status']) ?>">
<?= ucfirst($ticket['status']) ?>
</span>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<form method="POST" class="status-update-form">
<input type="hidden" name="ticket_id" value="<?= $ticket['id'] ?>">
<select name="status" onchange="this.form.submit()">
<option value="open" <?= $ticket['status'] === 'open' ? 'selected' : '' ?>>Open</option>
<option value="assigned" <?= $ticket['status'] === 'assigned' ? 'selected' : '' ?>>Assigned</option>
<option value="pending" <?= $ticket['status'] === 'pending' ? 'selected' : '' ?>>Pending</option>
<option value="solved" <?= $ticket['status'] === 'solved' ? 'selected' : '' ?>>Solved</option>
<option value="closed" <?= $ticket['status'] === 'closed' ? 'selected' : '' ?>>Closed</option>
</select>
<input type="hidden" name="update_status" value="1">
</form>
<?php endif; ?>
</td>
<td class="priority-<?= htmlspecialchars($ticket['priority']) ?>">
<?= ucfirst($ticket['priority']) ?>
</td>
<td><?= htmlspecialchars($ticket['department_name'] ?? 'None') ?></td>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<td>
<?php if ($ticket['assigned_to']): ?>
<?= htmlspecialchars($ticket['assigned_name'] ?? 'N/A') ?>
<?php else: ?>
<form method="POST" class="assign-form">
<input type="hidden" name="ticket_id" value="<?= $ticket['id'] ?>">
<select name="assign_to" onchange="this.form.submit()">
<option value="">Assign to...</option>
<?php foreach ($staff_members as $staff): ?>
<option value="<?= $staff['id'] ?>"><?= htmlspecialchars($staff['name']) ?></option>
<?php endforeach; ?>
</select>
<input type="hidden" name="assign_ticket" value="1">
</form>
<?php endif; ?>
</td>
<?php endif; ?>
<td><?= date('M j, Y', strtotime($ticket['created_at'])) ?></td>
<td>
<a href="<?= home_url('/tickets?ticket_id=' . $ticket['id']) ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= home_url('/edit-ticket?id=' . $ticket['id']) ?>" class="button">Edit</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</main>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// AJAX form submissions
document.querySelectorAll('.status-update-form select, .assign-form select').forEach(select => {
select.addEventListener('change', function() {
const form = this.closest('form');
fetch('', {
method: 'POST',
body: new FormData(form)
})
.then(response => {
if (response.ok) {
window.location.reload();
} else {
alert('Error updating ticket');
}
})
.catch(error => {
console.error('Error:', error);
alert('Error updating ticket');
});
});
});
});
</script>
</body>
</html>
Key improvements made:
home_url() functionThe code now handles:
The issue with the "Not Found" error occurs because the URLs for "View" and "Edit" buttons aren't pointing to valid endpoints. Let's fix this by modifying the URLs to work within WordPress and ensuring all functionality stays in one file.
Here's the corrected version with proper URL handling:
<?php
// [Previous PHP code remains exactly the same until the actions section in the tickets table]
<td>
<a href="<?= add_query_arg('ticket_id', $ticket['id'], home_url('/tickets')) ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= add_query_arg(['ticket_id' => $ticket['id'], 'action' => 'edit'], home_url('/tickets')) ?>" class="button">Edit</a>
<?php endif; ?>
</td>
// [Rest of the code remains the same]
<?php
// [Previous PHP code remains exactly the same until the actions section in the tickets table]
<td>
<a href="<?= add_query_arg('ticket_id', $ticket['id'], home_url('/tickets')) ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= add_query_arg(['ticket_id' => $ticket['id'], 'action' => 'edit'], home_url('/tickets')) ?>" class="button">Edit</a>
<?php endif; ?>
</td>
// [Rest of the code remains the same]
The key changes are:
<a href="<?= add_query_arg('ticket_id', $ticket['id'], home_url('/tickets')) ?>" class="button">View</a>
<a href="<?= add_query_arg('ticket_id', $ticket['id'], home_url('/tickets')) ?>" class="button">View</a>
<a href="<?= add_query_arg(['ticket_id' => $ticket['id'], 'action' => 'edit'], home_url('/tickets')) ?>" class="button">Edit</a>
<a href="<?= add_query_arg(['ticket_id' => $ticket['id'], 'action' => 'edit'], home_url('/tickets')) ?>" class="button">Edit</a>
These changes ensure that:
home_url() function to generate proper URLsadd_query_arg() function safely adds parameters to the URLThe edit functionality will need to be implemented in your PHP code by checking for $_GET['action'] === 'edit' when displaying the ticket details view.
Would you like me to provide the complete updated code with the edit functionality implementation as well?
Here's the complete solution with all URLs properly configured for your WordPress installation at http://localhost/helpdesk/?page_id=70:
<?php
// Start session for custom authentication
session_start();
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Base URL for ticket system
$base_url = 'http://localhost/helpdesk/?page_id=70';
// Check if viewing/editing ticket
$viewing_ticket = isset($_GET['ticket_id']);
$editing_ticket = $viewing_ticket && isset($_GET['action']) && $_GET['action'] === 'edit';
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
// [Rest of your existing PHP code remains the same until the HTML section]
?>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- [Your existing head section remains the same] -->
</head>
<body>
<div class="helpdesk-container">
<!-- Sidebar Navigation -->
<aside class="helpdesk-sidebar">
<div class="sidebar-header">
<h1 class="site-name">Helpdesk System</h1>
</div>
<nav class="helpdesk-menu">
<ul>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-users-cog"></i> Users</a></li>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-building"></i> Departments</a></li>
<?php endif; ?>
<li class="<?= !$viewing_ticket ? 'active' : '' ?>"><a href="http://localhost/helpdesk/?page_id=70"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-envelope"></i> Messages</a></li>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-chart-bar"></i> Reports</a></li>
<?php endif; ?>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="helpdesk-main">
<!-- [Your existing header and content sections remain the same until the action buttons] -->
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit" class="button">Edit</a>
<?php endif; ?>
</td>
<!-- [Rest of your existing HTML/PHP code remains the same] -->
</main>
</div>
</body>
</html>
<?php
// Start session for custom authentication
session_start();
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Base URL for ticket system
$base_url = 'http://localhost/helpdesk/?page_id=70';
// Check if viewing/editing ticket
$viewing_ticket = isset($_GET['ticket_id']);
$editing_ticket = $viewing_ticket && isset($_GET['action']) && $_GET['action'] === 'edit';
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
// [Rest of your existing PHP code remains the same until the HTML section]
?>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- [Your existing head section remains the same] -->
</head>
<body>
<div class="helpdesk-container">
<!-- Sidebar Navigation -->
<aside class="helpdesk-sidebar">
<div class="sidebar-header">
<h1 class="site-name">Helpdesk System</h1>
</div>
<nav class="helpdesk-menu">
<ul>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-users-cog"></i> Users</a></li>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-building"></i> Departments</a></li>
<?php endif; ?>
<li class="<?= !$viewing_ticket ? 'active' : '' ?>"><a href="http://localhost/helpdesk/?page_id=70"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-envelope"></i> Messages</a></li>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-chart-bar"></i> Reports</a></li>
<?php endif; ?>
<li><a href="http://localhost/helpdesk/?page_id=XX"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="helpdesk-main">
<!-- [Your existing header and content sections remain the same until the action buttons] -->
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit" class="button">Edit</a>
<?php endif; ?>
</td>
<!-- [Rest of your existing HTML/PHP code remains the same] -->
</main>
</div>
</body>
</html>
Key changes made:
$base_url = 'http://localhost/helpdesk/?page_id=70';
$base_url = 'http://localhost/helpdesk/?page_id=70';
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>">View</a>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit">Edit</a>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>">View</a>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit">Edit</a>
WordPress-Compatible URLs:
All menu links now use the full WordPress URL format http://localhost/helpdesk/?page_id=XX
Parameter Handling:
The code checks for both ticket_id and action parameters in the URL to determine if viewing or editing.
Important notes:
XX in the menu URLs with your actual WordPress page IDs$_GET['action'] === 'edit'Would you like me to provide the complete implementation of the edit functionality as well?*
The blank page issue typically occurs when there's a PHP error that's being suppressed. Let's fix this by implementing proper error handling and ensuring the view/edit functionality works correctly within your WordPress page. Here's the complete solution:
<?php
// Enable error reporting for debugging (remove in production)
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Start session for custom authentication
session_start();
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Base URL for ticket system
$base_url = 'http://localhost/helpdesk/?page_id=70';
// Check if viewing/editing ticket
$viewing_ticket = isset($_GET['ticket_id']);
$editing_ticket = $viewing_ticket && isset($_GET['action']) && $_GET['action'] === 'edit';
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
// Handle form submissions
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// [Your existing form handling code]
}
// Get ticket details if viewing/editing
if ($viewing_ticket) {
try {
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.id = ?
");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$ticket) {
die("Ticket not found");
}
if ($current_user['role'] === 'user' && $ticket['created_by'] != $current_user['id']) {
die("You don't have permission to view this ticket");
}
// Get ticket messages
$stmt = $pdo->prepare("
SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as user_name, u.role as user_role
FROM ticket_messages m
JOIN users u ON m.user_id = u.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error fetching ticket: " . $e->getMessage());
}
}
// Get data for ticket list if not viewing single ticket
if (!$viewing_ticket) {
try {
// [Your existing ticket list query code]
} catch (PDOException $e) {
die("Error fetching tickets: " . $e->getMessage());
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- [Your existing head section] -->
</head>
<body>
<div class="helpdesk-container">
<!-- Sidebar Navigation -->
<aside class="helpdesk-sidebar">
<!-- [Your existing sidebar code] -->
</aside>
<!-- Main Content -->
<main class="helpdesk-main">
<div class="header">
<h2><?= $viewing_ticket ? ($editing_ticket ? 'Edit Ticket' : 'Ticket Details') : 'Ticket Management' ?></h2>
<div class="user-info">
<span><?= htmlspecialchars($current_user['first_name'] . ' ' . $current_user['last_name']) ?></span>
<i class="fas fa-user-circle"></i>
</div>
</div>
<?php if ($message): ?>
<div class="notice notice-<?= $message_type ?>">
<p><?= $message ?></p>
</div>
<?php endif; ?>
<?php if ($viewing_ticket): ?>
<?php if ($editing_ticket): ?>
<!-- Edit Ticket Form -->
<div class="edit-ticket-form">
<h3>Edit Ticket #<?= $ticket['ticket_number'] ?></h3>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" value="<?= htmlspecialchars($ticket['subject']) ?>" required>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" required><?= htmlspecialchars($ticket['description']) ?></textarea>
</div>
<div class="form-group">
<label>Priority</label>
<select name="priority" required>
<option value="low" <?= $ticket['priority'] === 'low' ? 'selected' : '' ?>>Low</option>
<option value="medium" <?= $ticket['priority'] === 'medium' ? 'selected' : '' ?>>Medium</option>
<option value="high" <?= $ticket['priority'] === 'high' ? 'selected' : '' ?>>High</option>
</select>
</div>
<button type="submit" name="update_ticket" class="button-primary">Update Ticket</button>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket_id ?>" class="button">Cancel</a>
</form>
</div>
<?php else: ?>
<!-- Ticket Details View -->
<!-- [Your existing ticket details view code] -->
<?php endif; ?>
<?php else: ?>
<!-- Ticket List View -->
<!-- [Your existing ticket list view code] -->
<!-- In the actions column of the tickets table: -->
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit" class="button">Edit</a>
<?php endif; ?>
</td>
<?php endif; ?>
</main>
</div>
</body>
</html>
<?php
// Enable error reporting for debugging (remove in production)
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Start session for custom authentication
session_start();
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Base URL for ticket system
$base_url = 'http://localhost/helpdesk/?page_id=70';
// Check if viewing/editing ticket
$viewing_ticket = isset($_GET['ticket_id']);
$editing_ticket = $viewing_ticket && isset($_GET['action']) && $_GET['action'] === 'edit';
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
// Handle form submissions
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// [Your existing form handling code]
}
// Get ticket details if viewing/editing
if ($viewing_ticket) {
try {
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.id = ?
");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$ticket) {
die("Ticket not found");
}
if ($current_user['role'] === 'user' && $ticket['created_by'] != $current_user['id']) {
die("You don't have permission to view this ticket");
}
// Get ticket messages
$stmt = $pdo->prepare("
SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as user_name, u.role as user_role
FROM ticket_messages m
JOIN users u ON m.user_id = u.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error fetching ticket: " . $e->getMessage());
}
}
// Get data for ticket list if not viewing single ticket
if (!$viewing_ticket) {
try {
// [Your existing ticket list query code]
} catch (PDOException $e) {
die("Error fetching tickets: " . $e->getMessage());
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- [Your existing head section] -->
</head>
<body>
<div class="helpdesk-container">
<!-- Sidebar Navigation -->
<aside class="helpdesk-sidebar">
<!-- [Your existing sidebar code] -->
</aside>
<!-- Main Content -->
<main class="helpdesk-main">
<div class="header">
<h2><?= $viewing_ticket ? ($editing_ticket ? 'Edit Ticket' : 'Ticket Details') : 'Ticket Management' ?></h2>
<div class="user-info">
<span><?= htmlspecialchars($current_user['first_name'] . ' ' . $current_user['last_name']) ?></span>
<i class="fas fa-user-circle"></i>
</div>
</div>
<?php if ($message): ?>
<div class="notice notice-<?= $message_type ?>">
<p><?= $message ?></p>
</div>
<?php endif; ?>
<?php if ($viewing_ticket): ?>
<?php if ($editing_ticket): ?>
<!-- Edit Ticket Form -->
<div class="edit-ticket-form">
<h3>Edit Ticket #<?= $ticket['ticket_number'] ?></h3>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" value="<?= htmlspecialchars($ticket['subject']) ?>" required>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" required><?= htmlspecialchars($ticket['description']) ?></textarea>
</div>
<div class="form-group">
<label>Priority</label>
<select name="priority" required>
<option value="low" <?= $ticket['priority'] === 'low' ? 'selected' : '' ?>>Low</option>
<option value="medium" <?= $ticket['priority'] === 'medium' ? 'selected' : '' ?>>Medium</option>
<option value="high" <?= $ticket['priority'] === 'high' ? 'selected' : '' ?>>High</option>
</select>
</div>
<button type="submit" name="update_ticket" class="button-primary">Update Ticket</button>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket_id ?>" class="button">Cancel</a>
</form>
</div>
<?php else: ?>
<!-- Ticket Details View -->
<!-- [Your existing ticket details view code] -->
<?php endif; ?>
<?php else: ?>
<!-- Ticket List View -->
<!-- [Your existing ticket list view code] -->
<!-- In the actions column of the tickets table: -->
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit" class="button">Edit</a>
<?php endif; ?>
</td>
<?php endif; ?>
</main>
</div>
</body>
</html>
Key fixes and improvements:
& instead of ? for parameters after the page_id&action=editCommon reasons for blank pages and how this fixes them:
To implement this:
The blank page issue should now be resolved, and you should see either the ticket details or the edit form when clicking the respective buttons.*_
Here are the key changes needed to fix the blank page issue when clicking View/Edit:
<?php):error_reporting(E_ALL);
ini_set('display_errors', 1);
error_reporting(E_ALL);
ini_set('display_errors', 1);
<li class="<?= !$viewing_ticket ? 'active' : '' ?>"><a href="http://localhost/helpdesk/?page_id=70"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<li class="<?= !$viewing_ticket ? 'active' : '' ?>"><a href="http://localhost/helpdesk/?page_id=70"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit" class="button">Edit</a>
<?php endif; ?>
</td>
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>&action=edit" class="button">Edit</a>
<?php endif; ?>
</td>
<?php elseif ($editing_ticket): ?>
<!-- Edit Ticket Form -->
<div class="edit-ticket-form">
<h3>Edit Ticket #<?= $ticket['ticket_number'] ?></h3>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" value="<?= htmlspecialchars($ticket['subject']) ?>" required>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" required><?= htmlspecialchars($ticket['description']) ?></textarea>
</div>
<div class="form-group">
<label>Priority</label>
<select name="priority" required>
<option value="low" <?= $ticket['priority'] === 'low' ? 'selected' : '' ?>>Low</option>
<option value="medium" <?= $ticket['priority'] === 'medium' ? 'selected' : '' ?>>Medium</option>
<option value="high" <?= $ticket['priority'] === 'high' ? 'selected' : '' ?>>High</option>
</select>
</div>
<button type="submit" name="update_ticket" class="button-primary">Update Ticket</button>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket_id ?>" class="button">Cancel</a>
</form>
</div>
<?php elseif ($editing_ticket): ?>
<!-- Edit Ticket Form -->
<div class="edit-ticket-form">
<h3>Edit Ticket #<?= $ticket['ticket_number'] ?></h3>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<label>Subject</label>
<input type="text" name="subject" value="<?= htmlspecialchars($ticket['subject']) ?>" required>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" required><?= htmlspecialchars($ticket['description']) ?></textarea>
</div>
<div class="form-group">
<label>Priority</label>
<select name="priority" required>
<option value="low" <?= $ticket['priority'] === 'low' ? 'selected' : '' ?>>Low</option>
<option value="medium" <?= $ticket['priority'] === 'medium' ? 'selected' : '' ?>>Medium</option>
<option value="high" <?= $ticket['priority'] === 'high' ? 'selected' : '' ?>>High</option>
</select>
</div>
<button type="submit" name="update_ticket" class="button-primary">Update Ticket</button>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket_id ?>" class="button">Cancel</a>
</form>
</div>
elseif (isset($_POST['update_ticket'])) {
$ticket_id = (int)$_POST['ticket_id'];
$subject = htmlspecialchars($_POST['subject']);
$description = htmlspecialchars($_POST['description']);
$priority = htmlspecialchars($_POST['priority']);
try {
$stmt = $pdo->prepare("UPDATE tickets SET subject = ?, description = ?, priority = ?, updated_at = NOW() WHERE id = ?");
$stmt->execute([$subject, $description, $priority, $ticket_id]);
// Add update message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
"Ticket details updated"
]);
$message = 'Ticket updated successfully!';
$message_type = 'success';
// Refresh ticket data
$stmt = $pdo->prepare("SELECT * FROM tickets WHERE id = ?");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message = 'Error updating ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['update_ticket'])) {
$ticket_id = (int)$_POST['ticket_id'];
$subject = htmlspecialchars($_POST['subject']);
$description = htmlspecialchars($_POST['description']);
$priority = htmlspecialchars($_POST['priority']);
try {
$stmt = $pdo->prepare("UPDATE tickets SET subject = ?, description = ?, priority = ?, updated_at = NOW() WHERE id = ?");
$stmt->execute([$subject, $description, $priority, $ticket_id]);
// Add update message
$stmt = $pdo->prepare("INSERT INTO ticket_messages
(ticket_id, user_id, message, created_at)
VALUES (?, ?, ?, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
"Ticket details updated"
]);
$message = 'Ticket updated successfully!';
$message_type = 'success';
// Refresh ticket data
$stmt = $pdo->prepare("SELECT * FROM tickets WHERE id = ?");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$message = 'Error updating ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
These changes will:
The blank page was likely occurring because:
With these changes, clicking View will show the ticket details and clicking Edit will show the edit form, all within the same WordPress page.*