getMessage()); http_response_code(500); echo json_encode(['success' => false, 'error' => 'Internal server error']); exit; } $apiKeyAuth = new ApiKeyAuth($conn); try { $apiKeyAuth->authenticate(); } catch (Exception $e) { // ApiKeyAuth already sent the 401 response. exit; } // Posting a comment is a write — reject 'read' keys with 403 before any mutation. $apiKeyAuth->requireScope('read_write'); if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['success' => false, 'error' => 'Method not allowed. Use POST.']); exit; } $context = $apiKeyAuth->getKeyContext(); $keyName = $context['key_name'] ?? 'API'; $createdBy = ($context['created_by'] ?? null) !== null ? (int)$context['created_by'] : null; $rawInput = file_get_contents('php://input'); $data = json_decode($rawInput, true); if (!is_array($data)) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Invalid JSON body']); exit; } $ticketId = isset($data['ticket_id']) ? trim((string)$data['ticket_id']) : ''; if ($ticketId === '') { http_response_code(400); echo json_encode(['success' => false, 'error' => 'ticket_id is required']); exit; } $commentText = isset($data['comment_text']) ? trim((string)$data['comment_text']) : ''; if ($commentText === '') { http_response_code(400); echo json_encode(['success' => false, 'error' => 'comment_text is required']); exit; } $markdownEnabled = !empty($data['markdown_enabled']); // Validate the ticket exists. $ticketModel = new TicketModel($conn); $ticket = $ticketModel->getTicketById($ticketId); if (!$ticket) { http_response_code(404); echo json_encode(['success' => false, 'error' => 'Ticket not found']); exit; } // Post the comment under the key's label / owner. $commentModel = new CommentModel($conn); $result = $commentModel->addComment($ticketId, [ 'user_name' => $keyName, 'comment_text' => $commentText, 'markdown_enabled' => $markdownEnabled, ], $createdBy); if (empty($result['success'])) { error_log('ticket_comment_api: addComment failed for ticket ' . $ticketId . ': ' . ($result['error'] ?? 'unknown')); http_response_code(500); echo json_encode(['success' => false, 'error' => 'Failed to add comment']); exit; } $commentId = $result['comment_id'] ?? null; // Audit trail (action 'comment' / entity 'comment' are both whitelisted). $auditLog = new AuditLogModel($conn); $auditLog->log($createdBy, 'comment', 'comment', (string)$commentId, [ 'ticket_id' => $ticketId, 'key_name' => $keyName, 'via_api' => true, ]); echo json_encode(['success' => true, 'comment_id' => $commentId]); exit;