我有一个简单的注册表单,有3个字段。电子邮件,姓名和密码。到现在为止还挺好。我能够创建新用户。当我想编辑用户信息时,问题出现了。
我想仅在html密码字段不为空时才更新数据库中的密码字段
public function editAction(User $user, Request $request)
{
$form = $this->createForm(new UserForm(), $user);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$this->redirectToRoute('bd_user_list');
}
return $this->render('BDUserBundle:User:add.html.twig', [
'form' => $form->createView()
]);
}
如果我将密码字段留空,我会收到此错误(这是正常的)
An exception occurred while executing 'UPDATE users SET password = ? WHERE id = ?' with params [null, 5]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'password' cannot be null
我已阅读过有关验证小组的信息,但我不确定他们是否可以提供帮助。
//解决方案
UserForm.php
[...]
builder->addEventSubscriber(new UserFormListener());
[...]
UserFormListener.php
<?php
namespace SDUserBundle\Form\EventListener;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserFormListener implements EventSubscriberInterface
{
private $password;
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::POST_SUBMIT => 'postSubmit'
);
}
public function preSetData(FormEvent $event)
{
$this->password = $event->getData()->getPassword();
}
public function postSubmit(FormEvent $event)
{
$data = $event->getData();
if ($data->getPassword() == false) {
$data->setPassword($this->password);
}
}
}
答案 0 :(得分:2)
修改您的代码,如下所示
public function editAction(User $user, Request $request)
{
$old_pwd = $user->getPassword(); //or whatever the method is called
$form = $this->createForm(new UserForm(), $user);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$em = $this->getDoctrine()->getManager();
if (null == $user->getPassword()) {
$user->setPassword($old_pwd);
}
$em->persist($user);
$em->flush();
$this->redirectToRoute('bd_user_list');
}
return $this->render('BDUserBundle:User:add.html.twig', [
'form' => $form->createView()
]);
}
这是第一个解决方案,但涉及控制器内部的一些逻辑;也许您需要在其他地方使用该代码,因此您可以将其迁移到FormEvents::PRE_SET_DATA
因此,您需要修改UserForm
,如下所示
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
[...]
class UserForm extends AbstractType
{
private $old_pwd;
[...]
$builder
[...]
->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
$data = $event->getData();
$this->old_pwd = $data->getPassword();
})
->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
$data = $event->getData();
if (false == $data->getPassword()) {
$data->setPassword($this->old_pwd);
$this->setData($data);
}
})
}
我真的不知道第二种方法是否有效,因为我现在无法对其进行测试,但FormEvents
可以帮助您完成所需的工作。
也许您可以直接修改用户设置器
class User
{
[...]
public function setPassword($pwd)
{
if ($pwd) {
$this->pwd = //logic here to store a safe pwd
}
}
}
为什么第三种解决方案是最糟糕的,我让你找到自己;)
只是为了让您知道isValid()
关注来自Symfony2.3的已提交控件,因此您不需要isSubmitted()
明确控制