Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

I'm building a web application in Symfony 2 where I have a User entity class for holding registered users.

Every user should have at least a username and a password of course, hence, I use the @Assert\NotBlank validation rule for both fields in the entity. The username is static, however, being able to change the password is desirable.

Thus, I'm building a form where signed in users can change their password (among other things). This form utilizes the repeated field type in Symfony for password confirmation purposes.

Now, in most cases I guess users are not looking to change their password, but rather update other fields in their profile. Therefore, I would want it to be possible for them to leave the password field blank. However, that will interfere with the NotBlank validation rule.

Removing the NotBlank validation rule is of course an option. Although, hardly the solution I'm looking for since that incures the problem of users ending up with a blank password.

Finally, As I understand it the symfony Request object autofills the form data back into the User entity on form submission.

Now, my question is: Is there any way to, upon empty password-field, make Symfony refill the User entity with the existing password from the database rather than a blank value? This would allow validation to follow through and won't cause any undesired changes to the password upon saving.

This is the code for the password field in the entity

/**
 * @var string
 * 
 * @ORM\Column(name="password",type="string",length=255) 
 * @Assert\NotBlank()
 * @Assert\Type(type="string")
 * @Assert\Length(max="255")
 * @Assert\NotEqualTo(value="password")
 */
private $password;

This is the code for generating the form

private function initForm($user) {
  return $this->createFormBuilder($user)
           ->add('name', 'text')
           ->add('mail', 'email')
           ->add('password', 'repeated', [
              'type' => 'password',
              'invalid_message' => 'The password fields must match.',
              'first_options' => ['label' => false],
              'second_options' => ['label' => false] //set to false to hide label in view
           ])
           ->add('save', 'submit')->getForm();
}

This is the Action-code for the /profile/edit page:

/**
 *  @ParamConverter("user",class="MyBundle:User")
 */
public function editAction(User $user, Request $request) {

   $form = $this->initForm($user);
   $form->handleRequest($request);

   if ($form->isValid()) {
      //update to database and redirect user back to profile_view
      $this->getDoctrine()->getManager()->flush();
      return $this->redirect($this->generateUrl('profile_view'));
   }

   return $this->render('MyBundle:User:edit.html.twig',
                        array('form' => $form->createView()));
}

Thanks in advance for any help!

EDIT

I did try the "obvious" approach, i.e. temporarilly storing the original password in a variable and "putting" it back if it was blank after the form was submitted:

/**
 * @ParamConverter("user",
                   class="MyBundle:User")
 */
public function editAction(User $user, Request $request) {
   $password = $user->getPassword();

   $form = $this->initForm($user)->getForm();
   $form->handleRequest($request);

   if ( $user->getPassword() == NULL ) {
       $user->setPassword($password);
       $form = $this->initForm($user)->getForm(); //this is the problem

   }

   if ( $form->isValid() ) {
       //update to database and redirect user back to profile view
       $this->getDoctrine()->getManager()->flush();
       return $this->redirect($this->generateUrl('profile_view'));
   }
   return $this->render('MyBundle:User:edit.html.twig',
                        array('form' => $form->createView()));
}

However, this did not work for apparent reasons. When the form is reinitialised within the if statement, Symfony finds the form has never been submitted in the first place, i.e. no validation is performed. And adding the $form->handleRequest($request) leaves us back with the first problem where the password field might be blank.

What I do find peculiar though. Symfony validates the Entity and not the form. But removing the problem row $form->initForm($user)->getForm() still didn't work, although the entity should be valid.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

I think this is not a good idea. The right way is create a separate form for changing user password. Examples: twitter, facebook, google

share|improve this answer
    
After some continued research I do believe you're right! I'll accept it as an answer.. but if someone should find a way, I'm all ears! – walander Jul 18 '14 at 12:12
1  
And I completely forgot; great thanks for your help! =) – walander Jul 18 '14 at 12:31

A solution is to use an extra class member $rawPassword, not stored in database, to be only used on your form. You will, of course, have keep your $password variable for database storage as defined in your question.

On your edit action, you just have to test after $form->bind($request); if your user as a $rawPassword password defined. If it's the case, update $password with the encoding value of $rawPassword, and flush.

EDIT : $form->bind($request); below 2.3, $form->handleRequest($request); otherwise.

share|improve this answer
    
Interesting thought! That would absolutely work for me. Thank you very much! Just a kind remark too, I do believe the $form->bind($request) method is depreceated since Symfony 2.3. – walander Jul 18 '14 at 13:00
    
Holly cow ! Indeed ! It's my job to thank you this time, I completely missed this. – L. Wartel Jul 18 '14 at 13:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.