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/-5c095af6/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/.cursor-server/data/User/History/-5c095af6/0HEe.php
<?php
/**
 * Image Compression Tool
 * Admin interface for compressing existing images
 */

require_once __DIR__ . '/../utils/image_compression.php';

// Handle AJAX compression request
if (isset($_POST['action']) && $_POST['action'] === 'compress_images') {
    header('Content-Type: application/json');
    
    $dry_run = isset($_POST['dry_run']) && $_POST['dry_run'] === '1';
    $limit = isset($_POST['limit']) ? (int)$_POST['limit'] : null;
    $directory = $_POST['directory'] ?? 'all';
    
    $directories = [
        'track_covers' => [
            'path' => 'uploads/track_covers/',
            'function' => 'compressTrackCover',
            'name' => 'Track Covers'
        ],
        'profile_images' => [
            'path' => 'uploads/profile_images/',
            'function' => 'compressProfileImage',
            'name' => 'Profile Images'
        ],
        'cover_images' => [
            'path' => 'uploads/cover_images/',
            'function' => 'compressImage',
            'name' => 'Cover Images',
            'options' => [
                'max_width' => 1920,
                'max_height' => 1080,
                'quality' => 85,
                'convert_png_to_jpeg' => true,
                'max_file_size' => 500 * 1024,
            ]
        ],
    ];
    
    $results = [];
    $total_processed = 0;
    $total_saved = 0;
    $total_errors = 0;
    
    $dirs_to_process = $directory === 'all' ? array_keys($directories) : [$directory];
    
    foreach ($dirs_to_process as $dir_key) {
        if (!isset($directories[$dir_key])) continue;
        
        $config = $directories[$dir_key];
        $full_path = __DIR__ . '/../' . $config['path'];
        
        if (!is_dir($full_path)) {
            continue;
        }
        
        $files = glob($full_path . '*');
        $files = array_filter($files, 'is_file');
        
        $dir_results = [
            'directory' => $config['name'],
            'files' => [],
            'processed' => 0,
            'saved' => 0,
            'errors' => 0,
        ];
        
        $processed = 0;
        foreach ($files as $filepath) {
            if ($limit && $processed >= $limit) break;
            
            $filename = basename($filepath);
            $original_size = filesize($filepath);
            
            // Skip if already small
            if ($original_size < 50 * 1024) continue;
            
            if ($dry_run) {
                $image_info = @getimagesize($filepath);
                if ($image_info) {
                    $estimated_savings = (int)($original_size * 0.5);
                    $dir_results['files'][] = [
                        'filename' => $filename,
                        'original_size' => $original_size,
                        'estimated_savings' => $estimated_savings,
                        'status' => 'dry_run'
                    ];
                    $dir_results['saved'] += $estimated_savings;
                } else {
                    $dir_results['errors']++;
                }
            } else {
                if ($config['function'] === 'compressImage' && isset($config['options'])) {
                    $result = compressImage($filepath, $config['options']);
                } elseif ($config['function'] === 'compressTrackCover') {
                    $result = compressTrackCover($filepath);
                } elseif ($config['function'] === 'compressProfileImage') {
                    $result = compressProfileImage($filepath);
                } else {
                    $result = compressImage($filepath);
                }
                
                if ($result['success']) {
                    if (!empty($result['skipped'])) {
                        $dir_results['files'][] = [
                            'filename' => $filename,
                            'original_size' => $original_size,
                            'new_size' => $original_size,
                            'saved_bytes' => 0,
                            'status' => 'skipped',
                            'message' => $result['message'] ?? 'Already optimized'
                        ];
                    } else {
                        $dir_results['files'][] = [
                            'filename' => $filename,
                            'original_size' => $result['original_size'],
                            'new_size' => $result['new_size'],
                            'saved_bytes' => $result['saved_bytes'],
                            'status' => 'compressed',
                            'message' => $result['message'] ?? 'Compressed'
                        ];
                        $dir_results['saved'] += $result['saved_bytes'];
                    }
                } else {
                    $dir_results['files'][] = [
                        'filename' => $filename,
                        'original_size' => $original_size,
                        'status' => 'error',
                        'error' => $result['error'] ?? 'Unknown error'
                    ];
                    $dir_results['errors']++;
                }
            }
            
            $processed++;
        }
        
        $dir_results['processed'] = $processed;
        $total_processed += $processed;
        $total_saved += $dir_results['saved'];
        $total_errors += $dir_results['errors'];
        
        $results[] = $dir_results;
    }
    
    echo json_encode([
        'success' => true,
        'dry_run' => $dry_run,
        'results' => $results,
        'summary' => [
            'total_processed' => $total_processed,
            'total_saved' => $total_saved,
            'total_errors' => $total_errors,
        ]
    ]);
    exit;
}

