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_community_fixed_tracks.php
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../utils/audio_token.php';

// Start session to get current user context
session_start();

// Get parameters
$page = max(1, intval($_GET['page'] ?? 1));
$per_page = intval($_GET['per_page'] ?? 24);
$offset = ($page - 1) * $per_page;

$sort = $_GET['sort'] ?? 'latest';
$genre = $_GET['genre'] ?? 'all';
if ($genre !== 'all') {
    $genre = urldecode($genre);
    $genre = trim($genre, '"\'');
    $genre = trim($genre);
    
    // Validate genre - reject JSON objects or invalid formats
    // Check if it looks like JSON (starts with { or [)
    if (preg_match('/^[\s]*[{\[]/', $genre)) {
        // This is JSON, not a valid genre - reset to 'all'
        error_log("API: Invalid genre parameter detected (JSON): " . substr($genre, 0, 100));
        $genre = 'all';
    }
    
    // Check if it contains JSON-like structures (callBackUrl, etc.)
    if (stripos($genre, 'callBackUrl') !== false || stripos($genre, 'callback') !== false) {
        // This contains callback URL data, not a valid genre - reset to 'all'
        error_log("API: Invalid genre parameter detected (contains callback): " . substr($genre, 0, 100));
        $genre = 'all';
    }
    
    // Additional validation: genre should be a simple string, not contain JSON characters
    if (preg_match('/[{}[\]]/', $genre)) {
        // Contains JSON brackets - invalid genre
        error_log("API: Invalid genre parameter detected (contains JSON brackets): " . substr($genre, 0, 100));
        $genre = 'all';
    }
}
$time_filter = $_GET['time'] ?? 'all';
$search = $_GET['search'] ?? '';
if (!empty($search)) {
    $search = urldecode($search);
    $search = trim($search, '"\'');
    $search = trim($search);
}

$user_id = $_SESSION['user_id'] ?? null;

