Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.06% |
118 / 134 |
|
66.67% |
4 / 6 |
CRAP | |
0.00% |
0 / 1 |
DocumentType | |
88.06% |
118 / 134 |
|
66.67% |
4 / 6 |
14.33 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
buildForm | |
100.00% |
53 / 53 |
|
100.00% |
1 / 1 |
1 | |||
configureOptions | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
getSubscribedEvents | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
setIsLink | |
79.66% |
47 / 59 |
|
0.00% |
0 / 1 |
5.21 | |||
ensureOneFieldIsSubmitted | |
42.86% |
3 / 7 |
|
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 | |
22 | declare(strict_types=1); |
23 | |
24 | namespace App\Domain\Documentation\Form\Type; |
25 | |
26 | use App\Domain\Documentation\Model; |
27 | use Doctrine\ORM\EntityRepository; |
28 | use Doctrine\ORM\QueryBuilder; |
29 | use Symfony\Bridge\Doctrine\Form\Type\EntityType; |
30 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
31 | use Symfony\Component\Form\AbstractType; |
32 | use Symfony\Component\Form\Exception\TransformationFailedException; |
33 | use Symfony\Component\Form\Extension\Core\Type\CheckboxType; |
34 | use Symfony\Component\Form\Extension\Core\Type\FileType; |
35 | use Symfony\Component\Form\Extension\Core\Type\HiddenType; |
36 | use Symfony\Component\Form\Extension\Core\Type\TextType; |
37 | use Symfony\Component\Form\Extension\Core\Type\UrlType; |
38 | use Symfony\Component\Form\FormBuilderInterface; |
39 | use Symfony\Component\Form\FormEvent; |
40 | use Symfony\Component\Form\FormEvents; |
41 | use Symfony\Component\HttpFoundation\RequestStack; |
42 | use Symfony\Component\OptionsResolver\OptionsResolver; |
43 | use Symfony\Component\Validator\Constraints\File; |
44 | use Symfony\Component\Validator\Constraints\Image; |
45 | use Symfony\Contracts\Translation\TranslatorInterface; |
46 | |
47 | class 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 | } |