Hola.
Necesito tomar algunas decisiones en mi aplicación respecto al usuario que se loguea.
Tengo este servicio:
login_listener: class: AppBundle\Listener\LoginListener arguments: [@security.authorization_checker, @security.token_storage, @router] tags: - { name: kernel.event_listener, event: security.interactive_login } - { name: kernel.event_listener, event: kernel.response }
Y esta es la clase LoginListener
:
<?php // src/AppBundle/Listener/LoginListener.php namespace AppBundle\Listener; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Routing\Router; class LoginListener { private $router, $ciudad = null; public function __construct(Router $router) { $this->router = $router; } public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { $token = $event->getAuthenticationToken(); } public function onKernelResponse(FilterResponseEvent $event) { if (...) { $event->setResponse(new RedirectResponse(...)); } } }
Debo hacer una serie de consultas a la base de datos (para lo cual pienso inyectar repositorios como servicios al servicio login_listener
).
Una vez obtenido esos valores debo guardarlos en variables de sesión (si hay otra forma de almacenamiento sería bueno saberlo) los cuales voy a usar durante todo el tiempo que el usuario se mantenga conectado.
Yo se que el objeto que guarda las sesiones es el Request
lo debo pasar como argumento al servicio y usarlo en el método onSecurityInteractiveLogin()
o al inyectar ese servicio debo agregar un nuevo método?
Muchas gracias por su ayuda.
Respuestas
En este caso no tienes que pasar el objeto que representa a la petición del usuario. El motivo es que la clase InteractiveLoginEvent
(como la mayoría de eventos propios que proporciona Symfony) ya incluye dentro el objeto $request
, por lo que puedes usarlo directamente así:
// src/AppBundle/Listener/LoginListener.php namespace AppBundle\Listener; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; class LoginListener { // ... public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { $session = $event->getRequest()->getSession(); $session->set('clave', 'valor'); } // ... }
@javiereguiluz
Grandioso.
Muchas gracias por tu respuesta.
Voy a hacer más ladybug_dump_die($event);
para ver qué hay por detrás.
Gracias.
@ramiroanacona
Hola Javier.
Tengo una duda mas, sobre buenas practicas.
Quiero hacer un servicio que le provee funcionalidad a la aplicación (no responde a ningún evento), en que directorio debo guardar la clase que responde a este servicio?
Gracias.
@ramiroanacona
La recomendación consiste en guardar los servicios en directorios con un nombre que los agrupe por funcionalidad: Mailer
, Checker
, etc. Si son servicios muy pequeños y no se te ocurre ningún nombre bueno, algunos programadores utilizan Utils
o Services
como nombre del directorio, pero no te aconsejo utilizar esos nombres porque son demasiado genéricos.
Una buena fuente de inspiración puede ser ver el código fuente de los mejores proyectos Symfony. Te indico a continuación tres referencias que consulto habitualmente para saber cómo organizan su código (entra dentro de los bundles de cada proyecto para ver cómo llaman a sus directorios y cómo organizan los servicios):
@javiereguiluz