Initale Einrichtung
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/Support/functions.php';
|
||||
require __DIR__ . '/Repository/RecordRepositoryInterface.php';
|
||||
require __DIR__ . '/Repository/JsonRepository.php';
|
||||
require __DIR__ . '/Repository/MySqlJsonRepository.php';
|
||||
require __DIR__ . '/Services/BookingService.php';
|
||||
require __DIR__ . '/Services/InvoicePdfService.php';
|
||||
|
||||
session_start();
|
||||
|
||||
function runApplication(): void
|
||||
{
|
||||
$config = require dirname(__DIR__) . '/config.php';
|
||||
|
||||
[$bookingRepository, $invoiceRepository] = resolveRepositories($config);
|
||||
|
||||
$bookingService = new BookingService($bookingRepository, $invoiceRepository, $config);
|
||||
$invoicePdfService = new InvoicePdfService($config);
|
||||
|
||||
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
||||
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
|
||||
|
||||
if ($method === 'POST' && $path === '/book') {
|
||||
handlePublicBooking($bookingService);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($method === 'POST' && $path === '/admin/login') {
|
||||
handleAdminLogin($config['admin']);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($method === 'POST' && $path === '/admin/logout') {
|
||||
handleAdminLogout();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($path === '/admin/invoice/pdf') {
|
||||
requireAdmin();
|
||||
handleInvoicePdf($bookingService, $invoicePdfService);
|
||||
return;
|
||||
}
|
||||
|
||||
if (str_starts_with($path, '/admin')) {
|
||||
handleAdminRequest($path, $method, $bookingService);
|
||||
return;
|
||||
}
|
||||
|
||||
renderHome($bookingService, $config);
|
||||
}
|
||||
|
||||
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(),
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user