From 32ad1bcad952cfabbbc1b96b90af808279b1a1ee Mon Sep 17 00:00:00 2001 From: Stakovicz Date: Sun, 17 Nov 2024 20:44:08 +0100 Subject: [PATCH] afup#1125 better uniq login/email --- .../member_contact_details.html.twig | 87 ++++------------ .../views/admin/members/user_add.html.twig | 9 +- .../views/admin/members/user_edit.html.twig | 9 +- app/config/services.yml | 3 - db/migrations/A20241117165505_login_uniq.php | 11 +++ htdocs/templates/site/scss/base/reset.scss | 3 +- htdocs/templates/site/scss/generic/form.scss | 1 - .../Association/Form/ContactDetailsType.php | 14 ++- .../Association/Form/UserEditFormData.php | 7 +- .../Form/UserEditFormDataFactory.php | 85 ---------------- .../Association/Form/UserEditType.php | 99 ++++++++++++++----- .../Admin/Members/UserAddAction.php | 57 ++++++----- .../Admin/Members/UserEditAction.php | 35 +++---- .../Controller/MemberShipController.php | 34 ++----- .../Constraints/UniqueEntityValidator.php | 2 +- .../Admin/AdminPersonnesPhysiques.feature | 2 +- .../features/PublicSite/Register.feature | 20 ++++ 17 files changed, 210 insertions(+), 268 deletions(-) create mode 100644 db/migrations/A20241117165505_login_uniq.php delete mode 100644 sources/AppBundle/Association/Form/UserEditFormDataFactory.php diff --git a/app/Resources/views/admin/association/membership/member_contact_details.html.twig b/app/Resources/views/admin/association/membership/member_contact_details.html.twig index 862bb081b..541c9c5bc 100644 --- a/app/Resources/views/admin/association/membership/member_contact_details.html.twig +++ b/app/Resources/views/admin/association/membership/member_contact_details.html.twig @@ -12,84 +12,37 @@
{{ form_start(form) }} - +

+ * Indique un champ obligatoire +

Informations
-
- {{ form_errors(form.email) }} - {{ form_label(form.email, 'Email', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.email, {'attr': {'size': '30', 'maxlength': '100'}}) }} -
-
- {{ form_errors(form.address) }} - {{ form_label(form.address, 'Address', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.address, {'attr': {'rows': '4', 'cols': '42'}}) }} -
-
- {{ form_errors(form.zipcode) }} - {{ form_label(form.zipcode, 'Zip code', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.zipcode, {'attr': {'size': '6', 'maxlength': '10'}}) }} -
-
- {{ form_errors(form.city) }} - {{ form_label(form.city, 'City', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.city, {'attr': {'size': '30', 'maxlength': '50'}}) }} -
-
- {{ form_errors(form.country) }} - {{ form_label(form.country, 'country', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.country) }} -
-
- {{ form_errors(form.phone) }} - {{ form_label(form.phone, 'Landline phone', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.phone, {'attr': {'size': '20', 'maxlength': '20'}}) }} -
-
- {{ form_errors(form.mobilephone) }} - {{ form_label(form.mobilephone, 'Mobile phone', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.mobilephone, {'attr': {'size': '20', 'maxlength': '20'}}) }} -
-
- {{ form_errors(form.nearest_office) }} - {{ form_label(form.nearest_office, 'Nearest office', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.nearest_office) }} -
+ {{ form_errors(form) }} + {{ form_row(form.email) }} + {{ form_row(form.address) }} + {{ form_row(form.zipcode) }} + {{ form_row(form.city) }} + {{ form_row(form.country) }} + {{ form_row(form.phone) }} + {{ form_row(form.mobilephone) }} + {{ form_row(form.nearest_office) }}
- Paramètres - + Identifiants de connexion
-
- {{ form_errors(form.username) }} - {{ form_label(form.username, 'Login', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.username, {'attr': {'size': '30', 'maxlength': '30'}}) }} -
-
-

- Ne renseignez le mot de passe et sa confirmation que si vous souhaitez le changer -

