Completed
Push — master ( 1cc057...1c0904 )
by
unknown
03:48
created

AbstractProvider::getPointOfInterestChoices()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 0
cts 34
cp 0
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 20
nc 1
nop 0
crap 2
1
<?php
2
3
namespace MediaMonks\SonataMediaBundle\Provider;
4
5
use League\Flysystem\Filesystem;
6
use MediaMonks\SonataMediaBundle\Entity\Media;
7
use MediaMonks\SonataMediaBundle\Model\MediaInterface;
8
use Sonata\AdminBundle\Form\FormMapper;
9
use Sonata\CoreBundle\Validator\ErrorElement;
10
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
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
     * @param Filesystem $filesystem
46
     */
47
    public function setFilesystem(Filesystem $filesystem)
48
    {
49
        $this->filesystem = $filesystem;
50
    }
51
52
    /**
53
     * @param TranslatorInterface $translator
54
     */
55
    public function setTranslator(TranslatorInterface $translator)
56
    {
57
        $this->translator = $translator;
58
    }
59
60
    /**
61
     * @return \Symfony\Component\Translation\TranslatorInterface
62
     */
63
    public function getTranslator()
64
    {
65
        return $this->translator;
66
    }
67
68
    /**
69
     * @param array $options
70
     */
71
    public function setImageConstraintOptions(array $options)
72
    {
73
        $this->imageConstraintOptions = $options;
74
    }
75
76
    /**
77
     * @return Filesystem
78
     */
79
    public function getFilesystem()
80
    {
81
        return $this->filesystem;
82
    }
83
84
    /**
85
     * @param Media $media
86
     * @param $providerReferenceUpdated
87
     */
88
    public function update(Media $media, $providerReferenceUpdated)
89
    {
90
        $this->updateImage($media);
91
    }
92
93
    /**
94
     * @return string
95
     */
96
    public function getTranslationDomain()
97
    {
98
        return 'MediaMonksSonataMediaBundle';
99
    }
100
101
    /**
102
     * @param MediaInterface $media
103
     * @param array $options
104
     * @return array
105
     */
106
    public function toArray(MediaInterface $media, array $options = [])
107
    {
108
        return [
109
            'type'        => $this->getName(),
110
            'title'       => $media->getTitle(),
111
            'description' => $media->getDescription(),
112
            'authorName'  => $media->getAuthorName(),
113
            'copyright'   => $media->getCopyright(),
114
            'reference'   => $media->getProviderReference(),
115
        ];
116
    }
117
118
    /**
119
     * @return array
120
     */
121
    protected function getFocalPoint()
122
    {
123
        return array_flip(
124
            [
125
                'top-left'     => $this->translator->trans(
126
                    'form.image_focal_point.top_left'
127
                ),
128
                'top'          => $this->translator->trans(
129
                    'form.image_focal_point.top'
130
                ),
131
                'top-right'    => $this->translator->trans(
132
                    'form.image_focal_point.top_right'
133
                ),
134
                'left'         => $this->translator->trans(
135
                    'form.image_focal_point.left'
136
                ),
137
                'center'       => $this->translator->trans(
138
                    'form.image_focal_point.center'
139
                ),
140
                'right'        => $this->translator->trans(
141
                    'form.image_focal_point.right'
142
                ),
143
                'bottom-left'  => $this->translator->trans(
144
                    'form.image_focal_point.bottom_left'
145
                ),
146
                'bottom'       => $this->translator->trans(
147
                    'form.image_focal_point.bottom'
148
                ),
149
                'bottom-right' => $this->translator->trans(
150
                    'form.image_focal_point.bottom_right'
151
                ),
152
            ]
153
        );
154
    }
155
156
    /**
157
     * @param FormMapper $formMapper
158
     */
159
    public function buildCreateForm(FormMapper $formMapper)
160
    {
161
        $formMapper
162
            ->add('provider', 'hidden');
163
164
        $this->buildProviderCreateForm($formMapper);
165
    }
166
167
    /**
168
     * @param FormMapper $formMapper
169
     */
170
    public function buildEditForm(FormMapper $formMapper)
