feat: basic themes for event sites

This commit is contained in:
Björn Fromme
2026-03-16 12:00:56 +01:00
parent c7a27f1dc7
commit ee84690cd9
28 changed files with 1158 additions and 157 deletions
@@ -72,6 +72,9 @@ class IndexController extends AbstractController
// Store optional return URL in session (defaults to main EP site)
$this->bookingService->storeReturnUrl($request, $params->returnUrl);
// Store theme for consistent styling throughout the booking flow
$this->bookingService->storeTheme($request, $params->theme);
// Create fresh booking session with the provided parameters
$bookingDto = $this->bookingService->startFreshBooking($request, $dateId, $hotelId, $agencyId);
@@ -158,7 +158,6 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
if (true === $service->mandatory) {
$attributes['checked'] = true;
$attributes['readonly'] = true;
$attributes['class'] = 'text-pink';
$attributes['data-tooltip'] = 'Diese Leistung ist nicht abwählbar';
}
+2 -1
View File
@@ -25,5 +25,6 @@ readonly class BookingQueryParams
#[SerializedName('r')]
public ?string $returnUrl = null,
) {}
) {
}
}
+29
View File
@@ -20,6 +20,8 @@ class BookingService
public const BOOKING_EDIT_KEY = 'booking_edit';
public const RETURN_URL_KEY = 'booking_return_url';
public const DEFAULT_RETURN_URL = 'https://www.ep-reisen.de';
public const THEME_KEY = 'booking_theme';
public const DEFAULT_THEME = 'base';
public function __construct(
private readonly TravelDataService $travelDataService,
@@ -188,6 +190,33 @@ class BookingService
return $request->getSession()->get(self::RETURN_URL_KEY, self::DEFAULT_RETURN_URL);
}
/**
* Stores the theme identifier in the session.
*
* Sanitizes the theme value to allow only alphanumeric characters and hyphens.
* Falls back to the default theme if empty or invalid.
*/
public function storeTheme(Request $request, string $theme): void
{
$sanitized = preg_replace('/[^a-zA-Z0-9-]/', '', $theme);
if ('' === $sanitized) {
$sanitized = self::DEFAULT_THEME;
}
$request->getSession()->set(self::THEME_KEY, $sanitized);
}
/**
* Retrieves the theme identifier from the session.
*
* Returns the default theme if not set in session.
*/
public function getTheme(Request $request): string
{
return $request->getSession()->get(self::THEME_KEY, self::DEFAULT_THEME);
}
/**
* Creates a fresh booking session with the provided travel parameters.
*
+1
View File
@@ -30,6 +30,7 @@ class AppExtension extends AbstractExtension
new TwigFunction('is_static_text', [AppRuntime::class, 'isStaticText']),
new TwigFunction('is_hidden', [AppRuntime::class, 'isHidden']),
new TwigFunction('collect_invalid_field_labels', [AppRuntime::class, 'collectInvalidFieldLabels']),
new TwigFunction('booking_theme', [AppRuntime::class, 'getBookingTheme']),
];
}
}
+18
View File
@@ -6,8 +6,10 @@ use App\BusProNet\DataProvider\CountryDataProvider;
use App\Form\Model\BookingDto;
use App\Form\Service\CreateFieldStateProvider;
use App\Form\Service\EditFieldStateProvider;
use App\Service\BookingService;
use App\Service\ParticipantEligibilityService;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\RequestStack;
use Twig\Environment;
use Twig\Extension\RuntimeExtensionInterface;
use Twig\Extra\Intl\IntlExtension;
@@ -20,6 +22,7 @@ class AppRuntime implements RuntimeExtensionInterface
private readonly ParticipantEligibilityService $participantEligibilityService,
private readonly CreateFieldStateProvider $createFieldStateProvider,
private readonly EditFieldStateProvider $editFieldStateProvider,
private readonly RequestStack $requestStack,
private readonly string $environment,
) {
}
@@ -211,6 +214,21 @@ class AppRuntime implements RuntimeExtensionInterface
return $labels;
}
/**
* Returns the current booking theme from session.
*
* Defaults to 'base' if no theme is set.
*/
public function getBookingTheme(): string
{
$request = $this->requestStack->getCurrentRequest();
if (null === $request) {
return BookingService::DEFAULT_THEME;
}
return $request->getSession()->get(BookingService::THEME_KEY, BookingService::DEFAULT_THEME);
}
/**
* Gets the appropriate field state provider based on booking mode.
*