src/Form/UserType.php line 31

Open in your IDE?
  1. <?php
  2. namespace App\Form;
  3. use Symfony\Component\Form\AbstractType;
  4. use Symfony\Component\Form\FormBuilderInterface;
  5. use Symfony\Component\Form\Extension\Core\Type\TextType;
  6. use Symfony\Component\Form\Extension\Core\Type\NumberType;
  7. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  8. use Symfony\Component\Form\Extension\Core\Type\DateType;
  9. use Symfony\Component\Form\Extension\Core\Type\FileType;
  10. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  11. use Symfony\Component\Form\Extension\Core\Type\PasswordType;
  12. use Symfony\Component\Form\Extension\Core\Type\TelType;
  13. use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
  14. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  15. use Symfony\Component\Validator\Constraints\File;
  16. use Symfony\Component\OptionsResolver\OptionsResolver;
  17. use App\Entity\User;
  18. use App\Service\Subscription;
  19. use Symfony\Component\Form\Extension\Core\Type\IntegerType;
  20. use Symfony\Component\Form\Extension\Core\Type\ResetType;
  21. use Symfony\Component\Form\FormEvent;
  22. use Symfony\Component\Form\FormEvents;
  23. class UserType extends AbstractType
  24. {
  25.     private $subscriptionService;
  26.     public function __construct(Subscription $subscriptionService)
  27.     {   
  28.         $this->subscriptionService $subscriptionService;
  29.     }
  30.     public function buildForm(FormBuilderInterface $builder, array $options)
  31.     {
  32.         if ($options['data'] == NULL || $options['data']->getIsActive() === null) {
  33.             $checked true;
  34.         } else {
  35.             $checked $options['data']->getIsActive();
  36.         }
  37.         $isLicensed false;
  38.         if ($options['data'] == NULL || $options['data']->getId() !== null) {
  39.             $subs $options['data']->getSubscriptions();
  40.             foreach ($subs as $sub) {
  41.                 if($sub->getOfferSnapshot()->getOffer()->getPeriodicity() === "infinity") {
  42.                     $isLicensed true;
  43.                 }
  44.             }
  45.         }
  46.         if ($options['data'] == NULL || $options['data']->getId() === null) {
  47.             //$sendChecked = true;
  48.             $sendChecked true;
  49.         } else {
  50.             $sendChecked false;
  51.         }
  52.         $signatureRequired false;
  53.         if (!isset($options['data'])) {
  54.             $signatureRequired false;
  55.         }
  56.         $data $options['data'];
  57.         if (!$data->getId()) {
  58.             $signatureRequired false;
  59.         }
  60.         $isSubscribed $this->subscriptionService->is_subscribed(false$data);
  61.         $hasNoSignature $data->getSignature() === null;
  62.         $signatureRequired $isSubscribed && $hasNoSignature;
  63.         
  64.         $builder
  65.         ->add('lastname'TextType::class, [
  66.             'label' => 'Nom',
  67.             'required' => true,
  68.             'attr' => [
  69.                 'placeholder' => "DUPONT",
  70.                 'onkeyup' => "this.value = this.value.toUpperCase();",
  71.                 "pattern" => "^[ a-zA-ZÀ-ÿ\-\u00f1\u00d1]*$",
  72.                 "oninput" => "this.value = this.value.replace(/[^A-Za-zÀ-ÖØ-öø-ÿ- ]/g, '')"
  73.             ]
  74.         ])
  75.         ->add('firstname'TextType::class, [
  76.             'label' => 'Prénom',
  77.             'required' => true,
  78.             'attr' => [
  79.                 'placeholder' => "Charles",
  80.                 'onkeyup' => "this.value = ucfirst(this.value);",
  81.                 "pattern" => "^[ a-zA-ZÀ-ÿ\-\u00f1\u00d1]*$",
  82.                 "oninput" => "this.value = this.value.replace(/[^A-Za-zÀ-ÖØ-öø-ÿ- ]/g, '')"
  83.             ]
  84.         ])
  85.         ->add('telephone'TextType::class, [
  86.             'label' => 'Téléphone',
  87.             'required' => true,
  88.             'attr' => [
  89.                 'placeholder' => "(+33) 0606060606",
  90.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '').slice(0, 10)",
  91.                 "pattern" => "^((\+)33|0)[1-9](\d{2}){4}$",
  92.                 "minlength" => "10",
  93.                 "maxlength" => "10",
  94.             ]
  95.         ])
  96.         ->add('naissance'DateType::class, [
  97.             'label' => 'Date de naissance',
  98.             'html5' => false,
  99.             'widget' => 'single_text',
  100.             "format" => 'dd/MM/yyyy',
  101.             'attr' => [
  102.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')",
  103.                 'class' => 'naissancePicker',
  104.                 'placeholder' => 'dd/mm/yyyy',
  105.                 'data-date-format' => 'dd/mm/yyyy',
  106.                 'x-mask' => "99/99/9999",
  107.                 'x-data' => '{}',
  108.                 'onchange'=>"window.validateDate(this)"
  109.             ],
  110.             'required' => true
  111.         ])
  112.         ->add('adeli'TextType::class, [
  113.             'label' => 'Numéro professionnel de santé selon votre pays d\'exercice (RPPS, INAMI...)',
  114.             'required' => true,
  115.             'attr' => [
  116.                 'placeholder' => "123456789",
  117.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')"
  118.             ],
  119.         ])
  120.         ->add('adeli_certif'FileType::class, [
  121.             'label' => 'Identification',
  122.             'label_attr' => ["class" => "fw-bold form-control-label"],
  123.             'multiple' => false,
  124.             'mapped' => false,
  125.             'required' => $options['adeli_certif'] == null true false,
  126.         ])
  127.         ->add('adresse'TextType::class, [
  128.             'label' => 'Adresse professionnelle',
  129.             'required' => true,
  130.             'attr' => [
  131.                 'placeholder' => "39 allée du Profil Diet",
  132.             ]
  133.         ])
  134.         ->add('complementAdresse'TextType::class, [
  135.             'label' => 'Complément d\'adresse',
  136.             'required' => false,
  137.             'attr' => [
  138.                 'placeholder' => "Résidence de la santé",
  139.             ]
  140.         ])
  141.         ->add('zip'TextType::class, [
  142.             'label' => 'Code postal',
  143.             'required' => true,
  144.             'attr' => [
  145.                 'placeholder' => "99999",
  146.                 'pattern' => "[0-9]{5,5}",
  147.                 'maxlength' => "5",
  148.                 'minlength' => "5",
  149.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')",
  150.             ]
  151.         ])
  152.         ->add('ville'TextType::class, [
  153.             'label' => 'Ville',
  154.             'required' => true,
  155.             'attr' => [
  156.                 'placeholder' => "Ville",
  157.                 "oninput" => "this.value = this.value.replace(/[^A-Za-zÀ-ÿ\s'-]/g, '')"
  158.             ]
  159.         ])
  160.         ->add('country'TextType::class, [
  161.             'label' => 'Pays',
  162.             'required' => true,
  163.             'attr' => [
  164.                 'value' => "France",
  165.                 'placeholder' => "Pays",
  166.                 "oninput" => "this.value = this.value.replace(/[^A-Za-z]/g, '')"
  167.             ]
  168.         ])
  169.         ->add('statuts'ChoiceType::class, [
  170.             'label' => false,
  171.             'required' => false,
  172.             'choices' => [
  173.                 'Entreprise individuelle (EI)' => "ei",
  174.                 'Entreprise unipersonnelle à responsabilité limitée (EURL)' => "eurl",
  175.                 'Société à responsabilité limitée (SARL)' => "sarl",
  176.                 'Société anonyme (SA)' => "sa",
  177.                 'Société par actions simplifiée (SAS)' => "sas",
  178.                 'Société par actions simplifiée unipersonnelle (SASU)' => "sasu",
  179.                 'Employé(e)' => "Employé(e)",
  180.                 'Autre' => "autre"
  181.             ],
  182.             'attr' => [
  183.                 'class' => 'select2',
  184.                 'required' => false,
  185.             ]
  186.         ])
  187.         ->add('siret'TextType::class, [
  188.             'label' => 'SIRET',
  189.             'required' => false,
  190.             'attr' => [
  191.                 'placeholder' => "90480694087920",
  192.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')",
  193.                 "pattern" => "[0-9]+",
  194.                 "maxlength" => "14",
  195.                 "minlength" => "14",
  196.                 "class" => "siret"
  197.             ]
  198.         ])
  199.         ->add('asso'ChoiceType::class, [
  200.             'label' => "Membre d'associations, réseaux",
  201.             'required' => false,
  202.             "multiple" => true,
  203.             'choices' => [
  204.                 '' => "",
  205.                 'ADL' => "ADL",
  206.                 'AFA' => "AFA",
  207.                 'AFDN' => "AFDN",
  208.                 'GROS' => "GROS",
  209.                 'ONCODIET' => "ONCODIET",
  210.                 'REPPOP' => "REPPOP",
  211.                 'Autre' => "Autre"
  212.             ],
  213.             'attr' => [
  214.                 'class' => 'select2'
  215.             ]
  216.         ])
  217.         ->add('asso_autre'TextType::class, [
  218.             'required' => false,
  219.             'label' => 'Autre',
  220.             'attr' => [
  221.                 'placeholder' => "Autre",
  222.             ]
  223.         ])
  224.         ->add('diplome'ChoiceType::class, [
  225.             'label' => "Diplôme",
  226.             'required' => true,
  227.             'choices' => [
  228.                 '' => '',
  229.                 'BTS Diététique' => 'BTS Diététique',
  230.                 'BUT Diététique et Nutrition' => 'BUT diététique et nutrition',
  231.                 'Autre' => 'Autre'
  232.             ],
  233.             'attr' => [
  234.                 'class' => 'select2'
  235.             ]
  236.         ])
  237.         ->add('diplome_copy'FileType::class, [
  238.             'label' => 'Copie Diplôme',
  239.             'multiple' => false,
  240.             'mapped' => false,
  241.             'label_attr' => ["class" => "fw-bold form-control-label"],
  242.             'required' =>  $options['diplome_copy'] == null true false
  243.         ])
  244.         ->add('specialite'ChoiceType::class, [
  245.             'label' => 'Spécialités',
  246.             'required' => false,
  247.             'multiple' => true,
  248.             'attr' => [
  249.                 'class' => 'select2'
  250.             ],
  251.             'choices' => [
  252.                 '' => '',
  253.                 'Addictions' => 'Addictions',
  254.                 'Alimentation en pleine conscience' => 'Alimentation en pleine conscience',
  255.                 'Alimentation intuitive' => 'Alimentation intuitive',
  256.                 'Allergies, intolérances' => 'Allergies, intolérances',
  257.                 'Cancérologie' => 'Cancérologie',
  258.                 'Cardiologie' => 'Cardiologie',
  259.                 'Chirurgie bariatrique' => 'Chirurgie bariatrique',
  260.                 'Dénutrition, malnutrition' => 'Dénutrition, malnutrition',
  261.                 'Diabétologie' => 'Diabétologie',
  262.                 'Diététique sportive' => 'Diététique sportive',
  263.                 'Endométriose' => 'Endométriose',
  264.                 'ETP' => 'ETP',
  265.                 'FODMAP' => 'FODMAP',
  266.                 'Gériatrie' => 'Gériatrie',
  267.                 'Grossesse' => 'Grossesse',
  268.                 'Maladie coeliaque' => 'Maladie coeliaque',
  269.                 'Microbiote' => 'Microbiote',
  270.                 'Micronutrition' => 'Micronutrition',
  271.                 'Néphrologie' => 'Néphrologie',
  272.                 'Pédiatrie' => 'Pédiatrie',
  273.                 'Psychonutrition' => 'Psychonutrition',
  274.                 'Sevrage tabagique' => 'Sevrage tabagique',
  275.                 'Suivi post opératoire' => 'Suivi post opératoire',
  276.                 'Surpoids/Obésité' => 'Surpoids/Obésité',
  277.                 'TCA' => 'TCA',
  278.                 'Troubles hormonaux' => 'Troubles hormonaux',
  279.                 'Troubles digestifs' => 'Troubles digestifs',
  280.                 'Végétarisme, végétalisme, végan' => 'Végétarisme, végétalisme, végan',
  281.                 'Autre' => 'Autre',
  282.             ],
  283.         ])
  284.         ->add('specialite_autre'TextType::class, [
  285.             'required' => false,
  286.             'label' => 'Autre',
  287.             'attr' => [
  288.                 'placeholder' => "Autre",
  289.             ]
  290.         ])
  291.         ->add('anneeDiplome'TextType::class, [
  292.             'label' => "Année",
  293.             'required' => true,
  294.             'attr' => [
  295.                 'placeholder' => "2016",
  296.                 'pattern' => "[0-9]+",
  297.                 "minlength" => "4",
  298.                 "maxlength" => "4",
  299.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')"
  300.             ]
  301.         ])
  302.         ->add('email'EmailType::class, [
  303.             'required' => true,
  304.             'label' => 'Adresse e-mail',
  305.             'attr' => [
  306.                 'placeholder' => "exemple@societe.com",
  307.                 'pattern' => '[^@]+@[^@]+\.[a-zA-Z]{2,6}'
  308.             ]
  309.         ])
  310.         ->add('password'PasswordType::class, [
  311.             'required' => $options['password'],
  312.             'empty_data' => "",
  313.             'mapped' => false,
  314.             'label' => 'Mot de passe',
  315.             'attr' => [
  316.                 'autocomplete' => $options['password'] ? '' 'off',
  317.             ]
  318.         ])
  319.         ->add('signature'FileType::class, [
  320.             'label' => 'Signature',
  321.             'multiple' => false,
  322.             'mapped' => false,
  323.             'required' => $signatureRequired
  324.         ])
  325.         ->add('isOptin'CheckboxType::class, [
  326.             'required' => false,
  327.             'label' => 'Recevoir les e-mails automatiques de la plateforme',
  328.             'label_attr' => ['class' => 'custom-control-label'],
  329.             'data' => $checked,
  330.             'attr' => ['class' => 'custom-control-input']])
  331.         ->add('reset'ResetType::class)
  332.         ->add('logo'FileType::class, [
  333.             'label' => 'Logo du cabinet',
  334.             'label_attr' => ["class" => "fw-bold form-control-label"],
  335.             'multiple' => false,
  336.             'mapped' => false,
  337.             'attr' => [
  338.                 'accept' => 'image/*',
  339.                 'required' =>  false
  340.             ],
  341.             'required' =>  false
  342.         ])
  343.         ->add('office'TextType::class, [
  344.             'label' => 'Nom du cabinet',
  345.             'required' =>  false,
  346.             'attr' => [
  347.             ]
  348.         ])
  349.         ->add('website'TextType::class, [
  350.             'label' => 'Site internet',
  351.             'required' =>  false,
  352.             'attr' => [
  353.             ]
  354.         ])
  355.         ->add('priceNumber'TextType::class, [
  356.             'label' => 'Honoraires 1 (€)',
  357.             'required' => false,
  358.             'attr' => [
  359.                 'placeholder' => "70",
  360.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')",
  361.             ]
  362.         ])
  363.         ->add('priceLetter'TextType::class, [
  364.             'label' => 'Honoraires 1 (lettres)',
  365.             'required' => false,
  366.             'attr' => [
  367.                 'placeholder' => "soixante-dix",
  368.                 "oninput" => "this.value = this.value.replace(/[^A-Za-zÀ-ÿ\s'-]/g, '')"
  369.             ]
  370.         ])
  371.         ->add('priceNumber2'TextType::class, [
  372.             'label' => 'Honoraires 2 (€)',
  373.             'required' => false,
  374.             'attr' => [
  375.                 'placeholder' => "50",
  376.                 "oninput" => "this.value = this.value.replace(/[A-Za-z]/g, '')",
  377.             ]
  378.         ])
  379.         ->add('priceLetter2'TextType::class, [
  380.             'label' => 'Honoraires 2 (lettres)',
  381.             'required' => false,
  382.             'attr' => [
  383.                 'placeholder' => "cinquante",
  384.                 "oninput" => "this.value = this.value.replace(/[^A-Za-zÀ-ÿ\s'-]/g, '')"
  385.             ]
  386.         ]);
  387.         if($options['is_register'] === false) {
  388.             $builder->add('isActive'CheckboxType::class, [
  389.                 'required' => false,
  390.                 'label' => 'Activer le compte de cet utilisateur ',
  391.                 'label_attr' => ['class' => 'custom-control-label'],
  392.                 'data' => $checked,
  393.                 'attr' =>[
  394.                     'class' => 'custom-control-input'
  395.             ]])
  396.             ->add('sendEmail'CheckboxType::class, [
  397.                 "mapped" => false,
  398.                 'required' => false,
  399.                 'data' =>$sendChecked,
  400.                 'label' => "Envoyer le lien de réinitialisation du mot de passe à cet utilisateur par e-mail",
  401.                 'label_attr' => ['class' => 'custom-control-label'],
  402.                 'attr' =>[
  403.                     'class' => 'custom-control-input'
  404.             ]])
  405.             ->add('isLicensed'CheckboxType::class, [
  406.                 "mapped" => false,
  407.                 'required' => false,
  408.                 'data' =>$isLicensed,
  409.                 'label' => "Utilisateur licencié",
  410.                 'label_attr' => ['class' => 'custom-control-label'],
  411.                 'attr' =>[
  412.                     'class' => 'custom-control-input'
  413.             ]]);
  414.         }
  415.         if($options['admin'] === true) {
  416.             $builder->add('roles'ChoiceType::class, [
  417.                 'label' => false,
  418.                 'attr' => [
  419.                     'class' => 'select2'
  420.                 ],
  421.                 'choices'  => [
  422.                     'Admin' => 'ROLE_ADMIN',
  423.                     // === MODIFICATION 2025-01-13 : Migration ROLE_CUSTOMER vers rôles spécialisés ===
  424.                     'Praticien' => 'ROLE_PRATICIEN',  // Changé de ROLE_CUSTOMER
  425.                     'Coach' => 'ROLE_COACH',           // Ajout du rôle Coach
  426.                     // === FIN MODIFICATION ===
  427.                     'Patient' => 'ROLE_PATIENT',
  428.                 ],
  429.                 'multiple' => true,
  430.                 'expanded' => false,
  431.                 'required' => true
  432.             ]);
  433.             
  434.             $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
  435.                 $user $event->getData();
  436.                 $form $event->getForm();
  437.                 // If no roles are set, default to ROLE_COACH
  438.                 if (empty($user) || !$user->getRoles()) {
  439.                     $user->setRoles(['ROLE_COACH']);
  440.                 }
  441.                 $event->setData($user);
  442.             });
  443.         }
  444.         ;
  445.     }
  446.     public function configureOptions(OptionsResolver $resolver)
  447.     {
  448.         $resolver->setDefaults([
  449.             'data_class' => User::class,
  450.             'admin' => false,
  451.             'password' => false,
  452.             'adeli_certif' => null,
  453.             'signature' => null,
  454.             'diplome_copy' => null,
  455.             'logo' => null,
  456.             'is_register' => false,
  457.         ]);
  458.     }
  459. }