Completed
Push — master ( a931e7...639746 )
by Freek
02:59
created

HasMediaTrait   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 294
Duplicated Lines 0 %

Coupling/Cohesion

Components 4
Dependencies 9

Importance

Changes 8
Bugs 0 Features 5
Metric Value
wmc 29
lcom 4
cbo 9
dl 0
loc 294
rs 10
c 8
b 0
f 5

18 Methods

Rating   Name   Duplication   Size   Complexity  
A bootHasMediaTrait() 0 10 2
B updateMedia() 0 32 5
A addMediaFromUrl() 0 16 2
A media() 0 4 1
A addMedia() 0 4 1
A addMediaFromRequest() 0 4 1
A copyMedia() 0 4 1
A hasMedia() 0 4 2
A getMedia() 0 4 1
A getFirstMedia() 0 6 1
A getFirstMediaUrl() 0 10 2
A getFirstMediaPath() 0 10 2
A removeMediaItemsNotPresentInArray() 0 10 1
A clearMediaCollection() 0 12 1
A deleteMedia() 0 14 3
A addMediaConversion() 0 8 1
A deletePreservingMedia() 0 6 1
A shouldDeletePreservingMedia() 0 4 1
1
<?php
2
3
namespace Spatie\MediaLibrary\HasMedia;
4
5
use Illuminate\Support\Collection;
6
use Spatie\MediaLibrary\Conversion\Conversion;
7
use Spatie\MediaLibrary\Events\CollectionHasBeenCleared;
8
use Spatie\MediaLibrary\Exceptions\FileCannotBeAdded;
9
use Spatie\Medialibrary\Exceptions\MediaCannotBeDeleted;
10
use Spatie\Medialibrary\Exceptions\MediaCannotBeUpdated;
11
use Spatie\MediaLibrary\FileAdder\FileAdderFactory;
12
use Spatie\MediaLibrary\Filesystem;
13
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;
14
use Spatie\MediaLibrary\Media;
15
use Spatie\MediaLibrary\MediaRepository;
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 false;
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 false;
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)->lists('id')->toArray());
0 ignored issues
show
Deprecated Code introduced by
The method Illuminate\Support\Collection::lists() has been deprecated with message: since version 5.2. Use the "pluck" method directly.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
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
244
        $this->getMedia($collectionName)->map(function (Media $media) {
245
            app(Filesystem::class)->removeFiles($media);
246
            $media->delete();
247
        });
248
249
        event(new CollectionHasBeenCleared($this, $collectionName));
250
251
        return $this;
252
    }
253
254
    /**
255
     * Delete the associated media with the given id.
256
     * You may also pass a media object.
257
     *
258
     * @param int|\Spatie\MediaLibrary\Media $mediaId
259
     *
260
     * @throws \Spatie\Medialibrary\Exceptions\MediaCannotBeDeleted
261
     */
262
    public function deleteMedia($mediaId)
263
    {
264
        if ($mediaId instanceof Media) {
265
            $mediaId = $mediaId->id;
266
        }
267
268
        $media = $this->media->find($mediaId);
269
270
        if (!$media) {
271
            throw MediaCannotBeDeleted::doesNotBelongToModel($media, $this);
272
        }
273
274
        $media->delete();
275
    }
276
277
    /*
278
     * Add a conversion.
279
     */
280
    public function addMediaConversion(string $name) : Conversion
281
    {
282
        $conversion = Conversion::create($name);
283
284
        $this->mediaConversions[] = $conversion;
285
286
        return $conversion;
287
    }
288
289
    /**
290
     * Delete the model, but preserve all the associated media.
291
     *
292
     * @return bool
293
     */
294
    public function deletePreservingMedia() : bool
295
    {
296
        $this->deletePreservingMedia = true;
297
298
        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...
299
    }
300
301
    /**
302
     * Determines if the media files will be deleted when the media object gets deleted.
303
     *
304
     * @return \Spatie\MediaLibrary\Media
305
     */
306
    public function shouldDeletePreservingMedia() {
307
308
        return $this->deletePreservingMedia ?? false;
309
    }
310
}
311