Files
2026-05-17 05:22:06 +03:00

110 lines
4.2 KiB
PHP

<?php
/**
* AegisOne Engineering — Blog AJAX API
*
* Возвращает HTML-фрагмент списка статей для AJAX-подгрузки.
* Параметры: cat, page, search
*/
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../data/db-config.php';
header('Content-Type: application/json; charset=utf-8');
function getDB(): PDO {
static $pdo = null;
if ($pdo === null) {
if (DB_TYPE === 'pgsql') {
$dsn = 'pgsql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME;
} else {
$dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
}
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
}
return $pdo;
}
$pdo = getDB();
$categories = [
'audit' => 'Аудит',
'sla' => 'SLA',
'incident' => 'Инциденты',
'supervision' => 'Технадзор',
'documentation' => 'Документация',
'risk' => 'Риск-инжиниринг',
'cases' => 'Кейсы',
];
$search = trim($_GET['search'] ?? '');
$category = trim($_GET['cat'] ?? '');
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 12;
$where = "status='published'";
$params = [];
if ($category !== '' && isset($categories[$category])) {
$where .= " AND category=?";
$params[] = $category;
}
if ($search !== '') {
$where .= " AND (title LIKE ? OR excerpt LIKE ? OR content LIKE ?)";
$searchTerm = '%' . $search . '%';
$params[] = $searchTerm;
$params[] = $searchTerm;
$params[] = $searchTerm;
}
$countStmt = $pdo->prepare("SELECT COUNT(*) FROM blog_posts WHERE $where");
$countStmt->execute($params);
$totalPosts = (int)$countStmt->fetchColumn();
$totalPages = max(1, (int)ceil($totalPosts / $perPage));
$offset = ($page - 1) * $perPage;
$stmt = $pdo->prepare("SELECT bp.*, u.full_name AS author_name FROM blog_posts bp LEFT JOIN users u ON u.id=bp.author_id WHERE $where ORDER BY bp.published_at DESC LIMIT $perPage OFFSET $offset");
$stmt->execute($params);
$posts = $stmt->fetchAll();
ob_start();
if (empty($posts)): ?>
<div class="empty-state">
<h2>Записей пока нет</h2>
<p>Следите за обновлениями — мы регулярно публикуем новые статьи.</p>
</div>
<?php else: ?>
<div class="blog-grid">
<?php foreach ($posts as $p): ?>
<article class="blog-card">
<div class="cat"><?= htmlspecialchars($categories[$p['category']] ?? $p['category']) ?></div>
<h2><a href="/blog/<?= htmlspecialchars($p['slug']) ?>"><?= htmlspecialchars($p['title']) ?></a></h2>
<?php if ($p['excerpt']): ?><p><?= htmlspecialchars($p['excerpt']) ?></p><?php endif; ?>
<div class="meta">
<?= $p['published_at'] ? date('d.m.Y', strtotime($p['published_at'])) : date('d.m.Y', strtotime($p['created_at'])) ?>
<?= $p['author_name'] ? ' · ' . htmlspecialchars($p['author_name']) : '' ?>
</div>
</article>
<?php endforeach; ?>
</div>
<?php if ($totalPages > 1): ?>
<div class="pagination">
<?php if ($page > 1): ?>
<a href="#" data-page="<?= $page - 1 ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>">← Назад</a>
<?php endif; ?>
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
<a href="#" data-page="<?= $i ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>" class="<?= $i === $page ? 'current' : '' ?>"><?= $i ?></a>
<?php endfor; ?>
<?php if ($page < $totalPages): ?>
<a href="#" data-page="<?= $page + 1 ?>" data-cat="<?= htmlspecialchars($category) ?>" data-search="<?= htmlspecialchars($search) ?>">Вперёд →</a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif;
$html = ob_get_clean();
echo json_encode(['html' => $html, 'totalPages' => $totalPages, 'currentPage' => $page, 'category' => $category], JSON_UNESCAPED_UNICODE);