Reputation: 62
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
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
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
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