Passed
Pull Request — master (#26)
by Philippe
08:53 queued 03:20
created

AssetUploader   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 208
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 18
eloc 56
dl 0
loc 208
ccs 63
cts 63
cp 1
rs 10
c 0
b 0
f 0

9 Methods

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