I have the same problem as yours, but without SonataAdminBundle .
In the classic admin management (Symfony3), this works:
// src/AppBundle/Form/UserType.php <?php namespace AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { // By default, password is required (create user case) $passwordOptions = array( 'type' => PasswordType::class, 'first_options' => array('label' => 'Password'), 'second_options' => array('label' => 'Repeat password'), 'required' => true ); // If edit user : password is optional // User object is stored in $options['data'] $recordId = $options['data']->getId(); if (!empty($recordId)) { $passwordOptions['required'] = false; } $builder ->add('prenom', TextType::class, array('label' => 'First name')) ->add('nom', TextType::class, array('label' => 'Last name')) ->add('email', EmailType::class) ->add('username', TextType::class) ->add('plainPassword', RepeatedType::class, $passwordOptions) ->add('roleList', ChoiceType::class, array( 'label' => 'Role', 'choices' => array( 'Admin' => 'ROLE_ADMIN', 'User' => 'ROLE_USER' ), )) ->add('save', SubmitType::class, array( 'attr' => array('class' => 'button-link save'), 'label' => 'Validate' )); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'AppBundle\Entity\User', )); } }
Remember to delete @Assert \ NotBlank () in plainPassword in your user:
private $plainPassword;
My editAction () in UserController.php:
/** * @Route("/users/edit/{id}", name="user_edit") */ public function editAction($id, Request $request) { // get user from database $em = $this->getDoctrine()->getManager(); $user = $em->getRepository('AppBundle:User')->find($id); // user doesn't exist if (!$user) { throw $this->createNotFoundException('No user found for id '. $id); } // build the form with user data $originalPassword = $user->getPassword(); # encoded password $form = $this->createForm(UserType::class, $user); // form POST $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // Encode the password if needed # password has changed if (!empty($form->get('plainPassword')->getData())) { $password = $this->get('security.password_encoder') ->encodePassword($user, $user->getPlainPassword()); $user->setPassword($password); # password not changed } else { $user->setPassword($originalPassword); } $role = $form->get('roleList')->getData(); $user->setRoles(array($role)); // update the User $em->flush(); // success message $this->addFlash('notice', 'User has been updated successfully !'); // redirection return $this->redirectToRoute('user'); } // show form return $this->render('users/form.html.twig', array( 'h1_title' => 'Edit user : ' . $user->getPrenom() . " " . $user->getNom(), 'form' => $form->createView() )); }
Now, when you create a new user, a password is required, but this is not when you edit it.