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/.cursor-server/data/User/History/-24d6c3ee/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/.cursor-server/data/User/History/-24d6c3ee/INLd.php
<?php
// Playlist Management Tab
// This file handles all playlist management functionality

// Ensure database connection is available
if (!isset($pdo)) {
    echo '<div style="color: red; padding: 20px;">Database connection not available. Please access this page through the admin panel.</div>';
    return;
}

// Playlist form submissions are now handled via AJAX in admin.php
// This prevents the fast refresh and bug issues

// Get playlist filter
$playlist_tab = $_GET['playlist_tab'] ?? 'all';

// Get tracks for playlist management
$playlist_where = "mt.status = 'complete' AND mt.audio_url IS NOT NULL";
$playlist_params = [];

if ($playlist_tab === 'featured') {
    $playlist_where .= " AND mt.is_featured = 1";
} elseif ($playlist_tab === 'vip') {
    $playlist_where .= " AND mt.is_vip_sample = 1";
}

$playlist_tracks = $pdo->prepare("
    SELECT mt.*, u.name as artist_name,
           (SELECT COUNT(*) FROM track_plays WHERE track_id = mt.id) as play_count,
           (SELECT COUNT(*) FROM track_likes WHERE track_id = mt.id) as like_count
    FROM music_tracks mt 
    JOIN users u ON mt.user_id = u.id
    WHERE $playlist_where
    ORDER BY mt.playlist_order ASC, mt.created_at DESC
    LIMIT 100
");
$playlist_tracks->execute($playlist_params);
$tracks = $playlist_tracks->fetchAll();

// Debug: Check for duplicates
$track_ids = array_column($tracks, 'id');
$duplicate_ids = array_diff_assoc($track_ids, array_unique($track_ids));
if (!empty($duplicate_ids)) {
    error_log("Duplicate track IDs found in admin playlists: " . implode(', ', array_unique($duplicate_ids)));
}

// Get playlist stats
$playlist_stats = [
    'total' => $pdo->query("SELECT COUNT(*) FROM music_tracks mt WHERE mt.status = 'complete' AND mt.audio_url IS NOT NULL")->fetchColumn(),
    'featured' => $pdo->query("SELECT COUNT(*) FROM music_tracks mt WHERE mt.status = 'complete' AND mt.audio_url IS NOT NULL AND mt.is_featured = 1")->fetchColumn(),
    'vip' => $pdo->query("SELECT COUNT(*) FROM music_tracks mt WHERE mt.status = 'complete' AND mt.audio_url IS NOT NULL AND mt.is_vip_sample = 1")->fetchColumn()
];
?>

<!-- Playlist Management -->
<div class="section-header">
    <h2><i class="fas fa-list-music"></i> Professional Playlist Management</h2>
    <p>Curate and manage Featured tracks and VIP Sample playlists for the homepage global player. Control track visibility, order, and playlist assignments.</p>
</div>

<!-- Quick Actions Bar -->
<div class="quick-actions-bar" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 1rem; border-radius: 12px; margin-bottom: 2rem; color: white;">
    <div style="display: flex; justify-content: space-between; align-items: center;">
        <div>
            <h3 style="margin: 0; font-size: 1.2rem;"><i class="fas fa-bolt"></i> Quick Actions</h3>
            <p style="margin: 0.5rem 0 0 0; opacity: 0.9;">Manage your playlists efficiently</p>
        </div>
        <div style="display: flex; gap: 1rem;">
            <button onclick="refreshPlaylistData()" class="btn btn-primary" style="background: rgba(255,255,255,0.2); border: 1px solid rgba(255,255,255,0.3); color: white;">
                <i class="fas fa-sync-alt"></i> Refresh Data
            </button>
            <button onclick="exportPlaylistData()" class="btn btn-primary" style="background: rgba(255,255,255,0.2); border: 1px solid rgba(255,255,255,0.3); color: white;">
                <i class="fas fa-download"></i> Export
            </button>
        </div>
    </div>
</div>

<style>
.playlist-filters {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}
.filter-btn {
    padding: 8px 16px;
    border: 1px solid #d1d5db;
    background: white;
    color: #374151;
    text-decoration: none;
    border-radius: 6px;
    transition: all 0.2s ease;
}
.filter-btn:hover {
    background: #f9fafb;
    border-color: #9ca3af;
}
.filter-btn.active {
    background: #3b82f6;
    border-color: #3b82f6;
    color: white;
}
.track-grid {
    display: grid;
    gap: 15px;
    margin-top: 20px;
}
.track-item {
    background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
    border: 2px solid #e5e7eb;
    border-radius: 16px;
    padding: 20px;
    display: flex;
    align-items: center;
    gap: 20px;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;
    overflow: hidden;
}

.track-item::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
    opacity: 0;
    transition: opacity 0.3s ease;
}

.track-item:hover {
    border-color: #667eea;
    box-shadow: 0 8px 32px rgba(102, 126, 234, 0.15);
    transform: translateY(-2px);
}

.track-item:hover::before {
    opacity: 1;
}

