Skip to content

Commit

Permalink
Explo: amélioration des perfs UpdateMeasureController
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarchois committed Dec 18, 2024
1 parent 401f562 commit b73c4f3
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 47 deletions.
2 changes: 2 additions & 0 deletions config/packages/framework.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ framework:
#fragments: true
php_errors:
log: true
validation:
cache: validator.mapping.cache.adapter

http_client:
scoped_clients:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,9 @@ public function getRoadDeleteCommand(): ?CommandInterface

return null;
}

public function getRoadType(): string
{
return $this->roadType;
}
}
144 changes: 97 additions & 47 deletions src/Infrastructure/Form/Regulation/LocationFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,97 +12,147 @@
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;

final class LocationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// Ajout du champ roadType qui contrôle l'affichage des autres formulaires
$builder->add('roadType', ChoiceType::class, [
'choices' => $this->getRoadTypeChoices($options['permissions']),
'label' => 'regulation.location.type',
'label_attr' => [
'class' => 'required',
],
]);

// Ajout de tous les sous-formulaires avec mapped => false par défaut
$this->addAllSubForms($builder, $options);

// Gestion des événements PRE_SET_DATA et PRE_SUBMIT
$this->addFormEventListeners($builder, $options);
}

private function addAllSubForms(FormBuilderInterface $builder, array $options): void
{
// Ajout des formulaires de routes numérotées
$builder
->add(
'roadType',
ChoiceType::class,
options: $this->getRoadTypeOptions(),
)
->add(RoadTypeEnum::DEPARTMENTAL_ROAD->value, NumberedRoadFormType::class, [
'roadType' => RoadTypeEnum::DEPARTMENTAL_ROAD->value,
'administrators' => $options['administrators'][RoadTypeEnum::DEPARTMENTAL_ROAD->value],
->add('departmentalRoad', NumberedRoadFormType::class, [
'mapped' => false,
'label' => false,
'roadType' => RoadTypeEnum::DEPARTMENTAL_ROAD->value,
'administrators' => $options['administrators'][RoadTypeEnum::DEPARTMENTAL_ROAD->value] ?? [],
])
->add(RoadTypeEnum::NATIONAL_ROAD->value, NumberedRoadFormType::class, [
'roadType' => RoadTypeEnum::NATIONAL_ROAD->value,
'administrators' => $options['administrators'][RoadTypeEnum::NATIONAL_ROAD->value],
->add('nationalRoad', NumberedRoadFormType::class, [
'mapped' => false,
'label' => false,
'roadType' => RoadTypeEnum::NATIONAL_ROAD->value,
'administrators' => $options['administrators'][RoadTypeEnum::NATIONAL_ROAD->value] ?? [],
])
->add('namedStreet', NamedStreetFormType::class, [
'mapped' => false,
'label' => false,
])
->add('rawGeoJSON', RawGeoJSONFormType::class, [
'mapped' => false,
'label' => false,
])
;
]);
}

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
private function addFormEventListeners(FormBuilderInterface $builder, array $options): void
{
// PRE_SET_DATA pour le chargement initial
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void {
$form = $event->getForm();
$command = $event->getData();

$isRawGeoJSON = $command?->roadType === RoadTypeEnum::RAW_GEOJSON->value;
$canUseRawGeoJSON = \in_array(CanUseRawGeoJSON::PERMISSION_NAME, $options['permissions']);

if ($isRawGeoJSON || $canUseRawGeoJSON) {
// Replace field with new options
$form->add(
'roadType',
ChoiceType::class,
options: $this->getRoadTypeOptions(
includeRawGeoJSONOption: true,
),
);
$data = $event->getData();

if (!$data) {
return;
}

$this->updateFormMappingBasedOnRoadType($form, $data->getRoadType());
});

// PRE_SUBMIT pour la soumission du formulaire
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event): void {
$form = $event->getForm();
$data = $event->getData();

if (!isset($data['roadType'])) {
return;
}

$this->updateFormMappingBasedOnRoadType($form, $data['roadType']);
});
}

private function getRoadTypeOptions(bool $includeRawGeoJSONOption = false): array
private function updateFormMappingBasedOnRoadType(FormInterface $form, string $roadType): void
{
// Réinitialiser tous les mapped à false
foreach (['departmentalRoad', 'nationalRoad', 'namedStreet', 'rawGeoJSON'] as $field) {
if ($form->has($field)) {
$config = $form->get($field)->getConfig();
$form->add($field, \get_class($config->getType()->getInnerType()), [
'mapped' => false,
'label' => false,
] + $config->getOptions());
}
}

// Activer le mapping uniquement pour le formulaire correspondant au type de route
$fieldMap = [
RoadTypeEnum::DEPARTMENTAL_ROAD->value => 'departmentalRoad',
RoadTypeEnum::NATIONAL_ROAD->value => 'nationalRoad',
'lane' => 'namedStreet',
RoadTypeEnum::RAW_GEOJSON->value => 'rawGeoJSON',
];

if (isset($fieldMap[$roadType]) && $form->has($fieldMap[$roadType])) {
$field = $fieldMap[$roadType];
$config = $form->get($field)->getConfig();
$form->add($field, \get_class($config->getType()->getInnerType()), [
'mapped' => true,
'label' => false,
] + $config->getOptions());
}
}

private function getRoadTypeChoices(array $permissions): array
{
$choices = [];
$choiceAttr = [];
$choices['regulation.location.type.placeholder'] = '';

foreach (RoadTypeEnum::cases() as $case) {
$label = \sprintf('regulation.location.road.type.%s', $case->value);

if ($case->value === RoadTypeEnum::RAW_GEOJSON->value && !$includeRawGeoJSONOption) {
$choiceAttr[$label] = [
'hidden' => '',
'disabled' => 'disabled', // For Safari (it does not support <option hidden>)
];
// Gestion spéciale pour RAW_GEOJSON
if ($case->value === RoadTypeEnum::RAW_GEOJSON->value
&& !\in_array(CanUseRawGeoJSON::PERMISSION_NAME, $permissions)) {
continue;
}

$choices[$label] = $case->value;
}

return [
'choices' => array_merge(
['regulation.location.type.placeholder' => ''],
$choices,
),
'choice_attr' => $choiceAttr,
'label' => 'regulation.location.type',
'label_attr' => [
'class' => 'required',
],
];
return $choices;
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => SaveLocationCommand::class,
'administrators' => [
RoadTypeEnum::DEPARTMENTAL_ROAD->value => [],
RoadTypeEnum::NATIONAL_ROAD->value => [],
],
'permissions' => [],
'data_class' => SaveLocationCommand::class,
'validation_groups' => function (FormInterface $form) {
return ['Default', $form->getData()?->getRoadType() ?? ''];
},
]);

$resolver->setAllowedTypes('administrators', 'array');
$resolver->setAllowedTypes('permissions', 'array');
}
Expand Down

0 comments on commit b73c4f3

Please sign in to comment.