diff --git a/README.md b/README.md index 449e973..35e632d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ photo-gallery/ ├─ style.css # стили (material-like, строгий) ├─ app.js # лайтбокс ├─ deploy.php # webhook-триггер деплоя +├─ admin.php # закрытая админка (папки + загрузка фото) ├─ deploy-config.php.example # пример конфига webhook ├─ photos/ # исходные фото по категориям (папкам) ├─ thumbs/ # автогенерируемые превью @@ -91,6 +92,25 @@ bash scripts/deploy.sh BRANCH=master bash scripts/deploy.sh ``` +## Админка загрузки (по токену) + +Админка использует тот же `token`, что и `deploy.php`, из файла `deploy-config.php`. + +Ссылка входа: + +```text +https://<домен>/admin.php?token=<твой_секрет> +``` + +В админке можно: +- создавать папки-категории, +- загружать фото в выбранную папку. + +Ограничения загрузки: +- только изображения: JPG/PNG/WEBP/GIF, +- максимум 3 МБ на файл, +- MIME-тип и расширение проверяются на сервере. + ## Удалённый запуск деплоя по ссылке (webhook) 1. На хостинге создай конфиг из примера: diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..ac90297 --- /dev/null +++ b/admin.php @@ -0,0 +1,308 @@ + $config */ +$config = require $configPath; +$tokenExpected = (string)($config['token'] ?? ''); + +$tokenIncoming = (string)($_REQUEST['token'] ?? ''); +if ($tokenExpected === '' || !hash_equals($tokenExpected, $tokenIncoming)) { + http_response_code(403); + header('Content-Type: text/plain; charset=utf-8'); + echo "Forbidden: invalid token\n"; + exit; +} + +$photosDir = __DIR__ . '/photos'; +if (!is_dir($photosDir)) { + mkdir($photosDir, 0775, true); +} + +$message = ''; +$errors = []; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $action = (string)($_POST['action'] ?? ''); + + if ($action === 'create_category') { + $rawName = trim((string)($_POST['category_name'] ?? '')); + $safeName = sanitizeCategoryName($rawName); + + if ($safeName === '') { + $errors[] = 'Введите корректное имя папки.'; + } else { + $dir = $photosDir . '/' . $safeName; + if (is_dir($dir)) { + $message = 'Папка уже существует.'; + } elseif (mkdir($dir, 0775, true)) { + $message = 'Папка создана: ' . $safeName; + } else { + $errors[] = 'Не удалось создать папку.'; + } + } + } + + if ($action === 'upload') { + $selectedCategory = sanitizeCategoryName((string)($_POST['category'] ?? '')); + if ($selectedCategory === '') { + $errors[] = 'Выберите папку для загрузки.'; + } else { + $categoryDir = $photosDir . '/' . $selectedCategory; + if (!is_dir($categoryDir)) { + $errors[] = 'Выбранная папка не существует.'; + } else { + if (!isset($_FILES['photos'])) { + $errors[] = 'Файлы не переданы.'; + } else { + $result = handleUploads($_FILES['photos'], $categoryDir); + $errors = array_merge($errors, $result['errors']); + if ($result['ok'] > 0) { + $message = 'Загружено файлов: ' . $result['ok']; + } + } + } + } + } +} + +$categories = listCategories($photosDir); +$tokenForUrl = urlencode($tokenIncoming); + +?> + +
+ + +Разрешены буквы/цифры/пробел/._- (остальное отфильтруется).
+Ограничения: только JPG/PNG/WEBP/GIF, максимум 3 МБ на файл.
+Пока нет категорий.
+ +