Files
easystream/api/comments_enhanced.php
Krystie a656c7685c feat: Enhance comment system with threading and reactions
- Add threaded comment support (up to 5 levels deep)
- Implement comment reactions (like, heart, laugh, thinking, sad, angry)
- Add @mention system with user notifications
- Enable comment pinning for video owners
- Support comment editing with edit indicator
- Build moderation system (approve/reject/delete/flag)
- Create cached reaction counts for performance
- Document enhanced comment system

Features:
- Nested comment threads with depth limiting
- Six reaction types per comment
- Automatic mention detection and notifications
- Pin important comments
- Edit history tracking
- Comprehensive moderation tools
- Optimized with aggregated counts
- Production-ready with proper indexing
2026-03-30 17:48:15 -07:00

185 lines
6.2 KiB
PHP

<?php
/**
* Enhanced Comments API
*
* POST /api/comments_enhanced.php?action=post - Post comment/reply
* POST /api/comments_enhanced.php?action=react - Add reaction
* POST /api/comments_enhanced.php?action=unreact - Remove reaction
* POST /api/comments_enhanced.php?action=edit - Edit comment
* POST /api/comments_enhanced.php?action=pin - Pin comment
* GET /api/comments_enhanced.php?action=list&video_id=X - Get threaded comments
* GET /api/comments_enhanced.php?action=replies&comment_id=X - Get replies
*/
require_once dirname(__DIR__) . '/f_core/config.boot.php';
require_once dirname(__DIR__) . '/f_core/f_classes/class.comments_enhanced.php';
header('Content-Type: application/json');
session_start();
$current_user_id = $_SESSION['user_id'] ?? null;
$comments = new VCommentsEnhanced();
$action = $_GET['action'] ?? $_POST['action'] ?? 'list';
switch ($action) {
case 'list':
$video_id = $_GET['video_id'] ?? null;
$limit = intval($_GET['limit'] ?? 50);
$offset = intval($_GET['offset'] ?? 0);
$sort = $_GET['sort'] ?? 'top'; // top, newest, oldest
if (!$video_id) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Video ID required']);
exit;
}
$data = $comments->getThreadedComments($video_id, $limit, $offset, $sort);
echo json_encode(['success' => true, 'comments' => $data]);
break;
case 'replies':
$comment_id = $_GET['comment_id'] ?? null;
$limit = intval($_GET['limit'] ?? 10);
if (!$comment_id) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Comment ID required']);
exit;
}
$data = $comments->getReplies($comment_id, $limit);
echo json_encode(['success' => true, 'replies' => $data]);
break;
case 'post':
if (!$current_user_id) {
http_response_code(401);
echo json_encode(['success' => false, 'error' => 'Authentication required']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$video_id = $input['video_id'] ?? null;
$comment_text = $input['comment'] ?? null;
$parent_comment_id = $input['parent_comment_id'] ?? null;
if (!$video_id || !$comment_text) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Video ID and comment text required']);
exit;
}
$comment_id = $comments->postComment($video_id, $current_user_id, $comment_text, $parent_comment_id);
echo json_encode(['success' => true, 'comment_id' => $comment_id]);
break;
case 'react':
if (!$current_user_id) {
http_response_code(401);
echo json_encode(['success' => false, 'error' => 'Authentication required']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$comment_id = $input['comment_id'] ?? null;
$reaction_type = $input['reaction_type'] ?? 'like';
if (!$comment_id) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Comment ID required']);
exit;
}
$comments->addReaction($comment_id, $current_user_id, $reaction_type);
echo json_encode(['success' => true]);
break;
case 'unreact':
if (!$current_user_id) {
http_response_code(401);
echo json_encode(['success' => false, 'error' => 'Authentication required']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$comment_id = $input['comment_id'] ?? null;
$reaction_type = $input['reaction_type'] ?? 'like';
if (!$comment_id) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Comment ID required']);
exit;
}
$comments->removeReaction($comment_id, $current_user_id, $reaction_type);
echo json_encode(['success' => true]);
break;
case 'edit':
if (!$current_user_id) {
http_response_code(401);
echo json_encode(['success' => false, 'error' => 'Authentication required']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$comment_id = $input['comment_id'] ?? null;
$new_text = $input['comment'] ?? null;
if (!$comment_id || !$new_text) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Comment ID and new text required']);
exit;
}
$success = $comments->editComment($comment_id, $current_user_id, $new_text);
if ($success) {
echo json_encode(['success' => true]);
} else {
http_response_code(403);
echo json_encode(['success' => false, 'error' => 'Permission denied']);
}
break;
case 'pin':
if (!$current_user_id) {
http_response_code(401);
echo json_encode(['success' => false, 'error' => 'Authentication required']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$comment_id = $input['comment_id'] ?? null;
if (!$comment_id) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Comment ID required']);
exit;
}
$success = $comments->pinComment($comment_id, $current_user_id);
if ($success) {
echo json_encode(['success' => true]);
} else {
http_response_code(403);
echo json_encode(['success' => false, 'error' => 'Permission denied']);
}
break;
default:
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Invalid action']);
}