【发布时间】:2014-09-09 12:00:28
【问题描述】:
我正在 Symfony 2 中构建一个 Web 应用程序,其中我有一个 User 实体类来保存注册用户。
当然,每个用户至少应该有一个用户名和一个密码,因此,我对实体中的两个字段都使用@Assert\NotBlank 验证规则。用户名是静态的,但是,能够更改密码是可取的。
因此,我正在构建一个表单,登录用户可以在其中更改密码(除其他外)。此表单使用 Symfony 中的重复字段类型来确认密码。
现在,在大多数情况下,我猜用户并不想更改密码,而是更新个人资料中的其他字段。因此,我希望他们可以将密码字段留空。但是,这会干扰NotBlank 验证规则。
删除NotBlank 验证规则当然是一种选择。虽然,这几乎不是我正在寻找的解决方案,因为这会导致用户最终获得空白密码的问题。
最后,据我了解,symfony Request 对象在提交表单时将表单数据自动填充回用户实体。
现在,我的问题是:有什么方法可以在密码字段为空的情况下,让 Symfony 使用数据库中的现有密码而不是空白值重新填充用户实体?这将允许验证进行,并且不会在保存时对密码进行任何不希望的更改。
这是实体中密码字段的代码
/**
* @var string
*
* @ORM\Column(name="password",type="string",length=255)
* @Assert\NotBlank()
* @Assert\Type(type="string")
* @Assert\Length(max="255")
* @Assert\NotEqualTo(value="password")
*/
private $password;
这是生成表单的代码
private function initForm($user) {
return $this->createFormBuilder($user)
->add('name', 'text')
->add('mail', 'email')
->add('password', 'repeated', [
'type' => 'password',
'invalid_message' => 'The password fields must match.',
'first_options' => ['label' => false],
'second_options' => ['label' => false] //set to false to hide label in view
])
->add('save', 'submit')->getForm();
}
这是/profile/edit 页面的操作代码:
/**
* @ParamConverter("user",class="MyBundle:User")
*/
public function editAction(User $user, Request $request) {
$form = $this->initForm($user);
$form->handleRequest($request);
if ($form->isValid()) {
//update to database and redirect user back to profile_view
$this->getDoctrine()->getManager()->flush();
return $this->redirect($this->generateUrl('profile_view'));
}
return $this->render('MyBundle:User:edit.html.twig',
array('form' => $form->createView()));
}
提前感谢您的帮助!
编辑
我确实尝试过“显而易见”的方法,即将原始密码临时存储在一个变量中,如果在提交表单后它是空白的,则将其“放回”:
/**
* @ParamConverter("user",
class="MyBundle:User")
*/
public function editAction(User $user, Request $request) {
$password = $user->getPassword();
$form = $this->initForm($user)->getForm();
$form->handleRequest($request);
if ( $user->getPassword() == NULL ) {
$user->setPassword($password);
$form = $this->initForm($user)->getForm(); //this is the problem
}
if ( $form->isValid() ) {
//update to database and redirect user back to profile view
$this->getDoctrine()->getManager()->flush();
return $this->redirect($this->generateUrl('profile_view'));
}
return $this->render('MyBundle:User:edit.html.twig',
array('form' => $form->createView()));
}
但是,由于明显的原因,这并没有奏效。当表单在 if 语句中重新初始化时,Symfony 发现表单从未被提交过,即没有执行验证。添加$form->handleRequest($request) 让我们回到第一个问题,即密码字段可能为空白。
不过,我确实觉得很奇怪。 Symfony 验证实体而不是表单。但是删除问题行$form->initForm($user)->getForm() 仍然无效,尽管实体应该是有效的。
【问题讨论】:
标签: php forms validation symfony