Passed
Push — master ( 6957cf...3bb145 )
by Joachim
04:59
created

DownloadReportAction::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 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 Safe\Exceptions\StringsException;
10
use function Safe\fread;
11
use function Safe\sprintf;
12
use Setono\SyliusStockMovementPlugin\Model\ReportInterface;
13
use Setono\SyliusStockMovementPlugin\Repository\ReportRepositoryInterface;
14
use Setono\SyliusStockMovementPlugin\Resolver\ReportPathResolverInterface;
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 ReportPathResolverInterface */
29
    private $reportPathResolver;
30
31
    /** @var FilesystemInterface */
32
    private $filesystem;
33
34
    public function __construct(
35
        ReportRepositoryInterface $reportRepository,
36
        ReportWriterInterface $reportWriter,
37
        ReportPathResolverInterface $reportPathResolver,
38
        FilesystemInterface $filesystem
39
    ) {
40
        $this->reportRepository = $reportRepository;
41
        $this->reportWriter = $reportWriter;
42
        $this->reportPathResolver = $reportPathResolver;
43
        $this->filesystem = $filesystem;
44
    }
45
46
    /**
47
     * @throws StringsException
48
     * @throws FileNotFoundException
49
     */
50
    public function __invoke($id): StreamedResponse
51
    {
52
        /** @var ReportInterface|null $report */
53
        $report = $this->reportRepository->find($id);
54
        if (null === $report) {
55
            throw new NotFoundHttpException(sprintf('The report with id %s does not exist', $id));
56
        }
57
58
        $reportPath = $this->reportPathResolver->resolve($report);
59
60
        if (!$this->filesystem->has($reportPath)) {
61
            $this->reportWriter->write($report);
62
        }
63
64
        $stream = $this->filesystem->readStream($reportPath);
65
        if (false === $stream) {
66
            throw new \RuntimeException(sprintf('Could not open %s for reading', $reportPath));
67
        }
68
69
        $response = new StreamedResponse();
70
        $response->setCallback(static function () use ($stream) {
71
            while (!feof($stream)) {
72
                echo fread($stream, 8192);
73
                flush();
74
            }
75
        });
76
77
        $disposition = HeaderUtils::makeDisposition(
78
            HeaderUtils::DISPOSITION_ATTACHMENT,
79
            basename($reportPath)
80
        );
81
        $response->headers->set('Content-Disposition', $disposition);
82
83
        return $response;
84
    }
85
}
86