// Get directory statistics
function getDirectoryStats($path) {
    $full_path = __DIR__ . '/../' . $path;
    if (!is_dir($full_path)) {
        return ['count' => 0, 'total_size' => 0, 'large_files' => 0];
    }
    
    $files = glob($full_path . '*');
    $files = array_filter($files, 'is_file');
    
    $total_size = 0;
    $large_files = 0;
    
    foreach ($files as $file) {
        $size = filesize($file);
        $total_size += $size;
        if ($size > 200 * 1024) { // Files larger than 200KB
            $large_files++;
        }
    }
    
    return [
        'count' => count($files),
        'total_size' => $total_size,
        'large_files' => $large_files
    ];
}

$track_covers_stats = getDirectoryStats('uploads/track_covers/');
$profile_images_stats = getDirectoryStats('uploads/profile_images/');
$cover_images_stats = getDirectoryStats('uploads/cover_images/');
?>

<div class="admin-section">
    <h2 class="admin-title">
        <i class="fas fa-compress"></i>
        Image Compression Tool
    </h2>
    <p class="admin-subtitle">Compress and optimize existing uploaded images to reduce file sizes and improve page load times</p>
    
    <div class="compression-stats" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; margin-bottom: 2rem;">
        <div class="stat-card" style="background: rgba(102, 126, 234, 0.1); border: 1px solid rgba(102, 126, 234, 0.3); border-radius: 12px; padding: 1.5rem;">
            <h3 style="margin: 0 0 0.5rem 0; color: #a5b4fc; font-size: 1.2rem;">
                <i class="fas fa-music"></i> Track Covers
            </h3>
            <div style="font-size: 2rem; font-weight: bold; color: white; margin-bottom: 0.5rem;">
                <?= number_format($track_covers_stats['count']) ?>
            </div>
            <div style="color: #a0aec0; font-size: 0.9rem;">
                <?= formatBytes($track_covers_stats['total_size']) ?> total
                <?php if ($track_covers_stats['large_files'] > 0): ?>
                    <br><span style="color: #fbbf24;"><?= $track_covers_stats['large_files'] ?> large files (>200KB)</span>
                <?php endif; ?>
            </div>
        </div>
        
        <div class="stat-card" style="background: rgba(118, 75, 162, 0.1); border: 1px solid rgba(118, 75, 162, 0.3); border-radius: 12px; padding: 1.5rem;">
            <h3 style="margin: 0 0 0.5rem 0; color: #c084fc; font-size: 1.2rem;">
                <i class="fas fa-user"></i> Profile Images
            </h3>
            <div style="font-size: 2rem; font-weight: bold; color: white; margin-bottom: 0.5rem;">
                <?= number_format($profile_images_stats['count']) ?>
            </div>
            <div style="color: #a0aec0; font-size: 0.9rem;">
                <?= formatBytes($profile_images_stats['total_size']) ?> total
                <?php if ($profile_images_stats['large_files'] > 0): ?>
                    <br><span style="color: #fbbf24;"><?= $profile_images_stats['large_files'] ?> large files (>200KB)</span>
                <?php endif; ?>
            </div>
        </div>
        
        <div class="stat-card" style="background: rgba(79, 172, 254, 0.1); border: 1px solid rgba(79, 172, 254, 0.3); border-radius: 12px; padding: 1.5rem;">
            <h3 style="margin: 0 0 0.5rem 0; color: #60a5fa; font-size: 1.2rem;">
                <i class="fas fa-image"></i> Cover Images
            </h3>
            <div style="font-size: 2rem; font-weight: bold; color: white; margin-bottom: 0.5rem;">
                <?= number_format($cover_images_stats['count']) ?>
            </div>
            <div style="color: #a0aec0; font-size: 0.9rem;">
                <?= formatBytes($cover_images_stats['total_size']) ?> total
                <?php if ($cover_images_stats['large_files'] > 0): ?>
                    <br><span style="color: #fbbf24;"><?= $cover_images_stats['large_files'] ?> large files (>200KB)</span>
                <?php endif; ?>
            </div>
        </div>
    </div>
    
    <div class="compression-controls" style="background: rgba(255, 255, 255, 0.05); border-radius: 12px; padding: 2rem; margin-bottom: 2rem;">
        <h3 style="margin-top: 0; color: white; margin-bottom: 1.5rem;">
            <i class="fas fa-cog"></i> Compression Settings
        </h3>
        
        <form id="compressionForm" style="display: flex; flex-direction: column; gap: 1.5rem;">
            <div style="display: flex; flex-direction: column; gap: 0.5rem;">
                <label style="color: #a0aec0; font-weight: 600;">Directory to Process</label>
                <select name="directory" id="directory" style="padding: 0.8rem; border-radius: 8px; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); color: white; font-size: 1rem;">
                    <option value="all">All Directories</option>
                    <option value="track_covers">Track Covers Only</option>
                    <option value="profile_images">Profile Images Only</option>
                    <option value="cover_images">Cover Images Only</option>
                </select>
            </div>
            
            <div style="display: flex; flex-direction: column; gap: 0.5rem;">
                <label style="color: #a0aec0; font-weight: 600;">Limit (optional)</label>
                <input type="number" name="limit" id="limit" placeholder="Leave empty to process all files" min="1" style="padding: 0.8rem; border-radius: 8px; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); color: white; font-size: 1rem;">
                <small style="color: #718096;">Maximum number of files to process per directory</small>
            </div>
            
            <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                <button type="button" id="dryRunBtn" class="btn" style="background: linear-gradient(135deg, #f59e0b, #d97706); border: none; color: white; padding: 1rem 2rem; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease;">
                    <i class="fas fa-eye"></i> Dry Run (Preview)
                </button>
                <button type="button" id="compressBtn" class="btn" style="background: linear-gradient(135deg, #667eea, #764ba2); border: none; color: white; padding: 1rem 2rem; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease;">
                    <i class="fas fa-compress"></i> Compress Images
                </button>
            </div>
        </form>
    </div>
    
    <div id="compressionResults" style="display: none; background: rgba(255, 255, 255, 0.05); border-radius: 12px; padding: 2rem;">
        <h3 style="margin-top: 0; color: white; margin-bottom: 1.5rem;">
            <i class="fas fa-chart-bar"></i> Compression Results
        </h3>
        <div id="resultsContent"></div>
    </div>
    
    <div style="background: rgba(59, 130, 246, 0.1); border: 1px solid rgba(59, 130, 246, 0.3); border-radius: 12px; padding: 1.5rem; margin-top: 2rem;">
        <h4 style="margin-top: 0; color: #60a5fa;">
            <i class="fas fa-info-circle"></i> About Image Compression
        </h4>
        <ul style="color: #a0aec0; line-height: 1.8; margin: 0; padding-left: 1.5rem;">
            <li>Track covers are compressed to max 1920x1920px, 500KB file size</li>
            <li>Profile images are compressed to max 800x800px, 200KB file size</li>
            <li>Cover images are compressed to max 1920x1080px, 500KB file size</li>
            <li>PNG/GIF images without transparency are converted to JPEG for better compression</li>
            <li>Images smaller than 50KB are skipped automatically</li>
            <li><strong>All future uploads are automatically compressed</strong></li>
        </ul>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const form = document.getElementById('compressionForm');
    const dryRunBtn = document.getElementById('dryRunBtn');
    const compressBtn = document.getElementById('compressBtn');
    const resultsDiv = document.getElementById('compressionResults');
    const resultsContent = document.getElementById('resultsContent');
    
    function showLoading() {
        resultsDiv.style.display = 'block';
        resultsContent.innerHTML = '<div style="text-align: center; padding: 2rem;"><i class="fas fa-spinner fa-spin" style="font-size: 2rem; color: #667eea;"></i><p style="color: #a0aec0; margin-top: 1rem;">Processing images...</p></div>';
        dryRunBtn.disabled = true;
        compressBtn.disabled = true;
    }
    
    function hideLoading() {
        dryRunBtn.disabled = false;
        compressBtn.disabled = false;
    }
    
    function formatBytes(bytes) {
        if (bytes === 0) return '0 B';
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
    }
    
    function displayResults(data) {
        let html = '';
        
        if (data.dry_run) {
            html += '<div style="background: rgba(251, 191, 36, 0.1); border: 1px solid rgba(251, 191, 36, 0.3); border-radius: 8px; padding: 1rem; margin-bottom: 1.5rem; color: #fbbf24;"><i class="fas fa-exclamation-triangle"></i> <strong>Dry Run Mode:</strong> No files were modified. This is a preview of what would happen.</div>';
        }
        
        // Summary
        html += '<div style="background: rgba(102, 126, 234, 0.1); border: 1px solid rgba(102, 126, 234, 0.3); border-radius: 8px; padding: 1.5rem; margin-bottom: 2rem;">';
        html += '<h4 style="margin-top: 0; color: white; margin-bottom: 1rem;">Summary</h4>';
        html += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem;">';
        html += '<div><strong style="color: #a0aec0;">Files Processed:</strong><br><span style="color: white; font-size: 1.5rem; font-weight: bold;">' + data.summary.total_processed + '</span></div>';
        html += '<div><strong style="color: #a0aec0;">Space Saved:</strong><br><span style="color: #4ade80; font-size: 1.5rem; font-weight: bold;">' + formatBytes(data.summary.total_saved) + '</span></div>';
        if (data.summary.total_errors > 0) {
            html += '<div><strong style="color: #a0aec0;">Errors:</strong><br><span style="color: #f87171; font-size: 1.5rem; font-weight: bold;">' + data.summary.total_errors + '</span></div>';
        }
        html += '</div></div>';
        
        // Detailed results per directory
        data.results.forEach(function(dirResult) {
            if (dirResult.processed === 0) return;
            
            html += '<div style="margin-bottom: 2rem;">';
            html += '<h4 style="color: white; margin-bottom: 1rem;"><i class="fas fa-folder"></i> ' + dirResult.directory + '</h4>';
            html += '<div style="background: rgba(255, 255, 255, 0.05); border-radius: 8px; padding: 1rem; max-height: 400px; overflow-y: auto;">';
            html += '<table style="width: 100%; border-collapse: collapse;">';
            html += '<thead><tr style="border-bottom: 1px solid rgba(255, 255, 255, 0.1);">';
            html += '<th style="text-align: left; padding: 0.8rem; color: #a0aec0;">File</th>';
            html += '<th style="text-align: right; padding: 0.8rem; color: #a0aec0;">Original</th>';
            html += '<th style="text-align: right; padding: 0.8rem; color: #a0aec0;">New Size</th>';
            html += '<th style="text-align: right; padding: 0.8rem; color: #a0aec0;">Saved</th>';
            html += '<th style="text-align: center; padding: 0.8rem; color: #a0aec0;">Status</th>';
            html += '</tr></thead><tbody>';
            
            dirResult.files.forEach(function(file) {
                html += '<tr style="border-bottom: 1px solid rgba(255, 255, 255, 0.05);">';
                html += '<td style="padding: 0.8rem; color: white;">' + file.filename + '</td>';
                html += '<td style="text-align: right; padding: 0.8rem; color: #a0aec0;">' + formatBytes(file.original_size) + '</td>';
                
                if (file.status === 'compressed') {
                    html += '<td style="text-align: right; padding: 0.8rem; color: #4ade80;">' + formatBytes(file.new_size) + '</td>';
                    html += '<td style="text-align: right; padding: 0.8rem; color: #4ade80; font-weight: bold;">-' + formatBytes(file.saved_bytes) + '</td>';
                    html += '<td style="text-align: center; padding: 0.8rem;"><span style="background: rgba(74, 222, 128, 0.2); color: #4ade80; padding: 0.3rem 0.6rem; border-radius: 4px; font-size: 0.85rem;">✓ Compressed</span></td>';
                } else if (file.status === 'skipped') {
                    html += '<td style="text-align: right; padding: 0.8rem; color: #a0aec0;">' + formatBytes(file.new_size) + '</td>';
                    html += '<td style="text-align: right; padding: 0.8rem; color: #a0aec0;">-</td>';
                    html += '<td style="text-align: center; padding: 0.8rem;"><span style="background: rgba(156, 163, 175, 0.2); color: #9ca3af; padding: 0.3rem 0.6rem; border-radius: 4px; font-size: 0.85rem;">⊘ Skipped</span></td>';
                } else if (file.status === 'dry_run') {
                    html += '<td style="text-align: right; padding: 0.8rem; color: #fbbf24;">~' + formatBytes(file.original_size - file.estimated_savings) + '</td>';
                    html += '<td style="text-align: right; padding: 0.8rem; color: #fbbf24;">~' + formatBytes(file.estimated_savings) + '</td>';
                    html += '<td style="text-align: center; padding: 0.8rem;"><span style="background: rgba(251, 191, 36, 0.2); color: #fbbf24; padding: 0.3rem 0.6rem; border-radius: 4px; font-size: 0.85rem;">👁 Preview</span></td>';
                } else {
                    html += '<td style="text-align: right; padding: 0.8rem; color: #a0aec0;">-</td>';
                    html += '<td style="text-align: right; padding: 0.8rem; color: #a0aec0;">-</td>';
                    html += '<td style="text-align: center; padding: 0.8rem;"><span style="background: rgba(248, 113, 113, 0.2); color: #f87171; padding: 0.3rem 0.6rem; border-radius: 4px; font-size: 0.85rem;">✗ Error</span></td>';
                }
                
                html += '</tr>';
            });
            
            html += '</tbody></table>';
            html += '</div>';
            html += '<div style="margin-top: 1rem; color: #a0aec0;">';
            html += 'Processed: <strong style="color: white;">' + dirResult.processed + '</strong> files';
            if (!data.dry_run) {
                html += ' | Saved: <strong style="color: #4ade80;">' + formatBytes(dirResult.saved) + '</strong>';
            }
            if (dirResult.errors > 0) {
                html += ' | Errors: <strong style="color: #f87171;">' + dirResult.errors + '</strong>';
            }
            html += '</div>';
            html += '</div>';
        });
        
        resultsContent.innerHTML = html;
        hideLoading();
    }
    
    function runCompression(dryRun) {
        showLoading();
        
        const formData = new FormData();
        formData.append('action', 'compress_images');
        formData.append('dry_run', dryRun ? '1' : '0');
        formData.append('directory', document.getElementById('directory').value);
        const limit = document.getElementById('limit').value;
        if (limit) {
            formData.append('limit', limit);
        }
        
        fetch('?tab=image-compression', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                displayResults(data);
            } else {
                resultsContent.innerHTML = '<div style="color: #f87171; padding: 1rem;"><i class="fas fa-exclamation-circle"></i> Error: ' + (data.error || 'Unknown error') + '</div>';
                hideLoading();
            }
        })
        .catch(error => {
            resultsContent.innerHTML = '<div style="color: #f87171; padding: 1rem;"><i class="fas fa-exclamation-circle"></i> Network error: ' + error.message + '</div>';
            hideLoading();
        });
    }
    
    dryRunBtn.addEventListener('click', function() {
        if (confirm('Run a dry run to preview what would happen? No files will be modified.')) {
            runCompression(true);
        }
    });
    
    compressBtn.addEventListener('click', function() {
        if (confirm('This will compress images and may take some time. Continue?')) {
            runCompression(false);
        }
    });
});
</script>


CasperSecurity Mini