-
-
- {{ form_errors(form.password.first) }} - {{ form_label(form.password.first, 'Password', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.password.first, {'attr': {'size': '30'}}) }} -
-
- {{ form_errors(form.password.second) }} - {{ form_label(form.password.second, 'Repeat Password', {'label_attr': {'class': 'libelle'}}) }} - {{ form_widget(form.password.second, {'attr': {'size': '30'}}) }} -
+ {{ form_row(form.username) }} + +

+ Ne renseignez le mot de passe et sa confirmation que si vous souhaitez le changer +

+ {{ form_row(form.plainPassword.first) }} + {{ form_row(form.plainPassword.second) }}
-

- *  Indique un champ obligatoire -

-
{{ form_widget(form.save, {"attr": {"class": "button button--call-to-action"}}) }}
diff --git a/app/Resources/views/admin/members/user_add.html.twig b/app/Resources/views/admin/members/user_add.html.twig index 504cc2d15..3fcac53b7 100644 --- a/app/Resources/views/admin/members/user_add.html.twig +++ b/app/Resources/views/admin/members/user_add.html.twig @@ -10,6 +10,7 @@
+ {{ form_errors(form) }} {{ form_row(form.companyId) }} {{ form_row(form.civility) }} {{ form_row(form.lastname, {attr: {'data-role': 'field-lastname'}}) }} @@ -19,9 +20,9 @@ {{ form_row(form.address) }} {{ form_row(form.zipcode) }} {{ form_row(form.city) }} - {{ form_row(form.countryId) }} + {{ form_row(form.country) }} {{ form_row(form.phone) }} - {{ form_row(form.cellphone) }} + {{ form_row(form.mobilephone) }}

Paramètres

@@ -34,14 +35,14 @@ {{ form_row(form.websiteLevel) }} {{ form_row(form.officeLevel) }} {{ form_row(form.status) }} - {{ form_row(form.login, {attr: {'data-role': 'field-login'}}) }} + {{ form_row(form.username, {attr: {'data-role': 'field-login'}}) }}
Ne renseignez le mot de passe et sa confirmation que si vous souhaitez le définir
- {{ form_row(form.password) }} + {{ form_row(form.plainPassword) }} {{ form_row(form.roles) }} {{ form_row(form.needsUpToDateMembership) }} diff --git a/app/Resources/views/admin/members/user_edit.html.twig b/app/Resources/views/admin/members/user_edit.html.twig index b57b2eb2c..beaeaff32 100644 --- a/app/Resources/views/admin/members/user_edit.html.twig +++ b/app/Resources/views/admin/members/user_edit.html.twig @@ -41,6 +41,7 @@
+ {{ form_errors(form) }} {{ form_row(form.companyId) }} {{ form_row(form.civility) }} {{ form_row(form.lastname, {attr: {'data-role': 'field-lastname'}}) }} @@ -50,9 +51,9 @@ {{ form_row(form.address) }} {{ form_row(form.zipcode) }} {{ form_row(form.city) }} - {{ form_row(form.countryId) }} + {{ form_row(form.country) }} {{ form_row(form.phone) }} - {{ form_row(form.cellphone) }} + {{ form_row(form.mobilephone) }}

Paramètres

