Skip to content

Commit fa5f6fb

Browse files
committed
Merge branch 'master' of github.com:gdarko/laravel-vue-starter
2 parents e59382d + c9790ac commit fa5f6fb

18 files changed

+215
-181
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The project is built with the following components:
1818
- Laravel Fortify
1919
- Tailwind
2020
- ForkAwesome
21+
- Media Library (by Spatie)
22+
- Bouncer (by JosephSilber)
2123

2224
## ⚡️ How to install
2325

app/Models/User.php

+49-25
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,28 @@
66
use App\Traits\Searchable;
77
use Illuminate\Contracts\Auth\MustVerifyEmail;
88
use Illuminate\Database\Eloquent\Factories\HasFactory;
9+
use Illuminate\Database\Eloquent\Relations\MorphMany;
910
use Illuminate\Foundation\Auth\User as Authenticatable;
11+
use Illuminate\Foundation\Testing\Concerns\InteractsWithAuthentication;
1012
use Illuminate\Notifications\Notifiable;
1113
use Illuminate\Support\Facades\Log;
1214
use Laravel\Sanctum\HasApiTokens;
1315
use Silber\Bouncer\Database\HasRolesAndAbilities;
16+
use Spatie\Image\Manipulations;
17+
use Spatie\MediaLibrary\HasMedia;
18+
use Spatie\MediaLibrary\InteractsWithMedia;
19+
use Spatie\MediaLibrary\MediaCollections\Models\Media;
1420

