Completed
Push — master ( 9af361...a55b85 )
by Rafał
09:23
created

ExportAnalyticsHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Core Bundle.
7
 *
8
 * Copyright 2020 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2020 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\CoreBundle\AnalyticsExport;
18
19
use FOS\ElasticaBundle\Manager\RepositoryManagerInterface;
20
use RuntimeException;
21
use SWP\Bundle\CoreBundle\AnalyticsExport\Exception\AnalyticsReportNotFoundException;
22
use SWP\Bundle\CoreBundle\Context\CachedTenantContextInterface;
23
use SWP\Bundle\CoreBundle\Model\AnalyticsReportInterface;
24
use SWP\Bundle\CoreBundle\Model\Article;
25
use SWP\Bundle\ElasticSearchBundle\Criteria\Criteria;
26
use SWP\Component\Common\Model\DateTime;
27
use SWP\Component\MultiTenancy\Repository\TenantRepositoryInterface;
28
use SWP\Component\Storage\Repository\RepositoryInterface;
29
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
30
use Throwable;
31
32
final class ExportAnalyticsHandler implements MessageHandlerInterface
33
{
34
    /** @var RepositoryManagerInterface */
35
    private $elasticaRepositoryManager;
36
37
    /** @var string */
38
    private $cacheDir;
39
40
    /** @var ReportMailer */
41
    private $mailer;
42
43
    /** @var ReportFileUploader */
44
    private $reportFileUploader;
45
46
    /** @var CsvFileWriter */
47
    private $csvFileWriter;
48
49
    /** @var RepositoryInterface */
50
    private $analyticsReportRepository;
51
52
    /** @var CachedTenantContextInterface */
53
    private $cachedTenantContext;
54
55
    /** @var TenantRepositoryInterface */
56
    private $tenantRepository;
57
58
    public function __construct(
59
        RepositoryManagerInterface $elasticaRepositoryManager,
60
        string $cacheDir,
61
        ReportMailer $mailer,
62
        ReportFileUploader $reportFileUploader,
63
        CsvFileWriter $csvFileWriter,
64
        RepositoryInterface $analyticsReportRepository,
65
        CachedTenantContextInterface $cachedTenantContext,
66
        TenantRepositoryInterface $tenantRepository
67
    ) {
68
        $this->elasticaRepositoryManager = $elasticaRepositoryManager;
69
        $this->cacheDir = $cacheDir;
70
        $this->mailer = $mailer;
71
        $this->reportFileUploader = $reportFileUploader;
72
        $this->csvFileWriter = $csvFileWriter;
73
        $this->analyticsReportRepository = $analyticsReportRepository;
74
        $this->cachedTenantContext = $cachedTenantContext;
75
        $this->tenantRepository = $tenantRepository;
76
    }
77
78
    public function __invoke(ExportAnalytics $exportAnalytics)
79
    {
80
        $fileName = $exportAnalytics->getFileName();
81
82
        /** @var AnalyticsReportInterface $analyticsReport */
83
        $analyticsReport = $this->analyticsReportRepository->findOneBy(['assetId' => $fileName]);
84
85
        if (null === $analyticsReport) {
86
            throw new AnalyticsReportNotFoundException("Analytics report $fileName not found.");
87
        }
88
89
        try {
90
            $tenantCode = $exportAnalytics->getTenantCode();
91
            $criteria = Criteria::fromQueryParameters(
92
                $exportAnalytics->getTerm(),
93
                [
94
                    'sort' => ['articleStatistics.pageViewsNumber' => 'desc'],
95
                    'publishedBefore' => $exportAnalytics->getEnd(),
96
                    'publishedAfter' => $exportAnalytics->getStart(),
97
                    'tenantCode' => $tenantCode,
98
                    'routes' => $exportAnalytics->getRouteIds(),
99
                    'authors' => $exportAnalytics->getAuthors(),
100
                ]
101
            );
102
103
            $tenant = $this->tenantRepository->findOneBy(['code' => $tenantCode]);
104
            if (null === $tenant) {
105
                throw new RuntimeException("Tenant with code $tenantCode not found");
106
            }
107
108
            $this->cachedTenantContext->setTenant($tenant);
109
110
            $articleRepository = $this->elasticaRepositoryManager->getRepository(Article::class);
111
112
            $articles = $articleRepository->findByCriteria($criteria);
113
            $total = $articles->getTotalHits();
114
            $articles = $articles->getResults(0, 0 !== $total ? $total : 1);
115
            $data = $this->objectsToArray($articles->toArray());
116
            $path = $this->cacheDir.'/'.$fileName;
117
118
            $this->csvFileWriter->write($path, $data);
119
120
            $url = $this->reportFileUploader->upload($analyticsReport, $path);
121
122
            $this->mailer->sendReportReadyEmailNotification($exportAnalytics->getUserEmail(), $url);
123
            $analyticsReport->setStatus(AnalyticsReportInterface::STATUS_COMPLETED);
124
        } catch (Throwable $e) {
125
            $analyticsReport->setStatus(AnalyticsReportInterface::STATUS_ERRORED);
126
        }
127
128
        $analyticsReport->setUpdatedAt(DateTime::getCurrentDateTime());
129
        $this->analyticsReportRepository->flush();
130
    }
131
132
    private function objectsToArray(array $rows): array
133
    {
134
        $data = [
135
            ['Article ID', 'Publish Date', 'Total Views', 'Section', 'Title', 'Author(s)'],
136
        ];
137
138
        /** @var Article $article */
139
        foreach ($rows as $article) {
140
            $data[] = [
141
                $article->getId(),
142
                $article->getPublishedAt()->format('Y-m-d H:i'),
143
                null !== $article->getArticleStatistics() ? $article->getArticleStatistics()->getPageViewsNumber() : 0,
144
                $article->getRoute()->getName(),
145
                $article->getTitle(),
146
                implode(', ', $article->getAuthorsNames()),
147
            ];
148
        }
149
150
        return $data;
151
    }
152
}
153