Completed
Push — master ( 01eb52...fc03c7 )
by
unknown
19:01
created

AbstractProvider::buildEditForm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 38
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 47
ccs 38
cts 38
cp 1
rs 9.0303
c 0
b 0
f 0
cc 1
eloc 33
nc 1
nop 1
crap 1
1
<?php
2
3
namespace MediaMonks\SonataMediaBundle\Provider;
4
5
use League\Flysystem\Filesystem;
6
use MediaMonks\SonataMediaBundle\Model\AbstractMedia;
7
use MediaMonks\SonataMediaBundle\Form\Type\MediaFocalPointType;
8
use MediaMonks\SonataMediaBundle\Model\MediaInterface;
9
use Sonata\AdminBundle\Form\FormMapper;
10
use Sonata\CoreBundle\Validator\ErrorElement;
11
use Symfony\Component\Form\Extension\Core\Type\FileType;
12
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
13
use Symfony\Component\Form\Extension\Core\Type\TextType;
14
use Symfony\Component\HttpFoundation\File\UploadedFile;
15
use Symfony\Component\Translation\TranslatorInterface;
16
use Symfony\Component\Validator\Constraints as Constraint;
17
18
abstract class AbstractProvider implements ProviderInterface
19
{
20
    const SUPPORT_EMBED = 'embed';
21
    const SUPPORT_IMAGE = 'image';
22
    const SUPPORT_DOWNLOAD = 'download';
23
24
    const TYPE_AUDIO = 'audio';
25
    const TYPE_IMAGE = 'image';
26
    const TYPE_FILE = 'file';
27
    const TYPE_VIDEO = 'video';
28
29
    /**
30
     * @var Filesystem
31
     */
32
    protected $filesystem;
33
34
    /**
35
     * @var TranslatorInterface
36
     */
37
    private $translator;
38
39
    /**
40
     * @var array
41
     */
42
    private $imageConstraintOptions = [];
43
44
    /**
45
     * @var AbstractMedia
46
     */
47
    private $media;
48
49
    /**
50
     * @param Filesystem $filesystem
51
     */
52 4
    public function setFilesystem(Filesystem $filesystem)
53
    {
54 4
        $this->filesystem = $filesystem;
55 4
    }
56
57
    /**
58
     * @param TranslatorInterface $translator
59
     */
60 4
    public function setTranslator(TranslatorInterface $translator)
61
    {
62 4
        $this->translator = $translator;
63 4
    }
64
65
    /**
66
     * @return \Symfony\Component\Translation\TranslatorInterface
67
     */
68
    public function getTranslator()
69
    {
70
        return $this->translator;
71
    }
72
73
    /**
74
     * @param array $options
75
     */
76 4
    public function setImageConstraintOptions(array $options)
77
    {
78 4
        $this->imageConstraintOptions = $options;
79 4
    }
80
81
    /**
82
     * @return Filesystem
83
     */
84 1
    public function getFilesystem()
85
    {
86 1
        return $this->filesystem;
87
    }
88
89
    /**
90
     * @param AbstractMedia $media
91
     * @return AbstractProvider
92
     */
93 1
    public function setMedia($media)
94
    {
95 1
        $this->media = $media;
96
97 1
        return $this;
98
    }
99
100
    /**
101
     * @param AbstractMedia $media
102
     * @param $providerReferenceUpdated
103
     */
104 1
    public function update(AbstractMedia $media, $providerReferenceUpdated)
105
    {
106 1
        $this->updateImage($media);
107 1
    }
108
109
    /**
110
     * @return string
111
     */
112
    public function getTranslationDomain()
113
    {
114
        return 'MediaMonksSonataMediaBundle';
115
    }
116
117
    /**
118
     * @param MediaInterface $media
119
     * @param array $options
120
     * @return array
121
     */
122
    public function toArray(MediaInterface $media, array $options = [])
123
    {
124
        return [
125
            'type'        => $this->getName(),
126
            'title'       => $media->getTitle(),
127
            'description' => $media->getDescription(),
128
            'authorName'  => $media->getAuthorName(),
129
            'copyright'   => $media->getCopyright(),
130
            'reference'   => $media->getProviderReference(),
131
        ];
132
    }
133
134
    /**
135
     * @param FormMapper $formMapper
136
     */
137 1
    public function buildCreateForm(FormMapper $formMapper)
138
    {
139
        $formMapper
140 1
            ->add('provider', 'hidden');
141
142 1
        $this->buildProviderCreateForm($formMapper);
143 1
    }
144
145
    /**
146
     * @param FormMapper $formMapper
147
     */
148 1
    public function buildEditForm(FormMapper $formMapper)
149
    {
150
        $formMapper
151 1
            ->tab('general')
152 1
            ->add('provider', HiddenType::class);
153
154 1
        $this->buildProviderEditFormBefore($formMapper);
155
156 1
        $formMapper->add(
157 1
            'imageContent',
158 1
            'file',
159
            [
160 1
                'required'    => false,
161
                'constraints' => [
162 1
                    new Constraint\File(),
163 1
                ],
164 1
                'label'       => 'form.replacement_image',
165
            ]
166 1
        )
167 1
            ->add('title', TextType::class, ['label' => 'form.title'])
168 1
            ->add(
169 1
                'description',
170 1
                TextType::class,
171 1
                ['label' => 'form.description', 'required' => false]
172 1
            )
173 1
            ->add(
174 1
                'authorName',
175 1
                TextType::class,
176 1
                ['label' => 'form.authorName', 'required' => false]
177 1
            )
178 1
            ->add(
179 1
                'copyright',
180 1
                TextType::class,
181 1
                ['label' => 'form.copyright', 'required' => false]
182 1
            )
183 1
            ->end()
184 1
            ->end()
185 1
            ->tab('image')
186 1
            ->add('focalPoint', MediaFocalPointType::class, [
187 1
                'media' => $this->media
188 1
            ])
189 1
            ->end()
190 1
            ->end()
191
        ;
192
193 1
        $this->buildProviderEditFormAfter($formMapper);
194 1
    }
195
196
    /**
197
     * @param FormMapper $formMapper
198
     */
199
    public function buildProviderEditFormBefore(FormMapper $formMapper)
200
    {
201
    }
202
203
    /**
204
     * @param FormMapper $formMapper
205
     */
206 1
    public function buildProviderEditFormAfter(FormMapper $formMapper)
207
    {
208 1
    }
209
210
    /**
211
     * @param AbstractMedia $media
212
     * @param bool $useAsImage
213
     * @return string|void
214
     */
215
    protected function handleFileUpload(AbstractMedia $media, $useAsImage = false)
216
    {
217
        /**
218
         * @var UploadedFile $file
219
         */
220
        $file = $media->getBinaryContent();
221
222
        if (empty($file)) {
223
            return;
224
        }
225
226
        $filename = $this->getFilenameByFile($file);
227
        $this->writeToFilesystem($file, $filename);
228
229
        $media->setProviderMetadata(
230
            array_merge(
231
                $media->getProviderMetaData(),
232
                $this->getFileMetaData($file)
233
            )
234
        );
235
236
        if (empty($media->getImage()) && $useAsImage) {
237
            $media->setImage($filename);
238
            $media->setImageMetaData($media->getProviderMetaData());
239
        }
240
241
        if (empty($media->getTitle())) {
242
            $media->setTitle(
243
                str_replace(
244
                    '_',
245
                    ' ',
246
                    pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)
247
                )
248
            );
249
        }
250
251
        return $filename;
252
    }
