2016-04-25 47 views
1

我面臨着一個非常奇怪的情況爲我改名字,甚至如果我不改變任何東西,然後按保存按鈕它就會退出與ROLE_ADMIN用戶,即會退出。如果我直接將數據庫中的用戶角色更改爲ROLE_USER,則相同的代碼可以正常工作,並且用戶不會註銷。Symfony的 - 用戶被註銷甚至在更名

以下是該配置文件更新的護理控制器

/** 
    * @Route("/profile", name="profile") 
    */ 
    public function profileAction(Request $request) 
    { 

     $em = $this->getDoctrine()->getManager(); 

     $userInfo = $this->getUser(); 

     //create the form object 
     $profileForm = $this->createForm(UserType::class, $userInfo); 
     $profileForm->handleRequest($request); 


     //check data validity 
     if($profileForm->isValid()){ 
      $em->persist($userInfo); 
      $em->flush(); 
      $this->get('session')->getFlashBag()->add(
       'success', 
       'Your profile information has been updated' 
      ); 

      return $this->render('AppBundle:admin/user:admin-edit.html.twig',array(
       'edit_form' => $profileForm->createView() 
      )); 
     } 


     // render registration form 
     return $this->render('AppBundle:admin/user:admin-edit.html.twig',array(
      'edit_form' => $profileForm->createView() 
     )); 
    } 

} 

這是我security.yml

security: 
    encoders: 
     # Our user class and the algorithm we'll use to encode passwords 
     # http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password 
     AppBundle\Entity\User: bcrypt 

    providers: 
     # Simple example of loading users via Doctrine 
     # To load users from somewhere else: http://symfony.com/doc/current/cookbook/security/custom_provider.html 
     database_users: 
      entity: { class: AppBundle:User, property: username } 

    firewalls: 
     # disables authentication for assets and the profiler, adapt it according to your needs 
     dev: 
      pattern: ^/(_(profiler|wdt)|css|images|js)/ 
      security: false 

     main: 
      http_basic: ~ 
      anonymous: ~ 
      logout: ~ 
      guard: 
       authenticators: 
        - app.form_login_authenticator 
        - app.facebook_authenticator 
       # by default, use the start() function from FormLoginAuthenticator 
       entry_point: app.form_login_authenticator 
    access_control: 
     - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/admin/, roles: ROLE_ADMIN } 
     - { path: ^/user, roles: ROLE_USER } 

更新1

這是我UserType

namespace AppBundle\Form; 

use AppBundle\Form\EventListener\AddDepartmentDegreeCourseFieldSubscriber; 
use AppBundle\Form\EventListener\AddProfileFieldSubscriber; 
use Doctrine\ORM\EntityManager; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 


class UserType extends AbstractType 
{ 

    private $addDepartmentDegreeCourseFieldSubscriber; 
    private $addProfileFieldSubscriver; 

