feat: flux RSS pagine (20 items/page), aliases /rss et /rss.xml, fix migration booleen PostgreSQL

This commit is contained in:
Cedric Abonnel
2026-05-08 22:58:26 +02:00
parent 9cde19fe42
commit 35503e43b0
56 changed files with 99 additions and 68 deletions
+41 -12
View File
@@ -14,20 +14,29 @@ require_once BASE_PATH . '/src/auth.php';
require_once BASE_PATH . '/config/config.php';
require_once BASE_PATH . '/src/ArticleManager.php';
const FEED_PAGE_SIZE = 20;
$articles = new ArticleManager(BASE_PATH . '/data');
$now = time();
$base = rtrim(APP_URL, '/');
$items = array_filter(
$all = array_values(array_filter(
$articles->getAll(publishedOnly: true),
static fn (array $a): bool => strtotime((string)($a['published_at'] ?? '')) <= $now
);
));
$total = count($all);
$lastPage = max(1, (int)ceil($total / FEED_PAGE_SIZE));
$page = max(1, min($lastPage, (int)($_GET['page'] ?? 1)));
$items = array_slice($all, ($page - 1) * FEED_PAGE_SIZE, FEED_PAGE_SIZE);
$feedUrl = static fn (int $p): string => $base . '/feed' . ($p > 1 ? '?page=' . $p : '');
$lastBuild = '';
foreach ($items as $a) {
$ts = strtotime((string)($a['updated_at'] ?? $a['published_at'] ?? ''));
if ($ts && $ts > strtotime($lastBuild ?: '1970-01-01')) {
foreach ($all as $a) {
$ts = (int)strtotime((string)($a['updated_at'] ?? $a['published_at'] ?? ''));
if ($ts > (int)strtotime($lastBuild ?: '1970-01-01')) {
$lastBuild = date(DATE_RSS, $ts);
}
}
@@ -40,20 +49,40 @@ header('X-Content-Type-Options: nosniff');
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:fh="http://purl.org/syndication/history/1.0">
<channel>
<title>varlog</title>
<link><?= htmlspecialchars($base) ?></link>
<description>Journal personnel de Cédrix — informatique, hack et loisirs techniques.</description>
<language>fr</language>
<lastBuildDate><?= htmlspecialchars($lastBuild) ?></lastBuildDate>
<atom:link href="<?= htmlspecialchars($base . '/feed') ?>" rel="self" type="application/rss+xml"/>
<!-- Flux canonique (toujours page 1) -->
<atom:link href="<?= htmlspecialchars($feedUrl(1)) ?>" rel="self" type="application/rss+xml"/>
<?php if ($page > 1): ?>
<!-- Navigation entre pages -->
<atom:link href="<?= htmlspecialchars($feedUrl(1)) ?>" rel="first" type="application/rss+xml"/>
<atom:link href="<?= htmlspecialchars($feedUrl($page - 1)) ?>" rel="previous" type="application/rss+xml"/>
<?php endif; ?>
<?php if ($page < $lastPage): ?>
<atom:link href="<?= htmlspecialchars($feedUrl($page + 1)) ?>" rel="next" type="application/rss+xml"/>
<atom:link href="<?= htmlspecialchars($feedUrl($lastPage)) ?>" rel="last" type="application/rss+xml"/>
<?php endif; ?>
<?php if ($lastPage > 1): ?>
<!-- Métadonnées de pagination (RFC 5005) -->
<fh:archive/>
<?php endif; ?>
<?php foreach ($items as $article):
$pubDate = date(DATE_RSS, (int)strtotime((string)($article['published_at'] ?? $article['created_at'] ?? '')));
$link = $base . '/post/' . rawurlencode($article['slug'] ?? '');
$title = htmlspecialchars($article['title'] ?? '', ENT_XML1);
$desc = htmlspecialchars(mb_strimwidth(strip_tags($article['content'] ?? ''), 0, 300, '…'), ENT_XML1);
$guid = htmlspecialchars($base . '/post/' . rawurlencode($article['slug'] ?? ''), ENT_XML1);
$pubDate = date(DATE_RSS, (int)strtotime((string)($article['published_at'] ?? $article['created_at'] ?? '')));
$link = $base . '/post/' . rawurlencode($article['slug'] ?? '');
$title = htmlspecialchars($article['title'] ?? '', ENT_XML1);
$desc = htmlspecialchars(mb_strimwidth(strip_tags($article['content'] ?? ''), 0, 300, '…'), ENT_XML1);
$guid = htmlspecialchars($base . '/post/' . rawurlencode($article['slug'] ?? ''), ENT_XML1);
?>
<item>
<title><?= $title ?></title>