253
254
    /**
255
     * @param UploadedFile $file
256
     * @return array
257
     */
258
    protected function getFileMetaData(UploadedFile $file)
259
    {
260
        $fileData = [
261
            'originalName'      => $file->getClientOriginalName(),
262
            'originalExtension' => $file->getClientOriginalExtension(),
263
            'mimeType'          => $file->getClientMimeType(),
264
            'size'              => $file->getSize(),
265
        ];
266
267
        if (strpos($file->getClientMimeType(), 'image') !== false) {
268
            $this->disableErrorHandler();
269
            $imageSize = getimagesize($file->getRealPath());
270
            if (is_array($imageSize)) {
271
                list($width, $height) = $imageSize;
272
                if (is_int($width) && is_int($height)) {
273
                    $fileData['height'] = $height;
274
                    $fileData['width']  = $width;
275
                }
276
            }
277
            $this->restoreErrorHandler();
278
        }
279
280
        return $fileData;
281
    }
282
283
    /**
284
     * @param AbstractMedia $media
285
     */
286 1
    public function updateImage(AbstractMedia $media)
287
    {
288
        /**
289
         * @var UploadedFile $file
290
         */
291 1
        $file = $media->getImageContent();
292 1
        if (empty($file)) {
293 1
            return;
294
        }
295
296
        $filename = $this->getFilenameByFile($file);
297
        $this->writeToFilesystem($file, $filename);
298
299
        $media->setImage($filename);
300
        $media->setImageMetaData($this->getFileMetaData($file));
301
    }
