Passed
Push — master ( 705018...c55970 )
by Daniel
12:42 queued 06:12
created

MediaObjectFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
nc 1
nop 9
dl 0
loc 11
ccs 10
cts 10
cp 1
crap 1
rs 9.9666
c 1
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\Factory\Uploadable;
15
16
use ApiPlatform\Core\Api\IriConverterInterface;
17
use Doctrine\Common\Collections\ArrayCollection;
18
use Doctrine\Persistence\ManagerRegistry;
19
use League\Flysystem\Filesystem;
20
use League\Flysystem\UnableToReadFile;
21
use Liip\ImagineBundle\Service\FilterService;
22
use Silverback\ApiComponentsBundle\Annotation\UploadableField;
23
use Silverback\ApiComponentsBundle\AnnotationReader\UploadableAnnotationReader;
24
use Silverback\ApiComponentsBundle\Entity\Core\FileInfo;
25
use Silverback\ApiComponentsBundle\Entity\Utility\ImagineFiltersInterface;
26
use Silverback\ApiComponentsBundle\Flysystem\FilesystemProvider;
27
use Silverback\ApiComponentsBundle\Helper\Uploadable\FileInfoCacheManager;
28
use Silverback\ApiComponentsBundle\Imagine\FlysystemDataLoader;
29
use Silverback\ApiComponentsBundle\Model\Uploadable\MediaObject;
30
use Silverback\ApiComponentsBundle\Utility\ClassMetadataTrait;
31
use Symfony\Component\HttpFoundation\RequestStack;
32
use Symfony\Component\HttpFoundation\UrlHelper;
33
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
34
35
/**
36
 * @author Daniel West <[email protected]>
37
 */
