<?php
namespace App\Form\Website\Type\Contact;
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\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
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\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\NotBlank;
use Symfony\Component\Validator\Constraints\Regex;
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
// Civilité - Radio buttons
->add('civility', ChoiceType::class, [
'label' => 'Civilité',
'required' => true,
'choices' => [
'M.' => 'M.',
'Mme' => 'Mme',
],
'expanded' => true,
'multiple' => false,
'constraints' => [
new NotBlank([
'message' => 'Veuillez sélectionner une civilité.',
]),
],
])
// Nom
->add('lastName', TextType::class, [
'label' => 'Nom',
'required' => true,
'attr' => [
'placeholder' => 'Nom',
],
'constraints' => [
new NotBlank([
'message' => 'Le nom est obligatoire.',
]),
],
])
// Prénom
->add('firstName', TextType::class, [
'label' => 'Prénom',
'required' => true,
'attr' => [
'placeholder' => 'Prénom',
],
'constraints' => [
new NotBlank([
'message' => 'Le prénom est obligatoire.',
]),
],
])
// Email
->add('email', EmailType::class, [
'label' => 'Email',
'required' => true,
'attr' => [
'placeholder' => 'email@exemple.fr',
],
'constraints' => [
new NotBlank([
'message' => 'L\'adresse email est obligatoire.',
]),
new Email([
'message' => 'Veuillez saisir une adresse email valide.',
]),
],
])
// Téléphone
->add('phone', TelType::class, [
'label' => 'Téléphone',
'required' => true,
'attr' => [
'placeholder' => '+33',
],
'constraints' => [
new NotBlank([
'message' => 'Le numéro de téléphone est obligatoire.',
]),
// Le JS pré-remplit souvent le champ avec le préfixe pays (+33 ...).
// On considère valide uniquement s'il y a assez de chiffres au-delà du préfixe.
new Regex([
'pattern' => '/^\\+?[0-9][0-9\\s\\-\\(\\)]{8,}$/',
'message' => 'Veuillez saisir un numéro de téléphone valide.',
]),
],
])
// Objet - Select
->add('subject', ChoiceType::class, [
'label' => 'Objet',
'required' => true,
'choices' => [
'Vous souhaitez faire une réservation, vous avez besoin, d\'un devis, d\'informations complémentaires' => 'reservation_info',
'Vous avez déjà une réservation, vous avez besoin d\'aide' => 'existing_reservation',
'Vous avez un projet de voyage en groupe, des questions, besoin d\'aide' => 'group_travel',
'Autres (précisez votre demande dans la partie message ci-dessous)' => 'other',
],
'placeholder' => 'Sélectionnez un objet',
'constraints' => [
new NotBlank([
'message' => 'Veuillez sélectionner un objet.',
]),
],
])
// Message - Textarea
->add('message', TextareaType::class, [
'label' => 'Message',
'required' => true,
'attr' => [
'placeholder' => 'Décrivez votre message',
],
'constraints' => [
new NotBlank([
'message' => 'Le message est obligatoire.',
]),
],
])
// Je souhaite être rappelé(e) - Radio buttons
->add('wantsCallback', ChoiceType::class, [
'label' => 'Je souhaite être rappelé(e)',
'required' => true,
'choices' => [
'Oui' => true,
'Non' => false,
],
'expanded' => true,
'multiple' => false,
])
// Date et heure de rappel - Conditionnel
->add('callbackDateTime', DateTimeType::class, [
'label' => 'Date et heure de rappel',
'required' => false,
'widget' => 'single_text',
'html5' => false,
'format' => 'yyyy-MM-dd HH:mm',
'attr' => [
'class' => 'form-control callback-field flatpickr-datetime',
'data-flatpickr' => 'true',
],
])
// Checkbox de consentement
->add('consent', CheckboxType::class, [
'label' => 'website.forms.contact.label.consent',
'required' => true,
'constraints' => [
new IsTrue([
'message' => 'Vous devez accepter l\'exploitation de vos données.',
]),
],
]);
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$wantsCallback = $form->get('wantsCallback')->getData();
if ($wantsCallback === null) {
$form->get('wantsCallback')->addError(
new \Symfony\Component\Form\FormError('Veuillez indiquer si vous souhaitez être rappelé(e).')
);
return;
}
$wantsCallbackYes = $wantsCallback === true
|| $wantsCallback === 1
|| $wantsCallback === '1'
|| $wantsCallback === 'true';
if (!$wantsCallbackYes) {
return;
}
$callbackDateTime = $form->get('callbackDateTime')->getData();
if ($callbackDateTime === null || $callbackDateTime === '') {
$form->get('callbackDateTime')->addError(
new \Symfony\Component\Form\FormError('Veuillez sélectionner un créneau de rappel.')
);
}
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'csrf_protection' => true,
]);
}
}