171
    {
172
        $formMapper
173
            ->tab('General')
174
            ->add('provider', HiddenType::class);
175
176
        $this->buildProviderEditFormBefore($formMapper);
177
178
        $formMapper->add(
179
            'imageContent',
180
            'file',
181
            [
182
                'required'    => false,
183
                'constraints' => [
184
                    new Constraint\File(),
185
                ],
186
                'label'       => 'form.replacement_image',
187
            ]
188
        )
189
            ->add('title', TextType::class, ['label' => 'form.title'])
190
            ->add(
191
                'description',
192
                TextType::class,
193
                ['label' => 'form.description', 'required' => false]
194
            )
195
            ->add(
196
                'authorName',
197
                TextType::class,
198
                ['label' => 'form.authorName', 'required' => false]
199
            )
200
            ->add(
201
                'copyright',
202
                TextType::class,
203
                ['label' => 'form.copyright', 'required' => false]
204
            )
205
            ->end()
206
            ->end()
207
            ->tab('Image')
208
            ->add(
209
                'focalPoint',
210
                ChoiceType::class,
211
                [
212
                    'required' => false,
213
                    'label'    => 'form.image_focal_point',
214
                    'choices'  => $this->getFocalPoint(),
215
                ]
216
            )
217
            ->end()
218
            ->end()
219
        ;
220
221
        $this->buildProviderEditFormAfter($formMapper);
222
    }
223
224
    /**
225
     * @param FormMapper $formMapper
226
     */
227
    public function buildProviderEditFormBefore(FormMapper $formMapper)
228
    {
229
    }
230
231
    /**
232
     * @param FormMapper $formMapper
233
     */
234
    public function buildProviderEditFormAfter(FormMapper $formMapper)
235
    {
236
    }
237
238
    /**
239
     * @param Media $media
240
     * @param bool $useAsImage
241
     * @return string|void
242
     */
243
    protected function handleFileUpload(Media $media, $useAsImage = false)
244
    {
245
        /**
246
         * @var UploadedFile $file
247
         */
248
        $file = $media->getBinaryContent();
249
250
        if (empty($file)) {
251
            return;
252
        }
253
254
        $filename = $this->getFilenameByFile($file);
255
        $this->writeToFilesystem($file, $filename);
256
257
        $media->setProviderMetadata(
258
            array_merge(
259
                $media->getProviderMetaData(),
260
                $this->getFileMetaData($file)
261
            )
262
        );
263
264
        if (empty($media->getImage()) && $useAsImage) {
265
            $media->setImage($filename);
266
            $media->setImageMetaData($media->getProviderMetaData());
267
        }
268
269
        if (empty($media->getTitle())) {
270
            $media->setTitle(
271
                str_replace(
272
                    '_',
273
                    ' ',
274
                    pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)
275
                )
276
            );
277
        }
278
279
        return $filename;
280
    }
281
282
    /**
283
     * @param UploadedFile $file
284
     * @return array
285
     */
286
    protected function getFileMetaData(UploadedFile $file)
287
    {
288
        return [
289
            'originalName'      => $file->getClientOriginalName(),
290
            'originalExtension' => $file->getClientOriginalExtension(),
291
            'mimeType'          => $file->getClientMimeType(),
292
            'size'              => $file->getSize(),
293
        ];
294
    }
295
296
    /**
297
     * @param Media $media
298
     */
299
    public function updateImage(Media $media)
300
    {
301
        /**
302
         * @var UploadedFile $file
303
         */
304
        $file = $media->getImageContent();
305
        if (empty($file)) {
306
            return;
307
        }
308
309
        $filename = $this->getFilenameByFile($file);
310
        $this->writeToFilesystem($file, $filename);
311
312
        $media->setImage($filename);
313
        $media->setImageMetaData($this->getFileMetaData($file));
314
    }
315
316
    /**
317
     * @param \Sonata\AdminBundle\Form\FormMapper $formMapper
318
     * @param $name
319
     * @param $label
320
     * @param $required
321
     * @param array $constraints
322
     */