try {
    $pdo = getDBConnection();
    
    // Build time filter
    $time_condition = '';
    switch ($time_filter) {
        case 'today':
            $time_condition = 'AND mt.created_at >= CURDATE()';
            break;
        case 'week':
            $time_condition = 'AND mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 WEEK)';
            break;
        case 'month':
            $time_condition = 'AND mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)';
            break;
    }
    
    // Build sort order - use subqueries to match SELECT structure
    $order_by = 'mt.created_at DESC';
    switch ($sort) {
        case 'trending':
            // OPTIMIZED: Use JOIN aliases instead of subqueries
            $order_by = '(COALESCE(like_stats.like_count, 0) * 2 + COALESCE(play_stats.play_count, 0) + COALESCE(comment_stats.comment_count, 0)) DESC, mt.created_at DESC';
            break;
        case 'popular':
            // OPTIMIZED: Use JOIN aliases instead of subqueries
            $order_by = 'COALESCE(like_stats.like_count, 0) DESC, COALESCE(play_stats.play_count, 0) DESC';
            break;
        case 'random':
            $order_by = 'RAND()';
            break;
        default:
            $order_by = 'mt.created_at DESC';
    }
    
    // Build genre filter
    $genre_condition = '';
    if ($genre !== 'all' && !empty($genre)) {
        $genre_lower = strtolower(trim($genre));
        $genre_like = '%' . $genre_lower . '%';
        $genre_condition = "AND (
            LOWER(mt.genre) LIKE ?
            OR LOWER(mt.tags) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre'))) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.style'))) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.genre') AS CHAR)) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.style') AS CHAR)) LIKE ?
        )";
    }
    
    // Build search filter
    $search_condition = '';
    if (!empty($search)) {
        $search_lower = strtolower(trim($search));
        $search_param = '%' . $search_lower . '%';
        $search_condition = "AND (
            LOWER(mt.title) LIKE ? 
            OR LOWER(u.name) LIKE ?
            OR LOWER(COALESCE(mt.prompt, '')) LIKE ?
            OR LOWER(COALESCE(mt.lyrics, '')) LIKE ?
            OR LOWER(mt.genre) LIKE ?
            OR LOWER(mt.tags) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre'))) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.style'))) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.genre') AS CHAR)) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.style') AS CHAR)) LIKE ?
            OR LOWER(mt.style) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proGenre') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proGenre'))) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proSubGenre') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proSubGenre'))) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.tags') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.tags'))) LIKE ?
            OR LOWER(COALESCE(mt.mood, '')) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.mood') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.mood'))) LIKE ?
            OR LOWER(COALESCE(mt.instruments, '')) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.instruments') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.instruments'))) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument'))) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proRhythmSection') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proRhythmSection'))) LIKE ?
            OR LOWER(COALESCE(mt.energy, '')) LIKE ?
            OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.energy') AS CHAR)) LIKE ?
            OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.energy'))) LIKE ?
        )";
    }
    
    // Get total count
    $count_sql = "
        SELECT COUNT(*) as total
        FROM music_tracks mt
        INNER JOIN users u ON mt.user_id = u.id
        WHERE mt.status = 'complete'
        AND (mt.audio_url IS NOT NULL AND mt.audio_url != '' OR mt.variations_count > 0)
        AND mt.user_id IS NOT NULL
        AND u.id IS NOT NULL
        AND (mt.is_public = 1 OR mt.is_public IS NULL)
        $time_condition
        $genre_condition
        $search_condition
    ";
    
    $count_stmt = $pdo->prepare($count_sql);
    $count_params = [];
    
    if ($genre !== 'all' && !empty($genre)) {
        $genre_like = '%' . strtolower(trim($genre)) . '%';
        $count_params = array_merge($count_params, [$genre_like, $genre_like, $genre_like, $genre_like, $genre_like, $genre_like]);
    }
    
    if (!empty($search)) {
        $search_param = '%' . strtolower(trim($search)) . '%';
        $count_params = array_merge($count_params, array_fill(0, 30, $search_param));
    }
    
    $count_stmt->execute($count_params);
    $total_tracks = $count_stmt->fetchColumn();
    
    // OPTIMIZED: Using JOINs instead of correlated subqueries for better performance
    // Get tracks
    $sql = "
        SELECT 
            mt.id,
            mt.title,
            mt.audio_url,
            mt.duration,
            mt.created_at,
            mt.user_id,
            mt.genre,
            mt.tags,
            mt.image_url,
            mt.task_id,
            mt.metadata,
            mt.variations_count,
            mt.price,
            u.name as artist_name,
            u.id as artist_id,
            u.profile_image,
            COALESCE(like_stats.like_count, 0) as like_count,
            COALESCE(comment_stats.comment_count, 0) as comment_count,
            COALESCE(play_stats.play_count, 0) as play_count,
            COALESCE(share_stats.share_count, 0) as share_count,
            CASE WHEN user_like_stats.track_id IS NOT NULL THEN 1 ELSE 0 END as user_liked,
            COALESCE((SELECT COUNT(*) FROM user_follows WHERE follower_id = ? AND following_id = mt.user_id), 0) as is_following,
            CASE WHEN wishlist_stats.track_id IS NOT NULL THEN 1 ELSE 0 END as is_in_wishlist
        FROM music_tracks mt
        INNER JOIN users u ON mt.user_id = u.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, 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 share_count FROM track_shares GROUP BY track_id) share_stats ON mt.id = share_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
        LEFT JOIN (SELECT track_id FROM user_wishlist WHERE user_id = ?) wishlist_stats ON mt.id = wishlist_stats.track_id
        WHERE mt.status = 'complete'
        AND (mt.audio_url IS NOT NULL AND mt.audio_url != '' OR mt.variations_count > 0)
        AND mt.user_id IS NOT NULL
        AND u.id IS NOT NULL
        AND (mt.is_public = 1 OR mt.is_public IS NULL)
        $time_condition
        $genre_condition
        $search_condition
        ORDER BY $order_by
        LIMIT ? OFFSET ?
    ";
    
    $stmt = $pdo->prepare($sql);
    // Parameters: user_like_stats.user_id, wishlist_stats.user_id, is_following user_id (3 total)
    $params = [$user_id ?? 0, $user_id ?? 0, $user_id ?? 0];
    
    if ($genre !== 'all' && !empty($genre)) {
        $genre_like = '%' . strtolower(trim($genre)) . '%';
        $params = array_merge($params, [$genre_like, $genre_like, $genre_like, $genre_like, $genre_like, $genre_like]);
    }
    
    if (!empty($search)) {
        $search_param = '%' . strtolower(trim($search)) . '%';
        $params = array_merge($params, array_fill(0, 30, $search_param));
    }
    
    // Add LIMIT and OFFSET parameters
    $params[] = $per_page;
    $params[] = $offset;
    
    $stmt->execute($params);
    $tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Get variations for each track and prepare data
    foreach ($tracks as &$track) {
        $track['variations'] = [];
        if ($track['variations_count'] > 0) {
            try {
                $var_stmt = $pdo->prepare("
                    SELECT 
                        variation_index,
                        audio_url,
                        duration,
                        title,
                        tags,
                        image_url
                    FROM audio_variations 
                    WHERE track_id = ? 
                    ORDER BY variation_index ASC
                ");
                $var_stmt->execute([$track['id']]);
                $track['variations'] = $var_stmt->fetchAll(PDO::FETCH_ASSOC);
            } catch (Exception $e) {
                error_log('Error loading variations for track ' . $track['id'] . ': ' . $e->getMessage());
                $track['variations'] = [];
            }
        }
        
        // Resolve image URL using same logic as PHP template
        $imageUrl = $track['image_url'] ?? null;
        
        // Trim whitespace and check for empty/null values
        if ($imageUrl !== null) {
            $imageUrl = trim($imageUrl);
            if ($imageUrl === '' || $imageUrl === 'null' || $imageUrl === 'NULL') {
                $imageUrl = null;
            }
        }
        
        // If image_url exists and is not empty/null, normalize and use it
        if (!empty($imageUrl)) {
            // Normalize local paths (add leading / if missing)
            if (!str_starts_with($imageUrl, '/')) {
                $imageUrl = '/' . ltrim($imageUrl, '/');
            }
        } else {
            // Only if image_url is empty/null, try fallback sources
            if (!empty($track['metadata'])) {
                try {
                    $metadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
                    if ($metadata) {
                        if (isset($metadata['image_url']) && !empty($metadata['image_url'])) {
                            $metaImageUrl = $metadata['image_url'];
                            // Only use if it's a local path (metadata might have external URLs)
                            if (strpos($metaImageUrl, 'http://') !== 0 && strpos($metaImageUrl, 'https://') !== 0) {
                                if (!str_starts_with($metaImageUrl, '/')) {
                                    $metaImageUrl = '/' . ltrim($metaImageUrl, '/');
                                }
                                $imageUrl = $metaImageUrl;
                            }
                        } elseif (isset($metadata['cover_url']) && !empty($metadata['cover_url'])) {
                            $metaCoverUrl = $metadata['cover_url'];
                            // Only use if it's a local path (metadata might have external URLs)
                            if (strpos($metaCoverUrl, 'http://') !== 0 && strpos($metaCoverUrl, 'https://') !== 0) {
                                if (!str_starts_with($metaCoverUrl, '/')) {
                                    $metaCoverUrl = '/' . ltrim($metaCoverUrl, '/');
                                }
                                $imageUrl = $metaCoverUrl;
                            }
                        }
                    }
                } catch (Exception $e) {
                    error_log('Error parsing metadata for image URL: ' . $e->getMessage());
                }
            }
            
            // Try to find image file by task_id pattern
            if (empty($imageUrl) && !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);
                        $imageUrl = '/uploads/track_covers/' . basename($mostRecent);
                    }
                }
            }
            
            // Fallback to default only if no image found
            if (empty($imageUrl)) {
                $imageUrl = '/assets/images/default-track.jpg';
            }
        }
        
        // Set the resolved image URL
        $track['resolved_image_url'] = $imageUrl;
        
        // Use signed audio URL
        $selectedVariationIndex = null;
        if (!empty($track['metadata'])) {
            try {
                $trackMetadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
                if ($trackMetadata && isset($trackMetadata['selected_variation'])) {
                    $selectedVariationIndex = (int)$trackMetadata['selected_variation'];
                }
            } catch (Exception $e) {
                error_log('Error parsing metadata for track ' . $track['id'] . ': ' . $e->getMessage());
            }
        }
        
        try {
            if ($selectedVariationIndex !== null) {
                $track['signed_audio_url'] = getSignedAudioUrl($track['id'], $selectedVariationIndex);
            } else {
                $track['signed_audio_url'] = getSignedAudioUrl($track['id']);
            }
        } catch (Exception $e) {
            error_log('Error generating signed URL for track ' . $track['id'] . ': ' . $e->getMessage());
            $track['signed_audio_url'] = '';
        }
        
        // Ensure all values are JSON-encodable
        $track['id'] = (int)$track['id'];
        $track['duration'] = $track['duration'] ? (int)$track['duration'] : 0;
        $track['user_id'] = (int)$track['user_id'];
        $track['artist_id'] = (int)$track['artist_id'];
        $track['variations_count'] = (int)$track['variations_count'];
        $track['price'] = $track['price'] ? (float)$track['price'] : 0;
        $track['like_count'] = (int)$track['like_count'];
        $track['comment_count'] = (int)$track['comment_count'];
        $track['play_count'] = (int)$track['play_count'];
        $track['share_count'] = (int)$track['share_count'];
        $track['user_liked'] = (int)$track['user_liked'];
        $track['is_following'] = (int)$track['is_following'];
        $track['is_in_wishlist'] = (int)$track['is_in_wishlist'];
    }
    unset($track);
    
    $response = [
        'success' => true,
        'tracks' => $tracks,
        'pagination' => [
            'page' => $page,
            'per_page' => $per_page,
            'total_tracks' => (int)$total_tracks,
            'total_pages' => (int)ceil($total_tracks / $per_page),
            'has_more' => ($page * $per_page) < $total_tracks
        ]
    ];
    
    $json = json_encode($response);
    if ($json === false) {
        error_log('JSON encoding error: ' . json_last_error_msg());
        throw new Exception('Failed to encode response as JSON: ' . json_last_error_msg());
    }
    
    echo $json;
    
} catch (PDOException $e) {
    error_log('Database error in get_community_fixed_tracks.php: ' . $e->getMessage());
    error_log('SQL State: ' . $e->getCode());
    error_log('Stack trace: ' . $e->getTraceAsString());
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'Database error occurred while loading tracks'
    ]);
} catch (Exception $e) {
    error_log('Error in get_community_fixed_tracks.php: ' . $e->getMessage());
    error_log('Stack trace: ' . $e->getTraceAsString());
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'An error occurred while loading tracks'
    ]);
}
?>


CasperSecurity Mini