Passed
Push — trunk ( 9c2f71...32e8e5 )
by Christian
10:51 queued 12s
created

ThumbnailService::updateThumbnails()   C

Complexity

Conditions 12
Paths 15

Size

Total Lines 65
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 36
nc 15
nop 3
dl 0
loc 65
rs 6.9666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\Content\Media\Thumbnail;
4
5
use League\Flysystem\FilesystemOperator;
6
use Shopware\Core\Content\Media\Aggregate\MediaFolder\MediaFolderEntity;
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Me...older\MediaFolderEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Shopware\Core\Content\Media\Aggregate\MediaFolderConfiguration\MediaFolderConfigurationEntity;
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Me...lderConfigurationEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Shopware\Core\Content\Media\Aggregate\MediaThumbnail\MediaThumbnailCollection;
9
use Shopware\Core\Content\Media\Aggregate\MediaThumbnail\MediaThumbnailEntity;
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Me...il\MediaThumbnailEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Shopware\Core\Content\Media\Aggregate\MediaThumbnailSize\MediaThumbnailSizeCollection;
11
use Shopware\Core\Content\Media\Aggregate\MediaThumbnailSize\MediaThumbnailSizeEntity;
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Me...ediaThumbnailSizeEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Shopware\Core\Content\Media\Exception\ThumbnailCouldNotBeSavedException;
13
use Shopware\Core\Content\Media\Exception\ThumbnailNotSupportedException;
14
use Shopware\Core\Content\Media\MediaCollection;
15
use Shopware\Core\Content\Media\MediaEntity;
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Media\MediaEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Shopware\Core\Content\Media\MediaType\ImageType;
17
use Shopware\Core\Content\Media\MediaType\MediaType;
18
use Shopware\Core\Content\Media\Pathname\UrlGeneratorInterface;
19
use Shopware\Core\Content\Media\Subscriber\MediaDeletionSubscriber;
20
use Shopware\Core\Framework\Context;
21
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
22
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
23
24
/**
25
 * @package content
26
 */
