Javi
Javi

Reputation: 62

How to store user last access in DB

I'm writing a Web App using Symfony2 and I need to register the last access of every user who log in to the app. My entity has a last_access property, type datetime.

The code is easy, I just need to get the entity of the current user and set the value, but I don't know where I have to put that code.

I was thinking in something like this:

$manager = $this->getDoctrine()->getManager();
$user= $this->get('security.context')->getToken()->getUser();
$user->setLastAccess(new \DateTime('now'));
$manager->persist($user);
$manager->flush();

##UPDATE##

I solved this using an event listener.

class LoginListener
{
    /**
     * @var Doctrine\Bundle\DoctrineBundle\Registry
     */
    private $doctrine;

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

    public function onInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();

        if ($user) {
            $user->setLastAccess(new \DateTime('now'));
            $this->doctrine->getEntityManager()->persist($user);
            $this->doctrine->getEntityManager()->flush();
        }
    }
}

Also I created a service:

services:
    my.service:
        class: SGRH\AdminBundle\Listener\LoginListener
        arguments: [@doctrine]
        tags:
           - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }

Thanks to everyone!

Upvotes: 2

Views: 1680

Answers (3)

Stan Alachniewicz
Stan Alachniewicz

Reputation: 402

Just in case anyone wants this for newer version of symfony, here is the code for that. A few things have changed, namely, there is no more Request, now you use RequestStack.

services.yml file

 app.security.interactive_login_listener:
      class: AppBundle\Security\InteractiveLoginListener
      arguments: ["@doctrine.orm.entity_manager", "@request_stack" ]
      scope: request
      tags:
        - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

And the class (note that I am using AppBundle not my own custom bundle.

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

use Doctrine\ORM\EntityManager;
use AppBundle\Entity\User;

class InteractiveLoginListener {

    protected $em;
    protected $request;

    public function __construct(EntityManager $em, RequestStack $request) {

        $this->em = $em;
        $this->request = $request;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {

        $user = $event->getAuthenticationToken()->getUser();

        if ($user instanceof User) {
            if($this->request->getCurrentRequest()->hasSession()) {
                $user->setLast_Login(new \DateTime('now'));
                $this->em->persist($user);
                $this->em->flush();
            }
        }
    }
}

Upvotes: 2

M. Foti
M. Foti

Reputation: 3182

You can do it with services, at logon the event "security.interactive_login" is invoked.

So if you use YML for services:

your_user_bundle.security.interactive_login_listener:
    class: ACME\YourBundle\Listener\InteractiveLoginListener
    arguments: [ "@doctrine.orm.entity_manager", "@request" ]
    scope: request
    tags:
      - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin } 

And the class:

<?php

namespace ACME\YourBundle\Listener;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

use Doctrine\ORM\EntityManager;
use ACME\YourBundle\Entity\User;

class InteractiveLoginListener {

    protected $em;
    protected $request;

    public function __construct(EntityManager $em, Request $request) {

        $this->em = $em;
        $this->request = $request;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {

        $user = $event->getAuthenticationToken()->getUser();

        if ($user instanceof User) {
            if($this->request->hasSession()) {
                $user->setLastAccess(new \DateTime('now'));
                $this->em->persist($user);
                $this->em->flush();
            }
        }
    }
}

Upvotes: 2

Marcia Ong
Marcia Ong

Reputation: 781

Normally you save the Current user information like Id,Username..etc in the cookies or session. Just call it out and do a query to the database and add the current datetime into it's column in the database.

E.g

Update Last_session = 'Current datetime'
Where UserID = 'UserID gotten form cookie/session'
From db.user;

Upvotes: -1

Related Questions