The problem is that you are binding the form to the user object before controlling the password. Analyze your code snippet.
Do the following
$user = $this->get('security.context')->getToken()->getUser();
load an existing user into a user object.
Now you "create" a form with this data and, if you receive a message, you take the published data to the previous object
$userForm = $this->createForm(new UserFormType(), $user); if ($request->getMethod() == 'POST') { $userForm->bindRequest($request);
So, on bindRequest you have alredy that has lost the previous password in the object (obviously not yet in the database) if it remains empty. Every control is useless from now on.
In this case, the solution is to manually check the value of the form field directly in the $request object before attaching it to the base object.
You can do this with this simple snippet of code.
$postedValues = $request->request->get('formName');
You must now confirm that the password is full
if($postedValues['plainPassword']) { ... }
where plainPassword I believe this is the name of the field that interests us.
If you find that this field contains a value (else branch), you should not do anything.
Otherwise, you should get the original password from the User Object and set it to $request .
( update ). Otherwise, you can get the password from the User Object, but since this password is stored with a hased rating, you cannot put it in the $request object, because it will suffer from hashing again. What could you do - I suppose - array_pop directly into the $request object and remove the field that will ruin all things (plainPassword) Now that you have done this, you can link the published data to the base object.
Another solution (perhaps better because you disconnect some business logic from the controller) is to use prePersist hook, but more conceptually advanced. If you want to explore this solution, you can read it about form events.