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

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/admin/sync_missing_tracks.php
<?php
session_start();

// Check if user is admin
if (!isset($_SESSION['user_id']) || !isset($_SESSION['is_admin']) || !$_SESSION['is_admin']) {
    header('Location: ../auth/login.php');
    exit;
}

require_once '../config/database.php';

$pdo = getDBConnection();
$API_KEY = '63edba40620216c5aa2c04240ac41dbd';
$API_URL = 'https://api.api.box';

// Function to fetch all tracks from API
function fetchAllTracksFromAPI($apiKey, $apiUrl) {
    $allTracks = [];
    $page = 1;
    $perPage = 50; // API usually returns 50 per page
    
    while (true) {
        $url = $apiUrl . "/api/v1/tracks?page=$page&per_page=$perPage";
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPGET, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: $error");
        }
        
        if ($httpCode !== 200) {
            throw new Exception("API Error: HTTP $httpCode - $response");
        }
        
        $data = json_decode($response, true);
        
        if (!$data || !isset($data['data']) || empty($data['data'])) {
            break; // No more tracks
        }
        
        $allTracks = array_merge($allTracks, $data['data']);
        
        // Check if we have more pages
        if (count($data['data']) < $perPage) {
            break;
        }
        
        $page++;
        
        // Safety check to prevent infinite loops
        if ($page > 20) {
            break;
        }
    }
    
    return $allTracks;
}

