Passed
Push — master ( 76cb70...440cff )
by Angel Fernando Quiroz
10:57
created

ControllerTrait::setHeadersToStreamedResponse()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 10
c 1
b 0
f 0
nc 1
nop 9
dl 0
loc 23
rs 9.9332

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
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Traits;
8
9
use Chamilo\CoreBundle\Entity\AccessUrl;
10
use Chamilo\CoreBundle\Helpers\GlideHelper;
11
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
12
use Chamilo\CoreBundle\Repository\Node\MessageAttachmentRepository;
13
use Chamilo\CoreBundle\Repository\ResourceFactory;
14
use Chamilo\CoreBundle\Repository\ResourceNodeRepository;
15
use Chamilo\CoreBundle\Settings\SettingsManager;
16
use Chamilo\CourseBundle\Repository\CAnnouncementAttachmentRepository;
17
use Chamilo\CourseBundle\Repository\CAnnouncementRepository;
18
use Chamilo\CourseBundle\Repository\CAttendanceRepository;
19
use Chamilo\CourseBundle\Repository\CCalendarEventAttachmentRepository;
20
use Chamilo\CourseBundle\Repository\CDocumentRepository;
21
use Chamilo\CourseBundle\Repository\CForumAttachmentRepository;
22
use Chamilo\CourseBundle\Repository\CForumRepository;
23
use Chamilo\CourseBundle\Repository\CLpCategoryRepository;
24
use Chamilo\CourseBundle\Repository\CLpRepository;
25
use Chamilo\CourseBundle\Repository\CQuizQuestionCategoryRepository;
26
use Chamilo\CourseBundle\Repository\CQuizQuestionRepository;
27
use Chamilo\CourseBundle\Repository\CStudentPublicationCommentRepository;
28
use Chamilo\CourseBundle\Repository\CStudentPublicationCorrectionRepository;
29
use Chamilo\CourseBundle\Repository\CStudentPublicationRepository;
30
use Chamilo\CourseBundle\Repository\CToolRepository;
31
use Chamilo\LtiBundle\Repository\ExternalToolRepository;
32
use Psr\Container\ContainerExceptionInterface;
33
use Psr\Container\ContainerInterface;
34
use Psr\Container\NotFoundExceptionInterface;
35
use Sylius\Bundle\SettingsBundle\Form\Factory\SettingsFormFactory;
36
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
37
use Symfony\Component\HttpFoundation\Request;
38
use Symfony\Component\HttpFoundation\Response;
39
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
40
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
41
use Symfony\Contracts\Translation\TranslatorInterface;
42
43
trait ControllerTrait
44
{
45
    /**
46
     * @var ContainerInterface
47
     */
48
    protected $container;
49
50
    public static function getSubscribedServices(): array
51
    {
52
        $services = AbstractController::getSubscribedServices();
53
        $services['translator'] = TranslatorInterface::class;
54
        $services['glide'] = GlideHelper::class;
55
        // $services['chamilo_settings.form_factory.settings'] = SettingsFormFactory::class;
56
57
        $services[] = SettingsManager::class;
58
        $services[] = MessageAttachmentRepository::class;
59
        $services[] = ResourceFactory::class;
60
        $services[] = ResourceNodeRepository::class;
61
        $services[] = SettingsFormFactory::class;
62
63
        /*
64
            The following classes are needed in order to load the resources files when using the /r/ path
65
            For example: http://my.chamilomaster.net/r/agenda/event_attachments/96/download?cid=1&sid=0&gid=0
66
            Then the repository CCalendarEventAttachmentRepository need to be added here,
67
            because it was set in the tools.yml like this:
68
            chamilo_core.tool.agenda:
69
                (...)
70
                event_attachments:
71
                    repository: Chamilo\CourseBundle\Repository\CCalendarEventAttachmentRepository
72
        */
73
        $services[] = CAnnouncementRepository::class;
74
        $services[] = CAnnouncementAttachmentRepository::class;
75
        $services[] = CAttendanceRepository::class;
76
        $services[] = CCalendarEventAttachmentRepository::class;
77
        $services[] = CDocumentRepository::class;
78
        $services[] = CForumRepository::class;
79
        $services[] = CForumAttachmentRepository::class;
80
        $services[] = CLpRepository::class;
81
        $services[] = CLpCategoryRepository::class;
82
        $services[] = CToolRepository::class;
83
        $services[] = CQuizQuestionRepository::class;
84
        $services[] = CQuizQuestionCategoryRepository::class;
85
        $services[] = CStudentPublicationRepository::class;
86
        $services[] = CStudentPublicationCommentRepository::class;
87
        $services[] = CStudentPublicationCorrectionRepository::class;
88
        $services[] = ExternalToolRepository::class;
89
        $services[] = IllustrationRepository::class;
90
91
        return $services;
92
    }
93
94
    public function getRequest(): ?Request
95
    {
96
        return $this->container->get('request_stack')->getCurrentRequest();
97
    }
98
99
    public function abort(string $message = ''): void
100
    {
101
        throw new NotFoundHttpException($message);
102
    }
103
104
    /**
105
     * Translator shortcut.
106
     */
107
    public function trans(string $variable): string
108
    {
109
        /** @var TranslatorInterface $translator */
110
        $translator = $this->container->get('translator');
111
112
        return $translator->trans($variable);
113
    }
114
115
    /**
116
     * @throws ContainerExceptionInterface
117
     * @throws NotFoundExceptionInterface
118
     */
119
    public function getGlide(): GlideHelper
120
    {
121
        return $this->container->get('glide');
122
    }
123
124
    public function getAccessUrl(): ?AccessUrl
125
    {
126
        $urlId = $this->getRequest()->getSession()->get('access_url_id');
127
128
        return $this->container->get('doctrine')->getRepository(AccessUrl::class)->find($urlId);
129
    }
130
131
    protected function getSettingsManager(): SettingsManager
132
    {
133
        return $this->container->get(SettingsManager::class);
134
    }
135
136
    protected function getSettingsFormFactory()
137
    {
138
        return $this->container->get(SettingsFormFactory::class);
139
    }
140
141
    /**
142
     * @return array<int, int>
143
     */
144
    protected function getRange(Request $request, int $fileSize): array
145
    {
146
        $range = $request->headers->get('Range');
147
148
        if ($range) {
149
            [, $range] = explode('=', $range, 2);
150
            [$start, $end] = explode('-', $range);
151
152
            $start = (int) $start;
153
            $end = ('' === $end) ? $fileSize - 1 : (int) $end;
154
155
            $length = $end - $start + 1;
156
        } else {
157
            $start = 0;
158
            $end = $fileSize - 1;
159
            $length = $fileSize;
160
        }
161
162
        return [$start, $end, $length];
163
    }
164
165
    /**
166
     * @param resource $stream
167
     */
168
    protected function echoBuffer($stream, int $start, int $length): void
169
    {
170
        fseek($stream, $start);
171
172
        $bytesSent = 0;
173
174
        while ($bytesSent < $length && !feof($stream)) {
175
            $buffer = fread($stream, min(1024 * 8, $length - $bytesSent));
176
177
            echo $buffer;
178
179
            $bytesSent += \strlen($buffer);
180
        }
181
182
        fclose($stream);
183
    }
184
185
    protected function setHeadersToStreamedResponse(
186
        Response $response,
187
        bool $forceDownload,
188
        string $filename,
189
        string $contentType,
190
        int $length,
191
        int $start,
192
        int $end,
193
        int $fileSize,
194
        int $finalStatus = Response::HTTP_OK
195
    ): void {
196
        $disposition = $response->headers->makeDisposition(
197
            $forceDownload ? ResponseHeaderBag::DISPOSITION_ATTACHMENT : ResponseHeaderBag::DISPOSITION_INLINE,
198
            $filename
199
        );
200
201
        $response->headers->set('Content-Disposition', $disposition);
202
        $response->headers->set('Content-Type', $contentType);
203
        $response->headers->set('Content-Length', (string) $length);
204
        $response->headers->set('Accept-Ranges', 'bytes');
205
        $response->headers->set('Content-Range', "bytes $start-$end/$fileSize");
206
        $response->setStatusCode(
207
            $start > 0 || $end < $fileSize - 1 ? Response::HTTP_PARTIAL_CONTENT : $finalStatus
208
        );
209
    }
210
}
211