<?php
declare(strict_types=1);
namespace Croisiland\CommonBundle\Form;
use Croisiland\CommonBundle\Filter\FilterInterface;
use Croisiland\CommonBundle\Form\FilterType\CompaniesFilterType;
use Croisiland\CommonBundle\Form\FilterType\CruiseCodeFilterType;
use Croisiland\CommonBundle\Form\FilterType\DeparturePortsFilterType;
use Croisiland\CommonBundle\Form\FilterType\DestinationsFilterType;
use Croisiland\CommonBundle\Form\FilterType\DurationsFilterType;
use Croisiland\CommonBundle\Form\FilterType\KeywordsFilterType;
use Croisiland\CommonBundle\Form\FilterType\OffersFilterType;
use Croisiland\CommonBundle\Form\FilterType\PaginationFilterType;
use Croisiland\CommonBundle\Form\FilterType\PartnerFilterType;
use Croisiland\CommonBundle\Form\FilterType\PeriodFilterType;
use Croisiland\CommonBundle\Form\FilterType\PriceRangeFilterType;
use Croisiland\CommonBundle\Form\FilterType\ShipsFilterType;
use Croisiland\CommonBundle\Form\FilterType\SortOrderFilterType;
use Croisiland\CommonBundle\Form\FilterType\TagsFilterType;
use Croisiland\CommonBundle\Form\FilterType\WorldTourFilterType;
use Croisiland\CommonBundle\Serializer\CruiseSearchModelSerializer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\RouterInterface;
/**
* @extends AbstractType<CruiseSearchFullFormType>
*/
class CruiseSearchFullFormType extends AbstractType
{
/**
* @var FilterInterface[]
*/
private array $filters;
/**
* @param iterable<FilterInterface> $filters
*/
public function __construct(
private readonly CruiseSearchModelSerializer $cruiseSearchModelSerializer,
private readonly RouterInterface $router,
iterable $filters,
) {
$this->filters = $filters instanceof \Traversable ? iterator_to_array($filters) : $filters;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// Mappage des noms de champs vers leurs types
$fieldTypes = [
'keywords' => KeywordsFilterType::class,
'cruiseCode' => CruiseCodeFilterType::class,
'period' => PeriodFilterType::class,
'priceRange' => PriceRangeFilterType::class,
'durations' => DurationsFilterType::class,
'worldTour' => WorldTourFilterType::class,
'companies' => CompaniesFilterType::class,
'partner' => PartnerFilterType::class,
'ships' => ShipsFilterType::class,
'destinations' => DestinationsFilterType::class,
'departurePorts' => DeparturePortsFilterType::class,
'tags' => TagsFilterType::class,
'offers' => OffersFilterType::class,
];
// Ajouter les champs dans l'ordre spécifié
foreach ($options['visible_fields'] as $fieldName => $fieldOptions) {
if (isset($fieldTypes[$fieldName])) {
$builder->add($fieldName, $fieldTypes[$fieldName], $fieldOptions);
}
}
$builder
->add('order', SortOrderFilterType::class, [
'attr' => [
'class' => 'hidden',
],
])
->add('pagination', PaginationFilterType::class, [
'attr' => [
'class' => 'hidden',
],
])
;
$builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']);
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']);
}
public function onPreSetData(FormEvent $event): void
{
$form = $event->getForm();
$data = $event->getData();
foreach ($this->filters as $filter) {
$filter->updateField(
$form,
$this->cruiseSearchModelSerializer->toSimpleArray($data)
);
}
}
public function onPreSubmit(FormEvent $event): void
{
$form = $event->getForm();
$data = $event->getData();
foreach ($this->filters as $filter) {
$filter->updateField(
$form,
$this->cruiseSearchModelSerializer->simplifyFormData($data)
);
}
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'translation_domain' => 'search-cruise-form',
'attr' => [
'id' => 'cruise-search-form-full',
'class' => 'common-search-engine-form',
'data-dynamic-options-url' => $this->router->generate('croisiland_common.get_dynamic-options'),
],
'visible_fields' => [
'keywords' => [],
'cruiseCode' => [],
'period' => [],
'priceRange' => [],
'durations' => [],
'worldTour' => [],
'companies' => [],
'partner' => [],
'ships' => [],
'destinations' => [],
'departurePorts' => [],
'tags' => [],
'offers' => [],
'order' => [],
'pagination' => [],
'submit' => [],
'reset' => [],
],
]);
$resolver->setAllowedTypes('visible_fields', 'array');
}
}