Files
folio/public/feed.php
cedricAbonnel 16965ee8cb feat : DATA_PATH configurable, DataGit auto-commit, UpdateChecker branche (v1.4.0)
- DATA_PATH : chemin /data hors document root, configurable via .env
  (fallback sur BASE_PATH/data si absent)
- DataGit : auto-commit git sur toutes les écritures articles/livres
  (create, update, delete, meta, tags, fichiers, liens…) sauf autosave
- UpdateChecker : getBranch() / getLastChecked() / clearCache(),
  branche configurable via FOLIO_UPDATE_BRANCH (plus de main hardcodé)
- Admin dashboard : affiche la branche suivie, date du dernier contrôle,
  bouton Vérifier pour forcer le check sans attendre le TTL
- CLAUDE.md : architecture DATA_PATH et flux de déploiement documentés

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:17:55 +02:00

111 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
define('BASE_PATH', realpath(__DIR__ . '/../'));
require_once BASE_PATH . '/src/auth.php';
require_once BASE_PATH . '/src/SiteSettings.php';
require_once BASE_PATH . '/config/config.php';
require_once BASE_PATH . '/src/ArticleManager.php';
require_once BASE_PATH . '/src/Parsedown.php';
const FEED_PAGE_SIZE = 20;
$articles = new ArticleManager(DATA_PATH);
$privateCats = $articles->getPrivateCategories();
$Parsedown = new Parsedown();
$now = time();
$base = rtrim(APP_URL, '/');
$all = array_values(array_filter(
$articles->getAll(publishedOnly: true),
static function (array $a) use ($now, $privateCats): bool {
if (strtotime((string)($a['published_at'] ?? '')) > $now) {
return false;
}
$cat = trim($a['category'] ?? '');
return $cat === '' || !in_array($cat, $privateCats, true);
}
));
// ─── Pagination curseur ──────────────────────────────────────────────────────
$after = trim($_GET['after'] ?? '');
$offset = 0;
if ($after !== '') {
foreach ($all as $i => $a) {
if ($a['uuid'] === $after) {
$offset = $i + 1;
break;
}
}
}
$items = array_slice($all, $offset, FEED_PAGE_SIZE);
$nextCursor = (count($all) > $offset + FEED_PAGE_SIZE)
? ($all[$offset + FEED_PAGE_SIZE - 1]['uuid'] ?? null)
: null;
$feedUrl = $base . '/feed';
$feedNextUrl = $nextCursor !== null ? $base . '/feed/' . $nextCursor : null;
// ─── lastBuildDate ───────────────────────────────────────────────────────────
$lastBuild = '';
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);
}
}
if ($lastBuild === '') {
$lastBuild = date(DATE_RSS);
}
header('Content-Type: application/rss+xml; charset=UTF-8');
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"
xmlns:fh="http://purl.org/syndication/history/1.0">
<channel>
<title><?= htmlspecialchars(siteTitle()) ?></title>
<link><?= htmlspecialchars($base) ?></link>
<description><?= htmlspecialchars(siteClaim()) ?></description>
<language><?= htmlspecialchars(siteLang()) ?></language>
<lastBuildDate><?= htmlspecialchars($lastBuild) ?></lastBuildDate>
<atom:link href="<?= htmlspecialchars($feedUrl) ?>" rel="self" type="application/rss+xml"/>
<?php if ($offset > 0): ?>
<atom:link href="<?= htmlspecialchars($feedUrl) ?>" rel="first" type="application/rss+xml"/>
<?php endif; ?>
<?php if ($feedNextUrl !== null): ?>
<atom:link href="<?= htmlspecialchars($feedNextUrl) ?>" rel="next" type="application/rss+xml"/>
<?php endif; ?>
<?php if ($feedNextUrl !== null || $offset > 0): ?>
<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);
$plain = preg_replace('/\s+/', ' ', strip_tags($Parsedown->text($article['content'] ?? '')));
$desc = htmlspecialchars(mb_strimwidth(trim((string)$plain), 0, 300, '…'), ENT_XML1);
$guid = htmlspecialchars($base . '/post/' . rawurlencode($article['slug'] ?? ''), ENT_XML1);
?>
<item>
<title><?= $title ?></title>
<link><?= htmlspecialchars($link) ?></link>
<description><?= $desc ?></description>
<pubDate><?= htmlspecialchars($pubDate) ?></pubDate>
<guid isPermaLink="true"><?= $guid ?></guid>
</item>
<?php endforeach; ?>
</channel>
</rss>