.track-item.featured {
    border-color: #f59e0b;
    background: linear-gradient(135deg, #ffffff 0%, #fef3c7 100%);
}

.track-item.vip {
    border-color: #8b5cf6;
    background: linear-gradient(135deg, #ffffff 0%, #f3e8ff 100%);
}
.track-info {
    flex: 1;
}
.track-title {
    font-weight: 600;
    margin-bottom: 4px;
}
.track-artist {
    color: #6b7280;
    font-size: 0.9em;
    margin-bottom: 4px;
}
.track-stats {
    color: #9ca3af;
    font-size: 0.8em;
}
.track-controls {
    display: flex;
    align-items: center;
    gap: 15px;
}
.play-btn {
    background: #3b82f6;
    color: white;
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
}
.play-btn:hover {
    background: #2563eb;
    transform: scale(1.05);
}
.checkbox-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.checkbox-group label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.9em;
    cursor: pointer;
}
.order-input {
    width: 60px;
    padding: 4px 8px;
    border: 1px solid #d1d5db;
    border-radius: 4px;
    text-align: center;
}

/* AJAX update feedback styles */
.checkbox-group, .track-controls > div {
    position: relative;
}

.update-feedback {
    position: absolute;
    font-size: 12px;
    margin-top: 2px;
    font-weight: 500;
    transition: opacity 0.3s ease;
}

/* Loading state styles */
.checkbox-group input:disabled,
.order-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Success/error states */
.checkbox-group input:disabled + span,
.order-input:disabled {
    opacity: 0.7;
}
</style>

<!-- Playlist Statistics -->
<div class="stats-grid" style="margin-bottom: 2rem;">
    <div class="stat-card">
        <div class="stat-number"><?= number_format($playlist_stats['total']) ?></div>
        <div class="stat-label">Total Tracks</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($playlist_stats['featured']) ?></div>
        <div class="stat-label">Featured</div>
    </div>
    <div class="stat-card">
        <div class="stat-number"><?= number_format($playlist_stats['vip']) ?></div>
        <div class="stat-label">VIP Samples</div>
    </div>
</div>

<!-- Playlist Filters -->
<div class="playlist-filters">
    <a href="?tab=playlists&playlist_tab=all" class="filter-btn <?= $playlist_tab === 'all' ? 'active' : '' ?>">
        <i class="fas fa-list"></i> All Tracks (<?= number_format($playlist_stats['total']) ?>)
    </a>
    <a href="?tab=playlists&playlist_tab=featured" class="filter-btn <?= $playlist_tab === 'featured' ? 'active' : '' ?>">
        <i class="fas fa-star"></i> Featured (<?= number_format($playlist_stats['featured']) ?>)
    </a>
    <a href="?tab=playlists&playlist_tab=vip" class="filter-btn <?= $playlist_tab === 'vip' ? 'active' : '' ?>">
        <i class="fas fa-crown"></i> VIP Samples (<?= number_format($playlist_stats['vip']) ?>)
    </a>
</div>

<!-- Track Grid -->
<div class="track-grid">
    <?php if (empty($tracks)): ?>
        <div style="text-align: center; padding: 40px; color: #6b7280;">
            <i class="fas fa-music" style="font-size: 48px; margin-bottom: 16px; opacity: 0.5;"></i>
            <h3>No tracks found</h3>
            <p>No tracks match the current filter criteria.</p>
        </div>
    <?php else: ?>
        <?php 
        $displayed_tracks = [];
        foreach ($tracks as $track): 
            // Skip if we've already displayed this track
            if (in_array($track['id'], $displayed_tracks)) {
                continue;
            }
            $displayed_tracks[] = $track['id'];
        ?>
            <div class="track-item">
                <button class="play-btn" onclick="playTrack('<?= htmlspecialchars($track['audio_url']) ?>', '<?= htmlspecialchars($track['title']) ?>', '<?= htmlspecialchars($track['artist_name']) ?>')">
                    <i class="fas fa-play"></i>
                </button>
                
                <div class="track-info">
                    <div class="track-title"><?= htmlspecialchars($track['title']) ?></div>
                    <div class="track-artist">by <?= htmlspecialchars($track['artist_name']) ?></div>
                    <div class="track-stats"><?= $track['play_count'] ?> plays • <?= $track['like_count'] ?> likes</div>
                </div>
                
                <div class="track-controls">
                    <!-- Featured Toggle -->
                    <div class="checkbox-group">
                        <label>
                            <input type="checkbox" 
                                   <?= $track['is_featured'] ? 'checked' : '' ?> 
                                   onchange="updatePlaylistSetting(<?= $track['id'] ?>, 'toggle_featured', this.checked, 'is_featured')">
                            <span style="color: #f59e0b;"><i class="fas fa-star"></i> Featured</span>
                        </label>
                    </div>
                    
                    <!-- VIP Toggle -->
                    <div class="checkbox-group">
                        <label>
                            <input type="checkbox" 
                                   <?= $track['is_vip_sample'] ? 'checked' : '' ?> 
                                   onchange="updatePlaylistSetting(<?= $track['id'] ?>, 'toggle_vip', this.checked, 'is_vip')">
                            <span style="color: #8b5cf6;"><i class="fas fa-crown"></i> VIP</span>
                        </label>
                    </div>
                    
                    <!-- Order Input -->
                    <div style="text-align: center;">
                        <label style="font-size: 0.8em; color: #6b7280; display: block; margin-bottom: 4px;">Order</label>
                        <input type="number" 
                               value="<?= $track['playlist_order'] ?>" 
                               class="order-input" min="0" max="999" 
                               onchange="updatePlaylistOrder(<?= $track['id'] ?>, this.value)"
                               onblur="updatePlaylistOrder(<?= $track['id'] ?>, this.value)">
                    </div>
                </div>
            </div>
        <?php endforeach; ?>
    <?php endif; ?>
</div>

<script>
// Play track function for playlist management
function playTrack(audioUrl, title, artist) {
    if (typeof window.playTrack === 'function') {
        window.playTrack(audioUrl, title, artist);
    } else if (typeof window.enhancedGlobalPlayer !== 'undefined' && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
        window.enhancedGlobalPlayer.playTrack(audioUrl, title, artist);
    } else {
        console.log('Playing:', title, 'by', artist);
        // Fallback to basic audio
        const audio = new Audio(audioUrl);
        audio.volume = 0.5;
        audio.play().catch(error => console.error('Audio play failed:', error));
    }
}

// AJAX playlist update functions
function updatePlaylistSetting(trackId, action, value, settingType) {
    console.log('Updating playlist setting:', { trackId, action, value, settingType });
    
    // Show loading state
    const checkbox = event.target;
    const originalChecked = checkbox.checked;
    checkbox.disabled = true;
    
    // Prepare form data
    const formData = new FormData();
    formData.append('playlist_action', action);
    formData.append('track_id', trackId);
    formData.append('playlist_tab', '<?= $playlist_tab ?>');
    
    if (action === 'toggle_featured') {
        formData.append('is_featured', value ? '1' : '0');
    } else if (action === 'toggle_vip') {
        formData.append('is_vip', value ? '1' : '0');
    }
    
    // Send AJAX request
    fetch('admin.php?tab=playlists&ajax=1', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log('Playlist setting updated successfully');
            // Show success feedback
            showPlaylistUpdateFeedback(checkbox, true);
        } else {
            console.error('Failed to update playlist setting:', data.error);
            // Revert checkbox state
            checkbox.checked = !originalChecked;
            showPlaylistUpdateFeedback(checkbox, false);
        }
    })
    .catch(error => {
        console.error('Error updating playlist setting:', error);
        // Revert checkbox state
        checkbox.checked = !originalChecked;
        showPlaylistUpdateFeedback(checkbox, false);
    })
    .finally(() => {
        checkbox.disabled = false;
    });
}

