Completed
Push — master ( 857129...3b32ca )
by Rafał
10:38
created

AnalyticsEventHandler::getPageViewSource()   A

Complexity

Conditions 4
Paths 3

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 4
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SWP\Bundle\CoreBundle\MessageHandler;
6
7
use Doctrine\Common\Persistence\ObjectManager;
8
use FOS\ElasticaBundle\Persister\PersisterRegistry;
9
use SWP\Bundle\AnalyticsBundle\Messenger\AnalyticsEvent;
10
use SWP\Bundle\AnalyticsBundle\Model\ArticleEventInterface;
11
use SWP\Bundle\AnalyticsBundle\Services\ArticleStatisticsServiceInterface;
12
use SWP\Bundle\CoreBundle\Model\ArticleStatistics;
13
use SWP\Component\MultiTenancy\Context\TenantContextInterface;
14
use SWP\Component\MultiTenancy\Resolver\TenantResolver;
15
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
16
17
class AnalyticsEventHandler implements MessageHandlerInterface
18
{
19
    /** @var ArticleStatisticsServiceInterface */
20
    private $articleStatisticsService;
21
22
    /** @var TenantResolver */
23
    private $tenantResolver;
24
25
    /** @var TenantContextInterface */
26
    private $tenantContext;
27
28
    /** @var ObjectManager */
29
    private $articleStatisticsObjectManager;
30
31
    private PersisterRegistry $persisterRegistry;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
32
33
    public function __construct(
34
        ArticleStatisticsServiceInterface $articleStatisticsService,
35
        TenantResolver $tenantResolver,
36
        TenantContextInterface $tenantContext,
37
        ObjectManager $articleStatisticsObjectManager,
38
        PersisterRegistry $persisterRegistry
39
    ) {
40
        $this->articleStatisticsService = $articleStatisticsService;
41
        $this->tenantResolver = $tenantResolver;
42
        $this->tenantContext = $tenantContext;
43
        $this->articleStatisticsObjectManager = $articleStatisticsObjectManager;
44
        $this->persisterRegistry = $persisterRegistry;
45
    }
46
47
    public function __invoke(AnalyticsEvent $analyticsEvent)
48
    {
49
        $this->setTenant($analyticsEvent->getHttpReferrer());
50
51
        $articleId = $analyticsEvent->getArticleId();
52
        $this->handleArticlePageViews($articleId, $analyticsEvent->getPageViewReferrer());
53
    }
54
55
    private function handleArticlePageViews(int $articleId, ?string $pageViewReferrer): void
56
    {
57
        if (0 !== $articleId) {
58
            $articleStatistics = $this->articleStatisticsService->addArticleEvent($articleId, ArticleEventInterface::ACTION_PAGEVIEW, [
59
                'pageViewSource' => $this->getPageViewSource($pageViewReferrer),
60
            ]);
61
            $query = $this->articleStatisticsObjectManager->createQuery('UPDATE '.ArticleStatistics::class.' s SET s.pageViewsNumber = s.pageViewsNumber + 1 WHERE s.id = :id');
62
            $query->setParameter('id', $articleStatistics->getId());
63
            $query->execute();
64
65
            $this->articleStatisticsObjectManager->clear();
66
67
            $this->persisterRegistry->getPersister('swp_article')->replaceOne($articleStatistics->getArticle());
68
        }
69
    }
70
71
    private function getPageViewSource(?string $pageViewReferer): string
72
    {
73
        if (null !== $pageViewReferer) {
74
            $refererHost = $this->getFragmentFromUrl($pageViewReferer, 'host');
75
            if ($refererHost && $this->isHostMatchingTenant($refererHost)) {
76
                return ArticleEventInterface::PAGEVIEW_SOURCE_INTERNAL;
77
            }
78
        }
79
80
        return ArticleEventInterface::PAGEVIEW_SOURCE_EXTERNAL;
81
    }
82
83
    private function getFragmentFromUrl(string $url, string $fragment): ?string
84
    {
85
        $fragments = \parse_url($url);
86
        if (!\array_key_exists($fragment, $fragments)) {
87
            return null;
88
        }
89
90
        return $fragments[$fragment];
91
    }
92
93
    private function isHostMatchingTenant(string $host): bool
94
    {
95
        $tenant = $this->tenantContext->getTenant();
96
        $tenantHost = $tenant->getDomainName();
97
        if (null !== ($subdomain = $tenant->getSubdomain())) {
98
            $tenantHost = $subdomain.'.'.$tenantHost;
99
        }
100
101
        return $host === $tenantHost;
102
    }
103
104
    private function setTenant(string $httpReferrer): void
105
    {
106
        $tenant = $this->tenantResolver->resolve($httpReferrer);
107
        $this->tenantContext->setTenant($tenant);
108
    }
109
}
110