<?php
declare(strict_types=1);
/**
* @author Mehrez Labidi
*/
namespace App\Form;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use App\Validator\Constraints\Nom;
use App\Validator\Constraints\Prenom;
use stdClass;
use App\Entity\Utilisateur;
use App\Form\DataTransformer\MessageTransformer;
use App\Form\Type\FormChoices;
use App\Helper\TransProvider;
use App\Helper\Utils;
use App\Services\TelephoneInternational;
use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\ChoiceList;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Rollerworks\Component\PasswordStrength\Validator\Constraints as RollerworksPassword;
use App\Validator\Constraints\UniqueEmail;
use App\Validator\Constraints\PhoneNumber;
use App\Validator\Constraints\ContainsOnlyAlphabetic;
use \App\Services\ManagerEntity\LocalisationsManagers;
use App\Repository\ParametresDiversRepository;
use App\Form\Type\Inscription\InscriptionRegionListener;
use Symfony\Component\Validator\Constraints as Assert;
class RegistrationFormType extends AbstractType {
/**
* @var MessageTransformer
*/
private $messageTransformer;
/**
* @var TelephoneInternational
*/
private $telephoneInternational;
/**
* @var TransProvider
*/
private $transProvider;
/**
* @var \App\Services\ManagerEntity\LocalisationsManagers
*/
private $localisationsManagers;
/**
* @var ContainerBagInterface
*/
private $params;
/**
*
* @var type
*/
private $parametresDiversRepository;
/**
* @param TransProvider $transProvider
* @param ContainerBagInterface $params
* @param MessageTransformer $messageTransformer
* @param TelephoneInternational $telephoneInternational
* @param LocalisationsManagers $localisationsManagers
*/
public function __construct(ParametresDiversRepository $parametresDiversRepository, TransProvider $transProvider, ContainerBagInterface $params, MessageTransformer $messageTransformer, TelephoneInternational $telephoneInternational, LocalisationsManagers $localisationsManagers) {
$this->params = $params;
$this->transProvider = $transProvider;
$this->messageTransformer = $messageTransformer;
$this->telephoneInternational = $telephoneInternational;
$this->localisationsManagers = $localisationsManagers;
$this->parametresDiversRepository = $parametresDiversRepository;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
* @return void
*/
public function buildForm(FormBuilderInterface $builder, array $options): void {
$builder
->add('civilite', ChoiceType::class, [
'choices' => ['M' => 'masculin', 'Mme' => 'feminin'],
'expanded' => true,
'multiple' => false,
"constraints" => [
new NotBlank([
"message" => 'le champ civilite est obligatoire',
]),
],
])
->add('type_utilisateur', ChoiceType::class,
[
"attr" => [],
'choices' => $this->transChoice(Utils::reverseArrayKeyValueValueKey(Utilisateur::TYPE_UTILISATEUR)),
'expanded' => true,
'multiple' => false,
"constraints" => [
new NotBlank([
"message" => 'le champ type utilisateur est obligatoire',
]),
],
]
)
// id_type_structure pour les choix expert /investisseur
->add('id_type_structure_investisseur', ChoiceType::class,
[
"attr" => [
"v-if" => "id_type_structure_investisseur"
],
"choices" => $this->transChoice(FormChoices::typeInvestisseur()),
"required" => true, 'mapped' => false,
]
)
// id_type_structure pour les choix expert /investisseur
->add('id_type_structure_expert', ChoiceType::class,
[
"attr" => [
"v-if" => "id_type_structure_expert"
],
"choices" => $this->transChoice(FormChoices::typeExpert()),
"required" => true, 'mapped' => false,
]
)
->add('nom_utilisateur', TextType::class,
[
"constraints" => [
new NotBlank([
"message" => $this->transChoice('le champ nom est obligatoire'),
]),
new Nom()
],
]
)
->add('prenom_utilisateur', TextType::class,
[
"constraints" => [
new NotBlank([
"message" => $this->transChoice('le champ prenom est obligatoire'),
]),
new Prenom()
],
]
)
->add('id_pays_utilisateur', ChoiceType::class,
[
"choices" => $this->listPays(),
'choice_attr' => function ($key, $val, $index) {
return ($key == "") ? ['disabled' => 'disabled'] : [];
},
'data' => array_values($this->listPays())[0],
"constraints" => [
new NotBlank([
"message" => $this->transChoice('le champ pays est obligatoire'),
]),
],
"attr" => [
"v-model" => "pays_utilisateur"
],
]
)
->add('id_region', ChoiceType::class,
["choices" => [],
"attr" => [
"v-html" => "regionHtml",
"v-if" => "seen_list_regions",
"class" => "form-control"
],
"constraints" => [
new NotBlank([
"message" => $this->transChoice('le champ region est obligatoire'),
]),
],
]
)->addEventSubscriber(new InscriptionRegionListener($this->localisationsManagers))
->add('ville_utilisateur', TextType::class,
[
"constraints" => [],
]
)
->add('code_postal_utilisateur', TextType::class,
[
"constraints" => [],
]
)
->add('adresse_utilisateur', TextType::class,
[
"constraints" => [],
]
)
->add('factur_nom_societe', TextType::class,
[
"constraints" => [],
]
)
->add('telephone_utilisateur', TextType::class,
[
"constraints" => [
new NotBlank([
"message" => $this->transChoice('le champ telephone est obligatoire'),
]),
new PhoneNumber()
],
]
)
->add('indicatif_tel', ChoiceType::class, [
"attr" => [
"v-model" => "indicatif_tel"
],
'choices' => $this->telephoneInternational->listIndicatifChoiceForm(),
'choice_attr' => function ($key, $val, $index) {
return ($key == "") ? ['disabled' => 'disabled'] : [];
},
'data' => array_values($this->telephoneInternational->listIndicatifChoiceForm())[0]
]
)
->add('provenance_notoriete_fusacq', ChoiceType::class,
[
'choices' => $this->transChoice(FormChoices::provenanceNotorieteFusacq())
]
)
->add('newsletters_internationals', ChoiceType::class, [
'choices' => $this->transChoice($this->listChoixPaysNewsletter()->listChoix),
'data' => $this->listChoixPaysNewsletter()->defaultChoix,
'expanded' => true, 'mapped' => false,
'multiple' => true, 'label_html' => true,
])
->add('email_utilisateur', TextType::class,
[
"constraints" => [
new Assert\Email(["message" => "l'adresse email saisie est invalide"]),
new NotBlank([
"message" => $this->transChoice('le champ email est obligatoire'),
]), // UniqueEmail unique mail mais pour les utilisateurs en mode non inscrit sont acceptées!
new UniqueEmail()
],
]
)
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'first_options' => [
'attr' => ['autocomplete' => 'new-password'],
'constraints' => [
new NotBlank([
"message" => 'le champ mot de passe est obligatoire',
]),
// https://github.com/rollerworks/PasswordStrengthValidator
new RollerworksPassword\PasswordStrength([
'minLength' => 8,
'minStrength' => 3
]),
],
'label' => 'le nouveau mot de passe',
],
'second_options' => [
'attr' => ['autocomplete' => 'new-password'],
'label' => 'le champ confirmation mot de passe est obligatoire',
],
'invalid_message' => 'les deux mots de passe ne sont pas identiques',
// Instead of being set onto the object directly,
// this is read and encoded in the controller
'mapped' => false,
])
->add('langue_utilisee', ChoiceType::class,
[
"required" => true,
"attr" => ["autocomplete" => "off", "class" => "form-control"],
"choices" => Utils::reverseArrayKeyValueValueKey($this->parametresDiversRepository->getLangueForSelect())
]
)
->add('non_assujetti_tva', CheckboxType::class, ['required' => false, 'label' => false])
->add('tva_intracommunautaire', TextType::class, ["constraints" => [],])
->add('agreeTerms', CheckboxType::class, [
'mapped' => false,
'label_html' => true,
'label' => html_entity_decode(
"<small>" .
$this->transChoice("je reconnais avoir pris connaissance des <a href='/conditions-generales-utilisation' target='_blank' style='text-decoration: underline;' >Conditions Générales d'utilisation</a> de FUSACQ et les accepte") .
"</small>"),
"constraints" => [
new IsTrue([
"message" => $this->transChoice("Vous devez accepter les conditions générales d'utilisation pour votre s'inscrire"),
]),
],
])
->add('btn', SubmitType::class, [
'label' => $this->transChoice('creer mon compte'),
'attr' => ['class' => 'btn btn-bleu active'],
])
->add('recaptcha', EWZRecaptchaType::class,
['mapped' => false, 'language' => $this->transProvider->getLocale()]
)
;
}
/**
* @param $var
* @return mixed|string
*/
private function transChoice($var) {
if (is_string($var)) {
$var = $this->transProvider
->translate($var, "", "M");
}
if (is_array($var)) {
foreach ($var as $key => $item) {
unset($var[$key]);
$key = $this->transProvider
->translate($key, "", "M");
$var[$key] = $item;
}
}
return $var;
}
/**
* @return array
*/
private function listChoixPaysNewsletter() {
$paramsNewslettersPays = $this->params->get('app.newsletters_pays');
$return = new stdClass();
$return->defaultChoix = NULL;
$result = [];
// on prend codePays de session pour afficher le pays du site en premier
foreach ($paramsNewslettersPays as $item) {
if ($_SESSION['codePays'] == strtolower($item[1])) {
$return->defaultChoix = [0 => strtolower($item[1])];
$tmpVar = html_entity_decode(" <img src='http://www.help-fusacq.com/fr/images/$item[3].png' alt='$item[0]'> ") . $item[0];
}
$result[html_entity_decode(" <img src='http://www.help-fusacq.com/fr/images/$item[3].png' alt='$item[0]'> ") . $item[0]] = strtolower($item[1]);
}
if (isset($tmpVar)) {
$result = [$tmpVar => $_SESSION['codePays']] + $result;
}
$return->listChoix = $result;
return $return;
}
/**
* Récupère la liste des pays en excluant les DOM-TOM
*
* Cette méthode retourne un tableau associatif des pays disponibles
* en filtrant les départements et territoires d'outre-mer (DOM-TOM).
* Le tableau retourné utilise le nom de la localisation comme clé
* et l'identifiant de localisation comme valeur.
*
* @return array<string, string> Tableau associatif [nom_localisation => id_localisation]
*/
private function listPays(): array { // sans les DOM_TOM
$nomDomTom = array_column($this->localisationsManagers->getListDOMTOM(), "nom_localisation");
$list = [];
foreach ($this->localisationsManagers->getListPays(true) as $pays) {
if (in_array($pays["nom_localisation"], $nomDomTom)) {
continue;
}
$list[$pays["nom_localisation"]] = $pays["id_localisation"];
}
return $list;
}
/**
* @param OptionsResolver $resolver
* @return void
*/
public function configureOptions(OptionsResolver $resolver): void {
$resolver->setDefaults([
'data_class' => Utilisateur::class,
'csrf_protection' => false,
'allow_extra_fields' => true,
]);
}
}