Completed
Push — master ( 7db90d...b62044 )
by
unknown
05:58
created

AbstractProvider::setTranslator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace MediaMonks\SonataMediaBundle\Provider;
4
5
use League\Flysystem\FilesystemInterface;
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 FilesystemInterface
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 FilesystemInterface $filesystem
66
     */
67 4
    public function setFilesystem(FilesystemInterface $filesystem)
68
    {
69 4
        $this->filesystem = $filesystem;
70 4
    }
71
72
    /**
73
     * @param TranslatorInterface $translator
74
     */
75 3
    public function setTranslator(TranslatorInterface $translator)
76
    {
77 3
        $this->translator = $translator;
78 3
    }
79
80
    /**
81
     * @return \Symfony\Component\Translation\TranslatorInterface
82
     */
83
    public function getTranslator()
84
    {
85
        return $this->translator;
86
    }
87
88
    /**
89
     * @param array $options
90
     */
91 3
    public function setImageConstraintOptions(array $options)
92
    {
93 3
        $this->imageConstraintOptions = $options;
94 3
    }
95
96
    /**
97
     * @param HttpClientInterface $httpClient
98
     */
99 5
    public function setHttpClient(HttpClientInterface $httpClient)
100
    {
101 5
        $this->httpClient = $httpClient;
102 5
    }
103
104
    /**
105
     * @return FileLocator
106
     */
107
    public function getFileLocator()
108
    {
109
        return $this->fileLocator;
110
    }
111
112
    /**
113
     * @param FileLocator $fileLocator
114
     */
115 3
    public function setFileLocator(FileLocator $fileLocator)
116
    {
117 3
        $this->fileLocator = $fileLocator;
118 3
    }
119
120
    /**
121
     * @return HttpClientInterface
122
     */
123 2
    public function getHttpClient()
124
    {
125 2
        return $this->httpClient;
126
    }
127
128
    /**
129
     * @return FilesystemInterface
130
     */
131 1
    public function getFilesystem()
132
    {
133 1
        return $this->filesystem;
134
    }
135
136
    /**
137
     * @param AbstractMedia $media
138
     * @return AbstractProvider
139
     */
140 1
    public function setMedia($media)
141
    {
142 1
        $this->media = $media;
143
144 1
        return $this;
145
    }
146
147
    /**
148
     * @param AbstractMedia $media
149
     * @param $providerReferenceUpdated
150
     */
151
    public function update(AbstractMedia $media, $providerReferenceUpdated)
152
    {
153
        $this->updateImage($media);
154
    }
155
156
    /**
157
     * @param FormMapper $formMapper
158
     */
159 1
    public function buildCreateForm(FormMapper $formMapper)
160
    {
161
        $formMapper
162 1
            ->add('provider', 'hidden');
163
164 1
        $this->buildProviderCreateForm($formMapper);
165 1
    }
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('focalPoint', MediaFocalPointType::class, [
209
                'media' => $this->media
210
            ])
211
            ->end()
212
            ->end()
213
        ;
214
215
        $this->buildProviderEditFormAfter($formMapper);
216
    }
217
218
    /**
219
     * @param FormMapper $formMapper
220
     * @codeCoverageIgnore
221
     */
222
    public function buildProviderEditFormBefore(FormMapper $formMapper)
223
    {
224
    }
225
226
    /**
227
     * @param FormMapper $formMapper
228
     * @codeCoverageIgnore
229
     */
230
    public function buildProviderEditFormAfter(FormMapper $formMapper)
231
    {
232
    }
233
234
    /**
235
     * @param AbstractMedia $media
236
     * @param bool $useAsImage
237
     * @return string|void
238
     */
239
    protected function handleFileUpload(AbstractMedia $media, $useAsImage = false)
240
    {
241
        /**
242
         * @var UploadedFile $file
243
         */
244
        $file = $media->getBinaryContent();
245
246
        if (empty($file)) {
247
            return;
248
        }
249
250
        $filename = $this->getFilenameByFile($file);
251
        $this->writeToFilesystem($file, $filename);
252
253
        $media->setProviderMetadata(
254
            array_merge(
255
                $media->getProviderMetaData(),
256
                $this->getFileMetaData($file)
257
            )
258
        );
259
260
        if (empty($media->getImage()) && $useAsImage) {
261
            $media->setImage($filename);
262
            $media->setImageMetaData($media->getProviderMetaData());
263
        }
264
265
        if (empty($media->getTitle())) {
266
            $media->setTitle(
267
                str_replace(
268
                    '_',
269
                    ' ',
270
                    pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)
271
                )
272
            );
273
        }
274
275
        return $filename;
276
    }
277
278
    /**
279
     * @param UploadedFile $file
280
     * @return array
281
     */
282
    protected function getFileMetaData(UploadedFile $file)
