*/ class AnalyticListener { protected DeviceDetector $deviceDetector; protected Request $request; protected Node $node; public function __construct( protected NodeRepository $nodeRepository, protected ViewRepositoryQuery $viewRepositoryQuery, protected ViewFactory $viewFactory, protected RefererRepositoryQuery $refererRepositoryQuery, protected RefererFactory $refererFactory, protected EntityManager $manager ) { $this->createDeviceDetector(); } public function onKernelRequest(RequestEvent $event) { $request = $event->getRequest(); if (!$request->attributes->has('_node')) { return; } $this->deviceDetector->setUserAgent((string) $request->headers->get('user-agent')); $this->deviceDetector->parse(); if ($this->deviceDetector->isBot()) { return; } $node = $this->nodeRepository->findOneBy([ 'id' => $request->attributes->get('_node'), 'enableAnalytics' => true, ]); if (!$node) { return; } $this->node = $node; $this->request = $request; $this->createView(); $this->createReferer(); } protected function createDeviceDetector() { $cache = new ApcuAdapter(); $this->deviceDetector = new DeviceDetector(); $this->deviceDetector->setCache(new PSR6Bridge($cache)); } protected function createView() { $entity = $this->viewRepositoryQuery->create() ->filterByRequest($this->request) ->andWhere('.date=CURRENT_DATE()') ->findOne() ; if (!$entity) { $entity = $this->viewFactory->create($this->node, $this->request->getPathInfo()); } $entity->addView(); if ($this->deviceDetector->isDesktop()) { $entity->addDesktopView(); } elseif ($this->deviceDetector->isMobile()) { $entity->addMobileView(); } $this->save($entity); } protected function createReferer() { if (!$this->request->headers->has('referer')) { return; } $referer = $this->request->headers->get('referer'); if (!filter_var($referer, FILTER_VALIDATE_URL)) { return; } if (!in_array(parse_url($referer, PHP_URL_SCHEME), ['http', 'https'])) { return; } $entity = $this->refererRepositoryQuery->create() ->filterByRequest($this->request) ->andWhere('.date=CURRENT_DATE()') ->findOne() ; if (!$entity) { $entity = $this->refererFactory->create($this->node, $referer); } $entity->addView(); $this->save($entity); } protected function save(EntityInterface $entity) { if ($entity->getId()) { $this->manager->update($entity); } else { $this->manager->create($entity); } } }