wip: refactoring

This commit is contained in:
Björn Fromme
2026-03-16 11:59:09 +01:00
parent 431839d36d
commit 9d99fe9272
+65 -16
View File
@@ -8,31 +8,80 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
class BookingCreateStep2Type extends AbstractType class BookingCreateStep2Type extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { $builder
/** @var BookingCreateDto|null $data */ ->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData'])
$data = $event->getData(); ->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit'])
$form = $event->getForm(); ;
}
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, [ // Now, rebuild the 'participants' field with the updated DTO.
'entry_type' => BookingCreateParticipantType::class, $this->addParticipantsField($form, $bookingDto);
'allow_add' => false, }
'allow_delete' => false,
'by_reference' => false, /**
'entry_options' => [ * Adds or replaces the 'participants' collection field on the form.
'selected_rooms' => $data->getSelectedRooms(), */
], 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 public function configureOptions(OptionsResolver $resolver): void