Passed
Push — dependabot/composer/orchestra/... ( 137c82...0b1a28 )
by
unknown
04:18
created

AssetUploader::isImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\AssetLibrary\Application;
4
5
use Illuminate\Http\UploadedFile;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded;
9
use Spatie\MediaLibrary\FileAdder\FileAdder;
10
use Thinktomorrow\AssetLibrary\Asset;
11
use Traversable;
12
13
class AssetUploader
14
{
15
    /**
16
     * Uploads the file/files or asset by creating the
17
     * asset that is needed to upload the files too.
18
     *
19
     * @param Asset|Traversable|array|Collection|UploadedFile $files
20
     * @param string|null $filename
21
     * @return Collection|null|Asset
22
     * @throws FileCannotBeAdded
23
     */
24 31
    public static function upload($files, ?string $filename = null)
25
    {
26 31
        if ($files instanceof Asset) {
27 2
            return $files;
28
        }
29
30 30
        if (is_array($files) || $files instanceof Traversable) {
31 2
            return self::uploadMultiple($files);
32
        }
33
34 29
        if (! ($files instanceof UploadedFile)) {
0 ignored issues
show
introduced by
$files is always a sub-type of Illuminate\Http\UploadedFile.
Loading history...
35 1
            return;
36
        }
37
38 28
        return self::uploadToAsset($files, Asset::create(), $filename);
39
    }
40
41
    /**
42
     * Uploads the multiple files or assets by creating the
43
     * asset that is needed to upload the files too.
44
     *
45
     * @param Asset|Traversable|array $files
46
     * @return Collection
47
     */
48 2
    private static function uploadMultiple($files)
49
    {
50 2
        $list = collect([]);
51
        collect($files)->each(function ($file) use ($list) {
52 2
            if ($file instanceof Asset) {
53 1
                $list->push($file);
54
            } else {
55 2
                $asset = new Asset();
56 2
                $asset->save();
57 2
                $list->push(self::uploadToAsset($file, $asset, null));
58
            }
59 2
        });
60
61 2
        return $list;
62
    }
63
64
    /**
65
     * Uploads the file/files or asset by creating the
66
     * asset that is needed to upload the files too.
67
     *
68
     * @param string $file
69
     * @param string|null $filename
70
     * @return Collection|null|Asset
71
     * @throws FileCannotBeAdded
72
     */
73 6
    public static function uploadFromBase64($file, $filename = null)
74
    {
75 6
        return self::uploadBase64ToAsset($file, Asset::create(), $filename);
76
    }
77
78
    /**
79
     * Uploads the url by creating the
80
     * asset that is needed to upload the files too.
81
     *
82
     * @param string $url
83
     * @return Asset
84
     * @throws FileCannotBeAdded
85
     */
86 11
    public static function uploadFromUrl($url)
87
    {
88 11
        return self::uploadFromUrlToAsset($url, Asset::create());
89
    }
90
91
    /**
92
     * Uploads the given file to this instance of asset
93
     * and sets the dimensions as a custom property.
94
     *
95
     * @param UploadedFile $file
96
     * @param Asset $asset
97
     * @param string|null $filename
98
     * @return null|Asset
99
     * @throws FileCannotBeAdded
100
     */
101 29
    public static function uploadToAsset($file, $asset, $filename = null): ?Asset
102
    {
103 29
        $customProps = [];
104 29
        if (self::isImage($file)) {
105 28
            $imagesize = getimagesize($file);
106
107 28
            $customProps['dimensions'] = $imagesize[0].' x '.$imagesize[1];
108
        }
109
110 29
        $fileAdd = $asset->addMedia($file)
111 29
                        ->withCustomProperties($customProps);
112
113 29
        $fileAdd = self::prepareOptions($fileAdd, $filename);
114
115 29
        $fileAdd->withResponsiveImages()->toMediaCollection();
116
117 29
        return $asset->load('media');
118
    }
119
120
    /**
121
     * Uploads the given file to this instance of asset
122
     * and sets the dimensions as a custom property.
123
     *
124
     * @param string $file
125
     * @param Asset $asset
126
     * @param string|null $filename
127
     * @return null|Asset
128
     * @throws FileCannotBeAdded
129
     * @internal param $files
130
     */
131 6
    public static function uploadBase64ToAsset($file, $asset, $filename = null): ?Asset
132
    {
133 6
        $fileAdd = $asset->addMediaFromBase64($file);
134
135 6
        if (! $filename) {
136 1
            $extension = substr($file, 11, strpos($file, ';') - 11);
137 1
            $filename  = pathinfo($file, PATHINFO_BASENAME).'.'.$extension;
138
        }
139
140 6
        $fileAdd = self::prepareOptions($fileAdd, $filename);
141
142 6
        $fileAdd->toMediaCollection();
143
144 6
        return $asset->load('media');
145
    }
146
147
    /**
148
     * Uploads the given file to this instance of asset
149
     * and sets the dimensions as a custom property.
150
     *
151
     * @param string $url
152
     * @param Asset $asset
153
     * @return Asset
154
     * @throws FileCannotBeAdded
155
     */
156 11
    public static function uploadFromUrlToAsset($url, $asset): Asset
157
    {
158 11
        $fileAdd = $asset->addMediaFromUrl($url);
159
160 11
        $filename = substr($url, strrpos($url, '/') + 1);
161 11
        $fileAdd->setName($filename);
162
163 11
        $fileAdd = self::prepareOptions($fileAdd, $filename);
164
165 11
        $fileAdd->toMediaCollection();
166
167 11
        return $asset->load('media');
168
    }
169
170
    /**
171
     * @param UploadedFile $file
172
     * @return bool
173
     */
174 29
    private static function isImage($file): bool
175
    {
176 29
        return Str::before($file->getMimetype() ?? '', '/') === 'image';
177
    }
178
179
    /**
180
     * Set the possible options on the fileAdder. This includes preserveOriginal
181
     * and filename.
182
     *
183
     * @param FileAdder $fileAdd
184
     * @param string|null $filename
185
     * @return FileAdder
186
     * @throws FileCannotBeAdded
187
     */
188 45
    private static function prepareOptions($fileAdd, $filename): FileAdder
189
    {
190 45
        if ($filename) {
191 19
            $fileAdd->usingName(substr($filename, 0, strpos($filename, '.')));
192 19
            $fileAdd->usingFileName($filename);
193
        }
194
195 45
        $fileAdd->preservingOriginal();
196
197
        // Sanitize filename by sluggifying the filename without the extension
198
        $fileAdd->sanitizingFileName(function ($filename) {
199 45
            $extension = substr($filename, strrpos($filename, '.') + 1);
200 45
            $filename  = substr($filename, 0, strrpos($filename, '.'));
201 45
            $filename  = Str::slug($filename).'.'.$extension;
202
203 45
            return strtolower($filename);
204 45
        });
205
206 45
        return $fileAdd;
207
    }
208
}
209