'text/css; charset=UTF-8', 'js' => 'application/javascript; charset=UTF-8', 'svg' => 'image/svg+xml', 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'webp' => 'image/webp', ]; header('Content-Type: ' . ($mimeTypes[$extension] ?? 'application/octet-stream')); header('Content-Length: ' . (string) filesize($file)); readfile($file); return true; } function resolveRepositories(array $config): array { $databaseFile = $config['database']['credentials_file']; if (file_exists($databaseFile)) { $databaseConfig = require $databaseFile; if (is_array($databaseConfig) && ($databaseConfig['enabled'] ?? false) === true) { try { $tablePrefix = (string) ($databaseConfig['table_prefix'] ?? $config['database']['table_prefix'] ?? ''); $dsn = sprintf( 'mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4', $databaseConfig['host'], $databaseConfig['port'] ?? 3306, $databaseConfig['database'] ); $pdo = new PDO($dsn, $databaseConfig['username'], $databaseConfig['password'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); return [ new MySqlJsonRepository($pdo, resolveTableName($tablePrefix, $config['database']['tables']['bookings'])), new MySqlJsonRepository($pdo, resolveTableName($tablePrefix, $config['database']['tables']['invoices'])), ]; } catch (Throwable $exception) { error_log('MySQL-Verbindung fehlgeschlagen, JSON-Fallback aktiv: ' . $exception->getMessage()); } } } return [ new JsonRepository($config['storage']['bookings']), new JsonRepository($config['storage']['invoices']), ]; } function resolveTableName(string $prefix, string $table): string { return $prefix . $table; } function handlePublicBooking(BookingService $bookingService): void { try { $bookingService->createPublicBooking($_POST); flash('success', 'Deine Anfrage wurde gespeichert. Wir melden uns zeitnah mit der Bestaetigung und allen Details.'); } catch (Throwable $exception) { flash('error', $exception->getMessage()); flash('old', $_POST); } redirect('/'); } function handleAdminLogin(array $adminConfig): void { $username = trim((string) ($_POST['username'] ?? '')); $password = (string) ($_POST['password'] ?? ''); if ($username === $adminConfig['username'] && hash_equals($adminConfig['password'], $password)) { $_SESSION['admin_authenticated'] = true; flash('success', 'Admin-Bereich geoeffnet.'); } else { flash('error', 'Die Admin-Zugangsdaten sind nicht korrekt.'); } redirect('/admin'); } function handleAdminLogout(): void { unset($_SESSION['admin_authenticated']); flash('success', 'Du wurdest aus dem Admin-Bereich abgemeldet.'); redirect('/admin'); } function handleAdminRequest(string $path, string $method, BookingService $bookingService): void { if (!isAdminAuthenticated()) { renderAdminLogin(); return; } if ($method === 'POST' && $path === '/admin/create') { try { $bookingService->createAdminBooking($_POST); flash('success', 'Die Bestellung wurde fuer den Kunden angelegt.'); } catch (Throwable $exception) { flash('error', $exception->getMessage()); flash('admin_old', $_POST); } redirect('/admin/create'); } if ($method === 'POST' && $path === '/admin/order/update') { try { $bookingService->updateBooking((string) ($_POST['booking_id'] ?? ''), $_POST); flash('success', 'Der Auftrag wurde aktualisiert.'); } catch (Throwable $exception) { flash('error', $exception->getMessage()); } redirect('admin/order?id=' . urlencode((string) ($_POST['booking_id'] ?? ''))); } if ($method === 'POST' && $path === '/admin/order/invoice') { try { $invoiceId = $bookingService->createInvoiceForBooking((string) ($_POST['booking_id'] ?? ''), $_POST); flash('success', 'Die Rechnung wurde erstellt.'); redirect('admin/order?id=' . urlencode((string) ($_POST['booking_id'] ?? '')) . '&invoice=' . urlencode($invoiceId)); } catch (Throwable $exception) { flash('error', $exception->getMessage()); redirect('admin/order?id=' . urlencode((string) ($_POST['booking_id'] ?? ''))); } } if ($path === '/admin/create') { renderAdminCreate($bookingService); return; } if ($path === '/admin/order') { renderAdminOrder($bookingService); return; } renderAdminDashboard($bookingService); } function handleInvoicePdf(BookingService $bookingService, InvoicePdfService $invoicePdfService): void { $invoiceId = (string) ($_GET['id'] ?? ''); $invoice = $bookingService->findInvoice($invoiceId); if ($invoice === null) { http_response_code(404); echo 'Rechnung nicht gefunden.'; return; } $pdf = $invoicePdfService->render($invoice); header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="' . $invoice['invoice_number'] . '.pdf"'); header('Content-Length: ' . strlen($pdf)); echo $pdf; } function renderHome(BookingService $bookingService, array $config): void { render('home', [ 'pageTitle' => 'Fotobox mieten', 'config' => $config, 'flashSuccess' => flash('success'), 'flashError' => flash('error'), 'old' => flash('old') ?? [], 'bookings' => $bookingService->getHighlightedBookings(), ]); } function renderAdminLogin(): void { render('admin/login', [ 'pageTitle' => 'Admin Login', 'flashSuccess' => flash('success'), 'flashError' => flash('error'), ]); } function renderAdminDashboard(BookingService $bookingService): void { render('admin/dashboard', [ 'pageTitle' => 'Admin Dashboard', 'flashSuccess' => flash('success'), 'flashError' => flash('error'), 'stats' => $bookingService->getDashboardStats(), 'bookings' => $bookingService->getBookings(), 'invoices' => $bookingService->getInvoices(), ]); } function renderAdminCreate(BookingService $bookingService): void { render('admin/create', [ 'pageTitle' => 'Kundenbestellung anlegen', 'flashSuccess' => flash('success'), 'flashError' => flash('error'), 'old' => flash('admin_old') ?? [], 'defaults' => $bookingService->getAdminDefaults(), ]); } function renderAdminOrder(BookingService $bookingService): void { $bookingId = (string) ($_GET['id'] ?? ''); $booking = $bookingService->findBooking($bookingId); if ($booking === null) { http_response_code(404); echo 'Auftrag nicht gefunden.'; return; } render('admin/order', [ 'pageTitle' => 'Auftrag ' . $booking['reference'], 'flashSuccess' => flash('success'), 'flashError' => flash('error'), 'booking' => $booking, 'invoice' => $booking['invoice_id'] ? $bookingService->findInvoice($booking['invoice_id']) : null, 'statusOptions' => $bookingService->getStatusOptions(), 'paymentOptions' => $bookingService->getPaymentStatusOptions(), ]); }