Completed
Push — master ( 090ba5...2dbd35 )
by Freek
01:55
created

HasMediaTrait::loadMedia()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 17
nc 3
nop 1
1
<?php
2
3
namespace Spatie\MediaLibrary\HasMedia;
4
5
use Spatie\MediaLibrary\Media;
6
use Illuminate\Support\Collection;
7
use Spatie\MediaLibrary\Filesystem;
8
use Spatie\MediaLibrary\MediaRepository;
9
use Spatie\MediaLibrary\Conversion\Conversion;
10
use Spatie\MediaLibrary\FileAdder\FileAdderFactory;
11
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded;
12
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;
13
use Spatie\MediaLibrary\Events\CollectionHasBeenCleared;
14
use Spatie\MediaLibrary\Exceptions\MediaCannotBeDeleted;
15
use Spatie\MediaLibrary\Exceptions\MediaCannotBeUpdated;
16
17
trait HasMediaTrait
18
{
19
    /** @var array */
20
    public $mediaConversions = [];
21
22
    /** @var bool */
23
    protected $deletePreservingMedia = false;
24
25
    public static function bootHasMediaTrait()
26
    {
27
        static::deleted(function (HasMedia $entity) {
28
            if (! $entity->shouldDeletePreservingMedia()) {
29
                $entity->media()->get()->each(function (Media $media) {
30
                    $media->delete();
31
                });
32
            }
33
        });
34
    }
35
36
    /**
37
     * Set the polymorphic relation.
38
     *
39
     * @return mixed
40
     */
41
    public function media()
42
    {
43
        return $this->morphMany(config('laravel-medialibrary.media_model'), 'model');
44
    }
45
46
    /**
47
     * Add a file to the medialibrary.
48
     *
49
     * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $file
50
     *
51
     * @return \Spatie\MediaLibrary\FileAdder\FileAdder
52
     */
53
    public function addMedia($file)
54
    {
55
        return app(FileAdderFactory::class)->create($this, $file);
56
    }
57
58
    /**
59
     * Add a file from a request.
60
     *
61
     * @param string $key
62
     *
63
     * @return \Spatie\MediaLibrary\FileAdder\FileAdder
64
     */
65
    public function addMediaFromRequest(string $key)
66
    {
67
        return app(FileAdderFactory::class)->createFromRequest($this, $key);
68
    }
69
70
    /**
71
     * Add a remote file to the medialibrary.
72
     *
73
     * @param string $url
74
     *
75
     * @return \Spatie\MediaLibrary\FileAdder\FileAdder
76
     *
77
     * @throws \Spatie\MediaLibrary\Exceptions\FileCannotBeAdded
78
     */
79
    public function addMediaFromUrl(string $url)
80
    {
81
        if (! $stream = @fopen($url, 'r')) {
82
            throw FileCannotBeAdded::unreachableUrl($url);
83
        }
84
85
        $tmpFile = tempnam(sys_get_temp_dir(), 'media-library');
86
        file_put_contents($tmpFile, $stream);
87
88
        $filename = basename(parse_url($url, PHP_URL_PATH));
89
90
        return app(FileAdderFactory::class)
91
            ->create($this, $tmpFile)
92
            ->usingName(pathinfo($filename, PATHINFO_FILENAME))
93
            ->usingFileName($filename);
94
    }
95
96
    /**
97
     * Copy a file to the medialibrary.
98
     *
99
     * @param string|\Symfony\Component\HttpFoundation\File\UploadedFile $file
100
     *
101
     * @return \Spatie\MediaLibrary\FileAdder\FileAdder
102
     */
103
    public function copyMedia($file)
104
    {
105
        return $this->addMedia($file)->preservingOriginal();
106
    }
107
108
    /*
109
     * Determine if there is media in the given collection.
110
     */
111
    public function hasMedia(string $collectionName = '') : bool
112
    {
113
        return count($this->getMedia($collectionName)) ? true : false;
114
    }
115
116
    /*
117
     * Get media collection by its collectionName.
118
     *
119
     * @param string $collectionName
120
     * @param array|callable  $filters
121
     *
122
     * @return \Illuminate\Support\Collection
123
     */
124
    public function getMedia(string $collectionName = '', $filters = []) : Collection
125
    {
126
        return app(MediaRepository::class)->getCollection($this, $collectionName, $filters);
127
    }
128
129
    /**
130
     * Get the first media item of a media collection.
131
     *
132
     * @param string $collectionName
133
     * @param array  $filters
134
     *
135
     * @return Media|null
136
     */
137
    public function getFirstMedia(string $collectionName = 'default', array $filters = [])
138
    {
139
        $media = $this->getMedia($collectionName, $filters);
140
141
        return $media->first();
142
    }
143
144
    /*
145
     * Get the url of the image for the given conversionName
146
     * for first media for the given collectionName.
147
     * If no profile is given, return the source's url.
148
     */
149
    public function getFirstMediaUrl(string $collectionName = 'default', string $conversionName = '') : string
150
    {
151
        $media = $this->getFirstMedia($collectionName);
152
153
        if (! $media) {
154
            return '';
155
        }
156
157
        return $media->getUrl($conversionName);
158
    }
159
160
    /*
161
     * Get the url of the image for the given conversionName
162
     * for first media for the given collectionName.
163
     * If no profile is given, return the source's url.
164
     */
165
    public function getFirstMediaPath(string $collectionName = 'default', string $conversionName = '') : string
166
    {
167
        $media = $this->getFirstMedia($collectionName);
168
169
        if (! $media) {
170
            return '';
171
        }
172
173
        return $media->getPath($conversionName);
174
    }
175
176
    /**
177
     * Update a media collection by deleting and inserting again with new values.
178
     *
179
     * @param array  $newMediaArray
180
     * @param string $collectionName
181
     *
182
     * @return array
183
     *
184
     * @throws \Spatie\MediaLibrary\Exceptions\MediaCannotBeUpdated
185
     */
186
    public function updateMedia(array $newMediaArray, string $collectionName = 'default') : array
187
    {
188
        $this->removeMediaItemsNotPresentInArray($newMediaArray, $collectionName);
189
190
        $orderColumn = 1;
191
192
        $updatedMedia = [];
193
        foreach ($newMediaArray as $newMediaItem) {
194
            $mediaClass = config('laravel-medialibrary.media_model');
195
            $currentMedia = $mediaClass::findOrFail($newMediaItem['id']);
196
197
            if ($currentMedia->collection_name != $collectionName) {
198
                throw MediaCannotBeUpdated::doesNotBelongToCollection($collectionName, $currentMedia);
199
            }
200
201
            if (array_key_exists('name', $newMediaItem)) {
202
                $currentMedia->name = $newMediaItem['name'];
203
            }
204
205
            if (array_key_exists('custom_properties', $newMediaItem)) {
206
                $currentMedia->custom_properties = $newMediaItem['custom_properties'];
207
            }
208
209
            $currentMedia->order_column = $orderColumn++;
210
211
            $currentMedia->save();
212
213
            $updatedMedia[] = $currentMedia;
214
        }
215
216
        return $updatedMedia;
217
    }
218
219
    /**
220
     * @param array  $newMediaArray
221
     * @param string $collectionName
222
     */
223
    protected function removeMediaItemsNotPresentInArray(array $newMediaArray, string $collectionName = 'default')
224
    {
225
        $this->getMedia($collectionName, [])
226
            ->filter(function (Media $currentMediaItem) use ($newMediaArray) {
227
                return ! in_array($currentMediaItem->id, collect($newMediaArray)->pluck('id')->toArray());
228
            })
229
            ->map(function (Media $media) {
230
                $media->delete();
231
            });
232
    }
233
234
    /**
235
     * Remove all media in the given collection.
236
     *
237
     * @param string $collectionName
238
     *
239
     * @return $this
240
     */
241
    public function clearMediaCollection(string $collectionName = 'default')
242
    {
243
        $this->getMedia($collectionName)->map(function (Media $media) {
244
            app(Filesystem::class)->removeFiles($media);
245
            $media->delete();
246
        });
247
248
        event(new CollectionHasBeenCleared($this, $collectionName));
249
250
        if ($this->mediaIsPreloaded()) {
251
            unset($this->media);
252
        }
253
254
        return $this;
255
    }
256
257
    /**
258
     * Delete the associated media with the given id.
259
     * You may also pass a media object.
260
     *
261
     * @param int|\Spatie\MediaLibrary\Media $mediaId
262
     *
263
     * @throws \Spatie\MediaLibrary\Exceptions\MediaCannotBeDeleted
264
     */
265
    public function deleteMedia($mediaId)
266
    {
267
        if ($mediaId instanceof Media) {
268
            $mediaId = $mediaId->id;
269
        }
270
271
        $media = $this->media->find($mediaId);
272
273
        if (! $media) {
274
            throw MediaCannotBeDeleted::doesNotBelongToModel($media, $this);
275
        }
276
277
        $media->delete();
278
    }
279
280
    /*
281
     * Add a conversion.
282
     */
283
    public function addMediaConversion(string $name) : Conversion
284
    {
285
        $conversion = Conversion::create($name);
286
287
        $this->mediaConversions[] = $conversion;
288
289
        return $conversion;
290
    }
291
292
    /**
293
     * Delete the model, but preserve all the associated media.
294
     *
295
     * @return bool
296
     */
297
    public function deletePreservingMedia() : bool
298
    {
299
        $this->deletePreservingMedia = true;
300
301
        return $this->delete();
0 ignored issues
show
Bug introduced by
The method delete() does not exist on Spatie\MediaLibrary\HasMedia\HasMediaTrait. Did you maybe mean deleteMedia()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
302
    }
303
304
    /**
305
     * Determines if the media files should be preserved when the media object gets deleted.
306
     *
307
     * @return \Spatie\MediaLibrary\Media
308
     */
309
    public function shouldDeletePreservingMedia()
310
    {
311
        return $this->deletePreservingMedia ?? false;
312
    }
313
314
    protected function mediaIsPreloaded() : bool
315
    {
316
        return isset($this->media);
317
    }
318
319
    /**
320
     * Cache the media on the object.
321
     *
322
     * @param string $collectionName
323
     *
324
     * @return mixed
325
     */
326
    public function loadMedia(string $collectionName)
327
    {
328
        if ($this->mediaIsPreloaded()) {
329
            $media = $this->media->filter(function (Media $mediaItem) use ($collectionName) {
330
                if ($collectionName == '') {
331
                    return true;
332
                }
333
334
                return $mediaItem->collection_name == $collectionName;
335
            })->sortBy(function (Media $media) {
0 ignored issues
show
Unused Code introduced by
The parameter $media is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
336
                return $this->order_column;
0 ignored issues
show
Bug introduced by
The property order_column does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
337
            })->values();
338
339
            return $media;
340
        }
341
342
        $query = $this->media();
343
344
        if ($collectionName !== '') {
345
            $query = $query->where('collection_name', $collectionName);
346
        }
347
348
        $media = $query
349
            ->orderBy('order_column')
350
            ->get();
351
352
        return $media;
353
    }
354
}
355