283
    {
284
        $fileData = [
285
            'originalName'      => $file->getClientOriginalName(),
286
            'originalExtension' => $file->getClientOriginalExtension(),
287
            'mimeType'          => $file->getClientMimeType(),
288
            'size'              => $file->getSize(),
289
        ];
290
291
292
        $this->disableErrorHandler();
293
        $imageSize = getimagesize($file->getRealPath());
294
        if (is_array($imageSize)) {
295
            if (is_int($imageSize[0]) && is_int($imageSize[1])) {
296
                $fileData['height'] = $imageSize[0];
297
                $fileData['width']  = $imageSize[1];
298
            }
299
            if (isset($imageSize['bits'])) {
300
                $fileData['bits'] = $imageSize['bits'];
301
            }
302
            if (isset($imageSize['channels'])) {
303
                $fileData['channels'] = $imageSize['channels'];
304
            }
305
        }
306
        $this->restoreErrorHandler();
307
308
        return $fileData;
309
    }
310
311
    /**
312
     * @param AbstractMedia $media
313
     */
314
    public function updateImage(AbstractMedia $media)
315
    {
316
        /**
317
         * @var UploadedFile $file
318
         */
319
        $file = $media->getImageContent();
320
        if (empty($file)) {
321
            return;
322
        }
323
324
        $filename = $this->getFilenameByFile($file);
325
        $this->writeToFilesystem($file, $filename);
326
327
        $media->setImage($filename);
328
        $media->setImageMetaData($this->getFileMetaData($file));
329
    }
330
331
    /**
332
     * @param \Sonata\AdminBundle\Form\FormMapper $formMapper
333
     * @param $name
334
     * @param $label
335
     * @param $required
336
     * @param array $constraints
337
     */
338 1
    protected function doAddFileField(
339
        FormMapper $formMapper,
340
        $name,
341
        $label,
342
        $required,
343
        $constraints = []
344
    ) {
345 1
        if ($required) {
346 1
            $constraints = array_merge(
347
                [
348 1
                    new Constraint\NotBlank(),
349 1
                    new Constraint\NotNull(),
350 1
                ],
351
                $constraints
352 1
            );
353 1
        }
354
355
        $formMapper
356 1
            ->add(
357 1
                $name,
358 1
                FileType::class,
359
                [
360 1
                    'multiple'    => false,
361 1
                    'data_class'  => null,
362 1
                    'constraints' => $constraints,
363 1
                    'label'       => $label,
364 1
                    'required'    => $required,
365
                ]
366 1
            );
367 1
    }
368
369
    /**
370
     * @param FormMapper $formMapper
371
     * @param string $name
372
     * @param string $label
373
     * @param array $options
374
     */
375 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...
376
        FormMapper $formMapper,
377
        $name,
378
        $label,
379
        $options = []
380
    ) {
381
        $this->doAddFileField(
382
            $formMapper,
383
            $name,
384
            $label,
385
            false,
386
            [
387
                new Constraint\Image(
388
                    array_merge($this->imageConstraintOptions, $options)
389
                ),
390
            ]
391
        );
392
    }
393
394
    /**
395
     * @param FormMapper $formMapper
396
     * @param $name
397
     * @param $label
398
     * @param array $options
399
     */
400 1 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...
401
        FormMapper $formMapper,
402
        $name,
403
        $label,
404
        $options = []
405
    ) {
406 1
        $this->doAddFileField(
407 1
            $formMapper,
408 1
            $name,
409 1
            $label,
410 1
            true,
411
            [
412 1
                new Constraint\Image(
413 1
                    array_merge($this->imageConstraintOptions, $options)
414 1
                ),
415
            ]
416 1
        );
417 1
    }
418
419
    /**
420
     * @param UploadedFile $file
421
     * @return string
422
     */
423
    protected function getFilenameByFile(UploadedFile $file)
424
    {
425
        return sprintf(
426
            '%s_%d.%s',
427
            sha1($file->getClientOriginalName()),
428
            time(),
429
            $file->getClientOriginalExtension()
430
        );
431
    }
432
433
    /**
434
     * @param UploadedFile $file
435
     * @param $filename
436
     * @throws FilesystemException
437
     */
438 1
    protected function writeToFilesystem(UploadedFile $file, $filename)
439
    {
440 1
        $this->disableErrorHandler();
441 1
        $stream = fopen($file->getRealPath(), 'r+');
442 1
        $written = $this->getFilesystem()->writeStream($filename, $stream);
443 1
        fclose($stream); // this sometime messes up
444 1
        $this->restoreErrorHandler();
445
446 1
        if (!$written) {
447 1
            throw new FilesystemException('Could not write to file system');
448
        }
449
    }
450
451
    /**
452
     * @param ErrorElement $errorElement
453
     * @param AbstractMedia $media
454
     */
455
    public function validate(ErrorElement $errorElement, AbstractMedia $media)
456
    {
457
    }
458
459
    /**
460
     * @return string
461
     */
462
    public function getEmbedTemplate()
463
    {
464
        return sprintf(
465
            'MediaMonksSonataMediaBundle:Provider:%s_embed.html.twig',
466
            $this->getName()
467
        );
468
    }
469
}
470