↩️ Назад

Категории

Добавление код-постов в блоге add_code_post.php save_code_post.php

13.04.2026 | коды из категории: php

➕ add_code_post.php + save_code_post.php

🔐 ЗАЩИТА:
- ip_check.php + сессия
- CSRF-токен
- htmlspecialchars() везде
- PDO подготовленные запросы
- (int) для category_id
- in_array() валидация типа блока
- trim() очистка данных

📝 ФУНКЦИИ add_code_post.php:
- Форма с блоками (динамическое добавление)
- Выбор категории из БД
- Автодополнение тегов
- Файловый браузер для изображений
- Meta Title/Description для SEO

💾 ФУНКЦИИ save_code_post.php:
- Валидация заголовка
- INSERT в code_posts
- INSERT в code_blocks (блоки контента)
- INSERT в tags + связь code_post_tags
- Редирект с сообщением об успехе/ошибке

🗂️ ТАБЛИЦЫ:
- code_posts — основной пост
- code_blocks — блоки контента
- categories — категории
- tags — теги
- code_post_tags — связь тегов с постами

add_code_post.php

<?php
include('ip_check.php');
session_start();
if (!isset($_SESSION['user'])) {
    header("Location: login.php");
    exit;
}

require '../includes/db.php';
include '../includes/header.php';

// CSRF-токен
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

