wip: refactor forms

This commit is contained in:
Björn Fromme
2025-07-23 17:15:39 +02:00
parent f225dac5fe
commit 4ce731bfcb
5 changed files with 54 additions and 29 deletions
@@ -18,9 +18,6 @@ trait BookingCreateTrait
{
/**
* Validates step access and redirects if necessary.
*
* @param BookingCreateDto $bookingCreateDto
* @param int $expectedStep
*/
private function validateStepAccess(BookingCreateDto $bookingCreateDto, int $expectedStep): void
{
@@ -34,8 +31,6 @@ trait BookingCreateTrait
/**
* Redirects to the current step based on the DTO's currentStep.
*
* @param BookingCreateDto $bookingCreateDto
*/
private function redirectToCurrentStep(BookingCreateDto $bookingCreateDto): RedirectResponse
{
@@ -53,4 +48,4 @@ trait BookingCreateTrait
return $this->redirectToRoute($route, $routeParams);
}
}
}
@@ -27,7 +27,8 @@ class CreateStep2Controller extends AbstractController
public function __construct(
private readonly BookingService $bookingService,
) {
)
{
}
/**
@@ -89,6 +90,7 @@ class CreateStep2Controller extends AbstractController
]);
$form->handleRequest($request);
$this->bookingService->saveBookingCreateDto($request, $bookingCreateDto);
$roomAssignmentCounts = $this->bookingService->getRoomAssignmentCounts($bookingCreateDto);
+5 -15
View File
@@ -5,7 +5,7 @@ namespace App\Form;
use App\BusProNet\Form\CountryType;
use App\Form\Model\BookingCreateDto;
use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantRoomChoiceLoaderFactory;
use App\Form\Service\ParticipantFormConfigurator;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\BirthdayType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -19,7 +19,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class BookingCreateParticipantType extends AbstractType
{
public function __construct(
private readonly ParticipantRoomChoiceLoaderFactory $choiceLoaderFactory,
private readonly ParticipantFormConfigurator $formConfigurator,
) {
}
@@ -66,7 +66,7 @@ class BookingCreateParticipantType extends AbstractType
'clean_xss' => true,
])
->add('bodyDimensions', BodyDimensionsType::class)
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
/** @var ParticipantDto|null $participantData */
$participantData = $event->getData();
$form = $event->getForm();
@@ -83,19 +83,9 @@ class BookingCreateParticipantType extends AbstractType
/** @var BookingCreateDto $bookingCreateDto */
$bookingCreateDto = $rootForm->getData();
$allParticipants = $bookingCreateDto->participants;
$choiceLoader = $this->choiceLoaderFactory->create(
$allParticipants,
$options['selected_rooms'],
$participantData->index
);
$form->add('assignedRoomId', ChoiceType::class, [
'label' => 'Zimmer',
'placeholder' => 'Bitte wählen',
'choice_loader' => $choiceLoader,
]);
$roomOptions = $this->formConfigurator->getRoomFieldOptions($bookingCreateDto, $participantData->index);
$form->add('assignedRoomId', ChoiceType::class, $roomOptions);
});
}
+4 -7
View File
@@ -31,7 +31,7 @@ class BookingCreateStep2Type extends AbstractType
return;
}
$this->addParticipantsField($event->getForm(), $data);
$this->addParticipantsField($event->getForm());
}
/**
@@ -59,26 +59,23 @@ class BookingCreateStep2Type extends AbstractType
if (isset($participantData['assignedRoomId']) && isset($bookingDto->participants[$index])) {
$roomId = $participantData['assignedRoomId'];
// An unselected choice submits an empty string.
$bookingDto->participants[$index]->assignedRoomId = empty($roomId) ? null : (int) $roomId;
$bookingDto->participants[$index]->assignedRoomId = empty($roomId) ? null : (int)$roomId;
}
}
// Now, rebuild the 'participants' field with the updated DTO.
$this->addParticipantsField($form, $bookingDto);
$this->addParticipantsField($form);
}
/**
* Adds or replaces the 'participants' collection field on the form.
*/
private function addParticipantsField(FormInterface $form, BookingCreateDto $data): void
private function addParticipantsField(FormInterface $form): void
{
$form->add('participants', CollectionType::class, [
'entry_type' => BookingCreateParticipantType::class,
'allow_add' => false,
'allow_delete' => false,
'entry_options' => [
'selected_rooms' => $data->getSelectedRooms(),
],
]);
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\Form\Service;
use App\Form\Model\BookingCreateDto;
/**
* Central service for configuring dynamic fields in the participant form.
*
* This class encapsulates all business logic for determining field options,
* choices, and states (e.g., visibility, disabled status) based on the
* overall booking state and individual participant data.
*/
class ParticipantFormConfigurator
{
public function __construct(
private readonly ParticipantRoomChoiceLoaderFactory $roomChoiceLoaderFactory,
)
{
}
/**
* Gets the complete form options for the 'assignedRoomId' field.
*/
public function getRoomFieldOptions(BookingCreateDto $bookingDto, int $participantIndex): array
{
$choiceLoader = $this->roomChoiceLoaderFactory->create(
$bookingDto->participants,
$bookingDto->getSelectedRooms(),
$participantIndex
);
return [
'label' => 'Zimmer',
'placeholder' => 'Bitte wählen',
'choice_loader' => $choiceLoader,
];
}
}