    function __construct(AddDepartmentDegreeCourseFieldSubscriber $subscriber, AddProfileFieldSubscriber $fields) 
    { 
     $this->addDepartmentDegreeCourseFieldSubscriber = $subscriber; 
     $this->addProfileFieldSubscriver = $fields; 
    } 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->addEventSubscriber($this->addProfileFieldSubscriver); 
     $builder->addEventSubscriber($this->addDepartmentDegreeCourseFieldSubscriber); 
    } 

    /** 
    * @param OptionsResolver $resolver 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\User' 
     )); 
    } 
} 

這是我AddProfileFieldSubscriber

namespace AppBundle\Form\EventListener; 


use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 
use Symfony\Component\Form\Extension\Core\Type\EmailType; 
use Symfony\Component\Form\Extension\Core\Type\FileType; 
use Symfony\Component\Form\Extension\Core\Type\PasswordType; 
use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker; 
use Symfony\Component\Validator\Constraints\NotBlank; 


class AddProfileFieldSubscriber implements EventSubscriberInterface 
{ 
    protected $authorizationChecker; 


    function __construct(AuthorizationChecker $authorizationChecker) 
    { 
     $this->authorizationChecker = $authorizationChecker; 
    } 

    public static function getSubscribedEvents() 
    { 
     // Tells the dispatcher that you want to listen on the form.pre_set_data 
     // event and that the preSetData method should be called. 
     return array(FormEvents::PRE_SET_DATA => 'preSetData'); 
    } 

    public function preSetData(FormEvent $event) 
    { 


     $user = $event->getData(); 
     $form = $event->getForm(); 




     if($user){ 
      $form->add('firstName', TextType::class); 
      $form->add('lastName', TextType::class); 
      $form->add('password', PasswordType::class, array(
       'mapped' => false 
      )); 
      $form->add('profileImage', FileType::class, array(
       'data_class' => null 
      )); 
      if (in_array("ROLE_USER", $user->getRoles())) { 
       $form->add('contactNumber', TextType::class); 

       $form->add('gender', ChoiceType::class, array(
        'choices' => array(
         'Male' => 'm', 
         'Female' => 'f' 
        ), 
        'placeholder' => 'provide_gender' 
       )); 
       $form->add('college', EntityType::class, array(
         'placeholder' => 'provide_college', 
         'class' => 'AppBundle\Entity\College') 
       ); 
       $form->add('interest', EntityType::class, array(
         'class' => 'AppBundle\Entity\Interest', 
         'multiple' => true, 
         'expanded' => false, 
         'by_reference' => false, 
        ) 
       ); 

      } 

      if($this->authorizationChecker->isGranted('ROLE_ADMIN') ) { 

       $form->add('isActive', ChoiceType::class, array(
        'choices' => array(
         'account_active' => '1', 
         'account_inactive' => '0' 
        ), 
        'placeholder' => 'provide_status' 
       )); 
      } 

     } 
     //if the selected user has role_user only then display the following fields in edit profile view 
     else { 
      $form->add('username', EmailType::class); 
      $form->add('password', PasswordType::class, array(
       'constraints' => array(new NotBlank(array(
         'message' => 'user.password.not_blank' 
        ) 
       ),), 
      )); 
     } 
    } 
} 

這是AddDepartmentDegreeCourseFieldSubscriber

namespace AppBundle\Form\EventListener; 


use AppBundle\Entity\Degree; 
use AppBundle\Entity\Department; 
use Doctrine\ORM\EntityManager; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Form\FormInterface; 

class AddDepartmentDegreeCourseFieldSubscriber implements EventSubscriberInterface 
{ 

    protected $em; 


    function __construct(EntityManager $em) 
    { 
     $this->em = $em; 
    } 

    public static function getSubscribedEvents() 
    { 
     // Tells the dispatcher that you want to listen on the form.pre_set_data 
     // event and that the preSetData method should be called. 
     return array(
      FormEvents::PRE_SET_DATA => 'onPreSetData', 
      FormEvents::PRE_SUBMIT => 'onPreSubmit' 
     ); 
    } 
    protected function addElements(FormInterface $form, Department $departments = null, Degree $degree = null) 
    { 

     // Add the department element 
     $form->add('department', EntityType::class, array(
       'data' => $departments, 
       'placeholder' => 'provide_department', 
       'class' => 'AppBundle\Entity\Department') 
     ); 
     // Degree are empty, unless we actually supplied a department 
     $degree = array(); 
     if ($departments) { 
      // Fetch the courses from specified degree 
      $repo = $this->em->getRepository('AppBundle:Degree'); 
      $degree = $repo->findByDepartment($departments, array('name' => 'asc')); 
     } 


     // Add the province element 
     $form->add('degree', EntityType::class, array(
       'placeholder' => 'provide_degree', 
       'class' => 'AppBundle\Entity\Degree', 
       'choices' => $degree) 
     ); 
     // Cities are empty, unless we actually supplied a province 
     $courses = array(); 
     if ($degree) { 
      // Fetch the cities from specified province 
      $repo = $this->em->getRepository('AppBundle:Course'); 
      $courses = $repo->findByDegree($degree, array('name' => 'asc')); 
     } 
     // Add the Course element 
     $form->add('course', EntityType::class, array(
      'class' => 'AppBundle\Entity\Course', 
      'choices' => $courses, 
     )); 

    } 
    function onPreSubmit(FormEvent $event) { 

     $form = $event->getForm(); 
     $data = $event->getData(); 
     if (isset($data['degree'])) { 

      // Note that the data is not yet hydrated into the entity. 
      $degree = $this->em->getRepository('AppBundle:Degree')->find($data['degree']); 
      $department = $this->em->getRepository('AppBundle:Department')->find($data['department']); 
      $this->addElements($form, $department, $degree); 
     } 
    } 
    function onPreSetData(FormEvent $event) { 
     //echo "before submit";die; 
     $user = $event->getData(); 
     $form = $event->getForm(); 



     if($user){ 
      //if the selected user has role_user only then display the following fields in edit profile view 
      if (in_array("ROLE_USER", $user->getRoles())) { 
       $degree = (!empty($user) && !empty($user->getCourse())) ? $user->getCourse()->getDegree() : null; 
       $departments = (!empty($user) && !empty($user->getCourse())) ? $user->getCourse()->getDegree()->getDepartment() : null; 
       $this->addElements($form, $departments, $degree); 
      } 

     } 

    } 
} 

在這一點上我真的很無能這可能是造成這一點,我真的會在這裏感謝所有幫助...

回答

0

你提供的內容有很多錯誤。其中的元素可能有助於你所看到的行爲。

安全規則

在security.yml,你有這樣一行:

- { path: ^/admin/, roles: ROLE_ADMIN } 

這意味着沒有任何ROLE_ADMIN使用是怎麼回事,如果他們訪問此獲得拍背到登錄屏幕模式。

同時,在你的控制器,你總是將用戶引導回到一個管理員基於路由:

/* 
* @Route("admin/profile", name="admin_profile") 
*/ 

