Symfony2 - 如何在 CallbackValidator 中使用实体变量? [英] Symfony2 - How to use Entity variables in 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屋!