/
codxplr
/
simple-php-blog
Обзор
Документация
Войти
/
codxplr
/
simple-php-blog
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
editor.php
112 строк
5 KB
codxplr
Create: article.php, config.php, editor.php, index.php, init.php, login.php, logout.php, sql_dump.sql, toggle_publish.php
08 авг 2026, 21:23
Верифицирован
08 авг 2026, 21:23
1113d72
Код
Авторство
О чём код?
<?php require 'init.php'; if (!is_admin_logged_in()) { redirect('login.php'); } $title = $content = $imagePath = ""; $errors = []; if ($_SERVER['REQUEST_METHOD'] === 'POST') { check_csrf(); $title = trim($_POST['title'] ?? ''); // Важно: используем $_POST как есть, так как это HTML-код $content = $_POST['content'] ?? ''; if (empty($title)) $errors[] = 'Введите заголовок.'; if (empty(strip_tags($content))) $errors[] = 'Введите текст статьи.'; $slug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $title), '-')); if (empty($slug)) $slug = uniqid('post-', true); $checkSlug = $pdo->prepare("SELECT id FROM posts WHERE slug = ? LIMIT 1"); $checkSlug->execute([$slug]); if ($checkSlug->fetch()) { $slug .= '-' . bin2hex(random_bytes(4)); } if (isset($_FILES['image']) && $_FILES['image']['error'] !== UPLOAD_ERR_NO_FILE) { if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) { $errors[] = 'Ошибка при загрузке файла.'; } elseif ($_FILES['image']['size'] > MAX_IMAGE_SIZE) { $errors[] = 'Размер изображения превышает лимит 2 МБ.'; } elseif (!in_array(mime_content_type($_FILES['image']['tmp_name']), ALLOWED_MIME_TYPES)) { $errors[] = 'Разрешены только JPG, PNG и WebP.'; } else { $ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION); $newFileName = uniqid('img_', true) . '.' . $ext; $destination = UPLOAD_DIR . $newFileName; if (!move_uploaded_file($_FILES['image']['tmp_name'], $destination)) { $errors[] = 'Не удалось переместить файл в директорию uploads.'; } else { $imagePath = 'uploads/' . $newFileName; } } } if (empty($errors)) { $stmt = $pdo->prepare("INSERT INTO posts (title, slug, content, image_path) VALUES (?, ?, ?, ?)"); $stmt->execute([$title, $slug, $content, $imagePath]); redirect('index.php'); } } ?> <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Написать статью</title> <link rel="stylesheet" href="assets/style.css"> <!-- ПУТЬ К ЛОКАЛЬНОМУ ФАЙЛУ НА ВАШЕМ СЕРВЕРЕ --> <script src="/vendor/ckeditor5/ckeditor5.js"></script> <style> #editor { border: 1px solid #ccc; min-height: 350px; padding: 10px; border-radius: 6px; } label { display: block; margin-top: 15px; font-weight: bold; color: #333; } </style> </head> <body> <header><h1>Редактор статей</h1></header> <a href="index.php" class="btn">← Назад к блогу</a> <?php if(!empty($errors)): ?> <div style="background:#f8d7da; color:#721c24; padding:10px; border-radius:4px; margin:20px 0;"> <?php foreach($errors as $err): echo "<p>" . e($err) . "</p>"; endforeach; ?> </div> <?php endif; ?> <form method="post" enctype="multipart/form-data"> <input type="hidden" name="csrf_token" value="<?= e(csrf_token()) ?>"> <label for="title">Заголовок:</label> <input type="text" id="title" name="title" required value="<?= e($title) ?>"> <label for="image">Изображение (опционально, до 2МБ):</label> <input type="file" id="image" name="image" accept="image/jpeg,image/png,image/webp"> <label for="content">Текст статьи:</label> <!-- Теперь textarea виден всегда. Редактор подменит его визуально после загрузки страницы --> <textarea id="editor" name="content"><?= e($content) ?></textarea> <button type="submit" class="btn">Опубликовать</button> </form> <script> // Инициализация локального редактора ClassicEditor .create(document.querySelector('#editor'), { language: 'ru', toolbar: ['heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', '|', 'insertTable', 'blockQuote', '|', 'undo', 'redo'], }) .catch(error => { console.error(error); alert('Произошла критическая ошибка визуального редактора. Проверьте консоль браузера (F12).'); // В случае ошибки у пользователя останется обычное текстовое поле (#editor) }); </script> </body> </html>