feat: reduce session payload
This commit is contained in:
@@ -325,4 +325,62 @@ class BookingDto
|
|||||||
{
|
{
|
||||||
return AgencyLoader::INTERNAL_AGENCY_CODE === $this->agencyCode;
|
return AgencyLoader::INTERNAL_AGENCY_CODE === $this->agencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls session serialization to exclude the heavy Travel object graph.
|
||||||
|
*
|
||||||
|
* Replaces the full Travel object with just its integer ID. The Booking's
|
||||||
|
* travelData reference is also removed since it points to the same object.
|
||||||
|
* BookingService::hydrate() restores the Travel from cache after session read.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function __serialize(): array
|
||||||
|
{
|
||||||
|
$data = get_object_vars($this);
|
||||||
|
|
||||||
|
// Replace the full Travel object graph with just its ID
|
||||||
|
$data['travel'] = $this->travel->id;
|
||||||
|
|
||||||
|
// Clone Booking to avoid mutating the live object, then strip its
|
||||||
|
// travelData reference which points to the same heavy Travel graph
|
||||||
|
if (null !== $this->booking) {
|
||||||
|
$booking = clone $this->booking;
|
||||||
|
$booking->travelData = null;
|
||||||
|
$data['booking'] = $booking;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the DTO from session data with a minimal Travel placeholder.
|
||||||
|
*
|
||||||
|
* Creates a Travel object containing only the ID. BookingService::hydrate()
|
||||||
|
* replaces this with the full Travel from cache on every session read.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $data
|
||||||
|
*/
|
||||||
|
public function __unserialize(array $data): void
|
||||||
|
{
|
||||||
|
// Extract the travel ID before the property loop — 'travel' in the
|
||||||
|
// serialized data is an int, not a Travel object
|
||||||
|
$travelId = $data['travel'];
|
||||||
|
unset($data['travel']);
|
||||||
|
|
||||||
|
// Skip keys that no longer exist as declared properties to avoid
|
||||||
|
// dynamic property creation (deprecated since PHP 8.2)
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if (false === property_exists($this, $key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a skeleton Travel with only the ID; BookingService::hydrate()
|
||||||
|
// replaces this with the full object from cache
|
||||||
|
$travel = new Travel();
|
||||||
|
$travel->id = $travelId;
|
||||||
|
$this->travel = $travel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Service;
|
namespace App\Service;
|
||||||
|
|
||||||
use App\BusProNet\Constants;
|
use App\BusProNet\Constants;
|
||||||
@@ -80,14 +82,12 @@ class BookingService
|
|||||||
*/
|
*/
|
||||||
public function getOrCreateBookingCreateDto(Request $request): BookingDto
|
public function getOrCreateBookingCreateDto(Request $request): BookingDto
|
||||||
{
|
{
|
||||||
$bookingCreateDto = $request->getSession()->get(self::BOOKING_CREATE_KEY);
|
$bookingDto = $this->getBookingDto($request, BookingDto::MODE_CREATE);
|
||||||
|
|
||||||
// Return existing DTO from session if available
|
if (null !== $bookingDto) {
|
||||||
if (null !== $bookingCreateDto) {
|
return $bookingDto;
|
||||||
return $bookingCreateDto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No session found - user must go through proper init flow
|
|
||||||
throw new BookingSessionNotFoundException();
|
throw new BookingSessionNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,12 +105,15 @@ class BookingService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the booking DTO from the session.
|
* Retrieves the booking DTO from the session and restores the Travel object.
|
||||||
|
*
|
||||||
|
* After deserialization the DTO contains only a Travel skeleton with the ID.
|
||||||
|
* This method replaces it with the full Travel from cache via hydrate().
|
||||||
*
|
*
|
||||||
* @param Request $request The HTTP request containing session data
|
* @param Request $request The HTTP request containing session data
|
||||||
* @param string $mode The booking mode (create/edit)
|
* @param string $mode The booking mode (create/edit)
|
||||||
*
|
*
|
||||||
* @return BookingDto|null The booking DTO from session or null if not found
|
* @return BookingDto|null The booking DTO or null if not found
|
||||||
*/
|
*/
|
||||||
public function getBookingDto(Request $request, string $mode): ?BookingDto
|
public function getBookingDto(Request $request, string $mode): ?BookingDto
|
||||||
{
|
{
|
||||||
@@ -121,7 +124,10 @@ class BookingService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $session->get($sessionKey);
|
$bookingDto = $session->get($sessionKey);
|
||||||
|
$this->hydrate($bookingDto);
|
||||||
|
|
||||||
|
return $bookingDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,6 +154,31 @@ class BookingService
|
|||||||
return BookingDto::MODE_EDIT === $mode ? self::BOOKING_EDIT_KEY : self::BOOKING_CREATE_KEY;
|
return BookingDto::MODE_EDIT === $mode ? self::BOOKING_EDIT_KEY : self::BOOKING_CREATE_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the full Travel object from cache after session deserialization.
|
||||||
|
*
|
||||||
|
* BookingDto::__serialize() replaces Travel with just its ID to keep session
|
||||||
|
* payloads small. This method fetches the complete Travel from the
|
||||||
|
* TravelDataService cache and sets it on both the DTO and the Booking reference.
|
||||||
|
*/
|
||||||
|
private function hydrate(BookingDto $bookingDto): void
|
||||||
|
{
|
||||||
|
$travel = $this->travelDataService->getTravelData(
|
||||||
|
$bookingDto->travel->id,
|
||||||
|
$bookingDto->hotelId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (null === $travel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bookingDto->travel = $travel;
|
||||||
|
|
||||||
|
if (null !== $bookingDto->booking) {
|
||||||
|
$bookingDto->booking->travelData = $travel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all booking-related session data.
|
* Clears all booking-related session data.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user