diff --git a/models/TicketModel.php b/models/TicketModel.php index c76f98f..a9cf330 100644 --- a/models/TicketModel.php +++ b/models/TicketModel.php @@ -151,26 +151,38 @@ class TicketModel { } // Validate sort column to prevent SQL injection - $allowedColumns = ['ticket_id', 'title', 'status', 'priority', 'category', 'type', 'created_at', 'updated_at']; + $allowedColumns = ['ticket_id', 'title', 'status', 'priority', 'category', 'type', 'created_at', 'updated_at', 'created_by', 'assigned_to']; if (!in_array($sortColumn, $allowedColumns)) { $sortColumn = 'ticket_id'; } - + + // Map column names to actual sort expressions + // For user columns, sort by display name with NULL handling for unassigned + $sortExpression = $sortColumn; + if ($sortColumn === 'created_by') { + $sortExpression = "COALESCE(u_created.display_name, u_created.username, 'System')"; + } elseif ($sortColumn === 'assigned_to') { + // Put unassigned (NULL) at the end regardless of sort direction + $sortExpression = "CASE WHEN t.assigned_to IS NULL THEN 1 ELSE 0 END, COALESCE(u_assigned.display_name, u_assigned.username)"; + } else { + $sortExpression = "t.$sortColumn"; + } + // Validate sort direction $sortDirection = strtolower($sortDirection) === 'asc' ? 'ASC' : 'DESC'; - + // Get total count for pagination $countSql = "SELECT COUNT(*) as total FROM tickets $whereClause"; $countStmt = $this->conn->prepare($countSql); - + if (!empty($params)) { $countStmt->bind_param($paramTypes, ...$params); } - + $countStmt->execute(); $totalResult = $countStmt->get_result(); $totalTickets = $totalResult->fetch_assoc()['total']; - + // Get tickets with pagination and creator info $sql = "SELECT t.*, u_created.username as creator_username, @@ -181,7 +193,7 @@ class TicketModel { LEFT JOIN users u_created ON t.created_by = u_created.user_id LEFT JOIN users u_assigned ON t.assigned_to = u_assigned.user_id $whereClause - ORDER BY $sortColumn $sortDirection + ORDER BY $sortExpression $sortDirection LIMIT ? OFFSET ?"; $stmt = $this->conn->prepare($sql);