Globinours/app/Controllers/AdminController.php

101 lines
4.2 KiB
PHP

<?php
class AdminController
{
public static function exports(): void
{
self::adminOnly();
render('admin_exports.php', ['title' => t('admin.exports_title'), 'datasets' => ExportService::catalog()]);
}
public static function downloadExport(): void
{
self::adminOnly();
$type = (string) ($_GET['type'] ?? '');
try {
AuditService::log(
'data_export',
'/admin/exports/download',
$type === 'all' ? 'Export complet des données' : 'Export CSV : ' . $type,
);
if ($type === 'all') {
ExportService::downloadZip();
} else {
ExportService::downloadCsv($type);
}
} catch (InvalidArgumentException) {
http_response_code(404);
echo h(t('admin.unknown_export'));
} catch (Throwable $e) {
error_log('Échec export ' . $type . ' : ' . $e->getMessage());
http_response_code(500);
echo h(t('admin.export_failed'));
}
}
public static function register(): void
{
[$rows, $year, $q, $species, $sort, $dir] = self::registerData();
render(
'admin_register.php',
compact('rows', 'year', 'q', 'species', 'sort', 'dir') + ['title' => t('admin.title')],
);
}
public static function registerPdf(): void
{
[$rows, $year, $q, $species, $sort, $dir] = self::registerData();
$generatedAt = new DateTimeImmutable('now', new DateTimeZone('Europe/Paris'));
header('Content-Type: text/html; charset=UTF-8');
require __DIR__ . '/../Views/admin_register_print.php';
}
private static function registerData(): array
{
$pdo = DB::pdo();
$year = isset($_GET['year']) ? (int) $_GET['year'] : (int) date('Y');
$q = trim((string) ($_GET['q'] ?? ''));
$species = trim((string) ($_GET['species'] ?? ''));
$allowedSort = [
'date' => 'm.created_at',
'name' => 'a.name',
'species' => 'a.species',
'sex' => 'a.sex',
'type' => 'm.kind',
];
$sort = (string) ($_GET['sort'] ?? 'date');
if (!isset($allowedSort[$sort])) {
$sort = 'date';
}
$dir = strtolower((string) ($_GET['dir'] ?? 'asc')) === 'desc' ? 'desc' : 'asc';
$sql = "SELECT m.*, a.id AS animal_id, a.internal_code, a.name, a.sex, a.species, a.birth_date, a.chip_id,
d.cause_code death_cause_code,d.cause_details death_cause_details,d.euthanized death_euthanized,d.body_disposition death_disposition,d.cremation_date,
vet.name death_veterinarian,crem.name death_crematorium
FROM animal_movements m JOIN animals a ON a.id=m.animal_id
LEFT JOIN animal_deaths d ON d.animal_id=m.animal_id AND m.kind='exit' AND lower(m.lieu) IN ('décès','deces','décès de l''animal','deces de l''animal')
LEFT JOIN directory_contacts vet ON vet.id=d.veterinarian_contact_id
LEFT JOIN directory_contacts crem ON crem.id=d.crematorium_contact_id
WHERE a.deleted_at IS NULL AND a.archived_at IS NULL
AND m.created_at BETWEEN :ys AND :ye";
$params = [':ys' => sprintf('%04d-01-01 00:00:00', $year), ':ye' => sprintf('%04d-12-31 23:59:59', $year)];
if ($q !== '') {
$sql .= ' AND (a.name LIKE :q OR a.internal_code LIKE :q OR a.chip_id LIKE :q)';
$params[':q'] = "%$q%";
}
if ($species !== '') {
$sql .= ' AND lower(a.species)=:species';
$params[':species'] = strtolower($species);
}
$sql .= ' ORDER BY ' . $allowedSort[$sort] . ' ' . strtoupper($dir);
$statement = $pdo->prepare($sql);
$statement->execute($params);
return [$statement->fetchAll(PDO::FETCH_ASSOC), $year, $q, $species, $sort, $dir];
}
private static function adminOnly(): void
{
if (!PermissionService::can('administrative', 'view')) {
http_response_code(403);
echo h(t('admin.forbidden'));
exit();
}
}
}