這意味着,不管他們做什麼,他們總是發送到管理員模式。這意味着如果他們改變了角色,他們將被防火牆踢走。

控制器

在您的控制器要綁定的用戶實體到formtype,罰款。但是,你編碼的方式意味着你不明白這是如何工作的。

當您致電handleRequest時,Symfony從表單中提取數據(如果已提交),並將其與您傳遞給它的實體「合併」。這意味着您不必爲對象調用任何setter,就像已經爲您完成的一切。

用戶實體

,你應該對你的User實體是什麼,是一個PlainPassword場和Password場。該窗體只映射到PlainPassword字段..然後,在您的控制器中,取PlainPassword值,對其進行編碼,將其設置爲實體的Password字段,並確保清除PlainPassword值(您不想存儲該值)。如果您在自定義用戶實體上實施了UserInterface(您應該擁有),則應該有一個名爲eraseCredentials的方法,這就是這樣的。 Here is an example

這樣做的結果是,當你檢查的東西,就好說了,一個新的密碼,你只需要做到這一點:

if($profileForm->isValid()){ 
     // $userInfo is populated by handleRequest 
     if ($userInfo->getPlainPassword()) { 
      // do your encoding/erasing credentials here 
     } 
     // ... 

} 

我也建議,就是你寫正確的UserManager類來處理大部分這些事情。它集中了一些東西,使調試變得更容易。 Heres an example

如果您使用的是像我在示例中寫過的內容,這也意味着當您想更新用戶信息時,只需撥打$userManager->updateUser($user)即可完成所有驢工作。

+0

關於'security.yml'是它的權利,爲了訪問任何以'admin'開頭的路徑,你需要'ROLE_ADMIN',所以設置很好,我明白你對密碼的意思,我會這樣做,但你的建議並不能解決問題,假設如果我創建一個配置文件路由的'ROLE_USER'可以訪問使用相同的代碼在控制器內的東西工作正常。它只有這個'ROLE_ADMIN',可以更新它的配置文件完好,但然後它會註銷...我無法理解爲什麼它被註銷。 – Saadia

+0

我通過刪除控制器內的所有內容並保持它的計劃和簡單性來更新我的問題,現在,此代碼適用於'ROLE_USER',但是在保存其數據後記錄了'ROLE_ADMIN'。 – Saadia

+0

你確定ROLE_ADMIN正在保存嗎?你可以添加formtype代碼嗎? – DevDonkey