From 5e1f2a87113969ea299ee18dcda42e0887831e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 23 Jul 2025 15:34:54 +0200 Subject: [PATCH] wip: refactor forms --- src/Form/BodyDimensionsType.php | 61 ++++++++++++ src/Form/BookingCreateParticipantType.php | 4 +- src/Form/BookingCreateStep2Type.php | 6 +- src/Form/BookingEditParticipantType.php | 115 +++++++--------------- src/Form/BookingEditType.php | 2 +- templates/booking/create_step_2.html.twig | 5 + templates/booking/edit.html.twig | 6 +- 7 files changed, 112 insertions(+), 87 deletions(-) create mode 100644 src/Form/BodyDimensionsType.php diff --git a/src/Form/BodyDimensionsType.php b/src/Form/BodyDimensionsType.php new file mode 100644 index 0000000..cf54a65 --- /dev/null +++ b/src/Form/BodyDimensionsType.php @@ -0,0 +1,61 @@ +add('height', ChoiceType::class, [ + 'label' => 'Körpergröße', + 'required' => false, + 'expanded' => false, + 'multiple' => false, + 'placeholder' => 'Keine Angabe', + 'choices' => [ + 'bis 148cm' => '-148', + '149 - 157cm' => '149-157', + '158 - 166cm' => '158-166', + '167 - 178cm' => '167-178', + '179 - 194cm' => '179-197', + '195cm oder mehr' => '195cm+', + ], + ]) + ->add('shoeSize', ChoiceType::class, [ + 'label' => 'Schuhgröße', + 'required' => false, + 'expanded' => false, + 'multiple' => false, + 'placeholder' => 'Keine Angabe', + 'choices' => array_combine(range(36, 48), range(36, 48)), + ]) + ->add('weight', ChoiceType::class, [ + 'label' => 'Gewicht', + 'required' => false, + 'expanded' => false, + 'multiple' => false, + 'placeholder' => 'Keine Angabe', + 'choices' => [ + '42 - 48kg' => '42-48', + '49 - 57kg' => '49-57', + '58 - 66kg' => '58-66', + '67 - 78kg' => '67-78', + '79 - 94kg' => '79-94', + '95kg oder mehr' => '95k+', + ], + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'inherit_data' => true, + ]); + } +} diff --git a/src/Form/BookingCreateParticipantType.php b/src/Form/BookingCreateParticipantType.php index 7404aff..e7e238b 100644 --- a/src/Form/BookingCreateParticipantType.php +++ b/src/Form/BookingCreateParticipantType.php @@ -65,6 +65,7 @@ class BookingCreateParticipantType extends AbstractType 'required' => false, 'clean_xss' => true, ]) + ->add('bodyDimensions', BodyDimensionsType::class) ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) { /** @var ParticipantDto|null $participantData */ $participantData = $event->getData(); @@ -95,8 +96,7 @@ class BookingCreateParticipantType extends AbstractType 'placeholder' => 'Bitte wählen', 'choice_loader' => $choiceLoader, ]); - }) - ; + }); } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/BookingCreateStep2Type.php b/src/Form/BookingCreateStep2Type.php index 93fdfc3..917cf4a 100644 --- a/src/Form/BookingCreateStep2Type.php +++ b/src/Form/BookingCreateStep2Type.php @@ -17,8 +17,7 @@ class BookingCreateStep2Type extends AbstractType { $builder ->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']) - ->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']) - ; + ->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']); } /** @@ -60,7 +59,7 @@ 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 = '' === $roomId ? null : (int) $roomId; + $bookingDto->participants[$index]->assignedRoomId = empty($roomId) ? null : (int) $roomId; } } @@ -77,7 +76,6 @@ class BookingCreateStep2Type extends AbstractType 'entry_type' => BookingCreateParticipantType::class, 'allow_add' => false, 'allow_delete' => false, - 'by_reference' => false, 'entry_options' => [ 'selected_rooms' => $data->getSelectedRooms(), ], diff --git a/src/Form/BookingEditParticipantType.php b/src/Form/BookingEditParticipantType.php index 9076ce5..4470fee 100644 --- a/src/Form/BookingEditParticipantType.php +++ b/src/Form/BookingEditParticipantType.php @@ -99,45 +99,7 @@ class BookingEditParticipantType extends AbstractType ], 'clean_xss' => true, ]) - ->add('height', ChoiceType::class, [ - 'label' => 'Körpergröße', - 'required' => false, - 'expanded' => false, - 'multiple' => false, - 'placeholder' => 'Keine Angabe', - 'choices' => [ - 'bis 148cm' => '-148', - '149 - 157cm' => '149-157', - '158 - 166cm' => '158-166', - '167 - 178cm' => '167-178', - '179 - 194cm' => '179-197', - '195cm oder mehr' => '195cm+', - ], - ]) - ->add('shoeSize', ChoiceType::class, [ - 'label' => 'Schuhgröße', - 'required' => false, - 'expanded' => false, - 'multiple' => false, - 'placeholder' => 'Keine Angabe', - 'choices' => array_combine(range(36, 48), range(36, 48)), - ]) - ->add('weight', ChoiceType::class, [ - 'label' => 'Gewicht', - 'required' => false, - 'expanded' => false, - 'multiple' => false, - 'placeholder' => 'Keine Angabe', - 'choices' => [ - '42 - 48kg' => '42-48', - '49 - 57kg' => '49-57', - '58 - 66kg' => '58-66', - '67 - 78kg' => '67-78', - '79 - 94kg' => '79-94', - '95kg oder mehr' => '95k+', - ], - ]) - ; + ->add('bodyDimensions', BodyDimensionsType::class); $commonChoiceFieldOptions = [ 'required' => false, @@ -278,8 +240,7 @@ class BookingEditParticipantType extends AbstractType 'multiple' => false, 'choices' => $options['selectable_transportation_services_fro'], 'choice_attr' => $transportationChoiceAttributes, - ]) - ; + ]); // Pickup $form->add('pickup', ChoiceType::class, [ @@ -296,7 +257,7 @@ class BookingEditParticipantType extends AbstractType $pickupLabel = $pickup->city; if (null !== $pickup->street) { - $pickupLabel .= ' ('.$pickup->street.')'; + $pickupLabel .= ' (' . $pickup->street . ')'; } $price = $pickup->price; @@ -324,46 +285,46 @@ class BookingEditParticipantType extends AbstractType ], ]); }) - ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) { - $data = $event->getData(); - $form = $event->getForm(); + ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) { + $data = $event->getData(); + $form = $event->getForm(); - // skip processing for canceled participants - if ('F' !== $form->getData()->status) { - return; - } - - $transportationId = $data['transportationServiceTo'] ?? null; - $transportation = $options['travel']->pickups[$transportationId] ?? null; - - if (null !== $transportation && 'PKW' === $transportation->subType) { - $form->remove('pickup'); - unset($data['pickup']); - } - - // forcibly select mandatory services that potentially have been disabled in PRE_SET_DATA - $mandatoryServices = array_filter($options['selectable_services'], function (Service $service) use ($form) { - $participantIndex = $form->getData()->index; - - return true === $service->mandatory - || (Constants::SOURCE_BOOKING === $service->source && in_array($participantIndex, $service->mapping)); - }); - - if (0 < count($mandatoryServices)) { - if (false === isset($data['additionalServices'])) { - $data['additionalServices'] = []; + // skip processing for canceled participants + if ('F' !== $form->getData()->status) { + return; } - $mandatoryServiceIds = array_map(function (Service $service) { - return $service->id; - }, $mandatoryServices); + $transportationId = $data['transportationServiceTo'] ?? null; + $transportation = $options['travel']->pickups[$transportationId] ?? null; - $allServiceIds = [...$mandatoryServiceIds, ...$data['additionalServices']]; - $data['additionalServices'] = array_unique($allServiceIds); - } + if (null !== $transportation && 'PKW' === $transportation->subType) { + $form->remove('pickup'); + unset($data['pickup']); + } - $event->setData($data); - }); + // forcibly select mandatory services that potentially have been disabled in PRE_SET_DATA + $mandatoryServices = array_filter($options['selectable_services'], function (Service $service) use ($form) { + $participantIndex = $form->getData()->index; + + return true === $service->mandatory + || (Constants::SOURCE_BOOKING === $service->source && in_array($participantIndex, $service->mapping)); + }); + + if (0 < count($mandatoryServices)) { + if (false === isset($data['additionalServices'])) { + $data['additionalServices'] = []; + } + + $mandatoryServiceIds = array_map(function (Service $service) { + return $service->id; + }, $mandatoryServices); + + $allServiceIds = [...$mandatoryServiceIds, ...$data['additionalServices']]; + $data['additionalServices'] = array_unique($allServiceIds); + } + + $event->setData($data); + }); } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/BookingEditType.php b/src/Form/BookingEditType.php index e431457..db48a84 100644 --- a/src/Form/BookingEditType.php +++ b/src/Form/BookingEditType.php @@ -47,7 +47,7 @@ class BookingEditType extends AbstractType }); } - private function mergeSelectableServices(BookingEditDto $data, mixed $subType): array + private function mergeSelectableServices(BookingEditDto $data, string|array $subType): array { // combine selectable services from travel data with additional services // from booking data diff --git a/templates/booking/create_step_2.html.twig b/templates/booking/create_step_2.html.twig index d224c53..3d3eb97 100644 --- a/templates/booking/create_step_2.html.twig +++ b/templates/booking/create_step_2.html.twig @@ -27,6 +27,11 @@ {{ form_row(participant.email) }} {{ form_row(participant.mobile) }} +
+ {{ form_row(participant.bodyDimensions.height) }} + {{ form_row(participant.bodyDimensions.shoeSize) }} + {{ form_row(participant.bodyDimensions.weight) }} +
{# hx-swap="none" tells HTMX not to do a normal swap, as OOB will handle it #} {{ form_row(participant.assignedRoomId, { diff --git a/templates/booking/edit.html.twig b/templates/booking/edit.html.twig index 273a998..5287505 100644 --- a/templates/booking/edit.html.twig +++ b/templates/booking/edit.html.twig @@ -175,9 +175,9 @@ {{ form_row(child.mobile) }}
- {{ form_row(child.height) }} - {{ form_row(child.shoeSize) }} - {{ form_row(child.weight) }} + {{ form_row(child.bodyDimensions.height) }} + {{ form_row(child.bodyDimensions.shoeSize) }} + {{ form_row(child.bodyDimensions.weight) }}
{% if not travelData.participantDataMutable %}