T.ME/BIBIL_0DAY
CasperSecurity


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/api/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/api/get_homepage_feed.php
<?php
session_start();
header('Content-Type: application/json');
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../utils/audio_token.php';

$pdo = getDBConnection();
if (!$pdo) {
    echo json_encode(['success' => false, 'message' => 'Database connection failed']);
    exit;
}

$user_id = $_SESSION['user_id'] ?? null;
$time_filter = $_GET['time'] ?? 'now'; // now, today, week, month
$scope_filter = $_GET['scope'] ?? 'global'; // global, following

// Build time filter condition - use published_at (when track was made public) instead of created_at
$time_condition = '';
switch ($time_filter) {
    case 'now':
        // "Now" means very recent - last hour
        $time_condition = 'AND COALESCE(mt.published_at, mt.created_at) >= DATE_SUB(NOW(), INTERVAL 1 HOUR)';
        break;
    case 'today':
        $time_condition = 'AND COALESCE(mt.published_at, mt.created_at) >= CURDATE()';
        break;
    case 'week':
        $time_condition = 'AND COALESCE(mt.published_at, mt.created_at) >= DATE_SUB(NOW(), INTERVAL 1 WEEK)';
        break;
    case 'month':
        $time_condition = 'AND COALESCE(mt.published_at, mt.created_at) >= DATE_SUB(NOW(), INTERVAL 1 MONTH)';
        break;
}

// Helper function to resolve track image
function resolveTrackImage($track) {
    $imageUrl = $track['image_url'] ?? null;
    
    if ($imageUrl) {
        $imageUrl = trim($imageUrl);
        if ($imageUrl === '' || strtolower($imageUrl) === 'null') {
            $imageUrl = null;
        }
    }
    
    if (!empty($imageUrl)) {
        if (!preg_match('/^https?:\/\//', $imageUrl)) {
            if (!str_starts_with($imageUrl, '/')) {
                $imageUrl = '/' . ltrim($imageUrl, '/');
            }
            return $imageUrl;
        }
        return $imageUrl;
    }
    
    if (!empty($track['metadata'])) {
        try {
            $metadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
            if ($metadata && is_array($metadata)) {
                if (isset($metadata['image_url']) && !empty($metadata['image_url'])) {
                    $metaImageUrl = $metadata['image_url'];
                    if (strpos($metaImageUrl, 'http://') !== 0 && strpos($metaImageUrl, 'https://') !== 0) {
                        if (!str_starts_with($metaImageUrl, '/')) {
                            $metaImageUrl = '/' . ltrim($metaImageUrl, '/');
                        }
                        return $metaImageUrl;
                    }
                } elseif (isset($metadata['cover_url']) && !empty($metadata['cover_url'])) {
                    $metaCoverUrl = $metadata['cover_url'];
                    if (strpos($metaCoverUrl, 'http://') !== 0 && strpos($metaCoverUrl, 'https://') !== 0) {
                        if (!str_starts_with($metaCoverUrl, '/')) {
                            $metaCoverUrl = '/' . ltrim($metaCoverUrl, '/');
                        }
                        return $metaCoverUrl;
                    }
                }
            }
        } catch (Exception $e) {
            error_log('Error parsing metadata: ' . $e->getMessage());
        }
    }
    
    if (!empty($track['task_id'])) {
        $uploadsDir = $_SERVER['DOCUMENT_ROOT'] . '/uploads/track_covers/';
        if (is_dir($uploadsDir)) {
            $pattern = $uploadsDir . "track_{$track['task_id']}_*";
            $files = glob($pattern);
            if (!empty($files)) {
                $mostRecent = end($files);
                return '/uploads/track_covers/' . basename($mostRecent);
            }
        }
    }
    
    return '/assets/images/default-track.jpg';
}

// Helper function to extract genre
function extractGenre($track) {
    if (!empty($track['genre'])) {
        return $track['genre'];
    }
    if (!empty($track['metadata'])) {
        $metadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
        if (isset($metadata['genre'])) return $metadata['genre'];
        if (isset($metadata['style'])) return $metadata['style'];
    }
    return 'Electronic';
}

