wip: refactoring
This commit is contained in:
@@ -8,31 +8,80 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class BookingCreateStep2Type extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
|
||||
/** @var BookingCreateDto|null $data */
|
||||
$data = $event->getData();
|
||||
$form = $event->getForm();
|
||||
$builder
|
||||
->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData'])
|
||||
->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit'])
|
||||
;
|
||||
}
|
||||
|
||||
if (null === $data) {
|
||||
return;
|
||||
/**
|
||||
* Handles the initial form creation.
|
||||
*/
|
||||
public function onPreSetData(FormEvent $event): void
|
||||
{
|
||||
/** @var BookingCreateDto|null $data */
|
||||
$data = $event->getData();
|
||||
if (null === $data) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addParticipantsField($event->getForm(), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles dynamic updates on POST requests (e.g., from HTMX).
|
||||
*
|
||||
* This listener synchronizes the DTO with the submitted data *before*
|
||||
* the form's children are processed. It then rebuilds the participants
|
||||
* field to ensure choice loaders are created with the fresh state.
|
||||
*/
|
||||
public function onPreSubmit(FormEvent $event): void
|
||||
{
|
||||
$form = $event->getForm();
|
||||
$submittedData = $event->getData();
|
||||
|
||||
/** @var BookingCreateDto $bookingDto */
|
||||
$bookingDto = $form->getData();
|
||||
|
||||
// If participant data isn't in the submission, we can't do anything.
|
||||
if (!isset($submittedData['participants']) || !is_array($submittedData['participants'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Manually update the DTO with the submitted room assignments.
|
||||
foreach ($submittedData['participants'] as $index => $participantData) {
|
||||
if (isset($participantData['assignedRoomId']) && isset($bookingDto->participants[$index])) {
|
||||
$roomId = $participantData['assignedRoomId'];
|
||||
// An unselected choice submits an empty string.
|
||||
$bookingDto->participants[$index]->assignedRoomId = '' === $roomId ? null : (int) $roomId;
|
||||
}
|
||||
}
|
||||
|
||||
$form->add('participants', CollectionType::class, [
|
||||
'entry_type' => BookingCreateParticipantType::class,
|
||||
'allow_add' => false,
|
||||
'allow_delete' => false,
|
||||
'by_reference' => false,
|
||||
'entry_options' => [
|
||||
'selected_rooms' => $data->getSelectedRooms(),
|
||||
],
|
||||
]);
|
||||
});
|
||||
// Now, rebuild the 'participants' field with the updated DTO.
|
||||
$this->addParticipantsField($form, $bookingDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or replaces the 'participants' collection field on the form.
|
||||
*/
|
||||
private function addParticipantsField(FormInterface $form, BookingCreateDto $data): void
|
||||
{
|
||||
$form->add('participants', CollectionType::class, [
|
||||
'entry_type' => BookingCreateParticipantType::class,
|
||||
'allow_add' => false,
|
||||
'allow_delete' => false,
|
||||
'by_reference' => false,
|
||||
'entry_options' => [
|
||||
'selected_rooms' => $data->getSelectedRooms(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
|
||||
Reference in New Issue
Block a user