diff --git a/api/add_comment.php b/api/add_comment.php index 8737dae..cc306c5 100644 --- a/api/add_comment.php +++ b/api/add_comment.php @@ -65,8 +65,8 @@ try { throw new Exception("Invalid JSON data received"); } - $ticketId = isset($data['ticket_id']) ? (int)$data['ticket_id'] : 0; - if ($ticketId <= 0) { + $ticketId = isset($data['ticket_id']) ? trim((string)$data['ticket_id']) : ''; + if (!ctype_digit($ticketId) || (int)$ticketId <= 0) { http_response_code(400); ob_end_clean(); header('Content-Type: application/json'); diff --git a/api/export_tickets.php b/api/export_tickets.php index 5c8d1b7..e6eec31 100644 --- a/api/export_tickets.php +++ b/api/export_tickets.php @@ -43,7 +43,8 @@ try { $search = isset($_GET['search']) ? trim($_GET['search']) : null; $format = isset($_GET['format']) ? $_GET['format'] : 'csv'; $ticketIds = isset($_GET['ticket_ids']) ? $_GET['ticket_ids'] : null; - $singleId = isset($_GET['ticket_id']) ? (int)$_GET['ticket_id'] : null; + $singleIdRaw = isset($_GET['ticket_id']) ? trim($_GET['ticket_id']) : null; + $singleId = ($singleIdRaw !== null && ctype_digit($singleIdRaw) && (int)$singleIdRaw > 0) ? $singleIdRaw : null; // Initialize model $ticketModel = new TicketModel($conn); diff --git a/api/notifications.php b/api/notifications.php index f3afd22..b32a21e 100644 --- a/api/notifications.php +++ b/api/notifications.php @@ -75,7 +75,7 @@ $stmt = $conn->prepare($myTicketsSql); $stmt->bind_param('ii', $userId, $userId); $stmt->execute(); $mtResult = $stmt->get_result(); -while ($mtRow = $mtResult->fetch_assoc()) { $myTicketIds[(int)$mtRow['ticket_id']] = true; } +while ($mtRow = $mtResult->fetch_assoc()) { $myTicketIds[(int)$mtRow['ticket_id']] = true; $myTicketIds[$mtRow['ticket_id']] = true; } $stmt->close(); $watchedSql = "SELECT ticket_id FROM ticket_watchers WHERE user_id = ?"; @@ -83,7 +83,7 @@ $stmt = $conn->prepare($watchedSql); $stmt->bind_param('i', $userId); $stmt->execute(); $wResult = $stmt->get_result(); -while ($wRow = $wResult->fetch_assoc()) { $myTicketIds[(int)$wRow['ticket_id']] = true; } +while ($wRow = $wResult->fetch_assoc()) { $myTicketIds[(int)$wRow['ticket_id']] = true; $myTicketIds[$wRow['ticket_id']] = true; } $stmt->close(); // Step B: fetch recent comment audit events not by the current user @@ -109,8 +109,9 @@ $stmt->close(); $commentRows = []; foreach ($rawCommentRows as $rawRow) { $d = json_decode($rawRow['details'] ?? '{}', true) ?? []; - $tid = (int)($d['ticket_id'] ?? 0); - if ($tid > 0 && isset($myTicketIds[$tid])) { + $tidRaw = $d['ticket_id'] ?? 0; + $tid = (int)$tidRaw; + if ($tid > 0 && (isset($myTicketIds[$tid]) || isset($myTicketIds[$tidRaw]))) { $commentRows[] = $rawRow; if (count($commentRows) >= 15) break; } @@ -158,8 +159,8 @@ foreach ($all as $row) { ? 'comment' : $row['action_type']; $ticketId = ($actionType === 'comment') - ? (int)($details['ticket_id'] ?? 0) - : (int)$row['entity_id']; + ? ($details['ticket_id'] ?? 0) + : $row['entity_id']; $isRead = $lastSeen && $row['created_at'] <= $lastSeen; // Build human-readable title diff --git a/api/update_ticket.php b/api/update_ticket.php index ccc76bb..29c32c7 100644 --- a/api/update_ticket.php +++ b/api/update_ticket.php @@ -252,7 +252,7 @@ try { throw new Exception("Missing ticket_id parameter"); } - $ticketId = (int)$data['ticket_id']; + $ticketId = trim((string)$data['ticket_id']); // Initialize controller $controller = new ApiTicketController($conn, $userId, $isAdmin, $currentUser); diff --git a/assets/js/dashboard.js b/assets/js/dashboard.js index b81fcae..06887e5 100644 --- a/assets/js/dashboard.js +++ b/assets/js/dashboard.js @@ -497,7 +497,7 @@ function updateSelectionCount() { function getSelectedTicketIds() { const checkboxes = document.querySelectorAll('.ticket-checkbox:checked'); - return Array.from(checkboxes).map(cb => parseInt(cb.value)); + return Array.from(checkboxes).map(cb => String(cb.value)); } function clearSelection() { diff --git a/controllers/TicketController.php b/controllers/TicketController.php index 9405f89..5172336 100644 --- a/controllers/TicketController.php +++ b/controllers/TicketController.php @@ -126,12 +126,12 @@ class TicketController { } // Auto-link as duplicate if requested from create form - $linkDupOf = isset($_POST['link_duplicate_of']) ? (int)$_POST['link_duplicate_of'] : 0; - if ($linkDupOf > 0) { - $depSql = "INSERT IGNORE INTO ticket_dependencies (ticket_id, depends_on_ticket_id, dependency_type, created_by) + $linkDupOfRaw = trim($_POST['link_duplicate_of'] ?? ''); + if ($linkDupOfRaw !== '' && ctype_digit($linkDupOfRaw)) { + $depSql = "INSERT IGNORE INTO ticket_dependencies (ticket_id, depends_on_id, dependency_type, created_by) VALUES (?, ?, 'duplicates', ?)"; $depStmt = $this->conn->prepare($depSql); - $depStmt->bind_param("iii", $result['ticket_id'], $linkDupOf, $userId); + $depStmt->bind_param("ssi", $result['ticket_id'], $linkDupOfRaw, $userId); $depStmt->execute(); $depStmt->close(); } diff --git a/views/DashboardView.php b/views/DashboardView.php index 79a3251..50a7991 100644 --- a/views/DashboardView.php +++ b/views/DashboardView.php @@ -762,7 +762,7 @@ include __DIR__ . '/layout_header.php'; aria-label="View ticket ">View EXPORT