Completed
Push — master ( 8c6fdb...9454c8 )
by Freek
01:51 queued 17s
created

FileAdder::defaultSanitizer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Spatie\MediaLibrary\FileAdder;
4
5
use Spatie\MediaLibrary\Media;
6
use Spatie\MediaLibrary\Helpers\File;
7
use Illuminate\Database\Eloquent\Model;
8
use Spatie\MediaLibrary\Filesystem\Filesystem;
9
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded;
10
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;
11
use Symfony\Component\HttpFoundation\File\UploadedFile;
12
use Symfony\Component\HttpFoundation\File\File as SymfonyFile;
13
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded\UnknownType;
14
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded\FileIsTooBig;
15
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded\DiskDoesNotExist;
16
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded\FileDoesNotExist;
17
18
class FileAdder
19
{
20
    /** @var \Illuminate\Database\Eloquent\Model subject */
21
    protected $subject;
22
23
    /** @var \Spatie\MediaLibrary\Filesystem\Filesystem */
24
    protected $filesystem;
25
26
    /** @var bool */
27
    protected $preserveOriginal = false;
28
29
    /** @var string|\Symfony\Component\HttpFoundation\File\UploadedFile */
30
    protected $file;
31
32
    /** @var array */
33
    protected $properties = [];
34
35
    /** @var array */
36
    protected $customProperties = [];
37
38
    /** @var string */
39
    protected $pathToFile;
40
41
    /** @var string */
42
    protected $fileName;
43
44
    /** @var string */
45
    protected $mediaName;
46
47
    /** @var string */
48
    protected $diskName = '';
49
50
    /** @var null|callable */
51
    protected $fileNameSanitizer;
52
53
    /**
54
     * @param Filesystem $fileSystem
55
     */
56
    public function __construct(Filesystem $fileSystem)
57
    {
58
        $this->filesystem = $fileSystem;
59
60
        $this->fileNameSanitizer = function($fileName) {
61
            return $this->defaultSanitizer($fileName);
62
        };
63
    }
64
65
    /**
66
     * @param \Illuminate\Database\Eloquent\Model $subject
67
     *
68
     * @return FileAdder
69
     */
70
    public function setSubject(Model $subject)
71
    {
72
        $this->subject = $subject;
73
74
        return $this;
75
    }
76
77
    /*
78
     * Set the file that needs to be imported.
79
     *
80
     * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $file
81
     *
82
     * @return $this
83
     */
84
    public function setFile($file)
85
    {
86
        $this->file = $file;
87
88
        if (is_string($file)) {
89
            $this->pathToFile = $file;
90
            $this->setFileName(pathinfo($file, PATHINFO_BASENAME));
91
            $this->mediaName = pathinfo($file, PATHINFO_FILENAME);
92
93
            return $this;
94
        }
95
96
        if ($file instanceof UploadedFile) {
97
            $this->pathToFile = $file->getPath().'/'.$file->getFilename();
98
            $this->setFileName($file->getClientOriginalName());
99
            $this->mediaName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
100
101
            return $this;
102
        }
103
104
        if ($file instanceof SymfonyFile) {
105
            $this->pathToFile = $file->getPath().'/'.$file->getFilename();
106
            $this->setFileName(pathinfo($file->getFilename(), PATHINFO_BASENAME));
107
            $this->mediaName = pathinfo($file->getFilename(), PATHINFO_FILENAME);
108
109
            return $this;
110
        }
111
112
        throw UnknownType::create();
113
    }
114
115
    /**
116
     * When adding the file to the media library, the original file
117
     * will be preserved.
118
     *
119
     * @return $this
120
     */
121
    public function preservingOriginal()
122
    {
123
        $this->preserveOriginal = true;
124
125
        return $this;
126
    }
127
128
    /**
129
     * Set the name of the media object.
130
     *
131
     * @param string $name
132
     *
133
     * @return $this
134
     */
135
    public function usingName(string $name)
136
    {
137
        return $this->setName($name);
138
    }
139
140
    /**
141
     * Set the name of the media object.
142
     *
143
     * @param string $name
144
     *
145
     * @return $this
146
     */
147
    public function setName(string $name)
148
    {
149
        $this->mediaName = $name;
150
151
        return $this;
152
    }
153
154
    /**
155
     * Set the name of the file that is stored on disk.
156
     *
157
     * @param string $fileName
158
     *
159
     * @return $this
160
     */
161
    public function usingFileName(string $fileName)
162
    {
163
        return $this->setFileName($fileName);
164
    }
165
166
    /**
167
     * Set the name of the file that is stored on disk.
168
     *
169
     * @param string $fileName
170
     *
171
     * @return $this
172
     */
173
    public function setFileName(string $fileName)
174
    {
175
        $this->fileName = $fileName;
176
177
        return $this;
178
    }
179
180
    /**
181
     * Set the metadata.
182
     *
183
     * @param array $customProperties
184
     *
185
     * @return $this
186
     */
187
    public function withCustomProperties(array $customProperties)
188
    {
189
        $this->customProperties = $customProperties;
190
191
        return $this;
192
    }
193
194
    /**
195
     * Set properties on the model.
196
     *
197
     * @param array $properties
198
     *
199
     * @return $this
200
     */
201
    public function withProperties(array $properties)
202
    {
203
        $this->properties = $properties;
204
205
        return $this;
206
    }
207
208
    /**
209
     * Set attributes on the model.
210
     *
211
     * @param array $properties
212
     *
213
     * @return $this
214
     */
215
    public function withAttributes(array $properties)
216
    {
217
        return $this->withProperties($properties);
218
    }
219
220
    /**
221
     * Add the given additional headers when copying the file to a remote filesystem.
222
     *
223
     * @param array $customRemoteHeaders
224
     *
225
     * @return $this
226
     */
227
    public function addCustomHeaders(array $customRemoteHeaders)
228
    {
229
        $this->filesystem->addCustomRemoteHeaders($customRemoteHeaders);
230
231
        return $this;
232
    }
233
234
    /**
235
     * @param string $collectionName
236
     *
237
     * @return \Spatie\MediaLibrary\Media
238
     *
239
     * @throws FileCannotBeAdded
240
     * @throws \Spatie\MediaLibrary\Exceptions\FileCannotBeAdded
241
     */
242
    public function toMediaCollectionOnCloudDisk(string $collectionName = 'default')
243
    {
244
        return $this->toMediaCollection($collectionName, config('filesystems.cloud'));
245
    }
246
247
    /**
248
     * @param string $collectionName
249
     * @param string $diskName
250
     *
251
     * @return \Spatie\MediaLibrary\Media
252
     *
253
     * @throws FileCannotBeAdded
254
     * @throws \Spatie\MediaLibrary\Exceptions\FileCannotBeAdded
255
     */
256
    public function toMediaCollection(string $collectionName = 'default', string $diskName = '')
257
    {
258
        if (! is_file($this->pathToFile)) {
259
            throw FileDoesNotExist::create($this->pathToFile);
260
        }
261
262
        if (filesize($this->pathToFile) > config('medialibrary.max_file_size')) {
263
            throw FileIsTooBig::create($this->pathToFile);
264
        }
265
266
        $mediaClass = config('medialibrary.media_model');
267
        $media = new $mediaClass();
268
269
        $media->name = $this->mediaName;
270
271
        $this->fileName = ($this->fileNameSanitizer)($this->fileName);
272
273
        $media->file_name = $this->fileName;
274
        $media->disk = $this->determineDiskName($diskName);
275
276
        $media->collection_name = $collectionName;
277
278
        $media->mime_type = File::getMimetype($this->pathToFile);
279
        $media->size = filesize($this->pathToFile);
280
        $media->custom_properties = $this->customProperties;
281
        $media->manipulations = [];
282
283
        $media->fill($this->properties);
284
285
        $this->attachMedia($media);
286
287
        return $media;
288
    }
289
290
    /**
291
     * @param string $diskName
292
     *
293
     * @return string
294
     *
295
     * @throws \Spatie\MediaLibrary\Exceptions\FileCannotBeAdded
296
     */
297
    protected function determineDiskName(string $diskName)
298
    {
299
        if ($diskName === '') {
300
            $diskName = config('medialibrary.default_filesystem');
301
        }
302
303
        if (is_null(config("filesystems.disks.{$diskName}"))) {
304
            throw DiskDoesNotExist::create($diskName);
305
        }
306
307
        return $diskName;
308
    }
309
310
    /**
311
     * @param $fileName
312
     *
313
     * @return string
314
     */
315
    public function defaultSanitizer(string $fileName): string
316
    {
317
        return str_replace(['#', '/', '\\'], '-', $fileName);
318
    }
319
320
    /**
321
     * Sanitize the fileName of the file using a callable.
322
     *
323
     * @param callable $fileNameSanitizer
324
     *
325
     * @return $this
326
     */
327
    public function sanitizingFileName(callable $fileNameSanitizer)
328
    {
329
        $this->fileNameSanitizer = $fileNameSanitizer;
330
331
        return $this;
332
    }
333
334
    /**
335
     * @param Media $media
336
     */
337
    protected function attachMedia(Media $media)
338
    {
339
        if (! $this->subject->exists) {
340
            $this->subject->prepareToAttachMedia($media, $this);
341
342
            $class = get_class($this->subject);
343
344
            $class::created(function ($model) {
345
                $model->processUnattachedMedia(function (Media $media, FileAdder $fileAdder) use ($model) {
346
                    $this->processMediaItem($model, $media, $fileAdder);
347
                });
348
            });
349
350
            return;
351
        }
352
353
        $this->processMediaItem($this->subject, $media, $this);
354
    }
355
356
    /**
357
     * @param HasMedia $model
358
     * @param Media $media
359
     * @param FileAdder $fileAdder
360
     */
361
    protected function processMediaItem(HasMedia $model, Media $media, FileAdder $fileAdder)
362
    {
363
        $model->media()->save($media);
364
365
        $this->filesystem->add($fileAdder->pathToFile, $media, $fileAdder->fileName);
366
367
        if (! $fileAdder->preserveOriginal) {
368
            unlink($fileAdder->pathToFile);
369
        }
370
    }
371
}
372