Я столкнулся с проблемой понимания того, как именно данные обрабатываются в DataTransformers из Symfony.
У меня есть просто форма пароля. Всего одно поле. Это поле принадлежит сущности пользователя, которая имеет ограничения, определенные в .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()
истина, а затем закодировать пароль после его проверки.
Я знаю, что могу просто закодировать пароль вручную, пока форма действительна без использования DataTransformer
но я надеялся на более элегантный способ.
Я ошибся?
Вы не можете, согласно документы.
Библиотека форм Symfony использует службу валидатора для проверки базового объекта после отправки значений.
Таким образом, вы на самом деле не проверяете форму, но объект под которым не имеет «понятия» простого пароля.
Не очень элегантным решением было бы включить поле простого пароля для вашего пользователя и не настаивать Это. Однако вы, вероятно, не сможете проверить существующие пользовательские объекты (например, в форме обновления), поскольку их поля с обычным паролем будут null
, Чтобы обойти это, вы можете создать собственный валидатор, который проверяет действительность $plainPassword
поле, только если пользователь не новый. Вы можете проверить это с помощью доктрины UnitOfWork
или проверив, если id
пользователя null
,
Я предлагаю вам также взглянуть на FOSUserBundle
он имеет (или имел) подобный подход к простому полю пароля и может быть есть то, что вы ищете.
Других решений пока нет …