I followed this tutorial for spatie Laravel Media Library and it worked for me.
Github Code: https://github.com/edwinaquino/Laravel-With-Spatie-Media-Library
Source: /g/APPS/REACT/OVERIMAGE/V5/LARAVEL/TUTORIAL/Code With Tony/laravel-media-posts
YOU CAN START WITH A NEW PROJECT IF NEEDED:laravel new DailyLogV3
cd DailyLogV3
code .
https://www.youtube.com/watch?v=FeIYurxiggU
Credit to: Code With Tony
$ composer require "spatie/laravel-medialibrary:^10.0.0"
$ php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
php artisan migrate
https://youtu.be/FeIYurxiggU?t=204php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="config"
https://youtu.be/FeIYurxiggU?t=294php artisan make:model Post -m
code database/migrations/2023_06_10_225451_create_posts_table.php
ADD:
$table->string('title');
$table->text('body');php artisan migrate
code routes/web.php
ADD:
use App\Http\Controllers\PostController;
Route::resource('/posts', PostController::class);php artisan make:controller PostController -r
code app/Http/Controllers/PostController.php
under create() ADD:
return view('posts.create');php artisan serve
mkdir resources/views/posts
code resources/views/posts/create.blade.php
php artisan make:component main
main.blade.php:
#####################################################
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:400,600&display=swap" rel="stylesheet" />
{{-- <script src="https://cdn.tailwindcss.com"></script> --}}
</head>
<body class="antialiased">
{{$slot}}
</body>
</html>
#####################################################
http://localhost:8000/posts/create
https://youtu.be/FeIYurxiggU?t=604code resources/views/components/main.blade.php
#####################################################
<x-main>
<div class="max-w-6xl mx-auto mt-12">
<form action="" enctype="multipart/form-data">
Post Title: <input type="text" name="title" id="title"><br />
Post Body: <input type="text" name="body" id="body"><br />
Post Image: <input type="file" name="image" id="image"><br />
<button type="submit">Create</button>
</form>
</div>
</x-main>
#####################################################$ php artisan make:request PostCreateRequest
$ code app/Http/Requests/PostCreateRequest.php
authorize()
FROM: return false
TO: return truecode app/Http/Controllers/PostController.php
#####################################################
ADD:
use App\Models\Post;
use App\Http\Requests\PostCreateRequest;
//// create()
public function create()
{
return view('posts.create');
}
//// store()
public function store(PostCreateRequest $request)
{
//https://stackoverflow.com/questions/58450648/too-few-arguments-through-laravel-custom-request-class
$validated = $request->validated();
Post::create($validated);
}
#####################################################code app/Models/Post.php
#####################################################
ADD after use HasFactory;
protected $guarded = [];
#####################################################
https://youtu.be/FeIYurxiggU?t=921code app/Models/Post.php
#####################################################
ADD
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
CHANGE:
FROM: class Post extends Model
TO: class Post extends Model implements HasMedia
ADD: InteractsWithMedia to:
use HasFactory, InteractsWithMedia;
#####################################################
https://youtu.be/FeIYurxiggU?t=1000code app/Http/Controllers/PostController.php
#####################################################
CHANGE store() TO:
public function store(PostCreateRequest $request) {
$validated = $request->validated();
$post = Post::create($validated);
if ($request->hasFile('image')) {
$post->addMediaFromRequest('image')
->usingName('Documents')
->toMediaCollection();
}
}
#####################################################
TRY IT: http://localhost:8000/posts/create
check media table: http://localhost:8080/phpmyadmin/index.php?route=/sql&pos=0&db=laravel_medialib&table=media
IF YOU WANT TO CHANGE THE colunm "name" to 'Documents' NAME IN THE DATABASE: https://youtu.be/FeIYurxiggU?t=1205
->usingName('Documents')
code app/Http/Controllers/PostController.php
#####################################################
CHANGE store() TO:
public function store(PostCreateRequest $request)
{
$validated = $request->validated();
$post = Post::create($validated);
$post->addMediaFromRequest('image')
->usingName('Documents') // or ->usingName($post->title)
->toMediaCollection();
}
#####################################################
TRY IT: http://localhost:8000/posts/create
check media table: http://localhost:8080/phpmyadmin/index.php?route=/sql&pos=0&db=laravel_medialib&table=media
https://youtu.be/FeIYurxiggU?t=1362
https://www.webune.com/forums/solution-laravel-spatie-image-lirbary-unable-to-view-images-with-href.html
https://www.webune.com/forums/laravel-spatie-image-lirbary-error-call-to-a-member-function-geturl-on-null.htmlcode resources/views/posts/index.blade.php
#####################################################
<x-main>
<div class="max-w-6xl mx-auto mt-12">
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Image</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach ($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td>{{ $post->title }}</td>
{{-- <td> <img src="{{ $post->getFirstMedia()->getUrl() }}" alt="image{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td> --}}
<!--OR use getFirstMediaUrl-->
<td><img src="{{ $post->getFirstMediaUrl() }}" alt="image{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td>
<td><a href="{{ route('posts.edit', $post->id) }}" class="btn btn-success">Edit</a></td>
<td><form action="{{ route('posts.destroy', $post->id) }}" onsubmit="return confirm('Are you sure?');">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form></td>
</tr>
@endforeach
</x-main>
#####################################################
E D I T
https://youtu.be/FeIYurxiggU?t=1477code app/Http/Controllers/PostController.php
#####################################################
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
#####################################################code resources/views/posts/edit.blade.php
#####################################################
<x-main>
<div class="max-w-6xl mx-auto mt-12">
<h1>Edit Post Id: {{$post->id}}</h1>
<form method="POST" action="{{ route('posts.update', $post->id) }}" enctype="multipart/form-data">
@csrf
@method('PUT')
Post Title: <input type="text" name="title" id="title" value="{{$post->title}}">><br />
Post Body: <input type="text" name="body" id="body" value="{{$post->body}}"><br />
Post Image: <input type="file" name="image" id="image"><br />
<button type="submit">Create</button>
</form>
</div>
</x-main>
#####################################################
https://youtu.be/FeIYurxiggU?t=1708code app/Http/Controllers/PostController.php
#####################################################
public function update(PostCreateRequest $request, Post $post)
{
// UPDATE DATABASE
$validated = $request->validated();
$post->update($validated);
if($request->hasFile('image')){
// delete the previous image
$post->clearMediaCollection();
// UPDATE the new image
$post->addMediaFromRequest('image')
->usingName('Documents')
->toMediaCollection();
}
return to_route('posts.index');
}
#####################################################
https://youtu.be/FeIYurxiggU?t=1946
UPDATE index.blade.phpcode resources/views/posts/index.blade.php
#####################################################
<x-main>
<div class="max-w-6xl mx-auto mt-12">
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Image</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach ($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td>{{ $post->title }}</td>
{{-- <td> <img src="{{ $post->getFirstMedia()->getUrl() }}" alt="image{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td> --}}
<!--OR use getFirstMediaUrl-->
<td><img src="{{ $post->getFirstMediaUrl() }}" alt="image{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td>
<td><a href="{{ route('posts.edit', $post->id) }}" class="btn btn-success">Edit</a></td>
<td><form
method="POST"
action="{{ route('posts.destroy', $post->id) }}"
onsubmit="return confirm('Are you sure?');"
>
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form></td>
</tr>
@endforeach
</x-main>
#####################################################
DELETE
https://youtu.be/FeIYurxiggU?t=1948code app/Http/Controllers/PostController.php
ADD function destroy()
#####################################################
public function destroy($id)
{
$post= Post::findOrFail($id);
$post->delete();
return to_route('posts.index');
}
/*
// ANOTHER WAY TO DELETE
public function destroy(Post $post)
{
$post->delete();
return to_route('posts.index');
}
*/
#####################################################
IMAGE COLLECTIONS: 'images' - this will add 'images' to the 'collection' column in the media database table
https://youtu.be/FeIYurxiggU?t=2011code app/Http/Controllers/PostController.php
#####################################################
UPDATE FROM: ->toMediaCollection();
TO: ->toMediaCollection('images');
#####################################################code resources/views/posts/index.blade.php
#####################################################
UPDATE FROM:img src="{{ $post->getFirstMediaUrl() }}"
TO: img src="{{ $post->getFirstMediaUrl('images') }}"
UPDATE FROM: $post->clearMediaCollection();
to: $post->clearMediaCollection('image');
#####################################################
https://youtu.be/FeIYurxiggU?t=2280
ADD ANOTHER IMAGE COLLECTION:
https://youtu.be/FeIYurxiggU?t=2433code app/Http/Controllers/PostController.php
#####################################################
Add to update and create methods:
if ($request->hasFile('download')) {
// delete the previous image
$post->clearMediaCollection('downloads');
// UPDATE the new image
$post->addMediaFromRequest('download')
->usingName('Documents')
->toMediaCollection('downloads');
}
#####################################################
CREATE A DOWNLOAD LINK FOR IMAGES:
https://youtu.be/FeIYurxiggU?t=2600code routes/web.php
ADD:
#####################################################
Route::get('/downloads/{id}', [PostController::class, 'download']);
#####################################################code app/Http/Controllers/PostController.php
#####################################################
public function download($id) {
$post = Post::findOrFail($id);
$media = $post->getFirstMedia('donloads');
return $media;
}
#####################################################
TEST THE DOWNLOA IN BROWSER: http://127.0.0.1:8000/downloads/5
WORKS!!!!!!!!!!!
DOWNLOAD ALL COLLECTION FILES:code routes/web.php
ADD:
#####################################################
Route::get('/downloads', [PostController::class, 'downloads']);
#####################################################code app/Http/Controllers/PostController.php
#####################################################
public function downloads() {
$media = Media::where('collection_name','downloads')->get();
return MediaStream::create('donwloads.zip')->addMedia($media);
}
#####################################################
https://youtu.be/FeIYurxiggU?t=2895
TEST THE DOWNLOA IN BROWSER: http://127.0.0.1:8000/downloads
WORKS!!!!!!!!!!!
DOWNLOAD ALL FILES:code routes/web.php
ADD:
#####################################################
Route::get('/downloadsall', [PostController::class, 'downloadsall']); //DOWNLOAD ALL FILES:
#####################################################code app/Http/Controllers/PostController.php
#####################################################
public function downloadsall() {
return MediaStream::create('donwloads.zip')->addMedia(Media::all());
}
#####################################################
TEST THE DOWNLOA IN BROWSER: http://127.0.0.1:8000/downloadsall
WORKS!!!!!!!!!!!
BETTER WAY TO REMOVE/UPDATE MEDIA COLLECTIONS:
https://youtu.be/FeIYurxiggU?t=3063code app/Http/Controllers/PostController.php
#####################################################
in update()
REMOVE or COMMENTOUT: $post->clearMediaCollection('images');
#####################################################code app/Models/Post.php
#####################################################
ADD
public function registerMediaCollections(): void
{
$this->addMediaCollection('images')
->singleFile();
}
#####################################################
TRY IN BROWSER: http://127.0.0.1:8000/posts
WORKS!!!!!!!!!!!
https://youtu.be/FeIYurxiggU?t=3345
https://spatie.be/docs/laravel-medialibrary/v10/converting-images/defining-conversions
MEDIA CONVERSIONS - CREATE A THUMBcode app/Models/Post.php
#####################################################
ADD
use Spatie\MediaLibrary\MediaCollections\Models\Media;
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(368)
->height(232)
->sharpen(10);
}
#####################################################
TRY IN BROWSER: http://127.0.0.1:8000/posts/create
Look in the public/storage/[ID] folder and you will see a Conversions folder where you can find the thumb image: storage/app/public/[id]$ ls storage/app/public/20/conversions
USAGE:code resources/views/posts/index.blade.php
#####################################################
CHANGE:
{{-- FULL IMAGE --}}
{{-- <td><img src="{{ $post->getFirstMediaUrl('images') }}" alt="image{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td> --}}
{{-- // THUMB IMAGE --}}
<td><img src="{{ $post->getFirstMedia('images')->getUrl('thumb') }}" alt="image{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td>
{{-- FULL IMAGE --}}
{{-- <td><img src="{{ $post->getFirstMediaUrl('downloads') }}" alt="download{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td> --}}
{{-- // THUMB DOWNLOA --}}
<td><img src="{{ $post->getFirstMedia('downloads')->getUrl('thumb') }}" alt="download{{ $post->id }}" class="img-thumbnail" style="width:250px" /></td>
#####################################################
https://youtu.be/FeIYurxiggU?t=3536
TRY IN BROWSER: http://127.0.0.1:8000/posts
RESPONSIVE IMAGES
https://spatie.be/docs/laravel-medialibrary/v10/responsive-images/getting-started-with-responsive-imagescode app/Http/Controllers/PostController.php
#####################################################
REPLACE ALL: ->usingName('Documents')
WITH: ->withResponsiveImages()
#####################################################
TRY IN BROWSER: http://127.0.0.1:8000/posts/create
(TAKES A WHILE TO LOAD)
SEE THE NEWLY CREATED folder: responsive_images$ ls storage/app/public/22/responsive-images
laravel-no-gd-extension-missing___media_library_original_1074_449.jpg
laravel-no-gd-extension-missing___media_library_original_1283_537.jpg
laravel-no-gd-extension-missing___media_library_original_1534_642.jpg
laravel-no-gd-extension-missing___media_library_original_1834_767.jpg
laravel-no-gd-extension-missing___media_library_original_526_220.jpg
laravel-no-gd-extension-missing___media_library_original_629_263.jpg
laravel-no-gd-extension-missing___media_library_original_751_314.jpg
laravel-no-gd-extension-missing___media_library_original_898_376.jpg
APPLY TO VIEW REPONSIVE IMAGES:code routes/web.php
#####################################################
Route::get('/res-image/{id}', [PostController::class, 'resImage']); // RESPONIVE IMAGES
#####################################################code app/Http/Controllers/PostController.php
#####################################################
public function resImage($id) {
//return $id;
$post = Post::findOrFail($id);
return view('posts.show', compact('post'));
}
#####################################################code resources/views/posts/show.blade.php
#####################################################
<x-main>
<div class="container">
<div class="row">
<h1>{{$post->title}}</h1>
{{$post->getFirstMedia('downloads')}}
</div>
</div>
</x-main>
#####################################################
TRY IN BROWSER: http://127.0.0.1:8000/resimage/7
WORKS!!!!!!!!!!!
try with different browser window size and in the network tab you will see diferent size images downloading.
https://youtu.be/FeIYurxiggU?t=4005