wip: refactoring

This commit is contained in:
Björn Fromme
2025-07-23 10:27:04 +02:00
parent 77afc0fe7b
commit c85c72863c
14 changed files with 165 additions and 179 deletions
Generated
+13 -12
View File
@@ -1758,16 +1758,16 @@
}, },
{ {
"name": "league/flysystem-bundle", "name": "league/flysystem-bundle",
"version": "3.4.0", "version": "3.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem-bundle.git", "url": "https://github.com/thephpleague/flysystem-bundle.git",
"reference": "6493f7f2ab49bc5817e4b064b9b971d93faabc12" "reference": "bf5ab3c072c0def47872e28f69876548d8669657"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-bundle/zipball/6493f7f2ab49bc5817e4b064b9b971d93faabc12", "url": "https://api.github.com/repos/thephpleague/flysystem-bundle/zipball/bf5ab3c072c0def47872e28f69876548d8669657",
"reference": "6493f7f2ab49bc5817e4b064b9b971d93faabc12", "reference": "bf5ab3c072c0def47872e28f69876548d8669657",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1791,6 +1791,7 @@
"league/flysystem-read-only": "^3.15", "league/flysystem-read-only": "^3.15",
"league/flysystem-sftp-v3": "^3.1", "league/flysystem-sftp-v3": "^3.1",
"league/flysystem-webdav": "^3.29", "league/flysystem-webdav": "^3.29",
"platformcommunity/flysystem-bunnycdn": "^3.3",
"symfony/dotenv": "^5.4 || ^6.0 || ^7.0", "symfony/dotenv": "^5.4 || ^6.0 || ^7.0",
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0",
"symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0", "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0",
@@ -1822,9 +1823,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/thephpleague/flysystem-bundle/issues", "issues": "https://github.com/thephpleague/flysystem-bundle/issues",
"source": "https://github.com/thephpleague/flysystem-bundle/tree/3.4.0" "source": "https://github.com/thephpleague/flysystem-bundle/tree/3.5.0"
}, },
"time": "2025-01-23T18:07:31+00:00" "time": "2025-06-22T12:43:01+00:00"
}, },
{ {
"name": "league/flysystem-local", "name": "league/flysystem-local",
@@ -10425,16 +10426,16 @@
}, },
{ {
"name": "friendsofphp/php-cs-fixer", "name": "friendsofphp/php-cs-fixer",
"version": "v3.82.2", "version": "v3.84.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "684ed3ab41008a2a4848de8bde17eb168c596247" "reference": "38dad0767bf2a9b516b976852200ae722fe984ca"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/684ed3ab41008a2a4848de8bde17eb168c596247", "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/38dad0767bf2a9b516b976852200ae722fe984ca",
"reference": "684ed3ab41008a2a4848de8bde17eb168c596247", "reference": "38dad0767bf2a9b516b976852200ae722fe984ca",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10518,7 +10519,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.82.2" "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.84.0"
}, },
"funding": [ "funding": [
{ {
@@ -10526,7 +10527,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-07-08T21:13:15+00:00" "time": "2025-07-15T18:21:57+00:00"
}, },
{ {
"name": "myclabs/deep-copy", "name": "myclabs/deep-copy",
+4
View File
@@ -62,3 +62,7 @@ services:
$logger: '@monolog.logger.core' $logger: '@monolog.logger.core'
$preferRemote: '%env(bool:APP_TRAVEL_PREFER_REMOTE)%' $preferRemote: '%env(bool:APP_TRAVEL_PREFER_REMOTE)%'
$enableFallback: '%env(bool:APP_TRAVEL_ENABLE_FALLBACK)%' $enableFallback: '%env(bool:APP_TRAVEL_ENABLE_FALLBACK)%'
App\Form\Service\ParticipantRoomChoiceLoaderFactory:
arguments:
$choiceListFactory: '@form.choice_list_factory.default'
+26 -5
View File
@@ -3,6 +3,7 @@
namespace App\Form; namespace App\Form;
use App\BusProNet\Form\CountryType; use App\BusProNet\Form\CountryType;
use App\Form\Model\BookingCreateDto;
use App\Form\Model\ParticipantDto; use App\Form\Model\ParticipantDto;
use App\Form\Service\ParticipantRoomChoiceLoaderFactory; use App\Form\Service\ParticipantRoomChoiceLoaderFactory;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
@@ -27,9 +28,11 @@ class BookingCreateParticipantType extends AbstractType
$builder $builder
->add('firstName', TextType::class, [ ->add('firstName', TextType::class, [
'label' => 'Vorname', 'label' => 'Vorname',
'clean_xss' => true,
]) ])
->add('lastName', TextType::class, [ ->add('lastName', TextType::class, [
'label' => 'Nachname', 'label' => 'Nachname',
'clean_xss' => true,
]) ])
->add('dateOfBirth', BirthdayType::class, [ ->add('dateOfBirth', BirthdayType::class, [
'label' => 'Geburtsdatum', 'label' => 'Geburtsdatum',
@@ -55,19 +58,36 @@ class BookingCreateParticipantType extends AbstractType
->add('email', EmailType::class, [ ->add('email', EmailType::class, [
'label' => 'E-Mail', 'label' => 'E-Mail',
'required' => false, 'required' => false,
'clean_xss' => true,
]) ])
->add('mobile', TextType::class, [ ->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)', 'label' => 'Telefon (mobil)',
'required' => false, 'required' => false,
'clean_xss' => true,
]) ])
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) { ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
$data = $event->getData(); /** @var ParticipantDto|null $participantData */
$participantData = $event->getData();
$form = $event->getForm(); $form = $event->getForm();
$choiceLoader = $this->choiceLoaderFactory->createChoiceLoader( if (null === $participantData) {
$options['participant_adapter'], return;
}
// Traverse up the form tree to get the root form's data.
$rootForm = $form;
while ($rootForm->getParent()) {
$rootForm = $rootForm->getParent();
}
/** @var BookingCreateDto $bookingCreateDto */
$bookingCreateDto = $rootForm->getData();
$allParticipants = $bookingCreateDto->participants;
$choiceLoader = $this->choiceLoaderFactory->create(
$allParticipants,
$options['selected_rooms'], $options['selected_rooms'],
$data->index $participantData->index
); );
$form->add('assignedRoomId', ChoiceType::class, [ $form->add('assignedRoomId', ChoiceType::class, [
@@ -83,8 +103,9 @@ class BookingCreateParticipantType extends AbstractType
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => ParticipantDto::class, 'data_class' => ParticipantDto::class,
'participant_adapter' => null,
'selected_rooms' => [], 'selected_rooms' => [],
]); ]);
$resolver->setAllowedTypes('selected_rooms', 'array');
} }
} }
+17 -41
View File
@@ -2,61 +2,37 @@
namespace App\Form; namespace App\Form;
use App\Form\DataAdapters\ParticipantDataAdapter;
use App\Form\Model\BookingCreateDto; use App\Form\Model\BookingCreateDto;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType; 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, [$this, 'onPreSetData']); $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']); /** @var BookingCreateDto|null $data */
} $data = $event->getData();
$form = $event->getForm();
public function onPreSetData(FormEvent $event): void if (null === $data) {
{ return;
/** @var BookingCreateDto $data */ }
$data = $event->getData();
$form = $event->getForm();
$adapter = new ParticipantDataAdapter($data->participants); $form->add('participants', CollectionType::class, [
$this->addParticipantsField($form, $adapter, $data->getSelectedRooms()); 'entry_type' => BookingCreateParticipantType::class,
} 'allow_add' => false,
'allow_delete' => false,
public function onPreSubmit(FormEvent $event): void 'by_reference' => false,
{ 'entry_options' => [
$data = $event->getData(); 'selected_rooms' => $data->getSelectedRooms(),
$form = $event->getForm(); ],
/** @var BookingCreateDto $bookingCreateDto */ ]);
$bookingCreateDto = $form->getData(); });
$adapter = new ParticipantDataAdapter($data['participants']);
$form->remove('participants');
$this->addParticipantsField($form, $adapter, $bookingCreateDto->getSelectedRooms());
}
/**
* Adds the participants collection field to the form.
*/
private function addParticipantsField(FormInterface $form, ParticipantDataAdapter $adapter, array $selectedRooms): void
{
$form->add('participants', CollectionType::class, [
'entry_type' => BookingCreateParticipantType::class,
'allow_add' => false,
'allow_delete' => false,
'by_reference' => false,
'entry_options' => [
'participant_adapter' => $adapter,
'selected_rooms' => $selectedRooms,
],
]);
} }
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
+4 -1
View File
@@ -42,12 +42,14 @@ class BookingEditParticipantType extends AbstractType
'attr' => [ 'attr' => [
'readonly' => false === $personalDataMutable, 'readonly' => false === $personalDataMutable,
], ],
'anti_xss' => true,
]) ])
->add('lastName', TextType::class, [ ->add('lastName', TextType::class, [
'label' => 'Nachname', 'label' => 'Nachname',
'attr' => [ 'attr' => [
'readonly' => false === $personalDataMutable, 'readonly' => false === $personalDataMutable,
], ],
'anti_xss' => true,
]) ])
->add('dateOfBirth', BirthdayType::class, [ ->add('dateOfBirth', BirthdayType::class, [
'label' => 'Geburtsdatum', 'label' => 'Geburtsdatum',
@@ -87,6 +89,7 @@ class BookingEditParticipantType extends AbstractType
'attr' => [ 'attr' => [
'readonly' => true === $isApplicant, 'readonly' => true === $isApplicant,
], ],
'anti_xss' => true,
]) ])
->add('mobile', TextType::class, [ ->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)', 'label' => 'Telefon (mobil)',
@@ -94,6 +97,7 @@ class BookingEditParticipantType extends AbstractType
'attr' => [ 'attr' => [
'readonly' => true === $isApplicant, 'readonly' => true === $isApplicant,
], ],
'anti_xss' => true,
]) ])
->add('height', ChoiceType::class, [ ->add('height', ChoiceType::class, [
'label' => 'Körpergröße', 'label' => 'Körpergröße',
@@ -379,7 +383,6 @@ class BookingEditParticipantType extends AbstractType
'transportation_services_mutable' => true, 'transportation_services_mutable' => true,
'pickups_mutable' => true, 'pickups_mutable' => true,
'applicant_id' => null, 'applicant_id' => null,
'anti_xss' => true,
]); ]);
} }
} }
+1 -2
View File
@@ -12,7 +12,7 @@ use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
final class BookingEditType extends AbstractType class BookingEditType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
@@ -69,7 +69,6 @@ final class BookingEditType extends AbstractType
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => BookingEditDto::class, 'data_class' => BookingEditDto::class,
'anti_xss' => true,
]); ]);
} }
} }
@@ -4,7 +4,8 @@ declare(strict_types=1);
namespace App\Form\ChoiceLoader; namespace App\Form\ChoiceLoader;
use App\Form\DataAdapters\ParticipantDataAdapter; use App\Form\Model\ParticipantDto;
use App\Form\Model\RoomSelectionDto;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface; use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface; use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
@@ -21,9 +22,14 @@ class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
{ {
private ?ChoiceListInterface $choiceList = null; private ?ChoiceListInterface $choiceList = null;
/**
* @param ParticipantDto[] $allParticipants all participant DTOs from the root form
* @param RoomSelectionDto[] $selectedRooms the rooms selected in the previous step
* @param int $participantIndex the index of the current participant
*/
public function __construct( public function __construct(
private readonly ChoiceListFactoryInterface $factory, private readonly ChoiceListFactoryInterface $factory,
private readonly ParticipantDataAdapter $adapter, private readonly array $allParticipants,
private readonly array $selectedRooms, private readonly array $selectedRooms,
private readonly int $participantIndex, private readonly int $participantIndex,
) { ) {
@@ -66,7 +72,7 @@ class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
{ {
$roomOccupancy = $this->calculateRoomOccupancy(); $roomOccupancy = $this->calculateRoomOccupancy();
$participantRoomChoices = []; $participantRoomChoices = [];
$assignedRoomId = $this->getParticipantAssignedRoomId(); $assignedRoomId = $this->allParticipants[$this->participantIndex]->assignedRoomId ?? null;
foreach ($this->selectedRooms as $roomSelection) { foreach ($this->selectedRooms as $roomSelection) {
$currentOccupancy = $roomOccupancy[$roomSelection->roomId] ?? 0; $currentOccupancy = $roomOccupancy[$roomSelection->roomId] ?? 0;
@@ -77,7 +83,8 @@ class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
--$adjustedOccupancy; --$adjustedOccupancy;
} }
$remainingCapacity = $roomSelection->minPax - $adjustedOccupancy; $totalAvailableRooms = $roomSelection->quantity;
$remainingCapacity = $totalAvailableRooms - $adjustedOccupancy;
// Include room if it has capacity OR if it's the participant's current assignment // Include room if it has capacity OR if it's the participant's current assignment
if ($remainingCapacity > 0 || $assignedRoomId === $roomSelection->roomId) { if ($remainingCapacity > 0 || $assignedRoomId === $roomSelection->roomId) {
@@ -89,7 +96,7 @@ class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
} }
/** /**
* Calculates room occupancy based on participant assignments. * Calculates room occupancy based on all participant assignments.
* *
* @return array<int, int> * @return array<int, int>
*/ */
@@ -97,24 +104,12 @@ class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
{ {
$roomOccupancy = []; $roomOccupancy = [];
foreach ($this->adapter->getParticipants() as $participant) { foreach ($this->allParticipants as $participant) {
$assignedRoomId = $this->adapter->getAssignedRoomId($participant); if (null !== $participant->assignedRoomId) {
if (null !== $assignedRoomId) { $roomOccupancy[$participant->assignedRoomId] = ($roomOccupancy[$participant->assignedRoomId] ?? 0) + 1;
$roomOccupancy[$assignedRoomId] = ($roomOccupancy[$assignedRoomId] ?? 0) + 1;
} }
} }
return $roomOccupancy; return $roomOccupancy;
} }
}
/**
* Gets the assigned room ID for the current participant.
*/
private function getParticipantAssignedRoomId(): ?int
{
$participants = $this->adapter->getParticipants();
$participant = $participants[$this->participantIndex] ?? null;
return null !== $participant ? $this->adapter->getAssignedRoomId($participant) : null;
}
}
@@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Form\DataAdapters;
/**
* Adapter pattern to unify access to participant data regardless of whether it comes from
* objects (during PRE_SET_DATA) or arrays (during PRE_SUBMIT).
*/
class ParticipantDataAdapter
{
private array $participants;
public function __construct(array $participants)
{
$this->participants = $participants;
}
public function getParticipants(): array
{
return $this->participants;
}
public function getAssignedRoomId(mixed $participant): ?int
{
if (is_array($participant)) {
$assignedRoomId = $participant['assignedRoomId'] ?? null;
return null !== $assignedRoomId ? (int) $assignedRoomId : null;
}
return $participant->assignedRoomId;
}
}
@@ -0,0 +1,29 @@
<?php
namespace App\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use voku\helper\AntiXSS;
class XssCleanTransformer implements DataTransformerInterface
{
private ?AntiXSS $antiXss = null;
public function transform(mixed $value): mixed
{
return $value;
}
public function reverseTransform(mixed $value): mixed
{
if (false === is_string($value) || true === empty($value)) {
return $value;
}
if (null === $this->antiXss) {
$this->antiXss = new AntiXSS();
}
return $this->antiXss->xss_clean($value);
}
}
-45
View File
@@ -1,45 +0,0 @@
<?php
namespace App\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use voku\helper\AntiXSS;
class AntiXssExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if (false === $options['anti_xss']) {
return;
}
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
if (null === $data) {
return;
}
$antiXss = new AntiXSS();
foreach ($data as $key => $value) {
$data[$key] = $antiXss->xss_clean($value);
}
$event->setData($data);
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'anti_xss' => false,
]);
}
public static function getExtendedTypes(): iterable
{
return [FormType::class];
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace App\Form\Extension;
use App\Form\DataTransformer\XssCleanTransformer;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class XssCleanExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if (true === $options['clean_xss']) {
$builder->addModelTransformer(new XssCleanTransformer());
}
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'clean_xss' => false,
]);
$resolver->setAllowedTypes('clean_xss', 'bool');
}
public static function getExtendedTypes(): iterable
{
return [
TextType::class,
TextareaType::class,
EmailType::class,
];
}
}
+6 -8
View File
@@ -7,7 +7,6 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PersonalDataType extends AbstractType class PersonalDataType extends AbstractType
{ {
@@ -17,14 +16,17 @@ class PersonalDataType extends AbstractType
->add('street', TextType::class, [ ->add('street', TextType::class, [
'label' => 'Straße', 'label' => 'Straße',
'property_path' => 'address.street', 'property_path' => 'address.street',
'anti_xss' => true,
]) ])
->add('postCode', TextType::class, [ ->add('postCode', TextType::class, [
'label' => 'PLZ', 'label' => 'PLZ',
'property_path' => 'address.postCode', 'property_path' => 'address.postCode',
'anti_xss' => true,
]) ])
->add('city', TextType::class, [ ->add('city', TextType::class, [
'label' => 'Stadt', 'label' => 'Stadt',
'property_path' => 'address.city', 'property_path' => 'address.city',
'anti_xss' => true,
]) ])
->add('country', CountryType::class, [ ->add('country', CountryType::class, [
'label' => 'Land', 'label' => 'Land',
@@ -33,23 +35,19 @@ class PersonalDataType extends AbstractType
->add('email', EmailType::class, [ ->add('email', EmailType::class, [
'label' => 'E-Mail', 'label' => 'E-Mail',
'property_path' => 'communication.email', 'property_path' => 'communication.email',
'anti_xss' => true,
]) ])
->add('phone', TextType::class, [ ->add('phone', TextType::class, [
'label' => 'Telefon', 'label' => 'Telefon',
'required' => false, 'required' => false,
'property_path' => 'communication.phone', 'property_path' => 'communication.phone',
'anti_xss' => true,
]) ])
->add('mobile', TextType::class, [ ->add('mobile', TextType::class, [
'label' => 'Mobil', 'label' => 'Mobil',
'property_path' => 'communication.mobile', 'property_path' => 'communication.mobile',
'anti_xss' => true,
]) ])
; ;
} }
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'anti_xss' => true,
]);
}
} }
+2 -2
View File
@@ -25,13 +25,14 @@ class RegistrationType extends AbstractType
]) ])
->add('firstName', TextType::class, [ ->add('firstName', TextType::class, [
'label' => 'Name', 'label' => 'Name',
'anti_xss' => true,
]) ])
->add('name', TextType::class, [ ->add('name', TextType::class, [
'label' => 'Nachname', 'label' => 'Nachname',
]) ])
->add('email', EmailType::class, [ ->add('email', EmailType::class, [
'label' => 'E-Mail', 'label' => 'E-Mail',
'property_path' => 'email', 'anti_xss' => true,
]) ])
; ;
} }
@@ -40,7 +41,6 @@ class RegistrationType extends AbstractType
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => RegistrationDto::class, 'data_class' => RegistrationDto::class,
'anti_xss' => true,
]); ]);
} }
} }
@@ -5,14 +5,12 @@ declare(strict_types=1);
namespace App\Form\Service; namespace App\Form\Service;
use App\Form\ChoiceLoader\ParticipantRoomChoiceLoader; use App\Form\ChoiceLoader\ParticipantRoomChoiceLoader;
use App\Form\DataAdapters\ParticipantDataAdapter; use App\Form\Model\ParticipantDto;
use App\Form\Model\RoomSelectionDto;
use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface; use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface;
/** /**
* Factory service for creating ParticipantRoomChoiceLoader instances. * Factory service for creating ParticipantRoomChoiceLoader instances.
*
* This service provides a clean way to create choice loaders with proper
* dependency injection instead of manually instantiating factories in form types.
*/ */
class ParticipantRoomChoiceLoaderFactory class ParticipantRoomChoiceLoaderFactory
{ {
@@ -23,17 +21,20 @@ class ParticipantRoomChoiceLoaderFactory
/** /**
* Creates a ParticipantRoomChoiceLoader for the given participant and room data. * Creates a ParticipantRoomChoiceLoader for the given participant and room data.
*
* @param ParticipantDto[] $allParticipants
* @param RoomSelectionDto[] $selectedRooms
*/ */
public function createChoiceLoader( public function create(
ParticipantDataAdapter $adapter, array $allParticipants,
array $selectedRooms, array $selectedRooms,
int $participantIndex, int $participantIndex,
): ParticipantRoomChoiceLoader { ): ParticipantRoomChoiceLoader {
return new ParticipantRoomChoiceLoader( return new ParticipantRoomChoiceLoader(
$this->choiceListFactory, $this->choiceListFactory,
$adapter, $allParticipants,
$selectedRooms, $selectedRooms,
$participantIndex $participantIndex
); );
} }
} }