<?php
namespace App\EventSubscriber;
use App\Entity\Tracking;
use App\Entity\User;
use App\Service\GeolocationService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class LoginSubscriber implements EventSubscriberInterface
{
public function __construct(
private TokenStorageInterface $tokenStorage,
private EntityManagerInterface $entityManager,
private GeolocationService $geolocationService
) {
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
{
$request = $event->getRequest();
$ip = $request->getClientIp();
if (!$ip) {
throw new \Exception('Ip not found', Response::HTTP_NOT_FOUND);
}
/** @var ?User $user */
$user = $this->tokenStorage->getToken()?->getUser();
if (!$user) {
throw new \Exception('User not found', Response::HTTP_NOT_FOUND);
}
$user->setLastKnowIp($ip);
$user->setLastConnection(new \DateTime());
if ($user->allowGeolocation()) {
$data = $this->geolocationService->getIpLocation($ip);
if (null !== $data) {
$tracking = new Tracking();
$tracking->setDate(new \DateTime());
$tracking->setLatitude($data['latitude']);
$tracking->setLongitude($data['longitude']);
$tracking->setCity($data['city']);
$tracking->setUser($user);
$user->addTracking($tracking);
$this->entityManager->persist($tracking);
}
}
$this->entityManager->flush();
}
public static function getSubscribedEvents()
{
return [
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
];
}
}