// Function to create track in database
function createTrackInDatabase($pdo, $trackData) {
    try {
        // Extract track information
        $taskId = $trackData['id'] ?? $trackData['task_id'] ?? null;
        $title = $trackData['title'] ?? 'Untitled Track';
        $prompt = $trackData['prompt'] ?? '';
        $status = $trackData['status'] ?? 'processing';
        $audioUrl = $trackData['audio_url'] ?? $trackData['source_audio_url'] ?? null;
        $duration = $trackData['duration'] ?? null;
        
        if (!$taskId) {
            return ['success' => false, 'error' => 'No task_id found in track data'];
        }
        
        // Check if track already exists
        $stmt = $pdo->prepare("SELECT id FROM music_tracks WHERE task_id = ?");
        $stmt->execute([$taskId]);
        
        if ($stmt->fetch()) {
            return ['success' => false, 'error' => 'Track already exists in database'];
        }
        
        // Create the track
        $stmt = $pdo->prepare("
            INSERT INTO music_tracks 
            (user_id, task_id, title, prompt, music_type, model_version, duration, status, audio_url, metadata, created_at, updated_at) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
        ");
        
        $metadata = json_encode($trackData);
        $userId = 1; // Default admin user ID
        
        $stmt->execute([
            $userId,
            $taskId,
            $title,
            $prompt,
            'music',
            'v3',
            $duration,
            $status,
            $audioUrl,
            $metadata
        ]);
        
        return ['success' => true, 'track_id' => $taskId, 'title' => $title];
        
    } catch (Exception $e) {
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

// Handle form submission
$message = '';
$stats = [
    'total_fetched' => 0,
    'created' => 0,
    'already_exists' => 0,
    'errors' => 0
];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['sync_missing'])) {
    try {
        // Fetch all tracks from API
        $apiTracks = fetchAllTracksFromAPI($API_KEY, $API_URL);
        $stats['total_fetched'] = count($apiTracks);
        
        // Process each track
        foreach ($apiTracks as $track) {
            $result = createTrackInDatabase($pdo, $track);
            
            if ($result['success']) {
                $stats['created']++;
            } elseif (strpos($result['error'], 'already exists') !== false) {
                $stats['already_exists']++;
            } else {
                $stats['errors']++;
            }
        }
        
        $message = "Sync completed! Fetched {$stats['total_fetched']} tracks, created {$stats['created']} new tracks, {$stats['already_exists']} already existed, {$stats['errors']} errors.";
        
    } catch (Exception $e) {
        $message = "Error: " . $e->getMessage();
    }
}

// Get current database stats
$dbStats = [];
$stmt = $pdo->query("SELECT COUNT(*) as total FROM music_tracks");
$dbStats['total'] = $stmt->fetch()['total'];

$stmt = $pdo->query("SELECT COUNT(*) as complete FROM music_tracks WHERE status = 'complete'");
$dbStats['complete'] = $stmt->fetch()['complete'];

$stmt = $pdo->query("SELECT COUNT(*) as failed FROM music_tracks WHERE status = 'failed'");
$dbStats['failed'] = $stmt->fetch()['failed'];

$stmt = $pdo->query("SELECT COUNT(*) as processing FROM music_tracks WHERE status = 'processing'");
$dbStats['processing'] = $stmt->fetch()['processing'];
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sync Missing Tracks - Admin Dashboard</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <style>
        :root {
            --primary: #667eea;
            --secondary: #764ba2;
            --accent: #f093fb;
            --success: #48bb78;
            --error: #f56565;
            --warning: #ed8936;
            --bg-dark: #1a202c;
            --bg-card: #2d3748;
            --text-primary: #f7fafc;
            --text-secondary: #a0aec0;
            --border-light: rgba(255, 255, 255, 0.1);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, var(--bg-dark), #2d3748);
            color: var(--text-primary);
            min-height: 100vh;
            line-height: 1.6;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }

        .header {
            text-align: center;
            margin-bottom: 3rem;
        }

        .header h1 {
            font-size: 2.5rem;
            margin-bottom: 1rem;
            background: linear-gradient(135deg, var(--primary), var(--accent));
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }

        .header p {
            color: var(--text-secondary);
            font-size: 1.1rem;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 1.5rem;
            margin-bottom: 3rem;
        }

        .stat-card {
            background: var(--bg-card);
            border: 1px solid var(--border-light);
            border-radius: 12px;
            padding: 1.5rem;
            text-align: center;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }

        .stat-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
        }

        .stat-number {
            font-size: 2.5rem;
            font-weight: bold;
            color: var(--accent);
            margin-bottom: 0.5rem;
        }

        .stat-label {
            color: var(--text-secondary);
            font-size: 1rem;
            font-weight: 600;
        }

        .sync-section {
            background: var(--bg-card);
            border: 1px solid var(--border-light);
            border-radius: 12px;
            padding: 2rem;
            margin-bottom: 2rem;
        }

        .sync-section h2 {
            color: var(--text-primary);
            margin-bottom: 1rem;
            font-size: 1.5rem;
        }

        .sync-info {
            background: rgba(255, 255, 255, 0.05);
            border-radius: 8px;
            padding: 1.5rem;
            margin-bottom: 1.5rem;
        }

        .sync-info h3 {
            color: var(--accent);
            margin-bottom: 1rem;
        }

        .sync-info ul {
            list-style: none;
            padding: 0;
        }

        .sync-info li {
            padding: 0.5rem 0;
            border-bottom: 1px solid var(--border-light);
            color: var(--text-secondary);
        }

        .sync-info li:last-child {
            border-bottom: none;
        }

        .sync-info li:before {
            content: "✅ ";
            color: var(--success);
        }

        .sync-button {
            background: linear-gradient(135deg, var(--primary), var(--secondary));
            color: white;
            border: none;
            padding: 1rem 2rem;
            border-radius: 8px;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            display: inline-flex;
            align-items: center;
            gap: 0.5rem;
        }

        .sync-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
        }

        .message {
            padding: 1rem;
            border-radius: 8px;
            margin-bottom: 1.5rem;
            font-weight: 600;
        }

        .message.success {
            background: rgba(72, 187, 120, 0.2);
            border: 1px solid var(--success);
            color: var(--success);
        }

        .message.error {
            background: rgba(245, 101, 101, 0.2);
            border: 1px solid var(--error);
            color: var(--error);
        }

        .back-link {
            display: inline-flex;
            align-items: center;
            gap: 0.5rem;
            color: var(--accent);
            text-decoration: none;
            font-weight: 600;
            transition: color 0.3s ease;
        }

        .back-link:hover {
            color: var(--primary);
        }

        @media (max-width: 768px) {
            .container {
                padding: 1rem;
            }
            
            .header h1 {
                font-size: 2rem;
            }
            
            .stats-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1><i class="fas fa-sync-alt"></i> Sync Missing Tracks</h1>
            <p>Fetch all your tracks from the API and sync them to your database</p>
        </div>

        <?php if ($message): ?>
            <div class="message <?= strpos($message, 'Error') !== false ? 'error' : 'success' ?>">
                <?= htmlspecialchars($message) ?>
            </div>
        <?php endif; ?>

        <!-- Current Database Stats -->
        <div class="stats-grid">
            <div class="stat-card">
                <div class="stat-number"><?= $dbStats['total'] ?></div>
                <div class="stat-label">Total Tracks in Database</div>
            </div>
            <div class="stat-card">
                <div class="stat-number"><?= $dbStats['complete'] ?></div>
                <div class="stat-label">Complete Tracks</div>
            </div>
            <div class="stat-card">
                <div class="stat-number"><?= $dbStats['failed'] ?></div>
                <div class="stat-label">Failed Tracks</div>
            </div>
            <div class="stat-card">
                <div class="stat-number"><?= $dbStats['processing'] ?></div>
                <div class="stat-label">Processing Tracks</div>
            </div>
        </div>

        <!-- Sync Section -->
        <div class="sync-section">
            <h2><i class="fas fa-download"></i> Sync Missing Tracks</h2>
            
            <div class="sync-info">
                <h3>What This Will Do:</h3>
                <ul>
                    <li>Connect to your API.box account using your API key</li>
                    <li>Fetch ALL tracks from your API dashboard (81 tracks)</li>
                    <li>Compare with your database (46 tracks)</li>
                    <li>Create missing tracks in your database</li>
                    <li>Preserve all metadata and audio URLs</li>
                    <li>Set proper status (complete/failed/processing)</li>
                </ul>
            </div>

            <form method="POST">
                <button type="submit" name="sync_missing" class="sync-button">
                    <i class="fas fa-sync-alt"></i>
                    Sync Missing Tracks from API
                </button>
            </form>
        </div>

        <!-- Sync Results -->
        <?php if ($stats['total_fetched'] > 0): ?>
        <div class="sync-section">
            <h2><i class="fas fa-chart-bar"></i> Sync Results</h2>
            
            <div class="stats-grid">
                <div class="stat-card">
                    <div class="stat-number"><?= $stats['total_fetched'] ?></div>
                    <div class="stat-label">Tracks Fetched from API</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number"><?= $stats['created'] ?></div>
                    <div class="stat-label">New Tracks Created</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number"><?= $stats['already_exists'] ?></div>
                    <div class="stat-label">Already Existed</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number"><?= $stats['errors'] ?></div>
                    <div class="stat-label">Errors</div>
                </div>
            </div>
        </div>
        <?php endif; ?>

        <div style="text-align: center; margin-top: 3rem;">
            <a href="index.php" class="back-link">
                <i class="fas fa-arrow-left"></i>
                Back to Admin Dashboard
            </a>
        </div>
    </div>
</body>
</html> 

CasperSecurity Mini