try {
    $result = [
        'for_you' => [],
        'suggested_creators' => [],
        'trending' => []
    ];
    
    // Build scope condition for "For You" and "Trending"
    $scope_condition = '';
    if ($scope_filter === 'following' && $user_id) {
        $scope_condition = 'AND mt.user_id IN (SELECT following_id FROM user_follows WHERE follower_id = ?)';
    }
    
    // For You: Personalized tracks
    if ($user_id && $scope_filter === 'following') {
        $stmt = $pdo->prepare("
            SELECT 
                mt.id,
                mt.title,
                mt.audio_url,
                mt.duration,
                mt.created_at,
                mt.metadata,
                mt.genre,
                mt.image_url,
                mt.task_id,
                u.name as artist_name,
                u.id as artist_id,
                COALESCE(play_stats.play_count, 0) as play_count,
                COALESCE(like_stats.like_count, 0) as like_count,
                COALESCE(comment_stats.comment_count, 0) as comment_count,
                (SELECT COUNT(*) FROM track_likes tl WHERE tl.track_id = mt.id AND tl.user_id = ?) as user_liked
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_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
            WHERE mt.status = 'complete'
            AND mt.audio_url IS NOT NULL 
            AND mt.audio_url != ''
            AND mt.is_public = TRUE
            AND mt.user_id IN (SELECT following_id FROM user_follows WHERE follower_id = ?)
            $time_condition
            ORDER BY COALESCE(mt.published_at, mt.created_at) DESC
            LIMIT 5
        ");
        $stmt->execute([$user_id, $user_id]);
    } elseif ($user_id) {
        $stmt = $pdo->prepare("
            SELECT 
                mt.id,
                mt.title,
                mt.audio_url,
                mt.duration,
                mt.created_at,
                mt.metadata,
                mt.genre,
                mt.image_url,
                mt.task_id,
                u.name as artist_name,
                u.id as artist_id,
                COALESCE(play_stats.play_count, 0) as play_count,
                COALESCE(like_stats.like_count, 0) as like_count,
                COALESCE(comment_stats.comment_count, 0) as comment_count,
                (SELECT COUNT(*) FROM track_likes tl WHERE tl.track_id = mt.id AND tl.user_id = ?) as user_liked
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_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
            WHERE mt.status = 'complete'
            AND mt.audio_url IS NOT NULL 
            AND mt.audio_url != ''
            AND mt.is_public = TRUE
            $time_condition
            ORDER BY (COALESCE(play_stats.play_count, 0) * 2 + COALESCE(like_stats.like_count, 0)) DESC
            LIMIT 5
        ");
        $stmt->execute([$user_id]);
    } else {
        $stmt = $pdo->prepare("
            SELECT 
                mt.id,
                mt.title,
                mt.audio_url,
                mt.duration,
                mt.created_at,
                mt.metadata,
                mt.genre,
                mt.image_url,
                mt.task_id,
                u.name as artist_name,
                u.id as artist_id,
                COALESCE(play_stats.play_count, 0) as play_count,
                COALESCE(like_stats.like_count, 0) as like_count,
                COALESCE(comment_stats.comment_count, 0) as comment_count,
                0 as user_liked
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_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
            WHERE mt.status = 'complete'
            AND mt.audio_url IS NOT NULL 
            AND mt.audio_url != ''
            AND mt.is_public = TRUE
            $time_condition
            ORDER BY (COALESCE(play_stats.play_count, 0) * 2 + COALESCE(like_stats.like_count, 0)) DESC
            LIMIT 5
        ");
        $stmt->execute();
    }
    $for_you_tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Process For You tracks
    foreach ($for_you_tracks as &$track) {
        if (!empty($track['audio_url'])) {
            $track['signed_audio_url'] = getSignedAudioUrl($track['id'], $user_id);
        }
        $track['image_url'] = resolveTrackImage($track);
        $track['genre'] = extractGenre($track);
    }
    unset($track);
    $result['for_you'] = $for_you_tracks;
    
    // Helper function to format profile image URL
    function formatProfileImageUrl($profile_image, $name) {
        // If no profile image, return null (will use initials)
        if (empty($profile_image)) {
            return null;
        }
        
        // Trim whitespace
        $profile_image = trim($profile_image);
        
        // If it's already a full URL (http/https), return as is
        if (preg_match('/^https?:\/\//i', $profile_image)) {
            return $profile_image;
        }
        
        // If it starts with /, it's a valid relative path
        if (strpos($profile_image, '/') === 0) {
            return $profile_image;
        }
        
        // If it looks like a file path but doesn't start with /, try to fix it
        // Check if it contains common image extensions
        if (preg_match('/\.(jpg|jpeg|png|gif|webp)$/i', $profile_image)) {
            // If it's in uploads directory, add leading slash
            if (strpos($profile_image, 'uploads/') !== false || strpos($profile_image, 'profile') !== false) {
                // Check if it already has a directory structure
                if (strpos($profile_image, '/') === false) {
                    // It's just a filename, assume it's in uploads/profile_images/
                    return '/uploads/profile_images/' . $profile_image;
                } else {
                    // It has a path but no leading slash
                    return '/' . ltrim($profile_image, '/');
                }
            }
            
            // If it starts with a directory name (like 'ds/'), try to construct proper path
            if (preg_match('/^[a-z0-9_]+\//i', $profile_image)) {
                // This might be a malformed path, try to find it in uploads
                $filename = basename($profile_image);
                return '/uploads/profile_images/' . $filename;
            }
        }
        
        // If we can't determine a valid image path, return null (will use initials)
        return null;
    }
    
    // Suggested Creators (not affected by time/scope filters)
    if ($user_id) {
        $stmt = $pdo->prepare("
            SELECT 
                u.id,
                u.name,
                COALESCE(NULLIF(up.profile_image, ''), NULLIF(u.profile_image, ''), NULL) as profile_image,
                COALESCE(up.profile_position, 'center center') as profile_position,
                COALESCE((SELECT COUNT(*) FROM user_follows WHERE following_id = u.id), 0) as followers_count,
                COALESCE((SELECT COUNT(*) FROM music_tracks WHERE user_id = u.id AND status = 'complete'), 0) as track_count
            FROM users u
            LEFT JOIN user_profiles up ON u.id = up.user_id
            WHERE u.id NOT IN (
                SELECT COALESCE(following_id, 0) FROM user_follows WHERE follower_id = ?
            ) AND u.id != ?
            AND EXISTS (
                SELECT 1 FROM music_tracks mt 
                WHERE mt.user_id = u.id 
                AND mt.status = 'complete' 
                AND mt.is_public = TRUE
            )
            ORDER BY followers_count DESC, track_count DESC
            LIMIT 5
        ");
        $stmt->execute([$user_id, $user_id]);
    } else {
        $stmt = $pdo->prepare("
            SELECT 
                u.id,
                u.name,
                COALESCE(NULLIF(up.profile_image, ''), NULLIF(u.profile_image, ''), NULL) as profile_image,
                COALESCE(up.profile_position, 'center center') as profile_position,
                COALESCE((SELECT COUNT(*) FROM user_follows WHERE following_id = u.id), 0) as followers_count,
                COALESCE((SELECT COUNT(*) FROM music_tracks WHERE user_id = u.id AND status = 'complete'), 0) as track_count
            FROM users u
            LEFT JOIN user_profiles up ON u.id = up.user_id
            WHERE EXISTS (
                SELECT 1 FROM music_tracks mt 
                WHERE mt.user_id = u.id 
                AND mt.status = 'complete' 
                AND mt.is_public = TRUE
            )
            ORDER BY followers_count DESC, track_count DESC
            LIMIT 5
        ");
        $stmt->execute();
    }
    $suggested_creators = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Format profile images for suggested creators
    foreach ($suggested_creators as &$creator) {
        $creator['profile_image'] = formatProfileImageUrl($creator['profile_image'], $creator['name']);
    }
    unset($creator);
    
    $result['suggested_creators'] = $suggested_creators;
    
    // Trending: Popular tracks (affected by time filter, scope filter)
    if ($scope_filter === 'following' && $user_id) {
        $stmt = $pdo->prepare("
            SELECT 
                mt.id,
                mt.title,
                mt.audio_url,
                mt.duration,
                mt.created_at,
                mt.metadata,
                mt.genre,
                mt.image_url,
                mt.task_id,
                u.name as artist_name,
                u.id as artist_id,
                COALESCE(play_stats.play_count, 0) as play_count,
                COALESCE(like_stats.like_count, 0) as like_count,
                COALESCE(comment_stats.comment_count, 0) as comment_count,
                (SELECT COUNT(*) FROM track_likes tl WHERE tl.track_id = mt.id AND tl.user_id = ?) as user_liked
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_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
            WHERE mt.status = 'complete'
            AND mt.audio_url IS NOT NULL 
            AND mt.audio_url != ''
            AND mt.is_public = TRUE
            AND mt.user_id IN (SELECT following_id FROM user_follows WHERE follower_id = ?)
            $time_condition
            ORDER BY (COALESCE(play_stats.play_count, 0) * 2 + COALESCE(like_stats.like_count, 0)) DESC
            LIMIT 5
        ");
        $stmt->execute([$user_id, $user_id]);
    } elseif ($user_id) {
        $stmt = $pdo->prepare("
            SELECT 
                mt.id,
                mt.title,
                mt.audio_url,
                mt.duration,
                mt.created_at,
                mt.metadata,
                mt.genre,
                mt.image_url,
                mt.task_id,
                u.name as artist_name,
                u.id as artist_id,
                COALESCE(play_stats.play_count, 0) as play_count,
                COALESCE(like_stats.like_count, 0) as like_count,
                COALESCE(comment_stats.comment_count, 0) as comment_count,
                (SELECT COUNT(*) FROM track_likes tl WHERE tl.track_id = mt.id AND tl.user_id = ?) as user_liked
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_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
            WHERE mt.status = 'complete'
            AND mt.audio_url IS NOT NULL 
            AND mt.audio_url != ''
            AND mt.is_public = TRUE
            $time_condition
            ORDER BY (COALESCE(play_stats.play_count, 0) * 2 + COALESCE(like_stats.like_count, 0)) DESC
            LIMIT 5
        ");
        $stmt->execute([$user_id]);
    } else {
        $stmt = $pdo->prepare("
            SELECT 
                mt.id,
                mt.title,
                mt.audio_url,
                mt.duration,
                mt.created_at,
                mt.metadata,
                mt.genre,
                mt.image_url,
                mt.task_id,
                u.name as artist_name,
                u.id as artist_id,
                COALESCE(play_stats.play_count, 0) as play_count,
                COALESCE(like_stats.like_count, 0) as like_count,
                COALESCE(comment_stats.comment_count, 0) as comment_count,
                0 as user_liked
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_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
            WHERE mt.status = 'complete'
            AND mt.audio_url IS NOT NULL 
            AND mt.audio_url != ''
            AND mt.is_public = TRUE
            $time_condition
            ORDER BY (COALESCE(play_stats.play_count, 0) * 2 + COALESCE(like_stats.like_count, 0)) DESC
            LIMIT 5
        ");
        $stmt->execute();
    }
    $trending_tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Process Trending tracks
    foreach ($trending_tracks as &$track) {
        if (!empty($track['audio_url'])) {
            $track['signed_audio_url'] = getSignedAudioUrl($track['id'], $user_id);
        }
        $track['image_url'] = resolveTrackImage($track);
        $track['genre'] = extractGenre($track);
    }
    unset($track);
    $result['trending'] = $trending_tracks;
    
    echo json_encode(['success' => true, 'data' => $result]);
    
} catch (Exception $e) {
    error_log('Error fetching homepage feed: ' . $e->getMessage());
    echo json_encode(['success' => false, 'message' => 'Error fetching feed data']);
}


CasperSecurity Mini