2014-02-06 17 views
6

Ich habe ein Problem, wenn ich einen vorhandenen Benutzer aus dem Backend (mit SonataAdminBundle und FOSUserBundle) bearbeiten möchte. In der configureFormFields-Methode meiner UserAdmin-Klasse erscheint das Kennwortfeld leer, und dies ist ein Problem, wenn ich ein anderes Feld (z. B. den Nachnamen) bearbeiten muss, das das gleiche Benutzerkennwort enthält. Dieses Feld (und das Passwortverifizierungsfeld) muss erneut ausgefüllt werden! (Ich möchte nicht, das Benutzer-Passwort ändern)Vermeiden Sie leere Passwort-Feld, wenn Sie einen bestimmten Benutzer mit SonataAdminBundle bearbeiten

In meiner Klasse Admin, ich habe:

public function configureFormFields(FormMapper $formMapper) 
{ 
     $formMapper 
      ->with('User Data') 
       ->add('username') 

       ->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', 
       )) 

       ->add('firstname') 
       ->add('lastname') 
       ->add('email') 
       ->add('user_roles') 
       ->add('enabled', 'checkbox', array(
         'label'  => 'Enable Account', 
         'required' => false, 
       )) 
      ->end() 
     ; 
} 

Ich versuchte PrePersist und Preupdate Methoden in meiner Klasse Admin zu überschreiben, aber diese funktionieren nicht. Das Passwort ist in der Datenbank nach dem FOS-Standard (mit salt und sha512) verschlüsselt.

Irgendeine Lösung? Vielen Dank!

+0

Haben Sie versucht, mit [ NotBlank] (http://symfony.com/doc/current/reference/constraints/NotBlank.html) Validierung? –

Antwort

2

Sie können die preUpdate Funktion in Ihrem Admin-Klasse überschreiben diese ist, wie ich

public function preUpdate($object) 
    { 
     $DM = $this->getConfigurationPool()->getContainer()->get('Doctrine')->getManager(); 
     $repository = $DM->getRepository('Namespace\YourBundle\Entity\User')->find($object->getId()); 

     $Password = $object->getPassword(); 
     if (!empty($Password)) { 
      $salt = md5(time()); 

      $encoderservice = $this->getConfigurationPool()->getContainer()->get('security.encoder_factory'); 
      $encoder = $encoderservice->getEncoder($object); 
      $encoded_pass = $encoder->encodePassword($object->getPassword(), $salt); 
      $object->setSalt($salt); 
      $object->setPassword($encoded_pass); 
     } else { 
      $object->setPassword($repository->getPassword()); 
     } 
    } 

Und meine configureFormFields Funktion

protected function configureFormFields(FormMapper $formMapper) 
{ 
    $passwordoptions=array('type' => 'password','invalid_message' => 'The password fields must match.', 
       'options' => array('attr' => array('class' => 'password-field')),'first_options' => array('label' => 'Password'), 
     'second_options' => array('label' => 'Confirm password'),'translation_domain' => 'FOSUserBundle' 
      ); 

    $this->record_id = $this->request->get($this->getIdParameter()); 
    if (!empty($this->record_id)) { 
     $passwordoptions['required'] = false; 
     $passwordoptions['constraints'] = array(new Assert\Length(array('min' => 10)) 
          ,new Assert\Regex(array('pattern' => '/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#[email protected]$%^&*-]).{10,}$/','match'=>true,'message'=>'Password must contain atleast 1 special character 1 upper case letter 1 number and 1 lower case letter !')) 
          ); 
    } else { 
     $passwordoptions['required'] = true; 
     $passwordoptions['constraints'] = array(new Assert\Length(array('min' => 10)) 
          ,new Assert\Regex(array('pattern' => '/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#[email protected]$%^&*-]).{10,}$/','match'=>true,'message'=>'Password must contain atleast 1 special character 1 upper case letter 1 number and 1 lower case letter !')) 
          ); 
    } 
    $formMapper->add('password', 'repeated', $passwordoptions); /*you can add your other fields*/ 
    } 
+0

Danke, aber die Idee ist es, den FOS User Manager zu verwenden, um das Benutzerpasswort (plainPassword) – jfontecha

+0

FOS Uesr Bundle nicht plainpasswrod in der Datenbank speichern Sie können auf das Palin-Passwort zugreifen, bevor persistiert aber einmal gespült die verschlüsselte in gespeichert wird Datenbank –

+1

Ich habe es geschafft, es mit Ihrem Code-Block an meine Admin-Klasse angepasst zu lösen. Vielen Dank! – jfontecha

0

Es getan haben, sind einige Möglichkeiten, das zu tun,

Ändern configureFormField behavoir

Sie könnten das aktuelle Objekt ($this->subject oder $this->getSubject();) innerhalb der configureFormFields und überprüfen, ob sein neues Objekt oder eine bestehende und ändern Sie die Felder Verhalten (Validierung zum Beispiel)

Mit saveHooks und FOSUser

erhalten

hier ist ein Beispiel

http://sonata-project.org/bundles/admin/master/doc/reference/saving_hooks.html

dies die Hash-Passwort innerhalb des Passwort-Feld zeigen, sondern aktualisieren es, wenn eine neue Ebene eine Eingabe (wenn ich mich richtig erinnere)

beide kombinieren und Ihre eigene Logik können Sie die FOSUserManager und behandeln den Benutzer Update mit dem

bekommen

innerhalb des Hakens implementieren

Behälter: $this->getConfigurationPool()->getContainer();

fosusermanager: $userManager = $container->get('fos_user.user_manager');

https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/user_manager.md

-1

Ich empfehle dringend, wenn Sie das SonataAdminBundle in Kombination mit dem FOSUserBundle verwenden, sollten Sie auch die SonataUserBundle installieren. Dies wird Ihr Problem beheben, da es dieses Problem bereits behandelt und es auch mit Standard-Admin-Klassen kommt. Überprüfen Sie die Installation, es ist sehr einfach, es mit dem FOSUserBundle zu kombinieren. Ich weiß, dass es auch viele zusätzliche Felder in der Benutzereinheit hinzugefügt hat, aber Sie können das Bündel überschreiben, wenn Sie nur Ihre Felder haben möchten.

2

Ich habe das gleiche Problem, aber ohne SonataAdminBundle.

In einem klassischen Benutzer admin Management (Symfony3), das funktioniert:

// 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', 
     )); 
    } 
} 

Vergessen Sie nicht @Assert \ NotBlank() auf Plain in Ihrem Benutzer-Entity zu entfernen:

/** 
* @Assert\Length(max=4096) 
*/ 
private $plainPassword; 

Meine editAction() in UserController.php:

/** 
    * @Route("https://stackoverflow.com/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() 
    )); 
    } 

Jetzt ist ein Passwort erforderlich, wenn Sie einen neuen Benutzer erstellen, dies ist jedoch nicht der Fall, wenn Sie einen neuen Benutzer erstellen.

1

Vielleicht zu spät, aber nützlich für andere. Mit Dank an andere Beiträge. So einfach. Verwenden Sie einfach:

class UserAdmin extends AbstractAdmin 
 
{ 
 
\t protected $formOptions = array(
 
\t \t 'validation_groups' => array('Profile') 
 
\t); 
 
//.. 
 
}

Es verwendet die Profilvalidierung Gruppe definiert in:

friendsofsymfony/user-Bundle/Ressourcen/config/validation.xml