Symfony2 - 如何在 CallbackValidator 中使用实体变量? [英] Symfony2 - How to use Entity variables in CallbackValidator?

查看:23
本文介绍了Symfony2 - 如何在 CallbackValidator 中使用实体变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用一些自定义验证器构建的表单,它们的工作原理非常棒,但我无法添加新的验证器,该验证器的工作原理与其他验证器略有不同.

I have a form built with some custom validators and they work like a charm, but I am having trouble adding in a new validator that works slightly different to the others.

基本上,我需要根据我通常可以从实体中提取的值来检查表单中的数据.

Basically I need to check data from the form against a value I can usually extract from an Entity.

在这种情况下,我需要获取用户密码 salt(使用 $user->getSalt() ).问题似乎是 CallbackValidator 类不能接受除 $form 之外的任何其他数据.

In this case, I need to grab the users password salt ( using $user->getSalt() ). the problem seems to be that the CallbackValidator class cannot accept any other data, other than $form.

我的代码:

    $user = $this->get('security.context')->getToken()->getUser();

    $form = $this->createFormBuilder($user)
            ->add('password', 'password')
            ->add('newPassword', 'password', array('label' => 'New Password', 'property_path' => false))
            ->add('confirmPassword', 'password', array('label' => 'Confirm Password', 'property_path' => false))
            ->addValidator(new CallbackValidator(function($form)
            {
                $encoder = new MessageDigestPasswordEncoder('sha1', false, 1);
                $password = $encoder->encodePassword($form['password']->getData(), $user->getSalt());

                if($password != $user->getPassword()) {
                    $form['password']->addError(new FormError('Incorrect password'));
                }
                if($form['confirmPassword']->getData() != $form['newPassword']->getData()) {
                    $form['confirmPassword']->addError(new FormError('Passwords must match.'));
                }
                if($form['newPassword']->getData() == '') {
                    $form['newPassword']->addError(new FormError('Password cannot be blank.'));
                }
            }))
            ->getForm();

现在,这是我得到的错误:

Now, this is the error I get:

Fatal error: Call to a member function getSalt() on a non-object in /Sites/src/UserBundle/Controller/DashboardController.php on line 57

第 57 行是:

$password = $encoder->encodePassword($form['password']->getData(), $user->getSalt());

我尝试了各种方法来尝试将盐传递给 CallbackValidator,到目前为止唯一的方法是将它作为隐藏字段添加到表单中,但这是不可接受的,因为它存在安全风险,我还需要添加散列密码作为隐藏字段以匹配输入.

I have tried various things to try and pass the salt to the CallbackValidator and so far the only way is to add it into the form as a hiddne field BUT this is not acceptable as it is a security risk and I would also need to add the hashed password as a hidden field in order to match the input against.

一定有更简单的方法来做到这一点吗?

There must be a simpler way to do this?

推荐答案

你的 $user 变量来自 $this->get('security.context')->getToken()->getUser(); 未定义在匿名函数的范围内.

Your $user variable coming from $this->get('security.context')->getToken()->getUser(); is not defined in the scope of the anonymous function.

与从父作用域(自动关闭)继承的 javascript 等语言相反,您需要明确要求 php 来执行此操作.use 关键字专门用于:http://php.net/manual/en/functions.anonymous.php

Contrary to languages like javascript that inherits from parent scope (automatic closure), you need to ask explicitly php to do it. The use keyword is especially made for that: http://php.net/manual/en/functions.anonymous.php

$user = new User;
function($form) use($user) { 

};

这里有一个更好的解释:) Javascript 闭包与 PHP 闭包,有什么区别?

Here is a better explanation :) Javascript closures vs PHP closures, what's the difference?

所以你应该做的就是像这样修改你的代码:

So all you should have to do is modify your code like that:

$user = $this->get('security.context')->getToken()->getUser();

$form = $this->createFormBuilder($user)
        ->add('password', 'password')
        ->add('newPassword', 'password', array('label' => 'New Password', 'property_path' => false))
        ->add('confirmPassword', 'password', array('label' => 'Confirm Password', 'property_path' => false))
        ->addValidator(new CallbackValidator(function($form) use($user)
        {
            $encoder = new MessageDigestPasswordEncoder('sha1', false, 1);
            $password = $encoder->encodePassword($form['password']->getData(), $user->getSalt());

            if($password != $user->getPassword()) {
                $form['password']->addError(new FormError('Incorrect password'));
            }
            if($form['confirmPassword']->getData() != $form['newPassword']->getData()) {
                $form['confirmPassword']->addError(new FormError('Passwords must match.'));
            }
            if($form['newPassword']->getData() == '') {
                $form['newPassword']->addError(new FormError('Password cannot be blank.'));
            }
        }))
        ->getForm();

这篇关于Symfony2 - 如何在 CallbackValidator 中使用实体变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