Symfony 4,编辑用户实体并保存新密码
Symfony 4, edit user entity and save new password
我执行了 make:crud
命令来为实体用户生成一些文件。
一切都很顺利,但我在编辑用户时遇到了一个问题。
当我编辑用户时,我可以:
- 更改密码并保存
或
- 不要修改密码并保存
来自生成的用户 'edit' 控制器:
/**
* @Route("/{id}/edit", name="user_edit", methods={"GET","POST"})
*/
public function edit(Request $request, User $user): Response
{
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// HERE : How can I check if the password was changed ?
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('user_index', [
'id' => $user->getId(),
]);
}
return $this->render('user/edit.html.twig', [
'user' => $user,
'form' => $form->createView(),
'title' => 'edit userr'
]);
}
如何检查密码是否已更改?用户变量包含新密码值...
如果密码是新的,我必须使用编码器服务。如果没有,我只需要用新数据更新用户
为此,在您的用户中有一个未写入数据库的 class 变量会有所帮助。然后,在您的表单中,您可以使用此变量临时存储更新后的密码,然后对其进行编码和删除。这就是用户界面中的 eraseCredentials()
方法的用途。
例如在你的用户中你可以
class User implements UserInterface
{
private $plainPassword;
// ...
public function setPlainPassword(string $plainPassword)
{
$this->plainPassword = $plainPassword;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function eraseCredentials()
{
$this->plainPassword = null;
}
}
注意 private $plainPassword
没有任何 ORM 注释,这意味着它不会存储在数据库中。但是,您可以使用验证约束,例如如果您想确保密码具有最小长度或一定的复杂性。您仍然需要存储加密密码的原始密码字段。
然后您将此字段添加到您的用户更新表单,而不是实际的密码字段。在您的控制器中,您只能检查新的 plainPassword-field 是否已填写,然后读取该值,对其进行编码并替换实际的密码字段。
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->getData();
if ($user->getPlainPassword() !== null) {
$user->setPassword($this->userPasswordEncoder->encode(
$user->getPlainPassword(),
$user
);
}
// ...
不向用户添加此 "helper"-属性 的另一种方法是使用未映射的表单字段:
# UserForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('plainPassword', PasswordType::class, ['mapped' => false])
;
}
控制器看起来很相似,只是您从未映射的字段而不是从用户那里获取数据:
$form->get('plainPassword')->getData();
我执行了 make:crud
命令来为实体用户生成一些文件。
一切都很顺利,但我在编辑用户时遇到了一个问题。 当我编辑用户时,我可以:
- 更改密码并保存
或
- 不要修改密码并保存
来自生成的用户 'edit' 控制器:
/**
* @Route("/{id}/edit", name="user_edit", methods={"GET","POST"})
*/
public function edit(Request $request, User $user): Response
{
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// HERE : How can I check if the password was changed ?
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('user_index', [
'id' => $user->getId(),
]);
}
return $this->render('user/edit.html.twig', [
'user' => $user,
'form' => $form->createView(),
'title' => 'edit userr'
]);
}
如何检查密码是否已更改?用户变量包含新密码值...
如果密码是新的,我必须使用编码器服务。如果没有,我只需要用新数据更新用户
为此,在您的用户中有一个未写入数据库的 class 变量会有所帮助。然后,在您的表单中,您可以使用此变量临时存储更新后的密码,然后对其进行编码和删除。这就是用户界面中的 eraseCredentials()
方法的用途。
例如在你的用户中你可以
class User implements UserInterface
{
private $plainPassword;
// ...
public function setPlainPassword(string $plainPassword)
{
$this->plainPassword = $plainPassword;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function eraseCredentials()
{
$this->plainPassword = null;
}
}
注意 private $plainPassword
没有任何 ORM 注释,这意味着它不会存储在数据库中。但是,您可以使用验证约束,例如如果您想确保密码具有最小长度或一定的复杂性。您仍然需要存储加密密码的原始密码字段。
然后您将此字段添加到您的用户更新表单,而不是实际的密码字段。在您的控制器中,您只能检查新的 plainPassword-field 是否已填写,然后读取该值,对其进行编码并替换实际的密码字段。
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->getData();
if ($user->getPlainPassword() !== null) {
$user->setPassword($this->userPasswordEncoder->encode(
$user->getPlainPassword(),
$user
);
}
// ...
不向用户添加此 "helper"-属性 的另一种方法是使用未映射的表单字段:
# UserForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('plainPassword', PasswordType::class, ['mapped' => false])
;
}
控制器看起来很相似,只是您从未映射的字段而不是从用户那里获取数据:
$form->get('plainPassword')->getData();