RegistrationCodeController   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 145
c 1
b 0
f 0
dl 0
loc 246
ccs 0
cts 98
cp 0
rs 9.76
wmc 33

9 Methods

Rating   Name   Duplication   Size   Complexity  
A remove() 0 20 3
A addBulk() 0 28 4
A index() 0 25 3
A edit() 0 21 4
A removeRedeemed() 0 15 3
A export() 0 54 5
A add() 0 20 4
A __construct() 0 2 1
B addBulkForStudentsWithoutParent() 0 34 6
1
<?php
2
3
namespace App\Controller;
4
5
use App\Entity\RegistrationCode;
6
use App\Entity\User;
7
use App\Form\RegistrationCodeBulkStudentsWithoutParentAccountType;
8
use App\Form\RegistrationCodeBulkType;
9
use App\Form\RegistrationCodeType;
10
use App\Repository\RegistrationCodeRepositoryInterface;
11
use App\Repository\UserRepositoryInterface;
12
use App\Security\Registration\CodeGenerator;
13
use League\Csv\ByteSequence;
14
use League\Csv\Writer;
15
use SchulIT\CommonBundle\Form\ConfirmType;
16
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
17
use Symfony\Component\HttpFoundation\HeaderUtils;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\Routing\Annotation\Route;
21
use Symfony\Contracts\Translation\TranslatorInterface;
22
23
#[Route(path: '/registration_codes')]
24
class RegistrationCodeController extends AbstractController {
25
26
    private const CodesPerPage = 25;
27
28
    public function __construct(private RegistrationCodeRepositoryInterface $repository)
29
    {
30
    }
31
32
    #[Route(path: '', name: 'registration_codes')]
33
    public function index(Request $request, UserRepositoryInterface $userRepository): Response {
34
        $query = $request->query->get('q');
35
        $page = $request->query->getInt('page');
36
        $grade = $request->query->get('grade');
37
38
        $grades = $userRepository->findGrades();
39
40
        if(!in_array($grade, $grades)) {
41
            $grade = null;
42
        }
43
44
        $paginator = $this->repository->getPaginatedUsers(self::CodesPerPage, $page, $query, $grade);
45
        $pages = 1;
46
        if($paginator->count() > 0) {
47
            $pages = ceil((float)$paginator->count() / self::CodesPerPage);
48
        }
49
50
        return $this->render('codes/index.html.twig', [
51
            'codes' => $paginator->getIterator(),
52
            'page' => $page,
53
            'pages' => $pages,
54
            'query' => $query,
55
            'grade' => $grade,
56
            'grades' => $grades
57
        ]);
58
    }
59
60
    #[Route(path: '/export', name: 'export_codes')]
61
    public function export(Request $request, UserRepositoryInterface $userRepository, TranslatorInterface $translator): Response {
62
        $grade = $request->query->get('grade');
63
64
        $grades = $userRepository->findGrades();
65
66
        if(!in_array($grade, $grades)) {
67
            $grade = null;
68
        }
69
70
        if($grade !== null) {
71
            $filename = sprintf('codes_%s.csv', $grade);
72
            $codes = $this->repository->findByGrade($grade);
73
        } else {
74
            $filename = 'codes.csv';
75
            $codes = $this->repository->findAll();
76
        }
77
78
        $csv = Writer::createFromString();
79
        $csv->setDelimiter(';');
80
        $csv->setOutputBOM(ByteSequence::BOM_UTF8);
81
        $csv->insertOne([
82
            $translator->trans('label.firstname'),
83
            $translator->trans('label.lastname'),
84
            $translator->trans('label.code'),
85
            $translator->trans('label.grade'),
86
            $translator->trans('codes.redeemed')
87
        ]);
88
89
        foreach($codes as $code) {
90
            $csv->insertOne([
91
                $code->getStudent()->getFirstname(),
92
                $code->getStudent()->getLastname(),
93
                $code->getCode(),
94
                $code->getStudent()->getGrade(),
95
                $code->getRedeemingUser() !== null ? $translator->trans('yes') : $translator->trans('no')
96
            ]);
97
        }
98
99
        $response = new Response(
100
            $csv->toString(),
101
            Response::HTTP_OK,
102
            [
103
                'Content-Type' => 'application/csv'
104
            ]);
105
106
        $disposition = HeaderUtils::makeDisposition(
107
            HeaderUtils::DISPOSITION_ATTACHMENT,
108
            $filename
109
        );
110
111
        $response->headers->set('Content-Disposition', $disposition);
112
113
        return $response;
114
    }
115
116
    #[Route(path: '/remove/redeemed', name: 'remove_redeemed_codes')]
117
    public function removeRedeemed(Request $request): Response {
118
        $form = $this->createForm(ConfirmType::class, null, [
119
            'message' => 'codes.remove_redeemed.confirm'
120
        ]);
121
        $form->handleRequest($request);
122
123
        if($form->isSubmitted() && $form->isValid()) {
124
            $this->repository->removeRedeemed();
125
            $this->addFlash('success', 'codes.remove_redeemed.success');
126
            return $this->redirectToRoute('registration_codes');
127
        }
128
129
        return $this->render('codes/remove_redeemed.html.twig', [
130
            'form' => $form->createView()
131
        ]);
132
    }
133
134
    #[Route(path: '/add', name: 'add_registration_code')]
135
    public function add(Request $request, UserRepositoryInterface $userRepository): Response {
136
        $code = new RegistrationCode();
137
138
        if(($studentUuid = $request->query->get('student')) !== null) {
139
            $code->setStudent($userRepository->findOneByUuid($studentUuid));
140
        }
141
142
        $form = $this->createForm(RegistrationCodeType::class, $code);
143
        $form->handleRequest($request);
144
145
        if($form->isSubmitted() && $form->isValid()) {
146
            $this->repository->persist($code);
147
            $this->addFlash('success', 'codes.add.success');
148
149
            return $this->redirectToRoute('registration_codes');
150
        }
151
152
        return $this->render('codes/add.html.twig', [
153
            'form' => $form->createView()
154
        ]);
155
    }
156
157
    #[Route(path: '/bulk', name: 'add_registration_code_bulk')]
158
    public function addBulk(Request $request, UserRepositoryInterface $userRepository, CodeGenerator $codeGenerator): Response {
159
        $form = $this->createForm(RegistrationCodeBulkType::class);
160
        $form->handleRequest($request);
161
162
        if($form->isSubmitted() && $form->isValid()) {
163
            $grade = $form->get('grade')->getData();
164
            $users = $userRepository->findStudentsByGrade($grade);
165
            $count = 0;
166
167
            foreach($users as $user) {
168
                $code = (new RegistrationCode())
169
                    ->setCode($codeGenerator->generateCode())
170
                    ->setValidFrom($form->get('validFrom')->getData())
171
                    ->setStudent($user);
172
173
                $this->repository->persist($code);
174
                $count++;
175
            }
176
177
            $this->addFlash('success', 'codes.bulk.success');
178
            return $this->redirectToRoute('registration_codes', [
179
                'grade' => $grade
180
            ]);
181
        }
182
183
        return $this->render('codes/bulk.html.twig', [
184
            'form' => $form->createView()
185
        ]);
186
    }
187
188
    #[Route(path: '/bulk/students_without_parent', name: 'add_registration_code_bulk_for_students_without_parent')]
189
    public function addBulkForStudentsWithoutParent(Request $request, CodeGenerator $codeGenerator): Response {
190
        $form = $this->createForm(RegistrationCodeBulkStudentsWithoutParentAccountType::class);
191
        $form->handleRequest($request);
192
193
        if($form->isSubmitted() && $form->isValid()) {
194
            /** @var User[] $users */
195
            $users = $form->get('students')->getData();
196
            $count = 0;
197
198
            foreach($users as $user) {
199
                if($user->getType()->getAlias() !== 'student') {
200
                    continue;
201
                }
202
203
                if($this->repository->codeForStudentExists($user)) {
204
                    continue;
205
                }
206
207
                $code = (new RegistrationCode())
208
                    ->setCode($codeGenerator->generateCode())
209
                    ->setValidFrom($form->get('validFrom')->getData())
210
                    ->setStudent($user);
211
212
                $this->repository->persist($code);
213
                $count++;
214
            }
215
216
            $this->addFlash('success', 'codes.bulk_noparents.success');
217
            return $this->redirectToRoute('registration_codes');
218
        }
219
220
        return $this->render('codes/bulk_students_without_parents.html.twig', [
221
            'form' => $form->createView()
222
        ]);
223
    }
224
225
    #[Route(path: '/{uuid}/edit', name: 'edit_registration_code')]
226
    public function edit(RegistrationCode $code, Request $request): Response {
227
        if($code->getRedeemingUser() !== null) {
228
            $this->addFlash('error', 'codes.edit.error.already_redeemed.message');
229
            return $this->redirectToRoute('registration_codes');
230
        }
231
232
        $form = $this->createForm(RegistrationCodeType::class, $code);
233
        $form->handleRequest($request);
234
235
        if($form->isSubmitted() && $form->isValid()) {
236
            $this->repository->persist($code);
237
238
            $this->addFlash('success', 'codes.edit.success');
239
240
            return $this->redirectToRoute('registration_codes');
241
        }
242
243
        return $this->render('codes/edit.html.twig', [
244
            'form' => $form->createView(),
245
            'code' => $code
246
        ]);
247
    }
248
249
    #[Route(path: '/{uuid}/remove', name: 'remove_registration_code')]
250
    public function remove(RegistrationCode $code, Request $request): Response {
251
        $form = $this->createForm(ConfirmType::class, [], [
252
            'message' => 'codes.remove.confirm',
253
            'message_parameters' => [
254
                '%code%' => $code->getCode()
255
            ]
256
        ]);
257
        $form->handleRequest($request);
258
259
        if($form->isSubmitted() && $form->isValid()) {
260
            $this->repository->remove($code);
261
262
            $this->addFlash('success', 'codes.remove.success');
263
            return $this->redirectToRoute('registration_codes');
264
        }
265
266
        return $this->render('codes/remove.html.twig', [
267
            'code' => $code,
268
            'form' => $form->createView()
269
        ]);
270
    }
271
272
}