// Debounce function to prevent rapid AJAX calls
let updateOrderTimeout = null;

function updatePlaylistOrder(trackId, order) {
    console.log('Updating playlist order:', { trackId, order });
    
    // Validate order value
    const orderNum = parseInt(order);
    if (isNaN(orderNum) || orderNum < 0 || orderNum > 999) {
        console.error('Invalid order value:', order);
        return;
    }
    
    // Clear previous timeout
    if (updateOrderTimeout) {
        clearTimeout(updateOrderTimeout);
    }
    
    // Debounce the update
    updateOrderTimeout = setTimeout(() => {
        // Show loading state
        const input = event.target;
        const originalValue = input.value;
        input.disabled = true;
    
        // Prepare form data
        const formData = new FormData();
        formData.append('playlist_action', 'update_order');
        formData.append('track_id', trackId);
        formData.append('order', orderNum);
        formData.append('playlist_tab', '<?= $playlist_tab ?>');
        
        // Send AJAX request
        fetch('admin.php?tab=playlists&ajax=1', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                console.log('Playlist order updated successfully');
                showPlaylistUpdateFeedback(input, true);
            } else {
                console.error('Failed to update playlist order:', data.error);
                input.value = originalValue;
                showPlaylistUpdateFeedback(input, false);
            }
        })
        .catch(error => {
            console.error('Error updating playlist order:', error);
            input.value = originalValue;
            showPlaylistUpdateFeedback(input, false);
        })
        .finally(() => {
            input.disabled = false;
        });
    }, 500); // 500ms debounce

function showPlaylistUpdateFeedback(element, success) {
    // Create or update feedback element
    let feedback = element.parentNode.querySelector('.update-feedback');
    if (!feedback) {
        feedback = document.createElement('div');
        feedback.className = 'update-feedback';
        feedback.style.cssText = 'position: absolute; font-size: 12px; margin-top: 2px;';
        element.parentNode.style.position = 'relative';
        element.parentNode.appendChild(feedback);
    }
    
    if (success) {
        feedback.textContent = '✓ Updated';
        feedback.style.color = '#10b981';
    } else {
        feedback.textContent = '✗ Failed';
        feedback.style.color = '#ef4444';
    }
    
    // Clear feedback after 2 seconds
    setTimeout(() => {
        if (feedback && feedback.parentNode) {
            feedback.remove();
        }
    }, 2000);
}
</script> 

CasperSecurity Mini