302
303
    /**
304
     * @param \Sonata\AdminBundle\Form\FormMapper $formMapper
305
     * @param $name
306
     * @param $label
307
     * @param $required
308
     * @param array $constraints
309
     */
310
    protected function doAddFileField(
311
        FormMapper $formMapper,
312
        $name,
313
        $label,
314
        $required,
315
        $constraints = []
316
    ) {
317
        if ($required) {
318
            $constraints = array_merge(
319
                [
320
                    new Constraint\NotBlank(),
321
                    new Constraint\NotNull(),
322
                ],
323
                $constraints
324
            );
325
        }
326
327
        $formMapper
328
            ->add(
329
                $name,
330
                FileType::class,
331
                [
332
                    'multiple'    => false,
333
                    'data_class'  => null,
334
                    'constraints' => $constraints,
335
                    'label'       => $label,
336
                    'required'    => $required,
337
                ]
338
            );
339
    }
340
341
    /**
342
     * @param FormMapper $formMapper
343
     * @param string $name
344
     * @param string $label
345
     * @param array $options
346
     */
347 View Code Duplication
    public function addImageField(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
348
        FormMapper $formMapper,
349
        $name,
350
        $label,
351
        $options = []
352
    ) {
353
        $this->doAddFileField(
354
            $formMapper,
355
            $name,
356
            $label,
357
            false,
358
            [
359
                new Constraint\Image(
360
                    array_merge($this->imageConstraintOptions, $options)
361
                ),
362
            ]
363
        );
364
    }
365
366
    /**
367
     * @param FormMapper $formMapper
368
     * @param $name
369
     * @param $label
370
     * @param array $options
371
     */
372 View Code Duplication
    public function addRequiredImageField(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
373
        FormMapper $formMapper,
374
        $name,
375
        $label,
376
        $options = []
377
    ) {
378
        $this->doAddFileField(
379
            $formMapper,
380
            $name,
381
            $label,
382
            true,
383
            [
384
                new Constraint\Image(
385
                    array_merge($this->imageConstraintOptions, $options)
386
                ),
387
            ]
388
        );
389
    }
390
391
    /**
392
     * @param UploadedFile $file
393
     * @return string
394
     */
395
    protected function getFilenameByFile(UploadedFile $file)
396
    {
397
        return sprintf(
398
            '%s_%d.%s',
399
            sha1($file->getClientOriginalName()),
400
            time(),
401
            $file->getClientOriginalExtension()
402
        );
403
    }
404
405
    /**
406
     * @param UploadedFile $file
407
     * @param $filename
408
     * @throws \Exception
409
     */
410
    protected function writeToFilesystem(UploadedFile $file, $filename)
411
    {
412
        $this->disableErrorHandler();
413
        $stream = fopen($file->getRealPath(), 'r+');
414
        $written = $this->getFilesystem()->writeStream($filename, $stream);
415
        fclose($stream); // this sometime messes up
416
        $this->restoreErrorHandler();
417
418
        if (!$written) {
419
            throw new \Exception('Could not write to file system');
420
        }
421
    }
422
423
    /**
424
     * @param $renderType
425
     * @return boolean
426
     */
427 1
    public function supports($renderType)
428
    {
429 1
        if ($renderType === self::SUPPORT_EMBED) {
430 1
            return $this->supportsEmbed();
431
        }
432 1
        if ($renderType === self::SUPPORT_IMAGE) {
433 1
            return $this->supportsImage();
434
        }
435 1
        if ($renderType === self::SUPPORT_DOWNLOAD) {
436 1
            return $this->supportsDownload();
437
        }
438
439
        return false;
440
    }
441
442
    /**
443
     *
444
     */
445 1
    protected function disableErrorHandler()
446
    {
447 1
        set_error_handler(
448
            function () {
449
            }
450 1
        );
451 1
    }
452
453
    /**
454
     *
455
     */
456 1
    protected function restoreErrorHandler()
457
    {
458 1
        restore_error_handler();
459 1
    }
460
461
    /**
462
     * @param ErrorElement $errorElement
463
     * @param AbstractMedia $media
464
     */
465
    public function validate(ErrorElement $errorElement, AbstractMedia $media)
466
    {
467
    }
468
469
    /**
470
     * @return string
471
     */
472
    public function getEmbedTemplate()
473
    {
474
        return sprintf(
475
            'MediaMonksSonataMediaBundle:Provider:%s_embed.html.twig',
476
            $this->getName()
477
        );
478
    }
479
480
    /**
481
     * @return string
482
     */
483
    public function getTitle()
484
    {
485
        return $this->translator->trans($this->getName());
486
    }
487
}
488