Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.06% covered (warning)
88.06%
118 / 134
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
DocumentType
88.06% covered (warning)
88.06%
118 / 134
66.67% covered (warning)
66.67%
4 / 6
14.33
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
100.00% covered (success)
100.00%
53 / 53
100.00% covered (success)
100.00%
1 / 1
1
 configureOptions
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 getSubscribedEvents
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 setIsLink
79.66% covered (warning)
79.66%
47 / 59
0.00% covered (danger)
0.00%
0 / 1
5.21
 ensureOneFieldIsSubmitted
42.86% covered (danger)
42.86%
3 / 7
0.00% covered (danger)
0.00%
0 / 1
9.66
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\Documentation\Form\Type;
25
26use App\Domain\Documentation\Model;
27use Doctrine\ORM\EntityRepository;
28use Doctrine\ORM\QueryBuilder;
29use Symfony\Bridge\Doctrine\Form\Type\EntityType;
30use Symfony\Component\EventDispatcher\EventSubscriberInterface;
31use Symfony\Component\Form\AbstractType;
32use Symfony\Component\Form\Exception\TransformationFailedException;
33use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
34use Symfony\Component\Form\Extension\Core\Type\FileType;
35use Symfony\Component\Form\Extension\Core\Type\HiddenType;
36use Symfony\Component\Form\Extension\Core\Type\TextType;
37use Symfony\Component\Form\Extension\Core\Type\UrlType;
38use Symfony\Component\Form\FormBuilderInterface;
39use Symfony\Component\Form\FormEvent;
40use Symfony\Component\Form\FormEvents;
41use Symfony\Component\HttpFoundation\RequestStack;
42use Symfony\Component\OptionsResolver\OptionsResolver;
43use Symfony\Component\Validator\Constraints\File;
44use Symfony\Component\Validator\Constraints\Image;
45use Symfony\Contracts\Translation\TranslatorInterface;
46
47class DocumentType extends AbstractType implements EventSubscriberInterface
48{
49    private RequestStack $requestStack;
50    private string $maxSize;
51    private TranslatorInterface $translator;
52
53    public function __construct(RequestStack $requestStack, string $maxSize, TranslatorInterface $translator)
54    {
55        $this->requestStack = $requestStack;
56        $this->maxSize      = $maxSize;
57        $this->translator   = $translator;
58    }
59
60    /**
61     * Build type form.
62     */
63    public function buildForm(FormBuilderInterface $builder, array $options)
64    {
65        $request = $this->requestStack->getCurrentRequest();
66        $builder
67            ->add('isLink', HiddenType::class, [
68                'label'      => false,
69                'required'   => false,
70                'empty_data' => '0',
71            ])
72            ->add('name', TextType::class, [
73                'label'       => 'documentation.document.label.name',
74                'purify_html' => true,
75            ])
76            ->add('categories', EntityType::class, [
77                'label'         => 'documentation.document.label.categories',
78                'class'         => 'App\Domain\Documentation\Model\Category',
79                'query_builder' => function (EntityRepository $er): QueryBuilder {
80                    return $er->createQueryBuilder('c')
81                        ->orderBy('c.name', 'ASC');
82                },
83                'choice_label' => 'name',
84                'multiple'     => true,
85                'required'     => false,
86                'expanded'     => false,
87                'attr'         => [
88                    'class'            => 'selectpicker',
89                    'data-live-search' => 'true',
90                    'title'            => 'global.placeholder.multiple_select',
91                    'aria-label'       => 'Catégories',
92                ],
93            ])
94            ->add('thumbUploadedFile', FileType::class, [
95                'label'       => 'documentation.document.label.thumbnail',
96                'required'    => false,
97                'constraints' => [
98                    // Élément suivant commenté, car il génère un message d'erreur en plus de l'autre message
99                    // new Image(['groups' => ['default']]),
100                    new File([
101                        'maxSize'   => $this->maxSize,
102                        'groups'    => ['default'],
103                        'mimeTypes' => [
104                            'image/png', // .png
105                            'image/jpeg', // .jpg, .jpeg
106                        ],
107                        'mimeTypesMessage' => 'document_validator.document_file.thumbnail',
108                    ]),
109                ],
110                'attr' => [
111                    'accept' => 'image/*',
112                ],
113            ])
114
115            ->add('pinned', CheckboxType::class, [
116                'label'    => 'documentation.document.label.pinned',
117                'required' => false,
118            ])
119
120        ;
121
122        $builder->addEventSubscriber($this);
123    }
124
125    /**
126     * Provide type options.
127     */
128    public function configureOptions(OptionsResolver $resolver)
129    {
130        $resolver
131            ->setDefaults([
132                'data_class'        => Model\Document::class,
133                'validation_groups' => [
134                    'default',
135                    'document',
136                ],
137            ]);
138    }
139
140    public static function getSubscribedEvents()
141    {
142        return [
143            FormEvents::SUBMIT       => 'ensureOneFieldIsSubmitted',
144            FormEvents::PRE_SET_DATA => 'setIsLink',
145        ];
146    }
147
148    public function setIsLink(FormEvent $event)
149    {
150        $isLink = (bool) $this->requestStack->getCurrentRequest()->get('isLink');
151        $data   = $event->getData();
152        if (!$data->getId()) {
153            $data->setIsLink($isLink);
154        }
155        // $data->setIsLink($isLink);
156        $event->setData($data);
157
158        $form = $event->getForm();
159        if ($data->getThumbUrl()) {
160            $form->add('removeThumb', HiddenType::class, [
161                'label'    => 'documentation.document.action.removeThumb',
162                'required' => false,
163            ]);
164        }
165        if ($isLink || (true === $data->getIsLink())) {
166            $form->add('url', UrlType::class, [
167                'label'    => 'documentation.document.label.url',
168                'required' => true,
169            ]);
170            $form->add('isLink', HiddenType::class, [
171                'data' => 1,
172            ]);
173        } else {
174            $form->add('isLink', HiddenType::class, [
175                'data' => 0,
176            ]);
177            $form->add('uploadedFile', FileType::class, [
178                'label'       => 'documentation.document.label.file',
179                'required'    => !$data->getId(),
180                'constraints' => [
181                    new File([
182                        'maxSize'   => $this->maxSize,
183                        'groups'    => ['default'],
184                        'mimeTypes' => [
185                            'image/png', // .png
186                            'image/jpeg', // .jpg, .jpeg
187                            'audio/mpeg', // .mp3
188                            'audio/ogg', // .ogg
189                            'audio/wav', // .wav
190                            'audio/m4a', // .m4a
191                            'video/mp4', // .mp4
192                            'video/quicktime', // .mov
193                            'video/x-msvideo', // .avi
194                            'video/mpeg', // .mpg
195                            'video/x-ms-wmv', // .wmv
196                            'video/ogg', // .ogv, .ogg
197                            'video/webm', // .webm
198                            'application/pdf', // .pdf
199                            'application/msword', // .doc
200                            'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
201                            'application/vnd.oasis.opendocument.text', // .odt
202                            'application/vnd.ms-powerpoint', // .ppt
203                            'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
204                            'application/vnd.oasis.opendocument.presentation', // .odp
205                            'application/vnd.ms-excel', // .xls
206                            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
207                            'application/vnd.ms-excel.sheet.macroEnabled.12', // .xlsm
208                            'application/vnd.oasis.opendocument.spreadsheet', // .ods
209                        ],
210                        'mimeTypesMessage' => 'document_validator.document_file.file',
211                    ]),
212                ],
213            ]);
214        }
215    }
216
217    public function ensureOneFieldIsSubmitted(FormEvent $event)
218    {
219        $submittedData = $event->getData();
220
221        if (!$submittedData->getUploadedFile() && !$submittedData->getUrl()) {
222            $error = $this->translator->trans('documentation.document.form.error.fileorurl');
223
224            throw new TransformationFailedException($error, 400, /* code */ null, /* previous */ $error, /* user message */ ['{{ what }}' => 'aa'] /* message context for the translater */);
225        }
226
227        if (true === $submittedData->getIsLink() && !$submittedData->getUrl()) {
228            $error = $this->translator->trans('documentation.document.form.error.missingurl');
229
230            throw new TransformationFailedException($error, 400, /* code */ null, /* previous */ $error, /* user message */ ['{{ what }}' => 'aa'] /* message context for the translater */);
231        }
232    }
233}