我有一个表格,用户可以更改为自己的电子邮件。但是,当发生验证错误或某些因约束失败的会话死亡时,用户将被重定向到登录页面。重要的是要注意,用户是通过数据库中的用户和密码进行身份验证的。感谢您的帮助
更新
我刚刚添加了User.php文件以获取更多详细信息。
namespace App\Form;
class ChangeEmailType extends AbstractType
{
private $translator;
private $transformer;
public function __construct(TranslatorInterface $translator, DateTimeToStringTransformer $transformer)
{
$this->transformer = $transformer;
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', EmailType::class, array(
'required' => true,
'label' => $this->translator->trans('email'),
'attr' => array('class' => 'form-control')
))
->add('updationDate', HiddenType::class, array(
'required' => true,
'label' => false,
));
$builder->get('updationDate')->addModelTransformer($this>transformer);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\User',
'attr' => array('class' => 'change-email-form')
));
}
}
UserController.php
/**
* @Security("has_role('ROLE_USER')")
* @Route("/profile/change-email", name="change email")
*/
public function changeEmail(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(ChangeEmailType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
try
{
$this->entityManager->lock($this->getUser(), LockMode::OPTIMISTIC, $user->getUpdationDate());
$this->entityManager->flush();
$this->addFlash('success', $this->translator->trans('email_is_successfully_changed'));
return $this->redirectToRoute('dashboard');
}
catch (OptimisticLockException $exception)
{
$this->addFlash('success', $this->translator->trans('data_is_outdated_try_again'));
return $this->redirectToRoute('change email');
}
}
return $this->render('app/pages/profile/change-email.html.twig', array(
'form' => $form->createView()
));
}
User.php
namespace App\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\HasLifecycleCallbacks()
* @ORM\Table(name="users")
* @UniqueEntity(fields={"email"})
*/
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @Assert\Length(
* min = 6,
* minMessage = "Password should by at least 6 characters long",
* groups={"registration"}
* )
* @Assert\Type(
* type="alnum",
* message="Password should contains only numbers and letters",
* groups={"registration"}
* )
* @Assert\NotBlank()
* @ORM\Column(type="text", nullable=true)
*/
private $password;
/**
* @Assert\NotBlank(message="field_is_required")
* @Assert\Email(message="email_is_invalid")
* @ORM\Column(type="string", length=255, unique=true)
*/
private $email;
/**
* @ORM\Column(type="string", length=255)
*/
private $theme;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $facebookId;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $linkedinId;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $passwordRecoveryHash;
/**
* @ORM\Column(type="integer")
*/
private $status;
/**
* @ORM\Column(type="string", length=255)
*/
private $emailConfirmationHash;
/**
* @ORM\Column(type="datetime")
* @ORM\Version
*/
private $updationDate;
/**
* @ORM\Column(type="datetime")
*/
private $creationDate;
/**
* @ORM\PrePersist()
*/
public function prePersist(): void
{
$this->creationDate = new DateTime();
$this->theme = 'light';
$this->status = 0;
}
public function getRoles()
{
return ['ROLE_USER'];
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return 'salt';
}
public function getUsername()
{
return $this->email;
}
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
public function getId()
{
return $this->id;
}
public function setId($id): void
{
$this->id = $id;
}
public function setPassword($password): void
{
$this->password = $password;
}
public function getEmail()
{
return $this->email;
}
public function setEmail($email): void
{
$this->email = $email;
}
public function getUpdationDate()
{
return $this->updationDate;
}
public function setUpdationDate($updationDate): void
{
$this->updationDate = $updationDate;
}
public function getCreationDate()
{
return $this->creationDate;
}
public function setCreationDate($creationDate): void
{
$this->creationDate = $creationDate;
}
public function getTheme()
{
return $this->theme;
}
public function setTheme($theme): void
{
$this->theme = $theme;
}
public function getPasswordRecoveryHash()
{
return $this->passwordRecoveryHash;
}
public function setPasswordRecoveryHash($passwordRecoveryHash): void
{
$this->passwordRecoveryHash = $passwordRecoveryHash;
}
public function getFacebookId()
{
return $this->facebookId;
}
public function setFacebookId($facebookId): void
{
$this->facebookId = $facebookId;
}
public function getLinkedinId()
{
return $this->linkedinId;
}
public function setLinkedinId($linkedinId): void
{
$this->linkedinId = $linkedinId;
}
public function getEmailConfirmationHash()
{
return $this->emailConfirmationHash;
}
public function setEmailConfirmationHash($emailConfirmationHash): void
{
$this->emailConfirmationHash = $emailConfirmationHash;
}
public function getStatus()
{
return $this->status;
}
public function setStatus($status): void
{
$this->status = $status;
}
}
答案 0 :(得分:0)
所以我遇到了同样的问题,但是我通过不将对象User传递给formType来解决了它。 这是我的代码
$user = $this->getUser();
// don't pass pass $user as parameter
$form = $this->createForm(ChangeEmailType::class);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$em = $this->getDoctrine()->getManager();
$currentEmail = $user->getEmail();
$newEmail = $form->get('email')->getData();
$currentPassword = $form->get('currentPassword')->getData();
// verify if the tow emails are different
if ($currentEmail === $newEmail) {
$form->get('email')->addError(new FormError('You must choose a different email.'));
}
// verify if the email is used by another user
$userHasAlreadyThisEmail = $em->getRepository('App:User')->findOneBy(array('email' => $newEmail));
if ($userHasAlreadyThisEmail && $userHasAlreadyThisEmail !== $user) {
$form->get('email')->addError(new FormError('This email is already used.'));
}
// verify if the password is correct
$verify = $this->verify($currentPassword, $user->getPassword());
if ($verify === false) {
$form->get('currentPassword')->addError(new FormError('Incorrect password.'));
}
if ($form->isValid()) {
$this->addFlash('success', 'The email has been successfully modified.');
$user->setEmail($newEmail);
$em->flush();
return $this->redirectToRoute('profile_change_email');
}
}
public function verify($input, $existingHash)
{
$hash = password_verify($input, $existingHash);
return $hash === true;
}