conn = $conn; } /** * Extract @mentions from comment text * * @param string $text Comment text * @return array Array of mentioned usernames */ public function extractMentions($text) { $mentions = []; // Match @username patterns (alphanumeric, underscores, hyphens) if (preg_match_all('/@([a-zA-Z0-9_-]+)/', $text, $matches)) { $mentions = array_unique($matches[1]); } return $mentions; } /** * Get user IDs for mentioned usernames * * @param array $usernames Array of usernames * @return array Array of user records with user_id, username, display_name */ public function getMentionedUsers($usernames) { if (empty($usernames)) { return []; } $placeholders = str_repeat('?,', count($usernames) - 1) . '?'; $sql = "SELECT user_id, username, display_name FROM users WHERE username IN ($placeholders)"; $stmt = $this->conn->prepare($sql); $types = str_repeat('s', count($usernames)); $stmt->bind_param($types, ...$usernames); $stmt->execute(); $result = $stmt->get_result(); $users = []; while ($row = $result->fetch_assoc()) { $users[] = $row; } $stmt->close(); return $users; } public function getCommentsByTicketId($ticketId) { $sql = "SELECT tc.*, u.display_name, u.username FROM ticket_comments tc LEFT JOIN users u ON tc.user_id = u.user_id WHERE tc.ticket_id = ? ORDER BY tc.created_at DESC"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("s", $ticketId); // Changed to string since ticket_id is varchar $stmt->execute(); $result = $stmt->get_result(); $comments = []; while ($row = $result->fetch_assoc()) { // Use display_name from users table if available, fallback to user_name field if (!empty($row['display_name'])) { $row['display_name_formatted'] = $row['display_name']; } else { $row['display_name_formatted'] = $row['user_name'] ?? 'Unknown User'; } $comments[] = $row; } return $comments; } public function addComment($ticketId, $commentData, $userId = null) { $sql = "INSERT INTO ticket_comments (ticket_id, user_id, user_name, comment_text, markdown_enabled) VALUES (?, ?, ?, ?, ?)"; $stmt = $this->conn->prepare($sql); // Set default username (kept for backward compatibility) $username = $commentData['user_name'] ?? 'User'; $markdownEnabled = isset($commentData['markdown_enabled']) && $commentData['markdown_enabled'] ? 1 : 0; // Preserve line breaks in the comment text $commentText = $commentData['comment_text']; $stmt->bind_param( "sissi", $ticketId, $userId, $username, $commentText, $markdownEnabled ); if ($stmt->execute()) { $commentId = $this->conn->insert_id; return [ 'success' => true, 'comment_id' => $commentId, 'user_name' => $username, 'created_at' => date('M d, Y H:i'), 'markdown_enabled' => $markdownEnabled, 'comment_text' => $commentText ]; } else { return [ 'success' => false, 'error' => $this->conn->error ]; } } /** * Get a single comment by ID */ public function getCommentById($commentId) { $sql = "SELECT tc.*, u.display_name, u.username FROM ticket_comments tc LEFT JOIN users u ON tc.user_id = u.user_id WHERE tc.comment_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $commentId); $stmt->execute(); $result = $stmt->get_result(); return $result->fetch_assoc(); } /** * Update an existing comment * Only the comment owner or an admin can update */ public function updateComment($commentId, $commentText, $markdownEnabled, $userId, $isAdmin = false) { // First check if user owns this comment or is admin $comment = $this->getCommentById($commentId); if (!$comment) { return ['success' => false, 'error' => 'Comment not found']; } if ($comment['user_id'] != $userId && !$isAdmin) { return ['success' => false, 'error' => 'You do not have permission to edit this comment']; } $sql = "UPDATE ticket_comments SET comment_text = ?, markdown_enabled = ?, updated_at = NOW() WHERE comment_id = ?"; $stmt = $this->conn->prepare($sql); $markdownInt = $markdownEnabled ? 1 : 0; $stmt->bind_param("sii", $commentText, $markdownInt, $commentId); if ($stmt->execute()) { return [ 'success' => true, 'comment_id' => $commentId, 'comment_text' => $commentText, 'markdown_enabled' => $markdownInt, 'updated_at' => date('M d, Y H:i') ]; } else { return ['success' => false, 'error' => $this->conn->error]; } } /** * Delete a comment * Only the comment owner or an admin can delete */ public function deleteComment($commentId, $userId, $isAdmin = false) { // First check if user owns this comment or is admin $comment = $this->getCommentById($commentId); if (!$comment) { return ['success' => false, 'error' => 'Comment not found']; } if ($comment['user_id'] != $userId && !$isAdmin) { return ['success' => false, 'error' => 'You do not have permission to delete this comment']; } $ticketId = $comment['ticket_id']; $sql = "DELETE FROM ticket_comments WHERE comment_id = ?"; $stmt = $this->conn->prepare($sql); $stmt->bind_param("i", $commentId); if ($stmt->execute()) { return [ 'success' => true, 'comment_id' => $commentId, 'ticket_id' => $ticketId ]; } else { return ['success' => false, 'error' => $this->conn->error]; } } } ?>