$error = '';
$form_data = [
    'title' => '',
    'meta_title' => '',
    'meta_description' => '',
    'preview_text' => '',
    'image' => '',
    'category_id' => '',
    'tags' => ''
];
?>

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Добавить код-пост — Админка</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <link rel="stylesheet" href="/css/style.css">
    <link rel="stylesheet" href="/css/adminka.css">
    <script src="tag-autocomplete.js"></script>
    <style>
        .error { background: #f44336; color: white; padding: 10px; border-radius: 5px; margin: 10px 0; }
        .form-group { margin-bottom: 15px; }
        .form-group label { display: block; font-weight: bold; margin-bottom: 5px; }
        .form-group input, .form-group textarea, .form-group select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; }
        .block { background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px; }
        button, input[type="submit"] { background: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; margin: 5px; }
        button:hover, input[type="submit"]:hover { background: #0056b3; }
        .btn-secondary { background: #6c757d; }
        .btn-secondary:hover { background: #5a6268; }
    </style>
    <script>
    function openFileBrowser() {
        window.open('file_browser.php', 'FileBrowser', 'width=600,height=400');
    }
    
    function insertFilePath(filePath) {
        document.getElementsByName('image')[0].value = filePath;
    }
    
    let blockCount = 1;
    
    function addBlock() {
        const container = document.getElementById('blocks-container');
        const div = document.createElement('div');
        div.className = 'block';
        div.innerHTML = `
            <strong>Блок ${blockCount + 1}</strong><br>
            <label>Тип блока:
                <select name="blocks[${blockCount}][type]">
                    <option value="heading">Заголовок H2</option>
                    <option value="text">Обычный текст</option>
                    <option value="code">Пример кода</option>
                    <option value="image">Изображение</option>
                    <option value="quote">Цитата</option>
                </select>
            </label><br>
            <label>Содержание:<br>
                <textarea name="blocks[${blockCount}][content]" rows="5" placeholder="Содержание блока"></textarea>
            </label><br>
            <button type="button" class="btn-secondary" onclick="this.parentElement.remove()">🗑 Удалить блок</button>
        `;
        container.appendChild(div);
        blockCount++;
    }
    </script>
</head>
<body>
<div class="container">
    <?php include '../includes/admin_menu.php'; ?>
    
    <h2>➕ Добавить код-пост</h2>
    
    <?php if ($error): ?>
        <div class="error"><?= htmlspecialchars($error) ?></div>
    <?php endif; ?>
    
    <form method="post" action="save_code_post.php">
        <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
        
        <div class="form-group">
            <label>🏷️ Теги (через запятую)</label>
            <input type="text" id="tag-input" name="tags" value="<?= htmlspecialchars($form_data['tags']) ?>" placeholder="Начните вводить тег...">
        </div>
        
        <div class="form-group">
            <label>📚 Категория</label>
            <select name="category_id">
                <option value="">— Без категории —</option>
                <?php
                $stmt = $pdo->query("SELECT id, name FROM categories ORDER BY name ASC");
                while ($cat = $stmt->fetch()): ?>
                    <option value="<?= $cat['id'] ?>" <?= $form_data['category_id'] == $cat['id'] ? 'selected' : '' ?>>
                        <?= htmlspecialchars($cat['name']) ?>
                    </option>
                <?php endwhile; ?>
            </select>
        </div>
        
        <div class="form-group">
            <label>📌 Заголовок *</label>
            <input type="text" name="title" required value="<?= htmlspecialchars($form_data['title']) ?>">
        </div>
        
        <div class="form-group">
            <label>📝 Мета-заголовок (SEO)</label>
            <input type="text" name="meta_title" value="<?= htmlspecialchars($form_data['meta_title']) ?>">
        </div>
        
        <div class="form-group">
            <label>📄 Мета-описание (SEO)</label>
            <textarea name="meta_description" rows="2"><?= htmlspecialchars($form_data['meta_description']) ?></textarea>
        </div>
        
        <div class="form-group">
            <label>📖 Краткое описание (предпросмотр)</label>
            <textarea name="preview_text" rows="3"><?= htmlspecialchars($form_data['preview_text']) ?></textarea>
        </div>
        
        <div class="form-group">
            <label>📷 Изображение</label>
            <div style="display: flex; gap: 10px;">
                <input type="text" name="image" value="<?= htmlspecialchars($form_data['image']) ?>" style="flex:1">
                <button type="button" onclick="openFileBrowser()">📁 Выбрать</button>
            </div>
        </div>
        
        <h3>📦 Блоки контента</h3>
        <div id="blocks-container">
            <div class="block">
                <strong>Блок 1</strong><br>
                <label>Тип блока:
                    <select name="blocks[0][type]">
                        <option value="heading">Заголовок H2</option>
                        <option value="text">Обычный текст</option>
                        <option value="code">Пример кода</option>
                        <option value="image">Изображение</option>
                        <option value="quote">Цитата</option>
                    </select>
                </label><br>
                <label>Содержание:<br>
                    <textarea name="blocks[0][content]" rows="5" placeholder="Содержание блока"></textarea>
                </label><br>
            </div>
        </div>
        
        <button type="button" onclick="addBlock()">+ Добавить блок</button>
        <button type="submit">💾 Сохранить пост</button>
        <a href="index.php"><button type="button" class="btn-secondary">← Назад</button></a>
    </form>
</div>
</body>
</html>

save_code_post.php

<?php
include('ip_check.php');
session_start();
if (!isset($_SESSION['user'])) {
    header("Location: login.php");
    exit;
}

require '../includes/db.php';

// CSRF-проверка
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    die("CSRF атака!");
}

// Получаем и очищаем данные
$title = trim($_POST['title'] ?? '');
$meta_title = trim($_POST['meta_title'] ?? '');
$meta_description = trim($_POST['meta_description'] ?? '');
$preview_text = trim($_POST['preview_text'] ?? '');
$image = trim($_POST['image'] ?? '');
$category_id = !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null;
$tags = trim($_POST['tags'] ?? '');

// Валидация
if (empty($title)) {
    $_SESSION['error'] = "Заголовок обязателен!";
    header("Location: add_code_post.php");
    exit;
}

// Сохраняем код-пост
$stmt = $pdo->prepare("INSERT INTO code_posts 
    (title, meta_title, meta_description, intro, image, category_id, created_at)
    VALUES (?, ?, ?, ?, ?, ?, NOW())");

$stmt->execute([$title, $meta_title, $meta_description, $preview_text, $image, $category_id]);
$post_id = $pdo->lastInsertId();

// Сохраняем блоки
if (isset($_POST['blocks']) && is_array($_POST['blocks'])) {
    $block_stmt = $pdo->prepare("INSERT INTO code_blocks (post_id, type, content, position) VALUES (?, ?, ?, ?)");
    
    foreach ($_POST['blocks'] as $position => $block) {
        $type = in_array($block['type'], ['heading', 'text', 'code', 'image', 'quote']) ? $block['type'] : 'text';
        $content = $block['content'] ?? '';
        
        $block_stmt->execute([$post_id, $type, $content, $position]);
    }
}

// Сохраняем теги (если есть)
if (!empty($tags)) {
    $tag_names = array_map('trim', explode(',', $tags));
    
    foreach ($tag_names as $tag_name) {
        if (empty($tag_name)) continue;
        
        $slug = strtolower(trim(preg_replace('/[^a-zA-Z0-9-]/', '-', $tag_name)));
        
        // Вставляем или получаем ID тега
        $tag_stmt = $pdo->prepare("INSERT INTO tags (name, slug) VALUES (?, ?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)");
        $tag_stmt->execute([$tag_name, $slug]);
        $tag_id = $pdo->lastInsertId();
        
        // Связываем с постом
        $link_stmt = $pdo->prepare("INSERT INTO code_post_tags (code_post_id, tag_id) VALUES (?, ?)");
        $link_stmt->execute([$post_id, $tag_id]);
    }
}

$_SESSION['success'] = "Код-пост успешно добавлен!";
header("Location: index.php");
exit;
?>



Категории:

Категории

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку

Посетителей сегодня: 0
о блоге | карта блога | 📡 Подписаться на RSS

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA