<?php
/**
 * Простой файловый проводник
 * Разместите этот файл в корне директории, которую хотите просматривать
 */

// === ЖЕСТКАЯ УСТАНОВКА КОДИРОВКИ UTF-8 ===
// Это решает проблему с "?" и ромбиками, если сервер по умолчанию отдаёт Windows-1251
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');

// Настройки
$baseDir = __DIR__; // Корневая директория (текущая)
$allowDownload = true; // Разрешить скачивание файлов
$allowDelete = false;  // Разрешить удаление файлов (осторожно!)
$hiddenFiles = ['.', '..', '.htaccess', '.git', '.env'];

// Текущая директория (относительно baseDir)
$currentDir = isset($_GET['dir']) ? $_GET['dir'] : '';
$currentDir = str_replace(['..', '\\'], ['', '/'], $currentDir); // защита от обхода
$currentDir = trim($currentDir, '/');

$fullPath = $baseDir . ($currentDir ? DIRECTORY_SEPARATOR . $currentDir : '');

// Проверка существования
if (!is_dir($fullPath)) {
    $currentDir = '';
    $fullPath = $baseDir;
}

// Скачивание файла
if ($allowDownload && isset($_GET['download'])) {
    $file = $_GET['download'];
    $file = str_replace(['..', '\\'], ['', '/'], $file);
    $filePath = $baseDir . DIRECTORY_SEPARATOR . $file;

    if (is_file($filePath) && strpos(realpath($filePath), realpath($baseDir)) === 0) {
        // Очищаем буфер вывода перед отправкой файла
        if (ob_get_level()) ob_end_clean();
        
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
        header('Content-Length: ' . filesize($filePath));
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        readfile($filePath);
        exit;
    } else {
        http_response_code(404);
        die('Файл не найден');
    }
}

// Удаление файла/папки
if ($allowDelete && isset($_POST['delete'])) {
    $target = $_POST['delete'];
    $target = str_replace(['..', '\\'], ['', '/'], $target);
    $targetPath = $baseDir . DIRECTORY_SEPARATOR . $target;

    if (file_exists($targetPath) && strpos(realpath($targetPath), realpath($baseDir)) === 0) {
        if (is_dir($targetPath)) {
            @rmdir($targetPath);
        } else {
            @unlink($targetPath);
        }
    }
    header('Location: ?dir=' . urlencode($currentDir));
    exit;
}

// Получение списка элементов
$items = @scandir($fullPath);
if ($items === false) {
    $items = [];
}

$dirs = [];
$files = [];

foreach ($items as $item) {
    if (in_array($item, $hiddenFiles)) continue;

    $itemPath = $fullPath . DIRECTORY_SEPARATOR . $item;
    $relative = ($currentDir ? $currentDir . '/' : '') . $item;

    if (is_dir($itemPath)) {
        $dirs[] = [
            'name' => $item,
            'path' => $relative,
            'size' => 0,
            'mtime' => filemtime($itemPath),
        ];
    } else {
        $files[] = [
            'name' => $item,
            'path' => $relative,
            'size' => filesize($itemPath),
            'mtime' => filemtime($itemPath),
        ];
    }
}

// Сортировка по имени
usort($dirs, fn($a, $b) => strcasecmp($a['name'], $b['name']));
usort($files, fn($a, $b) => strcasecmp($a['name'], $b['name']));

/**
 * Форматирование размера
 */
function formatSize($bytes)
{
    if ($bytes < 1024) return $bytes . ' B';
    if ($bytes < 1024 * 1024) return round($bytes / 1024, 1) . ' KB';
    if ($bytes < 1024 * 1024 * 1024) return round($bytes / (1024 * 1024), 1) . ' MB';
    return round($bytes / (1024 * 1024 * 1024), 2) . ' GB';
}

/**
 * Определение иконки по расширению
 */
function fileIcon($name)
{
    $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    $icons = [
        'php' => '🐘', 'js' => '🟨', 'css' => '🎨', 'html' => '🌐', 'htm' => '🌐',
        'jpg' => '🖼️', 'jpeg' => '🖼️', 'png' => '🖼️', 'gif' => '🖼️', 'svg' => '🖼️', 'webp' => '🖼️',
        'mp3' => '🎵', 'wav' => '🎵', 'ogg' => '🎵',
        'mp4' => '🎬', 'avi' => '🎬', 'mkv' => '🎬', 'mov' => '🎬',
        'zip' => '📦', 'rar' => '📦', '7z' => '📦', 'tar' => '📦', 'gz' => '📦',
        'pdf' => '📄', 'doc' => '📝', 'docx' => '📝', 'txt' => '📝', 'md' => '📝',
        'json' => '⚙️', 'xml' => '⚙️', 'yaml' => '⚙️', 'yml' => '⚙️',
        'exe' => '⚙️', 'sh' => '⚙️',
    ];
    return $icons[$ext] ?? '📄';
}

