Initial CAT application and deployment update
This commit is contained in:
+167
@@ -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);
|
||||
Reference in New Issue
Block a user