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

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/admin_includes/tracks.php
<?php
// Track Management Tab
// This file handles all track management functionality

// Get filter parameters
$status_filter = $_GET['status'] ?? 'all';
$user_filter = $_GET['user'] ?? 'all';
$search_term = $_GET['search'] ?? '';
$page = max(1, intval($_GET['page'] ?? 1));
$per_page = 50;
$offset = ($page - 1) * $per_page;

// Build WHERE clause
$where_conditions = [];
$params = [];

if ($status_filter !== 'all') {
    $where_conditions[] = "mt.status = ?";
    $params[] = $status_filter;
}

if ($user_filter !== 'all') {
    if ($user_filter === 'orphaned') {
        $where_conditions[] = "(mt.user_id IS NULL OR mt.user_id = 0)";
    } else {
        $where_conditions[] = "mt.user_id = ?";
        $params[] = $user_filter;
    }
}

if (!empty($search_term)) {
    $where_conditions[] = "(mt.title LIKE ? OR mt.prompt LIKE ? OR u.name LIKE ?)";
    $search_param = "%$search_term%";
    $params[] = $search_param;
    $params[] = $search_param;
    $params[] = $search_param;
}

$where_clause = !empty($where_conditions) ? "WHERE " . implode(" AND ", $where_conditions) : "";

// Save original params for count query (before adding LIMIT/OFFSET)
$count_params = $params;

// Get tracks for management with enhanced data
try {
    $stmt = $pdo->prepare("
        SELECT 
            mt.*,
            u.name as user_name,
            u.email as user_email,
            u.plan as user_plan,
            CASE 
                WHEN mt.user_id IS NULL OR mt.user_id = 0 THEN 'Orphaned'
                ELSE u.name
            END as display_name,
            CASE 
                WHEN mt.user_id IS NULL OR mt.user_id = 0 THEN 'orphaned@system.com'
                ELSE u.email
            END as display_email,
            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(view_stats.view_count, 0) as view_count
        FROM music_tracks mt
        LEFT 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 view_count FROM track_views GROUP BY track_id) view_stats ON mt.id = view_stats.track_id
        $where_clause
        ORDER BY mt.created_at DESC
        LIMIT ? OFFSET ?
    ");
    // Add LIMIT and OFFSET parameters
    $params[] = $per_page;
    $params[] = $offset;
    $stmt->execute($params);
    $tracks = $stmt->fetchAll();
} catch (Exception $e) {
    $tracks = [];
    error_log("Admin tracks query error: " . $e->getMessage());
}

