168 lines
5.1 KiB
PHP
168 lines
5.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
session_set_cookie_params([
|
|
'httponly' => 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);
|