Ajouter les pages personnalisées au site public

This commit is contained in:
Alexandre NOEL 2026-10-12 10:42:59 +02:00
commit 21ee1bec36
17 changed files with 428 additions and 65 deletions

View file

@ -62,6 +62,7 @@ final class AppSettings
'update_last_error' => '',
'public_site_legal_text' => '',
'public_site_privacy_text' => '',
'public_site_navigation_order' => '["home","animals","about","donation","contact"]',
];
private static ?array $cache = null;
public static function all(): array

View file

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
final class PublicPageService
{
private const RESERVED = [
'site','animaux','adoption','presentation','dons','contact','mentions-legales','confidentialite',
'logo-association','login','logout','setup','dashboard','statistics','agenda','directory','settings','admin',
'accounting','inventory','care-round','animal','litter','documents','media','assets','api',
];
public static function all(bool $enabledOnly = false): array
{
$sql = 'SELECT * FROM public_site_pages' . ($enabledOnly ? ' WHERE enabled=1' : '') .
' ORDER BY sort_order,id';
return DB::pdo()->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
public static function findBySlug(string $slug, bool $enabledOnly = true): ?array
{
$slug = self::normalizeSlug($slug);
if ($slug === '') return null;
$stmt = DB::pdo()->prepare(
'SELECT * FROM public_site_pages WHERE slug=:slug' . ($enabledOnly ? ' AND enabled=1' : '') . ' LIMIT 1',
);
$stmt->execute([':slug' => $slug]);
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
}
public static function saveAll(array $pages): void
{
$db = DB::pdo();
$pages = array_values(array_filter($pages, 'is_array'));
usort($pages, static fn (array $a, array $b): int => (int) ($a['position'] ?? 0) <=> (int) ($b['position'] ?? 0));
$seenSlugs = [];
$position = 0;
foreach ($pages as $page) {
if (!is_array($page)) continue;
$id = max(0, (int) ($page['id'] ?? 0));
if (!empty($page['delete'])) {
if ($id > 0) $db->prepare('DELETE FROM public_site_pages WHERE id=?')->execute([$id]);
continue;
}
$title = mb_substr(trim((string) ($page['title'] ?? '')), 0, 150);
$slug = self::normalizeSlug((string) ($page['slug'] ?? ''));
if ($slug === '') $slug = self::normalizeSlug($title);
if ($title === '' && $slug === '' && trim((string) ($page['content'] ?? '')) === '') continue;
if ($title === '' || $slug === '' || in_array($slug, self::RESERVED, true)) {
throw new InvalidArgumentException(t('public_site.page_invalid'));
}
if (isset($seenSlugs[$slug])) throw new InvalidArgumentException(t('public_site.page_slug_duplicate'));
$seenSlugs[$slug] = true;
$duplicate = $db->prepare('SELECT id FROM public_site_pages WHERE slug=:slug AND id<>:id LIMIT 1');
$duplicate->execute([':slug' => $slug, ':id' => $id]);
if ($duplicate->fetchColumn()) throw new InvalidArgumentException(t('public_site.page_slug_duplicate'));
$content = trim((string) ($page['content'] ?? ''));
$enabled = !empty($page['enabled']) ? 1 : 0;
if ($id > 0) {
$check = $db->prepare('SELECT 1 FROM public_site_pages WHERE id=?');
$check->execute([$id]);
if (!$check->fetchColumn()) throw new InvalidArgumentException(t('public_site.page_invalid'));
$stmt = $db->prepare('UPDATE public_site_pages SET slug=:slug,title=:title,content=:content,enabled=:enabled,sort_order=:sort,updated_at=CURRENT_TIMESTAMP WHERE id=:id');
$stmt->execute([':slug'=>$slug,':title'=>$title,':content'=>$content,':enabled'=>$enabled,':sort'=>$position,':id'=>$id]);
} else {
$stmt = $db->prepare('INSERT INTO public_site_pages(slug,title,content,enabled,sort_order) VALUES(:slug,:title,:content,:enabled,:sort)');
$stmt->execute([':slug'=>$slug,':title'=>$title,':content'=>$content,':enabled'=>$enabled,':sort'=>$position]);
}
$position++;
}
}
public static function normalizeSlug(string $value): string
{
$value = mb_strtolower(trim($value), 'UTF-8');
$ascii = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
$value = $ascii === false ? $value : $ascii;
$value = preg_replace('/[^a-z0-9]+/', '-', strtolower($value)) ?? '';
return mb_substr(trim($value, '-'), 0, 80);
}
}