Completed
Push — master ( 9f73c5...5f3db3 )
by
unknown
11:12
created

AbstractProvider::getFileLocator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace MediaMonks\SonataMediaBundle\Provider;
4
5
use League\Flysystem\Filesystem;
6
use League\Glide\Filesystem\FilesystemException;
7
use MediaMonks\SonataMediaBundle\Client\HttpClientInterface;
8
use MediaMonks\SonataMediaBundle\ErrorHandlerTrait;
9
use MediaMonks\SonataMediaBundle\Model\AbstractMedia;
10
use MediaMonks\SonataMediaBundle\Form\Type\MediaFocalPointType;
11
use Sonata\AdminBundle\Form\FormMapper;
12
use Sonata\CoreBundle\Validator\ErrorElement;
13
use Symfony\Component\Form\Extension\Core\Type\FileType;
14
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
15
use Symfony\Component\Form\Extension\Core\Type\TextType;
16
use Symfony\Component\HttpFoundation\File\UploadedFile;
17
use Symfony\Component\HttpKernel\Config\FileLocator;
18
use Symfony\Component\Translation\TranslatorInterface;
19
use Symfony\Component\Validator\Constraints as Constraint;
20
21
abstract class AbstractProvider implements ProviderInterface
22
{
23
    use ErrorHandlerTrait;
24
25
    const SUPPORT_EMBED = 'embed';
26
    const SUPPORT_IMAGE = 'image';
27
    const SUPPORT_DOWNLOAD = 'download';
28
29
    const TYPE_AUDIO = 'audio';
30
    const TYPE_IMAGE = 'image';
31
    const TYPE_FILE = 'file';
32
    const TYPE_VIDEO = 'video';
33
34
    /**
35
     * @var Filesystem
36
     */
37
    protected $filesystem;
38
39
    /**
40
     * @var TranslatorInterface
41
     */
42
    private $translator;
43
44
    /**
45
     * @var array
46
     */
47
    private $imageConstraintOptions = [];
48
49
    /**
50
     * @var HttpClientInterface
51
     */
52
    private $httpClient;
53
54
    /**
55
     * @var FileLocator
56
     */
57
    private $fileLocator;
58
59
    /**
60
     * @var AbstractMedia
61
     */
62
    private $media;
63
64
    /**
65
     * @param Filesystem $filesystem
66
     */
67 14
    public function setFilesystem(Filesystem $filesystem)
68
    {
69 14
        $this->filesystem = $filesystem;
70 14
    }
71
72
    /**
73
     * @param TranslatorInterface $translator
74
     */
75 13
    public function setTranslator(TranslatorInterface $translator)
76
    {
77 13
        $this->translator = $translator;
78 13
    }
79
80
    /**
81
     * @return \Symfony\Component\Translation\TranslatorInterface
82
     */
83 1
    public function getTranslator()
84
    {
85 1
        return $this->translator;
86
    }
87
88
    /**
89
     * @param array $options
90
     */
91 13
    public function setImageConstraintOptions(array $options)
92
    {
93 13
        $this->imageConstraintOptions = $options;
94 13
    }
95
96
    /**
97
     * @param HttpClientInterface $httpClient
98
     */
99 13
    public function setHttpClient(HttpClientInterface $httpClient)
100
    {
101 13
        $this->httpClient = $httpClient;
102 13
    }
103
104
    /**
105
     * @return FileLocator
106
     */
107 2
    public function getFileLocator()
108
    {
109 2
        return $this->fileLocator;
110
    }
111
112
    /**
113
     * @param FileLocator $fileLocator
114
     */
115 13
    public function setFileLocator(FileLocator $fileLocator)
116
    {
117 13
        $this->fileLocator = $fileLocator;
118 13
    }
119
120
    /**
121
     * @return HttpClientInterface
122
     */
123 4
    public function getHttpClient()
124
    {
125 4
        return $this->httpClient;
126
    }
127
128
    /**
129
     * @return Filesystem
130
     */
131 8
    public function getFilesystem()
132
    {
133 8
        return $this->filesystem;
134
    }
135
136
    /**
137
     * @param AbstractMedia $media
138
     * @return AbstractProvider
139
     */
140 11
    public function setMedia($media)
141
    {
142 11
        $this->media = $media;
143
144 11
        return $this;
145
    }
146
147
    /**
148
     * @param AbstractMedia $media
149
     * @param $providerReferenceUpdated
150
     */
151 7
    public function update(AbstractMedia $media, $providerReferenceUpdated)
152
    {
153 7
        $this->updateImage($media);
154 7
    }
155
156
    /**
157
     * @param FormMapper $formMapper
158
     */
159 11
    public function buildCreateForm(FormMapper $formMapper)
160
    {
161
        $formMapper
162 11
            ->add('provider', 'hidden');
163
164 11
        $this->buildProviderCreateForm($formMapper);
165 11
    }
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
290 4
        $this->disableErrorHandler();
291 4
        $imageSize = getimagesize($file->getRealPath());
292 4
        if (is_array($imageSize)) {
293 4
            if (is_int($imageSize[0]) && is_int($imageSize[1])) {
294 4
                $fileData['height'] = $imageSize[0];
295 4
                $fileData['width']  = $imageSize[1];
296
            }
297 4
            if (isset($imageSize['bits'])) {
298 4
                $fileData['bits'] = $imageSize['bits'];
299
            }
300 4
            if (isset($imageSize['channels'])) {
301 2
                $fileData['channels'] = $imageSize['channels'];
302
            }
303
        }
304 4
        $this->restoreErrorHandler();
305
306 4
        return $fileData;
307
    }