38
class MediaObjectFactory
39
{
40
    use ClassMetadataTrait;
41
42
    private FileInfoCacheManager $fileInfoCacheManager;
43
    private UploadableAnnotationReader $annotationReader;
44
    private FilesystemProvider $filesystemProvider;
45
    private FlysystemDataLoader $flysystemDataLoader;
46
    private RequestStack $requestStack;
47
    private IriConverterInterface $iriConverter;
48
    private UrlHelper $urlHelper;
49
    private ?FilterService $filterService;
50
51 7
    public function __construct(ManagerRegistry $managerRegistry, FileInfoCacheManager $fileInfoCacheManager, UploadableAnnotationReader $annotationReader, FilesystemProvider $filesystemProvider, FlysystemDataLoader $flysystemDataLoader, RequestStack $requestStack, IriConverterInterface $iriConverter, UrlHelper $urlHelper, ?FilterService $filterService = null)
52
    {
53 7
        $this->initRegistry($managerRegistry);
54 7
        $this->fileInfoCacheManager = $fileInfoCacheManager;
55 7
        $this->annotationReader = $annotationReader;
56 7
        $this->filesystemProvider = $filesystemProvider;
57 7
        $this->flysystemDataLoader = $flysystemDataLoader;
58 7
        $this->requestStack = $requestStack;
59 7
        $this->iriConverter = $iriConverter;
60 7
        $this->urlHelper = $urlHelper;
61 7
        $this->filterService = $filterService;
62 7
    }
63
64
    public function createMediaObjects(object $object): ?ArrayCollection
65
    {
66
        $collection = new ArrayCollection();
67
        $classMetadata = $this->getClassMetadata($object);
68
69
        $configuredProperties = $this->annotationReader->getConfiguredProperties($object, true);
70
71
        $resourceId = $this->iriConverter->getIriFromItem($object);
72
        foreach ($configuredProperties as $fileProperty => $fieldConfiguration) {
73
            $propertyMediaObjects = [];
74
            $filesystem = $this->filesystemProvider->getFilesystem($fieldConfiguration->adapter);
0 ignored issues
show
Bug introduced by
It seems like $fieldConfiguration->adapter can also be of type null; however, parameter $name of Silverback\ApiComponents...ovider::getFilesystem() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

74
            $filesystem = $this->filesystemProvider->getFilesystem(/** @scrutinizer ignore-type */ $fieldConfiguration->adapter);
Loading history...
75
            $path = $classMetadata->getFieldValue($object, $fieldConfiguration->property);
76
            if (!$path) {
77
                continue;
78
            }
79
            if (!$filesystem->fileExists($path)) {
80
                continue;
81
            }
82
83
            $converter = new CamelCaseToSnakeCaseNameConverter();
84
            $contentUrl = sprintf('%s/download/%s', $resourceId, $converter->normalize($fileProperty));
85
86
            // Populate the primary MediaObject
87
            try {
88
                $propertyMediaObjects[] = $this->create($filesystem, $path, $contentUrl);
89
            } catch (UnableToReadFile $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
90
            }
91
92
            array_push($propertyMediaObjects, ...$this->getMediaObjectsForImagineFilters($object, $path, $fieldConfiguration, $fileProperty));
93
94
            $collection->set($fileProperty, $propertyMediaObjects);
95
        }
96
97
        return $collection->count() ? $collection : null;
98
    }
99
100
    /**
101
     * @return MediaObject[]
102
     */
103
    private function getMediaObjectsForImagineFilters(object $object, string $path, UploadableField $uploadableField, string $fileProperty): array
104
    {
105
        $mediaObjects = [];
106
        if (!$this->filterService) {
107
            return $mediaObjects;
108
        }
109
110
        // Let the data loader which should be configured for imagine to know which adapter to use
111
        $this->flysystemDataLoader->setAdapter($uploadableField->adapter);
112
113
        $filters = $uploadableField->imagineFilters;
114
        if ($object instanceof ImagineFiltersInterface) {
115
            $request = $this->requestStack->getMasterRequest();
116
            array_push($filters, ...$object->getImagineFilters($fileProperty, $request));
0 ignored issues
show
Bug introduced by
It seems like $filters can also be of type null; however, parameter $array of array_push() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

116
            array_push(/** @scrutinizer ignore-type */ $filters, ...$object->getImagineFilters($fileProperty, $request));
Loading history...
117
        }
118
119
        foreach ($filters as $filter) {
120
            $resolvedUrl = $this->filterService->getUrlOfFilteredImage($path, $filter);
121
            $mediaObjects[] = $this->createFromImagine($resolvedUrl, $path, $filter);
122
        }
123
124
        return $mediaObjects;
125
    }
126
127
    private function create(Filesystem $filesystem, string $filename, string $contentUrl): MediaObject
128
    {
129
        $mediaObject = new MediaObject();
130
131
        $mediaObject->contentUrl = $this->urlHelper->getAbsoluteUrl($contentUrl);
132
        $mediaObject->imagineFilter = null;
133
134
        $fileInfo = $this->fileInfoCacheManager->resolveCache($filename);
135
        if ($fileInfo) {
136
            return $this->populateMediaObjectFromCache($mediaObject, $fileInfo);
137
        }
138
139
        $mediaObject->fileSize = $filesystem->fileSize($filename);
140
        $mediaObject->mimeType = $filesystem->mimeType($filename);
141
        if (false !== strpos($mediaObject->mimeType, 'image/')) {
142
            $file = $filesystem->read($filename);
143
            if ('image/svg+xml' === $mediaObject->mimeType) {
144
                $xmlget = simplexml_load_string(file_get_contents($file));
145
                $xmlattributes = $xmlget->attributes();
146
                $mediaObject->width = (int) $xmlattributes->width;
147
                $mediaObject->height = (int) $xmlattributes->height;
148
            } else {
149
                [$mediaObject->width, $mediaObject->height] = @getimagesize($file);
150
            }
151
        }
152
153
        $fileInfo = new FileInfo($filename, $mediaObject->mimeType, $mediaObject->fileSize, $mediaObject->width, $mediaObject->height);
154
        $this->fileInfoCacheManager->saveCache($fileInfo);
155
156
        return $mediaObject;
157
    }
158
159
    private function createFromImagine(string $contentUrl, string $path, string $imagineFilter): MediaObject
160
    {
161
        $mediaObject = new MediaObject();
162
        $mediaObject->contentUrl = $contentUrl;
163
        $mediaObject->imagineFilter = $imagineFilter;
164
165
        $fileInfo = $this->fileInfoCacheManager->resolveCache($path, $imagineFilter);
166
        if ($fileInfo) {
167
            return $this->populateMediaObjectFromCache($mediaObject, $fileInfo);
168
        }
169
        $mediaObject->width = $mediaObject->height = $mediaObject->fileSize = -1;
170
        $mediaObject->mimeType = '';
171
172
        return $mediaObject;
173
    }
174
175
    private function populateMediaObjectFromCache(MediaObject $mediaObject, FileInfo $fileInfo): MediaObject
176
    {
177
        $mediaObject->fileSize = $fileInfo->fileSize;
178
        $mediaObject->mimeType = $fileInfo->mimeType;
179
        $mediaObject->width = $fileInfo->width;
180
        $mediaObject->height = $fileInfo->height;
181
182
        return $mediaObject;
183
    }
184
}
185