2
votes

Nice to meet you.

I'm developping with Symfony 3.1.3 and I'm using the security system offered by the framework, no FOSUser neither Guard.

I have in my controller the typical function login:

public function loginAction(Request $request)
{
    // This works
    $authenticationUtils = $this->get('security.authentication_utils');

    // get the login error if there is one
    $error = $authenticationUtils->getLastAuthenticationError();

    // last username entered by the user
    $lastUsername = $authenticationUtils->getLastUsername();

    return $this->render(
        'security/loginForm_old.html.twig',
        array(
            // last username entered by the user
            'last_username' => $lastUsername,
            'error'         => $error,
        )
    );
}

And I want to check if the user has activated his account. In the entity User I have the isActive attribute set to false by default and only with the link into the registration email is setted to true.

I have been searching for this issue without results and I'm sure this is something very common, everybody wants to check if the user's email is a good one.

Thanks.

1

1 Answers

4
votes

Lets assume that you have an RegistrationController.php class where you store all code that manage about user's registration.

Create a function which sends email to user after registration:

public function sendConfirmationEmailMessage(User $user)
{

    $confirmationToken = $user->getConfirmationToken();
    $username = $user->getUsername();

    $subject = 'Account activation';
    $email = $user->getEmail();

    $renderedTemplate = $this->templating->render('AppBundle:Emails:registration.html.twig', array(
        'username' => $username,
        'confirmationToken' => $confirmationToken
    ));

    $message = \Swift_Message::newInstance()
            ->setSubject($subject)
            ->setFrom(MAILER_FROM)
            ->setReplyTo(MAILER_FROM)
            ->setTo($email)
            ->setBody($renderedTemplate, "text/html");

    $this->mailer->send($message);

}

Create a route associated with function which takes an generated token as argument, then search user by that token and activate if user exist:

/**
* @Route("user/activate/{token}")
*/
public function confirmAction(Request $request, $token)
{
    $em = $this->getDoctrine()->getManager();
    $repository = $em->getRepository('AppBundle:User');

    $user = $repository->findUserByConfirmationToken($token);

    if (!$user)
    {
        throw $this->createNotFoundException('We couldn\'t find an account for that confirmation token');
    }

    $user->setConfirmationToken(null);
    $user->setEnabled(true);

    $em->persist($user);
    $em->flush();

    return $this->redirectToRoute('user_registration_confirmed');
}

Then when you have a function which actually registers the user you call the sendConfirmationEmailMessage as shown below:

public function registerAction(Request $request)
{
    /* All the logic goes here: form validation, creating new user */
    /* $user is created user */
    sendConfirmationEmailMessage($user);
}

Anyway if isActive() function return false Symfony security system will prevent you from login. Your User entity should implement UserInterface.