feat: load cms data early to display image on login page
This commit is contained in:
@@ -11,6 +11,7 @@ use App\Exception\NoRoomsAvailableException;
|
|||||||
use App\Exception\TravelNotFoundException;
|
use App\Exception\TravelNotFoundException;
|
||||||
use App\Htmx\HxTrait;
|
use App\Htmx\HxTrait;
|
||||||
use App\Service\BookingService;
|
use App\Service\BookingService;
|
||||||
|
use App\Service\BookingSummaryDataService;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@@ -30,6 +31,7 @@ class IndexController extends AbstractController
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly BookingService $bookingService,
|
private readonly BookingService $bookingService,
|
||||||
private readonly AgencyLoader $agencyLoader,
|
private readonly AgencyLoader $agencyLoader,
|
||||||
|
private readonly BookingSummaryDataService $summaryDataService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +65,13 @@ class IndexController extends AbstractController
|
|||||||
$this->bookingService->storeReturnUrl($request, $request->query->get('r'));
|
$this->bookingService->storeReturnUrl($request, $request->query->get('r'));
|
||||||
|
|
||||||
// Create fresh booking session with the provided parameters
|
// Create fresh booking session with the provided parameters
|
||||||
$this->bookingService->startFreshBooking($request, $dateId, $hotelId, $agencyId);
|
$bookingDto = $this->bookingService->startFreshBooking($request, $dateId, $hotelId, $agencyId);
|
||||||
|
|
||||||
|
// Warm the CMS cache early so data is available on the login page
|
||||||
|
$this->summaryDataService->getCmsDataForProduct(
|
||||||
|
$bookingDto->travel->productCode,
|
||||||
|
$bookingDto->travel->hotel?->code
|
||||||
|
);
|
||||||
|
|
||||||
// Redirect to login page (optional authentication before Step 1)
|
// Redirect to login page (optional authentication before Step 1)
|
||||||
return $this->redirectToRoute('app_login');
|
return $this->redirectToRoute('app_login');
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Service\BookingService;
|
use App\Service\BookingService;
|
||||||
|
use App\Service\BookingSummaryDataService;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@@ -14,8 +15,12 @@ class SecurityController extends AbstractController
|
|||||||
{
|
{
|
||||||
#[Route('/', name: 'app_login')]
|
#[Route('/', name: 'app_login')]
|
||||||
#[IsGranted('PUBLIC_ACCESS')]
|
#[IsGranted('PUBLIC_ACCESS')]
|
||||||
public function login(AuthenticationUtils $authenticationUtils, Request $request, BookingService $bookingService): Response
|
public function login(
|
||||||
{
|
AuthenticationUtils $authenticationUtils,
|
||||||
|
Request $request,
|
||||||
|
BookingService $bookingService,
|
||||||
|
BookingSummaryDataService $summaryDataService,
|
||||||
|
): Response {
|
||||||
// Check if this is a booking flow (BookingDto exists in session)
|
// Check if this is a booking flow (BookingDto exists in session)
|
||||||
$bookingDto = $bookingService->getBookingDto($request, BookingService::BOOKING_CREATE_KEY);
|
$bookingDto = $bookingService->getBookingDto($request, BookingService::BOOKING_CREATE_KEY);
|
||||||
$isBookingFlow = null !== $bookingDto;
|
$isBookingFlow = null !== $bookingDto;
|
||||||
@@ -50,12 +55,22 @@ class SecurityController extends AbstractController
|
|||||||
// Render booking login template if in booking flow, otherwise standard login
|
// Render booking login template if in booking flow, otherwise standard login
|
||||||
$template = true === $isBookingFlow ? 'booking/create/authenticate.html.twig' : 'security/login.html.twig';
|
$template = true === $isBookingFlow ? 'booking/create/authenticate.html.twig' : 'security/login.html.twig';
|
||||||
|
|
||||||
|
// Fetch CMS data for booking flow (uses cache warmed in IndexController)
|
||||||
|
$cmsData = null;
|
||||||
|
if (true === $isBookingFlow) {
|
||||||
|
$cmsData = $summaryDataService->getCmsDataForProduct(
|
||||||
|
$bookingDto->travel->productCode,
|
||||||
|
$bookingDto->travel->hotel?->code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->render($template, [
|
return $this->render($template, [
|
||||||
'last_username' => $lastUsername,
|
'last_username' => $lastUsername,
|
||||||
'error' => $error,
|
'error' => $error,
|
||||||
'travel_title' => $bookingDto?->travel->label,
|
'travel_title' => $bookingDto?->travel->label,
|
||||||
'travel_date_from' => $bookingDto?->travel->dateFrom,
|
'travel_date_from' => $bookingDto?->travel->dateFrom,
|
||||||
'travel_date_to' => $bookingDto?->travel->dateTo,
|
'travel_date_to' => $bookingDto?->travel->dateTo,
|
||||||
|
'cmsData' => $cmsData,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,21 +128,15 @@ class BookingSummaryDataService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches CMS data for the product and hotel in the booking.
|
* Fetches CMS data for a product and hotel combination.
|
||||||
*
|
*
|
||||||
* Data is cached for 1 hour as it rarely changes. Returns null
|
* Data is cached for 1 hour as it rarely changes. Returns null
|
||||||
* if the API call fails or if product/hotel codes are not available.
|
* if the API call fails or if product code is not available.
|
||||||
|
* This method can be called early in the booking flow to warm the cache.
|
||||||
*/
|
*/
|
||||||
private function getCmsData(BookingDto $bookingDto): ?array
|
public function getCmsDataForProduct(?string $productCode, ?string $hotelCode): ?array
|
||||||
{
|
{
|
||||||
$productCode = $bookingDto->travel->productCode;
|
|
||||||
$hotelCode = $bookingDto->travel->hotel?->code;
|
|
||||||
|
|
||||||
if (null === $productCode) {
|
if (null === $productCode) {
|
||||||
$this->logger->debug('Cannot fetch CMS data: product code is not available', [
|
|
||||||
'travel_id' => $bookingDto->travel->id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,4 +171,23 @@ class BookingSummaryDataService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches CMS data for the product and hotel in the booking.
|
||||||
|
*/
|
||||||
|
private function getCmsData(BookingDto $bookingDto): ?array
|
||||||
|
{
|
||||||
|
$productCode = $bookingDto->travel->productCode;
|
||||||
|
$hotelCode = $bookingDto->travel->hotel?->code;
|
||||||
|
|
||||||
|
if (null === $productCode) {
|
||||||
|
$this->logger->debug('Cannot fetch CMS data: product code is not available', [
|
||||||
|
'travel_id' => $bookingDto->travel->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getCmsDataForProduct($productCode, $hotelCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,16 @@
|
|||||||
Neue<br>Buchung
|
Neue<br>Buchung
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="text-white uppercase pb-4 ld:pb-8">
|
<div class="text-white uppercase pb-4 lg:pb-8">
|
||||||
{{ travel_title }}
|
{{ travel_title }}
|
||||||
<br>
|
<br>
|
||||||
{{ travel_date_from | date('d.m.Y') }} - {{ travel_date_to | date('d.m.Y') }}
|
{{ travel_date_from | date('d.m.Y') }} - {{ travel_date_to | date('d.m.Y') }}
|
||||||
|
<br>
|
||||||
|
{% if cmsData.hotel.images is defined %}
|
||||||
|
<img src="{{ cmsData.hotel.images.resized.l[0].url }}"
|
||||||
|
alt="{{ cmsData.hotel.images.resized.l[0].alt }}"
|
||||||
|
class="block w-full max-w-64 h-auto mt-4">
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
|||||||
Reference in New Issue
Block a user