Completed
Push — master ( c8c83d...485c1e )
by
unknown
06:17
created

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