true, 'samesite' => 'Strict', 'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off', 'use_strict_mode' => true, ]); session_start(); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Pragma: no-cache'); header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: DENY'); header('Referrer-Policy: no-referrer'); header('Permissions-Policy: camera=(), microphone=(), geolocation=()'); header("Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; base-uri 'self'; frame-ancestors 'none'"); require_once __DIR__ . '/inc/db.inc.php'; if (!isset($_SESSION['admin_id'])) { http_response_code(403); exit('Zugriff verweigert.'); } $dsn = sprintf( 'mysql:host=%s;port=%d;dbname=%s;charset=%s', $dbConfig['host'], $dbConfig['port'], $dbConfig['database'], $dbConfig['charset'] ); $pdo = new PDO($dsn, $dbConfig['username'], $dbConfig['password'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, ]); $adminCheck = $pdo->prepare( 'SELECT id FROM admin_users WHERE id = :id AND is_active = 1 LIMIT 1' ); $adminCheck->execute([':id' => (int) $_SESSION['admin_id']]); if ($adminCheck->fetchColumn() === false) { http_response_code(403); exit('Zugriff verweigert.'); } function exportAccommodation(?string $value): string { return match ($value) { 'single' => 'Einzelzimmer', 'double' => 'Doppelzimmer', 'multi' => 'Mehrbettzimmer', null, '' => '', default => $value, }; } function exportDay(mixed $value): string { return match ((string) $value) { '1' => 'Fr.', '2' => 'Sa.', '3' => 'So.', default => (string) $value, }; } function csvSafe(mixed $value): string { $value = (string) $value; return preg_match('/^[=+\-@]/', $value) === 1 ? "'" . $value : $value; } function exportMeal(mixed $value): string { return match ((string) $value) { 'breakfast' => 'Frühstück', 'lunch' => 'Mittagessen', 'coffee' => 'Kaffee', 'drinks' => 'Getränkepauschale', 'dinner' => 'Abendessen', default => (string) $value, }; } function exportEarlyDeparture(mixed $value): string { return match ((string) $value) { 'sat_breakfast' => 'Samstag nach dem Frühstück', 'sat_lunch' => 'Samstag nach dem Mittagessen', 'sat_coffee' => 'Samstag nach dem Kaffee', 'sat_dinner' => 'Samstag nach dem Abendessen', 'sun_breakfast' => 'Sonntag nach dem Frühstück', default => (string) $value, }; } $rows = $pdo->query( 'SELECT p.name, p.email, p.role, p.under_27, p.allergies, b.type, b.accommodation_type, b.meal_preferences, b.is_paid, b.total_price, b.roommate_requests, b.early_departure, b.other_notes FROM bookings b INNER JOIN participants p ON p.id = b.participant_id ORDER BY b.id DESC' )->fetchAll(PDO::FETCH_ASSOC); header('Content-Type: text/csv; charset=UTF-8'); header('Content-Disposition: attachment; filename="registrierungen.csv"'); header('Cache-Control: no-store, no-cache, must-revalidate'); echo "\xEF\xBB\xBF"; $output = fopen('php://output', 'wb'); fputcsv($output, [ 'Name', 'E-Mail', 'Altersgruppe', 'Bezahlt', 'Preis', 'Gasttyp', 'Zimmerart', 'Zimmerpartner-Wunsch', 'Frühzeitige Abreise', 'Anwesenheitstage', 'Mahlzeiten', 'Allergien / Essensvorlieben', 'Sonstiges', ], ';', '"', '\\'); foreach ($rows as $row) { $mealData = $row['meal_preferences'] !== null ? json_decode($row['meal_preferences'], true) : null; $daysRaw = is_array($mealData['days'] ?? null) ? $mealData['days'] : []; $mealsByDay = is_array($mealData['meals_by_day'] ?? null) ? $mealData['meals_by_day'] : []; if ($mealsByDay === [] && is_array($mealData['meals'] ?? null)) { foreach ($daysRaw as $day) { $mealsByDay[(string) $day] = $mealData['meals']; } } $days = array_map('exportDay', $daysRaw); $meals = []; foreach ($daysRaw as $day) { $dayMeals = array_map('exportMeal', $mealsByDay[(string) $day] ?? []); $dayMeals[] = 'Getränkepauschale'; $dayMeals[] = 'Proberaumpauschale'; $meals[] = exportDay($day) . ': ' . implode(', ', $dayMeals); } fputcsv($output, [ csvSafe($row['name']), csvSafe($row['email']), csvSafe((int) $row['under_27'] === 1 ? 'Unter 27' : 'Ab 27'), csvSafe((int) $row['is_paid'] === 1 ? 'Ja' : 'Nein'), csvSafe(number_format((float) $row['total_price'], 2, ',', '.') . ' €'), csvSafe($row['role']), csvSafe(exportAccommodation($row['accommodation_type'])), csvSafe($row['roommate_requests'] ?? ''), csvSafe($row['early_departure'] !== null && $row['early_departure'] !== '' ? exportEarlyDeparture($row['early_departure']) : ''), csvSafe(implode(', ', $days)), csvSafe(implode(', ', $meals)), csvSafe($row['allergies'] ?? ''), csvSafe($row['other_notes'] ?? ''), ], ';', '"', '\\'); } fclose($output);