Cómo almacenar el último acceso del usuario en DB

Estoy escribiendo una aplicación web usando Symfony2 y necesito registrar el último acceso de cada usuario que inicia sesión en la aplicación. Mi entidad tiene un last_access propiedad, escriba fecha y hora.

El código es fácil, solo necesito obtener la entidad del usuario actual y establecer el valor, pero no sé dónde tengo que poner ese código.

Estaba pensando en algo como esto:

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

ACTUALIZACIÓN

Resolví esto usando un detector de eventos.

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();
    }
}

}

También creé un servicio:

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

¡Gracias a todos!

preguntado el 21 de septiembre de 13 a las 12:09

Estaba pensando en algo como esto: $manager = $this->getDoctrine()->getManager(); $user= $this->get('security.context')->getToken()->getUser(); $user->setLastAccess(new \DateTime('now')); $manager->persist($user); $manager->flush(); -

¿Necesita sólo el tiempo, no qué acción? Un detector de eventos podría ser lo correcto. -

4 Respuestas

Puede hacerlo con servicios, al iniciar sesión se invoca el evento "security.interactive_login".

Entonces, si usa YML para servicios:

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 } 

Y la clase:

<?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();
            }
        }
    }
}

Respondido el 21 de Septiembre de 13 a las 22:09

He usado esta solución. Gracias por la ayuda - javi

En caso de que alguien quiera esto para una versión más nueva de Symfony, aquí está el código para eso. Algunas cosas han cambiado, a saber, ya no hay Solicitud, ahora usa RequestStack.

archivo services.yml

 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 }

Y la clase (tenga en cuenta que estoy usando AppBundle, no mi propio paquete personalizado.

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();
            }
        }
    }
}

Respondido 16 Feb 17, 19:02

Normalmente, guarda la información del usuario actual, como Id, nombre de usuario, etc., en las cookies o en la sesión. Simplemente llámelo y haga una consulta a la base de datos y agregue la fecha y hora actual en su columna en la base de datos.

P.ej

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

Respondido el 21 de Septiembre de 13 a las 12:09

En Symfony2 puedes usar la extensión de doctrina. proporciona Traducible, Sluggable, Tree-NestedSet, Timestampable, Loggable, Sortable similar a la funcionalidad.

https://github.com/l3pp4rd/DoctrineExtensions

Espero que esto ayude

Respondido el 21 de Septiembre de 13 a las 17:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.