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

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/api_track_management.php
<?php
session_start();
require_once 'config/database.php';

header('Content-Type: application/json');

// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Not authenticated']);
    exit;
}

$user_id = $_SESSION['user_id'];
$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? '';

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

try {
    switch ($action) {
        case 'duplicate':
            $track_id = $input['track_id'] ?? 0;
            
            // Verify track ownership
            $stmt = $pdo->prepare("SELECT * FROM music_tracks WHERE id = ? AND user_id = ?");
            $stmt->execute([$track_id, $user_id]);
            $original_track = $stmt->fetch();
            
            if (!$original_track) {
                echo json_encode(['success' => false, 'message' => 'Track not found or access denied']);
                break;
            }
            
            // Create duplicate track
            $stmt = $pdo->prepare("
                INSERT INTO music_tracks (
                    user_id, title, prompt, model_name, status, price, 
                    duration, metadata, is_public, created_at
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
            ");
            
            $duplicate_title = $original_track['title'] . ' (Copy)';
            $stmt->execute([
                $user_id,
                $duplicate_title,
                $original_track['prompt'],
                $original_track['model_name'],
                'pending', // New duplicate starts as pending
                $original_track['price'],
                $original_track['duration'],
                $original_track['metadata'],
                0 // Start as private
            ]);
            
            echo json_encode([
                'success' => true, 
                'message' => 'Track duplicated successfully',
                'new_track_id' => $pdo->lastInsertId()
            ]);
            break;
            
        case 'toggle_visibility':
            $track_id = $input['track_id'] ?? 0;
            $visibility = $input['visibility'] ?? 0;
            
            error_log("Toggle visibility request: track_id=$track_id, visibility=$visibility, user_id=$user_id");
            
            // Verify track ownership and get current state
            $stmt = $pdo->prepare("SELECT id, is_public, published_at FROM music_tracks WHERE id = ? AND user_id = ?");
            $stmt->execute([$track_id, $user_id]);
            $track = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$track) {
                error_log("Track not found or access denied: track_id=$track_id, user_id=$user_id");
                echo json_encode(['success' => false, 'message' => 'Track not found or access denied']);
                break;
            }
            
            // Determine if we need to set published_at (first time going public)
            $set_published_at = false;
            if ($visibility == 1 && $track['is_public'] == 0 && empty($track['published_at'])) {
                $set_published_at = true;
            }
            
            // Update visibility
            if ($set_published_at) {
                // First time publishing - set permanent published_at timestamp
                $stmt = $pdo->prepare("UPDATE music_tracks SET is_public = ?, published_at = NOW(), updated_at = NOW() WHERE id = ? AND user_id = ?");
                $result = $stmt->execute([$visibility, $track_id, $user_id]);
            } else {
                // Not first publish - don't touch published_at
                $stmt = $pdo->prepare("UPDATE music_tracks SET is_public = ?, updated_at = NOW() WHERE id = ? AND user_id = ?");
                $result = $stmt->execute([$visibility, $track_id, $user_id]);
            }
            
            if (!$result) {
                error_log("Failed to update track visibility: " . implode(", ", $stmt->errorInfo()));
                echo json_encode(['success' => false, 'message' => 'Database update failed']);
                break;
            }
            
            $status = $visibility ? 'public' : 'private';
            error_log("Successfully updated track visibility: track_id=$track_id, new_status=$status, published_at_set=" . ($set_published_at ? 'yes' : 'no'));
            echo json_encode([
                'success' => true, 
                'message' => "Track is now $status"
            ]);
            break;
            
        case 'delete':
            $track_id = $input['track_id'] ?? 0;
            
            // Check if user is admin
            if (!isset($_SESSION['is_admin']) || !$_SESSION['is_admin']) {
                echo json_encode(['success' => false, 'message' => 'Admin access required to delete tracks']);
                break;
            }
            
            // Verify track exists (admins can delete any track)
            $stmt = $pdo->prepare("SELECT audio_url, user_id FROM music_tracks WHERE id = ?");
            $stmt->execute([$track_id]);
            $track = $stmt->fetch();
            
            if (!$track) {
                echo json_encode(['success' => false, 'message' => 'Track not found']);
                break;
            }
            
            // Delete related data first (foreign key constraints)
            $pdo->prepare("DELETE FROM track_likes WHERE track_id = ?")->execute([$track_id]);
            $pdo->prepare("DELETE FROM track_comments WHERE track_id = ?")->execute([$track_id]);
            $pdo->prepare("DELETE FROM track_plays WHERE track_id = ?")->execute([$track_id]);
            $pdo->prepare("DELETE FROM track_views WHERE track_id = ?")->execute([$track_id]);
            $pdo->prepare("DELETE FROM sales WHERE track_id = ?")->execute([$track_id]);
            
            // Delete the track (admins can delete any track)
            $stmt = $pdo->prepare("DELETE FROM music_tracks WHERE id = ?");
            $stmt->execute([$track_id]);
            
            // Optionally delete audio file (be careful with this)
            if (!empty($track['audio_url']) && file_exists($track['audio_url'])) {
                // unlink($track['audio_url']); // Uncomment if you want to delete files
            }
            
            echo json_encode([
                'success' => true, 
                'message' => 'Track deleted successfully by admin'
            ]);
            break;
            
        case 'bulk_action':
            $track_ids = $input['track_ids'] ?? [];
            $bulk_action = $input['bulk_action'] ?? '';
            
            if (empty($track_ids) || !is_array($track_ids)) {
                echo json_encode(['success' => false, 'message' => 'No tracks selected']);
                break;
            }
            
            // Verify all tracks belong to user
            $placeholders = str_repeat('?,', count($track_ids) - 1) . '?';
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM music_tracks WHERE id IN ($placeholders) AND user_id = ?");
            $params = array_merge($track_ids, [$user_id]);
            $stmt->execute($params);
            
            if ($stmt->fetchColumn() != count($track_ids)) {
                echo json_encode(['success' => false, 'message' => 'Some tracks not found or access denied']);
                break;
            }
            
            switch ($bulk_action) {
                case 'make_public':
                    // First, set published_at for tracks that don't have it yet (first time going public)
                    $stmt = $pdo->prepare("UPDATE music_tracks SET is_public = 1, published_at = NOW(), updated_at = NOW() WHERE id IN ($placeholders) AND user_id = ? AND (is_public = 0 OR published_at IS NULL)");
                    $stmt->execute($params);
                    
                    // Then, update tracks that are already public but might need is_public set
                    $stmt = $pdo->prepare("UPDATE music_tracks SET is_public = 1, updated_at = NOW() WHERE id IN ($placeholders) AND user_id = ? AND is_public = 0 AND published_at IS NOT NULL");
                    $stmt->execute($params);
                    
                    echo json_encode(['success' => true, 'message' => 'Tracks made public']);
                    break;
                    
                case 'make_private':
                    $stmt = $pdo->prepare("UPDATE music_tracks SET is_public = 0 WHERE id IN ($placeholders) AND user_id = ?");
                    $stmt->execute($params);
                    echo json_encode(['success' => true, 'message' => 'Tracks made private']);
                    break;
                    
                case 'update_price':
                    $new_price = floatval($input['new_price'] ?? 0);
                    $stmt = $pdo->prepare("UPDATE music_tracks SET price = ? WHERE id IN ($placeholders) AND user_id = ?");
                    $params = array_merge([$new_price], $track_ids, [$user_id]);
                    $stmt->execute($params);
                    echo json_encode(['success' => true, 'message' => "Price updated to $" . number_format($new_price, 2)]);
                    break;
                    
                default:
                    echo json_encode(['success' => false, 'message' => 'Invalid bulk action']);
            }
            break;
            
        case 'update_metadata':
            $track_id = $input['track_id'] ?? 0;
            $metadata = $input['metadata'] ?? [];
            
            // Verify track ownership
            $stmt = $pdo->prepare("SELECT id FROM music_tracks WHERE id = ? AND user_id = ?");
            $stmt->execute([$track_id, $user_id]);
            
            if (!$stmt->fetch()) {
                echo json_encode(['success' => false, 'message' => 'Track not found or access denied']);
                break;
            }
            
            // Update metadata
            $stmt = $pdo->prepare("UPDATE music_tracks SET metadata = ? WHERE id = ? AND user_id = ?");
            $stmt->execute([json_encode($metadata), $track_id, $user_id]);
            
            echo json_encode([
                'success' => true, 
                'message' => 'Track metadata updated successfully'
            ]);
            break;
            
        case 'generate_share_token':
            require_once __DIR__ . '/utils/share_token.php';
            
            $track_id = $input['track_id'] ?? 0;
            $expires_in = $input['expires_in'] ?? SHARE_TOKEN_DEFAULT_EXPIRY; // Default 1 hour
            
            // Verify track ownership
            $stmt = $pdo->prepare("SELECT id, is_public FROM music_tracks WHERE id = ? AND user_id = ?");
            $stmt->execute([$track_id, $user_id]);
            $track = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$track) {
                echo json_encode(['success' => false, 'message' => 'Track not found or access denied']);
                break;
            }
            
            // If track is public, return regular URL (no token needed)
            if ($track['is_public'] == 1) {
                $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
                $host = $_SERVER['HTTP_HOST'] ?? 'soundstudiopro.com';
                $baseUrl = $protocol . '://' . $host;
                $share_url = $baseUrl . '/track.php?id=' . $track_id;
                
                echo json_encode([
                    'success' => true,
                    'share_url' => $share_url,
                    'is_public' => 1,
                    'message' => 'Track is public - using regular link'
                ]);
                break;
            }
            
            // Generate or retrieve share token for private tracks
            $tokenData = getOrCreateShareToken($track_id, $user_id, $expires_in);
            
            if (!$tokenData) {
                echo json_encode(['success' => false, 'message' => 'Failed to generate share token']);
                break;
            }
            
            // Generate shareable URL
            $share_url = getShareableUrl($track_id, $tokenData['token']);
            
            echo json_encode([
                'success' => true,
                'share_token' => $tokenData['token'],
                'share_url' => $share_url,
                'expires' => $tokenData['expires'],
                'expires_in' => $expires_in,
                'is_public' => 0
            ]);
            break;
            
        case 'revoke_share_token':
            require_once __DIR__ . '/utils/share_token.php';
            
            $track_id = $input['track_id'] ?? 0;
            
            // Verify track ownership
            $stmt = $pdo->prepare("SELECT id FROM music_tracks WHERE id = ? AND user_id = ?");
            $stmt->execute([$track_id, $user_id]);
            
            if (!$stmt->fetch()) {
                echo json_encode(['success' => false, 'message' => 'Track not found or access denied']);
                break;
            }
            
            // Revoke share token
            $result = revokeShareToken($track_id, $user_id);
            
            echo json_encode([
                'success' => $result,
                'message' => $result ? 'Share link revoked successfully' : 'Failed to revoke share link'
            ]);
            break;
            
        default:
            echo json_encode(['success' => false, 'message' => 'Invalid action']);
    }
    
} catch (Exception $e) {
    error_log("Track management API error: " . $e->getMessage());
    echo json_encode([
        'success' => false, 
        'message' => 'An error occurred while processing your request'
    ]);
}
?> 

CasperSecurity Mini