Call a method after user Login

Hussein Nazzal picture Hussein Nazzal · Jun 12, 2013 · Viewed 9.2k times · Source

I was wondering if there is away to call a function after the user login.

Here is the code I want to call:

$point = $this->container->get('process_points');
$point->ProcessPoints(1 , $this->container);

Answer

Pier-Luc Gendreau picture Pier-Luc Gendreau · Jun 12, 2013

You can find the events FOSUserBundle fires in the FOSUserEvents class. More specifically, this is the one you are looking for:

/**
 * The SECURITY_IMPLICIT_LOGIN event occurs when the user is logged in programmatically.
 *
 * This event allows you to access the response which will be sent.
 * The event listener method receives a FOS\UserBundle\Event\UserEvent instance.
 */
const SECURITY_IMPLICIT_LOGIN = 'fos_user.security.implicit_login';

The documentation for hooking into those events can be found on the Hooking into the controllers doc page. In your case, you will need to implement something like this:

namespace Acme\UserBundle\EventListener;

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

/**
 * Listener responsible to change the redirection at the end of the password resetting
 */
class LoginListener implements EventSubscriberInterface
{
    private $container;

    public function __construct($container)
    {
        $this->container = $container;
    }

    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::SECURITY_IMPLICIT_LOGIN => 'onLogin',
            SecurityEvents::INTERACTIVE_LOGIN => 'onLogin',
        );
    }

    public function onLogin($event)
    {
        // FYI
        // if ($event instanceof UserEvent) {
        //    $user = $event->getUser();
        // }
        // if ($event instanceof InteractiveLoginEvent) {
        //    $user = $event->getAuthenticationToken()->getUser();
        // }

        $point = $this->container->get('process_points');
        $point->ProcessPoints(1 , $this->container);
    }
}

You should then define the listener as a service and inject the container. Alternatively, you could inject just the service you need instead of the whole container.

services:
    acme_user.login:
        class: Acme\UserBundle\EventListener\LoginListener
        arguments: [@container]
        tags:
            - { name: kernel.event_subscriber }

There is also another method which involves overriding the controller, but as noted in the documentation, you have to duplicate their code so it's not exactly clean and bound to break if (or rather, when) FOSUserBundle is changed.