Passed
Pull Request — master (#58)
by Daniel
06:00
created

UploadableHelper::getMediaObjects()   B

Complexity

Conditions 7
Paths 14

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 18
nc 14
nop 1
dl 0
loc 31
ccs 0
cts 18
cp 0
crap 56
rs 8.8333
c 0
b 0
f 0
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\Uploadable;
15
16
use Doctrine\Persistence\ManagerRegistry;
17
use Liip\ImagineBundle\Service\FilterService;
18
use Silverback\ApiComponentsBundle\Annotation\UploadableField;
19
use Silverback\ApiComponentsBundle\AnnotationReader\UploadableAnnotationReader;
20
use Silverback\ApiComponentsBundle\Entity\Utility\ImagineFiltersInterface;
21
use Silverback\ApiComponentsBundle\Flysystem\FilesystemProvider;
22
use Silverback\ApiComponentsBundle\Imagine\CacheManager;
23
use Silverback\ApiComponentsBundle\Imagine\FlysystemDataLoader;
24
use Silverback\ApiComponentsBundle\Model\Uploadable\UploadedDataUriFile;
25
use Silverback\ApiComponentsBundle\Utility\ClassMetadataTrait;
26
use Symfony\Component\HttpFoundation\FileBag;
27
use Symfony\Component\PropertyAccess\PropertyAccess;
28
29
/**
30
 * @author Daniel West <[email protected]>
31
 */
32
class UploadableHelper
33
{
34
    use ClassMetadataTrait;
35
36
    private UploadableAnnotationReader $annotationReader;
37
    private FilesystemProvider $filesystemProvider;
38
    private FlysystemDataLoader $flysystemDataLoader;
39
    private FileInfoCacheHelper $fileInfoCacheHelper;
40
    private ?CacheManager $imagineCacheManager;
41
    private ?FilterService $filterService;
42
43
    public function __construct(
44
        ManagerRegistry $registry,
45
        UploadableAnnotationReader $annotationReader,
46
        FilesystemProvider $filesystemProvider,
47
        FlysystemDataLoader $flysystemDataLoader,
48
        FileInfoCacheHelper $fileInfoCacheHelper,
49
        ?CacheManager $imagineCacheManager,
50
        ?FilterService $filterService = null
51
    ) {
52
        $this->initRegistry($registry);
53
        $this->annotationReader = $annotationReader;
54
        $this->filesystemProvider = $filesystemProvider;
55
        $this->flysystemDataLoader = $flysystemDataLoader;
56
        $this->fileInfoCacheHelper = $fileInfoCacheHelper;
57
        $this->imagineCacheManager = $imagineCacheManager;
58
        $this->filterService = $filterService;
59
    }
60
61
    public function setUploadedFilesFromFileBag(object $object, FileBag $fileBag): void
62
    {
63
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
64
        $configuredProperties = $this->annotationReader->getConfiguredProperties($object, false, true);
65
66
        /**
67
         * @var UploadableField[] $configuredProperties
68
         */
69
        foreach ($configuredProperties as $fileProperty => $fieldConfiguration) {
70
            if ($file = $fileBag->get($fileProperty, null)) {
71
                $propertyAccessor->setValue($object, $fileProperty, $file);
72
            }
73
        }
74
    }
75
76
    public function storeFilesMetadata(object $object): void
77
    {
78
        $configuredProperties = $this->annotationReader->getConfiguredProperties($object, true, true);
79
        $classMetadata = $this->getClassMetadata($object);
80
81
        foreach ($configuredProperties as $fileProperty => $fieldConfiguration) {
82
            // Let the data loader which should be configured for imagine to know which adapter to use
83
            $this->flysystemDataLoader->setAdapter($fieldConfiguration->adapter);
84
85
            $filename = $classMetadata->getFieldValue($object, $fieldConfiguration->property);
86
87
            if ($object instanceof ImagineFiltersInterface && $this->filterService) {
88
                $filters = $object->getImagineFilters($fileProperty, null);
89
                foreach ($filters as $filter) {
90
                    // This will trigger the cached file to be store
91
                    // When cached files are store we save the file info
92
                    $this->filterService->getUrlOfFilteredImage($filename, $filter);
93
                }
94
            }
95
        }
96
    }
97
98
    public function persistFiles(object $object): void
99
    {
100
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
101
        $classMetadata = $this->getClassMetadata($object);
102
103
        $configuredProperties = $this->annotationReader->getConfiguredProperties($object, true, true);
104
        /**
105
         * @var UploadableField[] $configuredProperties
106
         */
107
        foreach ($configuredProperties as $fileProperty => $fieldConfiguration) {
108
            $currentFilepath = $classMetadata->getFieldValue($object, $fieldConfiguration->property);
109
            if ($currentFilepath) {
110
                $this->removeFilepath($object, $fieldConfiguration);
0 ignored issues
show
Bug introduced by
It seems like $fieldConfiguration can also be of type string; however, parameter $fieldConfiguration of Silverback\ApiComponents...elper::removeFilepath() does only seem to accept Silverback\ApiComponents...otation\UploadableField, 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

110
                $this->removeFilepath($object, /** @scrutinizer ignore-type */ $fieldConfiguration);
Loading history...
111
            }
112
            /** @var UploadedDataUriFile|null $file */
113
            $file = $propertyAccessor->getValue($object, $fileProperty);
114
            if (!$file) {
115
                $classMetadata->setFieldValue($object, $fieldConfiguration->property, null);
116
                continue;
117
            }
118
119
            $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

119
            $filesystem = $this->filesystemProvider->getFilesystem(/** @scrutinizer ignore-type */ $fieldConfiguration->adapter);
Loading history...
120
121
            $path = $fieldConfiguration->prefix ?? '';
122
            $path .= $file->getFilename();
123
            $stream = fopen($file->getRealPath(), 'r');
124
            $filesystem->writeStream($path, $stream, [
125
                'mimetype' => $file->getMimeType(),
126
            ]);
127
            $classMetadata->setFieldValue($object, $fieldConfiguration->property, $path);
128
            $propertyAccessor->setValue($object, $fileProperty, null);
129
        }
130
    }
131
132
    public function deleteFiles(object $object): void
133
    {
134
        $classMetadata = $this->getClassMetadata($object);
135
136
        $configuredProperties = $this->annotationReader->getConfiguredProperties($object, true, true);
137
        foreach ($configuredProperties as $fileProperty => $fieldConfiguration) {
138
            $currentFilepath = $classMetadata->getFieldValue($object, $fieldConfiguration->property);
139
            if ($currentFilepath) {
140
                $this->removeFilepath($object, $fieldConfiguration);
0 ignored issues
show
Bug introduced by
It seems like $fieldConfiguration can also be of type string; however, parameter $fieldConfiguration of Silverback\ApiComponents...elper::removeFilepath() does only seem to accept Silverback\ApiComponents...otation\UploadableField, 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

140
                $this->removeFilepath($object, /** @scrutinizer ignore-type */ $fieldConfiguration);
Loading history...
141
            }
142
        }
143
    }
144
145
    private function removeFilepath(object $object, UploadableField $fieldConfiguration): void
146
    {
147
        $classMetadata = $this->getClassMetadata($object);
148
149
        $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

149
        $filesystem = $this->filesystemProvider->getFilesystem(/** @scrutinizer ignore-type */ $fieldConfiguration->adapter);
Loading history...
150
        $currentFilepath = $classMetadata->getFieldValue($object, $fieldConfiguration->property);
151
        $this->fileInfoCacheHelper->deleteCaches([$currentFilepath], [null]);
152
        if ($this->imagineCacheManager) {
153
            $this->imagineCacheManager->remove([$currentFilepath], null);
154
        }
155
        if ($filesystem->fileExists($currentFilepath)) {
156
            $filesystem->delete($currentFilepath);
157
        }
158
    }
159
}
160