I would like my users to be able to delete their own user account. I made a SecurityController
where there is my 3 functions login
, logout
and deleteUser
. When I delete the current user in database this error appears :
You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine.
When I delete another user, it works correctly because he's not connected. Do I have to serialize the User and pass it through a Service, logout the user then remove it in a Service? Or can I clear the PHP session in the controller but I don't know how to do it with symfony4 I think it changed since version 4.
<?php
namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use App\Entity\User;
use App\Form\UserType;
class SecurityController extends Controller
{
/**
* @Route("/createAdmin", name="create_admin")
*/
public function createAdminUser(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
$user = new User();
$form = $this->createForm(UserType::class, $user, array(
'is_fresh_install' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Encode the password
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
// save the User
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
// Do what you want here before redirecting the user
return $this->redirectToRoute('login');
}
return $this->render('security/register_admin_user.html.twig', array(
'form' => $form->createView(),
));
} else {
if ($this->getUser())
{
return $this->redirectToRoute('user_account');
} else {
return $this->redirectToRoute('login');
}
}
}
/**
* @Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $authUtils)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
return $this->redirectToRoute('create_admin');
} else {
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('security/login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
));
}
}
/**
* @Route("/logout", name="logout")
*/
public function logout()
{
}
/**
* @Route("/delete_user/{id}", name="delete_user")
*/
public function deleteUser($id)
{
$em = $this->getDoctrine()->getManager();
$usrRepo = $em->getRepository(User::class);
$user = $usrRepo->find($id);
$em->remove($user);
$em->flush();
return $this->redirectToRoute('user_registration');
}
}
SOLUTION :
You have to clear the Session before deleting user entry in DB with this method:
<?php
use Symfony\Component\HttpFoundation\Session\Session;
// In your deleteUser function...
$currentUserId = $this->getUser()->getId();
if ($currentUserId == $id)
{
$session = $this->get('session');
$session = new Session();
$session->invalidate();
}
I don't know why $this->get('session')->invalidate();
doesn't work directly... if someone knows :)
I find it also a good solution to do this what is an accepted answer but you can also simply redirect the user to the logout route. This has worked for me without any problem in Symfony 4.4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With