简体   繁体   English

$ form-> isValid()之后的Symfony数据转换器

[英]Symfony data transformer after $form->isValid()

I ran into a trouble of understanding how exactly data is processed in DataTransformers of Symfony . 我在理解Symfony的 DataTransformers中如何正确处理数据时遇到麻烦。

I have a just a password form. 我只有一个密码表。 Just one field. 只是一个领域。 This field belongs to the User entity which has to constraints defined in .yml file. 该字段属于User实体,该实体具有.yml文件中定义的约束。

Software\Bundle\Entity\User:
    password:
        - NotBlank: ~
        - Length:
            min: 6
            max: 155

The validation works fine, as supposed to. 验证工作正常,如预期的那样。 The problem arise when password must be encoded automatically from the field. 当必须从现场自动对密码进行编码时,就会出现问题。 So, 所以,

    $builder->add('password', 'password', [
        'label' => 'word.password'
    ]);

    $builder->get('password')
        ->addModelTransformer(new EncodePasswordTransformer());

And the transformer itself: 变压器本身:

class EncodePasswordTransformer implements DataTransformerInterface
{
    public function transform($value)
    {
        return $value;
    }

    public function reverseTransform($value)
    {
        // encode password
        return PasswordHash::createHash($value);
    }
}

So here's what's happening: 所以这是正在发生的事情:

The form should contain 6 to 155 characters but $form->isValid() is always true, because the PasswordHash::createHash($value) encodes the password to 32 characters. 表单应包含6到155个字符,但是$form->isValid()始终为true,因为PasswordHash::createHash($value)将密码编码为32个字符。 What I was expecting is: 我期望的是:

Form validates raw password, if more than 6 chars then go to $form->isValid() true and then encode the password after it's validated. Form会验证原始密码,如果超过6个字符,则转到$form->isValid() true,然后在验证后对密码进行编码。

I know I can just encode the password manually while the form is valid without using DataTransformer but I was hoping for a bit more elegant way. 我知道我可以在表单有效时手动编码密码,而无需使用DataTransformer但我希望有一种更优雅的方法。

Am I wrong? 我错了吗?

You can't, according to the documents . 根据文件 ,您不能。

Symfony's form library uses the validator service internally to validate the underlying object after values have been submitted. Symfony的表单库在提交值之后在内部使用验证器服务来验证基础对象。

So you're not actually validating form, but the object underneath which has no "notion" of the plain password. 因此,您实际上不是在验证表单,而是在其下的对象验证普通密码的“概念”。
A not so elegant solution would be to include a plain password field on your user and not persist it. 一个不太好的解决方案是在用户上包含一个普通密码字段, 而不保留它。 However you probably won't be able to validate your existing user objects (eg: in an update form), since their plain password fields will be null . 但是,您可能无法验证现有用户对象(例如,以更新形式),因为它们的普通密码字段将为null To get around that you could create a custom validator that checks the validity of the $plainPassword field only if the user is not new . 为了解决这个问题,您可以创建一个自定义验证器,该验证器仅在用户不是new时才检查$plainPassword字段的有效性。 You could check that by using doctrine's UnitOfWork or by checking if the id of the user is null . 您可以通过使用教义的UnitOfWork或通过检查用户的id是否为null来进行检查。
I suggest you also take a look at FOSUserBundle it has (or had) a similar approach to the plain password field and might have what you're looking for. 我建议您还看看FOSUserBundle它对普通密码字段具有(或具有类似的方法)并且可能具有所需的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM