<?php
namespace App\EventSubscriber;
use App\Entity\User;
use App\Entity\UserInterface;
use App\Event\ObjectEvent;
use App\Events;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Tracking information used for marketing.
*/
class TrackingInfoSubscriber implements EventSubscriberInterface
{
public const SESSION_NAME = 'app_tracking_info';
/** @var RequestStack */
private $requestStack;
/** @var ManagerRegistry */
private $managerRegistry;
/**
* @param RequestStack $requestStack
* @param ManagerRegistry $managerRegistry
*/
public function __construct(RequestStack $requestStack, ManagerRegistry $managerRegistry)
{
$this->requestStack = $requestStack;
$this->managerRegistry = $managerRegistry;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => 'onKernelRequest',
Events::USER_CREATED => 'onUserCreated',
];
}
/**
* @param RequestEvent $event
*/
public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
if ($request->isXmlHttpRequest()) {
return;
}
$session = $request->getSession();
if ($session->has(self::SESSION_NAME)) {
return;
}
$trackingInfo = [
'referer' => $request->headers->get('Referer'),
'ipAddress' => $request->getClientIp(),
'userAgent' => $request->headers->get('User-Agent'),
];
// Loop through all query parameters and add those starting with "utm_"
foreach ($request->query->all() as $key => $value) {
if (0 === strpos($key, 'utm_')) {
$trackingInfo[$key] = $value;
}
}
// Ignore requests from referrers with the same HTTP host
if (null !== $trackingInfo['referer'] && 0 === stripos($trackingInfo['referer'], $request->getSchemeAndHttpHost())) {
return;
}
$filteredTrackingInfo = array_filter($trackingInfo);
$session->set(self::SESSION_NAME, $filteredTrackingInfo);
}
/**
* @param ObjectEvent $event
*/
public function onUserCreated(ObjectEvent $event): void
{
try {
/** @var SessionInterface $session */
$session = $this->requestStack->getSession();
} catch (SessionNotFoundException $e) {
return;
}
if (!$session->has(self::SESSION_NAME)) {
return;
}
$entity = $event->getObject();
$trackingInfo = $session->get(self::SESSION_NAME);
if ($entity instanceof UserInterface && !empty($trackingInfo)) {
$entity->setTrackingInfo($trackingInfo);
$this->managerRegistry
->getRepository(User::class)
->update($entity);
}
$session->remove(self::SESSION_NAME);
}
}