<?php
namespace App\Form;
use DateTime;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Entity\Demande;
use App\Form\CategoryType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
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\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Regex;
class DemandeType extends AbstractType
{
protected $emptyValue = '– Sélectionnez –';
public function __construct()
{
}
protected function buildCategoryFields(FormBuilderInterface $builder, array $options)
{
foreach ($options['categories'] as &$category) {
$category['group'] = $options['groups'][$category['node']['id']];
}
$catOpts = array(
'label' => 'Votre demande',
'choices' => $options['categories'],
// 'empty_value' => $this->emptyValue,
'compound' => false,
'em' => $options['em']
);
if ($options['pre_demande']) {
$catOpts['help'] = 'Vous pourrez préciser votre demande à la fin du formulaire';
}
$categorieField = $builder->create('categorie', CategoryType::class, $catOpts);
$builder->add($categorieField, ChoiceType::class, $catOpts);
$default_group = null;
/** @var Demande $demande */
$demande = $options['data'];
$groupId = null;
if ($demande->getCategorie()) {
if ($demande->getCategorie()->getParent()) {
$groupId = $demande->getCategorie()->getParent()->getId();
} else {
$groupId = $demande->getCategorie()->getId();
}
}
$builder->add('group', HiddenType::class, array(
'mapped' => false,
'data' => array_key_exists($groupId, $options['groups']) ? $options['groups'][$groupId] : null
));
}
private function buildPreDemande(FormBuilderInterface $builder, array $options)
{
$categorie = $builder->get('categorie');
$categorie->setRequired(false);
// $categorie->getOptions()['empty_value'] = 'Catégorie';
$bienTypes = Demande::$bienTypes;
unset($bienTypes[6], $bienTypes[8], $bienTypes[9], $bienTypes[10]);
$bienTypes = array_flip($bienTypes);
$builder->add('bienType', ChoiceType::class, array(
'choices' => $bienTypes,
'label' => 'Type de bien',
'placeholder' => $this->emptyValue,
'required' => false
));
$this->addBienLocalisation($builder, $options);
$builder->get('bienLocalisation')->setRequired(false);
$this->addBienCodePostalField($builder, $options);
$builder->get('bienCodePostal')->setRequired(false);
$this->addBienVilleField($builder, $options);
$builder->get('bienVille')->setRequired(false);
$header['attr']['class'] = 'cta-form-header';
$builder->add('submit', SubmitType::class, array(
'label' => 'Comparer',
'attr' => [
'class' => ($options['header']) ? 'cta-form-header' : '',
],
));
}
private function addBienLocalisation(FormBuilderInterface $builder, array $options)
{
$builder->add('bienLocalisation', TextType::class, array(
'label' => 'Ville ou code postal du bien',
// 'mapped' => false,
'attr' => array(
'class' => 'localisation',
'autocomplete' => 'off'
)
));
}
private function addBienCodePostalField(FormBuilderInterface $builder, array $options)
{
$type = HiddenType::class;
if ($options['admin'] === true) {
$type = TextType::class;
}
$builder->add('bienCodePostal', $type, array(
'label' => 'Code postal du bien',
'attr' => array(
'size' => 13,
'class' => 'auto_cp',
'autocomplete' => 'off'
)
));
}
private function addBienVilleField(FormBuilderInterface $builder, array $options)
{
$type = HiddenType::class;
if ($options['admin'] === true) {
$type = TextType::class;
}
$builder->add('bienVille', $type, array(
'label' => 'Ville du bien',
'attr' => array(
'class' => 'auto_ville',
'autocomplete' => 'off'
)
));
}
private function buildDemande(FormBuilderInterface $builder, array $options)
{
// votre bien
$bienTypes = Demande::$bienTypes;
unset($bienTypes[6], $bienTypes[8], $bienTypes[9], $bienTypes[10]);
$bienTypes = array_flip($bienTypes);
$builder->add('bienType', ChoiceType::class, array(
'choices' => $bienTypes,
'label' => 'Type de bien',
'placeholder' => $this->emptyValue,
));
$this->addBienLocalisation($builder, $options);
$this->addBienCodePostalField($builder, $options);
$this->addBienVilleField($builder, $options);
$builder->add('bienNombrePieces', ChoiceType::class, array(
'choices' => array_flip(Demande::$nombrePieces),
'label' => 'Nombre de pièces',
'placeholder' => $this->emptyValue,
));
$builder->add('bienSurface', $options['admin'] ? TextType::class : NumberType::class, array(
'label' => 'Surface (m²)',
'invalid_message' => 'Veuillez entrer une surface valide.'
));
$builder->add('bienAnneeConstructionChoice', ChoiceType::class, array(
'choices' => array_flip(Demande::$constructYears),
'label' => 'Année de construction',
'placeholder' => $this->emptyValue,
'mapped' => false,
'attr' => ['groups' => 'diagnostics']
));
$builder->add('bienAnneeConstructionFree', TextType::class, array(
'label' => 'Année de construction',
'mapped' => false,
'attr' => ['groups' => 'expertises etudes solutions energies']
));
$builder->add('bienCopropriete', ChoiceType::class, array(
'choices' => array_flip(Demande::$coproprieteAnswers),
'label' => 'Le bien est en copropriété',
// 'attr' => array(
// 'class' => 'col-sm-4'
// ),
'placeholder' => $this->emptyValue
));
$builder->add('bienGaz', ChoiceType::class, array(
'choices' => array_flip(Demande::$answers),
'label' => 'Installation gaz + de 15 ans',
'placeholder' => $this->emptyValue,
'attr' => ['groups' => 'diagnostics']
));
$builder->add('bienElectricite', ChoiceType::class, array(
'choices' => array_flip(Demande::$answers),
'label' => 'Installation électrique + de 15 ans',
'placeholder' => $this->emptyValue,
'attr' => ['groups' => 'diagnostics']
));
// votre projet
$builder->add('prestation', ChoiceType::class, array(
'choices' => array_flip(Demande::$prestationAnswers),
'label' => 'Prestation souhaitée',
'placeholder' => $this->emptyValue,
'attr' => ['groups' => 'solutions energies']
));
// $builder->add('descriptionFile', FileType::class, array(
// 'label' => 'Joignez un descriptif (10 Mo max)',
// 'required' => false,
// 'mapped' => false,
// 'attr' => ['groups' => 'expertises etudes solutions energies']
// ));
// $dateMin = new DateTime();
// $dateMin->add(new DateInterval('P2D'));
// $dateMax = new DateTime();
// $dateMax->add(new DateInterval('P3M'));
// $builder->add('expiration', DateType::class, array(
// 'label' => 'Date limite de réception des devis',
// 'format' => 'yyyy-MM-dd',
// 'widget' => 'single_text',
// 'input' => 'datetime',
// 'attr' => array(
// 'min' => $this->getExpirationMin()->format('Y-m-d'),
// 'max' => $dateMax->format('Y-m-d')
// )
// ));
$builder->add('comment', TextareaType::class, array(
'label' => 'Précisez votre demande si vous voulez (sans partager de coordonnées)',
'attr' => array('cols' => 25, 'rows' => 5),
'required' => false
));
// vous-même
$builder->add('clientStatut', ChoiceType::class, array(
'choices' => array_flip(Demande::$clientStatuts),
'label' => 'Vous êtes',
// 'empty_value' => $this->emptyValue
));
$builder->add('clientNom', TextType::class, array(
'label' => 'Nom / Prénom'
));
$builder->add('clientEmail', TextType::class, array(
'label' => 'Email'
));
$builder->add('clientTelephone', TelType::class, array(
'label' => 'Téléphone (10 chiffres)',
'attr' => [
'minlength' => 10,
'maxlength' => 10,
],
'constraints' => [
new Length([
'min' => 10,
'max' => 10,
'exactMessage' => 'Cette valeur doit comporter exactement {{ limit }} chiffre.',
]),
new Regex([
'pattern' => '/^\d+$/',
'message' => 'Veuillez entrer uniquement des chiffres.',
]),
],
));
$builder->add('submit', SubmitType::class, array('label' => 'Valider ma demande'));
$builder->addEventListener(FormEvents::SUBMIT, array($this, 'onSubmit'));
$builder->addEventListener(FormEvents::POST_SET_DATA, array($this, 'onPostSetData'));
}
private function getExpirationMin()
{
$date = new DateTime();
$date->setTimestamp(strtotime('+2 weekdays'));
// $date = DateTime::createFromFormat('U', strtotime('+5 weekdays'));
// $day = (int)$date->format('N');
// if ($day > 5) {
// $date->add(new DateInterval('P1W'));
// $date->sub(new DateInterval('P'. ($day - 1) .'D'));
// }
return $date;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->buildCategoryFields($builder, $options);
$builder->add('pre_demande', HiddenType::class, array(
'mapped' => false,
'data' => $options['pre_demande']
));
if ($options['pre_demande'] === true) {
$this->buildPreDemande($builder, $options);
} else {
$this->buildDemande($builder, $options);
}
}
/**
* @param FormEvent $event
*/
public function onSubmit(FormEvent $event)
{
/** @var Demande $demande */
$demande = $event->getData();
$validationGroups = self::determineValidationGroups($event->getForm());
$group = '';
if (count($validationGroups) > 1) {
$group = $validationGroups[1];
}
if ($group) {
$fields = array('bienAnneeConstructionChoice', 'bienAnneeConstructionFree');
foreach ($fields as $fieldName) {
$field = $event->getForm()->get($fieldName);
// if field is enabled for the current validation group
if (strpos($field->getConfig()->getOption('attr')['groups'], $group) !== false) {
if ($field->getData() === null) {
$field->addError(new FormError('Veuillez renseigner ce champ.'));
} elseif ($fieldName == 'bienAnneeConstructionChoice') {
$values = Demande::$constructYears;
if (array_key_exists($field->getData(), $values)) {
$demande->setBienAnneeConstruction($values[$field->getData()]);
} else {
$field->addError(new FormError('Valeur invalide'));
}
} else {
$demande->setBienAnneeConstruction($field->getData());
}
}
}
}
}
public function onPostSetData(FormEvent $event)
{
/** @var Demande $demande */
$demande = $event->getData();
$data = $demande->getBienAnneeConstruction();
$key = array_search($data, Demande::$constructYears);
if ($key !== false) {
$event->getForm()->get('bienAnneeConstructionChoice')->setData($key);
}
$event->getForm()->get('bienAnneeConstructionFree')->setData($data);
// if ($key !== false) {
// $field = $event->getForm()->get('bienAnneeConstructionChoice');
// $field->setData($key);
// }
// else {
// $field = $event->getForm()->get('bienAnneeConstructionFree');
// $field->setData($data);
// }
}
public static function determineValidationGroups(FormInterface $form)
{
$extra = $form->getExtraData();
if (!empty($extra['pre_demande'])) {
return false;
}
/** @var Demande $demande */
$demande = $form->getData();
$categorie = $demande->getCategorie();
if ($categorie) {
$cid = $categorie->getId();
$groups = $form->getConfig()->getOption('groups');
$categories = $form->getConfig()->getOption('categories');
// look for child / parent
foreach ($categories as $parent) {
foreach ($parent['children'] as $child) {
if ($child['node']['id'] == $cid) {
return array('Default', $groups[$parent['node']['id']]);
}
}
}
} else {
// no categorie given, look for group field
return array('Default', $form->get('group')->getData());
}
return 'Default';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults(array(
'data_class' => 'App\Entity\Demande',
'validation_groups' => array(
'App\Form\DemandeType',
'determineValidationGroups'
),
'pre_demande' => false,
'admin' => false,
'header' => false,
'attr' => array('novalidate' => 'novalidate')
))
->setRequired(array(
'em',
'categories',
'groups'
));
}
/**
* Returns the name of this type.
*
* @return string The name of this type
*/
public function getName()
{
return 'demande';
}
}