In this chapter, we can edit the covers of a particular record
Delete the cover
Upload a new cover
Reset the cover by downloading it from the MusicBrainz API
In the next chapter, we list all the redundant covers in our storage and delete them
WARNING
Even though you can perfectly separate the two functionalities on two different pages, we will keep them on the same page
to demonstrate how route-parameters works and how to use those parameters in the Livewire component
Create a new Livewire component with the terminal command php artisan make:livewire Admin/Covers
app/Http/Livewire/Admin/Covers.php (the component class)
resources/views/livewire/admin/covers.blade.php (the component view)
Open the component class and change the layout to layouts.vinylshop (leave the title empty)
classCoversextendsComponent{publicfunctionrender(){returnview('livewire.admin.covers')->layout('layouts.vinylshop',['description'=>'Manage album covers','title'=>'',]);}}
You can name the parameter whatever you want, but keep in mind that you have to use
the same name in the Livewire component otherwise the parameter will not be passed
classCoversextendsComponent{public$showModal=false;public$record=null;public$newCover;public$redundantCovers=[];// open modal to upload a new coverpublicfunctionopenModal(){$this->reset('newCover');$this->resetValidation();$this->showModal=true;}// get the uploaded cover and save it to the diskpublicfunctionsaveCover(){}// try to get the original cover from the coverartarchive.orgpublicfunctiongetOriginalCover(){}// delete the cover from the diskpublicfunctiondeleteCover(){}// save the cover to the diskpublicfunctionsaveToDisk($cover){}publicfunctionmount($id=null){}publicfunctionrender(){returnview('livewire.admin.covers')->layout('layouts.vinylshop',['description'=>'Manage album covers','title'=>'',]);}}
The mount() method of the Covers component has a parameter $id with a default value of null
If the parameter is not null, the mount() method will get the record with the given id from the database
If the parameter is null, the mount() method don't do anything for now (see part 2)
publicfunctionmount($id=null){if($id){// get the selected record if id is not null$this->record= Record::findOrFail($id);}else{// get all the redundant covers from the disk}}
1 2 3 4 5 6 7 8 9
`find()` vs `findOrFail()`
To select one single record from the database, you can use the findOrFail() method or the find() method
If you try to select a record that doesn't exist:
the findOrFail() method will throw a 404 exception
Every time you upload a new file, a new temporary file will be created and stored in the storage/app/livewire-temp directory
In the screenshot below you can see that I temporarily uploaded 4 files, and they are all stored on the server, in the storage/app/livewire-temp directory
Livewire will automatically delete the temporary files after 24 hours, but you can also delete them manually
The SAVE button will only be visible if the newCover property contains a value
When the SAVE button is clicked, the saveCover() method will be called and:
Line 8 - 10: validate the newCover property
Line 11: create a new Image object from the newCover property, resize it to 250x250 pixels and encode it to a jpg file with a quality of 75%
Line 12: call the saveToDisk() method to save the cover to the disk
Line 14 -17: delete all temporary files from the livewire-tmp directory (optional)
Line 18: close the modal
The saveToDisk() method will;
Line 30: set the path where the cover will be saved
Line 31: save the cover to the disk
Line 32: reset the newCover and showModal properties
classCoversextendsComponent{...// get the uploaded cover and save it to the diskpublicfunctionsaveCover(){$this->validate(['newCover'=>'required|image|mimes:jpg,jpeg,png,webp',]);$cover= Image::make($this->newCover->getRealPath())->fit(250,250)->encode('jpg',75);$this->saveToDisk($cover);// delete all temporary files from the livewire-tmp directory (optional)$files= Storage::disk('local')->files('livewire-tmp');foreach($filesas$file){
Storage::disk('local')->delete($file);}$this->showModal=false;}// try to get the original cover from the coverartarchive.orgpublicfunctiongetOriginalCover(){}// delete the cover from the diskpublicfunctiondeleteCover(){}// save the cover to the diskpublicfunctionsaveToDisk($cover){$coverName='covers/'.$this->record->mb_id.'.jpg';
Storage::disk('public')->put($coverName,$cover,'public');$this->reset('newCover','showModal');}...}
When you upload a new cover, the browser will cache the image and probably won't show the new cover because it thinks it's already in his cache
(the name of the file is not changed, only the content)
To avoid this, you can add a random string to the end of the image url, eg: the current timestamp
Update the src attribute of the img tag in the livewire/admin/covers.blade.php file
Line 10: try to get the original cover from the coverartarchive.org
Line 11: if the cover is found than the variable $cover has a status code of 200
Line 12: get the cover and encode it to a jpg file with a quality of 75%
Line 13: save the cover to the disk
Line 15 - 16: if the cover is not available, show a toast message
classCoversextendsComponent{...// try to get the original cover from the coverartarchive.orgpublicfunctiongetOriginalCover(){$mb_id=$this->record->mb_id;$url="https://coverartarchive.org/release/{$mb_id}/front-250.jpg";$cover= Http::get($url);if($cover->status()===200){$cover= Image::make($cover->body())->encode('jpg',75);$this->saveToDisk($cover);}else{$this->dispatchBrowserEvent('swal:toast',['background'=>'error','html'=>'Cover not available on the Cover Art Archive',]);}}...}
Line 11: add a listener for the deleteCover event and call the deleteCover() method
Line 18 - 19: delete the cover from the disk
classCoversextendsComponent{useWithFileUploads;public$showModal=false;public$record=null;public$newCover;public$redundantCovers=[];protected$listeners=['deleteCover'];...// delete the cover from the diskpublicfunctiondeleteCover(){$coverName='covers/'.$this->record->mb_id.'.jpg';
Storage::disk('public')->delete($coverName);}}