is emitted with hx-trigger="revealed": when it
* scrolls into view htmx fetches the next offset and swaps itself
* (outerHTML) with the next chunk of rows + a new sentinel. This keeps the
* initial payload small instead of shipping all languages at once.
*
* When $offset > 0 the fragment returns only the
rows (append mode),
* because the sentinel lives inside the existing .
*/
require_once __DIR__ . '/../../bootstrap.php';
require_once __DIR__ . '/../../src/AdminAuth.php';
AdminAuth::requireLogin();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
require_once __DIR__ . '/../../src/Database.php';
const LANGUES_PAGE_SIZE = 25;
$searchQuery = trim($_GET['q'] ?? '');
$offset = max(0, (int) ($_GET['offset'] ?? 0));
try {
$db = new Database();
$languages = $db->getLanguagesPage($searchQuery, LANGUES_PAGE_SIZE, $offset);
$total = $db->countLanguagesWithCount($searchQuery);
} catch (Exception $e) {
die('Erreur : ' . htmlspecialchars($e->getMessage()) . '
');
}
$hasMore = ($offset + count($languages)) < $total;
$nextUrl = '/admin/contenus-langues-fragment.php?offset=' . ($offset + LANGUES_PAGE_SIZE)
. ($searchQuery !== '' ? '&q=' . urlencode($searchQuery) : '');
/**
* Render one for a language row.
*/
function render_langue_row(array $lang): void
{
?>
= htmlspecialchars($lang['name']) ?>
= icon('pencil-note') ?>
= (int)$lang['thesis_count'] ?>
Chargement…
0) {
foreach ($languages as $lang) {
render_langue_row($lang);
}
render_langues_sentinel($hasMore, $nextUrl);
return;
}
// ── Initial load: full wrapper ────────────────────────────────────────────
?>
0 langue(s) sélectionnée(s)
= icon('x-close') ?>
Annuler
= icon('trash') ?>
Supprimer
= icon('link-chain') ?>
Fusionner