Test Failed
Push — master ( 8a5ddb...74d2a8 )
by Gerhard
16:07 queued 05:38
created

FileController::getStreamingDisabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace Enhavo\Bundle\MediaBundle\Controller;
4
5
use Enhavo\Bundle\AppBundle\Controller\ResourceController;
6
use Enhavo\Bundle\MediaBundle\Media\MediaManager;
7
use Enhavo\Bundle\MediaBundle\Model\FileInterface;
8
use Enhavo\Bundle\MediaBundle\Model\FormatInterface;
9
use Enhavo\Bundle\MediaBundle\Security\AuthorizationCheckerInterface;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\HttpFoundation\StreamedResponse;
13
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
14
15
class FileController extends ResourceController
16
{
17
    /**
18
     * @return MediaManager
19
     */
20
    private function getMediaManager()
21
    {
22
        return $this->container->get('enhavo_media.media.media_manager');
23
    }
24
25
    /**
26
     * @return AuthorizationCheckerInterface
27
     */
28
    private function getAuthorizationChecker()
29
    {
30
        return $this->container->get('enhavo_media.security.default_authorization_checker');
31
    }
32
33
    public function showAction(Request $request): Response
34
    {
35
        $file = $this->getFile($request);
36
37
        if(!$this->getAuthorizationChecker()->isGranted($file)) {
38
            throw $this->createAccessDeniedException();
39
        }
40
41
        $response = $this->getResponse($file);
42
43
        $maxAge = $this->getMaxAge();
44
        if($maxAge) {
45
            $this->setMaxAge($response, $maxAge);
46
        }
47
48
        return $response;
49
    }
50
51
    /**
52
     * @param Request $request
53
     * @return FileInterface
54
     */
55
    private function getFile(Request $request): FileInterface
56
    {
57
        $id = $request->get('id');
58
        $filename = $request->get('filename');
59
        $shortChecksum = $request->get('shortMd5Checksum');
60
61
        $file = $this->getMediaManager()->findOneBy([
62
            'id' => $id,
63
            'filename' => $filename
64
        ]);
65
66
        if($file === null) {
67
            throw $this->createNotFoundException();
68
        }
69
70
        if($shortChecksum != substr($file->getMd5Checksum(), 0, 6)) {
71
            throw $this->createNotFoundException();
72
        }
73
74
        return $file;
75
    }
76
77 View Code Duplication
    public function downloadAction(Request $request): Response
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...
78
    {
79
        $filename = $request->get('filename');
80
81
        $response = $this->showAction($request);
82
        $response->headers->set('Content-Type', 'application/octet-stream');
83
        $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
84
        return $response;
85
    }
86
87
    public function showFormatAction(Request $request): Response
88
    {
89
        $id = $request->get('id');
90
        $filename = $request->get('filename');
91
        $shortChecksum = $request->get('shortMd5Checksum');
92
        $format = $request->get('format');
93
94
        $file = $this->getMediaManager()->findOneBy([
95
            'id' => $id
96
        ]);
97
98
        if($file === null) {
99
            throw $this->createNotFoundException();
100
        }
101
102
        if($shortChecksum != substr($file->getMd5Checksum(), 0, 6)) {
103
            throw $this->createNotFoundException();
104
        }
105
106
        $formatFile = $this->getMediaManager()->getFormat($file, $format);
107
108
        if(pathinfo($formatFile->getFilename())['filename'] !== pathinfo($filename)['filename']) {
109
            throw $this->createNotFoundException();
110
        }
111
112
        if(!$this->getAuthorizationChecker()->isGranted($file)) {
113
            throw $this->createAccessDeniedException();
114
        }
115
116
        $response = $this->getResponse($formatFile);
117
118
        $maxAge = $this->getMaxAge();
119
        if($maxAge) {
120
            $this->setMaxAge($response, $maxAge);
121
        }
122
123
        return $response;
124
    }
125
126
    /**
127
     * @param FileInterface|FormatInterface $file
128
     * @return Response
129
     */
130
    private function getResponse($file): Response
131
    {
132
        $fileSize = filesize($file->getContent()->getFilePath());
133
        if (!$this->getStreamingDisabled() && $this->getStreamingThreshold() < $fileSize) {
134
            $response = new StreamedResponse(function () use ($file) {
135
                $outputStream = fopen('php://output', 'wb');
136
                $fileStream = fopen($file->getContent()->getFilePath(), 'r');
137
                stream_copy_to_stream($fileStream, $outputStream);
138
            });
139
        } else {
140
            $response = new Response();
141
            $content = $file->getContent()->getContent();
142
            $response->setContent($content);
143
        }
144
        $response->headers->set('Content-Type', $file->getMimeType());
145
        $response->headers->set('Content-Length', $fileSize);
146
147
        return $response;
148
    }
149
150
    private function getMaxAge()
151
    {
152
        return $this->getParameter('enhavo_media.cache_control.max_age');
153
    }
154
155
    private function getStreamingDisabled()
156
    {
157
        return $this->getParameter('enhavo_media.streaming.disabled');
158
    }
159
160
    private function getStreamingThreshold()
161
    {
162
        return $this->getParameter('enhavo_media.streaming.threshold');
163
    }
164
165
    private function setMaxAge(Response $response, $maxAge)
166
    {
167
        $response
168
            ->setExpires($this->getDateInSeconds($maxAge))
169
            ->setMaxAge($maxAge)
170
            ->setPublic();
171
172
        $response->headers->add([
173
            AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER => true
174
        ]);
175
    }
176
177
    private function getDateInSeconds($seconds)
178
    {
179
        $date = new \DateTime();
180
        $date->modify(sprintf('+%s seconds', $seconds));
181
        return $date;
182
    }
183
184 View Code Duplication
    public function downloadFormatAction(Request $request): Response
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...
185
    {
186
        $filename = $request->get('filename');
187
188
        $response = $this->showFormatAction($request);
189
        $response->headers->set('Content-Type', 'application/octet-stream');
190
        $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
191
        return $response;
192
    }
193
194
    public function resolveAction(Request $request): Response
195
    {
196
        $token = $request->get('token');
197
198
        $file = $this->getMediaManager()->findOneBy([
199
            'token' => $token
200
        ]);
201
202
        return $this->redirectToRoute('enhavo_media_file_show', [
203
            'id' => $file->getId(),
204
            'shortMd5Checksum' => substr($file->getMd5Checksum(), 0, 6),
205
            'filename' => $file->getFilename(),
206
        ]);
207
    }
208
209
    public function resolveFormatAction(Request $request): Response
210
    {
211
        $token = $request->get('token');
212
        $format = $request->get('format');
213
214
        $file = $this->getMediaManager()->findOneBy([
215
            'token' => $token
216
        ]);
217
218
        return $this->redirectToRoute('enhavo_media_file_format', [
219
            'id' => $file->getId(),
220
            'format' => $format,
221
            'shortMd5Checksum' => substr($file->getMd5Checksum(), 0, 6),
222
            'filename' => $file->getFilename(),
223
        ]);
224
    }
225
}
226