我在理解Symfony的datattransformer中数据是如何处理的时候遇到了麻烦。
我有一个密码表单。只有一个领域。该字段属于User实体,必须在.yml
文件中定义约束。
Software'Bundle'Entity'User:
password:
- NotBlank: ~
- Length:
min: 6
max: 155
验证工作正常,正如预期的那样。当密码必须从字段自动编码时,问题就出现了。
$builder->add('password', 'password', [
'label' => 'word.password'
]);
$builder->get('password')
->addModelTransformer(new EncodePasswordTransformer());
和变压器本身:
class EncodePasswordTransformer implements DataTransformerInterface
{
public function transform($value)
{
return $value;
}
public function reverseTransform($value)
{
// encode password
return PasswordHash::createHash($value);
}
}
下面是结果:
表单应该包含6到155个字符,但$form->isValid()
总是为真,因为PasswordHash::createHash($value)
将密码编码为32个字符。我期待的是:
表单验证原始密码,如果超过6个字符然后转到$form->isValid()
true,然后在验证后对密码进行编码。
我知道我可以手动编码密码,而表单是有效的,而不使用DataTransformer
,但我希望有一个更优雅的方式。
我错了吗?
根据文件,你不能。
Symfony的表单库在内部使用验证器服务来在提交值之后验证底层对象。
所以你实际上不是在验证表单,而是下面的对象,它没有纯密码的"概念"。
一个不那么优雅的解决方案是在用户中包含一个纯密码字段,并且不保存。但是,您可能无法验证现有的用户对象(例如:在更新表单中),因为它们的纯密码字段将是null
。为了解决这个问题,您可以创建一个自定义验证器,仅在用户不是new时才检查$plainPassword
字段的有效性。你可以通过使用doctrine的UnitOfWork
或者检查用户的id
是否为null
来检查。
我建议你也看看FOSUserBundle
,它有(或曾经)一个类似的方法,以纯密码字段和可能有你正在寻找的。