简体   繁体   中英

SonataAdminBundle can not update the user password

I can not update the user password via sonataadmin dashboard.

I use symfony2 FosUserBundle2.0 SonataAdminBundle(but not use SonataUserBundle) and follow the Document to do.

MyUserBundle\\Admin\\UserAdmin.php class UserAdmin extends Admin like this

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ......
        ->add('plainPassword', 'repeated', array(
            'type' => 'password',
            'options' => array('translation_domain' => 'FOSUserBundle'),
            'first_options' => array('label' => 'form.password'),
            'second_options' => array('label' => 'form.password_confirmation'),
            'invalid_message' => 'fos_user.password.mismatch',
                'required'    => false,
            )
        )
        ..
}

there is no problem when i use sonataadminbundle dashboard to create a new user, but when i use dashboard to update the password,the password in DB doesn't change.

the others can update but the password, i don't know why. there is no any errror message.

I am new in symfony2, some one help me?

thanks to kwozny ,now i fix it~ i don't change the function configureFormFields code, just follow kwozny's advise , add the following code.i don't know why ,but i works! i can update the password and when i update the others(password field is empty) the password will not change.

public function prePersist($object)
    {
        parent::prePersist($object);

    }
    public function preUpdate($object)
    {
        parent::preUpdate($object);

    }

that's because you have to catch the object User (preUpdate() and prePersist()) and set password using $user->setPlainPassword. Thats how my code looks:

Instead:

->add('plainPassword', 'repeated', array(
        'type' => 'password',
        'options' => array('translation_domain' => 'FOSUserBundle'),
        'first_options' => array('label' => 'form.password'),
        'second_options' => array('label' => 'form.password_confirmation'),
        'invalid_message' => 'fos_user.password.mismatch',
            'required'    => false,
        )
    )

I have:

            ->add('newPass', 'text', array(
                'label' => 'New password (empty filed means no changes)',
                'required' => FALSE
            ))

and then in the same admin file:

public function prePersist($object) {
    parent::prePersist($object);
    $this->updateUser($object);
}

public function preUpdate($object) {
    parent::preUpdate($object);
    $this->updateUser($object);
}

public function updateUser(\AppBundle\Entity\User $u) {
    if ($u->getNewPass()) {
        $u->setPlainPassword($u->getNewPass());
    }

    $um = $this->getConfigurationPool()->getContainer()->get('fos_user.user_manager');
    $um->updateUser($u, false);
}

I found a better way based on kamwoz answer and it worked for me.

In FormMapper:

    $passwordoptions=array(
        'type' => 'password',
        'options' => array('translation_domain' => 'FOSUserBundle'),
        'first_options' => array('label' => 'form.password'),
        'second_options' => array('label' => 'form.password_confirmation'),
        'translation_domain' => 'FOSUserBundle',
        'invalid_message' => 'fos_user.password.mismatch',
    );

    $this->record_id = $this->request->get($this->getIdParameter());
    if (!empty($this->record_id)) {
        $passwordoptions['required'] = false;
    } else {
        $passwordoptions['required'] = true;
    }

    $formMapper
        // ...
        ->add('plainPassword', 'repeated', $passwordoptions)

Note: I added condition if user exist: password not required, new user: pass required.

Now just add the code like this in the admin:

public function prePersist($object) {
    parent::prePersist($object);
    $this->updateUser($object);
}

public function preUpdate($object) {
    parent::preUpdate($object);
    $this->updateUser($object);
}

public function updateUser(\AppBundle\Entity\User $u) {
    $um = $this->getConfigurationPool()->getContainer()->get('fos_user.user_manager');
    $um->updateUser($u, false);
}

There is no need to change User Entity, just use plainPassword as usual.

In my case add

 public function preUpdate($object) {
    parent::preUpdate($object);
    //$this->updateUser($object);
    if($object->getPlainPassword())
    {
        $um = $this->getConfigurationPool()->getContainer()->get('fos_user.user_manager');
        $um->updateCanonicalFields($object);
        $um->updatePassword($object);
    }
}

In my case i have solved in this way. My answer is below. I have used some code of above answer with code of sonata type repeated so validation still work for same password validation.

 public function prePersist($object)
{
    parent::prePersist($object);

}

public function preUpdate($object)
{
    parent::preUpdate($object);
    $this->updateUser($object);

}

//update password
public function updateUser(\AppBundle\Entity\User $u) {
  if ($u->getPlainPassword()) {
    $u->setPlainPassword($u->getPlainPassword());
  }

  $um = $this->getConfigurationPool()->getContainer()->get('fos_user.user_manager');
  $um->updateUser($u, false);
}

protected function configureFormFields(FormMapper $formMapper)
{
    $pass_required = false;
    //if form is create then add required validation
    if (!$this->subject->getId()) 
      $pass_required = true;

    $formMapper->add('name', 'text')
               ->add('email', 'email', array('label' => "Email") )  
               ->add('username', 'text', array('label' => "Username") )  
               ->add('groups', 'entity', array(
                   'class' => 'AppBundle\Entity\Group',
                   'required' => false,
                   'multiple' =>true
                ))
                ->add('plainPassword', 'repeated', array(
                   'type' => 'password',
                   'options' => array('translation_domain' => 'FOSUserBundle'),
                   'first_options' => array('label' => 'form.password'),
                   'second_options' => array('label' => 'form.password_confirmation'),
                   'invalid_message' => 'fos_user.password.mismatch',
                   'required'    => $pass_required,
               ))
               ->end()
                ;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM