Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.05% covered (success)
94.05%
237 / 252
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ViolationType
94.05% covered (success)
94.05%
237 / 252
66.67% covered (warning)
66.67%
2 / 3
10.02
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 buildForm
93.78% covered (success)
93.78%
226 / 241
0.00% covered (danger)
0.00%
0 / 1
8.02
 configureOptions
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * This file is part of the MADIS - RGPD Management application.
5 *
6 * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22declare(strict_types=1);
23
24namespace App\Domain\Registry\Form\Type;
25
26use App\Application\Form\Type\LinkableType;
27use App\Domain\Registry\Model\Contractor;
28use App\Domain\Registry\Model\Mesurement;
29use App\Domain\Registry\Model\Proof;
30use App\Domain\Registry\Model\Request;
31use App\Domain\Registry\Model\Tool;
32use App\Domain\Registry\Model\Treatment;
33use App\Domain\Registry\Model\Violation;
34use App\Domain\User\Model\Service;
35use App\Domain\User\Model\User;
36use Doctrine\ORM\EntityRepository;
37use Knp\DictionaryBundle\Form\Type\DictionaryType;
38use Symfony\Bridge\Doctrine\Form\Type\EntityType;
39use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
40use Symfony\Component\Form\Extension\Core\Type\DateType;
41use Symfony\Component\Form\Extension\Core\Type\HiddenType;
42use Symfony\Component\Form\Extension\Core\Type\IntegerType;
43use Symfony\Component\Form\Extension\Core\Type\TextareaType;
44use Symfony\Component\Form\Extension\Core\Type\TextType;
45use Symfony\Component\Form\FormBuilderInterface;
46use Symfony\Component\OptionsResolver\OptionsResolver;
47use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
48use Symfony\Component\Security\Core\Security;
49
50class ViolationType extends LinkableType
51{
52    /**
53     * @var Security
54     */
55    private $security;
56
57    /**
58     * @var AuthorizationCheckerInterface
59     */
60    private $authorizationChecker;
61
62    public function __construct(Security $security, AuthorizationCheckerInterface $authorizationChecker)
63    {
64        $this->security             = $security;
65        $this->authorizationChecker = $authorizationChecker;
66        parent::__construct($security);
67    }
68
69    /**
70     * Build type form.
71     */
72    public function buildForm(FormBuilderInterface $builder, array $options)
73    {
74        $violation = $options['data'] ?? null;
75
76        $collectivity = null;
77        if ($violation) {
78            $collectivity = $violation->getCollectivity();
79        }
80        /** @var User $user */
81        $user = $this->security->getUser();
82
83        if (!$collectivity) {
84            $collectivity = $user->getCollectivity();
85        }
86        $builder
87            ->add('date', DateType::class, [
88                'label'    => 'registry.violation.label.date',
89                'required' => true,
90                'widget'   => 'single_text',
91                'format'   => 'dd/MM/yyyy',
92                'html5'    => false,
93                'attr'     => [
94                    'class' => 'datepicker',
95                ],
96            ])
97        ;
98        if ($collectivity->getIsServicesEnabled()) {
99            $builder->add('service', EntityType::class, [
100                'class'         => Service::class,
101                'label'         => 'registry.label.service',
102                'query_builder' => function (EntityRepository $er) use ($violation) {
103                    /** @var User $authenticatedUser */
104                    $authenticatedUser = $this->security->getUser();
105                    $collectivity      = $violation->getCollectivity();
106
107                    $qb = $er->createQueryBuilder('s')
108                        ->where('s.collectivity = :collectivity')
109                        ->setParameter(':collectivity', $collectivity)
110                    ;
111                    if (!$this->authorizationChecker->isGranted('ROLE_ADMIN') && $authenticatedUser->getServices()->getValues()) {
112                        $qb->leftJoin('s.users', 'users')
113                            ->andWhere('users.id = :id')
114                            ->setParameter('id', $authenticatedUser->getId())
115                        ;
116                    }
117                    $qb
118                        ->orderBy('s.name', 'ASC');
119
120                    return $qb;
121                },
122                'required' => false,
123            ]);
124        }
125        /** @var User $user */
126        $user = $this->security->getUser();
127
128        $builder
129            ->add('inProgress', CheckboxType::class, [
130                'label'    => 'registry.violation.label.in_progress',
131                'required' => false,
132            ])
133            ->add('violationNatures', DictionaryType::class, [
134                'label'    => 'registry.violation.label.violation_natures',
135                'name'     => 'registry_violation_nature',
136                'expanded' => false,
137                'multiple' => true,
138                'attr'     => [
139                    'class'            => 'selectpicker',
140                    'data-live-search' => 'true',
141                    'title'            => 'global.placeholder.multiple_select',
142                    'aria-label'       => 'Natures de la violation',
143                ],
144            ])
145            ->add('origins', DictionaryType::class, [
146                'label'    => 'registry.violation.label.origins',
147                'name'     => 'registry_violation_origin',
148                'expanded' => false,
149                'multiple' => true,
150                'attr'     => [
151                    'class'            => 'selectpicker',
152                    'data-live-search' => 'true',
153                    'title'            => 'global.placeholder.multiple_select',
154                    'aria-label'       => 'Origine de la perte de données',
155                ],
156            ])
157            ->add('cause', DictionaryType::class, [
158                'label'    => 'registry.violation.label.cause',
159                'name'     => 'registry_violation_cause',
160                'expanded' => true,
161                'multiple' => false,
162            ])
163            ->add('concernedDataNature', DictionaryType::class, [
164                'label'    => 'registry.violation.label.concerned_data_nature',
165                'name'     => 'registry_violation_concerned_data',
166                'expanded' => false,
167                'multiple' => true,
168                'attr'     => [
169                    'class'            => 'selectpicker',
170                    'data-live-search' => 'true',
171                    'title'            => 'global.placeholder.multiple_select',
172                    'aria-label'       => 'Nature des données concernées',
173                ],
174            ])
175            ->add('concernedPeopleCategories', DictionaryType::class, [
176                'label'    => 'registry.violation.label.concerned_people_categories',
177                'name'     => 'registry_violation_concerned_people',
178                'expanded' => false,
179                'multiple' => true,
180                'attr'     => [
181                    'class'            => 'selectpicker',
182                    'data-live-search' => 'true',
183                    'title'            => 'global.placeholder.multiple_select',
184                    'aria-label'       => 'Catégorie des personnes concernées',
185                ],
186            ])
187            ->add('nbAffectedRows', IntegerType::class, [
188                'label' => 'registry.violation.label.nb_affected_rows',
189                'attr'  => [
190                    'min' => 0,
191                    'max' => 999999999,
192                ],
193            ])
194            ->add('nbAffectedPersons', IntegerType::class, [
195                'label' => 'registry.violation.label.nb_affected_persons',
196                'attr'  => [
197                    'min' => 0,
198                    'max' => 999999999,
199                ],
200            ])
201            ->add('potentialImpactsNature', DictionaryType::class, [
202                'label'    => 'registry.violation.label.potential_impacts_nature',
203                'name'     => 'registry_violation_impact',
204                'expanded' => false,
205                'multiple' => true,
206                'attr'     => [
207                    'class'            => 'selectpicker',
208                    'data-live-search' => 'true',
209                    'title'            => 'global.placeholder.multiple_select',
210                    'aria-label'       => 'Nature des impacts potentiels pour les personnes',
211                ],
212            ])
213            ->add('gravity', DictionaryType::class, [
214                'label'    => 'registry.violation.label.gravity',
215                'name'     => 'registry_violation_gravity',
216                'expanded' => true,
217                'multiple' => false,
218            ])
219            ->add('communication', DictionaryType::class, [
220                'label'    => 'registry.violation.label.communication',
221                'name'     => 'registry_violation_communication',
222                'expanded' => true,
223                'multiple' => false,
224            ])
225            ->add('communicationPrecision', TextareaType::class, [
226                'label'    => 'registry.violation.label.communication_precision',
227                'required' => false,
228                'attr'     => [
229                    'rows' => 5,
230                ],
231                'purify_html' => true,
232            ])
233            ->add('appliedMeasuresAfterViolation', TextareaType::class, [
234                'label' => 'registry.violation.label.applied_measures_after_violation',
235                'attr'  => [
236                    'rows' => 5,
237                ],
238                'purify_html' => true,
239            ])
240            ->add('notification', DictionaryType::class, [
241                'label'    => 'registry.violation.label.notification',
242                'name'     => 'registry_violation_notification',
243                'required' => true,
244                'expanded' => true,
245                'multiple' => false,
246            ])
247            ->add('notificationDetails', TextType::class, [
248                'label'    => 'registry.violation.label.notification_details',
249                'required' => false,
250                'attr'     => [
251                    'maxlength' => 255,
252                ],
253                'purify_html' => true,
254            ])
255            ->add('comment', TextareaType::class, [
256                'label'    => 'registry.violation.label.comment',
257                'required' => false,
258                'attr'     => [
259                    'rows' => 5,
260                ],
261                'purify_html' => true,
262            ])
263            ->add('mesurements',
264                EntityType::class,
265                $this->getLinkedFormField(
266                    'global.label.linked_mesurement',
267                    Mesurement::class,
268                    $violation,
269                    'Actions de protection',
270                    ['status' => 'asc', 'name' => 'asc'],
271                ),
272            )
273            ->add('treatments', EntityType::class, $this->getLinkedFormField(
274                'global.label.linked_treatment',
275                Treatment::class,
276                $violation,
277                'Traitements',
278                ['active' => 'desc', 'name' => 'asc'],
279            ),
280            )
281            ->add('violations', EntityType::class, $this->getLinkedFormField(
282                'global.label.linked_violation',
283                Violation::class,
284                $violation,
285                'Violations',
286                ['deletedAt' => 'asc', 'date' => 'asc'],
287            ),
288            )
289            ->add('proofs', EntityType::class, $this->getLinkedFormField(
290                'global.label.linked_proof',
291                Proof::class,
292                $violation,
293                'Preuves',
294                ['deletedAt' => 'asc', 'name' => 'asc'],
295            ),
296            )
297            ->add('requests', EntityType::class, $this->getLinkedFormField(
298                'global.label.linked_request',
299                Request::class,
300                $violation,
301                'Demandes',
302                ['deletedAt' => 'asc', 'date' => 'asc'],
303            ),
304            )
305            ->add('contractors', EntityType::class, $this->getLinkedFormField(
306                'global.label.linked_contractor',
307                Contractor::class,
308                $violation,
309                'Sous-traitants',
310                ['name' => 'asc'],
311            ),
312            )
313
314            ->add('updatedBy', HiddenType::class, [
315                'required' => false,
316                'data'     => $user ? $user->getFirstName() . ' ' . strtoupper($user->getLastName()) : '',
317            ])
318        ;
319        if ($collectivity->isHasModuleTools()) {
320            $builder
321                ->add('tools', EntityType::class, $this->getLinkedFormField(
322                    'global.label.linked_tool',
323                    Tool::class,
324                    $violation,
325                    'Logiciels et supports',
326                ),
327                );
328        }
329    }
330
331    /**
332     * Provide type options.
333     */
334    public function configureOptions(OptionsResolver $resolver)
335    {
336        $resolver
337            ->setDefaults([
338                'data_class'        => Violation::class,
339                'validation_groups' => [
340                    'default',
341                    'violation',
342                ],
343            ]);
344    }
345}