@@ -65,14 +66,14 @@ {{ form_row(form.websiteLevel) }} {{ form_row(form.officeLevel) }} {{ form_row(form.status) }} - {{ form_row(form.login, {attr: {'data-role': 'field-login'}}) }} + {{ form_row(form.username, {attr: {'data-role': 'field-login'}}) }}
Ne renseignez le mot de passe et sa confirmation que si vous souhaitez le changer
- {{ form_row(form.password) }} + {{ form_row(form.plainPassword) }} {{ form_row(form.roles) }} {{ form_row(form.needsUpToDateMembership) }} diff --git a/app/config/services.yml b/app/config/services.yml index 0466fbab5..0fb952c1d 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -357,9 +357,6 @@ services: AppBundle\Association\UserMembership\UserService: autowire: true - AppBundle\Association\Form\UserEditFormDataFactory: - autowire: true - AppBundle\Association\Factory\UserFactory: autowire: true diff --git a/db/migrations/A20241117165505_login_uniq.php b/db/migrations/A20241117165505_login_uniq.php new file mode 100644 index 000000000..01b8db435 --- /dev/null +++ b/db/migrations/A20241117165505_login_uniq.php @@ -0,0 +1,11 @@ +execute("CREATE UNIQUE INDEX idx_login_unique ON afup_personnes_physiques (login)"); + } +} \ No newline at end of file diff --git a/htdocs/templates/site/scss/base/reset.scss b/htdocs/templates/site/scss/base/reset.scss index 58e41b18a..df7c7f252 100644 --- a/htdocs/templates/site/scss/base/reset.scss +++ b/htdocs/templates/site/scss/base/reset.scss @@ -34,8 +34,7 @@ blockquote, pre, td, th, -label, -textarea { +label { font-size: 1em; line-height: 1.54; margin: 10px 0; diff --git a/htdocs/templates/site/scss/generic/form.scss b/htdocs/templates/site/scss/generic/form.scss index bb1e23d86..3cee8b31a 100644 --- a/htdocs/templates/site/scss/generic/form.scss +++ b/htdocs/templates/site/scss/generic/form.scss @@ -9,7 +9,6 @@ input, button, select, label { textarea { overflow: auto; min-height: 5em; - font-size: 1.75em; vertical-align: top; resize: vertical } diff --git a/sources/AppBundle/Association/Form/ContactDetailsType.php b/sources/AppBundle/Association/Form/ContactDetailsType.php index 119d74ff1..5f570b08a 100644 --- a/sources/AppBundle/Association/Form/ContactDetailsType.php +++ b/sources/AppBundle/Association/Form/ContactDetailsType.php @@ -4,6 +4,7 @@ namespace AppBundle\Association\Form; use Afup\Site\Utils\Pays; +use AppBundle\Association\Model\User; use AppBundle\Offices\OfficesCollection; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -42,6 +43,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) ] ]) ->add('zipcode', TextType::class, [ + 'label' => 'Zip code', 'constraints' => [ new NotBlank(), ] @@ -52,7 +54,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) ] ]) ->add('country', ChoiceType::class, [ + 'label' => 'Pays', 'choices' => $this->getCountyChoices(), + 'preferred_choices' => ['FR'] ]) ->add('phone', TextType::class, [ 'required' => false, @@ -61,6 +65,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) ], ]) ->add('mobilephone', TextType::class, [ + 'label' => 'Portable', 'required' => false, 'constraints' => [ new Length(['max' => 20]), @@ -78,10 +83,13 @@ public function buildForm(FormBuilderInterface $builder, array $options) new Length(['max' => 30]), ] ]) - ->add('password', RepeatedType::class, [ + ->add('plainPassword', RepeatedType::class, [ + 'mapped' => false, 'type' => PasswordType::class, 'required' => false, 'invalid_message' => 'The password fields must match', + 'first_options' => ['label' => 'Password'], + 'second_options' => ['label' => 'Repeat Password'], ]) ->add('save', SubmitType::class, ['label' => 'Update']) ; @@ -89,7 +97,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefaults([]); + $resolver->setDefaults([ + 'data_class' => User::class, + ]); } private function getOfficesList() diff --git a/sources/AppBundle/Association/Form/UserEditFormData.php b/sources/AppBundle/Association/Form/UserEditFormData.php index 26d14d53a..707f2a0ac 100644 --- a/sources/AppBundle/Association/Form/UserEditFormData.php +++ b/sources/AppBundle/Association/Form/UserEditFormData.php @@ -3,9 +3,14 @@ namespace AppBundle\Association\Form; use AppBundle\Association\Model\User; +use AppBundle\Validator\Constraints as AppAssert; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Context\ExecutionContextInterface; +/** + * @AppAssert\UniqueEntity(fields={"username"}, repository="\AppBundle\Association\Model\Repository\UserRepository") + * @AppAssert\UniqueEntity(fields={"email"}, repository="\AppBundle\Association\Model\Repository\UserRepository") + */ class UserEditFormData { public $companyId; @@ -85,7 +90,7 @@ class UserEditFormData * @Assert\NotBlank() * @Assert\Length(max=30) */ - public $login; + public $username; /** * @Assert\Length(max=30) */ diff --git a/sources/AppBundle/Association/Form/UserEditFormDataFactory.php b/sources/AppBundle/Association/Form/UserEditFormDataFactory.php deleted file mode 100644 index 1a0b1ffa7..000000000 --- a/sources/AppBundle/Association/Form/UserEditFormDataFactory.php +++ /dev/null @@ -1,85 +0,0 @@ -civility = $user->getCivility(); - $data->firstname = $user->getFirstName(); - $data->lastname = $user->getLastName(); - $data->companyId = $user->getCompanyId(); - $data->email = $user->getEmail(); - $data->alternateEmail = $user->getAlternateEmail(); - $data->address = $user->getAddress(); - $data->zipcode = $user->getZipCode(); - $data->city = $user->getCity(); - $data->countryId = $user->getCountry(); - $data->phone = $user->getPhone(); - $data->cellphone = $user->getMobilephone(); - $data->level = $user->getLevel(); - $data->directoryLevel = $user->getDirectoryLevel(); - $data->eventLevel = $user->getEventLevel(); - $data->websiteLevel = $user->getWebsiteLevel(); - $data->officeLevel = $user->getOfficeLevel(); - $data->status = $user->getStatus(); - $data->login = $user->getUsername(); - $data->roles = json_encode($user->getRoles()); - $data->needsUpToDateMembership = $user->getNeedsUpToDateMembership(); - - return $data; - } - - public function toUser(UserEditFormData $data, User $user) - { - $user->setUsername($data->login); - $user->setCompanyId((int) $data->companyId); - $user->setCivility($data->civility); - $user->setLastName($data->lastname); - $user->setFirstName($data->firstname); - $user->setEmail($data->email); - $user->setAddress($data->address); - $user->setZipCode($data->zipcode); - $user->setCity($data->city); - $user->setCountry($data->countryId); - $user->setPhone($data->phone); - $user->setMobilephone($data->cellphone); - $user->setStatus($data->status); - $user->setRoles(json_decode($data->roles, true)); - $user->setAlternateEmail($data->alternateEmail); - $user->setNeedsUpToDateMembership($data->needsUpToDateMembership); - $user->setLevel($data->level); - $user->setDirectoryLevel($data->directoryLevel); - $user->setWebsiteLevel($data->websiteLevel); - $user->setEventLevel($data->eventLevel); - $user->setOfficeLevel($data->officeLevel); - if (null !== $data->password) { - $user->setPlainPassword($data->password); - } - } - - public function fromSession(array $sessionData) - { - $data = new UserEditFormData(); - $data->civility = $sessionData['civilite']; - $data->lastname = $sessionData['nom']; - $data->firstname = $sessionData['prenom']; - $data->email = $sessionData['email']; - $data->address = $sessionData['adresse']; - $data->zipcode = $sessionData['code_postal']; - $data->city = $sessionData['ville']; - $data->countryId = $sessionData['id_pays']; - $data->phone = $sessionData['telephone_fixe']; - $data->cellphone = $sessionData['telephone_portable']; - $data->status = $sessionData['etat']; - - return $data; - } -} diff --git a/sources/AppBundle/Association/Form/UserEditType.php b/sources/AppBundle/Association/Form/UserEditType.php index 2a489ab10..9e75ace83 100644 --- a/sources/AppBundle/Association/Form/UserEditType.php +++ b/sources/AppBundle/Association/Form/UserEditType.php @@ -6,6 +6,7 @@ use Afup\Site\Utils\Pays; use AppBundle\Association\Model\User; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EmailType; @@ -15,6 +16,10 @@ 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\Email; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; class UserEditType extends AbstractType { @@ -47,7 +52,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]) ->add('lastname', TextType::class, [ 'label' => 'Nom', - 'required' => true, + 'constraints' => [ + new NotBlank(), + ], 'attr' => [ 'size' => 30, 'maxlength' => 40, @@ -55,7 +62,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]) ->add('firstname', TextType::class, [ 'label' => 'Prénom', - 'required' => true, + 'constraints' => [ + new NotBlank(), + ], 'attr' => [ 'size' => 30, 'maxlength' => 40, @@ -63,7 +72,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]) ->add('email', EmailType::class, [ 'label' => 'Email', - 'required' => true, + 'constraints' => [ + new Email(), + ], 'attr' => [ 'size' => 30, 'maxlength' => 100, @@ -79,7 +90,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]) ->add('address', TextareaType::class, [ 'label' => 'Adresse', - 'required' => true, + 'constraints' => [ + new NotBlank(), + ], 'attr' => [ 'cols' => 42, 'rows' => 10, @@ -87,7 +100,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]) ->add('zipcode', TextType::class, [ 'label' => 'Code postal', - 'required' => true, + 'constraints' => [ + new NotBlank(), + ], 'attr' => [ 'size' => 6, 'maxlength' => 10, @@ -95,28 +110,39 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]) ->add('city', TextType::class, [ 'label' => 'Ville', - 'required' => true, + 'constraints' => [ + new NotBlank(), + ], 'attr' => [ 'size' => 30, 'maxlength' => 50, ], ]) - ->add('countryId', ChoiceType::class, [ + ->add('country', ChoiceType::class, [ 'label' => 'Pays', - 'required' => true, + 'constraints' => [ + new NotBlank(), + ], + 'preferred_choices' => ['FR'], 'choices' => array_flip($this->pays->obtenirPays()), ]) ->add('phone', TextType::class, [ 'label' => 'Tél. fixe', 'required' => false, + 'constraints' => [ + new Length(['max' => 20]), + ], 'attr' => [ 'size' => 20, 'maxlength' => 20, ], ]) - ->add('cellphone', TextType::class, [ + ->add('mobilephone', TextType::class, [ 'label' => 'Tél. portable', 'required' => false, + 'constraints' => [ + new Length(['max' => 20]), + ], 'attr' => [ 'size' => 20, 'maxlength' => 20, @@ -166,31 +192,24 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'Inactif' => User::STATUS_INACTIVE, ], ]) - ->add('login', TextType::class, [ + ->add('username', TextType::class, [ 'label' => 'Login', - 'required' => true, + 'constraints' => [ + new NotBlank(), + new Length(['max' => 30]), + ], 'attr' => [ 'size' => 30, 'maxlength' => 30, ], ]) - ->add('password', RepeatedType::class, [ - 'required' => false, + ->add('plainPassword', RepeatedType::class, [ + 'mapped' => false, 'type' => PasswordType::class, - 'first_options' => [ - 'label' => 'Mot de passe', - 'attr' => [ - 'size' => 30, - 'maxlength' => 30, - ], - ], - 'second_options' => [ - 'label' => 'Confirmation mot de passe', - 'attr' => [ - 'size' => 30, - 'maxlength' => 30, - ], - ], + 'required' => false, + 'invalid_message' => 'The password fields must match', + 'first_options' => ['label' => 'Password'], + 'second_options' => ['label' => 'Repeat Password'], ]) ->add('roles', TextareaType::class, [ 'label' => 'Rôles', @@ -204,5 +223,31 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'required' => false, ]) ->add('save', SubmitType::class, ['label' => 'Ajouter']); + + $builder->get('roles')->addModelTransformer(new CallbackTransformer( + function ($rolesAsArray): string { + return json_encode($rolesAsArray); + }, + function ($rolesAsString): array { + return json_decode($rolesAsString); + } + )); + + $builder + ->get('companyId')->addModelTransformer(new CallbackTransformer( + function ($value): string { + return $value; + }, + function ($value): int { + return (int) $value; + } + )); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => User::class, + ]); } } diff --git a/sources/AppBundle/Controller/Admin/Members/UserAddAction.php b/sources/AppBundle/Controller/Admin/Members/UserAddAction.php index 23af3f1af..3c729c4f5 100644 --- a/sources/AppBundle/Controller/Admin/Members/UserAddAction.php +++ b/sources/AppBundle/Controller/Admin/Members/UserAddAction.php @@ -3,13 +3,10 @@ namespace AppBundle\Controller\Admin\Members; use Afup\Site\Logger\DbLoggerTrait; -use AppBundle\Association\Form\UserEditFormData; -use AppBundle\Association\Form\UserEditFormDataFactory; use AppBundle\Association\Form\UserEditType; use AppBundle\Association\Model\Repository\UserRepository; use AppBundle\Association\Model\User; use AppBundle\Association\UserMembership\UserService; -use Exception; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -25,8 +22,6 @@ class UserAddAction /** @var UserRepository */ private $userRepository; - /** @var UserEditFormDataFactory */ - private $userEditFormDataFactory; /** @var UserService */ private $userService; /** @var FormFactoryInterface */ @@ -42,7 +37,6 @@ class UserAddAction public function __construct( UserRepository $userRepository, - UserEditFormDataFactory $userEditFormDataFactory, UserService $userService, FormFactoryInterface $formFactory, SessionInterface $session, @@ -51,7 +45,6 @@ public function __construct( Environment $twig ) { $this->userRepository = $userRepository; - $this->userEditFormDataFactory = $userEditFormDataFactory; $this->userService = $userService; $this->formFactory = $formFactory; $this->session = $session; @@ -63,33 +56,51 @@ public function __construct( public function __invoke(Request $request) { if ($this->session->has('generer_personne_physique')) { - $data = $this->userEditFormDataFactory->fromSession($this->session->get('generer_personne_physique')); + $user = $this->fromSession($this->session->get('generer_personne_physique')); $this->session->remove('generer_personne_physique'); } else { - $data = new UserEditFormData(); - $data->roles = json_encode([]); + $user = new User(); + $user->setRoles([]); } - $form = $this->formFactory->create(UserEditType::class, $data); + + $form = $this->formFactory->create(UserEditType::class, $user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $user = new User(); - if (null === $data->password) { - $data->password = $this->userService->generateRandomPassword(); + if (!$user->getCompanyId()) { + $user->setCompanyId(0); } - $this->userEditFormDataFactory->toUser($data, $user); - try { - $this->userRepository->create($user); - $this->log('Ajout de la personne physique ' . $user->getFirstName() . ' ' . $user->getLastName()); - $this->flashBag->add('notice', 'La personne physique a été ajoutée'); - - return new RedirectResponse($this->urlGenerator->generate('admin_members_user_list', ['filter' => $user->getEmail()])); - } catch (Exception $e) { - $this->flashBag->add('error', 'Une erreur est survenue lors de l\'ajout de la personne physique'); + if (null === $user->getPassword()) { + $user->setPlainPassword($this->userService->generateRandomPassword()); } + + $this->userRepository->create($user); + $this->log('Ajout de la personne physique ' . $user->getFirstName() . ' ' . $user->getLastName()); + $this->flashBag->add('notice', 'La personne physique a été ajoutée'); + + return new RedirectResponse($this->urlGenerator->generate('admin_members_user_list', ['filter' => $user->getEmail()])); } return new Response($this->twig->render('admin/members/user_add.html.twig', [ 'form' => $form->createView(), ])); } + + private function fromSession(array $session): User + { + $user = new User(); + + $user->setCity($session['civilite']); + $user->setLastname($session['nom']); + $user->setFirstname($session['prenom']); + $user->setEmail($session['email']); + $user->setAddress($session['adresse']); + $user->setZipCode($session['code_postal']); + $user->setCity($session['ville']); + $user->setCountry($session['id_pays']); + $user->setPhone($session['telephone_fixe']); + $user->setMobilephone($session['telephone_portable']); + $user->setStatus($session['etat']); + + return $user; + } } diff --git a/sources/AppBundle/Controller/Admin/Members/UserEditAction.php b/sources/AppBundle/Controller/Admin/Members/UserEditAction.php index 2d936c7bb..be3dbaacc 100644 --- a/sources/AppBundle/Controller/Admin/Members/UserEditAction.php +++ b/sources/AppBundle/Controller/Admin/Members/UserEditAction.php @@ -4,12 +4,9 @@ use Afup\Site\Logger\DbLoggerTrait; use AppBundle\Association\Form\UserBadgeType; -use AppBundle\Association\Form\UserEditFormDataFactory; use AppBundle\Association\Form\UserEditType; use AppBundle\Association\Model\Repository\UserRepository; use AppBundle\Event\Model\Repository\UserBadgeRepository; -use Assert\Assertion; -use Exception; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -26,8 +23,6 @@ class UserEditAction private $userRepository; /** @var UserBadgeRepository */ private $userBadgeRepository; - /** @var UserEditFormDataFactory */ - private $userEditFormDataFactory; /** @var FormFactoryInterface */ private $formFactory; /** @var UrlGeneratorInterface */ @@ -40,7 +35,6 @@ class UserEditAction public function __construct( UserRepository $userRepository, UserBadgeRepository $userBadgeRepository, - UserEditFormDataFactory $userEditFormDataFactory, FormFactoryInterface $formFactory, UrlGeneratorInterface $urlGenerator, FlashBagInterface $flashBag, @@ -48,7 +42,6 @@ public function __construct( ) { $this->userRepository = $userRepository; $this->userBadgeRepository = $userBadgeRepository; - $this->userEditFormDataFactory = $userEditFormDataFactory; $this->formFactory = $formFactory; $this->urlGenerator = $urlGenerator; $this->flashBag = $flashBag; @@ -58,22 +51,24 @@ public function __construct( public function __invoke(Request $request) { $user = $this->userRepository->get($request->query->get('id')); - Assertion::notNull($user); - $data = $this->userEditFormDataFactory->fromUser($user); - $form = $this->formFactory->create(UserEditType::class, $data); + if (!$user) { + $this->flashBag->add('error', 'Utilisateur non trouvé'); + return new RedirectResponse($this->urlGenerator->generate('admin_members_user_list')); + } + $form = $this->formFactory->create(UserEditType::class, $user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->userEditFormDataFactory->toUser($data, $user); - try { - $this->userRepository->edit($user); - $this->log('Modification de la personne physique ' . $user->getFirstName() . ' ' . $user->getLastName() . ' (' . $user->getId() . ')'); - // Redirection sur la liste filtrée - $this->flashBag->add('notice', 'La personne physique a été modifiée'); - - return new RedirectResponse($this->urlGenerator->generate('admin_members_user_list', ['filter' => $user->getEmail()])); - } catch (Exception $e) { - $this->flashBag->add('error', 'Une erreur est survenue lors de la modification de la personne physique'); + // Save password if not empty + $newPassword = $request->request->get($form->getName())['plainPassword']['first']; + if ($newPassword) { + $user->setPlainPassword($newPassword); } + $this->userRepository->edit($user); + $this->log('Modification de la personne physique ' . $user->getFirstName() . ' ' . $user->getLastName() . ' (' . $user->getId() . ')'); + // Redirection sur la liste filtrée + $this->flashBag->add('notice', 'La personne physique a été modifiée'); + + return new RedirectResponse($this->urlGenerator->generate('admin_members_user_list', ['filter' => $user->getEmail()])); } $userBadges = iterator_to_array($this->userBadgeRepository->findByUserId($user->getId())); diff --git a/sources/AppBundle/Controller/MemberShipController.php b/sources/AppBundle/Controller/MemberShipController.php index d85fd8aec..cbd3a621d 100644 --- a/sources/AppBundle/Controller/MemberShipController.php +++ b/sources/AppBundle/Controller/MemberShipController.php @@ -329,36 +329,16 @@ public function contactDetailsAction(Request $request) $logs = $this->get(LegacyModelFactory::class)->createObject(Logs::class); $repo = $this->get('ting')->get(UserRepository::class); + /** @var User $user */ $user = $repo->get($this->getUserId()); - $data = [ - 'email' => $user->getEmail(), - 'address' => $user->getAddress(), - 'username' => $user->getUsername(), - 'zipcode' => $user->getZipCode(), - 'city' => $user->getCity(), - 'phone' => $user->getPhone(), - 'mobilephone' => $user->getMobilePhone(), - 'country' => $user->getCountry(), - 'nearest_office' => $user->getNearestOffice(), - ]; - - $userForm = $this->createForm(ContactDetailsType::class, $data); + + $userForm = $this->createForm(ContactDetailsType::class, $user); $userForm->handleRequest($request); - if ($userForm->isValid()) { - $data = $userForm->getData(); - - $user->setEmail($data['email']); - $user->setAddress($data['address']); - $user->setZipCode($data['zipcode']); - $user->setCity($data['city']); - $user->setUsername($data['username']); - $user->setPhone($data['phone']); - $user->setMobilePhone($data['mobilephone']); - $user->setCountry($data['country']); - $user->setNearestOffice($data['nearest_office']); + if ($userForm->isSubmitted() && $userForm->isValid()) { // Save password if not empty - if (! empty($data['password'])) { - $user->setPassword(md5($data['password'])); /** @TODO We should change that */ + $newPassword = $request->request->get($userForm->getName())['plainPassword']['first']; + if ($newPassword) { + $user->setPlainPassword($newPassword); } $repo->save($user); diff --git a/sources/AppBundle/Validator/Constraints/UniqueEntityValidator.php b/sources/AppBundle/Validator/Constraints/UniqueEntityValidator.php index 7d459efeb..7e344f572 100644 --- a/sources/AppBundle/Validator/Constraints/UniqueEntityValidator.php +++ b/sources/AppBundle/Validator/Constraints/UniqueEntityValidator.php @@ -35,7 +35,7 @@ public function validate($entity, Constraint $constraint) $myEntity = $repository->getOneBy($criteria); - if ($myEntity !== null) { + if ($myEntity !== null && $myEntity->getId() !== $entity->getId()) { $this->context->buildViolation($constraint->message) ->setParameter('{{ data }}', implode(', ', $criteria)) ->addViolation(); diff --git a/tests/behat/features/Admin/AdminPersonnesPhysiques.feature b/tests/behat/features/Admin/AdminPersonnesPhysiques.feature index 97b44dd13..f69417ccc 100644 --- a/tests/behat/features/Admin/AdminPersonnesPhysiques.feature +++ b/tests/behat/features/Admin/AdminPersonnesPhysiques.feature @@ -17,7 +17,7 @@ Feature: Administration - Partie Personnes physiques And I fill in "user_edit[address]" with "32 rue des lilas" And I fill in "user_edit[zipcode]" with "69001" And I fill in "user_edit[city]" with "LYON" - And I fill in "user_edit[login]" with "monlogin" + And I fill in "user_edit[username]" with "monlogin" And I press "Ajouter" Then I should not see "Cette valeur ne doit pas être vide" # on vérifie qu'il est dans la liste diff --git a/tests/behat/features/PublicSite/Register.feature b/tests/behat/features/PublicSite/Register.feature index 1fd051349..74604e4e0 100644 --- a/tests/behat/features/PublicSite/Register.feature +++ b/tests/behat/features/PublicSite/Register.feature @@ -1,5 +1,25 @@ Feature: Site Public - Register + Scenario: Je ne peux pas adhérer comme particulier avec un email existant + Given I am on the homepage + When I follow "Adhérer" + Then I should see "Devenir membre de l'AFUP" + When I follow "Adhérer en tant que particulier" + Then I should see "Formulaire d'inscription à l'AFUP" + And I fill in "register_user_userCommonInfo_email" with "admin@admin.fr" + And I press "Créer mon compte" + And I should see "Un autre compte existe avec cette information: admin@admin.fr" + + Scenario: Je ne peux pas adhérer comme particulier avec un login existant + Given I am on the homepage + When I follow "Adhérer" + Then I should see "Devenir membre de l'AFUP" + When I follow "Adhérer en tant que particulier" + Then I should see "Formulaire d'inscription à l'AFUP" + And I fill in "register_user_userCommonInfo_username" with "admin" + And I press "Créer mon compte" + And I should see "Un autre compte existe avec cette information: admin" + @reloadDbWithTestData @clearEmails Scenario: Accès à l'adhésion particulier