// Построение хлебных крошек
$crumbs = [['name' => '🏠 Корень', 'path' => '']];
if ($currentDir) {
    $parts = explode('/', $currentDir);
    $acc = '';
    foreach ($parts as $p) {
        $acc = $acc ? $acc . '/' . $p : $p;
        $crumbs[] = ['name' => $p, 'path' => $acc];
    }
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>📁 Проводник — /<?= htmlspecialchars($currentDir) ?></title>
    <style>
        * { box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            background: #f5f7fa;
            margin: 0;
            padding: 20px;
            color: #2c3e50;
        }
        .container {
            max-width: 1100px;
            margin: 0 auto;
            background: #fff;
            border-radius: 10px;
            box-shadow: 0 2px 12px rgba(0,0,0,.08);
            overflow: hidden;
        }
        .header {
            padding: 16px 20px;
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: #fff;
        }
        .header h1 { margin: 0; font-size: 20px; font-weight: 600; }
        .breadcrumbs {
            padding: 10px 20px;
            background: #f8f9fc;
            border-bottom: 1px solid #e9edf3;
            font-size: 14px;
            word-break: break-all;
        }
        .breadcrumbs a {
            color: #667eea;
            text-decoration: none;
            padding: 2px 4px;
            border-radius: 4px;
        }
        .breadcrumbs a:hover { background: #eef1ff; }
        .breadcrumbs .sep { color: #aaa; margin: 0 4px; }

        table { width: 100%; border-collapse: collapse; }
        th, td { padding: 10px 16px; text-align: left; border-bottom: 1px solid #eef1f6; font-size: 14px; }
        th { background: #f8f9fc; font-weight: 600; color: #666; font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }
        tr:hover td { background: #f8f9fc; }
        td.size, td.date { color: #888; white-space: nowrap; }
        td.name { display: flex; align-items: center; gap: 8px; }
        td.name a { color: #2c3e50; text-decoration: none; word-break: break-all; }
        td.name a:hover { color: #667eea; text-decoration: underline; }
        .icon { font-size: 18px; flex-shrink: 0; }
        .actions { text-align: right; white-space: nowrap; }
        .btn {
            display: inline-block;
            padding: 4px 10px;
            font-size: 12px;
            border-radius: 4px;
            text-decoration: none;
            border: 1px solid #dde3ed;
            background: #fff;
            color: #555;
            cursor: pointer;
            margin-left: 4px;
        }
        .btn:hover { background: #667eea; color: #fff; border-color: #667eea; }
        .btn.danger:hover { background: #e74c3c; border-color: #e74c3c; }

        .empty { padding: 40px; text-align: center; color: #999; }

        .footer {
            padding: 12px 20px;
            background: #f8f9fc;
            border-top: 1px solid #e9edf3;
            font-size: 12px;
            color: #888;
            text-align: right;
        }

        @media (max-width: 600px) {
            th.date, td.date { display: none; }
        }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1>📁 Файловый проводник</h1>
    </div>

    <div class="breadcrumbs">
        <?php foreach ($crumbs as $i => $c): ?>
            <?php if ($i > 0): ?><span class="sep">/</span><?php endif; ?>
            <?php if ($i === count($crumbs) - 1): ?>
                <strong><?= htmlspecialchars($c['name']) ?></strong>
            <?php else: ?>
                <a href="?dir=<?= urlencode($c['path']) ?>"><?= htmlspecialchars($c['name']) ?></a>
            <?php endif; ?>
        <?php endforeach; ?>
    </div>

    <?php if (empty($dirs) && empty($files)): ?>
        <div class="empty">📭 Папка пуста</div>
    <?php else: ?>
        <table>
            <thead>
                <tr>
                    <th>Имя</th>
                    <th class="size">Размер</th>
                    <th class="date">Изменён</th>
                    <th class="actions">Действия</th>
                </tr>
            </thead>
            <tbody>
                <?php if ($currentDir): ?>
                    <?php
                    $parent = dirname($currentDir);
                    if ($parent === '.') $parent = '';
                    ?>
                    <tr>
                        <td class="name">
                            <span class="icon">↩️</span>
                            <a href="?dir=<?= urlencode($parent) ?>">.. (Наверх)</a>
                        </td>
                        <td colspan="3"></td>
                    </tr>
                <?php endif; ?>

                <?php foreach ($dirs as $d): ?>
                    <tr>
                        <td class="name">
                            <span class="icon">📁</span>
                            <a href="?dir=<?= urlencode($d['path']) ?>"><?= htmlspecialchars($d['name']) ?></a>
                        </td>
                        <td class="size">—</td>
                        <td class="date"><?= date('d.m.Y H:i', $d['mtime']) ?></td>
                        <td class="actions">
                            <?php if ($allowDelete): ?>
                                <form method="post" style="display:inline" onsubmit="return confirm('Удалить папку?')">
                                    <input type="hidden" name="delete" value="<?= htmlspecialchars($d['path']) ?>">
                                    <button class="btn danger" type="submit">Удалить</button>
                                </form>
                            <?php endif; ?>
                        </td>
                    </tr>
                <?php endforeach; ?>

                <?php foreach ($files as $f): ?>
                    <tr>
                        <td class="name">
                            <span class="icon"><?= fileIcon($f['name']) ?></span>
                            <?php if ($allowDownload): ?>
                                <a href="?download=<?= urlencode($f['path']) ?>"><?= htmlspecialchars($f['name']) ?></a>
                            <?php else: ?>
                                <?= htmlspecialchars($f['name']) ?>
                            <?php endif; ?>
                        </td>
                        <td class="size"><?= formatSize($f['size']) ?></td>
                        <td class="date"><?= date('d.m.Y H:i', $f['mtime']) ?></td>
                        <td class="actions">
                            <?php if ($allowDownload): ?>
                                <a class="btn" href="?download=<?= urlencode($f['path']) ?>">⬇ Скачать</a>
                            <?php endif; ?>
                            <?php if ($allowDelete): ?>
                                <form method="post" style="display:inline" onsubmit="return confirm('Удалить файл?')">
                                    <input type="hidden" name="delete" value="<?= htmlspecialchars($f['path']) ?>">
                                    <button class="btn danger" type="submit">Удалить</button>
                                </form>
                            <?php endif; ?>
                        </td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    <?php endif; ?>

    <div class="footer">
        Всего: <?= count($dirs) ?> папок, <?= count($files) ?> файлов
    </div>
</div>
</body>
</html>