mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 03:29:19 +02:00
perf+a11y: WAL mode for SQLite, skip links, :focus-visible, .sr-only
SQLite performance (Database::__construct): - PRAGMA journal_mode = WAL: eliminates full-DB read locks on write, safe for concurrent PHP-FPM workers - PRAGMA synchronous = NORMAL: durable on commit without full fsync per write - PRAGMA cache_size = -8000: ~8 MB page cache per connection Accessibility foundation (WCAG 2.1 AA): - common.css: add .sr-only utility, .skip-link (hidden until focused), global :focus-visible (2px purple outline, 2px offset), prefers-reduced-motion guard; remove bare outline:none from .site-search__input - admin.css: same :focus-visible, skip-link, and motion guard scoped to admin purple; remove outline:none from .admin-input/.admin-select/ .admin-textarea and .admin-filters select (both had :focus border rules already, so focus is still visually communicated) - search.css: remove outline:none from .search-filter-select (already has :focus border-color rule) - All 5 public pages (index, search, tfe, apropos, licence): add <a href="#main-content" class="skip-link"> as first child of <body>; add id="main-content" to <main> - templates/admin/head.php: same skip link; aria-label="Navigation admin" on <nav>; id="main-content" on all 10 admin <main> elements All 4 test suites pass (unit, integration, security, rate-limit).
This commit is contained in:
31
TODO.md
31
TODO.md
@@ -347,7 +347,7 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
|||||||
|
|
||||||
### A — SQLite / Query performance
|
### A — SQLite / Query performance
|
||||||
|
|
||||||
- [ ] **WAL mode** — set `PRAGMA journal_mode = WAL` and `PRAGMA synchronous = NORMAL` in `Database::__construct()` after `foreign_keys = ON`.
|
- [x] **WAL mode** — set `PRAGMA journal_mode = WAL` and `PRAGMA synchronous = NORMAL` in `Database::__construct()` after `foreign_keys = ON`.
|
||||||
Eliminates full-database read-locks on every write; makes concurrent PHP-FPM workers safe.
|
Eliminates full-database read-locks on every write; makes concurrent PHP-FPM workers safe.
|
||||||
Also add `PRAGMA cache_size = -8000` (≈8 MB page cache) while there.
|
Also add `PRAGMA cache_size = -8000` (≈8 MB page cache) while there.
|
||||||
|
|
||||||
@@ -1308,27 +1308,14 @@ Current state: **zero ARIA attributes, zero skip links, zero focus-visible style
|
|||||||
|
|
||||||
These are things that must be added once and apply everywhere:
|
These are things that must be added once and apply everywhere:
|
||||||
|
|
||||||
- [ ] **Add `.sr-only` utility class to `common.css`** — needed for skip links, visually-hidden
|
- [x] **Add `.sr-only` utility class to `common.css`** — needed for skip links, visually-hidden
|
||||||
labels, and screen-reader-only context text referenced throughout this audit:
|
labels, and screen-reader-only context text referenced throughout this audit.
|
||||||
```css
|
|
||||||
.sr-only {
|
|
||||||
position: absolute;
|
|
||||||
width: 1px;
|
|
||||||
height: 1px;
|
|
||||||
padding: 0;
|
|
||||||
margin: -1px;
|
|
||||||
overflow: hidden;
|
|
||||||
clip: rect(0,0,0,0);
|
|
||||||
white-space: nowrap;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Add skip-to-content link in all page templates** — as described in 2.4.1 above. This
|
- [x] **Add skip-to-content link in all page templates** — added to all 5 public pages and
|
||||||
one change has the highest impact-per-line-of-code ratio of any item in this audit.
|
admin head template; `id="main-content"` added to every `<main>` in the codebase.
|
||||||
|
|
||||||
- [ ] **Add global `:focus-visible` rule in `common.css` and `admin.css`** — as described in
|
- [x] **Add global `:focus-visible` rule in `common.css` and `admin.css`** — consistent
|
||||||
2.4.7. Second highest impact item.
|
2px purple outline with 2px offset; `prefers-reduced-motion` guard also added.
|
||||||
|
|
||||||
- [ ] **Remove all `outline: none` declarations that have no replacement focus style** —
|
- [x] **Remove all `outline: none` declarations that have no replacement focus style** —
|
||||||
`common.css:125`, `admin.css:121`, `admin.css:323`, `search.css:241`.
|
removed from `common.css`, `admin.css` (×2), and `search.css`.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ if (empty($_SESSION['csrf_token'])) {
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Compte administrateur</h1>
|
<h1 class="admin-page-title">Compte administrateur</h1>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function wasSelected($key, $value) {
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Ajouter un TFE</h1>
|
<h1 class="admin-page-title">Ajouter un TFE</h1>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ try {
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Modifier un TFE</h1>
|
<h1 class="admin-page-title">Modifier un TFE</h1>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Importer une liste de TFE</h1>
|
<h1 class="admin-page-title">Importer une liste de TFE</h1>
|
||||||
|
|
||||||
<?php if (!empty($errors)): ?>
|
<?php if (!empty($errors)): ?>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Liste des TFE</h1>
|
<h1 class="admin-page-title">Liste des TFE</h1>
|
||||||
|
|
||||||
<?php if (isset($_SESSION['error'])): ?>
|
<?php if (isset($_SESSION['error'])): ?>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ $pageTitle = "Éditer : " . htmlspecialchars($page['title']);
|
|||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Éditer : <?= htmlspecialchars($page['title']) ?></h1>
|
<h1 class="admin-page-title">Éditer : <?= htmlspecialchars($page['title']) ?></h1>
|
||||||
|
|
||||||
<form action="/admin/actions/page.php" method="post" class="admin-form">
|
<form action="/admin/actions/page.php" method="post" class="admin-form">
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ unset($_SESSION['success']);
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Pages statiques</h1>
|
<h1 class="admin-page-title">Pages statiques</h1>
|
||||||
|
|
||||||
<?php if ($success): ?>
|
<?php if ($success): ?>
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ require_once APP_ROOT . '/templates/admin/head.php';
|
|||||||
.nginx-location { color: #79dac8; }
|
.nginx-location { color: #79dac8; }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Système</h1>
|
<h1 class="admin-page-title">Système</h1>
|
||||||
|
|
||||||
<p class="sys-refresh-note">
|
<p class="sys-refresh-note">
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ unset($_SESSION['admin_error'], $_SESSION['admin_success']);
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Mots-clés (<?= count($tags) ?>)</h1>
|
<h1 class="admin-page-title">Mots-clés (<?= count($tags) ?>)</h1>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ $pageTitle = "Récapitulatif TFE";
|
|||||||
?>
|
?>
|
||||||
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
<?php require_once APP_ROOT . '/templates/admin/head.php'; ?>
|
||||||
|
|
||||||
<main class="admin-main">
|
<main class="admin-main" id="main-content">
|
||||||
<h1 class="admin-page-title">Récapitulatif TFE</h1>
|
<h1 class="admin-page-title">Récapitulatif TFE</h1>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
|
|||||||
@@ -46,11 +46,12 @@ $aboutHtml = $pd->text($rawContent);
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</head>
|
</head>
|
||||||
<body class="apropos-body">
|
<body class="apropos-body">
|
||||||
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||||
|
|
||||||
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
||||||
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
||||||
|
|
||||||
<main class="apropos-main">
|
<main class="apropos-main" id="main-content">
|
||||||
<div class="apropos-layout">
|
<div class="apropos-layout">
|
||||||
|
|
||||||
<!-- LEFT: main text (from DB, Markdown-rendered) -->
|
<!-- LEFT: main text (from DB, Markdown-rendered) -->
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ html, body {
|
|||||||
font-size: 0.92rem;
|
font-size: 0.92rem;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
padding: 0.4rem 0;
|
padding: 0.4rem 0;
|
||||||
outline: none;
|
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
transition: border-color 0.15s;
|
transition: border-color 0.15s;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
@@ -320,7 +319,6 @@ html, body {
|
|||||||
font-size: 0.88rem;
|
font-size: 0.88rem;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
padding: 0.45rem 0.75rem;
|
padding: 0.45rem 0.75rem;
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,3 +806,42 @@ html, body {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
ACCESSIBILITY UTILITIES
|
||||||
|
============================================================ */
|
||||||
|
|
||||||
|
/* Consistent keyboard-focus outline for admin interactive elements */
|
||||||
|
:focus-visible {
|
||||||
|
outline: 2px solid var(--admin-purple);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip-to-admin-content link */
|
||||||
|
.skip-link {
|
||||||
|
position: absolute;
|
||||||
|
top: -999px;
|
||||||
|
left: 1rem;
|
||||||
|
z-index: 9999;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
background: var(--admin-purple);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skip-link:focus {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Respect user motion preferences */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ a:hover {
|
|||||||
.site-search__input {
|
.site-search__input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
color: var(--black);
|
color: var(--black);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -133,3 +132,55 @@ a:hover {
|
|||||||
.site-search__input::placeholder {
|
.site-search__input::placeholder {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
ACCESSIBILITY UTILITIES
|
||||||
|
============================================================ */
|
||||||
|
|
||||||
|
/* Visually-hidden but screen-reader-accessible */
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip-to-content link (visible only on keyboard focus) */
|
||||||
|
.skip-link {
|
||||||
|
position: absolute;
|
||||||
|
top: -999px;
|
||||||
|
left: 1rem;
|
||||||
|
z-index: 9999;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
background: var(--purple);
|
||||||
|
color: var(--white);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skip-link:focus {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consistent keyboard-focus outline for all interactive elements */
|
||||||
|
:focus-visible {
|
||||||
|
outline: 2px solid var(--purple);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Respect user motion preferences */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -238,7 +238,6 @@ html, body {
|
|||||||
padding: 0.2rem 0.5rem;
|
padding: 0.2rem 0.5rem;
|
||||||
background: var(--white);
|
background: var(--white);
|
||||||
color: var(--black);
|
color: var(--black);
|
||||||
outline: none;
|
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ $currentNav = '';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</head>
|
</head>
|
||||||
<body class="home-body">
|
<body class="home-body">
|
||||||
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||||
|
|
||||||
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
||||||
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
||||||
@@ -97,7 +98,7 @@ $currentNav = '';
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<main class="home-main">
|
<main class="home-main" id="main-content">
|
||||||
<div class="cards-container">
|
<div class="cards-container">
|
||||||
<?php foreach ($itemsToLoad as $item): ?>
|
<?php foreach ($itemsToLoad as $item): ?>
|
||||||
<a href="tfe.php?id=<?= (int)$item["id"] ?>" class="card-link">
|
<a href="tfe.php?id=<?= (int)$item["id"] ?>" class="card-link">
|
||||||
|
|||||||
@@ -41,11 +41,12 @@ $html = $pd->text($content);
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</head>
|
</head>
|
||||||
<body class="apropos-body">
|
<body class="apropos-body">
|
||||||
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||||
|
|
||||||
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
||||||
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
||||||
|
|
||||||
<main class="apropos-main">
|
<main class="apropos-main" id="main-content">
|
||||||
<div class="apropos-layout">
|
<div class="apropos-layout">
|
||||||
<div class="apropos-left">
|
<div class="apropos-left">
|
||||||
<div class="apropos-description apropos-page-content">
|
<div class="apropos-description apropos-page-content">
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ $searchBarValue = $_GET['query'] ?? '';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</head>
|
</head>
|
||||||
<body class="search-body">
|
<body class="search-body">
|
||||||
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||||
|
|
||||||
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
||||||
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
||||||
@@ -140,7 +141,7 @@ $searchBarValue = $_GET['query'] ?? '';
|
|||||||
<a href="search.php" class="search-reset-link">Réinitialiser</a>
|
<a href="search.php" class="search-reset-link">Réinitialiser</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<main class="search-main">
|
<main class="search-main" id="main-content">
|
||||||
<div class="search-results-view">
|
<div class="search-results-view">
|
||||||
<p class="search-results-header"><?= $totalItems ?> résultat<?= $totalItems > 1 ? 's' : '' ?></p>
|
<p class="search-results-header"><?= $totalItems ?> résultat<?= $totalItems > 1 ? 's' : '' ?></p>
|
||||||
|
|
||||||
@@ -173,7 +174,7 @@ $searchBarValue = $_GET['query'] ?? '';
|
|||||||
|
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<!-- ── RÉPERTOIRE INDEX VIEW ─────────────────────────── -->
|
<!-- ── RÉPERTOIRE INDEX VIEW ─────────────────────────── -->
|
||||||
<main class="search-main">
|
<main class="search-main" id="main-content">
|
||||||
<div class="repertoire-index">
|
<div class="repertoire-index">
|
||||||
|
|
||||||
<!-- ANNÉES -->
|
<!-- ANNÉES -->
|
||||||
|
|||||||
@@ -39,11 +39,12 @@ $currentNav = '';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</head>
|
</head>
|
||||||
<body class="tfe-body">
|
<body class="tfe-body">
|
||||||
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||||
|
|
||||||
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
<?php include APP_ROOT . '/templates/nav.php'; ?>
|
||||||
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
<?php include APP_ROOT . '/templates/search-bar.php'; ?>
|
||||||
|
|
||||||
<main class="tfe-main">
|
<main class="tfe-main" id="main-content">
|
||||||
<div class="tfe-layout">
|
<div class="tfe-layout">
|
||||||
|
|
||||||
<!-- LEFT: info -->
|
<!-- LEFT: info -->
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ class Database {
|
|||||||
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
// Enable foreign key constraints
|
// Enable foreign key constraints + performance pragmas
|
||||||
$this->pdo->exec('PRAGMA foreign_keys = ON');
|
$this->pdo->exec('PRAGMA foreign_keys = ON');
|
||||||
|
$this->pdo->exec('PRAGMA journal_mode = WAL');
|
||||||
|
$this->pdo->exec('PRAGMA synchronous = NORMAL');
|
||||||
|
$this->pdo->exec('PRAGMA cache_size = -8000');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
error_log("Database connection failed: " . $e->getMessage());
|
error_log("Database connection failed: " . $e->getMessage());
|
||||||
throw new Exception("Impossible de se connecter à la base de données.");
|
throw new Exception("Impossible de se connecter à la base de données.");
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[1774547615,1774547646]
|
[1774615474]
|
||||||
BIN
storage/test.db
BIN
storage/test.db
Binary file not shown.
@@ -18,7 +18,8 @@
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</head>
|
</head>
|
||||||
<body class="admin-body">
|
<body class="admin-body">
|
||||||
<nav class="admin-nav">
|
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||||
|
<nav class="admin-nav" aria-label="Navigation admin">
|
||||||
<a href="/admin/" class="admin-nav__logo">Posterg</a>
|
<a href="/admin/" class="admin-nav__logo">Posterg</a>
|
||||||
<?php
|
<?php
|
||||||
$currentPage = basename($_SERVER['PHP_SELF']);
|
$currentPage = basename($_SERVER['PHP_SELF']);
|
||||||
|
|||||||
Reference in New Issue
Block a user