Completed
Push — master ( 058792...851441 )
by Freek
14:36
created

FileAdder::attachMedia()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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