2014-02-06 39 views
6

我想要從後端編輯現有用戶(使用SonataAdminBundle和FOSUserBundle)時遇到問題。在我的UserAdmin類的configureFormFields方法中,密碼字段顯示爲空,當我需要編輯保持相同用戶密碼的其他字段(例如姓氏)時,這是一個問題。該字段(和密碼驗證字段)必須重新填寫! (我不希望修改用戶密碼)使用SonataAdminBundle編輯特定用戶時避免使用空密碼字段

在我UserAdmin類,我有:

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() 
     ; 
} 

我試圖覆蓋在我的UserAdmin類prePersist和更新前的方法,但這些不工作。密碼在FOS標準數據庫中加入(使用salt和sha512)。

任何解決方案? 非常感謝!

+0

你試着用[ NotBlank](http://symfony.com/doc/current/reference/constraints/NotBlank.html)驗證? –

回答

2

您可以覆蓋你的preUpdate功能在您的管理類,這是我如何做了

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()); 
     } 
    } 

而且我configureFormFields功能

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

謝謝,但想法是使用FOS用戶管理器檢索用戶密碼(plainPassword) – jfontecha

+0

FOS Uesr包不保存數據庫中的plainpasswrod,您可以在持久保存前訪問palin密碼,但一旦刷新加密後的密碼將被保存在數據庫 –

+1

我用適合於我的管理員類的代碼塊實現瞭解決此問題。謝謝! – jfontecha

0

有一些方法可以做到這一點

更改configureFormField行爲

你可以得到configureFormFields內當前對象($this->subject$this->getSubject();),如果它檢查新對象或現有改變域的行爲(驗證爲例)

使用saveHooks和FOSUser

這裏有一個例子

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

這將顯示密碼字段中的散列密碼,但需要更新進入它,當一個新的簡單的一個(如果我沒記錯)

合併兩組貫徹鉤就可以得到FOSUserManager 內自己的邏輯

,並與

處理用戶的更新

容器:$this->getConfigurationPool()->getContainer();

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

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

-1

我強烈建議您,如果您將SonataAdminBundle與FOSUserBundle組合使用,則還應安裝SonataUserBundle。這將解決您的問題,因爲它已經處理了這個問題,並且還附帶了標準的管理員類。檢查安裝是否很容易將其與FOSUserBundle結合使用。我知道它也在用戶實體中添加了很多額外的字段,但是如果只想要字段,則可以覆蓋該包。

2

我有和你一樣的問題,但沒有SonataAdminBundle的

在一個典型的用戶管理管理(Symfony3),這個工程:

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

不要忘記,以消除plainPassword @assert \ NotBlank()在你的用戶實體:

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

我editAction()在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() 
    )); 
    } 

現在,創建新用戶時需要密碼,但編輯密碼時不需要密碼。

1

也許爲時已晚,但對其他人有用。 感謝其他職位。 太簡單了。只需使用:

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

它使用限定的輪廓驗證組:

friendsofsymfony /用戶束/資源/配置/ validation.xml中

相關問題