Initial CAT application and deployment update

This commit is contained in:
2026-09-19 23:27:40 +00:00
commit 6684062400
22 changed files with 3690 additions and 0 deletions
+167
View File
@@ -0,0 +1,167 @@
<?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);