diff --git a/config/services.yaml b/config/services.yaml index e449aaf..82f738e 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -178,7 +178,7 @@ services: tags: - { name: monolog.processor } - App\Service\Newsletter\NewsletterDoubleOptInService: + App\Service\NewsletterDoubleOptInService: arguments: $newsletterConfirmationTtlHours: '%newsletter_confirmation_ttl_hours%' diff --git a/src/Controller/Booking/Create/Step2ParticipantController.php b/src/Controller/Booking/Create/Step2ParticipantController.php index 7d67f90..7bd492d 100644 --- a/src/Controller/Booking/Create/Step2ParticipantController.php +++ b/src/Controller/Booking/Create/Step2ParticipantController.php @@ -138,6 +138,8 @@ class Step2ParticipantController extends AbstractController 'form' => $form->createView(), 'participantIndex' => $index, 'bookingCreateContext' => $bookingCreateContext, + 'bookingDto' => $bookingCreateContext->bookingDto, + 'summaryData' => $bookingCreateContext->summaryData, 'refreshRouteName' => 'app_booking_create_step_2_participant_refresh', ]); } @@ -207,6 +209,8 @@ class Step2ParticipantController extends AbstractController 'form' => $form->createView(), 'participantIndex' => $index, 'bookingCreateContext' => $bookingCreateContext, + 'bookingDto' => $bookingCreateContext->bookingDto, + 'summaryData' => $bookingCreateContext->summaryData, 'refreshRouteName' => $refreshRouteName, ] ); diff --git a/src/Controller/Booking/Edit/ParticipantController.php b/src/Controller/Booking/Edit/ParticipantController.php index 1d020c2..0723275 100644 --- a/src/Controller/Booking/Edit/ParticipantController.php +++ b/src/Controller/Booking/Edit/ParticipantController.php @@ -102,6 +102,9 @@ class ParticipantController extends AbstractController 'form' => $form->createView(), 'participantIndex' => $index, 'bookingEditContext' => $context, + 'bookingDto' => $context->bookingDto, + 'summaryData' => $context->summaryData, + 'mutableData' => $context->mutableData, 'refreshRouteName' => 'app_booking_edit_participant_refresh', 'refreshRouteParams' => ['id' => $id, 'index' => $index], 'cancelRouteName' => 'app_booking_edit', @@ -158,6 +161,9 @@ class ParticipantController extends AbstractController 'form' => $form->createView(), 'participantIndex' => $index, 'bookingEditContext' => $context, + 'bookingDto' => $context->bookingDto, + 'summaryData' => $context->summaryData, + 'mutableData' => $context->mutableData, 'refreshRouteName' => 'app_booking_edit_participant_refresh', 'refreshRouteParams' => ['id' => $id, 'index' => $index], 'cancelRouteName' => 'app_booking_edit', diff --git a/src/Form/Model/BookingSummaryDto.php b/src/Form/Model/BookingSummaryDto.php index 147e72c..ae31697 100644 --- a/src/Form/Model/BookingSummaryDto.php +++ b/src/Form/Model/BookingSummaryDto.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Form\Model; +use App\Model\BookingSummaryCmsHotelDto; + /** * DTO containing all booking summary data for sidebar display. */ @@ -17,7 +19,7 @@ class BookingSummaryDto public readonly int $participantCount, public readonly BookingSummaryPricingDto $pricing, public readonly BookingSummaryVoucherDto $vouchers, - public readonly ?array $cmsData, + public readonly ?BookingSummaryCmsHotelDto $cmsData, ) { } } diff --git a/src/Model/BookingSummaryCmsHotelDto.php b/src/Model/BookingSummaryCmsHotelDto.php new file mode 100644 index 0000000..68495ed --- /dev/null +++ b/src/Model/BookingSummaryCmsHotelDto.php @@ -0,0 +1,21 @@ +|null $images + */ + public function __construct( + public ?string $name, + public ?string $address, + public ?array $images, + ) { + } +} diff --git a/src/Service/BookingSummaryDataService.php b/src/Service/BookingSummaryDataService.php index db524a5..9133cf8 100644 --- a/src/Service/BookingSummaryDataService.php +++ b/src/Service/BookingSummaryDataService.php @@ -12,6 +12,7 @@ use App\Form\Model\BookingDto; use App\Form\Model\BookingSummaryDto; use App\Form\Model\BookingSummaryPricingDto; use App\Form\Model\BookingSummaryVoucherDto; +use App\Model\BookingSummaryCmsHotelDto; use Psr\Log\LoggerInterface; use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Cache\ItemInterface; @@ -153,7 +154,7 @@ class BookingSummaryDataService * Data is cached for 1 hour. This method can be called early in the booking * flow to warm the cache. */ - public function getCmsDataForProduct(?string $productCode, ?string $hotelCode): ?array + public function getCmsDataForProduct(?string $productCode, ?string $hotelCode): ?BookingSummaryCmsHotelDto { if (null === $hotelCode) { return null; @@ -171,14 +172,11 @@ class BookingSummaryDataService // Fetch CMS images (nice to have) $images = $this->cmsDataService->getProductImages($productCode, $hotelCode); - // Return combined data structure compatible with templates - return [ - 'hotel' => [ - 'name' => $baseHotel?->name, - 'address' => $this->formatHotelAddress($baseHotel), - 'images' => $images, - ], - ]; + return new BookingSummaryCmsHotelDto( + name: $baseHotel?->name, + address: $this->formatHotelAddress($baseHotel), + images: $images, + ); }); } catch (\Throwable $e) { $this->logger->error('Failed to fetch hotel display data', [ diff --git a/templates/booking/_participant_form.html.twig b/templates/booking/_participant_form.html.twig index a9e71b0..7808013 100644 --- a/templates/booking/_participant_form.html.twig +++ b/templates/booking/_participant_form.html.twig @@ -141,10 +141,10 @@ {% endmacro %} {# Shared by booking create and edit flows; callers should pass one of the flow contexts. #} -{% set bookingFlowContext = bookingEditContext|default(bookingCreateContext|default(null)) %} -{% set bookingDto = bookingFlowContext.bookingDto %} -{% set summaryData = bookingFlowContext.summaryData %} -{% set mutableData = bookingFlowContext.mutableData|default(null) %} +{% set bookingFlowContext = bookingFlowContext|default(bookingEditContext|default(bookingCreateContext|default(null))) %} +{% set bookingDto = bookingDto|default(bookingFlowContext ? bookingFlowContext.bookingDto : null) %} +{% set summaryData = summaryData|default(bookingFlowContext ? bookingFlowContext.summaryData : null) %} +{% set mutableData = mutableData|default(bookingFlowContext and bookingFlowContext.mutableData is defined ? bookingFlowContext.mutableData : null) %} {# Standalone participant form view (replaces main content area) #} {% block participant_form %} diff --git a/templates/booking/_summary.html.twig b/templates/booking/_summary.html.twig index cbf41c1..0b461fd 100644 --- a/templates/booking/_summary.html.twig +++ b/templates/booking/_summary.html.twig @@ -69,7 +69,9 @@ - {% include 'booking/_summary_hotel.html.twig' %} + {% include 'booking/_summary_hotel.html.twig' with { + 'summaryData': summaryData + } %} {# Mutability information (edit mode only) #} {% if bookingDto.mode == constant('App\\Form\\Model\\BookingDto::MODE_EDIT') and mutableData %} diff --git a/templates/booking/_summary_hotel.html.twig b/templates/booking/_summary_hotel.html.twig index abd81b1..a74653d 100644 --- a/templates/booking/_summary_hotel.html.twig +++ b/templates/booking/_summary_hotel.html.twig @@ -1,14 +1,14 @@ -{% if summaryData.cmsData.hotel.name %} +{% if summaryData.cmsData and summaryData.cmsData.name %}
- {% if summaryData.cmsData.hotel.images.resized.l[0] is defined %} - {{ summaryData.cmsData.hotel.images.resized.l[0].alt }} {% endif %} -
- {{ summaryData.cmsData.hotel.name }} - {% if summaryData.cmsData.hotel.address %} - {{ summaryData.cmsData.hotel.address | nl2br }} +
+ {{ summaryData.cmsData.name }} + {% if summaryData.cmsData.address %} + {{ summaryData.cmsData.address | nl2br }} {% endif %}
diff --git a/templates/booking/create/authenticate.html.twig b/templates/booking/create/authenticate.html.twig index 8dff463..ed05a18 100644 --- a/templates/booking/create/authenticate.html.twig +++ b/templates/booking/create/authenticate.html.twig @@ -10,9 +10,9 @@
- {% if cmsData.hotel.images.resized.l[0] is defined %} - {{ cmsData.hotel.images.resized.l[0].alt }} {% endif %}
@@ -22,11 +22,11 @@
{{ travel_date_from | date('d.m.Y') }} - {{ travel_date_to | date('d.m.Y') }}
- {% if cmsData.hotel.name is defined and cmsData.hotel.name %} -
{{ cmsData.hotel.name }}
+ {% if cmsData and cmsData.name %} +
{{ cmsData.name }}
{% endif %} - {% if cmsData.hotel.address is defined and cmsData.hotel.address %} -
{{ cmsData.hotel.address | nl2br }}
+ {% if cmsData and cmsData.address %} +
{{ cmsData.address | nl2br }}
{% endif %}
diff --git a/templates/booking/create/step_2_participant.html.twig b/templates/booking/create/step_2_participant.html.twig index 9b202e8..0c24170 100644 --- a/templates/booking/create/step_2_participant.html.twig +++ b/templates/booking/create/step_2_participant.html.twig @@ -30,7 +30,11 @@
{# Flash messages - must be inside main-content for HTMX swap to display them #} {% include '_partials/_flashes.html.twig' %} - {% include 'booking/_participant_form.html.twig' %} + {% include 'booking/_participant_form.html.twig' with { + 'bookingCreateContext': bookingCreateContext, + 'bookingDto': bookingCreateContext.bookingDto, + 'summaryData': bookingCreateContext.summaryData + } %}
diff --git a/templates/booking/create/step_4.html.twig b/templates/booking/create/step_4.html.twig index 2fcb9e1..55f23d8 100644 --- a/templates/booking/create/step_4.html.twig +++ b/templates/booking/create/step_4.html.twig @@ -65,7 +65,9 @@ - {% include 'booking/_summary_hotel.html.twig' %} + {% include 'booking/_summary_hotel.html.twig' with { + 'summaryData': bookingCreateContext.summaryData + } %} @@ -123,7 +125,9 @@ - {% include 'booking/_summary_hotel.html.twig' %} + {% include 'booking/_summary_hotel.html.twig' with { + 'summaryData': bookingCreateContext.summaryData + } %} {# Detailed Pricing Breakdown #} diff --git a/templates/booking/edit/participant.html.twig b/templates/booking/edit/participant.html.twig index f4363ad..24520e9 100644 --- a/templates/booking/edit/participant.html.twig +++ b/templates/booking/edit/participant.html.twig @@ -29,6 +29,9 @@ {% include '_partials/_flashes.html.twig' %} {% include 'booking/_participant_form.html.twig' with { 'bookingEditContext': bookingEditContext, + 'bookingDto': bookingEditContext.bookingDto, + 'summaryData': bookingEditContext.summaryData, + 'mutableData': bookingEditContext.mutableData|default(null), 'participantIndex': participantIndex, 'refreshRouteName': refreshRouteName, 'refreshRouteParams': refreshRouteParams|default({}),