getMessage());
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = (string)($_POST['action'] ?? '');
try {
if ($action === 'create_section') {
$name = trim((string)($_POST['name'] ?? ''));
$sort = (int)($_POST['sort_order'] ?? 1000);
if ($name === '') throw new RuntimeException('Название раздела пустое');
sectionCreate($name, $sort);
$message = 'Раздел создан';
}
if ($action === 'upload_photo') {
$sectionId = (int)($_POST['section_id'] ?? 0);
$codeName = trim((string)($_POST['code_name'] ?? ''));
$sortOrder = (int)($_POST['sort_order'] ?? 1000);
$description = trim((string)($_POST['description'] ?? ''));
$description = $description !== '' ? $description : null;
if ($sectionId < 1) throw new RuntimeException('Выбери раздел');
if ($codeName === '') throw new RuntimeException('Укажи код фото (например АВФ1)');
if (!isset($_FILES['before'])) throw new RuntimeException('Файл "до" обязателен');
if (!sectionById($sectionId)) throw new RuntimeException('Раздел не найден');
$photoId = photoCreate($sectionId, $codeName, $description, $sortOrder);
$before = saveImageUpload($_FILES['before'], $codeName, 'before', $sectionId);
photoFileUpsert($photoId, 'before', $before['path'], $before['mime'], $before['size']);
if (isset($_FILES['after']) && (int)($_FILES['after']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
$after = saveImageUpload($_FILES['after'], $codeName . 'р', 'after', $sectionId);
photoFileUpsert($photoId, 'after', $after['path'], $after['mime'], $after['size']);
}
$message = 'Фото добавлено';
}
if ($action === 'create_commenter') {
$displayName = trim((string)($_POST['display_name'] ?? ''));
if ($displayName === '') throw new RuntimeException('Укажи имя комментатора');
$u = commenterCreate($displayName);
$link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost') . '/index-mysql.php?viewer=' . urlencode($u['token']);
$message = 'Комментатор создан: ' . $u['display_name'] . ' | ссылка: ' . $link;
}
if ($action === 'delete_commenter') {
$id = (int)($_POST['id'] ?? 0);
if ($id > 0) {
commenterDelete($id);
$message = 'Комментатор удалён (доступ отозван)';
}
}
if ($action === 'delete_comment') {
$id = (int)($_POST['id'] ?? 0);
if ($id > 0) {
commentDelete($id);
$message = 'Комментарий удалён';
}
}
} catch (Throwable $e) {
$errors[] = $e->getMessage();
}
}
$sections = sectionsAll();
$activeSectionId = (int)($_GET['section_id'] ?? ($sections[0]['id'] ?? 0));
$photos = $activeSectionId > 0 ? photosBySection($activeSectionId) : [];
$commenters = commentersAll();
$latestComments = commentsLatest(80);
function h(string $v): string { return htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
function assetUrl(string $path): string { $f=__DIR__ . '/' . ltrim($path,'/'); $v=is_file($f)?(string)filemtime($f):(string)time(); return $path . '?v=' . rawurlencode($v); }
function saveImageUpload(array $file, string $baseName, string $kind, int $sectionId): array
{
$allowedMime = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp', 'image/gif' => 'gif'];
$err = (int)($file['error'] ?? UPLOAD_ERR_NO_FILE);
if ($err !== UPLOAD_ERR_OK) throw new RuntimeException("Ошибка загрузки ({$kind})");
$size = (int)($file['size'] ?? 0);
if ($size < 1 || $size > MAX_UPLOAD_BYTES) throw new RuntimeException("Файл {$kind}: превышен лимит 3 МБ");
$tmp = (string)($file['tmp_name'] ?? '');
if (!is_uploaded_file($tmp)) throw new RuntimeException("Файл {$kind}: некорректный источник");
$mime = mime_content_type($tmp) ?: '';
if (!isset($allowedMime[$mime])) throw new RuntimeException("Файл {$kind}: недопустимый mime {$mime}");
$safeBase = preg_replace('/[^\p{L}\p{N}._-]+/u', '_', $baseName) ?? 'photo';
$safeBase = trim($safeBase, '._-');
if ($safeBase === '') $safeBase = 'photo';
$ext = $allowedMime[$mime];
$dir = __DIR__ . '/photos/section_' . $sectionId;
if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) throw new RuntimeException('Не удалось создать папку раздела');
$final = uniqueName($dir, $safeBase, $ext);
$dest = $dir . '/' . $final;
if (!move_uploaded_file($tmp, $dest)) throw new RuntimeException('Не удалось сохранить файл');
return [
'path' => 'photos/section_' . $sectionId . '/' . $final,
'mime' => $mime,
'size' => $size,
];
}
function uniqueName(string $dir, string $base, string $ext): string
{
$i = 0;
do {
$name = $i === 0 ? "{$base}.{$ext}" : "{$base}_{$i}.{$ext}";
$i++;
} while (is_file($dir . '/' . $name));
return $name;
}
?>
Админка (MySQL)
Админка (MySQL)
Открыть публичную MySQL-галерею
= h($message) ?>
= h($e) ?>
Фото раздела
| ID | Код | Превью | Описание | Порядок |
| = (int)$p['id'] ?> |
= h((string)$p['code_name']) ?> |
$p['before_file_id'] ?>) |
= h((string)($p['description'] ?? '')) ?> |
= (int)$p['sort_order'] ?> |
Последние комментарии
| ID | Фото | Пользователь | Комментарий | |
| = (int)$c['id'] ?> |
= h((string)$c['code_name']) ?> |
= h((string)($c['display_name'] ?? '—')) ?> |
= h((string)$c['comment_text']) ?> |
|