Completed
Push — master ( 7ee0d9...1aff7f )
by Rafał
24:06 queued 15:30
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 DateTime;
20
use FOS\ElasticaBundle\Manager\RepositoryManagerInterface;
21
use RuntimeException;
22
use SWP\Bundle\CoreBundle\AnalyticsExport\Exception\AnalyticsReportNotFoundException;
23
use SWP\Bundle\CoreBundle\Context\CachedTenantContextInterface;
24
use SWP\Bundle\CoreBundle\Model\AnalyticsReportInterface;
25
use SWP\Bundle\CoreBundle\Model\Article;
26
use SWP\Bundle\ElasticSearchBundle\Criteria\Criteria;
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
                '',
93
                [
94
                    'sort' => ['articleStatistics.pageViewsNumber' => 'desc'],
95
                    'publishedBefore' => $exportAnalytics->getEnd(),
96
                    'publishedAfter' => $exportAnalytics->getStart(),
97
                    'tenantCode' => $tenantCode,
98
                ]
99
            );
100
101
            $tenant = $this->tenantRepository->findOneBy(['code' => $tenantCode]);
102
            if (null === $tenant) {
103
                throw new RuntimeException("Tenant with code $tenantCode not found");
104
            }
105
106
            $this->cachedTenantContext->setTenant($tenant);
107
108
            $articleRepository = $this->elasticaRepositoryManager->getRepository(Article::class);
109
110
            $articles = $articleRepository->findByCriteria($criteria);
111
            $total = $articles->getTotalHits();
112
            $articles = $articles->getResults(0, $total);
113
            $data = $this->objectsToArray($articles->toArray());
114
            $path = $this->cacheDir.'/'.$fileName;
115
116
            $this->csvFileWriter->write($path, $data);
117
118
            $url = $this->reportFileUploader->upload($analyticsReport, $path);
119
120
            $this->mailer->sendReportReadyEmailNotification($exportAnalytics->getUserEmail(), $url);
121
            $analyticsReport->setStatus(AnalyticsReportInterface::STATUS_COMPLETED);
122
        } catch (Throwable $e) {
123
            $analyticsReport->setStatus(AnalyticsReportInterface::STATUS_ERRORED);
124
        }
125
126
        $analyticsReport->setUpdatedAt(new DateTime());
127
        $this->analyticsReportRepository->flush();
128
    }
129
130
    private function objectsToArray(array $rows): array
131
    {
132
        $data = [
133
            ['Article ID', 'Publish Date', 'Total Views', 'Section', 'Title', 'Author(s)'],
134
        ];
135
136
        /** @var Article $article */
137
        foreach ($rows as $article) {
138
            $data[] = [
139
                $article->getId(),
140
                $article->getPublishedAt()->format('Y-m-d H:i'),
141
                $article->getArticleStatistics()->getPageViewsNumber(),
142
                $article->getRoute()->getName(),
143
                $article->getTitle(),
144
                implode(', ', $article->getAuthorsNames()),
145
            ];
146
        }
147
148
        return $data;
149
    }
150
}
151