File size: 7.5Kb
<?php
/**
* CMS: LaiCMS (v1.0 Edition 2026)
* File: blog/index.php
* Оптимизация: Ultra-Safe Query Engine & Modern Grid
*/
require_once '../system/db.php';
require_once '../system/functions.php';
// Безопасность заголовков
header("X-Frame-Options: SAMEORIGIN");
header("X-Content-Type-Options: nosniff");
// 1. ПАРАМЕТРЫ И ФИЛЬТРАЦИЯ (Безопасный ввод)
$limit = 6;
$page = isset($_GET['p']) ? max(1, (int)$_GET['p']) : 1;
$offset = ($page - 1) * $limit;
$cat_id = isset($_GET['cat']) ? (int)$_GET['cat'] : 0;
// 2. ПОДСЧЕТ И ПОЛУЧЕНИЕ ДАННЫХ (Prepared Statements)
$where_sql = $cat_id > 0 ? "WHERE p.category_id = ?" : "WHERE 1=1";
// Считаем общее количество
$stmt_count = $mysqli->prepare("SELECT COUNT(*) FROM posts p $where_sql");
if ($cat_id > 0) $stmt_count->bind_param("i", $cat_id);
$stmt_count->execute();
$total_posts = $stmt_count->get_result()->fetch_row()[0] ?? 0;
$total_pages = ceil($total_posts / $limit);
// Получаем категории для навигации
$categories = $mysqli->query("SELECT * FROM categories ORDER BY name ASC");
// Основной запрос постов
$query = "
SELECT p.id, p.title, p.slug, p.content, p.created_at, u.username, u.avatar, c.name as cat_name
FROM posts p
JOIN users u ON p.author_id = u.id
LEFT JOIN categories c ON p.category_id = c.id
$where_sql
ORDER BY p.created_at DESC
LIMIT ? OFFSET ?
";
$stmt = $mysqli->prepare($query);
if ($cat_id > 0) {
$stmt->bind_param("iii", $cat_id, $limit, $offset);
} else {
$stmt->bind_param("ii", $limit, $offset);
}
$stmt->execute();
$result = $stmt->get_result();
$page_title = "Блог — LaiCMS 2026";
include '../system/header.php';
?>
<style>
.b-hero {
background: var(--pico-card-background-color);
padding: 2rem;
border-radius: 24px;
margin-bottom: 2rem;
border: 1px solid var(--pico-muted-border-color);
box-shadow: var(--pico-card-box-shadow);
}
/* Улучшенные карточки 2026 */
.p-card {
background: var(--pico-card-background-color);
border-radius: 20px;
border: 1px solid var(--pico-muted-border-color);
display: flex;
flex-direction: column;
overflow: hidden;
transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.p-card:hover {
border-color: var(--pico-primary);
transform: translateY(-4px);
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.cat-badge {
font-size: 0.6rem;
background: var(--pico-primary-background);
color: var(--pico-primary);
padding: 4px 12px;
border-radius: 8px;
font-weight: 800;
text-transform: uppercase;
}
/* Плавная навигация категорий */
.cat-scroller {
display: flex; gap: 8px; overflow-x: auto;
padding-bottom: 15px; margin-bottom: 20px;
scrollbar-width: none;
}
.cat-btn {
padding: 6px 16px; border-radius: 12px; font-size: 0.85rem;
border: 1px solid var(--pico-muted-border-color);
white-space: nowrap; transition: 0.2s;
}
.cat-btn.active { background: var(--pico-primary); color: white; border-color: var(--pico-primary); }
.p-footer {
padding: 1rem 1.5rem;
border-top: 1px solid var(--pico-muted-border-color);
display: flex; justify-content: space-between; align-items: center;
background: rgba(var(--pico-muted-color-rgb), 0.03);
}
</style>
<div class="b-hero">
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px;">
<hgroup style="margin: 0;">
<h2 style="margin:0;"><i class="fa-solid fa-layer-group"></i> Журнал событий</h2>
<p style="font-size: 0.8rem; opacity: 0.7;">Найдено публикаций: <?= $total_posts ?></p>
</hgroup>
<?php if(isset($_SESSION['user_id'])): ?>
<a href="/blog/add_post.php" role="button" class="primary btn-sm" style="border-radius: 12px;">
<i class="fa-solid fa-pen-nib"></i> Написать
</a>
<?php endif; ?>
</div>
</div>
<nav class="cat-scroller">
<a href="index.php" class="cat-btn <?= $cat_id == 0 ? 'active' : '' ?>">Все категории</a>
<?php while($c = $categories->fetch_assoc()): ?>
<a href="?cat=<?= $c['id'] ?>" class="cat-btn <?= $cat_id == $c['id'] ? 'active' : '' ?>">
<?= _e($c['name']) ?>
</a>
<?php endwhile; ?>
</nav>
<div class="grid" style="grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px;">
<?php if ($result && $result->num_rows > 0): ?>
<?php while($post = $result->fetch_assoc()): ?>
<article class="p-card">
<div style="padding: 1.5rem; flex: 1;">
<div style="display:flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<span class="cat-badge"><?= _e($post['cat_name'] ?? 'Общее') ?></span>
<i class="fa-regular fa-bookmark" style="opacity: 0.3;"></i>
</div>
<h4 style="margin-bottom: 0.8rem;">
<a href="view.php?slug=<?= $post['slug'] ?>" style="color: inherit; text-decoration: none;">
<?= _e($post['title']) ?>
</a>
</h4>
<p style="font-size: 0.85rem; opacity: 0.8; line-height: 1.5;">
<?= mb_strimwidth(strip_tags($post['content']), 0, 120, "...") ?>
</p>
</div>
<div class="p-footer">
<div style="display: flex; align-items: center; gap: 8px;">
<div style="width: 24px; height: 24px; border-radius: 6px; background: var(--pico-primary); color: white; display: flex; align-items: center; justify-content: center; font-size: 0.6rem; font-weight: bold;">
<?= mb_substr($post['username'], 0, 1) ?>
</div>
<span style="font-size: 0.75rem; font-weight: 700;"><?= _e($post['username']) ?></span>
</div>
<time style="font-size: 0.7rem; opacity: 0.5;">
<i class="fa-regular fa-calendar"></i> <?= date('d.m.Y', strtotime($post['created_at'])) ?>
</time>
</div>
</article>
<?php endwhile; ?>
<?php else: ?>
<div style="grid-column: 1/-1; text-align: center; padding: 3rem;">
<p class="secondary">В этой категории пока нет записей.</p>
</div>
<?php endif; ?>
</div>
<?php if ($total_pages > 1): ?>
<nav style="margin-top: 3rem; display: flex; justify-content: center;">
<ul style="display: flex; gap: 10px; list-style: none;">
<?php if($page > 1): ?>
<li><a href="?p=<?= $page - 1 ?><?= $cat_id ? '&cat='.$cat_id : '' ?>" role="button" class="outline secondary">←</a></li>
<?php endif; ?>
<li><span role="button" class="secondary" style="pointer-events: none; opacity: 0.6;"><?= $page ?> / <?= $total_pages ?></span></li>
<?php if($page < $total_pages): ?>
<li><a href="?p=<?= $page + 1 ?><?= $cat_id ? '&cat='.$cat_id : '' ?>" role="button" class="outline secondary">→</a></li>
<?php endif; ?>
</ul>
</nav>
<?php endif; ?>
<?php include '../system/footer.php'; ?>