// Get total count for pagination (using original params without LIMIT/OFFSET)
$count_stmt = $pdo->prepare("
    SELECT COUNT(*) as total
    FROM music_tracks mt
    LEFT JOIN users u ON mt.user_id = u.id
    $where_clause
");
$count_stmt->execute($count_params);
$total_tracks = $count_stmt->fetch()['total'];
$total_pages = ceil($total_tracks / $per_page);

// Get track statistics
$track_stats = $pdo->query("
    SELECT 
        COUNT(*) as total_tracks,
        COUNT(CASE WHEN status = 'complete' THEN 1 END) as completed,
        COUNT(CASE WHEN status = 'processing' THEN 1 END) as processing,
        COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed,
        COUNT(CASE WHEN user_id IS NULL OR user_id = 0 THEN 1 END) as orphaned,
        COUNT(CASE WHEN audio_url IS NOT NULL AND audio_url != '' THEN 1 END) as with_audio,
        COUNT(CASE WHEN audio_url LIKE '%apiboxfiles.erweima.ai%' THEN 1 END) as cdn_tracks,
        AVG(duration) as avg_duration,
        SUM(duration) as total_duration
    FROM music_tracks
")->fetch();

// Get all users for assignment
$users = $pdo->query("
    SELECT id, name, email, plan, credits, is_admin
    FROM users 
    ORDER BY name ASC
")->fetchAll();
?>

<!-- Track Management -->
<div class="section-header">
    <h2><i class="fas fa-music"></i> Track Management</h2>
    <p>Comprehensive track management with user assignment and transfer capabilities</p>
    

    <div style="margin-top: 10px; display: flex; gap: 1rem; flex-wrap: wrap;">
        <a href="/fix_track_titles.php" class="btn btn-primary" style="text-decoration: none;">
            <i class="fas fa-edit"></i> Fix Track Titles
        </a>
        <a href="/fix_external_audio_urls.php" class="btn btn-primary" style="text-decoration: none;">
            <i class="fas fa-link"></i> Fix External Audio URLs
        </a>
        <button class="btn btn-warning" onclick="fixAllFailedTracks()" style="text-decoration: none;">
            <i class="fas fa-redo"></i> Fix All Failed Tracks (<?= number_format($track_stats['failed']) ?>)
        </button>
        <button class="btn btn-info" onclick="showFailedTracksAnalysis()" style="text-decoration: none;">
            <i class="fas fa-chart-bar"></i> Failed Tracks Analysis
        </button>
        <button class="btn btn-success" onclick="assignAllOrphanedTracks()" style="text-decoration: none;">
            <i class="fas fa-users"></i> Assign All Orphaned (<?= number_format($track_stats['orphaned']) ?>)
        </button>
    </div>
</div>

<!-- Track Statistics Cards -->
<div class="stats-grid" style="margin-bottom: 3rem;">
    <div class="stat-card">
        <div class="stat-number"><?= number_format($track_stats['total_tracks']) ?></div>
        <div class="stat-label">Total Tracks</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($track_stats['completed']) ?></div>
        <div class="stat-label">Completed</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($track_stats['orphaned']) ?></div>
        <div class="stat-label">Orphaned</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($track_stats['with_audio']) ?></div>
        <div class="stat-label">With Audio</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($track_stats['processing']) ?></div>
        <div class="stat-label">Processing</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($track_stats['failed']) ?></div>
        <div class="stat-label">Failed</div>
    </div>
</div>

<!-- Filters and Search -->
<div class="filters-section" style="background: rgba(255, 255, 255, 0.05); border-radius: 12px; padding: 2rem; margin-bottom: 2rem;">
    <h3 style="margin-top: 0; color: white;">🔍 Filters & Search</h3>
    
    <form method="GET" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; align-items: end;">
        <input type="hidden" name="tab" value="tracks">
        
        <div>
            <label style="display: block; color: #a0aec0; margin-bottom: 0.5rem;">Status Filter</label>
            <select name="status" style="width: 100%; padding: 0.8rem; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 8px; background: rgba(255, 255, 255, 0.05); color: white;">
                <option value="all" <?= $status_filter === 'all' ? 'selected' : '' ?>>All Statuses</option>
                <option value="complete" <?= $status_filter === 'complete' ? 'selected' : '' ?>>Completed</option>
                <option value="processing" <?= $status_filter === 'processing' ? 'selected' : '' ?>>Processing</option>
                <option value="failed" <?= $status_filter === 'failed' ? 'selected' : '' ?>>Failed</option>
            </select>
        </div>
        
        <div>
            <label style="display: block; color: #a0aec0; margin-bottom: 0.5rem;">User Filter</label>
            <select name="user" style="width: 100%; padding: 0.8rem; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 8px; background: rgba(255, 255, 255, 0.05); color: white;">
                <option value="all" <?= $user_filter === 'all' ? 'selected' : '' ?>>All Users</option>
                <option value="orphaned" <?= $user_filter === 'orphaned' ? 'selected' : '' ?>>Orphaned Tracks</option>
                <?php foreach ($users as $user): ?>
                <option value="<?= $user['id'] ?>" <?= $user_filter == $user['id'] ? 'selected' : '' ?>>
                    <?= htmlspecialchars($user['name']) ?> (<?= $user['plan'] ?>)
                </option>
                <?php endforeach; ?>
            </select>
        </div>
        
        <div>
            <label style="display: block; color: #a0aec0; margin-bottom: 0.5rem;">Search</label>
            <input type="text" name="search" value="<?= htmlspecialchars($search_term) ?>" 
                   placeholder="Search tracks..." 
                   style="width: 100%; padding: 0.8rem; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 8px; background: rgba(255, 255, 255, 0.05); color: white;">
        </div>
        
        <div>
            <button type="submit" class="btn btn-primary" style="width: 100%;">
                <i class="fas fa-search"></i> Apply Filters
            </button>
        </div>
    </form>
</div>

<!-- Results Info -->
<div style="margin-bottom: 2rem; color: #a0aec0;">
    Showing <?= $offset + 1 ?>-<?= min($offset + $per_page, $total_tracks) ?> of <?= number_format($total_tracks) ?> tracks
    <?php if (!empty($search_term) || $status_filter !== 'all' || $user_filter !== 'all'): ?>
    <a href="?tab=tracks" class="btn btn-sm btn-secondary" style="margin-left: 1rem;">
        <i class="fas fa-times"></i> Clear Filters
    </a>
    <?php endif; ?>
</div>

<input type="text" id="trackSearch" placeholder="Search tracks by title, user, or status..." class="search-input">

<table class="data-table">
    <thead>
        <tr>
            <th>Track</th>
            <th>User</th>
            <th>Status</th>
            <th>Audio</th>
            <th>Social Stats</th>
            <th>Created</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($tracks as $track): ?>
        <tr data-track-id="<?= $track['id'] ?>">
            <td>
                <div style="display: flex; align-items: center; gap: 1rem;">
                    <div style="width: 50px; height: 50px; background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white;">
                        <i class="fas fa-music"></i>
                    </div>
                    <div>
                        <div style="font-weight: 600; color: white;"><?= htmlspecialchars($track['title'] ?? 'Untitled') ?></div>
                        <div style="font-size: 1.2rem; color: #a0aec0;">ID: <?= $track['id'] ?></div>
                        <?php if (!empty($track['prompt'])): ?>
                        <div style="font-size: 1.2rem; color: #a0aec0;"><?= htmlspecialchars(substr($track['prompt'], 0, 50)) ?>...</div>
                        <?php endif; ?>
                        <?php if (isset($track['music_type'])): ?>
                        <div style="font-size: 1.2rem; color: #a0aec0;">Type: <?= htmlspecialchars($track['music_type']) ?></div>
                        <?php endif; ?>
                    </div>
                </div>
            </td>
            <td>
                <?php if ($track['user_name']): ?>
                <div>
                    <div style="font-weight: 600; color: white;"><?= htmlspecialchars($track['display_name']) ?></div>
                    <div style="font-size: 1.2rem; color: #a0aec0;"><?= htmlspecialchars($track['display_email']) ?></div>
                    <div style="font-size: 1.2rem; color: #a0aec0;"><?= ucfirst($track['user_plan'] ?? 'free') ?></div>
                </div>
                <?php else: ?>
                <span style="color: #f56565; font-weight: bold;">⚠️ Orphaned</span>
                <?php endif; ?>
            </td>
            <td>
                <span class="status-badge status-<?= $track['status'] ?>">
                    <?= ucfirst($track['status']) ?>
                </span>
                <?php if ($track['duration']): ?>
                <div style="font-size: 1.2rem; color: #a0aec0; margin-top: 0.5rem;">
                    <?= floor($track['duration'] / 60) ?>m <?= $track['duration'] % 60 ?>s
                </div>
                <?php endif; ?>
            </td>
            <td>
                <?php if ($track['audio_url']): ?>
                    <div style="display: flex; align-items: center; gap: 0.5rem;">
                        <i class="fas fa-music" style="color: #48bb78;"></i>
                        <span style="color: #48bb78;">Available</span>
                        <?php if (strpos($track['audio_url'], 'apiboxfiles.erweima.ai') !== false): ?>
                            <i class="fas fa-cloud" style="color: #667eea;" title="CDN Track"></i>
                        <?php endif; ?>
                    </div>
                    <button class="btn btn-sm btn-secondary" onclick="playTrack('<?= htmlspecialchars($track['audio_url']) ?>', '<?= htmlspecialchars($track['title'] ?? 'Untitled') ?>')" style="margin-top: 0.5rem;">
                        <i class="fas fa-play"></i> Play
                    </button>
                <?php else: ?>
                    <span style="color: #f56565;">No Audio</span>
                <?php endif; ?>
            </td>
            <td>
                <div style="display: flex; flex-direction: column; gap: 0.2rem; font-size: 1.2rem;">
                    <span><i class="fas fa-heart" style="color: #e53e3e;"></i> <?= number_format($track['like_count']) ?></span>
                    <span><i class="fas fa-comment" style="color: #3182ce;"></i> <?= number_format($track['comment_count']) ?></span>
                    <span><i class="fas fa-play" style="color: #38a169;"></i> <?= number_format($track['play_count']) ?></span>
                    <span><i class="fas fa-eye" style="color: #d69e2e;"></i> <?= number_format($track['view_count']) ?></span>
                </div>
            </td>
            <td><?= date('M j, Y H:i', strtotime($track['created_at'])) ?></td>
            <td>
                <div style="display: flex; flex-direction: column; gap: 0.5rem;">
                    <select class="user-transfer" data-track-id="<?= $track['id'] ?>" style="background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); color: white; padding: 0.5rem; border-radius: 4px; font-size: 1.2rem;">
                        <option value="">Transfer to...</option>
                        <?php foreach ($users as $user): ?>
                        <option value="<?= $user['id'] ?>"><?= htmlspecialchars($user['name']) ?> (<?= $user['plan'] ?>)</option>
                        <?php endforeach; ?>
                    </select>
                    
                    <div style="display: flex; gap: 0.5rem;">
                        <button class="btn btn-sm btn-primary" onclick="editTrack(<?= $track['id'] ?>)">
                            <i class="fas fa-edit"></i>
                        </button>
                        <button class="btn btn-sm btn-warning" onclick="retryTrack(<?= $track['id'] ?>)">
                            <i class="fas fa-redo"></i>
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="deleteTrack(<?= $track['id'] ?>)">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                </div>
            </td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>

<!-- Pagination -->
<?php if ($total_pages > 1): ?>
<div class="pagination-container" style="margin-top: 3rem; text-align: center;">
    <div class="pagination-controls" style="display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap;">
        <?php if ($page > 1): ?>
            <a href="?tab=tracks&page=1&status=<?= $status_filter ?>&user=<?= $user_filter ?>&search=<?= urlencode($search_term) ?>" class="btn btn-secondary">
                <i class="fas fa-angle-double-left"></i> First
            </a>
            <a href="?tab=tracks&page=<?= $page - 1 ?>&status=<?= $status_filter ?>&user=<?= $user_filter ?>&search=<?= urlencode($search_term) ?>" class="btn btn-secondary">
                <i class="fas fa-angle-left"></i> Previous
            </a>
        <?php endif; ?>
        
        <?php
        $start_page = max(1, $page - 2);
        $end_page = min($total_pages, $page + 2);
        
        for ($i = $start_page; $i <= $end_page; $i++):
        ?>
            <a href="?tab=tracks&page=<?= $i ?>&status=<?= $status_filter ?>&user=<?= $user_filter ?>&search=<?= urlencode($search_term) ?>" 
               class="btn <?= $i == $page ? 'btn-primary' : 'btn-secondary' ?>">
                <?= $i ?>
            </a>
        <?php endfor; ?>
        
        <?php if ($page < $total_pages): ?>
            <a href="?tab=tracks&page=<?= $page + 1 ?>&status=<?= $status_filter ?>&user=<?= $user_filter ?>&search=<?= urlencode($search_term) ?>" class="btn btn-secondary">
                Next <i class="fas fa-angle-right"></i>
            </a>
            <a href="?tab=tracks&page=<?= $total_pages ?>&status=<?= $status_filter ?>&user=<?= $user_filter ?>&search=<?= urlencode($search_term) ?>" class="btn btn-secondary">
                Last <i class="fas fa-angle-double-right"></i>
            </a>
        <?php endif; ?>
    </div>
</div>
<?php endif; ?>

<script>
// Play track in global player
function playTrack(audioUrl, title) {
    if (typeof window.playTrackWithGlobalPlayer === 'function') {
        window.playTrackWithGlobalPlayer(audioUrl, title, 'Admin Track');
    } else if (typeof window.globalPlayer !== 'undefined' && window.globalPlayer.playTrack) {
        window.globalPlayer.playTrack(audioUrl, title, 'Admin Track');
    } else {
        alert('Global player not available');
    }
}

// Transfer track to different user
document.querySelectorAll('.user-transfer').forEach(select => {
    select.addEventListener('change', function() {
        if (this.value) {
            const trackId = this.getAttribute('data-track-id');
            const userId = this.value;
            
            if (confirm('Transfer this track to the selected user?')) {
                transferTrack(trackId, userId, this);
            } else {
                this.value = ''; // Reset selection
            }
        }
    });
});

function transferTrack(trackId, userId, select) {
    fetch('/admin_api.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            action: 'transfer_track',
            track_id: trackId,
            user_id: userId
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // Update the user display in the table
            const row = select.closest('tr');
            const userCell = row.querySelector('td:nth-child(2)');
            const selectedUser = select.options[select.selectedIndex].text;
            
            userCell.innerHTML = `
                <div>
                    <div style="font-weight: 600; color: white;">${selectedUser}</div>
                    <div style="font-size: 1.2rem; color: #a0aec0;">Transferred</div>
                </div>
            `;
            
            select.value = ''; // Reset selection
            showNotification('Track transferred successfully!', 'success');
        } else {
            alert('Error: ' + data.message);
            select.value = ''; // Reset selection
        }
    })
    .catch(error => {
        console.error('Error:', error);
        alert('Failed to transfer track');
        select.value = ''; // Reset selection
    });
}

// Edit track
function editTrack(trackId) {
    // Open edit modal or redirect to edit page
    window.open(`/edit_track.php?id=${trackId}`, '_blank');
}

// Retry failed track
function retryTrack(trackId) {
    if (confirm('Retry this track?')) {
        fetch('/admin_api.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                action: 'retry_track',
                track_id: trackId
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                location.reload();
            } else {
                alert('Error: ' + data.message);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            alert('Failed to retry track');
        });
    }
}