323
    protected function doAddFileField(
324
        FormMapper $formMapper,
325
        $name,
326
        $label,
327
        $required,
328
        $constraints = []
329
    ) {
330
        if ($required) {
331
            $constraints = array_merge(
332
                [
333
                    new Constraint\NotBlank(),
334
                    new Constraint\NotNull(),
335
                ],
336
                $constraints
337
            );
338
        }
339
340
        $formMapper
341
            ->add(
342
                $name,
343
                FileType::class,
344
                [
345
                    'multiple'    => false,
346
                    'data_class'  => null,
347
                    'constraints' => $constraints,
348
                    'label'       => $label,
349
                    'required'    => $required,
350
                ]
351
            );
352
    }
353
354
    /**
355
     * @param FormMapper $formMapper
356
     * @param string $name
357
     * @param string $label
358
     * @param array $options
359
     */
360 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...
361
        FormMapper $formMapper,
362
        $name,
363
        $label,
364
        $options = []
365
    ) {
366
        $this->doAddFileField(
367
            $formMapper,
368
            $name,
369
            $label,
370
            false,
371
            [
372
                new Constraint\Image(
373
                    array_merge($this->imageConstraintOptions, $options)
374
                ),
375
            ]
376
        );
377
    }
378
379
    /**
380
     * @param FormMapper $formMapper
381
     * @param $name
382
     * @param $label
383
     * @param array $options
384
     */
385 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...
386
        FormMapper $formMapper,
387
        $name,
388
        $label,
389
        $options = []
390
    ) {
391
        $this->doAddFileField(
392
            $formMapper,
393
            $name,
394
            $label,
395
            true,
396
            [
397
                new Constraint\Image(
398
                    array_merge($this->imageConstraintOptions, $options)
399
                ),
400
            ]
401
        );
402
    }
403
404
    /**
405
     * @param UploadedFile $file
406
     * @return string
407
     */
408
    protected function getFilenameByFile(UploadedFile $file)
409
    {
410
        return sprintf(
411
            '%s_%d.%s',
412
            sha1($file->getClientOriginalName()),
413
            time(),
414
            $file->getClientOriginalExtension()
415
        );
416
    }
417
418
    /**
419
     * @param UploadedFile $file
420
     * @param $filename
421
     * @throws \Exception
422
     */
423
    protected function writeToFilesystem(UploadedFile $file, $filename)
424
    {
425
        set_error_handler(
426
            function () {
427
            }
428
        );
429
        $stream = fopen($file->getRealPath(), 'r+');
430
        $written = $this->getFilesystem()->writeStream($filename, $stream);
431
        fclose($stream); // this sometime messes up
432
        restore_error_handler();
433
434
        if (!$written) {
435
            throw new \Exception('Could not write to file system');
436
        }
437
    }
438
439
    /**
440
     * @param $renderType
441
     * @return boolean
442
     */
443
    public function supports($renderType)
444
    {
445
        if ($renderType === self::SUPPORT_EMBED) {
446
            return $this->supportsEmbed();
447
        }
448
        if ($renderType === self::SUPPORT_IMAGE) {
449
            return $this->supportsImage();
450
        }
451
        if ($renderType === self::SUPPORT_DOWNLOAD) {
452
            return $this->supportsDownload();
453
        }
454
455
        return false;
456
    }
457
458
    /**
459
     *
460
     */
461
    protected function disableErrorHandler()
462
    {
463
        set_error_handler(
464
            function () {
465
            }
466
        );
467
    }
468
469
    /**
470
     *
471
     */
472
    protected function restoreErrorHandler()
473
    {
474
        restore_error_handler();
475
    }
476
477
    /**
478
     * @param ErrorElement $errorElement
479
     * @param Media $media
480
     */
481
    public function validate(ErrorElement $errorElement, Media $media)
482
    {
483
    }
484
485
    /**
486
     * @return string
487
     */
488
    public function getEmbedTemplate()
489
    {
490
        return sprintf(
491
            'MediaMonksSonataMediaBundle:Provider:%s_embed.html.twig',
492
            $this->getName()
493
        );
494
    }
495
496
    /**
497
     * @return string
498
     */
499
    public function getTitle()
500
    {
501
        return $this->translator->trans($this->getName());
502
    }
503
}
504