feat: configurable choices for body dimensions
closes #8697phk21
This commit is contained in:
@@ -7,6 +7,26 @@ parameters:
|
|||||||
travel_info_base_url: '%env(APP_TRAVEL_INFO_BASE_URL)%'
|
travel_info_base_url: '%env(APP_TRAVEL_INFO_BASE_URL)%'
|
||||||
path_to_keys: '%kernel.project_dir%/config/secret'
|
path_to_keys: '%kernel.project_dir%/config/secret'
|
||||||
|
|
||||||
|
# Body dimensions choices for BodyDimensionsType
|
||||||
|
body_dimensions.height_choices:
|
||||||
|
'bis 148cm': '-148'
|
||||||
|
'149 - 157cm': '149-157'
|
||||||
|
'158 - 166cm': '158-166'
|
||||||
|
'167 - 178cm': '167-178'
|
||||||
|
'179 - 185cm': '179-185'
|
||||||
|
'186 - 194cm': '186-194'
|
||||||
|
'195cm oder mehr': '195cm+'
|
||||||
|
body_dimensions.shoe_size_min: 36
|
||||||
|
body_dimensions.shoe_size_max: 48
|
||||||
|
body_dimensions.weight_choices:
|
||||||
|
'42 - 48kg': '42-48'
|
||||||
|
'49 - 57kg': '49-57'
|
||||||
|
'58 - 66kg': '58-66'
|
||||||
|
'67 - 78kg': '67-78'
|
||||||
|
'79 - 85kg': '79-85'
|
||||||
|
'86 - 94kg': '86-94'
|
||||||
|
'95kg oder mehr': '95k+'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
_defaults:
|
_defaults:
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use App\Service\ParticipantPrepopulationService;
|
|||||||
use App\Service\RoomAssignmentService;
|
use App\Service\RoomAssignmentService;
|
||||||
use App\Service\TravelDataService;
|
use App\Service\TravelDataService;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
@@ -35,6 +36,10 @@ class Step2Controller extends AbstractController
|
|||||||
use HxTrait;
|
use HxTrait;
|
||||||
use ParticipantCardFlowTrait;
|
use ParticipantCardFlowTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $heightChoices
|
||||||
|
* @param array<string, string> $weightChoices
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly BookingService $bookingService,
|
private readonly BookingService $bookingService,
|
||||||
private readonly BookingSummaryDataService $summaryDataService,
|
private readonly BookingSummaryDataService $summaryDataService,
|
||||||
@@ -43,9 +48,43 @@ class Step2Controller extends AbstractController
|
|||||||
private readonly ParticipantCardDataService $participantCardService,
|
private readonly ParticipantCardDataService $participantCardService,
|
||||||
private readonly ParticipantFieldOptionsProvider $fieldOptionsProvider,
|
private readonly ParticipantFieldOptionsProvider $fieldOptionsProvider,
|
||||||
private readonly ParticipantPrepopulationService $prepopulationService,
|
private readonly ParticipantPrepopulationService $prepopulationService,
|
||||||
|
#[Autowire(param: 'body_dimensions.height_choices')]
|
||||||
|
private readonly array $heightChoices,
|
||||||
|
#[Autowire(param: 'body_dimensions.weight_choices')]
|
||||||
|
private readonly array $weightChoices,
|
||||||
|
#[Autowire(param: 'body_dimensions.shoe_size_min')]
|
||||||
|
private readonly int $shoeSizeMin,
|
||||||
|
#[Autowire(param: 'body_dimensions.shoe_size_max')]
|
||||||
|
private readonly int $shoeSizeMax,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private function getHeightChoices(): array
|
||||||
|
{
|
||||||
|
return $this->heightChoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private function getWeightChoices(): array
|
||||||
|
{
|
||||||
|
return $this->weightChoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getShoeSizeMin(): int
|
||||||
|
{
|
||||||
|
return $this->shoeSizeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getShoeSizeMax(): int
|
||||||
|
{
|
||||||
|
return $this->shoeSizeMax;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display card grid for all participants.
|
* Display card grid for all participants.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use App\Service\ParticipantCardDataService;
|
|||||||
use App\Service\TravelDataService;
|
use App\Service\TravelDataService;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
@@ -45,6 +46,10 @@ class IndexController extends AbstractController
|
|||||||
use HxTrait;
|
use HxTrait;
|
||||||
use Traits\ParticipantCardFlowTrait;
|
use Traits\ParticipantCardFlowTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $heightChoices
|
||||||
|
* @param array<string, string> $weightChoices
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly ApiClient $apiClient,
|
private readonly ApiClient $apiClient,
|
||||||
private readonly BookingEditDataLoaderService $dataLoader,
|
private readonly BookingEditDataLoaderService $dataLoader,
|
||||||
@@ -55,9 +60,43 @@ class IndexController extends AbstractController
|
|||||||
private readonly ParticipantCardDataService $participantCardService,
|
private readonly ParticipantCardDataService $participantCardService,
|
||||||
private readonly Crypt $crypt,
|
private readonly Crypt $crypt,
|
||||||
private readonly LoggerInterface $logger,
|
private readonly LoggerInterface $logger,
|
||||||
|
#[Autowire(param: 'body_dimensions.height_choices')]
|
||||||
|
private readonly array $heightChoices,
|
||||||
|
#[Autowire(param: 'body_dimensions.weight_choices')]
|
||||||
|
private readonly array $weightChoices,
|
||||||
|
#[Autowire(param: 'body_dimensions.shoe_size_min')]
|
||||||
|
private readonly int $shoeSizeMin,
|
||||||
|
#[Autowire(param: 'body_dimensions.shoe_size_max')]
|
||||||
|
private readonly int $shoeSizeMax,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private function getHeightChoices(): array
|
||||||
|
{
|
||||||
|
return $this->heightChoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private function getWeightChoices(): array
|
||||||
|
{
|
||||||
|
return $this->weightChoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getShoeSizeMin(): int
|
||||||
|
{
|
||||||
|
return $this->shoeSizeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getShoeSizeMax(): int
|
||||||
|
{
|
||||||
|
return $this->shoeSizeMax;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display participant cards overview.
|
* Display participant cards overview.
|
||||||
*/
|
*/
|
||||||
@@ -181,6 +220,10 @@ class IndexController extends AbstractController
|
|||||||
// Create form for participant with booking context
|
// Create form for participant with booking context
|
||||||
$form = $this->createForm(BookingParticipantType::class, $wrapper, [
|
$form = $this->createForm(BookingParticipantType::class, $wrapper, [
|
||||||
'booking_context' => $bookingDto,
|
'booking_context' => $bookingDto,
|
||||||
|
'height_choices' => $this->heightChoices,
|
||||||
|
'weight_choices' => $this->weightChoices,
|
||||||
|
'shoe_size_min' => $this->shoeSizeMin,
|
||||||
|
'shoe_size_max' => $this->shoeSizeMax,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
@@ -264,6 +307,10 @@ class IndexController extends AbstractController
|
|||||||
$form = $this->createForm(BookingParticipantType::class, $wrapper, [
|
$form = $this->createForm(BookingParticipantType::class, $wrapper, [
|
||||||
'booking_context' => $bookingDto,
|
'booking_context' => $bookingDto,
|
||||||
'validation_groups' => false,
|
'validation_groups' => false,
|
||||||
|
'height_choices' => $this->heightChoices,
|
||||||
|
'weight_choices' => $this->weightChoices,
|
||||||
|
'shoe_size_min' => $this->shoeSizeMin,
|
||||||
|
'shoe_size_max' => $this->shoeSizeMax,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|||||||
@@ -71,14 +71,32 @@ trait ParticipantCardFlowTrait
|
|||||||
bookingContext: $bookingDto,
|
bookingContext: $bookingDto,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Merge default options with provided options
|
// Merge default options with provided options and body dimensions
|
||||||
$formOptions = array_merge([
|
$formOptions = array_merge([
|
||||||
'booking_context' => $bookingDto,
|
'booking_context' => $bookingDto,
|
||||||
|
'height_choices' => $this->getHeightChoices(),
|
||||||
|
'weight_choices' => $this->getWeightChoices(),
|
||||||
|
'shoe_size_min' => $this->getShoeSizeMin(),
|
||||||
|
'shoe_size_max' => $this->getShoeSizeMax(),
|
||||||
], $options);
|
], $options);
|
||||||
|
|
||||||
return $this->createForm(BookingParticipantType::class, $wrapper, $formOptions);
|
return $this->createForm(BookingParticipantType::class, $wrapper, $formOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
abstract private function getHeightChoices(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
abstract private function getWeightChoices(): array;
|
||||||
|
|
||||||
|
abstract private function getShoeSizeMin(): int;
|
||||||
|
|
||||||
|
abstract private function getShoeSizeMax(): int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects notifications from all participants and clears them from DTOs.
|
* Collects notifications from all participants and clears them from DTOs.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
use App\Form\Model\ParticipantDto;
|
use App\Form\Model\ParticipantDto;
|
||||||
@@ -12,44 +14,35 @@ class BodyDimensionsType extends AbstractType
|
|||||||
{
|
{
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
|
$shoeSizeChoices = array_combine(
|
||||||
|
range($options['shoe_size_min'], $options['shoe_size_max']),
|
||||||
|
range($options['shoe_size_min'], $options['shoe_size_max'])
|
||||||
|
);
|
||||||
|
|
||||||
$builder
|
$builder
|
||||||
->add('height', ChoiceType::class, [
|
->add('height', ChoiceType::class, [
|
||||||
'label' => 'Körpergröße',
|
'label' => 'Körpergröße',
|
||||||
'required' => $options['height_required'] ?? false,
|
'required' => $options['height_required'],
|
||||||
'expanded' => false,
|
'expanded' => false,
|
||||||
'multiple' => false,
|
'multiple' => false,
|
||||||
'placeholder' => 'Keine Angabe',
|
'placeholder' => 'Keine Angabe',
|
||||||
'choices' => [
|
'choices' => $options['height_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, [
|
->add('shoeSize', ChoiceType::class, [
|
||||||
'label' => 'Schuhgröße',
|
'label' => 'Schuhgröße',
|
||||||
'required' => $options['shoeSize_required'] ?? false,
|
'required' => $options['shoeSize_required'],
|
||||||
'expanded' => false,
|
'expanded' => false,
|
||||||
'multiple' => false,
|
'multiple' => false,
|
||||||
'placeholder' => 'Keine Angabe',
|
'placeholder' => 'Keine Angabe',
|
||||||
'choices' => array_combine(range(36, 48), range(36, 48)),
|
'choices' => $shoeSizeChoices,
|
||||||
])
|
])
|
||||||
->add('weight', ChoiceType::class, [
|
->add('weight', ChoiceType::class, [
|
||||||
'label' => 'Gewicht',
|
'label' => 'Gewicht',
|
||||||
'required' => $options['weight_required'] ?? false,
|
'required' => $options['weight_required'],
|
||||||
'expanded' => false,
|
'expanded' => false,
|
||||||
'multiple' => false,
|
'multiple' => false,
|
||||||
'placeholder' => 'Keine Angabe',
|
'placeholder' => 'Keine Angabe',
|
||||||
'choices' => [
|
'choices' => $options['weight_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+',
|
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +53,10 @@ class BodyDimensionsType extends AbstractType
|
|||||||
'height_required' => false,
|
'height_required' => false,
|
||||||
'weight_required' => false,
|
'weight_required' => false,
|
||||||
'shoeSize_required' => false,
|
'shoeSize_required' => false,
|
||||||
|
'height_choices' => [],
|
||||||
|
'weight_choices' => [],
|
||||||
|
'shoe_size_min' => 36,
|
||||||
|
'shoe_size_max' => 48,
|
||||||
'help' => 'Du kannst die Daten auch später nachreichen',
|
'help' => 'Du kannst die Daten auch später nachreichen',
|
||||||
'help_attr' => [
|
'help_attr' => [
|
||||||
'class' => 'lg:col-span-3 text-sm -mt-2 px-2',
|
'class' => 'lg:col-span-3 text-sm -mt-2 px-2',
|
||||||
@@ -69,5 +66,9 @@ class BodyDimensionsType extends AbstractType
|
|||||||
$resolver->setAllowedTypes('height_required', 'bool');
|
$resolver->setAllowedTypes('height_required', 'bool');
|
||||||
$resolver->setAllowedTypes('weight_required', 'bool');
|
$resolver->setAllowedTypes('weight_required', 'bool');
|
||||||
$resolver->setAllowedTypes('shoeSize_required', 'bool');
|
$resolver->setAllowedTypes('shoeSize_required', 'bool');
|
||||||
|
$resolver->setAllowedTypes('height_choices', 'array');
|
||||||
|
$resolver->setAllowedTypes('weight_choices', 'array');
|
||||||
|
$resolver->setAllowedTypes('shoe_size_min', 'int');
|
||||||
|
$resolver->setAllowedTypes('shoe_size_max', 'int');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,12 @@ class BookingEditParticipantType extends AbstractType
|
|||||||
'required' => false,
|
'required' => false,
|
||||||
'sanitize_html' => true,
|
'sanitize_html' => true,
|
||||||
], $getState('mobile')))
|
], $getState('mobile')))
|
||||||
->add('bodyDimensions', BodyDimensionsType::class);
|
->add('bodyDimensions', BodyDimensionsType::class, [
|
||||||
|
'height_choices' => $options['height_choices'],
|
||||||
|
'weight_choices' => $options['weight_choices'],
|
||||||
|
'shoe_size_min' => $options['shoe_size_min'],
|
||||||
|
'shoe_size_max' => $options['shoe_size_max'],
|
||||||
|
]);
|
||||||
|
|
||||||
$commonChoiceFieldOptions = [
|
$commonChoiceFieldOptions = [
|
||||||
'required' => false,
|
'required' => false,
|
||||||
@@ -371,7 +376,17 @@ class BookingEditParticipantType extends AbstractType
|
|||||||
'applicant_id' => null,
|
'applicant_id' => null,
|
||||||
// Booking DTO for field state provider (must be set by parent form)
|
// Booking DTO for field state provider (must be set by parent form)
|
||||||
'booking' => null,
|
'booking' => null,
|
||||||
|
// Body dimensions choices
|
||||||
|
'height_choices' => [],
|
||||||
|
'weight_choices' => [],
|
||||||
|
'shoe_size_min' => 36,
|
||||||
|
'shoe_size_max' => 48,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$resolver->setAllowedTypes('height_choices', 'array');
|
||||||
|
$resolver->setAllowedTypes('weight_choices', 'array');
|
||||||
|
$resolver->setAllowedTypes('shoe_size_min', 'int');
|
||||||
|
$resolver->setAllowedTypes('shoe_size_max', 'int');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -252,6 +252,10 @@ class BookingParticipantType extends AbstractType
|
|||||||
if ($this->fieldStateProvider->shouldIncludeField('bodyDimensions', $bookingDto, $participantIndex)) {
|
if ($this->fieldStateProvider->shouldIncludeField('bodyDimensions', $bookingDto, $participantIndex)) {
|
||||||
$form->add('bodyDimensions', BodyDimensionsType::class, [
|
$form->add('bodyDimensions', BodyDimensionsType::class, [
|
||||||
'property_path' => 'participant',
|
'property_path' => 'participant',
|
||||||
|
'height_choices' => $form->getConfig()->getOption('height_choices'),
|
||||||
|
'weight_choices' => $form->getConfig()->getOption('weight_choices'),
|
||||||
|
'shoe_size_min' => $form->getConfig()->getOption('shoe_size_min'),
|
||||||
|
'shoe_size_max' => $form->getConfig()->getOption('shoe_size_max'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -435,6 +439,10 @@ class BookingParticipantType extends AbstractType
|
|||||||
'data_class' => ParticipantEditDto::class,
|
'data_class' => ParticipantEditDto::class,
|
||||||
'selected_rooms' => [],
|
'selected_rooms' => [],
|
||||||
'booking_context' => null,
|
'booking_context' => null,
|
||||||
|
'height_choices' => [],
|
||||||
|
'weight_choices' => [],
|
||||||
|
'shoe_size_min' => 36,
|
||||||
|
'shoe_size_max' => 48,
|
||||||
'validation_groups' => function (FormInterface $form) {
|
'validation_groups' => function (FormInterface $form) {
|
||||||
/** @var ParticipantEditDto $data */
|
/** @var ParticipantEditDto $data */
|
||||||
$data = $form->getData();
|
$data = $form->getData();
|
||||||
@@ -462,5 +470,9 @@ class BookingParticipantType extends AbstractType
|
|||||||
|
|
||||||
$resolver->setAllowedTypes('selected_rooms', 'array');
|
$resolver->setAllowedTypes('selected_rooms', 'array');
|
||||||
$resolver->setAllowedTypes('booking_context', ['null', BookingDto::class]);
|
$resolver->setAllowedTypes('booking_context', ['null', BookingDto::class]);
|
||||||
|
$resolver->setAllowedTypes('height_choices', 'array');
|
||||||
|
$resolver->setAllowedTypes('weight_choices', 'array');
|
||||||
|
$resolver->setAllowedTypes('shoe_size_min', 'int');
|
||||||
|
$resolver->setAllowedTypes('shoe_size_max', 'int');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user