Completed
Push — master ( 7ee0d9...1aff7f )
by Rafał
24:06 queued 15:30
created

AnalyticsExportController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 5
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\Controller;
18
19
use Nelmio\ApiDocBundle\Annotation\Operation;
20
use Nelmio\ApiDocBundle\Annotation\Model;
21
use Swagger\Annotations as SWG;
22
use DateTime;
23
use Doctrine\Common\Cache\Cache;
24
use Hoa\Mime\Mime;
25
use League\Flysystem\Filesystem;
26
use SWP\Bundle\CoreBundle\AnalyticsExport\CsvReportFileLocationResolver;
27
use SWP\Bundle\CoreBundle\AnalyticsExport\ExportAnalytics;
28
use SWP\Bundle\CoreBundle\Context\CachedTenantContextInterface;
29
use SWP\Bundle\CoreBundle\Model\AnalyticsReport;
30
use SWP\Bundle\CoreBundle\Model\AnalyticsReportInterface;
31
use SWP\Bundle\CoreBundle\Model\UserInterface;
32
use SWP\Component\Common\Criteria\Criteria;
33
use SWP\Component\Common\Pagination\PaginationData;
34
use SWP\Component\Common\Response\ResourcesListResponse;
35
use SWP\Component\Storage\Repository\RepositoryInterface;
36
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
37
use Symfony\Component\HttpFoundation\Response;
38
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
39
use Symfony\Component\Routing\Annotation\Route;
40
use SWP\Component\Common\Response\ResponseContext;
41
use SWP\Component\Common\Response\SingleResourceResponse;
42
use Symfony\Component\HttpFoundation\Request;
43
use SWP\Component\Common\Model\DateTime as PublisherDateTime;
44
45
class AnalyticsExportController extends AbstractController
46
{
47
    /** @var Cache */
48
    protected $cacheProvider;
49
50
    /** @var RepositoryInterface */
51
    protected $analyticsReportRepository;
52
53
    /** @var Filesystem */
54
    protected $filesystem;
55
56
    /** @var CsvReportFileLocationResolver */
57
    protected $csvReportFileLocationResolver;
58
59
    /** @var CachedTenantContextInterface */
60
    protected $cachedTenantContext;
61
62
    public function __construct(
63
        Cache $cacheProvider,
64
        RepositoryInterface $analyticsReportRepository,
65
        Filesystem $filesystem,
66
        CsvReportFileLocationResolver $csvReportFileLocationResolver,
67
        CachedTenantContextInterface $cachedTenantContext
68
    ) {
69
        $this->cacheProvider = $cacheProvider;
70
        $this->analyticsReportRepository = $analyticsReportRepository;
71
        $this->filesystem = $filesystem;
72
        $this->csvReportFileLocationResolver = $csvReportFileLocationResolver;
73
        $this->cachedTenantContext = $cachedTenantContext;
74
    }
75
76
    /**
77
     * @Operation(
78
     *     tags={"export"},
79
     *     summary="Export analytics data",
80
     *     @SWG\Parameter(
81
     *         name="start",
82
     *         in="query",
83
     *         description="Export start date, e.g. 20150101",
84
     *         required=false,
85
     *         type="string"
86
     *     ),
87
     *     @SWG\Parameter(
88
     *         name="end",
89
     *         in="query",
90
     *         description="Export end date, e.g. 20160101",
91
     *         required=false,
92
     *         type="string"
93
     *     ),
94
     *     @SWG\Response(
95
     *         response="200",
96
     *         description="Returned on success."
97
     *     )
98
     * )
99
     *
100
     * @Route("/api/{version}/export/analytics", options={"expose"=true}, defaults={"version"="v2"}, methods={"POST"}, name="swp_api_core_analytics_export_post")
101
     *
102
     * @return SingleResourceResponse
103
     *
104
     * @throws \Exception
105
     */
106
    public function post(Request $request): SingleResourceResponse
107
    {
108
        /** @var UserInterface $currentlyLoggedInUser */
109
        $currentlyLoggedInUser = $this->getUser();
110
111
        $start = new DateTime($request->query->get('start', 'now'));
112
        $end = new DateTime($request->query->get('end', '-30 days'));
113
        $tenantCode = $this->cachedTenantContext->getTenant()->getCode();
114
        $userEmail = $currentlyLoggedInUser->getEmail();
115
        $now = PublisherDateTime::getCurrentDateTime();
116
        $fileName = 'analytics-'.$now->format('Y-m-d-H:i:s').'.csv';
117
118
        $analyticsReport = new AnalyticsReport();
119
        $analyticsReport->setAssetId($fileName);
120
        $analyticsReport->setFileExtension('csv');
121
        $analyticsReport->setUser($currentlyLoggedInUser);
122
        $this->analyticsReportRepository->add($analyticsReport);
123
124
        $this->dispatchMessage(new ExportAnalytics($start, $end, $tenantCode, $fileName, $userEmail));
125
126
        return new SingleResourceResponse(['status' => 'OK'], new ResponseContext(201));
127
    }
128
129
    /**
130
     * @Operation(
131
     *     tags={"export"},
132
     *     summary="Lists analytics reports",
133
     *     @SWG\Parameter(
134
     *         name="sorting",
135
     *         in="query",
136
     *         description="example: [createdAt]=asc|desc",
137
     *         required=false,
138
     *         type="string"
139
     *     ),
140
     *     @SWG\Response(
141
     *         response="200",
142
     *         description="Returned on success.",
143
     *         @SWG\Schema(
144
     *             type="array",
145
     *             @SWG\Items(ref=@Model(type=\SWP\Bundle\CoreRoute\Model\AnalyticsReport::class, groups={"api"}))
146
     *         )
147
     *     )
148
     * )
149
     *
150
     * @Route("/api/{version}/export/analytics", methods={"GET"}, options={"expose"=true}, defaults={"version"="v2"}, name="swp_api_core_list_analytics_reports")
151
     */
152 View Code Duplication
    public function listAction(Request $request)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
    {
154
        $redirectRoutes = $this->analyticsReportRepository->getPaginatedByCriteria(
155
            new Criteria(),
156
            $request->query->get('sorting', []),
157
            new PaginationData($request)
158
        );
159
160
        return new ResourcesListResponse($redirectRoutes);
161
    }
162
163
    /**
164
     * @Route("/analytics/export/{fileName}", methods={"GET"}, options={"expose"=true}, requirements={"mediaId"=".+"}, name="swp_export_analytics_download")
165
     */
166
    public function downloadFile(string $fileName): Response
167
    {
168
        $cacheKey = md5(serialize(['analytics_report', $fileName]));
169
        if (!$this->cacheProvider->contains($cacheKey)) {
170
            /** @var AnalyticsReportInterface $analyticsReport */
171
            $analyticsReport = $this->analyticsReportRepository->findOneBy(['assetId' => $fileName]);
172
            $this->cacheProvider->save($cacheKey, $analyticsReport, 63072000);
173
        } else {
174
            $analyticsReport = $this->cacheProvider->fetch($cacheKey);
175
        }
176
177
        if (null === $analyticsReport) {
178
            throw new NotFoundHttpException('Report file was not found.');
179
        }
180
181
        $response = new Response();
182
        $disposition = $response->headers->makeDisposition(
183
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
184
            str_replace('/', '_', $fileName)
185
        );
186
187
        $response->headers->set('Content-Disposition', $disposition);
188
        $response->headers->set('Content-Type', Mime::getMimeFromExtension($analyticsReport->getFileExtension()));
189
190
        $response->setPublic();
191
        $response->setMaxAge(63072000);
192
        $response->setSharedMaxAge(63072000);
193
        $response->setLastModified($analyticsReport->getUpdatedAt() ?: $analyticsReport->getCreatedAt());
194
        $response->setContent($this->filesystem->read($this->csvReportFileLocationResolver->getMediaBasePath().'/'.$analyticsReport->getAssetId()));
195
196
        return $response;
197
    }
198
}
199