Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony-用户即使在名称更改时也会注销_Php_Symfony - Fatal编程技术网

Php Symfony-用户即使在名称更改时也会注销

Php Symfony-用户即使在名称更改时也会注销,php,symfony,Php,Symfony,我面临着一个非常奇怪的情况,一个具有角色的用户在我更改名称后立即注销,即使我没有更改任何内容并按下保存按钮,它也会注销。如果我将用户在数据库中的角色直接更改为role\u user,则相同的代码工作正常,用户不会注销 以下是负责配置文件更新的控制器 /** * @Route("/profile", name="profile") */ public function profileAction(Request $request) {

我面临着一个非常奇怪的情况,一个具有
角色的用户在我更改名称后立即注销,即使我没有更改任何内容并按下保存按钮,它也会注销。如果我将用户在数据库中的角色直接更改为
role\u user
,则相同的代码工作正常,用户不会注销

以下是负责配置文件更新的控制器

    /**
     * @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);
            }

        }

    }
}

在这一点上,我真的不知道是什么原因导致了这一点,我将非常感谢这里的任何帮助…

您提供的内容中有很多错误。这些因素可能会导致你所看到的行为

安全规则

在security.yml中,您有以下行:

- { path: ^/admin/, roles: ROLE_ADMIN }
这意味着,如果用户访问此模式,任何不使用ROLE_ADMIN的用户都将返回登录屏幕

同时,在控制器中,您总是将用户引导回基于管理员的路由:

/*
 * @Route("admin/profile", name="admin_profile")
 */
这意味着,无论他们做什么,他们总是发送到一个管理模式。这意味着,如果他们改变角色,他们将被防火墙踢出

控制器

在控制器中,您将用户实体绑定到formtype,很好。但是,你编码的方式意味着你不了解它是如何工作的

调用
handleRequest
时,Symfony从表单中提取数据(如果已提交),并将其与传递给它的实体“合并”。这意味着您不必调用对象上的任何setter,因为所有这些都已经为您完成了

用户实体

您的
用户
实体上应该有一个
普通密码
字段和一个
密码
字段。该表单仅映射到
PlainPassword
字段。。然后,在控制器中,获取
PlainPassword
值,对其进行编码,将其设置为实体的
Password
字段,并确保清除
PlainPassword
值(您不想存储该值)。如果您已经在自定义用户实体上实现了
UserInterface
(您应该有),那么您应该有一个名为
eraseCredentials
的方法,这就是它的用途

这样做的结果是,当您检查某些东西(例如新密码)时,您只需执行以下操作:

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

}
我还建议您编写一个适当的
UserManager
类来处理这些事情。它将事情集中起来,使调试更容易


如果您使用的是我在示例中编写的内容,这也意味着当您想要更新用户信息时,您只需调用
$userManager->updateUser($user)
,它将为您完成所有繁琐的工作。

您提供的内容有很多错误。这些因素可能会导致你所看到的行为

安全规则

在security.yml中,您有以下行:

- { path: ^/admin/, roles: ROLE_ADMIN }
这意味着,如果用户访问此模式,任何不使用ROLE_ADMIN的用户都将返回登录屏幕

同时,在控制器中,您总是将用户引导回基于管理员的路由:

/*
 * @Route("admin/profile", name="admin_profile")
 */
这意味着,无论他们做什么,他们总是发送到一个管理模式。这意味着,如果他们改变角色,他们将被防火墙踢出

控制器

在控制器中,您将用户实体绑定到formtype,很好。但是,你编码的方式意味着你不了解它是如何工作的

调用
handleRequest
时,Symfony从表单中提取数据(如果已提交),并将其与传递给它的实体“合并”。这意味着您不必调用对象上的任何setter,因为所有这些都已经为您完成了

用户实体

您的
用户
实体上应该有一个
普通密码
字段和一个
密码
字段。该表单仅映射到
PlainPassword
字段。。然后,在控制器中,获取
PlainPassword
值,对其进行编码,将其设置为实体的
Password
字段,并确保清除
PlainPassword
值(您不想存储该值)。如果您已经在自定义用户实体上实现了
UserInterface
(您应该有),那么您应该有一个名为
eraseCredentials
的方法,这就是它的用途

这样做的结果是,当您检查某些东西(例如新密码)时,您只需执行以下操作:

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

}
我还建议您编写一个适当的
UserManager
类来处理这些事情。它将事情集中起来,使调试更容易


如果您使用了我在示例中编写的内容,这也意味着当您想要更新用户信息时,只需调用
$userManager->updateUser($user)
它将为您完成所有的繁琐工作。

关于
安全性。yml
是的,为了访问任何以
admin
开头的路径,您需要有
角色\u admin
,这样设置就可以了,我明白你对密码的看法,我会这样做,但你的建议并不能解决问题,假设我创建了一个配置文件路由,
ROLE\u USER
可以在控制器内部使用相同的代码进行访问,一切正常。只有这个
ROLE\u ADMIN
可以很好地更新它的配置文件,但是它会被注销。。。我不明白为什么它会被注销。我更新了我的问题,删除了里面的所有内容