src/EventSubscriber/LoginSubscriber.php line 24

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\Tracking;
  4. use App\Entity\User;
  5. use App\Service\GeolocationService;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  10. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  11. use Symfony\Component\Security\Http\SecurityEvents;
  12. class LoginSubscriber implements EventSubscriberInterface
  13. {
  14. public function __construct(
  15. private TokenStorageInterface $tokenStorage,
  16. private EntityManagerInterface $entityManager,
  17. private GeolocationService $geolocationService
  18. ) {
  19. }
  20. public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
  21. {
  22. $request = $event->getRequest();
  23. $ip = $request->getClientIp();
  24. if (!$ip) {
  25. throw new \Exception('Ip not found', Response::HTTP_NOT_FOUND);
  26. }
  27. /** @var ?User $user */
  28. $user = $this->tokenStorage->getToken()?->getUser();
  29. if (!$user) {
  30. throw new \Exception('User not found', Response::HTTP_NOT_FOUND);
  31. }
  32. $user->setLastKnowIp($ip);
  33. $user->setLastConnection(new \DateTime());
  34. if ($user->allowGeolocation()) {
  35. $data = $this->geolocationService->getIpLocation($ip);
  36. if (null !== $data) {
  37. $tracking = new Tracking();
  38. $tracking->setDate(new \DateTime());
  39. $tracking->setLatitude($data['latitude']);
  40. $tracking->setLongitude($data['longitude']);
  41. $tracking->setCity($data['city']);
  42. $tracking->setUser($user);
  43. $user->addTracking($tracking);
  44. $this->entityManager->persist($tracking);
  45. }
  46. }
  47. $this->entityManager->flush();
  48. }
  49. public static function getSubscribedEvents()
  50. {
  51. return [
  52. SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
  53. ];
  54. }
  55. }