15-
class User extends Authenticatable implements MustVerifyEmail
21+
class User extends Authenticatable implements MustVerifyEmail, HasMedia
1622
{
1723
use HasApiTokens, HasFactory, Notifiable;
1824

1925
use HasRolesAndAbilities;
2026

2127
use Searchable, Filterable;
2228

29+
use InteractsWithMedia;
30+
2331
/**
2432
* ALlowed search fields
2533
* @var string[]
@@ -59,6 +67,7 @@ class User extends Authenticatable implements MustVerifyEmail
5967
*/
6068
protected $appends = [
6169
'avatar_url',
70+
'avatar_thumb_url',
6271
'full_name',
6372
];
6473

@@ -70,48 +79,41 @@ class User extends Authenticatable implements MustVerifyEmail
7079
public static function boot()
7180
{
7281
parent::boot();
73-
74-
static::deleting(function (self $record) {
75-
Log::info('Deleting user...');
76-
Log::info(json_encode($record->mediaFiles));
77-
Log::info(json_encode($record->mediaFiles()->get()));
78-
foreach ($record->mediaFiles()->get() as $entry) {
79-
$entry->delete();
80-
}
81-
});
8282
}
8383

8484
/**
85-
* Returns the user avatar
86-
* @return \Illuminate\Database\Eloquent\Relations\HasOne|MediaFile
85+
* @return \Closure|mixed|null|Media
8786
*/
8887
public function avatar()
8988
{
90-
return $this->hasOne(MediaFile::class, 'id', 'avatar_id');
89+
return $this->getMedia('avatars')->first();
9190
}
9291

9392
/**
94-
* Returns the user files
95-
* @return \Illuminate\Database\Eloquent\Relations\HasMany
93+
* Returns the avatar url attribute
94+
* @return string|null
9695
*/
97-
public function mediaFiles()
96+
public function getAvatarUrlAttribute()
9897
{
99-
return $this->hasMany(MediaFile::class, 'user_id', 'id');
98+
$avatar = $this->avatar();
99+
if ($avatar) {
100+
return $avatar->getFullUrl();
101+
}
102+
103+
return null;
100104
}
101105

102106
/**
103107
* Returns the avatar url attribute
104108
* @return string|null
105109
*/
106-
public function getAvatarUrlAttribute()
110+
public function getAvatarThumbUrlAttribute()
107111
{
108-
$src = $this->getAttribute('avatar_id');
109-
if (is_null($src)) {
110-
return null;
111-
}
112-
if (!empty($this->avatar)) {
113-
return asset('storage/'.$this->avatar->path);
112+
$avatar = $this->avatar();
113+
if ($avatar) {
114+
return $avatar->getAvailableFullUrl(['small_thumb']);
114115
}
116+
115117
return null;
116118
}
117119

@@ -124,10 +126,11 @@ public function getFullNameAttribute()
124126
$names = [];
125127
foreach (['first_name', 'middle_name', 'last_name'] as $key) {
126128
$value = $this->getAttribute($key);
127-
if (!empty($value)) {
129+
if ( ! empty($value)) {
128130
$names[] = $value;
129131
}
130132
}
133+
131134
return implode(' ', $names);
132135
}
133136

@@ -139,4 +142,25 @@ public function getIsAdminAttribute()
139142
{
140143
return $this->isAn('admin');
141144
}
145+
146+
/**
147+
* Register the conversions
148+
*
149+
* @param Media|null $media
150+
*
151+
* @return void
152+
* @throws \Spatie\Image\Exceptions\InvalidManipulation
153+
*/
154+
public function registerMediaConversions(Media $media = null): void
155+
{
156+
$this->addMediaConversion('small_thumb')
157+
->fit(Manipulations::FIT_CROP, 300, 300)
158+
->nonQueued();
159+
$this->addMediaConversion('medium_thumb')
160+
->fit(Manipulations::FIT_CROP, 600, 600)
161+
->nonQueued();
162+
$this->addMediaConversion('large_thumb')
163+
->fit(Manipulations::FIT_CROP, 1200, 1200)
164+
->nonQueued();
165+
}
142166
}

app/Services/Media/MediaService.php

+24-51
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,51 @@
44

55
use App\Models\MediaFile;
66
use App\Models\User;
7+
use Illuminate\Database\Eloquent\Builder;
78
use Illuminate\Database\Eloquent\Model;
89
use Illuminate\Http\UploadedFile;
910
use Illuminate\Support\Facades\Storage;
11+
use Spatie\MediaLibrary\MediaCollections\Exceptions\FileDoesNotExist;
12+
use Spatie\MediaLibrary\MediaCollections\Exceptions\FileIsTooBig;
13+
use Spatie\MediaLibrary\MediaCollections\Models\Media;
1014

1115
class MediaService
1216
{
1317
/**
1418
* Handles a file upload to the storage
19+
*
1520
* @param UploadedFile $file
16-
* @param User|Model $user
17-
* @return MediaFile|null|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
18-
*/
19-
public function storeAvatar(UploadedFile $file, User $user)
20-
{
21-
return $this->store($file, $user, 'public', 'avatars');
22-
}
23-
24-
/**
25-
* Deletes a file
26-
* @param MediaFile $entry
27-
* @return bool
21+
* @param User $user
22+
* @param $collection
23+
*
24+
* @return Media
25+
* @throws FileDoesNotExist
26+
* @throws FileIsTooBig
2827
*/
29-
public function deleteMedia(MediaFile $entry)
28+
public function replace(UploadedFile $file, User $user, $collection)
3029
{
31-
$disk = Storage::disk($entry->disk);
32-
if ($disk->exists($entry->path) && $disk->delete($entry->path)) {
33-
return $entry->delete();
30+
$media = $user->getMedia($collection);
31+
foreach ($media as $media_item) {
32+
$media_item->delete();
3433
}
35-
return false;
36-
}
3734

38-
/**
39-
* Handles a file upload to the storage
40-
* @param UploadedFile $file
41-
* @param User $user
42-
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|null
43-
*/
44-
public function storeMedia(UploadedFile $file, User $user)
45-
{
46-
return $this->store($file, $user, 'local', 'media');
35+
return $this->store($file, $user, $collection);
4736
}
4837

4938
/**
5039
* Handles a file upload to the storage
40+
*
5141
* @param UploadedFile $file
5242
* @param User $user
53-
* @param $disk
54-
* @param $subdir
55-
* @return \Illuminate\Database\Eloquent\Builder|Model|null
43+
* @param $collection
44+
*
45+
* @return Media
46+
* @throws FileDoesNotExist
47+
* @throws FileIsTooBig
5648
*/
57-
public function store(UploadedFile $file, User $user, $disk, $subdir)
49+
public function store(UploadedFile $file, User $user, $collection)
5850
{
59-
$name = $file->hashName();
60-
$dir = "{$subdir}/{$user->id}";
61-
$key = "{$dir}/{$name}";
62-
$path = $file->storeAs($dir, $name, ['disk' => $disk]);
63-
if (!$path) {
64-
return null;
65-
}
66-
return MediaFile::query()->create(
67-
attributes: [
68-
'name' => "{$name}",
69-
'file_name' => $file->getClientOriginalName(),
70-
'mime_type' => $file->getClientMimeType(),
71-
'path' => $key,
72-
'disk' => $disk,
73-
'file_hash' => $file->hashName(),
74-
'collection' => null,
75-
'user_id' => $user->id,
76-
'size' => $file->getSize(),
77-
],
78-
);
51+
return $user->addMedia($file)->toMediaCollection($collection);
7952
}
8053

8154
}

0 commit comments

Comments
 (0)