Symfony Check if user exist in database
Solution 1
You shouldn't need to do this in the controller. This is basic entity validation and Symfony comes with built in constraints to handle this sort of thing.
Assuming you are using a User Entity similar to below in your Symfony application you need only apply a unique validation constraint to the user class and specify which properties you want to test against for uniqueness. This example will validate that the user is unique by email, and throw an exception if not.
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/** @UniqueEntity(
* fields={"email"},
* errorPath="email",
* message="It appears you have already registered with this email."
*)
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string $email
*
* @ORM\Column(name="email", type="string", length=255, unique=true)
* @Assert\Email()
*/
protected $email;
// ...
}
Pay notice to the @UniqueEntity("email")
annotation on the class and the use statements. Of course you'll need to adopt this logic to your user class.
// controller action
public function newAction(Request $request)
{
$invite = new Invite();
$form = $this->createForm(InviteType::class, $invite);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($invite);
$em->flush();
$this->get('app_mailer')->sendMailInscriptionMjml(
$invite, $this->getParameter('client_mail_to')
);
$this->get('session')->getFlashBag()
->add('success', 'Votre inscription à été pris en compte.');
return $this->redirect(
$this->generateUrl(
'invite_show', array(
'id' => $invite->getId()
)
)
);
}
}
return $this->render('@App/invite/new.html.twig', array(
'invite' => $invite,
'form' => $form->createView(),
));
}
For more on this:
https://symfony.com/doc/current/reference/constraints/UniqueEntity.html
Solution 2
// Pass in the entity manager to your form via options
// Do this before you call $this->createForm:
// $options['entityManager'] = $this->getDoctrine()->getManager();
// then call $form = $this->createForm(InviteType::class, $invite, $options);
// Inside your form type i.e. InviteType
$em = $options['entityManager'];
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
$user = $data['user']; // this needs to be whatever you called user in your form
$userRepo = $em->getRepository('User'); // this needs to be the location of your user repository
if ($userRepo->findOneBy(['user' => $user])) { // you need to pick a field that determines how you will search for the user via the repository
$form->addError(new FormError('User already exists'));
}
}
);
Related videos on Youtube
Admin
Updated on June 04, 2022Comments
-
Admin over 1 year
I am looking for a solution in my controller to check before sending a form if the user already exists in the database. Here is my action on which I would like to implement this.
/** * Creates a new invite entity. * * @Route("/inscription", name="invite_new") * @Method({"GET", "POST"}) */ public function newAction(Request $request) { $invite = new Invite(); $form = $this->createForm(InviteType::class, $invite); if ($request->isMethod('POST')) { $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($invite); $em->flush(); $this->get('app_mailer')->sendMailInscriptionMjml($invite, $this->getParameter('client_mail_to')); $this->get('session')->getFlashBag()->add('success', 'Votre inscription à été pris en compte.'); } else { $this->get('session')->getFlashBag()->add('error', 'Une erreur est survenue.'); } return $this->redirect($this->generateUrl('invite_show', array('id' => $invite->getId()))); } return $this->render('@App/invite/new.html.twig', array( 'invite' => $invite, 'form' => $form->createView(), )); }
Thank you for your help
-
Admin about 6 yearsI create my request directly in the controller or in the repository? thanks
-
wanderer0810 about 6 yearsYou would run it as an SQL statement.
-
Admin about 6 yearsI am trying to warn the user that he is already registered. Thanks
-
Robert Wade about 6 yearsyou can do that with this set up. It's what its for.
-
Robert Wade about 6 yearsIt validates that there are no other users with that email already in your database. Then throws the exception if it finds one. The point is, you don't have to write a query in your controller to do this. I've updated the annotation to show you can even include your own custom error message if you want.
-
Admin about 6 yearsThank you but I have nothing that appears in message on screen. I have to add something to my controller? Thank you
-
Robert Wade about 6 yearsit's hard for me to say without seeing your complete set up. This example assumes you have an "email" property on your Invite entity class, that you've set up the annotations correctly and are rendering your form properly in twig. Are you seeing an exception in your profiler?
-
Admin about 6 yearsI put my controller on top and here is my twig
-
Robert Wade about 6 yearsit's best if you edit your original question and not keep posting changes to it as answers :) Have you added the validation constraint to your Invite entity? And the use statements? are you seeing errors in your profiler?
-
Admin about 6 yearsYes it's true forgive me. Yes I have added what you told me but I have no error in return except that it goes into the else of my controller.
-
Robert Wade about 6 yearsyou should be able to get rid of that else. You don't need the flash bag for your error since you've defined it in your constraint. Are your errors bubbling? Again, I'll ask do you see the exception in your profiler??
-
Robert Wade about 6 yearsI made an edit to your controller (in my answer above). You had your return statement which redirected to the invite_show route outside of your isValid method. Therefore it would go to invite_show wether it was valid or not. You only want to go to that if it is valid, otherwise you stay with new.html.twig and are shown the exception. Also get rid of that pre submit event handler if you haven't already.
-
Admin about 6 yearsThank you it works however you can display it elsewhere than below the email input? like a flashbag.
-
Robert Wade about 6 yearsYes you can specify where to point the error in the annotation or you can set error bubbling in your form so that the exception bubbles. If you do that make sure you have ((form_errors(form)}} in your template. Read up on validation constraints and forms in the Symfony cookbook.