Laravel 11

Albums – Gérer les images

Dans le chapitre précédent, nous avons mis en place l’affichage de la galerie en prévoyant la possibilité de présenter les photos par catégorie et par auteur. Nous allons maintenant implémenter les fonctions de suppression de photos et ajouter la possibilité de modifier la description, la catégorie et le statut adulte. Ces actions doivent être réservées au créateur de la photo et à l’administrateur pour préserver l’intégrité de la plateforme.

Des boutons de commande

Pour chaque image, on va prévoir deux boutons :

  • pour supprimer l’image
  • pour modifier l’image : description, catégorie et statut adulte

On ajoute le code de la vue (toujours le composant index) :

<div class="relative items-center grid w-full px-5 py-5 mx-auto md:px-12 max-w-7xl">

    ...
    @adminOrOwner($image->user_id)                
    <div class="flex justify-between mt-2">
        <x-button 
            wire:click="deleteImage({{ $image->id }})" 
            icon="o-fire" 
            class="btn-circle btn-ghost text-left"
            wire:confirm="{{__('Are you sure to delete this photo?')}}"
            tooltip="{{__('Delete this photo')}}"/>
        <x-button wire:click="editImage({{ $image->id }})" icon="o-cog" class="btn-circle btn-ghost text-right" tooltip="{{__('Edit photo')}}"/>
    </div>
    @endadminOrOwner

    <x-slot:figure>
    <a href="{{ asset('storage/images/' . $image->name) }}">
        <img src="{{ asset('storage/thumbs/' . $image->name) }}" />
    </a>
    </x-slot:figure>
    ...
</div>

On ajoute ces traductions :

"Delete this photo": "Supprimer cette photo",
"Are you sure to delete this photo?": "Voulez-vous supprimer cette photo ?",
"Edit photo": "Modifier cette photo"

On voit apparaître les deux boutons pour chaque image :

Avec un message d’alerte pour la suppression :

Supprimer une photo

Commençons par la suppression qui est l’action la plus simple. On ajoute l’action dans le PHP du composant :

public function deleteImage(ImageRepository $imageRepository, int $id): void
{
    $imageRepository->deleteImage($id);
    $this->success(__('Photo deleted with success.'), redirectTo: '/');
}

On prévoit la traduction :

"Photo deleted with success.": "La photo a bien été supprimée"

D’autre part pour que le message de confirmation fonctionne, on doit ajouter Toast au composant :

...

use Mary\Traits\Toast;

new class extends Component {

    use Toast;

On voit qu’on fait appel au repository ImageRepository pour la suppression effective, on va donc coder cette suppression :

use Illuminate\Support\Facades\Storage;

class ImageRepository
{
    ...

    public function deleteImage(int $id): void
    {
        $image = Image::find($id);
        Storage::disk('public')->delete ([
            'images/' . $image->name,
            'thumbs/' . $image->name,
        ]);
        $image->delete();
    }

On supprime dans la base, mais également sur le disque, aussi bien l’image en dimension normale que sa vignette. Vous n’avez plus qu’à vérifier que ça fonctionne…

Modifier une photo

Voyons maintenant la partie la plus délicate de la modification. Pour une meilleure esthétique et pour changer un peu, on va prévoir une page modale. MaryUi propose un joli composant pour le faire :

<div class="relative items-center grid w-full px-5 py-5 mx-auto md:px-12 max-w-7xl">

    <x-modal wire:model="imageModal" title="{{__('Manage Photo')}}" separator>
        <x-form wire:submit="saveImage"> 
            <x-input label="{{__('Description')}}" value="{{ $description }}" wire:model="description" hint="{{__('Describre your image here')}}" />
            <x-select label="{{__('Category')}}" icon="o-tag" :options="$categories" wire:model="category_id" hint="{{__('Choose a pertinent category')}}"/>
            <x-checkbox label="{{ __('Adult content') }}" wire:model="adult"/>
            <x-slot:actions>
                <x-button label="{{__('Cancel')}}" icon="o-x-mark" class="btn-ghost" @click="$wire.imageModal = false" />
                <x-button label="{{__('Save')}}" type="submit" icon="o-check" class="btn-primary" />
            </x-slot:actions>
        </x-form>
    </x-modal>

On ajoute la commande en PHP :

...

use Livewire\Attributes\Rule;   

new class extends Component {

    ...

    #[Rule('required|exists:categories,id')]
    public string $category_id = '';

    #[Rule('nullable|string|max:255')]
    public $description = '';

    #[Rule('boolean')]
    public bool $adult = false;

    public bool $imageModal = false;

    ...

    public function editImage(ImageRepository $imageRepository, int $id): void
    {
        $this->image = $imageRepository->getImage($id);

        $this->description = $this->image->description;
        $this->category_id = $this->image->category_id;
        $this->adult = $this->image->adult;
        
        $this->imageModal = true;
    }

On prévoit les propriétés avec leurs règles de validation et la commande proprement dite qui fait appel au repository pour récupérer les informations sur l’image et qui ouvre la page modale.

On ajoute la fonction dans le repository ImageRepository :

public function getImage(int $id)
{
    return Image::find($id);
}

Et la traduction :

"Manage Photo": "Modification de la photo"

On obtient le formulaire dans la page modale :

On ajoute le traitement de la modification dans le PHP :

use App\Models\Image;  

new class extends Component {

    ...

    public Image $image;

    ...

    public function saveImage(ImageRepository $imageRepository): void
    {
        $data = $this->validate();

        $imageRepository->saveImage($this->image, $data);

        $this->success(__('Photo changed with success.'));

        $this->imageModal = false;
    }

Et le traitement effectif dans le repository :

public function saveImage(Image $image, array $data): void
{
    $image->update($data);
}

Et encore une traduction :

"Photo changed with success.": "La photo a bien été modifiée"

Vérifiez que tout ça fonctionne bien !

Conclusion

Dans ce chapitre, on a vu la modification d’une photo existante :

  • avec l’ajout de deux boutons de commande pour chaque image
  • avec l’utilisation d’une page modale pour afficher le formulaire de modification

On voit que par rapport à un codage classique de Laravel, on a un code plus compact. On n’a pas eu besoin d’ajouter de route. On a une protection automatique de ces commandes par rapport aux utilisateurs non autorisés. Le tout a un rendu très esthétique. C’est vraiment une autre façon de traiter ce genre de situation qui est assez séduisante.

Pour vous simplifier la vie, vous pouvez charger le projet dans son état à l’issue de ce chapitre.

Print Friendly, PDF & Email

Laisser un commentaire