<?php
namespace App\Form\Website\Type\PurchaseQuoteRequest;
use Crea\ToolsBundle\Helper\EntityManagerHelper;
use Croisiland\CommonBundle\Entity\Cabin\CabinCategory;
use Croisiland\CommonBundle\Entity\Cruise\Cruise;
use Croisiland\CommonBundle\Entity\Partner\Partner;
use Croisiland\CommonBundle\Model\CivilityEnum;
use Croisiland\CommonBundle\Model\ProspectRequestModel;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TelType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Regex;
use Symfony\Contracts\Translation\TranslatorInterface;
class PurchaseQuoteRequestType extends AbstractType
{
protected TranslatorInterface $translator;
protected EntityManagerInterface $entityManager;
public function __construct(TranslatorInterface $translator, EntityManagerInterface $entityManager)
{
$this->translator = $translator;
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('civility', ChoiceType::class, [
'label' => 'website.forms.contact.label.civility',
'choices' => [
'website.forms.civility.man' => CivilityEnum::MR->value,
'website.forms.civility.women' => CivilityEnum::MRS->value
],
'expanded' => true,
'getter' => function (ProspectRequestModel $prospectRequestModel): string {
return $prospectRequestModel->getCivility()->value;
},
'setter' => function (ProspectRequestModel $prospectRequestModel, ?string $choice): void {
$prospectRequestModel->setCivility($choice === CivilityEnum::MR->value ? CivilityEnum::MR : CivilityEnum::MRS);
},
])
->add('lastName', TextType::class, [
'label' => 'website.forms.contact.label.last_name',
'attr' => [
'placeholder' => 'website.forms.contact.placeholder.last_name',
],
'constraints' => [
new NotBlank(),
new Length(null, 2, 255),
]
])
->add('firstName', TextType::class, [
'label' => 'website.forms.contact.label.first_name',
'attr' => [
'placeholder' => 'website.forms.contact.placeholder.first_name',
],
'constraints' => [
new NotBlank(),
new Length(null, 2, 255),
]
])
->add('email', EmailType::class, [
'label' => 'website.forms.contact.label.email',
'attr' => [
'placeholder' => 'website.forms.contact.placeholder.email',
],
'constraints' => [
new NotBlank(),
new Email(),
new Length(null, 2, 255),
]
])
->add('phoneNumber', TelType::class, [
'label' => 'website.forms.contact.label.phone_number',
'constraints' => [
new NotBlank(),
new Regex([
'pattern' => '/^\\+?[0-9][0-9\\s\\-\\(\\)]{8,}$/',
'message' => 'Veuillez saisir un numéro de téléphone valide.',
]),
],
])
->add('purchaseQuoteRequestPassengers', CollectionType::class, [
'label' => 'website.forms.cruise_prospect_request.label.passengers',
'entry_type' => PurchaseQuoteRequestPassengerType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'error_bubbling' => false,
])
->add('message', TextareaType::class, [
'label' => $this->translator->trans('website.forms.contact.label.message'),
'attr' => [
'placeholder' => $this->translator->trans('website.forms.contact.label.content'),
'data-max-words' => 225
],
'constraints' => [
new NotBlank(),
new Length(['max' => 1125]) // 225 mots × 5 caractères par mot en moyenne
]
])
->add('newsletter', CheckboxType::class, [
'label' => 'website.forms.quote_request.label.newsletter',
'required' => false
])
->add('purchaseId', HiddenType::class, [
'required' => false,
'mapped' => false,
])
->add('cabinId', HiddenType::class, [
'required' => false,
'mapped' => false,
])
->add('atmosphereId', HiddenType::class, [
'required' => false,
'mapped' => false,
])
->add('subtypeId', HiddenType::class, [
'required' => false,
'mapped' => false,
])
->add('categoryId', HiddenType::class, [
'required' => false,
'mapped' => false
])
->add('price', HiddenType::class, [
'required' => false
])
->add('reservationMethod', HiddenType::class, [
'required' => false,
'mapped' => false,
])
->add('consent', CheckboxType::class, [
'label' => 'website.forms.quote_request.label.consent',
'required' => true,
'mapped' => false,
'constraints' => [
new IsTrue([
'message' => 'Vous devez accepter l\'exploitation de vos données.',
]),
],
])
->add('cruise', HiddenType::class, [
'required' => false,
'getter' => function (ProspectRequestModel $prospectRequestModel): ?int {
return $prospectRequestModel->getCruise()?->getId();
},
'setter' => function (ProspectRequestModel $prospectRequestModel, ?int $cruiseId): void {
if ($cruiseId !== null) {
$prospectRequestModel->setCruise($this->entityManager->getRepository(Cruise::class)->find($cruiseId));
}
},
])
->add('partner', HiddenType::class, [
'required' => false,
'getter' => function (ProspectRequestModel $prospectRequestModel): ?int {
return $prospectRequestModel->getPartner()?->getId();
},
'setter' => function (ProspectRequestModel $prospectRequestModel, ?int $partnerId): void {
if ($partnerId !== null) {
$prospectRequestModel->setPartner($this->entityManager->getRepository(Partner::class)->find($partnerId));
}
},
])
->add('cabinCategory', HiddenType::class, [
'required' => false,
'getter' => function (ProspectRequestModel $prospectRequestModel): ?int {
return $prospectRequestModel->getCabinCategory()?->getId();
},
'setter' => function (ProspectRequestModel $prospectRequestModel, ?int $cabinCategoryId): void {
if ($cabinCategoryId !== null) {
$prospectRequestModel->setCabinCategory($this->entityManager->getRepository(CabinCategory::class)->find($cabinCategoryId));
}
},
])
;
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$passengersCount = 0;
if (is_object($data) && method_exists($data, 'getPurchaseQuoteRequestPassengers')) {
$passengersCount = count($data->getPurchaseQuoteRequestPassengers());
} elseif (is_array($data) && isset($data['purchaseQuoteRequestPassengers'])) {
$passengersCount = count($data['purchaseQuoteRequestPassengers']);
}
$form
->add('purchaseQuoteRequestPassengersSelect', ChoiceType::class, [
'label' => null,
'choices' => [
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6'
],
'data' => $passengersCount > 0 ? (string)$passengersCount : '1',
'mapped' => false,
])
;
// Champs de rappel obligatoires
$form
->add('callbackDate', DateType::class, [
'label' => $this->translator->trans('website.forms.contact.label.callback_date'),
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',
'attr' => [
'placeholder' => $this->translator->trans('website.forms.contact.placeholder.callback_date'),
],
'required' => true
])
->add('callbackTime', TimeType::class, [
'label' => ' ',
'required' => true,
'widget' => 'single_text',
'attr' => [
'placeholder' => $this->translator->trans('website.forms.contact.placeholder.callback_time'),
],
])
;
});
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"data_class" => ProspectRequestModel::class,
"translation_domain" => "messages",
"validation_groups" => ['Default', 'prospect_request_model_form_validator']
]);
}
}