src/Form/DemandeType.php line 25

Open in your IDE?
  1. <?php
  2. namespace App\Form;
  3. use DateTime;
  4. use Symfony\Component\Form\AbstractType;
  5. use Symfony\Component\Form\FormBuilderInterface;
  6. use Symfony\Component\Form\FormError;
  7. use Symfony\Component\Form\FormEvent;
  8. use Symfony\Component\Form\FormEvents;
  9. use Symfony\Component\Form\FormInterface;
  10. use Symfony\Component\OptionsResolver\OptionsResolver;
  11. use App\Entity\Demande;
  12. use App\Form\CategoryType;
  13. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  14. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  15. use Symfony\Component\Form\Extension\Core\Type\NumberType;
  16. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  17. use Symfony\Component\Form\Extension\Core\Type\TelType;
  18. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  19. use Symfony\Component\Form\Extension\Core\Type\TextType;
  20. use Symfony\Component\Validator\Constraints\Length;
  21. use Symfony\Component\Validator\Constraints\Regex;
  22. class DemandeType extends AbstractType
  23. {
  24. protected $emptyValue = '– Sélectionnez –';
  25. public function __construct()
  26. {
  27. }
  28. protected function buildCategoryFields(FormBuilderInterface $builder, array $options)
  29. {
  30. foreach ($options['categories'] as &$category) {
  31. $category['group'] = $options['groups'][$category['node']['id']];
  32. }
  33. $catOpts = array(
  34. 'label' => 'Votre demande',
  35. 'choices' => $options['categories'],
  36. // 'empty_value' => $this->emptyValue,
  37. 'compound' => false,
  38. 'em' => $options['em']
  39. );
  40. if ($options['pre_demande']) {
  41. $catOpts['help'] = 'Vous pourrez préciser votre demande à la fin du formulaire';
  42. }
  43. $categorieField = $builder->create('categorie', CategoryType::class, $catOpts);
  44. $builder->add($categorieField, ChoiceType::class, $catOpts);
  45. $default_group = null;
  46. /** @var Demande $demande */
  47. $demande = $options['data'];
  48. $groupId = null;
  49. if ($demande->getCategorie()) {
  50. if ($demande->getCategorie()->getParent()) {
  51. $groupId = $demande->getCategorie()->getParent()->getId();
  52. } else {
  53. $groupId = $demande->getCategorie()->getId();
  54. }
  55. }
  56. $builder->add('group', HiddenType::class, array(
  57. 'mapped' => false,
  58. 'data' => array_key_exists($groupId, $options['groups']) ? $options['groups'][$groupId] : null
  59. ));
  60. }
  61. private function buildPreDemande(FormBuilderInterface $builder, array $options)
  62. {
  63. $categorie = $builder->get('categorie');
  64. $categorie->setRequired(false);
  65. // $categorie->getOptions()['empty_value'] = 'Catégorie';
  66. $bienTypes = Demande::$bienTypes;
  67. unset($bienTypes[6], $bienTypes[8], $bienTypes[9], $bienTypes[10]);
  68. $bienTypes = array_flip($bienTypes);
  69. $builder->add('bienType', ChoiceType::class, array(
  70. 'choices' => $bienTypes,
  71. 'label' => 'Type de bien',
  72. 'placeholder' => $this->emptyValue,
  73. 'required' => false
  74. ));
  75. $this->addBienLocalisation($builder, $options);
  76. $builder->get('bienLocalisation')->setRequired(false);
  77. $this->addBienCodePostalField($builder, $options);
  78. $builder->get('bienCodePostal')->setRequired(false);
  79. $this->addBienVilleField($builder, $options);
  80. $builder->get('bienVille')->setRequired(false);
  81. $header['attr']['class'] = 'cta-form-header';
  82. $builder->add('submit', SubmitType::class, array(
  83. 'label' => 'Comparer',
  84. 'attr' => [
  85. 'class' => ($options['header']) ? 'cta-form-header' : '',
  86. ],
  87. ));
  88. }
  89. private function addBienLocalisation(FormBuilderInterface $builder, array $options)
  90. {
  91. $builder->add('bienLocalisation', TextType::class, array(
  92. 'label' => 'Ville ou code postal du bien',
  93. // 'mapped' => false,
  94. 'attr' => array(
  95. 'class' => 'localisation',
  96. 'autocomplete' => 'off'
  97. )
  98. ));
  99. }
  100. private function addBienCodePostalField(FormBuilderInterface $builder, array $options)
  101. {
  102. $type = HiddenType::class;
  103. if ($options['admin'] === true) {
  104. $type = TextType::class;
  105. }
  106. $builder->add('bienCodePostal', $type, array(
  107. 'label' => 'Code postal du bien',
  108. 'attr' => array(
  109. 'size' => 13,
  110. 'class' => 'auto_cp',
  111. 'autocomplete' => 'off'
  112. )
  113. ));
  114. }
  115. private function addBienVilleField(FormBuilderInterface $builder, array $options)
  116. {
  117. $type = HiddenType::class;
  118. if ($options['admin'] === true) {
  119. $type = TextType::class;
  120. }
  121. $builder->add('bienVille', $type, array(
  122. 'label' => 'Ville du bien',
  123. 'attr' => array(
  124. 'class' => 'auto_ville',
  125. 'autocomplete' => 'off'
  126. )
  127. ));
  128. }
  129. private function buildDemande(FormBuilderInterface $builder, array $options)
  130. {
  131. // votre bien
  132. $bienTypes = Demande::$bienTypes;
  133. unset($bienTypes[6], $bienTypes[8], $bienTypes[9], $bienTypes[10]);
  134. $bienTypes = array_flip($bienTypes);
  135. $builder->add('bienType', ChoiceType::class, array(
  136. 'choices' => $bienTypes,
  137. 'label' => 'Type de bien',
  138. 'placeholder' => $this->emptyValue,
  139. ));
  140. $this->addBienLocalisation($builder, $options);
  141. $this->addBienCodePostalField($builder, $options);
  142. $this->addBienVilleField($builder, $options);
  143. $builder->add('bienNombrePieces', ChoiceType::class, array(
  144. 'choices' => array_flip(Demande::$nombrePieces),
  145. 'label' => 'Nombre de pièces',
  146. 'placeholder' => $this->emptyValue,
  147. ));
  148. $builder->add('bienSurface', $options['admin'] ? TextType::class : NumberType::class, array(
  149. 'label' => 'Surface (m²)',
  150. 'invalid_message' => 'Veuillez entrer une surface valide.'
  151. ));
  152. $builder->add('bienAnneeConstructionChoice', ChoiceType::class, array(
  153. 'choices' => array_flip(Demande::$constructYears),
  154. 'label' => 'Année de construction',
  155. 'placeholder' => $this->emptyValue,
  156. 'mapped' => false,
  157. 'attr' => ['groups' => 'diagnostics']
  158. ));
  159. $builder->add('bienAnneeConstructionFree', TextType::class, array(
  160. 'label' => 'Année de construction',
  161. 'mapped' => false,
  162. 'attr' => ['groups' => 'expertises etudes solutions energies']
  163. ));
  164. $builder->add('bienCopropriete', ChoiceType::class, array(
  165. 'choices' => array_flip(Demande::$coproprieteAnswers),
  166. 'label' => 'Le bien est en copropriété',
  167. // 'attr' => array(
  168. // 'class' => 'col-sm-4'
  169. // ),
  170. 'placeholder' => $this->emptyValue
  171. ));
  172. $builder->add('bienGaz', ChoiceType::class, array(
  173. 'choices' => array_flip(Demande::$answers),
  174. 'label' => 'Installation gaz + de 15 ans',
  175. 'placeholder' => $this->emptyValue,
  176. 'attr' => ['groups' => 'diagnostics']
  177. ));
  178. $builder->add('bienElectricite', ChoiceType::class, array(
  179. 'choices' => array_flip(Demande::$answers),
  180. 'label' => 'Installation électrique + de 15 ans',
  181. 'placeholder' => $this->emptyValue,
  182. 'attr' => ['groups' => 'diagnostics']
  183. ));
  184. // votre projet
  185. $builder->add('prestation', ChoiceType::class, array(
  186. 'choices' => array_flip(Demande::$prestationAnswers),
  187. 'label' => 'Prestation souhaitée',
  188. 'placeholder' => $this->emptyValue,
  189. 'attr' => ['groups' => 'solutions energies']
  190. ));
  191. // $builder->add('descriptionFile', FileType::class, array(
  192. // 'label' => 'Joignez un descriptif (10 Mo max)',
  193. // 'required' => false,
  194. // 'mapped' => false,
  195. // 'attr' => ['groups' => 'expertises etudes solutions energies']
  196. // ));
  197. // $dateMin = new DateTime();
  198. // $dateMin->add(new DateInterval('P2D'));
  199. // $dateMax = new DateTime();
  200. // $dateMax->add(new DateInterval('P3M'));
  201. // $builder->add('expiration', DateType::class, array(
  202. // 'label' => 'Date limite de réception des devis',
  203. // 'format' => 'yyyy-MM-dd',
  204. // 'widget' => 'single_text',
  205. // 'input' => 'datetime',
  206. // 'attr' => array(
  207. // 'min' => $this->getExpirationMin()->format('Y-m-d'),
  208. // 'max' => $dateMax->format('Y-m-d')
  209. // )
  210. // ));
  211. $builder->add('comment', TextareaType::class, array(
  212. 'label' => 'Précisez votre demande si vous voulez (sans partager de coordonnées)',
  213. 'attr' => array('cols' => 25, 'rows' => 5),
  214. 'required' => false
  215. ));
  216. // vous-même
  217. $builder->add('clientStatut', ChoiceType::class, array(
  218. 'choices' => array_flip(Demande::$clientStatuts),
  219. 'label' => 'Vous êtes',
  220. // 'empty_value' => $this->emptyValue
  221. ));
  222. $builder->add('clientNom', TextType::class, array(
  223. 'label' => 'Nom / Prénom'
  224. ));
  225. $builder->add('clientEmail', TextType::class, array(
  226. 'label' => 'Email'
  227. ));
  228. $builder->add('clientTelephone', TelType::class, array(
  229. 'label' => 'Téléphone (10 chiffres)',
  230. 'attr' => [
  231. 'minlength' => 10,
  232. 'maxlength' => 10,
  233. ],
  234. 'constraints' => [
  235. new Length([
  236. 'min' => 10,
  237. 'max' => 10,
  238. 'exactMessage' => 'Cette valeur doit comporter exactement {{ limit }} chiffre.',
  239. ]),
  240. new Regex([
  241. 'pattern' => '/^\d+$/',
  242. 'message' => 'Veuillez entrer uniquement des chiffres.',
  243. ]),
  244. ],
  245. ));
  246. $builder->add('submit', SubmitType::class, array('label' => 'Valider ma demande'));
  247. $builder->addEventListener(FormEvents::SUBMIT, array($this, 'onSubmit'));
  248. $builder->addEventListener(FormEvents::POST_SET_DATA, array($this, 'onPostSetData'));
  249. }
  250. private function getExpirationMin()
  251. {
  252. $date = new DateTime();
  253. $date->setTimestamp(strtotime('+2 weekdays'));
  254. // $date = DateTime::createFromFormat('U', strtotime('+5 weekdays'));
  255. // $day = (int)$date->format('N');
  256. // if ($day > 5) {
  257. // $date->add(new DateInterval('P1W'));
  258. // $date->sub(new DateInterval('P'. ($day - 1) .'D'));
  259. // }
  260. return $date;
  261. }
  262. public function buildForm(FormBuilderInterface $builder, array $options)
  263. {
  264. $this->buildCategoryFields($builder, $options);
  265. $builder->add('pre_demande', HiddenType::class, array(
  266. 'mapped' => false,
  267. 'data' => $options['pre_demande']
  268. ));
  269. if ($options['pre_demande'] === true) {
  270. $this->buildPreDemande($builder, $options);
  271. } else {
  272. $this->buildDemande($builder, $options);
  273. }
  274. }
  275. /**
  276. * @param FormEvent $event
  277. */
  278. public function onSubmit(FormEvent $event)
  279. {
  280. /** @var Demande $demande */
  281. $demande = $event->getData();
  282. $validationGroups = self::determineValidationGroups($event->getForm());
  283. $group = '';
  284. if (count($validationGroups) > 1) {
  285. $group = $validationGroups[1];
  286. }
  287. if ($group) {
  288. $fields = array('bienAnneeConstructionChoice', 'bienAnneeConstructionFree');
  289. foreach ($fields as $fieldName) {
  290. $field = $event->getForm()->get($fieldName);
  291. // if field is enabled for the current validation group
  292. if (strpos($field->getConfig()->getOption('attr')['groups'], $group) !== false) {
  293. if ($field->getData() === null) {
  294. $field->addError(new FormError('Veuillez renseigner ce champ.'));
  295. } elseif ($fieldName == 'bienAnneeConstructionChoice') {
  296. $values = Demande::$constructYears;
  297. if (array_key_exists($field->getData(), $values)) {
  298. $demande->setBienAnneeConstruction($values[$field->getData()]);
  299. } else {
  300. $field->addError(new FormError('Valeur invalide'));
  301. }
  302. } else {
  303. $demande->setBienAnneeConstruction($field->getData());
  304. }
  305. }
  306. }
  307. }
  308. }
  309. public function onPostSetData(FormEvent $event)
  310. {
  311. /** @var Demande $demande */
  312. $demande = $event->getData();
  313. $data = $demande->getBienAnneeConstruction();
  314. $key = array_search($data, Demande::$constructYears);
  315. if ($key !== false) {
  316. $event->getForm()->get('bienAnneeConstructionChoice')->setData($key);
  317. }
  318. $event->getForm()->get('bienAnneeConstructionFree')->setData($data);
  319. // if ($key !== false) {
  320. // $field = $event->getForm()->get('bienAnneeConstructionChoice');
  321. // $field->setData($key);
  322. // }
  323. // else {
  324. // $field = $event->getForm()->get('bienAnneeConstructionFree');
  325. // $field->setData($data);
  326. // }
  327. }
  328. public static function determineValidationGroups(FormInterface $form)
  329. {
  330. $extra = $form->getExtraData();
  331. if (!empty($extra['pre_demande'])) {
  332. return false;
  333. }
  334. /** @var Demande $demande */
  335. $demande = $form->getData();
  336. $categorie = $demande->getCategorie();
  337. if ($categorie) {
  338. $cid = $categorie->getId();
  339. $groups = $form->getConfig()->getOption('groups');
  340. $categories = $form->getConfig()->getOption('categories');
  341. // look for child / parent
  342. foreach ($categories as $parent) {
  343. foreach ($parent['children'] as $child) {
  344. if ($child['node']['id'] == $cid) {
  345. return array('Default', $groups[$parent['node']['id']]);
  346. }
  347. }
  348. }
  349. } else {
  350. // no categorie given, look for group field
  351. return array('Default', $form->get('group')->getData());
  352. }
  353. return 'Default';
  354. }
  355. public function configureOptions(OptionsResolver $resolver)
  356. {
  357. $resolver
  358. ->setDefaults(array(
  359. 'data_class' => 'App\Entity\Demande',
  360. 'validation_groups' => array(
  361. 'App\Form\DemandeType',
  362. 'determineValidationGroups'
  363. ),
  364. 'pre_demande' => false,
  365. 'admin' => false,
  366. 'header' => false,
  367. 'attr' => array('novalidate' => 'novalidate')
  368. ))
  369. ->setRequired(array(
  370. 'em',
  371. 'categories',
  372. 'groups'
  373. ));
  374. }
  375. /**
  376. * Returns the name of this type.
  377. *
  378. * @return string The name of this type
  379. */
  380. public function getName()
  381. {
  382. return 'demande';
  383. }
  384. }