27
class ThumbnailService
28
{
29
    private EntityRepository $thumbnailRepository;
30
31
    private FilesystemOperator $filesystemPublic;
32
33
    private FilesystemOperator $filesystemPrivate;
34
35
    private UrlGeneratorInterface $urlGenerator;
36
37
    private EntityRepository $mediaFolderRepository;
38
39
    /**
40
     * @internal
41
     */
42
    public function __construct(
43
        EntityRepository $thumbnailRepository,
44
        FilesystemOperator $fileSystemPublic,
45
        FilesystemOperator $fileSystemPrivate,
46
        UrlGeneratorInterface $urlGenerator,
47
        EntityRepository $mediaFolderRepository
48
    ) {
49
        $this->thumbnailRepository = $thumbnailRepository;
50
        $this->filesystemPublic = $fileSystemPublic;
51
        $this->filesystemPrivate = $fileSystemPrivate;
52
        $this->urlGenerator = $urlGenerator;
53
        $this->mediaFolderRepository = $mediaFolderRepository;
54
    }
55
56
    public function generate(MediaCollection $collection, Context $context): int
57
    {
58
        $delete = [];
59
60
        $generate = [];
61
62
        foreach ($collection as $media) {
63
            if ($media->getThumbnails() === null) {
64
                throw new \RuntimeException('Thumbnail association not loaded - please pre load media thumbnails');
65
            }
66
67
            if (!$this->mediaCanHaveThumbnails($media, $context)) {
0 ignored issues
show
Bug introduced by
$media of type array is incompatible with the type Shopware\Core\Content\Media\MediaEntity expected by parameter $media of Shopware\Core\Content\Me...ediaCanHaveThumbnails(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
            if (!$this->mediaCanHaveThumbnails(/** @scrutinizer ignore-type */ $media, $context)) {
Loading history...
68
                $delete = array_merge($delete, $media->getThumbnails()->getIds());
69
70
                continue;
71
            }
72
73
            $mediaFolder = $media->getMediaFolder();
74
            if ($mediaFolder === null) {
75
                continue;
76
            }
77
78
            $config = $mediaFolder->getConfiguration();
79
            if ($config === null) {
80
                continue;
81
            }
82
83
            $delete = array_merge($delete, $media->getThumbnails()->getIds());
84
85
            $generate[] = $media;
86
        }
87
88
        if (!empty($delete)) {
89
            $context->addState(MediaDeletionSubscriber::SYNCHRONE_FILE_DELETE);
90
91
            $delete = \array_values(\array_map(function (string $id) {
92
                return ['id' => $id];
93
            }, $delete));
94
95
            $this->thumbnailRepository->delete($delete, $context);
96
        }
97
98
        $updates = [];
99
        foreach ($generate as $media) {
100
            if ($media->getMediaFolder() === null || $media->getMediaFolder()->getConfiguration() === null) {
101
                continue;
102
            }
103
104
            $config = $media->getMediaFolder()->getConfiguration();
105
106
            $thumbnails = $this->createThumbnailsForSizes($media, $config, $config->getMediaThumbnailSizes());
107
108
            foreach ($thumbnails as $thumbnail) {
109
                $updates[] = $thumbnail;
110
            }
111
        }
112
113
        if (empty($updates)) {
114
            return 0;
115
        }
116
117
        $context->scope(Context::SYSTEM_SCOPE, function ($context) use ($updates): void {
118
            $this->thumbnailRepository->create($updates, $context);
119
        });
120
121
        return \count($updates);
122
    }
123
124
    /**
125
     * @throws ThumbnailNotSupportedException
126
     * @throws ThumbnailCouldNotBeSavedException
127
     */
128
    public function updateThumbnails(MediaEntity $media, Context $context, bool $strict): int
129
    {
130
        if (!$this->mediaCanHaveThumbnails($media, $context)) {
131
            $this->deleteAssociatedThumbnails($media, $context);
132
133
            return 0;
134
        }
135
136
        $mediaFolder = $media->getMediaFolder();
137
        if ($mediaFolder === null) {
138
            return 0;
139
        }
140
141
        $config = $mediaFolder->getConfiguration();
142
        if ($config === null) {
143
            return 0;
144
        }
145
146
        $strict = \func_get_args()[2] ?? false;
147
148
        if ($config->getMediaThumbnailSizes() === null) {
149
            return 0;
150
        }
151
        if ($media->getThumbnails() === null) {
152
            return 0;
153
        }
154
155
        $toBeCreatedSizes = new MediaThumbnailSizeCollection($config->getMediaThumbnailSizes()->getElements());
156
        $toBeDeletedThumbnails = new MediaThumbnailCollection($media->getThumbnails()->getElements());
157
158
        foreach ($toBeCreatedSizes as $thumbnailSize) {
159
            foreach ($toBeDeletedThumbnails as $thumbnail) {
160
                if (!$this->isSameDimension($thumbnail, $thumbnailSize)) {
0 ignored issues
show
Bug introduced by
$thumbnail of type array is incompatible with the type Shopware\Core\Content\Me...il\MediaThumbnailEntity expected by parameter $thumbnail of Shopware\Core\Content\Me...vice::isSameDimension(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
                if (!$this->isSameDimension(/** @scrutinizer ignore-type */ $thumbnail, $thumbnailSize)) {
Loading history...
161
                    continue;
162
                }
163
164
                if ($strict === true
165
                    && !$this->getFileSystem($media)->fileExists($this->urlGenerator->getRelativeThumbnailUrl($media, $thumbnail))) {
0 ignored issues
show
Bug introduced by
$thumbnail of type array is incompatible with the type Shopware\Core\Content\Me...il\MediaThumbnailEntity expected by parameter $thumbnail of Shopware\Core\Content\Me...tRelativeThumbnailUrl(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
                    && !$this->getFileSystem($media)->fileExists($this->urlGenerator->getRelativeThumbnailUrl($media, /** @scrutinizer ignore-type */ $thumbnail))) {
Loading history...
166
                    continue;
167
                }
168
169
                $toBeDeletedThumbnails->remove($thumbnail->getId());
170
                $toBeCreatedSizes->remove($thumbnailSize->getId());
171
172
                continue 2;
173
            }
174
        }
175
176
        $delete = \array_values(\array_map(static function (string $id) {
177
            return ['id' => $id];
178
        }, $toBeDeletedThumbnails->getIds()));
179
180
        $this->thumbnailRepository->delete($delete, $context);
181
182
        $update = $this->createThumbnailsForSizes($media, $config, $toBeCreatedSizes);
183
184
        if (empty($update)) {
185
            return 0;
186
        }
187
188
        $context->scope(Context::SYSTEM_SCOPE, function ($context) use ($update): void {
189
            $this->thumbnailRepository->create($update, $context);
190
        });
191
192
        return \count($update);
193
    }
194
195
    public function deleteThumbnails(MediaEntity $media, Context $context): void
196
    {
197
        $this->deleteAssociatedThumbnails($media, $context);
198
    }
199
200
    /**
201
     * @throws ThumbnailNotSupportedException
202
     * @throws ThumbnailCouldNotBeSavedException
203
     *
204
     * @return list<array{mediaId: string, width: int, height: int}>
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Media\Thumbnail\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
205
     */
206
    private function createThumbnailsForSizes(
207
        MediaEntity $media,
208
        MediaFolderConfigurationEntity $config,
209
        ?MediaThumbnailSizeCollection $thumbnailSizes
210
    ): array {
211
        if ($thumbnailSizes === null || $thumbnailSizes->count() === 0) {
212
            return [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return array() returns the type array which is incompatible with the documented return type Shopware\Core\Content\Media\Thumbnail\list.
Loading history...
213
        }
214
215
        $mediaImage = $this->getImageResource($media);
216
        $originalImageSize = $this->getOriginalImageSize($mediaImage);
217
        $originalUrl = $this->urlGenerator->getRelativeMediaUrl($media);
218
219
        $savedThumbnails = [];
220
221
        $type = $media->getMediaType();
222
        if ($type === null) {
223
            throw new \RuntimeException(\sprintf('Media type, for id %s, not loaded', $media->getId()));
224
        }
225
226
        try {
227
            foreach ($thumbnailSizes as $size) {
228
                $thumbnailSize = $this->calculateThumbnailSize($originalImageSize, $size, $config);
0 ignored issues
show
Bug introduced by
$size of type array is incompatible with the type Shopware\Core\Content\Me...ediaThumbnailSizeEntity expected by parameter $preferredThumbnailSize of Shopware\Core\Content\Me...alculateThumbnailSize(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

228
                $thumbnailSize = $this->calculateThumbnailSize($originalImageSize, /** @scrutinizer ignore-type */ $size, $config);
Loading history...
229
                $thumbnail = $this->createNewImage($mediaImage, $type, $originalImageSize, $thumbnailSize);
230
231
                $url = $this->urlGenerator->getRelativeThumbnailUrl(
232
                    $media,
233
                    (new MediaThumbnailEntity())->assign(['width' => $size->getWidth(), 'height' => $size->getHeight()])
234
                );
235
                $this->writeThumbnail($thumbnail, $media, $url, $config->getThumbnailQuality());
236
237
                $mediaFilesystem = $this->getFileSystem($media);
238
                if ($originalImageSize === $thumbnailSize
239
                    && $mediaFilesystem->fileSize($originalUrl) < $mediaFilesystem->fileSize($url)) {
240
                    $mediaFilesystem->write($url, $mediaFilesystem->read($originalUrl));
241
                }
242
243
                $savedThumbnails[] = [
244
                    'mediaId' => $media->getId(),
245
                    'width' => $size->getWidth(),
246
                    'height' => $size->getHeight(),
247
                ];
248
249
                imagedestroy($thumbnail);
250
            }
251
            imagedestroy($mediaImage);
252
        } finally {
253
            return $savedThumbnails;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $savedThumbnails returns the type array|array<mixed,array> which is incompatible with the documented return type Shopware\Core\Content\Media\Thumbnail\list.
Loading history...
254
        }
255
    }
256
257
    private function ensureConfigIsLoaded(MediaEntity $media, Context $context): void
258
    {
259
        $mediaFolderId = $media->getMediaFolderId();
260
        if ($mediaFolderId === null) {
261
            return;
262
        }
263
264
        if ($media->getMediaFolder() !== null) {
265
            return;
266
        }
267
268
        $criteria = new Criteria([$mediaFolderId]);
269
        $criteria->addAssociation('configuration.mediaThumbnailSizes');
270
271
        /** @var MediaFolderEntity $folder */
272
        $folder = $this->mediaFolderRepository->search($criteria, $context)->get($mediaFolderId);
273
        $media->setMediaFolder($folder);
274
    }
275
276
    private function getImageResource(MediaEntity $media): \GdImage
277
    {
278
        $filePath = $this->urlGenerator->getRelativeMediaUrl($media);
279
        /** @var string $file */
280
        $file = $this->getFileSystem($media)->read($filePath);
281
        $image = @imagecreatefromstring($file);
282
        if ($image === false) {
283
            throw new ThumbnailNotSupportedException($media->getId());
284
        }
285
286
        if (\function_exists('exif_read_data')) {
287
            /** @var resource $stream */
288
            $stream = fopen('php://memory', 'r+b');
289
290
            try {
291
                // use in-memory stream to read the EXIF-metadata,
292
                // to avoid downloading the image twice from a remote filesystem
293
                fwrite($stream, $file);
294
                rewind($stream);
295
296
                $exif = @exif_read_data($stream);
0 ignored issues
show
Bug introduced by
$stream of type resource is incompatible with the type string expected by parameter $file of exif_read_data(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

296
                $exif = @exif_read_data(/** @scrutinizer ignore-type */ $stream);
Loading history...
297
298
                if ($exif !== false) {
299
                    if (!empty($exif['Orientation']) && $exif['Orientation'] === 8) {
300
                        $image = imagerotate($image, 90, 0);
301
                    } elseif (!empty($exif['Orientation']) && $exif['Orientation'] === 3) {
302
                        $image = imagerotate($image, 180, 0);
303
                    } elseif (!empty($exif['Orientation']) && $exif['Orientation'] === 6) {
304
                        $image = imagerotate($image, -90, 0);
305
                    }
306
                }
307
            } catch (\Exception $e) {
308
                // Ignore.
309
            } finally {
310
                fclose($stream);
311
            }
312
        }
313
314
        if ($image === false) {
315
            throw new ThumbnailNotSupportedException($media->getId());
316
        }
317
318
        return $image;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $image could return the type resource which is incompatible with the type-hinted return GdImage. Consider adding an additional type-check to rule them out.
Loading history...
319
    }
320
321
    /**
322
     * @return array{width: int, height: int}
323
     */
324
    private function getOriginalImageSize(\GdImage $image): array
325
    {
326
        return [
327
            'width' => imagesx($image),
328
            'height' => imagesy($image),
329
        ];
330
    }
331
332
    /**
333
     * @param array{width: int, height: int} $imageSize
334
     *
335
     * @return array{width: int, height: int}
336
     */
337
    private function calculateThumbnailSize(
338
        array $imageSize,
339
        MediaThumbnailSizeEntity $preferredThumbnailSize,
340
        MediaFolderConfigurationEntity $config
341
    ): array {
342
        if (!$config->getKeepAspectRatio() || $preferredThumbnailSize->getWidth() !== $preferredThumbnailSize->getHeight()) {
343
            $calculatedWidth = $preferredThumbnailSize->getWidth();
344
            $calculatedHeight = $preferredThumbnailSize->getHeight();
345
346
            $useOriginalSizeInThumbnails = $imageSize['width'] < $calculatedWidth || $imageSize['height'] < $calculatedHeight;
347
348
            return $useOriginalSizeInThumbnails ? [
349
                'width' => $imageSize['width'],
350
                'height' => $imageSize['height'],
351
            ] : [
352
                'width' => $calculatedWidth,
353
                'height' => $calculatedHeight,
354
            ];
355
        }
356
357
        if ($imageSize['width'] >= $imageSize['height']) {
358
            $aspectRatio = $imageSize['height'] / $imageSize['width'];
359
360
            $calculatedWidth = $preferredThumbnailSize->getWidth();
361
            $calculatedHeight = (int) ceil($preferredThumbnailSize->getHeight() * $aspectRatio);
362
363
            $useOriginalSizeInThumbnails = $imageSize['width'] < $calculatedWidth || $imageSize['height'] < $calculatedHeight;
364
365
            return $useOriginalSizeInThumbnails ? [
366
                'width' => $imageSize['width'],
367
                'height' => $imageSize['height'],
368
            ] : [
369
                'width' => $calculatedWidth,
370
                'height' => $calculatedHeight,
371
            ];
372
        }
373
374
        $aspectRatio = $imageSize['width'] / $imageSize['height'];
375
376
        $calculatedWidth = (int) ceil($preferredThumbnailSize->getWidth() * $aspectRatio);
377
        $calculatedHeight = $preferredThumbnailSize->getHeight();
378
379
        $useOriginalSizeInThumbnails = $imageSize['width'] < $calculatedWidth || $imageSize['height'] < $calculatedHeight;
380
381
        return $useOriginalSizeInThumbnails ? [
382
            'width' => $imageSize['width'],
383
            'height' => $imageSize['height'],
384
        ] : [
385
            'width' => $calculatedWidth,
386
            'height' => $calculatedHeight,
387
        ];
388
    }
389
390
    /**
391
     * @param array{width: int, height: int} $originalImageSize
392
     * @param array{width: int, height: int} $thumbnailSize
393
     */
394
    private function createNewImage(\GdImage $mediaImage, MediaType $type, array $originalImageSize, array $thumbnailSize): \GdImage
395
    {
396
        $thumbnail = imagecreatetruecolor($thumbnailSize['width'], $thumbnailSize['height']);
397
398
        if ($thumbnail === false) {
399
            throw new \RuntimeException('Can not create image handle');
400
        }
401
402
        if (!$type->is(ImageType::TRANSPARENT)) {
403
            $colorWhite = (int) imagecolorallocate($thumbnail, 255, 255, 255);
404
            imagefill($thumbnail, 0, 0, $colorWhite);
405
        } else {
406
            imagealphablending($thumbnail, false);
407
        }
408
409
        imagesavealpha($thumbnail, true);
410
        imagecopyresampled(
411
            $thumbnail,
412
            $mediaImage,
413
            0,
414
            0,
415
            0,
416
            0,
417
            $thumbnailSize['width'],
418
            $thumbnailSize['height'],
419
            $originalImageSize['width'],
420
            $originalImageSize['height']
421
        );
422
423
        return $thumbnail;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $thumbnail could return the type resource which is incompatible with the type-hinted return GdImage. Consider adding an additional type-check to rule them out.
Loading history...
424
    }
425
426
    private function writeThumbnail(\GdImage $thumbnail, MediaEntity $media, string $url, int $quality): void
427
    {
428
        ob_start();
429
        switch ($media->getMimeType()) {
430
            case 'image/png':
431
                imagepng($thumbnail);
432
433
                break;
434
            case 'image/gif':
435
                imagegif($thumbnail);
436
437
                break;
438
            case 'image/jpg':
439
            case 'image/jpeg':
440
                imagejpeg($thumbnail, null, $quality);
441
442
                break;
443
            case 'image/webp':
444
                if (!\function_exists('imagewebp')) {
445
                    throw new ThumbnailCouldNotBeSavedException($url);
446
                }
447
448
                imagewebp($thumbnail, null, $quality);
449
450
                break;
451
        }
452
        $imageFile = ob_get_contents();
453
        ob_end_clean();
454
455
        try {
456
            $this->getFileSystem($media)->write($url, (string) $imageFile);
457
        } catch (\Exception $e) {
458
            throw new ThumbnailCouldNotBeSavedException($url);
459
        }
460
    }
461
462
    private function mediaCanHaveThumbnails(MediaEntity $media, Context $context): bool
463
    {
464
        if (!$media->hasFile()) {
465
            return false;
466
        }
467
468
        if (!$this->thumbnailsAreGeneratable($media)) {
469
            return false;
470
        }
471
472
        $this->ensureConfigIsLoaded($media, $context);
473
474
        if ($media->getMediaFolder() === null || $media->getMediaFolder()->getConfiguration() === null) {
475
            return false;
476
        }
477
478
        return $media->getMediaFolder()->getConfiguration()->getCreateThumbnails();
479
    }
480
481
    private function thumbnailsAreGeneratable(MediaEntity $media): bool
482
    {
483
        return $media->getMediaType() instanceof ImageType
484
            && !$media->getMediaType()->is(ImageType::VECTOR_GRAPHIC)
485
            && !$media->getMediaType()->is(ImageType::ANIMATED)
486
            && !$media->getMediaType()->is(ImageType::ICON);
487
    }
488
489
    private function deleteAssociatedThumbnails(MediaEntity $media, Context $context): void
490
    {
491
        if (!$media->getThumbnails()) {
492
            throw new \RuntimeException('Media contains no thumbnails');
493
        }
494
495
        $delete = $media->getThumbnails()->getIds();
496
497
        $delete = \array_values(\array_map(static function (string $id) {
498
            return ['id' => $id];
499
        }, $delete));
500
501
        $this->thumbnailRepository->delete($delete, $context);
502
    }
503
504
    private function getFileSystem(MediaEntity $media): FilesystemOperator
505
    {
506
        if ($media->isPrivate()) {
507
            return $this->filesystemPrivate;
508
        }
509
510
        return $this->filesystemPublic;
511
    }
512
513
    private function isSameDimension(MediaThumbnailEntity $thumbnail, MediaThumbnailSizeEntity $thumbnailSize): bool
514
    {
515
        return $thumbnail->getWidth() === $thumbnailSize->getWidth()
516
            && $thumbnail->getHeight() === $thumbnailSize->getHeight();
517
    }
518
}
519