Completed
Push — master ( ac02e0...0e5803 )
by
unknown
04:21
created

AbstractProvider   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 413
Duplicated Lines 8.72 %

Coupling/Cohesion

Components 3
Dependencies 8

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 33
lcom 3
cbo 8
dl 36
loc 413
ccs 0
cts 258
cp 0
rs 9.3999
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A getPointOfInterestChoices() 0 16 1
A buildCreateForm() 0 7 1
B buildEditForm() 0 34 1
A buildProviderEditForm() 0 3 1
A setFilesystem() 0 4 1
A setImageConstraintOptions() 0 4 1
A getFilesystem() 0 4 1
A update() 0 4 1
A getTranslationDomain() 0 4 1
A toArray() 0 11 1
B handleFileUpload() 0 38 5
A getFileMetaData() 0 9 1
A updateImage() 0 16 2
B doAddFileField() 0 30 2
A addImageField() 18 18 1
A addRequiredImageField() 18 18 1
A getFilenameByFile() 0 9 1
A writeToFilesystem() 0 15 2
A supports() 0 14 4
A disableErrorHandler() 0 7 1
A restoreErrorHandler() 0 4 1
A validate() 0 3 1
A getEmbedTemplate() 0 7 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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