![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/private_html/utils/ |
<?php
session_start();
header('Content-Type: application/json');
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['error' => 'Login required']);
exit;
}
require_once 'config/database.php';
$pdo = getDBConnection();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
$action = $input['action'] ?? '';
$user_id = $_SESSION['user_id'];
switch ($action) {
case 'like':
$track_id = $input['track_id'] ?? null;
if (!$track_id) {
http_response_code(400);
echo json_encode(['error' => 'Track ID required']);
exit;
}
// Check if already liked
$stmt = $pdo->prepare("SELECT id FROM track_likes WHERE user_id = ? AND track_id = ?");
$stmt->execute([$user_id, $track_id]);
$existing_like = $stmt->fetch();
if ($existing_like) {
// Unlike
$stmt = $pdo->prepare("DELETE FROM track_likes WHERE user_id = ? AND track_id = ?");
$stmt->execute([$user_id, $track_id]);
echo json_encode(['success' => true, 'action' => 'unliked']);
} else {
// Like
$stmt = $pdo->prepare("INSERT INTO track_likes (user_id, track_id, created_at) VALUES (?, ?, NOW())");
$stmt->execute([$user_id, $track_id]);
echo json_encode(['success' => true, 'action' => 'liked']);
}
break;
case 'follow':
$follow_user_id = $input['user_id'] ?? null;
if (!$follow_user_id || $follow_user_id == $user_id) {
http_response_code(400);
echo json_encode(['error' => 'Invalid user ID']);
exit;
}
// Check if already following
$stmt = $pdo->prepare("SELECT id FROM user_follows WHERE follower_id = ? AND following_id = ?");
$stmt->execute([$user_id, $follow_user_id]);
$existing_follow = $stmt->fetch();
if ($existing_follow) {
// Unfollow
$stmt = $pdo->prepare("DELETE FROM user_follows WHERE follower_id = ? AND following_id = ?");
$stmt->execute([$user_id, $follow_user_id]);
echo json_encode(['success' => true, 'action' => 'unfollowed']);
} else {
// Follow
$stmt = $pdo->prepare("INSERT INTO user_follows (follower_id, following_id, created_at) VALUES (?, ?, NOW())");
$stmt->execute([$user_id, $follow_user_id]);
echo json_encode(['success' => true, 'action' => 'followed']);
}
break;
case 'comment':
$track_id = $input['track_id'] ?? null;
$comment_text = $input['comment'] ?? '';
if (!$track_id || empty($comment_text)) {
http_response_code(400);
echo json_encode(['error' => 'Track ID and comment required']);
exit;
}
// Add comment
$stmt = $pdo->prepare("INSERT INTO track_comments (user_id, track_id, comment, created_at) VALUES (?, ?, ?, NOW())");
$stmt->execute([$user_id, $track_id, $comment_text]);
echo json_encode(['success' => true, 'comment_id' => $pdo->lastInsertId()]);
break;
default:
http_response_code(400);
echo json_encode(['error' => 'Invalid action']);
break;
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'GET') {
$action = $_GET['action'] ?? '';
$user_id = $_SESSION['user_id'];
switch ($action) {
case 'comments':
// SECURITY: Validate and sanitize track_id parameter
$track_id_raw = $_GET['track_id'] ?? null;
if (!$track_id_raw) {
http_response_code(400);
echo json_encode(['error' => 'Track ID required']);
exit;
}
// SECURITY: Validate that track_id is a positive integer
if (!is_numeric($track_id_raw) || (int)$track_id_raw <= 0) {
error_log("SECURITY: Invalid track_id attempt in api_social.php: " . htmlspecialchars($track_id_raw, ENT_QUOTES, 'UTF-8'));
http_response_code(400);
echo json_encode(['error' => 'Invalid track ID']);
exit;
}
$track_id = (int)$track_id_raw;
// Get comments for track
$stmt = $pdo->prepare("
SELECT
tc.id,
tc.comment,
tc.created_at,
u.name as user_name,
u.id as user_id
FROM track_comments tc
JOIN users u ON tc.user_id = u.id
WHERE tc.track_id = ?
ORDER BY tc.created_at DESC
");
$stmt->execute([$track_id]);
$comments = $stmt->fetchAll();
echo json_encode(['success' => true, 'comments' => $comments]);
break;
case 'feed':
// OPTIMIZED: Using JOINs instead of correlated subqueries for better performance
// Get feed of tracks from followed users
$stmt = $pdo->prepare("
SELECT
mt.id,
mt.title,
mt.prompt,
mt.audio_url,
mt.duration,
mt.created_at,
u.name as artist_name,
u.id as artist_id,
COALESCE(like_stats.like_count, 0) as like_count,
COALESCE(comment_stats.comment_count, 0) as comment_count,
CASE WHEN user_like_stats.track_id IS NOT NULL THEN 1 ELSE 0 END as user_liked
FROM music_tracks mt
JOIN users u ON mt.user_id = u.id
JOIN user_follows uf ON mt.user_id = uf.following_id
LEFT JOIN (SELECT track_id, COUNT(*) as like_count FROM track_likes GROUP BY track_id) like_stats ON mt.id = like_stats.track_id
LEFT JOIN (SELECT track_id, COUNT(*) as comment_count FROM track_comments GROUP BY track_id) comment_stats ON mt.id = comment_stats.track_id
LEFT JOIN (SELECT track_id FROM track_likes WHERE user_id = ?) user_like_stats ON mt.id = user_like_stats.track_id
WHERE uf.follower_id = ? AND mt.status = 'complete'
ORDER BY mt.created_at DESC
LIMIT 20
");
$stmt->execute([$user_id, $user_id]);
$feed_tracks = $stmt->fetchAll();
echo json_encode(['success' => true, 'tracks' => $feed_tracks]);
break;
default:
http_response_code(400);
echo json_encode(['error' => 'Invalid action']);
break;
}
} else {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
}
?>