|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the CMS Kernel package. |
|
5
|
|
|
* |
|
6
|
|
|
* Copyright (c) 2016-present LIN3S <[email protected]> |
|
7
|
|
|
* |
|
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
9
|
|
|
* file that was distributed with this source code. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace LIN3S\CMSKernel\Infrastructure\Symfony\Form\Type; |
|
13
|
|
|
|
|
14
|
|
|
use BenGorFile\File\Application\Query\FileOfIdHandler; |
|
15
|
|
|
use BenGorFile\File\Application\Query\FileOfIdQuery; |
|
16
|
|
|
use LIN3S\SharedKernel\Exception\InvalidArgumentException; |
|
17
|
|
|
use LIN3S\SharedKernel\Exception\LogicException; |
|
18
|
|
|
use Symfony\Component\Form\AbstractType; |
|
19
|
|
|
use Symfony\Component\Form\CallbackTransformer; |
|
20
|
|
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType; |
|
21
|
|
|
use Symfony\Component\Form\FormBuilderInterface; |
|
22
|
|
|
use Symfony\Component\Form\FormInterface; |
|
23
|
|
|
use Symfony\Component\Form\FormView; |
|
24
|
|
|
use Symfony\Component\OptionsResolver\OptionsResolver; |
|
25
|
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
|
26
|
|
|
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* @author Beñat Espiña <[email protected]> |
|
30
|
|
|
*/ |
|
31
|
|
|
class FileType extends AbstractType |
|
32
|
|
|
{ |
|
33
|
|
|
private $configuration; |
|
34
|
|
|
private $queryHandlers; |
|
35
|
|
|
private $implicitFileType; |
|
36
|
|
|
private $urlGenerator; |
|
37
|
|
|
|
|
38
|
|
|
public function __construct(UrlGeneratorInterface $urlGenerator, array $queryHandlers, array $configuration = null) |
|
39
|
|
|
{ |
|
40
|
|
|
$this->setQueryHandlers($queryHandlers); |
|
41
|
|
|
$this->configuration = $configuration; |
|
42
|
|
|
$this->urlGenerator = $urlGenerator; |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
View Code Duplication |
public function buildForm(FormBuilderInterface $builder, array $options) |
|
|
|
|
|
|
46
|
|
|
{ |
|
47
|
|
|
$builder |
|
48
|
|
|
->add('file', HiddenType::class, [ |
|
49
|
|
|
'attr' => array_key_exists('attr', $options) ? $options['attr'] : null, |
|
50
|
|
|
]) |
|
51
|
|
|
->addModelTransformer(new CallbackTransformer( |
|
52
|
|
|
function ($value) { |
|
53
|
|
|
return ['file' => $value]; |
|
54
|
|
|
}, |
|
55
|
|
|
function ($value) { |
|
56
|
|
|
return $value['file']; |
|
57
|
|
|
} |
|
58
|
|
|
)); |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
public function buildView(FormView $view, FormInterface $form, array $options) |
|
62
|
|
|
{ |
|
63
|
|
|
$this->implicitFileType = $form->getConfig()->getName(); |
|
64
|
|
|
$fileId = $form->get('file')->getData(); |
|
65
|
|
|
|
|
66
|
|
|
$filePreview = ''; |
|
67
|
|
|
if (null !== $fileId) { |
|
68
|
|
|
$filePreview = $this->queryHandler($this->fileType($options))->__invoke( |
|
69
|
|
|
new FileOfIdQuery($fileId) |
|
70
|
|
|
); |
|
71
|
|
|
|
|
72
|
|
|
$filePreview['preview_path'] = $this->getFilePreviewPath($filePreview['file_name'], $options); |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
$view->vars = array_merge( |
|
76
|
|
|
$view->vars, array_merge( |
|
77
|
|
|
$options, [ |
|
78
|
|
|
'file_preview' => $filePreview, |
|
79
|
|
|
'upload_endpoint' => $this->uploadEndpoint($options), |
|
80
|
|
|
'gallery_endpoint' => $this->galleryEndpoint($options), |
|
81
|
|
|
'mime_types' => $this->mimeTypes($options), |
|
82
|
|
|
] |
|
83
|
|
|
) |
|
84
|
|
|
); |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
public function configureOptions(OptionsResolver $resolver) |
|
88
|
|
|
{ |
|
89
|
|
|
$resolver->setDefined(['entry_file', 'upload_endpoint', 'gallery_endpoint', 'mime_types']); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
public function getBlockPrefix() |
|
93
|
|
|
{ |
|
94
|
|
|
return 'lin3s_cms_file'; |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
private function uploadEndpoint(array $options) |
|
98
|
|
|
{ |
|
99
|
|
|
if (!isset($options['upload_endpoint'])) { |
|
100
|
|
|
return $this->fromConfigFileType($options); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
return $options['upload_endpoint']; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
private function galleryEndpoint(array $options) |
|
107
|
|
|
{ |
|
108
|
|
|
if (!isset($options['gallery_endpoint'])) { |
|
109
|
|
|
return $this->fromConfigFileType($options, 'galleryEndpoint'); |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
return $options['gallery_endpoint']; |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
private function mimeTypes(array $options) |
|
116
|
|
|
{ |
|
117
|
|
|
if (isset($options['mime_types'])) { |
|
118
|
|
|
return $options['mime_types']; |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
if (!isset($this->configuration[$this->fileType($options)]['class'])) { |
|
122
|
|
|
throw new LogicException( |
|
123
|
|
|
'All the fallback are invalid. You can pass "entry_file" as option form, ' . |
|
124
|
|
|
'or you use implicit name of the form property, or also, you can pass ' . |
|
125
|
|
|
'explicitly the "mime_types" form options' |
|
126
|
|
|
); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
return forward_static_call_array([ |
|
130
|
|
|
$this->configuration[$this->fileType($options)]['class'], |
|
131
|
|
|
'availableMimeTypes', |
|
132
|
|
|
], []); |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
private function fromConfigFileType(array $options, $method = 'uploadEndpoint') |
|
136
|
|
|
{ |
|
137
|
|
|
$method = (new CamelCaseToSnakeCaseNameConverter())->normalize($method); |
|
138
|
|
|
|
|
139
|
|
|
return $this->configuration[$this->fileType($options)][$method]; |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
private function fileType(array $options) |
|
143
|
|
|
{ |
|
144
|
|
|
if (isset($options['entry_file']) && isset($this->configuration[$options['entry_file']])) { |
|
145
|
|
|
return $options['entry_file']; |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
if (!isset($this->configuration[$this->implicitFileType])) { |
|
149
|
|
|
throw new LogicException( |
|
150
|
|
|
'All the fallback are invalid. You can pass "entry_file" as option form, ' . |
|
151
|
|
|
'or you use implicit name of the form property, or also, you can pass ' . |
|
152
|
|
|
'explicitly the "upload_endpoint" and "gallery_endpoint" form options' |
|
153
|
|
|
); |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
return $this->implicitFileType; |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
private function queryHandler($fileType) |
|
160
|
|
|
{ |
|
161
|
|
|
if (!isset($this->queryHandlers[$fileType])) { |
|
162
|
|
|
throw new InvalidArgumentException( |
|
163
|
|
|
sprintf( |
|
164
|
|
|
'Does not exist any registered query handler with "%" file type', |
|
165
|
|
|
$fileType |
|
166
|
|
|
) |
|
167
|
|
|
); |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
return $this->queryHandlers[$fileType]; |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
private function setQueryHandlers(array $queryHandlers) |
|
174
|
|
|
{ |
|
175
|
|
|
$this->queryHandlers = array_map(function (FileOfIdHandler $fileOfIdHandler) { |
|
176
|
|
|
return $fileOfIdHandler; |
|
177
|
|
|
}, $queryHandlers); |
|
178
|
|
|
} |
|
179
|
|
|
|
|
180
|
|
|
private function getFilePreviewPath($filename, array $options) |
|
181
|
|
|
{ |
|
182
|
|
|
return $this->urlGenerator->generate( |
|
183
|
|
|
'bengor_file_' . $this->fileType($options) . '_download', |
|
184
|
|
|
[ |
|
185
|
|
|
'filename' => $filename, |
|
186
|
|
|
] |
|
187
|
|
|
); |
|
188
|
|
|
} |
|
189
|
|
|
} |
|
190
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.