Passed
Push — master ( a7ed20...e72196 )
by Daniel
08:57 queued 03:23
created

MediaObjectFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

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\Imagine\FlysystemDataLoader;
28
use Silverback\ApiComponentsBundle\Model\Uploadable\MediaObject;
29
use Silverback\ApiComponentsBundle\Uploadable\FileInfoCacheHelper;
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 FileInfoCacheHelper $fileInfoCacheHelper;
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
    public function __construct(
52
        ManagerRegistry $managerRegistry,
53
        FileInfoCacheHelper $fileInfoCacheHelper,
54
        UploadableAnnotationReader $annotationReader,
55
        FilesystemProvider $filesystemProvider,
56
        FlysystemDataLoader $flysystemDataLoader,
57
        RequestStack $requestStack,
58
        IriConverterInterface $iriConverter,
59
        UrlHelper $urlHelper,
60
        ?FilterService $filterService = null
61
    ) {
62
        $this->initRegistry($managerRegistry);
63
        $this->fileInfoCacheHelper = $fileInfoCacheHelper;
64
        $this->annotationReader = $annotationReader;
65
        $this->filesystemProvider = $filesystemProvider;
66
        $this->flysystemDataLoader = $flysystemDataLoader;
67
        $this->requestStack = $requestStack;
68
        $this->iriConverter = $iriConverter;
69
        $this->urlHelper = $urlHelper;
70
        $this->filterService = $filterService;
71
    }
72
73
    public function createMediaObjects(object $object): ?ArrayCollection
74
    {
75
        $collection = new ArrayCollection();
76
        $classMetadata = $this->getClassMetadata($object);
77
78
        $configuredProperties = $this->annotationReader->getConfiguredProperties($object, true);
79
80
        $resourceId = $this->iriConverter->getIriFromItem($object);
81
        foreach ($configuredProperties as $fileProperty => $fieldConfiguration) {
82
            $propertyMediaObjects = [];
83
            $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

83
            $filesystem = $this->filesystemProvider->getFilesystem(/** @scrutinizer ignore-type */ $fieldConfiguration->adapter);
Loading history...
84
            $path = $classMetadata->getFieldValue($object, $fieldConfiguration->property);
85
            if (!$path) {
86
                continue;
87
            }
88
            if (!$filesystem->fileExists($path)) {
89
                continue;
90
            }
91
92
            $converter = new CamelCaseToSnakeCaseNameConverter();
93
            $contentUrl = sprintf('%s/download/%s', $resourceId, $converter->normalize($fileProperty));
94
95
            // Populate the primary MediaObject
96
            try {
97
                $propertyMediaObjects[] = $this->create($filesystem, $path, $contentUrl);
98
            } catch (UnableToReadFile $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
99
            }
100
101
            array_push($propertyMediaObjects, ...$this->getMediaObjectsForImagineFilters($object, $path, $fieldConfiguration, $fileProperty));
102
103
            $collection->set($fieldConfiguration->property, $propertyMediaObjects);
104
        }
105
106
        return $collection->count() ? $collection : null;
107
    }
108
109
    /**
110
     * @return MediaObject[]
111
     */
112
    private function getMediaObjectsForImagineFilters(object $object, string $path, UploadableField $uploadableField, string $fileProperty): array
113
    {
114
        $mediaObjects = [];
115
        if (!$this->filterService) {
116
            return $mediaObjects;
117
        }
118
119
        // Let the data loader which should be configured for imagine to know which adapter to use
120
        $this->flysystemDataLoader->setAdapter($uploadableField->adapter);
121
122
        $filters = $uploadableField->imagineFilters;
123
        if ($object instanceof ImagineFiltersInterface) {
124
            $request = $this->requestStack->getMasterRequest();
125
            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

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