308
309
    /**
310
     * @param AbstractMedia $media
311
     */
312 7
    public function updateImage(AbstractMedia $media)
313
    {
314
        /**
315
         * @var UploadedFile $file
316
         */
317 7
        $file = $media->getImageContent();
318 7
        if (empty($file)) {
319 5
            return;
320
        }
321
322 2
        $filename = $this->getFilenameByFile($file);
323 2
        $this->writeToFilesystem($file, $filename);
324
325 2
        $media->setImage($filename);
326 2
        $media->setImageMetaData($this->getFileMetaData($file));
327 2
    }
328
329
    /**
330
     * @param \Sonata\AdminBundle\Form\FormMapper $formMapper
331
     * @param $name
332
     * @param $label
333
     * @param $required
334
     * @param array $constraints
335
     */
336 7
    protected function doAddFileField(
337
        FormMapper $formMapper,
338
        $name,
339
        $label,
340
        $required,
341
        $constraints = []
342
    ) {
343 7
        if ($required) {
344 7
            $constraints = array_merge(
345
                [
346 7
                    new Constraint\NotBlank(),
347 7
                    new Constraint\NotNull(),
348
                ],
349 7
                $constraints
350
            );
351
        }
352
353
        $formMapper
354 7
            ->add(
355
                $name,
356 7
                FileType::class,
357
                [
358 7
                    'multiple'    => false,
359
                    'data_class'  => null,
360 7
                    'constraints' => $constraints,
361 7
                    'label'       => $label,
362 7
                    'required'    => $required,
363
                ]
364
            );
365 7
    }
366
367
    /**
368
     * @param FormMapper $formMapper
369
     * @param string $name
370
     * @param string $label
371
     * @param array $options
372
     */
373 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...
374
        FormMapper $formMapper,
375
        $name,
376
        $label,
377
        $options = []
378
    ) {
379 2
        $this->doAddFileField(
380
            $formMapper,
381
            $name,
382
            $label,
383 2
            false,
384
            [
385 2
                new Constraint\Image(
386 2
                    array_merge($this->imageConstraintOptions, $options)
387
                ),
388
            ]
389
        );
390 2
    }
391
392
    /**
393
     * @param FormMapper $formMapper
394
     * @param $name
395
     * @param $label
396
     * @param array $options
397
     */
398 3 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...
399
        FormMapper $formMapper,
400
        $name,
401
        $label,
402
        $options = []
403
    ) {
404 3
        $this->doAddFileField(
405
            $formMapper,
406
            $name,
407
            $label,
408 3
            true,
409
            [
410 3
                new Constraint\Image(
411 3
                    array_merge($this->imageConstraintOptions, $options)
412
                ),
413
            ]
414
        );
415 3
    }
416
417
    /**
418
     * @param UploadedFile $file
419
     * @return string
420
     */
421 4
    protected function getFilenameByFile(UploadedFile $file)
422
    {
423 4
        return sprintf(
424 4
            '%s_%d.%s',
425 4
            sha1($file->getClientOriginalName()),
426 4
            time(),
427 4
            $file->getClientOriginalExtension()
428
        );
429
    }
430
431
    /**
432
     * @param UploadedFile $file
433
     * @param $filename
434
     * @throws FilesystemException
435
     */
436 5
    protected function writeToFilesystem(UploadedFile $file, $filename)
437
    {
438 5
        $this->disableErrorHandler();
439 5
        $stream = fopen($file->getRealPath(), 'r+');
440 5
        $written = $this->getFilesystem()->writeStream($filename, $stream);
441 5
        fclose($stream); // this sometime messes up
442 5
        $this->restoreErrorHandler();
443
444 5
        if (!$written) {
445 1
            throw new FilesystemException('Could not write to file system');
446
        }
447 4
    }
448
449
    /**
450
     * @param $renderType
451
     * @return boolean
452
     */
453 11
    public function supports($renderType)
454
    {
455 11
        if ($renderType === self::SUPPORT_EMBED) {
456 11
            return $this->supportsEmbed();
457
        }
458 11
        if ($renderType === self::SUPPORT_IMAGE) {
459 11
            return $this->supportsImage();
460
        }
461 11
        if ($renderType === self::SUPPORT_DOWNLOAD) {
462 11
            return $this->supportsDownload();
463
        }
464
465 4
        return false;
466
    }
467
468
    /**
469
     * @param ErrorElement $errorElement
470
     * @param AbstractMedia $media
471
     */
472 7
    public function validate(ErrorElement $errorElement, AbstractMedia $media)
473
    {
474 7
    }
475
476
    /**
477
     * @return string
478
     */
479 2
    public function getEmbedTemplate()
480
    {
481 2
        return sprintf(
482 2
            'MediaMonksSonataMediaBundle:Provider:%s_embed.html.twig',
483 2
            $this->getName()
484
        );
485
    }
486
}
487