Completed
Push — master ( f785fb...b21f25 )
by Rafał
09:51
created

AnalyticsEventHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SWP\Bundle\CoreBundle\MessageHandler;
6
7
use Doctrine\Common\Persistence\ObjectManager;
8
use SWP\Bundle\AnalyticsBundle\Messenger\AnalyticsEvent;
9
use SWP\Bundle\AnalyticsBundle\Model\ArticleEventInterface;
10
use SWP\Bundle\AnalyticsBundle\Services\ArticleStatisticsServiceInterface;
11
use SWP\Bundle\CoreBundle\Model\ArticleStatistics;
12
use SWP\Component\MultiTenancy\Context\TenantContextInterface;
13
use SWP\Component\MultiTenancy\Resolver\TenantResolver;
14
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
15
16
class AnalyticsEventHandler implements MessageHandlerInterface
17
{
18
    /** @var ArticleStatisticsServiceInterface */
19
    private $articleStatisticsService;
20
21
    /** @var TenantResolver */
22
    private $tenantResolver;
23
24
    /** @var TenantContextInterface */
25
    private $tenantContext;
26
27
    /** @var ObjectManager */
28
    private $articleStatisticsObjectManager;
29
30
    public function __construct(
31
        ArticleStatisticsServiceInterface $articleStatisticsService,
32
        TenantResolver $tenantResolver,
33
        TenantContextInterface $tenantContext,
34
        ObjectManager $articleStatisticsObjectManager
35
    ) {
36
        $this->articleStatisticsService = $articleStatisticsService;
37
        $this->tenantResolver = $tenantResolver;
38
        $this->tenantContext = $tenantContext;
39
        $this->articleStatisticsObjectManager = $articleStatisticsObjectManager;
40
    }
41
42
    public function __invoke(AnalyticsEvent $analyticsEvent)
43
    {
44
        $this->setTenant($analyticsEvent->getHttpReferrer());
45
46
        $articleId = $analyticsEvent->getArticleId();
47
        $this->handleArticlePageViews($articleId, $analyticsEvent->getPageViewReferrer());
48
    }
49
50
    private function handleArticlePageViews(int $articleId, ?string $pageViewReferrer): void
51
    {
52
        if (0 !== $articleId) {
53
            $articleStatistics = $this->articleStatisticsService->addArticleEvent($articleId, ArticleEventInterface::ACTION_PAGEVIEW, [
54
                'pageViewSource' => $this->getPageViewSource($pageViewReferrer),
55
            ]);
56
57
            $query = $this->articleStatisticsObjectManager->createQuery('UPDATE '.ArticleStatistics::class.' s SET s.pageViewsNumber = s.pageViewsNumber + 1 WHERE s.id = :id');
58
            $query->setParameter('id', $articleStatistics->getId());
59
            $query->execute();
60
        }
61
    }
62
63
    private function getPageViewSource(?string $pageViewReferer): string
64
    {
65
        if (null !== $pageViewReferer) {
66
            $refererHost = $this->getFragmentFromUrl($pageViewReferer, 'host');
67
            if ($refererHost && $this->isHostMatchingTenant($refererHost)) {
68
                return ArticleEventInterface::PAGEVIEW_SOURCE_INTERNAL;
69
            }
70
        }
71
72
        return ArticleEventInterface::PAGEVIEW_SOURCE_EXTERNAL;
73
    }
74
75
    private function getFragmentFromUrl(string $url, string $fragment): ?string
76
    {
77
        $fragments = \parse_url($url);
78
        if (!\array_key_exists($fragment, $fragments)) {
79
            return null;
80
        }
81
82
        return $fragments[$fragment];
83
    }
84
85
    private function isHostMatchingTenant(string $host): bool
86
    {
87
        $tenant = $this->tenantContext->getTenant();
88
        $tenantHost = $tenant->getDomainName();
89
        if (null !== ($subdomain = $tenant->getSubdomain())) {
90
            $tenantHost = $subdomain.'.'.$tenantHost;
91
        }
92
93
        return $host === $tenantHost;
94
    }
95
96
    private function setTenant(string $httpReferrer): void
97
    {
98
        $tenant = $this->tenantResolver->resolve($httpReferrer);
99
        $this->tenantContext->setTenant($tenant);
100
    }
101
}
102