Laravel 5.7 par la pratique – Les albums 1/2
Vendredi 21 septembre 2018 12:57
On va poursuivre la création de notre galerie photos en nous intéressant dans ce chapitre aux albums. On a vu qu'on organise les photos de la galerie avec des catégories et seul un administrateur peut créer, modifier ou supprimer une catégorie.
Maintenant on va permettre à chaque utilisateur inscrit d'organiser ses photos dans des albums personnels.
On va voir dans ce chapitre comment on crée un album et forcément le code est très proche de celui utilisé pour les catégories. Mais on va devoir ajouter 2 tables à la base de données et installer quelque relations. Il faudra également compléter le menu de la barre de navigation, créer un formulaire, les routes, le contrôleur, un événement...
La base de données
Il nous faut compléter notre base de données pour intégrer les albums. Une table pour les informations des albums : nom, slug, dates. D'autre part un album sera relié à un utilisateur, il faudra donc établir une relation avec User de type One To Many. On doit aussi établir une relation entre les albums et les images : un album contient plusieurs images et une image peut être dans plusieurs albums, on aura donc une relation Many To Many.Les migrations
On va ajouter une migration pour la table albums :php artisan make:migration create_albums_table --create=albums
Changez ainsi le code :
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAlbumsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('albums', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('slug')->unique();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('albums');
}
}
On ajoute aussi une migration pour la table pivot entre les albums et les images :
php artisan make:migration create_album_image_table
Avec ce code :
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAlbumImageTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('album_image', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('album_id');
$table->unsignedInteger('image_id');
$table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade');
$table->foreign('image_id')->references('id')->on('images')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('album_image');
}
}
On peut maintenant rafraîchir la base :
php artisan migrate:fresh --seed
On se retrouve avec cette organisation :
Les modèles
Dans le modèle Image on ajoute la relation :public function albums()
{
return $this->belongsToMany (Album::class);
}
Dans le modèle User on ajoute la relation :
public function albums()
{
return $this->hasMany (Album::class);
}
On crée un modèle Album :
Avec ce code :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Events\NameSaving;
class Album extends Model
{
protected $fillable = [
'name', 'slug',
];
protected $dispatchesEvents = [
'saving' => NameSaving::class,
];
public function images()
{
return $this->belongsToMany (Image::class);
}
public function user()
{
return $this->belongsTo (User::class);
}
}
On a mis en place les deux relations. D'autre part on a prévu le déclenchement de l'événement NameSaving pour la création du slug comme on l'avait fait pour les catégories.
Le contrôleur
Pour gérer les albums on va créer un contrôleur :php artisan make:controller AlbumController --resource
Le fait d'utiliser l'option --resource a généré les 7 méthodes de base. On va toutes les conserver sauf show.
Les routes
Pour les routes on va ajouter ça :Route::middleware ('auth', 'verified')->group (function () {
Route::resource ('album', 'AlbumController', [
'except' => 'show'
]);
...
});
On vérifie :
php artisan route:list
On a bien nos 6 routes pour notre contrôleur.
Le menu
Pour accéder au formulaire de création d'un album on va devoir compléter la barre de navigation dans views/layouts/app :@auth
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle{{ currentRoute(
route('album.create'),
route('image.create')
)}}"
href="#" id="navbarDropdownGestAlbum" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
@lang('Gestion')
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownGestAlbum">
<a class="dropdown-item" href="{{ route('image.create') }}">
<i class="fas fa-images fa-lg"></i> @lang('Ajouter une image')
</a>
<a class="dropdown-item" href="{{ route('album.create') }}">
<i class="fas fa-folder-open fa-lg"></i> @lang('Ajouter un album')
</a>
</div>
</li>
@endauth
Si on a affaire à un utilisateur authentifié (@auth) on crée le menu déroulant. On l'avait créé pour les catégories, là on ajoute l'album :
La vue de création
On crée un dossier pour les albums et une vue pour la création : Pour cette vue on utilise l'intendance qu'on a précédemment mise en place :@extends('layouts.form')
@section('card')
@component('components.card')
@slot('title')
@lang('Ajouter un album')
@endslot
<form method="POST" action="{{ route('album.store') }}">
@csrf
@include('partials.form-group', [
'title' => __('Nom'),
'type' => 'text',
'name' => 'name',
'required' => true,
])
@component('components.button')
@lang('Envoyer')
@endcomponent
</form>
@endcomponent
@endsection
L'affichage du formulaire
Il nous faut maintenant coder la gestion de tout ça dans le contrôleur ImageController. Déjà il faut afficher le formulaire :public function create()
{
return view('albums.create');
}
On vérifie avec le menu que ça marche (il faut se connecter comme administrateur) :
La validation
Pour la validation on crée une requête de formulaire :php artisan make:request AlbumRequest
Et on change ainsi le code :
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class AlbumRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
$id = $this->album ? ',' . $this->album->id : '';
return $rules = [
'name' => 'required|string|max:255|unique:albums,name' . $id,
];
}
}
C'est déjà préparé pour gérer la validation de la modification. Dans ce cas on sait qu'il faut arranger un peu la règle d'unicité.
La soumission
A la soumission on arrive dans la méthode store du contrôleur. On va la coder ainsi :<?php
namespace App\Http\Controllers;
use App\Models\Album;
use App\Http\Requests\AlbumRequest;
use App\Repositories\AlbumRepository;
use Illuminate\Http\Request;
class AlbumController extends Controller
{
protected $repository;
public function __construct(AlbumRepository $repository)
{
$this->repository = $repository;
}
public function store(AlbumRequest $request)
{
$this->repository->create ($request->user(), $request->all ());
return back()->with ('ok', __ ("L'album a bien été enregistré"));
}
}
Un repository
On voit qu'on passe par un repository histoire de bien organiser le code. Créons ce repository : Avec ce code :<?php
namespace App\Repositories;
use App\Models\Album;
class AlbumRepository extends BaseRepository
{
public function __construct(Album $album)
{
$this->model = $album;
}
public function create($user, array $inputs)
{
$user->albums ()->create($inputs);
}
}
On voit qu'on étend encore le repository de base parce qu'on va avoir des méthodes communes à tous nos repositories.
Maintenant on doit pouvoir ajouter un album :
On verra dans le prochain chapitre la gestion des albums : modification et supression. On ajoutera aussi une icône sur les images pour gérer directement leur affectation aux albums.
Conclusion
Dans ce chapitre on a :- créé les migrations pour les albums
- créé un modèle pour les albums
- créé les relations entre les modèles
- créé routes, contrôleur, repository et requête de formulaire pour la création d'un album
- complété la barre de navigation
Par bestmomo
Aucun commentaire