DownloadReportAction   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 5
eloc 23
c 2
b 0
f 1
dl 0
loc 55
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A __invoke() 0 30 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Setono\SyliusStockMovementPlugin\Controller\Action;
6
7
use League\Flysystem\FileNotFoundException;
8
use League\Flysystem\FilesystemInterface;
9
use RuntimeException;
10
use Safe\Exceptions\StringsException;
11
use function Safe\fread;
12
use function Safe\sprintf;
13
use Setono\SyliusStockMovementPlugin\Model\ReportInterface;
14
use Setono\SyliusStockMovementPlugin\Repository\ReportRepositoryInterface;
15
use Setono\SyliusStockMovementPlugin\Writer\ReportWriterInterface;
16
use Symfony\Component\HttpFoundation\HeaderUtils;
17
use Symfony\Component\HttpFoundation\StreamedResponse;
18
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
19
20
final class DownloadReportAction
21
{
22
    /** @var ReportRepositoryInterface */
23
    private $reportRepository;
24
25
    /** @var ReportWriterInterface */
26
    private $reportWriter;
27
28
    /** @var FilesystemInterface */
29
    private $filesystem;
30
31
    public function __construct(
32
        ReportRepositoryInterface $reportRepository,
33
        ReportWriterInterface $reportWriter,
34
        FilesystemInterface $filesystem
35
    ) {
36
        $this->reportRepository = $reportRepository;
37
        $this->reportWriter = $reportWriter;
38
        $this->filesystem = $filesystem;
39
    }
40
41
    /**
42
     * @throws StringsException
43
     * @throws FileNotFoundException
44
     */
45
    public function __invoke(string $uuid): StreamedResponse
46
    {
47
        /** @var ReportInterface|null $report */
48
        $report = $this->reportRepository->findByUuid($uuid);
49
        if (null === $report) {
50
            throw new NotFoundHttpException(sprintf('The report with uuid %s does not exist', $uuid));
51
        }
52
53
        $reportPath = $this->reportWriter->write($report);
54
55
        $stream = $this->filesystem->readStream($reportPath);
56
        if (false === $stream) {
57
            throw new RuntimeException(sprintf('Could not open %s for reading', $reportPath));
58
        }
59
60
        $response = new StreamedResponse();
61
        $response->setCallback(static function () use ($stream) {
62
            while (!feof($stream)) {
63
                echo fread($stream, 8192);
64
                flush();
65
            }
66
        });
67
68
        $disposition = HeaderUtils::makeDisposition(
69
            HeaderUtils::DISPOSITION_ATTACHMENT,
70
            basename($reportPath)
71
        );
72
        $response->headers->set('Content-Disposition', $disposition);
73
74
        return $response;
75
    }
76
}
77