// Delete track
function deleteTrack(trackId) {
    if (confirm('Are you sure you want to delete this track? This action cannot be undone.')) {
        fetch('/admin_api.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                action: 'delete_track',
                track_id: trackId
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                const row = document.querySelector(`[data-track-id="${trackId}"]`);
                row.style.background = 'rgba(245, 101, 101, 0.1)';
                setTimeout(() => {
                    row.remove();
                }, 1000);
            } else {
                alert('Error: ' + data.message);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            alert('Failed to delete track');
        });
    }
}

// Assign all orphaned tracks to admin
function assignAllOrphanedTracks() {
    if (confirm('Assign all orphaned tracks to admin user? This will organize all tracks properly.')) {
        fetch('/admin_api.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                action: 'assign_all_orphaned_tracks'
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert(`Successfully assigned ${data.assigned_count} tracks to admin`);
                location.reload();
            } else {
                alert('Error: ' + data.message);
            }
        })
        .catch(error => {
            console.error('Error:', error);
            alert('Failed to assign tracks');
        });
    }
}

// Search functionality
document.getElementById('trackSearch').addEventListener('input', function(e) {
    const searchTerm = e.target.value.toLowerCase();
    const rows = document.querySelectorAll('.data-table tbody tr');
    
    rows.forEach(row => {
        const title = row.querySelector('td:first-child').textContent.toLowerCase();
        const user = row.querySelector('td:nth-child(2)').textContent.toLowerCase();
        const status = row.querySelector('td:nth-child(3)').textContent.toLowerCase();
        
        if (title.includes(searchTerm) || user.includes(searchTerm) || status.includes(searchTerm)) {
            row.style.display = '';
        } else {
            row.style.display = 'none';
        }
    });
});

// Show notification
function showNotification(message, type = 'info') {
    // Create notification element
    const notification = document.createElement('div');
    notification.className = `notification notification-${type}`;
    notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: ${type === 'success' ? '#48bb78' : '#667eea'};
        color: white;
        padding: 1rem 2rem;
        border-radius: 8px;
        z-index: 10000;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    `;
    notification.textContent = message;
    
    document.body.appendChild(notification);
    
    setTimeout(() => {
        notification.remove();
    }, 3000);
}
</script> 

CasperSecurity Mini