Completed
Push — master ( 071097...7934b9 )
by
unknown
09:17
created

AbstractProvider::getFilenameByFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

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