Laravel est un framework PHP open-source utilisé pour le développement d'applications web. Il suit le modèle architectural MVC (Modèle-Vue-Contrôleur) et offre une syntaxe élégante et expressive. Ce tutoriel vous guidera pas à pas pour comprendre les bases de Laravel, installer le framework, explorer la structure MVC avec des exemples concrets, et comprendre la structure d'un projet Laravel.
Avant d'installer Laravel, assurez-vous que votre environnement satisfait les conditions suivantes :
Composer est essentiel pour gérer les dépendances de Laravel. Si vous ne l'avez pas encore installé, suivez ces étapes :
Ouvrez votre terminal et exécutez la commande suivante pour créer un nouveau projet Laravel :
composer create-project laravel/laravel nom-du-projet
Remplacez nom-du-projet
par le nom que vous souhaitez donner à votre application.
Accédez au répertoire de votre projet :
cd nom-du-projet
Démarrez le serveur local intégré de Laravel :
php artisan serve
Vous devriez voir un message indiquant que le serveur est en cours d'exécution. Par défaut, il est accessible à l'adresse suivante :
http://127.0.0.1:8000
Le modèle MVC divise une application en trois composants principaux :
Les migrations permettent de définir la structure de la base de données. Créez une migration pour une table tasks
:
Création d'une migration :
php artisan make:migration
dans Laravel).up()
et down()
.Écrire le code de la migration :
up()
, vous définissez les modifications à apporter à la base de données (par exemple, créer une table ou ajouter une colonne).down()
, vous définissez comment annuler ces modifications (par exemple, supprimer une table ou une colonne).Exécuter la commande de migration :
php artisan migrate
pour appliquer les migrations.Base de données mise à jour :
up()
.Versionnage de la structure :
migrations
) pour suivre son état.Rollback possible :
php artisan migrate:rollback
.down()
pour inverser les changements.php artisan make:migration create_tasks_table
Ouvrez le fichier généré dans le dossier database/migrations
et modifiez-le comme suit :
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->boolean('completed')->default(false);
$table->timestamps();
});
}
Exécutez la migration :
php artisan migrate
Créez un modèle Task
pour interagir avec la table tasks
:
php artisan make:model Task
Générez un contrôleur pour gérer les actions liées aux tâches :
php artisan make:controller TaskController --resource
Le flag --resource
crée un contrôleur avec des méthodes CRUD prédéfinies.
Ouvrez le fichier TaskController.php
et ajoutez la logique suivante :
use App\Models\Task;
public function index()
{
$tasks = Task::all();
return view('tasks.index', compact('tasks'));
}
public function store(Request $request)
{
$task = new Task();
$task->title = $request->input('title');
$task->save();
return redirect()->route('tasks.index');
}
Créez un fichier index.blade.php
dans le dossier resources/views/tasks
:
<!DOCTYPE html>
<html>
<head>
<title>Liste de Tâches</title>
</head>
<body>
<h1>Liste de Tâches</h1>
<ul>
@foreach ($tasks as $task)
<li>{{ $task->title }}</li>
@endforeach
</ul>
<form action="{{ route('tasks.store') }}" method="POST">
@csrf
<input type="text" name="title" placeholder="Ajouter une tâche">
<button type="submit">Ajouter</button>
</form>
</body>
</html>
Ouvrez le fichier routes/web.php
et ajoutez les routes suivantes :
use App\Http\Controllers\TaskController;
Route::get('/tasks', [TaskController::class, 'index'])->name('tasks.index');
Route::post('/tasks', [TaskController::class, 'store'])->name('tasks.store');
Voici une vue d'ensemble des principaux dossiers et fichiers dans un projet Laravel :
app
app/Models
, app/Http/Controllers
.config
database
public
index.php
(point d'entrée de l'application) et les assets (CSS, JS, images).resources
views
), les fichiers de langues (lang
) et les ressources non compilées (Sass, JavaScript).routes
web.php
, api.php
, etc.)..env
Ce tutoriel vous a introduit aux bases de Laravel, y compris son installation, la structure MVC et la création d'une application simple. Vous avez également appris à naviguer dans la structure d'un projet Laravel. À partir de là, vous pouvez approfondir vos connaissances en explorant des fonctionnalités avancées comme l'authentification, les relations Eloquent, et les API RESTful.
Si vous avez des questions ou besoin d'aide supplémentaire, n'hésitez pas à consulter la documentation officielle de Laravel.
créer un tutoriel bien detaillé sur "laravel:model et migration en incluant toutes les relations possible:belongsto,hasmany,haseone,table pivot , belongstomany,....
Voici l'exemple adapté pour le modèle Client (idClient
, nom
, prenom
, email
), en suivant la même structure.
Ce guide vous montrera comment créer une application Laravel permettant de gérer une liste de clients. Nous allons :
✅ Créer une migration pour la table clients
✅ Définir un modèle Client
✅ Mettre en place un contrôleur ClientController
✅ Créer une vue pour afficher et ajouter des clients
✅ Définir les routes correspondantes
Générez une migration pour la table clients
:
php artisan make:migration create_clients_table
Ouvrez le fichier généré dans database/migrations/ et modifiez-le comme suit :
public function up() { Schema::create('clients', function (Blueprint $table) { $table->id('idClient'); // Clé primaire personnalisée $table->string('nom'); $table->string('prenom'); $table->string('email')->unique(); $table->timestamps(); }); }
Exécutez la migration :
php artisan migrate
Créez un modèle Client
pour interagir avec la table clients
:
php artisan make:model Client
Modifiez le fichier app/Models/Client.php :
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Client extends Model { use HasFactory; protected $table = 'clients'; protected $primaryKey = 'idClient'; protected $fillable = ['nom', 'prenom', 'email']; }
Générez un contrôleur ClientController
:
php artisan make:controller ClientController --resource
Modifiez app/Http/Controllers/ClientController.php :
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Client; class ClientController extends Controller { public function index() { $clients = Client::all(); return view('clients.index', compact('clients')); } public function store(Request $request) { $request->validate([ 'nom' => 'required|string|max:255', 'prenom' => 'required|string|max:255', 'email' => 'required|email|unique:clients,email', ]); Client::create($request->all()); return redirect()->route('clients.index'); } }
Créez le fichier resources/views/clients/index.blade.php :
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Liste des Clients</title> </head> <body> <h1>Liste des Clients</h1> <ul> @foreach ($clients as $client) <li>{{ $client->nom }} {{ $client->prenom }} - {{ $client->email }}</li> @endforeach </ul> <h2>Ajouter un Client</h2> <form action="{{ route('clients.store') }}" method="POST"> @csrf <input type="text" name="nom" placeholder="Nom" required> <input type="text" name="prenom" placeholder="Prénom" required> <input type="email" name="email" placeholder="Email" required> <button type="submit">Ajouter</button> </form> </body> </html>
Ajoutez ces routes dans routes/web.php :
ClientController --resource
use App\Http\Controllers\ClientController;
Route::resource('clients', ClientController::class);
use App\Http\Controllers\ClientController; Route::get('/clients', [ClientController::class, 'index'])->name('clients.index'); Route::post('/clients', [ClientController::class, 'store'])->name('clients.store');
1️⃣ Démarrez le serveur Laravel :
php artisan serve
2️⃣ Accédez à http://127.0.0.1:8000/clients pour voir la liste des clients et ajouter un nouvel enregistrement.
Vous avez maintenant une application Laravel simple qui permet d'afficher et d'ajouter des clients dans une base de données. 🎉
Besoin d'une gestion plus avancée ? Vous pouvez ajouter des fonctionnalités comme l'édition et la suppression des clients. 🚀
Dans ce tutoriel, nous allons explorer en détail comment utiliser les modèles et les migrations dans Laravel. Nous couvrirons également toutes les relations possibles entre les modèles, y compris belongsTo
, hasMany
, hasOne
, belongsToMany
(avec une table pivot), et bien d'autres.
User
correspond à la table users
dans la base de données.Pour créer un modèle et sa migration associée, utilisez la commande suivante :
php artisan make:model NomDuModele -m
Le flag -m
génère automatiquement une migration associée au modèle.
Par exemple, pour créer un modèle Post
:
php artisan make:model Post -m
Cela générera :
Post.php
dans le dossier app/Models
.database/migrations
.Ouvrez le fichier de migration généré dans database/migrations
. Voici un exemple pour une table posts
:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id('idpost'); // Custom primary key: 'idpost' instead of default 'id'
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
Exécutez la migration pour créer la table dans la base de données :
php artisan migrate
Laravel Eloquent prend en charge plusieurs types de relations entre les modèles. Voici une explication détaillée de chaque relation avec des exemples.
belongsTo
La relation belongsTo
est utilisée lorsqu'une entité "appartient" à une autre. Par exemple, un Comment
appartient à un Post
.
Créer les Modèles et Migrations
Créez un modèle Comment
avec une migration :
php artisan make:model Comment -m
Dans la migration comments
, ajoutez une colonne post_id
pour établir la relation :
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id('idcomment'); // Custom primary key for comments
$table->unsignedBigInteger('post_id'); // Foreign key column
$table->foreign('post_id')->references('idpost')->on('posts')->onDelete('cascade'); // Correct foreign key setup
$table->text('content'); // Comment content
$table->timestamps();
});
}
Définir la Relation dans les Modèles
Dans le modèle Comment
:
class Comment extends Model
{
use HasFactory;
protected $table = 'comments'; // Explicitly define the table name
protected $primaryKey = 'idcomment'; // Define the custom primary key
protected $fillable = ['post_id', 'content']; // Define fillable fields for mass assignment
public function post()
{
return $this->belongsTo(Post::class, 'post_id', 'idpost');
}
}
Dans le modèle Post
:
class Post extends Model
{
use HasFactory;
protected $table = 'posts'; // Explicitly define the table name
protected $primaryKey = 'idpost'; // Define the custom primary key
protected $fillable = ['title', 'content']; // Define fillable fields for mass assignment
public function comments()
{
return $this->hasMany(Comment::class, 'post_id', 'idpost');
}
}
Utiliser la Relation
Récupérez tous les commentaires d'un post :
$post = Post::find(1);
$comments = $post->comments;
hasMany
La relation hasMany
est utilisée lorsqu'une entité "a plusieurs" autres entités. Par exemple, un Post
a plusieurs Comments
.
(Voir l'exemple précédent.)
hasOne
La relation hasOne
est utilisée lorsqu'une entité "a une seule" autre entité. Par exemple, un User
a un Profile
.
Créer les Modèles et Migrations
Créez un modèle Profile
avec une migration :
php artisan make:model Profile -m
Dans la migration profiles
, ajoutez une colonne user_id
:
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->id('idprofile'); // Define a custom primary key (if needed)
$table->unsignedBigInteger('user_id'); // Define the foreign key column
$table->string('bio');
$table->timestamps();
// Set up the foreign key constraint manually
$table->foreign('user_id')->references('iduser')->on('users')->onDelete('cascade');
});
}
Définir la Relation dans les Modèles
Dans le modèle User
:
class User extends Model
{
use HasFactory;
protected $table = 'users'; // Explicitly define the table name
protected $primaryKey = 'iduser'; // Define the custom primary key
protected $fillable = ['name', 'email', 'password']; // Define fillable fields for mass assignment
public function profile()
{
return $this->hasOne(Profile::class, 'user_id', 'iduser');
}
}
Dans le modèle Profile
:
class Profile extends Model
{
use HasFactory;
protected $table = 'profiles'; // Explicitly define the table name
protected $primaryKey = 'idprofile'; // Define the custom primary key
protected $fillable = ['user_id', 'bio']; // Define fillable fields for mass assignment
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'iduser');
}
}
Utiliser la Relation
Récupérez le profil d'un utilisateur :
$user = User::find(1);
$profile = $user->profile;
belongsToMany
(Table Pivot)La relation belongsToMany
est utilisée pour une relation "many-to-many". Elle nécessite une table pivot pour établir la connexion. Par exemple, un User
peut avoir plusieurs Roles
, et un Role
peut être attribué à plusieurs Users
.
Créer les Modèles et Migrations
Créez les modèles User
et Role
:
php artisan make:model Role -m
Créez une migration pour la table pivot role_user
:
php artisan make:migration create_role_user_table
Dans la migration role_user
:
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->unsignedBigInteger('user_id'); // Define the user foreign key column
$table->unsignedBigInteger('role_id'); // Define the role foreign key column
// Define foreign key constraints manually
$table->foreign('user_id')->references('iduser')->on('users')->onDelete('cascade');
$table->foreign('role_id')->references('idrole')->on('roles')->onDelete('cascade');
// Define composite primary key
$table->primary(['user_id', 'role_id']);
});
}
Définir la Relation dans les Modèles
Dans le modèle User
:
class User extends Model
{
use HasFactory;
protected $table = 'users'; // Explicitly define the table name
protected $primaryKey = 'iduser'; // Define the custom primary key
protected $fillable = ['name', 'email', 'password']; // Define fillable fields for mass assignment
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}
}
Dans le modèle Role
:
class Role extends Model
{
use HasFactory;
protected $table = 'roles'; // Explicitly define the table name
protected $primaryKey = 'idrole'; // Define the custom primary key
protected $fillable = ['name', 'description']; // Define fillable fields for mass assignment
public function users()
{
return $this->belongsToMany(User::class, 'role_user', 'role_id', 'user_id');
}
}
Utiliser la Relation
Attribuez un rôle à un utilisateur :
$user = User::find(1);
$role = Role::find(1);
$user->roles()->attach($role);
Récupérez les rôles d'un utilisateur :
$roles = $user->roles;
hasOneThrough
La relation hasOneThrough
est utilisée pour accéder à une entité via une autre entité intermédiaire. Par exemple, un Country
a un Post
via un User
.
Définir la Relation
Dans le modèle Country
:
class Country extends Model
{
use HasFactory;
protected $table = 'countries'; // Explicitly define the table name
protected $primaryKey = 'idcountry'; // Define the custom primary key
protected $fillable = ['name']; // Define fillable fields for mass assignment
public function post()
{
return $this->hasOneThrough(
Post::class, // Final target model
User::class, // Intermediate model
'country_id', // Foreign key on the users table
'user_id', // Foreign key on the posts table
'idcountry', // Local primary key in the countries table
'iduser' // Local primary key in the users table
);
}
}
Utiliser la Relation
Récupérez le post d'un pays :
$country = Country::find(1);
$post = $country->post;
hasManyThrough
La relation hasManyThrough
est similaire à hasOneThrough
, mais elle retourne plusieurs résultats. Par exemple, un Country
a plusieurs Posts
via des Users
.
Définir la Relation
Dans le modèle Country
:
class Country extends Model
{
use HasFactory;
protected $table = 'countries'; // Explicitly define the table name
protected $primaryKey = 'idcountry'; // Define the custom primary key
protected $fillable = ['name']; // Define fillable fields for mass assignment
public function posts()
{
return $this->hasManyThrough(
Post::class, // Final target model
User::class, // Intermediate model
'country_id', // Foreign key on the users table
'user_id', // Foreign key on the posts table
'idcountry', // Local primary key in the countries table
'iduser' // Local primary key in the users table
);
}
}
Utiliser la Relation
Récupérez les posts d'un pays :
$country = Country::find(1);
$posts = $country->posts;
User(idUser, name, email, email_verified_at, password, remember_token, created_at, updated_at)
Vehicle(idVehicle, make, model, year, #idUser, created_at, updated_at)
Trip(idTrip, #idVehicle, start_time, end_time, price, created_at, updated_at)
Reservation(idReservation, #idTrip, #idUser, reservation_date, created_at, updated_at)
Review(idReview, #idTrip, #idUser, comment, rating, created_at, updated_at)
php artisan make:migration create_users_table --create=users
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id('idUser');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
php artisan make:migration create_vehicles_table --create=vehicles
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateVehiclesTable extends Migration
{
public function up()
{
Schema::create('vehicles', function (Blueprint $table) {
$table->id('idVehicle');
$table->string('make');
$table->string('model');
$table->integer('year');
$table->unsignedBigInteger('idUser');
$table->foreign('idUser')->references('idUser')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('vehicles');
}
}
php artisan make:migration create_trips_table --create=trips
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTripsTable extends Migration
{
public function up()
{
Schema::create('trips', function (Blueprint $table) {
$table->id('idTrip');
$table->unsignedBigInteger('idVehicle');
$table->foreign('idVehicle')->references('idVehicle')->on('vehicles')->onDelete('cascade');
$table->dateTime('start_time');
$table->dateTime('end_time');
$table->decimal('price', 8, 2);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('trips');
}
}
php artisan make:migration create_reservations_table --create=reservations
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateReservationsTable extends Migration
{
public function up()
{
Schema::create('reservations', function (Blueprint $table) {
$table->id('idReservation');
$table->unsignedBigInteger('idTrip');
$table->foreign('idTrip')->references('idTrip')->on('trips')->onDelete('cascade');
$table->unsignedBigInteger('idUser');
$table->foreign('idUser')->references('idUser')->on('users')->onDelete('cascade');
$table->dateTime('reservation_date');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('reservations');
}
}
php artisan make:migration create_reviews_table --create=reviews
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateReviewsTable extends Migration
{
public function up()
{
Schema::create('reviews', function (Blueprint $table) {
$table->id('idReview');
$table->unsignedBigInteger('idTrip');
$table->foreign('idTrip')->references('idTrip')->on('trips')->onDelete('cascade');
$table->unsignedBigInteger('idUser');
$table->foreign('idUser')->references('idUser')->on('users')->onDelete('cascade');
$table->text('comment');
$table->integer('rating');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('reviews');
}
}
php artisan migrate
php artisan make:model User
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
protected $table = 'users';
protected $primaryKey = 'idUser';
protected $fillable = ['name', 'email', 'email_verified_at', 'password', 'remember_token'];
public function vehicles()
{
return $this->hasMany(Vehicle::class, 'idUser');
}
public function reservations()
{
return $this->hasMany(Reservation::class, 'idUser');
}
public function reviews()
{
return $this->hasMany(Review::class, 'idUser');
}
}
php artisan make:model Vehicle
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Vehicle extends Model
{
use HasFactory;
protected $table = 'vehicles';
protected $primaryKey = 'idVehicle';
protected $fillable = ['make', 'model', 'year', 'idUser'];
public function user()
{
return $this->belongsTo(User::class, 'idUser');
}
public function trips()
{
return $this->hasMany(Trip::class, 'idVehicle');
}
}
php artisan make:model Trip
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Trip extends Model
{
use HasFactory;
protected $table = 'trips';
protected $primaryKey = 'idTrip';
protected $fillable = ['idVehicle', 'start_time', 'end_time', 'price'];
public function vehicle()
{
return $this->belongsTo(Vehicle::class, 'idVehicle');
}
public function reservations()
{
return $this->hasMany(Reservation::class, 'idTrip');
}
public function reviews()
{
return $this->hasMany(Review::class, 'idTrip');
}
}
php artisan make:model Reservation
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Reservation extends Model
{
use HasFactory;
protected $table = 'reservations';
protected $primaryKey = 'idReservation';
protected $fillable = ['idTrip', 'idUser', 'reservation_date'];
public function trip()
{
return $this->belongsTo(Trip::class, 'idTrip');
}
public function user()
{
return $this->belongsTo(User::class, 'idUser');
}
}
php artisan make:model Review
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Review extends Model
{
use HasFactory;
protected $table = 'reviews';
protected $primaryKey = 'idReview';
protected $fillable = ['idTrip', 'idUser', 'comment', 'rating'];
public function trip()
{
return $this->belongsTo(Trip::class, 'idTrip');
}
public function user()
{
return $this->belongsTo(User::class, 'idUser');
}
}
Créer les migrations et les modèles
User(idUser, name, email, email_verified_at, password, remember_token, created_at, updated_at)
Team(idTeam, name, coach, stadium, created_at, updated_at)
Player(idPlayer, name, position, date_of_birth, #idTeam, created_at, updated_at)
Match(idMatch, #idHomeTeam, #idAwayTeam, match_date, location, created_at, updated_at)
Goal(idGoal, #idMatch, #idPlayer, minute, created_at, updated_at)
Comment(idComment, #idMatch, #idUser, content, created_at, updated_at)
User -> Comment (One-to-Many)
idUser
est présente dans la table Comment
.Team -> Player (One-to-Many)
idTeam
est présente dans la table Player
.Team -> Match (One-to-Many)
idHomeTeam
et idAwayTeam
sont présentes dans la table Match
.Match -> Goal (One-to-Many)
idMatch
est présente dans la table Goal
.Player -> Goal (One-to-Many)
idPlayer
est présente dans la table Goal
.Match -> Comment (One-to-Many)
idMatch
est présente dans la table Comment
.Créer les migrations et les modèles
User(idUser, name, email, email_verified_at, password, remember_token, created_at, updated_at)
Team(idTeam, name, coach, #idStadium, created_at, updated_at)
Player(idPlayer, name, position, date_of_birth, #idTeam, created_at, updated_at)
Match(idMatch, #idHomeTeam, #idAwayTeam, match_date, #idLeague, location, created_at, updated_at)
Goal(idGoal, #idMatch, #idPlayer, minute, created_at, updated_at)
Comment(idComment, #idMatch, #idUser, content, created_at, updated_at)
Stadium(idStadium, name, capacity, location, created_at, updated_at)
League(idLeague, name, country, created_at, updated_at)
PlayerMatch(idPlayerMatch, #idPlayer, #idMatch, minutes_played, created_at, updated_at)
User -> Comment (One-to-Many)
idUser
est présente dans la table Comment
.Team -> Player (One-to-Many)
idTeam
est présente dans la table Player
.Stadium -> Team (One-to-Many)
idStadium
est présente dans la table Team
.League -> Match (One-to-Many)
idLeague
est présente dans la table Match
.Match -> Goal (One-to-Many)
idMatch
est présente dans la table Goal
.Player -> Goal (One-to-Many)
idPlayer
est présente dans la table Goal
.Match -> Comment (One-to-Many)
idMatch
est présente dans la table Comment
.Team -> Match (Many-to-One)
idHomeTeam
et idAwayTeam
sont présentes dans la table Match
.Player <-> Match (Many-to-Many) via PlayerMatch
PlayerMatch
relie Player
et Match
avec des attributs supplémentaires comme minutes_played
.php artisan make:migration create_users_table --create=users
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id('idUser');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
php artisan make:migration create_stadiums_table --create=stadiums
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStadiumsTable extends Migration
{
public function up()
{
Schema::create('stadiums', function (Blueprint $table) {
$table->id('idStadium');
$table->string('name');
$table->integer('capacity');
$table->string('location');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('stadiums');
}
}
php artisan make:migration create_leagues_table --create=leagues
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateLeaguesTable extends Migration
{
public function up()
{
Schema::create('leagues', function (Blueprint $table) {
$table->id('idLeague');
$table->string('name');
$table->string('country');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('leagues');
}
}
php artisan make:migration create_teams_table --create=teams
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTeamsTable extends Migration
{
public function up()
{
Schema::create('teams', function (Blueprint $table) {
$table->id('idTeam');
$table->string('name');
$table->string('coach');
$table->unsignedBigInteger('idStadium');
$table->foreign('idStadium')->references('idStadium')->on('stadiums')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('teams');
}
}
php artisan make:migration create_players_table --create=players
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePlayersTable extends Migration
{
public function up()
{
Schema::create('players', function (Blueprint $table) {
$table->id('idPlayer');
$table->string('name');
$table->string('position');
$table->date('date_of_birth');
$table->unsignedBigInteger('idTeam');
$table->foreign('idTeam')->references('idTeam')->on('teams')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('players');
}
}
php artisan make:migration create_matches_table --create=matches
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMatchesTable extends Migration
{
public function up()
{
Schema::create('matches', function (Blueprint $table) {
$table->id('idMatch');
$table->unsignedBigInteger('idHomeTeam');
$table->unsignedBigInteger('idAwayTeam');
$table->unsignedBigInteger('idLeague');
$table->dateTime('match_date');
$table->string('location');
$table->foreign('idHomeTeam')->references('idTeam')->on('teams')->onDelete('cascade');
$table->foreign('idAwayTeam')->references('idTeam')->on('teams')->onDelete('cascade');
$table->foreign('idLeague')->references('idLeague')->on('leagues')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('matches');
}
}
php artisan make:migration create_goals_table --create=goals
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGoalsTable extends Migration
{
public function up()
{
Schema::create('goals', function (Blueprint $table) {
$table->id('idGoal');
$table->unsignedBigInteger('idMatch');
$table->unsignedBigInteger('idPlayer');
$table->integer('minute');
$table->foreign('idMatch')->references('idMatch')->on('matches')->onDelete('cascade');
$table->foreign('idPlayer')->references('idPlayer')->on('players')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('goals');
}
}
php artisan make:migration create_comments_table --create=comments
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCommentsTable extends Migration
{
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id('idComment');
$table->unsignedBigInteger('idMatch');
$table->unsignedBigInteger('idUser');
$table->text('content');
$table->foreign('idMatch')->references('idMatch')->on('matches')->onDelete('cascade');
$table->foreign('idUser')->references('idUser')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('comments');
}
}
php artisan make:migration create_player_match_table --create=player_match
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePlayerMatchTable extends Migration
{
public function up()
{
Schema::create('player_match', function (Blueprint $table) {
$table->id('idPlayerMatch');
$table->unsignedBigInteger('idPlayer');
$table->unsignedBigInteger('idMatch');
$table->integer('minutes_played');
$table->foreign('idPlayer')->references('idPlayer')->on('players')->onDelete('cascade');
$table->foreign('idMatch')->references('idMatch')->on('matches')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('player_match');
}
}
php artisan migrate
php artisan make:model User
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
protected $table = 'users';
protected $primaryKey = 'idUser';
protected $fillable = ['name', 'email', 'email_verified_at', 'password', 'remember_token'];
public function comments()
{
return $this->hasMany(Comment::class, 'idUser');
}
}
php artisan make:model Stadium
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Stadium extends Model
{
use HasFactory;
protected $table = 'stadiums';
protected $primaryKey = 'idStadium';
protected $fillable = ['name', 'capacity', 'location'];
public function teams()
{
return $this->hasMany(Team::class, 'idStadium');
}
}
php artisan make:model League
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class League extends Model
{
use HasFactory;
protected $table = 'leagues';
protected $primaryKey = 'idLeague';
protected $fillable = ['name', 'country'];
public function matches()
{
return $this->hasMany(Match::class, 'idLeague');
}
}
php artisan make:model Team
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
use HasFactory;
protected $table = 'teams';
protected $primaryKey = 'idTeam';
protected $fillable = ['name', 'coach', 'idStadium'];
public function stadium()
{
return $this->belongsTo(Stadium::class, 'idStadium');
}
public function players()
{
return $this->hasMany(Player::class, 'idTeam');
}
public function homeMatches()
{
return $this->hasMany(Match::class, 'idHomeTeam');
}
public function awayMatches()
{
return $this->hasMany(Match::class, 'idAwayTeam');
}
}
php artisan make:model Player
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Player extends Model
{
use HasFactory;
protected $table = 'players';
protected $primaryKey = 'idPlayer';
protected $fillable = ['name', 'position', 'date_of_birth', 'idTeam'];
public function team()
{
return $this->belongsTo(Team::class, 'idTeam');
}
public function goals()
{
return $this->hasMany(Goal::class, 'idPlayer');
}
public function matches()
{
return $this->belongsToMany(Match::class, 'player_match', 'idPlayer', 'idMatch')->withPivot('minutes_played');
}
}
php artisan make:model Match
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Match extends Model
{
use HasFactory;
protected $table = 'matches';
protected $primaryKey = 'idMatch';
protected $fillable = ['idHomeTeam', 'idAwayTeam', 'idLeague', 'match_date', 'location'];
public function league()
{
return $this->belongsTo(League::class, 'idLeague');
}
public function homeTeam()
{
return $this->belongsTo(Team::class, 'idHomeTeam');
}
public function awayTeam()
{
return $this->belongsTo(Team::class, 'idAwayTeam');
}
public function goals()
{
return $this->hasMany(Goal::class, 'idMatch');
}
public function comments()
{
return $this->hasMany(Comment::class, 'idMatch');
}
public function players()
{
return $this->belongsToMany(Player::class, 'player_match', 'idMatch', 'idPlayer')->withPivot('minutes_played');
}
}
php artisan make:model Goal
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Goal extends Model
{
use HasFactory;
protected $table = 'goals';
protected $primaryKey = 'idGoal';
protected $fillable = ['idMatch', 'idPlayer', 'minute'];
public function match()
{
return $this->belongsTo(Match::class, 'idMatch');
}
public function player()
{
return $this->belongsTo(Player::class, 'idPlayer');
}
}
php artisan make:model Comment
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
use HasFactory;
protected $table = 'comments';
protected $primaryKey = 'idComment';
protected $fillable = ['idMatch', 'idUser', 'content'];
public function match()
{
return $this->belongsTo(Match::class, 'idMatch');
}
public function user()
{
return $this->belongsTo(User::class, 'idUser');
}
}
client
Dans ce tutoriel, nous allons créer une application complète pour gérer les opérations CRUD (Create, Read, Update, Delete) sur une table client
en utilisant un contrôleur de ressource dans Laravel. Nous couvrirons le modèle, la migration, le contrôleur, les routes (web.php
) et les vues.
Exécutez la commande suivante pour générer un modèle Client
et sa migration associée :
php artisan make:model Client -m
Cela générera :
Client.php
dans le dossier app/Models
.database/migrations
.Ouvrez le fichier de migration généré dans database/migrations
et définissez la structure de la table clients
:
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->id('idclient'); // Clé primaire auto-incrémentée avec un nom personnalisé
$table->string('nom'); // Colonne pour le nom du client
$table->string('prenom'); // Colonne pour le prénom du client
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Exécutez la migration pour créer la table dans la base de données :
php artisan migrate
Un contrôleur de ressource contient des méthodes prédéfinies pour les opérations CRUD. Créez un contrôleur ClientController
:
php artisan make:controller ClientController --resource
Cela générera un fichier ClientController.php
dans le dossier app/Http/Controllers
. Le flag --resource
crée automatiquement les méthodes suivantes :
index()
: Liste tous les clients.create()
: Affiche le formulaire de création.store()
: Enregistre un nouveau client.show()
: Affiche un client spécifique.edit()
: Affiche le formulaire d'édition.update()
: Met à jour un client existant.destroy()
: Supprime un client.Ouvrez le fichier ClientController.php
et ajoutez le code suivant :
namespace App\Http\Controllers;
use App\Models\Client;
use Illuminate\Http\Request;
class ClientController extends Controller
{
// Liste tous les clients
public function index()
{
$clients = Client::all();
return view('clients.index', compact('clients'));
}
// Affiche le formulaire de création
public function create()
{
return view('clients.create');
}
// Enregistre un nouveau client
public function store(Request $request)
{
$request->validate([
'nom' => 'required|string|max:255',
'prenom' => 'required|string|max:255',
]);
Client::create($request->all());
return redirect()->route('clients.index')->with('success', 'Client créé avec succès.');
}
// Affiche un client spécifique
public function show(Client $client)
{
return view('clients.show', compact('client'));
}
// Affiche le formulaire d'édition
public function edit(Client $client)
{
return view('clients.edit', compact('client'));
}
// Met à jour un client existant
public function update(Request $request, Client $client)
{
$request->validate([
'nom' => 'required|string|max:255',
'prenom' => 'required|string|max:255',
]);
$client->update($request->all());
return redirect()->route('clients.index')->with('success', 'Client mis à jour avec succès.');
}
// Supprime un client
public function destroy(Client $client)
{
$client->delete();
return redirect()->route('clients.index')->with('success', 'Client supprimé avec succès.');
}
}
web.php
Ouvrez le fichier routes/web.php
et ajoutez les routes pour le contrôleur de ressource :
use App\Http\Controllers\ClientController;
Route::resource('clients', ClientController::class);
Cela créera automatiquement les routes suivantes :
GET /clients
→ index()
GET /clients/create
→ create()
POST /clients
→ store()
GET /clients/{client}
→ show()
GET /clients/{client}/edit
→ edit()
PUT/PATCH /clients/{client}
→ update()
DELETE /clients/{client}
→ destroy()
Créez un dossier clients
dans resources/views
pour organiser les vues.
index.blade.php
Cette vue affiche la liste des clients et inclut des liens pour créer, éditer ou supprimer un client.
<!-- resources/views/clients/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Clients</title>
</head>
<body>
<h1>Liste des Clients</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
<a href="{{ route('clients.create') }}">Ajouter un Client</a>
<ul>
@foreach ($clients as $client)
<li>
{{ $client->nom }} {{ $client->prenom }}
<a href="{{ route('clients.edit', $client->idclient) }}">Éditer</a>
<form action="{{ route('clients.destroy', $client->idclient) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
</body>
</html>
create.blade.php
Cette vue affiche un formulaire pour créer un nouveau client.
<!-- resources/views/clients/create.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Créer un Client</title>
</head>
<body>
<h1>Créer un Client</h1>
<form action="{{ route('clients.store') }}" method="POST">
@csrf
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" required><br>
<label for="prenom">Prénom :</label>
<input type="text" name="prenom" id="prenom" required><br>
<button type="submit">Enregistrer</button>
</form>
<a href="{{ route('clients.index') }}">Retour à la liste</a>
</body>
</html>
edit.blade.php
Cette vue affiche un formulaire pour éditer un client existant.
<!-- resources/views/clients/edit.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Éditer un Client</title>
</head>
<body>
<h1>Éditer un Client</h1>
<form action="{{ route('clients.update', $client->idclient) }}" method="POST">
@csrf
@method('PUT')
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" value="{{ $client->nom }}" required><br>
<label for="prenom">Prénom :</label>
<input type="text" name="prenom" id="prenom" value="{{ $client->prenom }}" required><br>
<button type="submit">Mettre à jour</button>
</form>
<a href="{{ route('clients.index') }}">Retour à la liste</a>
</body>
</html>
show.blade.php
Cette vue affiche les détails d'un client spécifique.
<!-- resources/views/clients/show.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Détails du Client</title>
</head>
<body>
<h1>Détails du Client</h1>
<p>Nom : {{ $client->nom }}</p>
<p>Prénom : {{ $client->prenom }}</p>
<a href="{{ route('clients.index') }}">Retour à la liste</a>
</body>
</html>
Vous avez maintenant une application complète pour gérer les opérations CRUD sur la table client
en utilisant un contrôleur de ressource dans Laravel. Voici un résumé des étapes que nous avons suivies :
web.php
.Pour tester l'application, démarrez le serveur local :
php artisan serve
Accédez à l'application via http://127.0.0.1:8000/clients.
Avec ces bases, vous pouvez maintenant personnaliser et étendre cette application pour répondre à vos besoins spécifiques. Bon développement !
client
Dans ce tutoriel, nous allons créer une application complète pour gérer les opérations CRUD (Create, Read, Update, Delete) sur une table client
en utilisant des fonctions personnalisées dans un contrôleur standard. Nous ne utiliserons pas un contrôleur de ressource (--resource
), mais plutôt des méthodes spécifiques comme ajouter
, afficher
, modifier
, et supprimer
.
Exécutez la commande suivante pour générer un modèle Client
et sa migration associée :
php artisan make:model Client -m
Cela générera :
Client.php
dans le dossier app/Models
.database/migrations
.Ouvrez le fichier de migration généré dans database/migrations
et définissez la structure de la table clients
:
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->id('idclient'); // Clé primaire auto-incrémentée avec un nom personnalisé
$table->string('nom'); // Colonne pour le nom du client
$table->string('prenom'); // Colonne pour le prénom du client
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Exécutez la migration pour créer la table dans la base de données :
php artisan migrate
Créez un contrôleur ClientController
sans utiliser le flag --resource
:
php artisan make:controller ClientController
Cela générera un fichier ClientController.php
dans le dossier app/Http/Controllers
. Vous devrez implémenter manuellement les méthodes pour les opérations CRUD.
Ouvrez le fichier ClientController.php
et ajoutez les méthodes suivantes :
namespace App\Http\Controllers;
use App\Models\Client;
use Illuminate\Http\Request;
class ClientController extends Controller
{
// Liste tous les clients
public function afficher()
{
$clients = Client::all();
return view('clients.afficher', compact('clients'));
}
// Affiche le formulaire d'ajout
public function creer()
{
return view('clients.creer');
}
// Enregistre un nouveau client
public function ajouter(Request $request)
{
$request->validate([
'nom' => 'required|string|max:255',
'prenom' => 'required|string|max:255',
]);
Client::create($request->all());
return redirect()->route('clients.afficher')->with('success', 'Client créé avec succès.');
}
// Affiche un client spécifique
public function voir($id)
{
$client = Client::findOrFail($id);
return view('clients.voir', compact('client'));
}
// Affiche le formulaire d'édition
public function editer($id)
{
$client = Client::findOrFail($id);
return view('clients.editer', compact('client'));
}
// Met à jour un client existant
public function modifier(Request $request, $id)
{
$request->validate([
'nom' => 'required|string|max:255',
'prenom' => 'required|string|max:255',
]);
$client = Client::findOrFail($id);
$client->update($request->all());
return redirect()->route('clients.afficher')->with('success', 'Client mis à jour avec succès.');
}
// Supprime un client
public function supprimer($id)
{
$client = Client::findOrFail($id);
$client->delete();
return redirect()->route('clients.afficher')->with('success', 'Client supprimé avec succès.');
}
}
web.php
Ouvrez le fichier routes/web.php
et ajoutez les routes pour chaque méthode du contrôleur :
use App\Http\Controllers\ClientController;
Route::get('/clients', [ClientController::class, 'afficher'])->name('clients.afficher');
Route::get('/clients/creer', [ClientController::class, 'creer'])->name('clients.creer');
Route::post('/clients/ajouter', [ClientController::class, 'ajouter'])->name('clients.ajouter');
Route::get('/clients/{id}', [ClientController::class, 'voir'])->name('clients.voir');
Route::get('/clients/{id}/editer', [ClientController::class, 'editer'])->name('clients.editer');
Route::put('/clients/{id}/modifier', [ClientController::class, 'modifier'])->name('clients.modifier');
Route::delete('/clients/{id}/supprimer', [ClientController::class, 'supprimer'])->name('clients.supprimer');
Créez un dossier clients
dans resources/views
pour organiser les vues.
afficher.blade.php
Cette vue affiche la liste des clients et inclut des liens pour créer, éditer ou supprimer un client.
<!-- resources/views/clients/afficher.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Clients</title>
</head>
<body>
<h1>Liste des Clients</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
<a href="{{ route('clients.creer') }}">Ajouter un Client</a>
<ul>
@foreach ($clients as $client)
<li>
{{ $client->nom }} {{ $client->prenom }}
<a href="{{ route('clients.voir', $client->idclient) }}">Voir</a>
<a href="{{ route('clients.editer', $client->idclient) }}">Éditer</a>
<form action="{{ route('clients.supprimer', $client->idclient) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
</body>
</html>
creer.blade.php
Cette vue affiche un formulaire pour créer un nouveau client.
<!-- resources/views/clients/creer.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Créer un Client</title>
</head>
<body>
<h1>Créer un Client</h1>
<form action="{{ route('clients.ajouter') }}" method="POST">
@csrf
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" required><br>
<label for="prenom">Prénom :</label>
<input type="text" name="prenom" id="prenom" required><br>
<button type="submit">Enregistrer</button>
</form>
<a href="{{ route('clients.afficher') }}">Retour à la liste</a>
</body>
</html>
editer.blade.php
Cette vue affiche un formulaire pour éditer un client existant.
<!-- resources/views/clients/editer.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Éditer un Client</title>
</head>
<body>
<h1>Éditer un Client</h1>
<form action="{{ route('clients.modifier', $client->idclient) }}" method="POST">
@csrf
@method('PUT')
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" value="{{ $client->nom }}" required><br>
<label for="prenom">Prénom :</label>
<input type="text" name="prenom" id="prenom" value="{{ $client->prenom }}" required><br>
<button type="submit">Mettre à jour</button>
</form>
<a href="{{ route('clients.afficher') }}">Retour à la liste</a>
</body>
</html>
voir.blade.php
Cette vue affiche les détails d'un client spécifique.
<!-- resources/views/clients/voir.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Détails du Client</title>
</head>
<body>
<h1>Détails du Client</h1>
<p>Nom : {{ $client->nom }}</p>
<p>Prénom : {{ $client->prenom }}</p>
<a href="{{ route('clients.afficher') }}">Retour à la liste</a>
</body>
</html>
Vous avez maintenant une application complète pour gérer les opérations CRUD sur la table client
en utilisant des fonctions personnalisées dans un contrôleur standard. Voici un résumé des étapes que nous avons suivies :
afficher
, creer
, ajouter
, voir
, editer
, modifier
, supprimer
).web.php
.Pour tester l'application, démarrez le serveur local :
php artisan serve
Accédez à l'application via http://127.0.0.1:8000/clients.
Avec ces bases, vous pouvez maintenant personnaliser et étendre cette application pour répondre à vos besoins spécifiques. Bon développement !
Categorie
et Produit
Dans ce tutoriel, nous allons créer une application complète pour gérer les opérations CRUD (Create, Read, Update, Delete) pour deux modèles : Categorie
et Produit
. Nous inclurons également la relation entre ces deux modèles (Produit
appartient à une Categorie
). Voici le code complet pour les migrations, modèles, relations, contrôleurs et vues.
Categorie
Exécutez la commande suivante pour générer une migration pour la table categories
:
php artisan make:migration create_categories_table
Ouvrez le fichier de migration généré dans database/migrations
et définissez la structure de la table categories
:
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id('idcategorie'); // Clé primaire auto-incrémentée avec un nom personnalisé
$table->string('nom'); // Nom de la catégorie
$table->text('description')->nullable(); // Description de la catégorie (peut être null)
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Produit
Exécutez la commande suivante pour générer une migration pour la table produits
:
php artisan make:migration create_produits_table
Ouvrez le fichier de migration généré dans database/migrations
et définissez la structure de la table produits
:
public function up()
{
Schema::create('produits', function (Blueprint $table) {
$table->id('idproduit'); // Clé primaire auto-incrémentée avec un nom personnalisé
$table->string('nom'); // Nom du produit
$table->decimal('prix', 8, 2); // Prix du produit avec 8 chiffres au total et 2 décimales
$table->foreignId('categorie_id')
->constrained('categories') // Spécifie explicitement la table référencée
->onDelete('cascade'); // Suppression en cascade si la catégorie est supprimée
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Exécutez les migrations pour créer les tables dans la base de données :
php artisan migrate
Categorie
Créez un modèle Categorie
:
php artisan make:model Categorie
Ajoutez la relation hasMany
dans le modèle Categorie
:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
use HasFactory;
protected $table = 'categories'; // Nom explicite de la table
protected $primaryKey = 'idcategorie'; // Clé primaire personnalisée
protected $fillable = ['nom', 'description']; // Champs modifiables en masse
// Une catégorie a plusieurs produits
public function produits()
{
return $this->hasMany(Produit::class, 'categorie_id', 'idcategorie');
}
}
Produit
Créez un modèle Produit
:
php artisan make:model Produit
Ajoutez la relation belongsTo
dans le modèle Produit
:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produit extends Model
{
use HasFactory;
protected $table = 'produits'; // Nom explicite de la table
protected $primaryKey = 'idproduit'; // Clé primaire personnalisée
protected $fillable = ['nom', 'prix', 'categorie_id']; // Champs modifiables en masse
// Un produit appartient à une catégorie
public function categorie()
{
return $this->belongsTo(Categorie::class, 'categorie_id', 'idcategorie');
}
}
CategorieController
Créez un contrôleur CategorieController
:
php artisan make:controller CategorieController
Implémentez les méthodes CRUD dans le contrôleur :
namespace App\Http\Controllers;
use App\Models\Categorie;
use Illuminate\Http\Request;
class CategorieController extends Controller
{
// Liste toutes les catégories
public function index()
{
$categories = Categorie::all();
return view('categories.index', compact('categories'));
}
// Affiche le formulaire de création
public function create()
{
return view('categories.create');
}
// Enregistre une nouvelle catégorie
public function store(Request $request)
{
$request->validate([
'nom' => 'required|string|max:255',
'description' => 'nullable|string',
]);
Categorie::create($request->all());
return redirect()->route('categories.index')->with('success', 'Catégorie créée avec succès.');
}
// Affiche une catégorie spécifique
public function show(Categorie $categorie)
{
return view('categories.show', compact('categorie'));
}
// Affiche le formulaire d'édition
public function edit(Categorie $categorie)
{
return view('categories.edit', compact('categorie'));
}
// Met à jour une catégorie existante
public function update(Request $request, Categorie $categorie)
{
$request->validate([
'nom' => 'required|string|max:255',
'description' => 'nullable|string',
]);
$categorie->update($request->all());
return redirect()->route('categories.index')->with('success', 'Catégorie mise à jour avec succès.');
}
// Supprime une catégorie
public function destroy(Categorie $categorie)
{
$categorie->delete();
return redirect()->route('categories.index')->with('success', 'Catégorie supprimée avec succès.');
}
}
ProduitController
Créez un contrôleur ProduitController
:
php artisan make:controller ProduitController
Implémentez les méthodes CRUD dans le contrôleur :
namespace App\Http\Controllers;
use App\Models\Produit;
use App\Models\Categorie;
use Illuminate\Http\Request;
class ProduitController extends Controller
{
// Liste tous les produits
public function index()
{
$produits = Produit::with('categorie')->get();
return view('produits.index', compact('produits'));
}
// Affiche le formulaire de création
public function create()
{
$categories = Categorie::all();
return view('produits.create', compact('categories'));
}
// Enregistre un nouveau produit
public function store(Request $request)
{
$request->validate([
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'categorie_id' => 'required|exists:categories,id',
]);
Produit::create($request->all());
return redirect()->route('produits.index')->with('success', 'Produit créé avec succès.');
}
// Affiche un produit spécifique
public function show(Produit $produit)
{
return view('produits.show', compact('produit'));
}
// Affiche le formulaire d'édition
public function edit(Produit $produit)
{
$categories = Categorie::all();
return view('produits.edit', compact('produit', 'categories'));
}
// Met à jour un produit existant
public function update(Request $request, Produit $produit)
{
$request->validate([
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'categorie_id' => 'required|exists:categories,id',
]);
$produit->update($request->all());
return redirect()->route('produits.index')->with('success', 'Produit mis à jour avec succès.');
}
// Supprime un produit
public function destroy(Produit $produit)
{
$produit->delete();
return redirect()->route('produits.index')->with('success', 'Produit supprimé avec succès.');
}
}
Ajoutez les routes dans routes/web.php
:
use App\Http\Controllers\CategorieController;
use App\Http\Controllers\ProduitController;
// Routes pour Catégorie
Route::get('/categories', [CategorieController::class, 'index'])->name('categories.index');
Route::get('/categories/create', [CategorieController::class, 'create'])->name('categories.create');
Route::post('/categories', [CategorieController::class, 'store'])->name('categories.store');
Route::get('/categories/{categorie}', [CategorieController::class, 'show'])->name('categories.show');
Route::get('/categories/{categorie}/edit', [CategorieController::class, 'edit'])->name('categories.edit');
Route::put('/categories/{categorie}', [CategorieController::class, 'update'])->name('categories.update');
Route::delete('/categories/{categorie}', [CategorieController::class, 'destroy'])->name('categories.destroy');
// Routes pour Produit
Route::get('/produits', [ProduitController::class, 'index'])->name('produits.index');
Route::get('/produits/create', [ProduitController::class, 'create'])->name('produits.create');
Route::post('/produits', [ProduitController::class, 'store'])->name('produits.store');
Route::get('/produits/{produit}', [ProduitController::class, 'show'])->name('produits.show');
Route::get('/produits/{produit}/edit', [ProduitController::class, 'edit'])->name('produits.edit');
Route::put('/produits/{produit}', [ProduitController::class, 'update'])->name('produits.update');
Route::delete('/produits/{produit}', [ProduitController::class, 'destroy'])->name('produits.destroy');
categories/index.blade.php
<!-- resources/views/categories/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Catégories</title>
</head>
<body>
<h1>Liste des Catégories</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
<a href="{{ route('categories.create') }}">Ajouter une Catégorie</a>
<ul>
@foreach ($categories as $categorie)
<li>
{{ $categorie->nom }} - {{ $categorie->description }}
<a href="{{ route('categories.edit', $categorie->idcategorie) }}">Éditer</a>
<form action="{{ route('categories.destroy', $categorie->idcategorie) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
</body>
</html>
produits/index.blade.php
<!-- resources/views/produits/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Produits</title>
</head>
<body>
<h1>Liste des Produits</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
<a href="{{ route('produits.create') }}">Ajouter un Produit</a>
<ul>
@foreach ($produits as $produit)
<li>
{{ $produit->nom }} - {{ $produit->prix }} € ({{ $produit->categorie->nom }})
<a href="{{ route('produits.edit', $produit->idproduit) }}">Éditer</a>
<form action="{{ route('produits.destroy', $produit->idproduit) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
</body>
</html>
Les autres vues (create
, edit
, show
) peuvent être créées en suivant le même principe que les exemples précédents.
Vous avez maintenant une application complète pour gérer les opérations CRUD pour les modèles Categorie
et Produit
, avec une relation belongsTo
et hasMany
. Vous pouvez tester l'application en démarrant le serveur local :
php artisan serve
Accédez aux routes via :
Bon développement !
Dans ce tutoriel, nous allons ajouter des fonctionnalités avancées à notre application existante pour les modèles Categorie
et Produit
. Nous inclurons des fonctions pour rechercher un produit par nom, filtrer les produits par catégorie, et effectuer des calculs (par exemple, calculer le prix total des produits). Ces fonctionnalités seront ajoutées dans les contrôleurs, vues et routes.
rechercherProduitParNom
Cette fonction permettra de rechercher des produits en fonction de leur nom.
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function rechercher(Request $request)
{
$query = $request->input('query'); // Récupérer le terme de recherche depuis la requête
// Rechercher les produits dont le nom contient le terme de recherche
$produits = Produit::where('nom', 'like', '%' . $query . '%')->get();
return view('produits.index', compact('produits'));
}
filterProduitParCategory
Cette fonction permettra de filtrer les produits par catégorie.
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function filterParCategorie($id)
{
// Récupérer la catégorie spécifique
$categorie = Categorie::findOrFail($id);
// Filtrer les produits appartenant à cette catégorie
$produits = $categorie->produits;
return view('produits.index', compact('produits', 'categorie'));
}
Cette fonction calculera le prix total de tous les produits ou d'une catégorie spécifique.
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function calculerPrixTotal()
{
// Calculer le prix total de tous les produits
$prixTotal = Produit::sum('prix');
return view('produits.prix_total', compact('prixTotal'));
}
public function calculerPrixTotalParCategorie($id)
{
// Récupérer la catégorie spécifique
$categorie = Categorie::findOrFail($id);
// Calculer le prix total des produits de cette catégorie
$prixTotal = $categorie->produits()->sum('prix');
return view('produits.prix_total', compact('prixTotal', 'categorie'));
}
Ajoutez les nouvelles routes dans routes/web.php
pour accéder aux fonctionnalités de recherche, filtrage et calcul :
// Route pour rechercher des produits par nom
Route::get('/produits/rechercher', [ProduitController::class, 'rechercher'])->name('produits.rechercher');
// Route pour filtrer les produits par catégorie
Route::get('/produits/filter/{id}', [ProduitController::class, 'filterParCategorie'])->name('produits.filter');
// Route pour calculer le prix total de tous les produits
Route::get('/produits/prix-total', [ProduitController::class, 'calculerPrixTotal'])->name('produits.prix_total');
// Route pour calculer le prix total des produits d'une catégorie spécifique
Route::get('/produits/prix-total/{id}', [ProduitController::class, 'calculerPrixTotalParCategorie'])->name('produits.prix_total_par_categorie');
produits/index.blade.php
Ajoutez un formulaire de recherche et des liens pour filtrer les produits par catégorie :
<!-- resources/views/produits/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Produits</title>
</head>
<body>
<h1>Liste des Produits</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
<!-- Formulaire de Recherche -->
<form action="{{ route('produits.rechercher') }}" method="GET">
<input type="text" name="query" placeholder="Rechercher un produit...">
<button type="submit">Rechercher</button>
</form>
<!-- Lien pour Afficher Tous les Produits -->
<a href="{{ route('produits.index') }}">Afficher Tous les Produits</a>
<!-- Filtrer par Catégorie -->
<h2>Filtrer par Catégorie</h2>
<ul>
@foreach ($categories as $categorie)
<li>
<a href="{{ route('produits.filter', $categorie->id) }}">{{ $categorie->nom }}</a>
</li>
@endforeach
</ul>
<!-- Liste des Produits -->
<ul>
@foreach ($produits as $produit)
<li>
{{ $produit->nom }} - {{ $produit->prix }} € ({{ $produit->categorie->nom }})
<a href="{{ route('produits.edit', $produit->id) }}">Éditer</a>
<form action="{{ route('produits.destroy', $produit->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
<!-- Liens pour Calculer le Prix Total -->
<h2>Calculs</h2>
<a href="{{ route('produits.prix_total') }}">Calculer le Prix Total de Tous les Produits</a>
@if(isset($categorie))
<a href="{{ route('produits.prix_total_par_categorie', $categorie->id) }}">Calculer le Prix Total de la Catégorie "{{ $categorie->nom }}"</a>
@endif
</body>
</html>
produits/prix_total.blade.php
Créez une nouvelle vue pour afficher le résultat des calculs :
<!-- resources/views/produits/prix_total.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Prix Total des Produits</title>
</head>
<body>
<h1>Prix Total des Produits</h1>
@if(isset($categorie))
<p>Prix total des produits de la catégorie "{{ $categorie->nom }}" : {{ $prixTotal }} €</p>
@else
<p>Prix total de tous les produits : {{ $prixTotal }} €</p>
@endif
<a href="{{ route('produits.index') }}">Retour à la liste des produits</a>
</body>
</html>
Accédez à la page /produits
et utilisez le formulaire de recherche pour trouver des produits par nom.
Cliquez sur une catégorie dans la liste pour filtrer les produits appartenant à cette catégorie.
/produits/prix-total
pour calculer le prix total de tous les produits./produits/prix-total/{id}
pour calculer le prix total des produits d'une catégorie spécifique.Vous avez maintenant une application complète avec des fonctionnalités avancées :
Ces fonctionnalités peuvent être facilement étendues pour inclure d'autres critères de recherche ou de filtrage. Bon développement !
Dans ce tutoriel, nous allons ajouter encore plus de fonctionnalités avancées à notre application Laravel. Nous inclurons des fonctions pour :
rechercherProduitAvecCritères
Cette fonction permettra de rechercher des produits en utilisant plusieurs critères (nom, prix, catégorie).
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function rechercher(Request $request)
{
// Initialiser une requête Eloquent
$query = Produit::query();
// Filtrer par nom si fourni
if ($request->has('nom')) {
$query->where('nom', 'like', '%' . $request->input('nom') . '%');
}
// Filtrer par prix minimum si fourni
if ($request->has('prix_min')) {
$query->where('prix', '>=', $request->input('prix_min'));
}
// Filtrer par prix maximum si fourni
if ($request->has('prix_max')) {
$query->where('prix', '<=', $request->input('prix_max'));
}
// Filtrer par catégorie si fourni
if ($request->has('categorie_id')) {
$query->where('categorie_id', $request->input('categorie_id'));
}
// Récupérer les résultats
$produits = $query->get();
// Passer les catégories pour le formulaire de recherche
$categories = Categorie::all();
return view('produits.index', compact('produits', 'categories'));
}
grouperProduitsParCategorie
Cette fonction regroupera les produits par catégorie.
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function grouperParCategorie()
{
// Grouper les produits par catégorie
$groupedProducts = Produit::with('categorie')->get()->groupBy('categorie.nom');
return view('produits.groupe_par_categorie', compact('groupedProducts'));
}
calculerStatistiques
Cette fonction calculera des statistiques avancées comme la moyenne des prix et le nombre total de produits par catégorie.
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function calculerStatistiques()
{
// Calculer la moyenne des prix de tous les produits
$prixMoyen = Produit::avg('prix');
// Calculer le nombre total de produits par catégorie
$nombreProduitsParCategorie = Categorie::withCount('produits')->get();
return view('produits.statistiques', compact('prixMoyen', 'nombreProduitsParCategorie'));
}
trierProduits
Cette fonction triera les produits par nom, prix ou date de création.
ProduitController
Ajoutez la méthode suivante dans le contrôleur ProduitController
:
public function trier(Request $request)
{
// Définir l'ordre de tri par défaut
$orderBy = $request->input('order_by', 'nom'); // Par défaut, trier par nom
$orderDirection = $request->input('order_direction', 'asc'); // Par défaut, ordre ascendant
// Trier les produits
$produits = Produit::orderBy($orderBy, $orderDirection)->get();
return view('produits.index', compact('produits'));
}
Ajoutez les nouvelles routes dans routes/web.php
pour accéder aux fonctionnalités avancées :
// Route pour rechercher des produits avec plusieurs critères
Route::get('/produits/rechercher', [ProduitController::class, 'rechercher'])->name('produits.rechercher');
// Route pour grouper les produits par catégorie
Route::get('/produits/grouper-par-categorie', [ProduitController::class, 'grouperParCategorie'])->name('produits.grouper_par_categorie');
// Route pour calculer des statistiques avancées
Route::get('/produits/statistiques', [ProduitController::class, 'calculerStatistiques'])->name('produits.statistiques');
// Route pour trier les produits
Route::get('/produits/trier', [ProduitController::class, 'trier'])->name('produits.trier');
produits/index.blade.php
Ajoutez un formulaire de recherche avancée et des options de tri :
<!-- resources/views/produits/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Produits</title>
</head>
<body>
<h1>Liste des Produits</h1>
<!-- Formulaire de Recherche Avancée -->
<form action="{{ route('produits.rechercher') }}" method="GET">
<input type="text" name="nom" placeholder="Nom du produit...">
<input type="number" name="prix_min" placeholder="Prix minimum...">
<input type="number" name="prix_max" placeholder="Prix maximum...">
<select name="categorie_id">
<option value="">Toutes les catégories</option>
@foreach ($categories as $categorie)
<option value="{{ $categorie->id }}">{{ $categorie->nom }}</option>
@endforeach
</select>
<button type="submit">Rechercher</button>
</form>
<!-- Options de Tri -->
<form action="{{ route('produits.trier') }}" method="GET">
<label for="order_by">Trier par :</label>
<select name="order_by">
<option value="nom">Nom</option>
<option value="prix">Prix</option>
<option value="created_at">Date de création</option>
</select>
<label for="order_direction">Ordre :</label>
<select name="order_direction">
<option value="asc">Croissant</option>
<option value="desc">Décroissant</option>
</select>
<button type="submit">Trier</button>
</form>
<!-- Liste des Produits -->
<ul>
@foreach ($produits as $produit)
<li>
{{ $produit->nom }} - {{ $produit->prix }} € ({{ $produit->categorie->nom }})
<a href="{{ route('produits.edit', $produit->id) }}">Éditer</a>
<form action="{{ route('produits.destroy', $produit->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
<!-- Liens pour Accéder aux Autres Fonctionnalités -->
<h2>Autres Fonctionnalités</h2>
<a href="{{ route('produits.grouper_par_categorie') }}">Grouper les Produits par Catégorie</a>
<a href="{{ route('produits.statistiques') }}">Voir les Statistiques</a>
</body>
</html>
produits/groupe_par_categorie.blade.php
Créez une nouvelle vue pour afficher les produits groupés par catégorie :
<!-- resources/views/produits/groupe_par_categorie.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Produits Groupés par Catégorie</title>
</head>
<body>
<h1>Produits Groupés par Catégorie</h1>
@foreach ($groupedProducts as $categorie => $produits)
<h2>{{ $categorie }}</h2>
<ul>
@foreach ($produits as $produit)
<li>{{ $produit->nom }} - {{ $produit->prix }} €</li>
@endforeach
</ul>
@endforeach
<a href="{{ route('produits.index') }}">Retour à la liste des produits</a>
</body>
</html>
produits/statistiques.blade.php
Créez une nouvelle vue pour afficher les statistiques :
<!-- resources/views/produits/statistiques.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Statistiques des Produits</title>
</head>
<body>
<h1>Statistiques des Produits</h1>
<p>Prix moyen des produits : {{ $prixMoyen }} €</p>
<h2>Nombre de Produits par Catégorie</h2>
<ul>
@foreach ($nombreProduitsParCategorie as $categorie)
<li>{{ $categorie->nom }} : {{ $categorie->produits_count }} produits</li>
@endforeach
</ul>
<a href="{{ route('produits.index') }}">Retour à la liste des produits</a>
</body>
</html>
Vous avez maintenant une application complète avec des fonctionnalités avancées :
Ces fonctionnalités peuvent être étendues davantage pour répondre à des besoins spécifiques. Bon développement !
Laravel Eloquent est un ORM (Object-Relational Mapping) inclus dans le framework Laravel. Il permet d'interagir avec la base de données en utilisant des objets PHP au lieu d'écrire des requêtes SQL directement. Cela simplifie grandement les opérations CRUD (Create, Read, Update, Delete).
Pour utiliser Eloquent, vous devez avoir un projet Laravel configuré avec une base de données. Assurez-vous que votre fichier .env
contient les bonnes informations de connexion à la base de données :
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_username
DB_PASSWORD=your_password
Un modèle Eloquent représente une table dans la base de données. Chaque modèle est associé à une table spécifique.
Pour créer un modèle, utilisez la commande Artisan suivante :
php artisan make:model NomDuModele
Cela crée un fichier dans le dossier app/Models
. Par exemple, si vous créez un modèle nommé Article
, le fichier sera app/Models/Article.php
.
Par défaut, Eloquent associe un modèle à une table dont le nom est le pluriel du nom du modèle en minuscules. Par exemple :
Article
articles
Si votre table a un nom différent, vous pouvez spécifier le nom de la table dans le modèle :
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
protected $table = 'custom_table_name';
}
Eloquent permet d'effectuer des opérations CRUD de manière simple et intuitive.
Pour insérer un nouvel enregistrement dans la table, utilisez la méthode create()
:
use App\Models\Article;
$data = [
'title' => 'Mon premier article',
'content' => 'Ceci est le contenu de l\'article.',
];
$article = Article::create($data);
Assurez-vous que les colonnes sont remplies correctement et que les champs autorisés sont définis dans la propriété $fillable
du modèle :
protected $fillable = ['title', 'content'];
Pour récupérer tous les enregistrements d'une table :
$articles = Article::all();
Pour récupérer un enregistrement par son ID :
$article = Article::find(1);
Pour récupérer un enregistrement avec des conditions spécifiques :
$article = Article::where('title', 'Mon premier article')->first();
Pour mettre à jour un enregistrement existant :
$article = Article::find(1);
$article->title = 'Nouveau titre';
$article->save();
Ou utilisez la méthode update()
:
$article = Article::find(1);
$article->update(['title' => 'Nouveau titre']);
Pour supprimer un enregistrement :
$article = Article::find(1);
$article->delete();
Ou utilisez la méthode destroy()
pour supprimer par ID :
Article::destroy(1);
Eloquent permet de définir des relations entre les modèles pour représenter les associations entre les tables.
Exemple : Un utilisateur a un profil.
Dans le modèle User
:
public function profile()
{
return $this->hasOne(Profile::class);
}
Dans le modèle Profile
:
public function user()
{
return $this->belongsTo(User::class);
}
Exemple : Un utilisateur peut avoir plusieurs articles.
Dans le modèle User
:
public function articles()
{
return $this->hasMany(Article::class);
}
Dans le modèle Article
:
public function user()
{
return $this->belongsTo(User::class);
}
Exemple : Un article peut avoir plusieurs tags, et un tag peut être associé à plusieurs articles.
Dans le modèle Article
:
public function tags()
{
return $this->belongsToMany(Tag::class);
}
Dans le modèle Tag
:
public function articles()
{
return $this->belongsToMany(Article::class);
}
Pour paginer les résultats, utilisez la méthode paginate()
:
$articles = Article::paginate(10);
Cela renvoie 10 enregistrements par page avec des liens pour naviguer entre les pages.
Eloquent déclenche des événements lors des opérations CRUD. Vous pouvez écouter ces événements pour exécuter du code personnalisé.
Exemple : Ajouter un timestamp lors de la création d'un enregistrement :
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->created_at = now();
});
}
Dans ce tutoriel, nous allons explorer les fonctions couramment utilisées dans Laravel Eloquent pour interagir avec la base de données. Chaque fonction sera expliquée avec des exemples concrets.
all()
La méthode all()
permet de récupérer tous les enregistrements d'une table.
use App\Models\Article;
$articles = Article::all();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode renvoie une collection de tous les enregistrements de la table associée au modèle Article
.
find($id)
La méthode find($id)
permet de récupérer un enregistrement spécifique en utilisant son ID.
use App\Models\Article;
$article = Article::find(1);
if ($article) {
echo $article->title;
} else {
echo "Aucun article trouvé.";
}
Explication : Si aucun enregistrement n'est trouvé avec l'ID spécifié, la méthode renvoie null
.
findOrFail($id)
La méthode findOrFail($id)
fonctionne comme find($id)
, mais elle renvoie une erreur 404 si aucun enregistrement n'est trouvé.
use App\Models\Article;
try {
$article = Article::findOrFail(1);
echo $article->title;
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
echo "Article non trouvé.";
}
Explication : Cette méthode est utile lorsque vous voulez afficher une page d'erreur si l'enregistrement n'existe pas.
first()
La méthode first()
permet de récupérer le premier enregistrement correspondant à une requête.
use App\Models\Article;
$article = Article::where('status', 'published')->first();
if ($article) {
echo $article->title;
} else {
echo "Aucun article publié trouvé.";
}
Explication : Si aucun enregistrement ne correspond, la méthode renvoie null
.
firstOrFail()
La méthode firstOrFail()
fonctionne comme first()
, mais elle renvoie une erreur 404 si aucun enregistrement n'est trouvé.
use App\Models\Article;
try {
$article = Article::where('status', 'published')->firstOrFail();
echo $article->title;
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
echo "Aucun article publié trouvé.";
}
Explication : Cette méthode est utile lorsque vous voulez garantir qu'un enregistrement existe avant de continuer.
where('column', 'value')
La méthode where()
permet de filtrer les résultats en fonction d'une condition.
use App\Models\Article;
$articles = Article::where('status', 'published')->get();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode filtre les articles dont le statut est "published".
whereBetween('column', [$min, $max])
La méthode whereBetween()
permet de filtrer les résultats compris entre deux valeurs.
use App\Models\Article;
$articles = Article::whereBetween('price', [50, 100])->get();
foreach ($articles as $article) {
echo $article->title . " - " . $article->price;
}
Explication : Cette méthode filtre les articles dont le prix est compris entre 50 et 100.
whereIn('column', [val1, val2])
La méthode whereIn()
permet de vérifier si une colonne contient une valeur présente dans une liste.
use App\Models\Article;
$articles = Article::whereIn('category_id', [1, 2, 3])->get();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode filtre les articles dont la catégorie est 1, 2 ou 3.
whereNotIn('column', [val1, val2])
La méthode whereNotIn()
permet de vérifier si une colonne ne contient aucune des valeurs d'une liste.
use App\Models\Article;
$articles = Article::whereNotIn('category_id', [1, 2, 3])->get();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode filtre les articles dont la catégorie n'est ni 1, ni 2, ni 3.
whereNull('column')
La méthode whereNull()
permet de vérifier si une colonne est NULL.
use App\Models\Article;
$articles = Article::whereNull('published_at')->get();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode filtre les articles qui n'ont pas encore été publiés (colonne published_at
est NULL).
whereNotNull('column')
La méthode whereNotNull()
permet de vérifier si une colonne n'est pas NULL.
use App\Models\Article;
$articles = Article::whereNotNull('published_at')->get();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode filtre les articles qui ont déjà été publiés (colonne published_at
n'est pas NULL).
orderBy('column', 'desc')
La méthode orderBy()
permet de trier les résultats par une colonne spécifique.
use App\Models\Article;
$articles = Article::orderBy('created_at', 'desc')->get();
foreach ($articles as $article) {
echo $article->title;
}
Explication : Cette méthode trie les articles par date de création décroissante (du plus récent au plus ancien).
groupBy('column')
La méthode groupBy()
permet de regrouper les résultats par une colonne spécifique.
use App\Models\Article;
$articles = Article::select('category_id', \DB::raw('COUNT(*) as total'))
->groupBy('category_id')
->get();
foreach ($articles as $article) {
echo "Catégorie ID: " . $article->category_id . ", Total: " . $article->total;
}
Explication : Cette méthode regroupe les articles par catégorie et compte le nombre d'articles dans chaque catégorie.
distinct()
La méthode distinct()
permet de sélectionner des valeurs distinctes d'une colonne.
use App\Models\Article;
$categories = Article::distinct()->pluck('category_id');
foreach ($categories as $category) {
echo $category;
}
Explication : Cette méthode renvoie une liste unique des IDs de catégorie sans doublons.
select('column1', 'column2')
La méthode select()
permet de sélectionner uniquement certaines colonnes.
use App\Models\Article;
$articles = Article::select('title', 'created_at')->get();
foreach ($articles as $article) {
echo $article->title . " - " . $article->created_at;
}
Explication : Cette méthode récupère uniquement les colonnes title
et created_at
pour chaque article.
Dans ce tutoriel, nous allons explorer les fonctions Eloquent pour la création, la mise à jour, la suppression et les requêtes avancées. Chaque fonction sera expliquée avec des exemples concrets.
create(['column' => 'value'])
La méthode create()
permet d'ajouter un nouvel enregistrement dans la table associée au modèle.
use App\Models\Article;
$data = [
'title' => 'Mon premier article',
'content' => 'Ceci est le contenu de l\'article.',
];
$article = Article::create($data);
echo "Nouvel article créé avec l'ID : " . $article->id;
Explication : Cette méthode insère un nouvel enregistrement dans la base de données et renvoie une instance du modèle créé.
update(['column' => 'newValue'])
La méthode update()
permet de mettre à jour un ou plusieurs enregistrements existants.
use App\Models\Article;
$article = Article::find(1);
if ($article) {
$article->update(['title' => 'Nouveau titre']);
echo "Article mis à jour.";
} else {
echo "Article non trouvé.";
}
Explication : Cette méthode met à jour les colonnes spécifiées dans la table.
save()
La méthode save()
permet de sauvegarder les modifications apportées à un modèle existant.
use App\Models\Article;
$article = Article::find(1);
if ($article) {
$article->title = 'Titre modifié';
$article->save();
echo "Article sauvegardé.";
} else {
echo "Article non trouvé.";
}
Explication : Cette méthode sauvegarde les changements effectués sur un modèle directement dans la base de données.
increment('column')
La méthode increment()
permet d'incrémenter une colonne numérique.
use App\Models\Article;
$article = Article::find(1);
if ($article) {
$article->increment('views');
echo "Nombre de vues incrémenté.";
} else {
echo "Article non trouvé.";
}
Explication : Cette méthode incrémente automatiquement la valeur d'une colonne (par exemple, le nombre de vues).
decrement('column')
La méthode decrement()
permet de décrémenter une colonne numérique.
use App\Models\Article;
$article = Article::find(1);
if ($article) {
$article->decrement('stock');
echo "Stock décrémenté.";
} else {
echo "Article non trouvé.";
}
Explication : Cette méthode décrémente automatiquement la valeur d'une colonne (par exemple, le stock).
delete()
La méthode delete()
permet de supprimer un enregistrement spécifique.
use App\Models\Article;
$article = Article::find(1);
if ($article) {
$article->delete();
echo "Article supprimé.";
} else {
echo "Article non trouvé.";
}
Explication : Cette méthode supprime l'enregistrement correspondant au modèle.
destroy($id)
La méthode destroy()
permet de supprimer un ou plusieurs enregistrements directement par leur ID.
use App\Models\Article;
Article::destroy(1); // Supprime l'article avec l'ID 1
Article::destroy([2, 3]); // Supprime les articles avec les IDs 2 et 3
Explication : Cette méthode supprime les enregistrements sans avoir besoin de récupérer le modèle au préalable.
truncate()
La méthode truncate()
permet de supprimer toutes les données d'une table.
use App\Models\Article;
Article::truncate();
echo "Tous les articles ont été supprimés.";
Explication : Cette méthode vide complètement la table associée au modèle.
count()
La méthode count()
permet de compter le nombre d'enregistrements correspondant à une requête.
use App\Models\Article;
$count = Article::where('status', 'published')->count();
echo "Nombre d'articles publiés : " . $count;
Explication : Cette méthode renvoie le nombre total d'enregistrements filtrés.
sum('column')
La méthode sum()
permet de calculer la somme des valeurs d'une colonne.
use App\Models\Article;
$totalPrice = Article::sum('price');
echo "Prix total des articles : " . $totalPrice;
Explication : Cette méthode calcule la somme des valeurs d'une colonne numérique.
avg('column')
La méthode avg()
permet de calculer la moyenne des valeurs d'une colonne.
use App\Models\Article;
$averagePrice = Article::avg('price');
echo "Prix moyen des articles : " . $averagePrice;
Explication : Cette méthode calcule la moyenne des valeurs d'une colonne numérique.
min('column')
La méthode min()
permet de trouver la plus petite valeur d'une colonne.
use App\Models\Article;
$lowestPrice = Article::min('price');
echo "Prix le plus bas : " . $lowestPrice;
Explication : Cette méthode renvoie la valeur minimale d'une colonne numérique.
max('column')
La méthode max()
permet de trouver la plus grande valeur d'une colonne.
use App\Models\Article;
$highestPrice = Article::max('price');
echo "Prix le plus élevé : " . $highestPrice;
Explication : Cette méthode renvoie la valeur maximale d'une colonne numérique.
exists()
La méthode exists()
permet de vérifier si des enregistrements existent pour une requête donnée.
use App\Models\Article;
if (Article::where('status', 'published')->exists()) {
echo "Il y a des articles publiés.";
} else {
echo "Aucun article publié trouvé.";
}
Explication : Cette méthode renvoie true
si au moins un enregistrement correspond à la requête.
doesntExist()
La méthode doesntExist()
permet de vérifier si aucun enregistrement ne correspond à une requête donnée.
use App\Models\Article;
if (Article::where('status', 'draft')->doesntExist()) {
echo "Aucun article en brouillon trouvé.";
} else {
echo "Il y a des articles en brouillon.";
}
Explication : Cette méthode renvoie true
si aucun enregistrement ne correspond à la requête.
Dans ce tutoriel, nous allons explorer l'utilisation de la classe DB::
pour exécuter des requêtes brutes, les jointures entre tables avec Eloquent, ainsi que les fonctions d'agrégation. Chaque concept sera expliqué avec des exemples concrets.
DB::
La classe DB::
permet d'exécuter des requêtes SQL directement sans passer par les modèles Eloquent. Cela est utile pour des requêtes complexes ou personnalisées.
DB::select()
La méthode DB::select()
permet d'exécuter une requête SQL brute et de récupérer les résultats.
use Illuminate\Support\Facades\DB;
$results = DB::select('SELECT * FROM articles WHERE status = ?', ['published']);
foreach ($results as $article) {
echo $article->title;
}
Explication : Cette méthode exécute une requête SQL brute et renvoie les résultats sous forme d'objets PHP.
DB::insert()
La méthode DB::insert()
permet d'insérer des données dans la base de données.
use Illuminate\Support\Facades\DB;
DB::insert('INSERT INTO articles (title, content) VALUES (?, ?)', ['Mon article', 'Ceci est le contenu']);
echo "Article inséré.";
Explication : Cette méthode exécute une requête SQL d'insertion.
DB::update()
La méthode DB::update()
permet de mettre à jour des données existantes.
use Illuminate\Support\Facades\DB;
$affectedRows = DB::update('UPDATE articles SET title = ? WHERE id = ?', ['Nouveau titre', 1]);
echo "Nombre de lignes mises à jour : " . $affectedRows;
Explication : Cette méthode met à jour les enregistrements correspondants et renvoie le nombre de lignes affectées.
DB::delete()
La méthode DB::delete()
permet de supprimer des enregistrements.
use Illuminate\Support\Facades\DB;
$deletedRows = DB::delete('DELETE FROM articles WHERE id = ?', [1]);
echo "Nombre de lignes supprimées : " . $deletedRows;
Explication : Cette méthode supprime les enregistrements correspondants et renvoie le nombre de lignes affectées.
Les jointures permettent de combiner des données provenant de plusieurs tables.
join()
La méthode join()
permet de faire une jointure entre deux tables.
use App\Models\Article;
use App\Models\Category;
$articles = Article::join('categories', 'articles.category_id', '=', 'categories.id')
->select('articles.title', 'categories.name as category_name')
->get();
foreach ($articles as $article) {
echo "Titre : " . $article->title . ", Catégorie : " . $article->category_name;
}
Explication : Cette méthode combine les données des tables articles
et categories
en utilisant une clé étrangère.
leftJoin()
La méthode leftJoin()
permet de faire une jointure gauche (LEFT JOIN).
use App\Models\Article;
use App\Models\Category;
$articles = Article::leftJoin('categories', 'articles.category_id', '=', 'categories.id')
->select('articles.title', 'categories.name as category_name')
->get();
foreach ($articles as $article) {
echo "Titre : " . $article->title . ", Catégorie : " . ($article->category_name ?? 'Aucune catégorie');
}
Explication : Cette méthode inclut tous les articles, même ceux qui n'ont pas de catégorie associée.
join(...)->where()
Vous pouvez ajouter des conditions supplémentaires à une jointure.
use App\Models\Article;
use App\Models\Category;
$articles = Article::join('categories', function ($join) {
$join->on('articles.category_id', '=', 'categories.id')
->where('categories.status', '=', 'active');
})
->select('articles.title', 'categories.name as category_name')
->get();
foreach ($articles as $article) {
echo "Titre : " . $article->title . ", Catégorie : " . $article->category_name;
}
Explication : Cette méthode ajoute une condition supplémentaire à la jointure.
Les fonctions d'agrégation permettent de calculer des valeurs globales sur un ensemble de données.
count()
La méthode count()
permet de compter le nombre d'enregistrements.
use App\Models\Article;
$count = Article::count();
echo "Nombre total d'articles : " . $count;
Explication : Cette méthode renvoie le nombre total d'enregistrements dans la table.
sum()
La méthode sum()
permet de calculer la somme des valeurs d'une colonne numérique.
use App\Models\Article;
$totalPrice = Article::sum('price');
echo "Prix total des articles : " . $totalPrice;
Explication : Cette méthode calcule la somme des valeurs d'une colonne spécifiée.
avg()
La méthode avg()
permet de calculer la moyenne des valeurs d'une colonne numérique.
use App\Models\Article;
$averagePrice = Article::avg('price');
echo "Prix moyen des articles : " . $averagePrice;
Explication : Cette méthode calcule la moyenne des valeurs d'une colonne spécifiée.
min()
La méthode min()
permet de trouver la plus petite valeur d'une colonne numérique.
use App\Models\Article;
$lowestPrice = Article::min('price');
echo "Prix le plus bas : " . $lowestPrice;
Explication : Cette méthode renvoie la valeur minimale d'une colonne spécifiée.
max()
La méthode max()
permet de trouver la plus grande valeur d'une colonne numérique.
use App\Models\Article;
$highestPrice = Article::max('price');
echo "Prix le plus élevé : " . $highestPrice;
Explication : Cette méthode renvoie la valeur maximale d'une colonne spécifiée.
Dans ce tutoriel, nous allons explorer les relations Eloquent et leurs fonctionnalités en utilisant le schéma relationnel suivant :
Nous expliquerons chaque fonctionnalité avec des exemples concrets.
hasOne()
Exemple : Un client peut avoir une seule vente préférée.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
public function ventePreferee()
{
return $this->hasOne(Vente::class, 'idclient', 'idclient');
}
}
Explication : Cette méthode définit une relation où un client est associé à une seule vente via la clé étrangère idclient
.
hasMany()
Exemple : Une catégorie peut avoir plusieurs produits.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
public function produits()
{
return $this->hasMany(Produit::class, 'idcategorie', 'idcategorie');
}
}
Explication : Cette méthode définit une relation où une catégorie est associée à plusieurs produits via la clé étrangère idcategorie
.
belongsTo()
Exemple : Un produit appartient à une catégorie.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Produit extends Model
{
public function categorie()
{
return $this->belongsTo(Categorie::class, 'idcategorie', 'idcategorie');
}
}
Explication : Cette méthode définit une relation où un produit est lié à une catégorie via la clé étrangère idcategorie
.
belongsToMany()
Exemple : Une vente peut inclure plusieurs produits, et un produit peut être inclus dans plusieurs ventes.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Vente extends Model
{
public function produits()
{
return $this->belongsToMany(Produit::class, 'vente_produit', 'idvente', 'idproduit');
}
}
Explication : Cette méthode définit une relation où une table pivot (vente_produit
) relie les tables vente
et produit
.
with('relationName')
Exemple : Charger les produits d'une catégorie.
use App\Models\Categorie;
$categorie = Categorie::with('produits')->find(1);
foreach ($categorie->produits as $produit) {
echo $produit->nom;
}
Explication : La méthode with()
charge la relation produits
pour éviter les requêtes N+1.
with(['relation1', 'relation2'])
Exemple : Charger les ventes et les produits d'un client.
use App\Models\Client;
$client = Client::with(['ventePreferee', 'ventePreferee.produits'])->find(1);
echo $client->ventePreferee->produits->first()->nom;
Explication : Cette méthode charge plusieurs relations en une seule requête.
load('relationName')
Exemple : Charger les produits après avoir récupéré une catégorie.
use App\Models\Categorie;
$categorie = Categorie::find(1);
$categorie->load('produits');
foreach ($categorie->produits as $produit) {
echo $produit->nom;
}
Explication : La méthode load()
charge une relation après que le modèle a été récupéré.
loadMissing('relationName')
Exemple : Charger les produits uniquement s'ils ne sont pas déjà chargés.
use App\Models\Categorie;
$categorie = Categorie::find(1);
$categorie->loadMissing('produits');
foreach ($categorie->produits as $produit) {
echo $produit->nom;
}
Explication : Cette méthode charge une relation uniquement si elle n'a pas encore été chargée.
withCount('relationName')
Exemple : Compter le nombre de produits par catégorie.
use App\Models\Categorie;
$categories = Categorie::withCount('produits')->get();
foreach ($categories as $categorie) {
echo "Catégorie : " . $categorie->nom . ", Nombre de produits : " . $categorie->produits_count;
}
Explication : Cette méthode ajoute une colonne produits_count
contenant le nombre de produits associés.
withSum('relationName', 'column')
Exemple : Calculer la somme des prix des produits d'une catégorie.
use App\Models\Categorie;
$categories = Categorie::withSum('produits', 'prix')->get();
foreach ($categories as $categorie) {
echo "Catégorie : " . $categorie->nom . ", Somme des prix : " . $categorie->produits_sum_prix;
}
Explication : Cette méthode ajoute une colonne produits_sum_prix
contenant la somme des prix.
has('relationName')
Exemple : Sélectionner les catégories ayant au moins un produit.
use App\Models\Categorie;
$categories = Categorie::has('produits')->get();
foreach ($categories as $categorie) {
echo $categorie->nom;
}
Explication : Cette méthode filtre les catégories qui ont au moins un produit associé.
whereHas('relationName', function ($query) {...})
Exemple : Sélectionner les catégories ayant des produits dont le prix est supérieur à 100.
use App\Models\Categorie;
$categories = Categorie::whereHas('produits', function ($query) {
$query->where('prix', '>', 100);
})->get();
foreach ($categories as $categorie) {
echo $categorie->nom;
}
Explication : Cette méthode filtre les catégories en fonction des conditions spécifiées sur les produits.
orWhereHas('relationName', function ($query) {...})
Exemple : Sélectionner les catégories ayant des produits dont le prix est supérieur à 100 ou la marque est "X".
use App\Models\Categorie;
$categories = Categorie::whereHas('produits', function ($query) {
$query->where('prix', '>', 100);
})->orWhereHas('produits', function ($query) {
$query->where('marque', 'X');
})->get();
foreach ($categories as $categorie) {
echo $categorie->nom;
}
Explication : Cette méthode ajoute une condition "OU" sur les relations filtrées.
doesntHave('relationName')
Exemple : Sélectionner les catégories sans produits.
use App\Models\Categorie;
$categories = Categorie::doesntHave('produits')->get();
foreach ($categories as $categorie) {
echo $categorie->nom;
}
Explication : Cette méthode filtre les catégories qui n'ont aucun produit associé.
whereDoesntHave('relationName', function ($query) {...})
Exemple : Sélectionner les catégories sans produits dont le prix est supérieur à 100.
use App\Models\Categorie;
$categories = Categorie::whereDoesntHave('produits', function ($query) {
$query->where('prix', '>', 100);
})->get();
foreach ($categories as $categorie) {
echo $categorie->nom;
}
Explication : Cette méthode filtre les catégories qui n'ont pas de produits répondant aux conditions spécifiées.
php artisan make:migration create_clients_table --create=clients
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateClientsTable extends Migration
{
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->id('idClient');
$table->string('nom');
$table->string('prenom');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('clients');
}
}
php artisan make:migration create_categories_table --create=categories
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id('idCategorie');
$table->string('nom');
$table->text('description')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('categories');
}
}
php artisan make:migration create_produits_table --create=produits
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProduitsTable extends Migration
{
public function up()
{
Schema::create('produits', function (Blueprint $table) {
$table->id('idProduit');
$table->unsignedBigInteger('idCategorie');
$table->string('nom');
$table->decimal('prix', 8, 2);
$table->integer('quantiteStock');
$table->string('marque');
$table->foreign('idCategorie')->references('idCategorie')->on('categories')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('produits');
}
}
php artisan make:migration create_ventes_table --create=ventes
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateVentesTable extends Migration
{
public function up()
{
Schema::create('ventes', function (Blueprint $table) {
$table->id('idVente');
$table->unsignedBigInteger('idClient');
$table->unsignedBigInteger('idProduit');
$table->integer('quantite');
$table->dateTime('dateVente');
$table->foreign('idClient')->references('idClient')->on('clients')->onDelete('cascade');
$table->foreign('idProduit')->references('idProduit')->on('produits')->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('ventes');
}
}
php artisan migrate
php artisan make:model Client
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
use HasFactory;
protected $table = 'clients';
protected $primaryKey = 'idClient';
protected $fillable = ['nom', 'prenom'];
public function ventes()
{
return $this->hasMany(Vente::class, 'idClient');
}
}
php artisan make:model Categorie
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
use HasFactory;
protected $table = 'categories';
protected $primaryKey = 'idCategorie';
protected $fillable = ['nom', 'description'];
public function produits()
{
return $this->hasMany(Produit::class, 'idCategorie');
}
}
php artisan make:model Produit
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produit extends Model
{
use HasFactory;
protected $table = 'produits';
protected $primaryKey = 'idProduit';
protected $fillable = ['idCategorie', 'nom', 'prix', 'quantiteStock', 'marque'];
public function categorie()
{
return $this->belongsTo(Categorie::class, 'idCategorie');
}
public function ventes()
{
return $this->hasMany(Vente::class, 'idProduit');
}
}
php artisan make:model Vente
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Vente extends Model
{
use HasFactory;
protected $table = 'ventes';
protected $primaryKey = 'idVente';
protected $fillable = ['idClient', 'idProduit', 'quantite', 'dateVente'];
public function client()
{
return $this->belongsTo(Client::class, 'idClient');
}
public function produit()
{
return $this->belongsTo(Produit::class, 'idProduit');
}
}
php artisan make:controller ClientController
namespace App\Http\Controllers;
use App\Models\Client;
use App\Models\Vente;
use Illuminate\Http\Request;
class ClientController extends Controller
{
// 1. Récupérer tous les clients
public function getAllClients()
{
return Client::all();
}
// 2. Récupérer un client par ID
public function getClientById($idClient)
{
return Client::find($idClient);
}
// 3. Ajouter un nouveau client
public function addClient(Request $request)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'prenom' => 'required|string|max:255',
]);
return Client::create($validatedData);
}
// 4. Mettre à jour un client
public function updateClient(Request $request, $idClient)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'prenom' => 'required|string|max:255',
]);
$client = Client::find($idClient);
if ($client) {
$client->update($validatedData);
return $client;
}
return response()->json(['message' => 'Client not found'], 404);
}
// 5. Supprimer un client
public function deleteClient($idClient)
{
$client = Client::find($idClient);
if ($client) {
$client->delete();
return response()->json(['message' => 'Client deleted successfully']);
}
return response()->json(['message' => 'Client not found'], 404);
}
// 6. Récupérer toutes les ventes d'un client
public function getClientVentes($idClient)
{
return Client::find($idClient)->ventes;
}
// 7. Calculer le total des ventes pour un client
public function getTotalVentesClient($idClient)
{
$total = Vente::where('idClient', $idClient)->sum('quantite');
return response()->json(['total_ventes' => $total]);
}
// 8. Filtrer les clients par nom
public function filterClientsByNom($nom)
{
return Client::where('nom', 'like', '%' . $nom . '%')->get();
}
// 9. Filtrer les clients par prénom
public function filterClientsByPrenom($prenom)
{
return Client::where('prenom', 'like', '%' . $prenom . '%')->get();
}
// 10. Filtrer les clients par nom et prénom
public function filterClientsByNomEtPrenom($nom, $prenom)
{
return Client::where('nom', 'like', '%' . $nom . '%')
->where('prenom', 'like', '%' . $prenom . '%')
->get();
}
// 11. Récupérer les clients ayant effectué au moins une vente
public function getClientsWithVentes()
{
return Client::has('ventes')->get();
}
// 12. Récupérer les clients sans ventes
public function getClientsWithoutVentes()
{
return Client::doesntHave('ventes')->get();
}
// 13. Récupérer les clients ayant effectué plus de X ventes
public function getClientsWithMoreThanXVentes($x)
{
return Client::has('ventes', '>=', $x)->get();
}
// 14. Récupérer les clients ayant effectué moins de X ventes
public function getClientsWithLessThanXVentes($x)
{
return Client::has('ventes', '<=', $x)->get();
}
// 15. Récupérer les clients ayant effectué des ventes dans une période donnée
public function getClientsWithVentesInPeriod($startDate, $endDate)
{
return Client::whereHas('ventes', function ($query) use ($startDate, $endDate) {
$query->whereBetween('dateVente', [$startDate, $endDate]);
})->get();
}
}
php artisan make:controller CategorieController
namespace App\Http\Controllers;
use App\Models\Categorie;
use App\Models\Produit;
use Illuminate\Http\Request;
class CategorieController extends Controller
{
// 1. Récupérer toutes les catégories
public function getAllCategories()
{
return Categorie::all();
}
// 2. Récupérer une catégorie par ID
public function getCategorieById($idCategorie)
{
return Categorie::find($idCategorie);
}
// 3. Ajouter une nouvelle catégorie
public function addCategorie(Request $request)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'description' => 'nullable|string',
]);
return Categorie::create($validatedData);
}
// 4. Mettre à jour une catégorie
public function updateCategorie(Request $request, $idCategorie)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'description' => 'nullable|string',
]);
$categorie = Categorie::find($idCategorie);
if ($categorie) {
$categorie->update($validatedData);
return $categorie;
}
return response()->json(['message' => 'Catégorie not found'], 404);
}
// 5. Supprimer une catégorie
public function deleteCategorie($idCategorie)
{
$categorie = Categorie::find($idCategorie);
if ($categorie) {
$categorie->delete();
return response()->json(['message' => 'Catégorie deleted successfully']);
}
return response()->json(['message' => 'Catégorie not found'], 404);
}
// 6. Récupérer tous les produits d'une catégorie
public function getCategorieProduits($idCategorie)
{
return Categorie::find($idCategorie)->produits;
}
// 7. Calculer le nombre total de produits dans une catégorie
public function getTotalProduitsCategorie($idCategorie)
{
$total = Produit::where('idCategorie', $idCategorie)->count();
return response()->json(['total_produits' => $total]);
}
// 8. Filtrer les catégories par nom
public function filterCategoriesByNom($nom)
{
return Categorie::where('nom', 'like', '%' . $nom . '%')->get();
}
// 9. Filtrer les catégories par description
public function filterCategoriesByDescription($description)
{
return Categorie::where('description', 'like', '%' . $description . '%')->get();
}
// 10. Filtrer les catégories par nom et description
public function filterCategoriesByNomEtDescription($nom, $description)
{
return Categorie::where('nom', 'like', '%' . $nom . '%')
->where('description', 'like', '%' . $description . '%')
->get();
}
// 11. Récupérer les catégories ayant au moins un produit
public function getCategoriesWithProduits()
{
return Categorie::has('produits')->get();
}
// 12. Récupérer les catégories sans produits
public function getCategoriesWithoutProduits()
{
return Categorie::doesntHave('produits')->get();
}
// 13. Récupérer les catégories ayant plus de X produits
public function getCategoriesWithMoreThanXProduits($x)
{
return Categorie::has('produits', '>=', $x)->get();
}
// 14. Récupérer les catégories ayant moins de X produits
public function getCategoriesWithLessThanXProduits($x)
{
return Categorie::has('produits', '<=', $x)->get();
}
// 15. Récupérer les catégories dont les produits sont en stock
public function getCategoriesWithProduitsEnStock()
{
return Categorie::whereHas('produits', function ($query) {
$query->where('quantiteStock', '>', 0);
})->get();
}
}
php artisan make:controller ProduitController
namespace App\Http\Controllers;
use App\Models\Categorie;
use App\Models\Produit;
use App\Models\Vente;
use Illuminate\Http\Request;
class ProduitController extends Controller
{
// 1. Récupérer tous les produits
public function getAllProduits()
{
return Produit::all();
}
// 2. Récupérer un produit par ID
public function getProduitById($idProduit)
{
return Produit::find($idProduit);
}
// 3. Ajouter un nouveau produit
public function addProduit(Request $request)
{
$validatedData = $request->validate([
'idCategorie' => 'required|exists:categories,idCategorie',
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'quantiteStock' => 'required|integer|min:0',
'marque' => 'required|string|max:255',
]);
return Produit::create($validatedData);
}
// 4. Mettre à jour un produit
public function updateProduit(Request $request, $idProduit)
{
$validatedData = $request->validate([
'idCategorie' => 'required|exists:categories,idCategorie',
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'quantiteStock' => 'required|integer|min:0',
'marque' => 'required|string|max:255',
]);
$produit = Produit::find($idProduit);
if ($produit) {
$produit->update($validatedData);
return $produit;
}
return response()->json(['message' => 'Produit not found'], 404);
}
// 5. Supprimer un produit
public function deleteProduit($idProduit)
{
$produit = Produit::find($idProduit);
if ($produit) {
$produit->delete();
return response()->json(['message' => 'Produit deleted successfully']);
}
return response()->json(['message' => 'Produit not found'], 404);
}
// 6. Récupérer la catégorie d'un produit
public function getProduitCategorie($idProduit)
{
return Produit::find($idProduit)->categorie;
}
// 7. Récupérer toutes les ventes d'un produit
public function getProduitVentes($idProduit)
{
return Produit::find($idProduit)->ventes;
}
// 8. Calculer le total des ventes pour un produit
public function getTotalVentesProduit($idProduit)
{
$total = Vente::where('idProduit', $idProduit)->sum('quantite');
return response()->json(['total_ventes' => $total]);
}
// 9. Filtrer les produits par nom
public function filterProduitsByNom($nom)
{
return Produit::where('nom', 'like', '%' . $nom . '%')->get();
}
// 10. Filtrer les produits par marque
public function filterProduitsByMarque($marque)
{
return Produit::where('marque', 'like', '%' . $marque . '%')->get();
}
// 11. Filtrer les produits par prix minimum
public function filterProduitsByPrixMin($prixMin)
{
return Produit::where('prix', '>=', $prixMin)->get();
}
// 12. Filtrer les produits par prix maximum
public function filterProduitsByPrixMax($prixMax)
{
return Produit::where('prix', '<=', $prixMax)->get();
}
// 13. Filtrer les produits par quantité en stock
public function filterProduitsByQuantiteStock($quantiteStock)
{
return Produit::where('quantiteStock', '>=', $quantiteStock)->get();
}
// 14. Filtrer les produits par catégorie
public function filterProduitsByCategorie($idCategorie)
{
return Produit::where('idCategorie', $idCategorie)->get();
}
// 15. Récupérer les produits en stock
public function getProduitsEnStock()
{
return Produit::where('quantiteStock', '>', 0)->get();
}
}
php artisan make:controller VenteController
namespace App\Http\Controllers;
use App\Models\Client;
use App\Models\Produit;
use App\Models\Vente;
use Illuminate\Http\Request;
class VenteController extends Controller
{
// 1. Récupérer toutes les ventes
public function getAllVentes()
{
return Vente::all();
}
// 2. Récupérer une vente par ID
public function getVenteById($idVente)
{
return Vente::find($idVente);
}
// 3. Ajouter une nouvelle vente
public function addVente(Request $request)
{
$validatedData = $request->validate([
'idClient' => 'required|exists:clients,idClient',
'idProduit' => 'required|exists:produits,idProduit',
'quantite' => 'required|integer|min:1',
'dateVente' => 'required|date',
]);
// Vérifier si la quantité en stock est suffisante
$produit = Produit::find($validatedData['idProduit']);
if ($produit->quantiteStock < $validatedData['quantite']) {
return response()->json(['message' => 'Quantité en stock insuffisante'], 400);
}
// Mettre à jour la quantité en stock
$produit->quantiteStock -= $validatedData['quantite'];
$produit->save();
return Vente::create($validatedData);
}
// 4. Mettre à jour une vente
public function updateVente(Request $request, $idVente)
{
$validatedData = $request->validate([
'idClient' => 'required|exists:clients,idClient',
'idProduit' => 'required|exists:produits,idProduit',
'quantite' => 'required|integer|min:1',
'dateVente' => 'required|date',
]);
$vente = Vente::find($idVente);
if ($vente) {
// Vérifier si la quantité en stock est suffisante
$produit = Produit::find($validatedData['idProduit']);
if ($produit->quantiteStock < $validatedData['quantite']) {
return response()->json(['message' => 'Quantité en stock insuffisante'], 400);
}
// Restaurer la quantité en stock précédente
$produit->quantiteStock += $vente->quantite;
$produit->save();
// Mettre à jour la quantité en stock actuelle
$produit->quantiteStock -= $validatedData['quantite'];
$produit->save();
$vente->update($validatedData);
return $vente;
}
return response()->json(['message' => 'Vente not found'], 404);
}
// 5. Supprimer une vente
public function deleteVente($idVente)
{
$vente = Vente::find($idVente);
if ($vente) {
// Restaurer la quantité en stock
$produit = Produit::find($vente->idProduit);
$produit->quantiteStock += $vente->quantite;
$produit->save();
$vente->delete();
return response()->json(['message' => 'Vente deleted successfully']);
}
return response()->json(['message' => 'Vente not found'], 404);
}
// 6. Récupérer le client d'une vente
public function getVenteClient($idVente)
{
return Vente::find($idVente)->client;
}
// 7. Récupérer le produit d'une vente
public function getVenteProduit($idVente)
{
return Vente::find($idVente)->produit;
}
// 8. Calculer le montant total d'une vente
public function getMontantTotalVente($idVente)
{
$vente = Vente::find($idVente);
if ($vente) {
$montantTotal = $vente->quantite * $vente->produit->prix;
return response()->json(['montant_total' => $montantTotal]);
}
return response()->json(['message' => 'Vente not found'], 404);
}
// 9. Filtrer les ventes par date
public function filterVentesByDate($dateVente)
{
return Vente::whereDate('dateVente', $dateVente)->get();
}
// 10. Filtrer les ventes par date entre deux dates
public function filterVentesByDateRange($startDate, $endDate)
{
return Vente::whereBetween('dateVente', [$startDate, $endDate])->get();
}
// 11. Filtrer les ventes par client
public function filterVentesByClient($idClient)
{
return Vente::where('idClient', $idClient)->get();
}
// 12. Filtrer les ventes par produit
public function filterVentesByProduit($idProduit)
{
return Vente::where('idProduit', $idProduit)->get();
}
// 13. Calculer le total des ventes pour une date donnée
public function getTotalVentesByDate($dateVente)
{
$total = Vente::whereDate('dateVente', $dateVente)->sum('quantite');
return response()->json(['total_ventes' => $total]);
}
// 14. Calculer le total des ventes pour une période donnée
public function getTotalVentesByDateRange($startDate, $endDate)
{
$total = Vente::whereBetween('dateVente', [$startDate, $endDate])->sum('quantite');
return response()->json(['total_ventes' => $total]);
}
// 15. Calculer le montant total des ventes pour une période donnée
public function getMontantTotalVentesByDateRange($startDate, $endDate)
{
$ventes = Vente::whereBetween('dateVente', [$startDate, $endDate])->get();
$montantTotal = $ventes->reduce(function ($carry, $vente) {
return $carry + ($vente->quantite * $vente->produit->prix);
}, 0);
return response()->json(['montant_total' => $montantTotal]);
}
}
use App\Http\Controllers\ClientController;
use App\Http\Controllers\CategorieController;
use App\Http\Controllers\ProduitController;
use App\Http\Controllers\VenteController;
use Illuminate\Support\Facades\Route;
// Routes pour Clients
Route::get('/clients', [ClientController::class, 'getAllClients']);
Route::get('/clients/{idClient}', [ClientController::class, 'getClientById']);
Route::post('/clients', [ClientController::class, 'addClient']);
Route::put('/clients/{idClient}', [ClientController::class, 'updateClient']);
Route::delete('/clients/{idClient}', [ClientController::class, 'deleteClient']);
Route::get('/clients/{idClient}/ventes', [ClientController::class, 'getClientVentes']);
Route::get('/clients/{idClient}/total-ventes', [ClientController::class, 'getTotalVentesClient']);
Route::get('/clients/filter/nom/{nom}', [ClientController::class, 'filterClientsByNom']);
Route::get('/clients/filter/prenom/{prenom}', [ClientController::class, 'filterClientsByPrenom']);
Route::get('/clients/filter/nom/{nom}/prenom/{prenom}', [ClientController::class, 'filterClientsByNomEtPrenom']);
Route::get('/clients/with-ventes', [ClientController::class, 'getClientsWithVentes']);
Route::get('/clients/without-ventes', [ClientController::class, 'getClientsWithoutVentes']);
Route::get('/clients/with-more-than-x-ventes/{x}', [ClientController::class, 'getClientsWithMoreThanXVentes']);
Route::get('/clients/with-less-than-x-ventes/{x}', [ClientController::class, 'getClientsWithLessThanXVentes']);
Route::get('/clients/with-ventes-in-period/{startDate}/{endDate}', [ClientController::class, 'getClientsWithVentesInPeriod']);
// Routes pour Catégories
Route::get('/categories', [CategorieController::class, 'getAllCategories']);
Route::get('/categories/{idCategorie}', [CategorieController::class, 'getCategorieById']);
Route::post('/categories', [CategorieController::class, 'addCategorie']);
Route::put('/categories/{idCategorie}', [CategorieController::class, 'updateCategorie']);
Route::delete('/categories/{idCategorie}', [CategorieController::class, 'deleteCategorie']);
Route::get('/categories/{idCategorie}/produits', [CategorieController::class, 'getCategorieProduits']);
Route::get('/categories/{idCategorie}/total-produits', [CategorieController::class, 'getTotalProduitsCategorie']);
Route::get('/categories/filter/nom/{nom}', [CategorieController::class, 'filterCategoriesByNom']);
Route::get('/categories/filter/description/{description}', [CategorieController::class, 'filterCategoriesByDescription']);
Route::get('/categories/filter/nom/{nom}/description/{description}', [CategorieController::class, 'filterCategoriesByNomEtDescription']);
Route::get('/categories/with-produits', [CategorieController::class, 'getCategoriesWithProduits']);
Route::get('/categories/without-produits', [CategorieController::class, 'getCategoriesWithoutProduits']);
Route::get('/categories/with-more-than-x-produits/{x}', [CategorieController::class, 'getCategoriesWithMoreThanXProduits']);
Route::get('/categories/with-less-than-x-produits/{x}', [CategorieController::class, 'getCategoriesWithLessThanXProduits']);
Route::get('/categories/with-produits-en-stock', [CategorieController::class, 'getCategoriesWithProduitsEnStock']);
// Routes pour Produits
Route::get('/produits', [ProduitController::class, 'getAllProduits']);
Route::get('/produits/{idProduit}', [ProduitController::class, 'getProduitById']);
Route::post('/produits', [ProduitController::class, 'addProduit']);
Route::put('/produits/{idProduit}', [ProduitController::class, 'updateProduit']);
Route::delete('/produits/{idProduit}', [ProduitController::class, 'deleteProduit']);
Route::get('/produits/{idProduit}/categorie', [ProduitController::class, 'getProduitCategorie']);
Route::get('/produits/{idProduit}/ventes', [ProduitController::class, 'getProduitVentes']);
Route::get('/produits/{idProduit}/total-ventes', [ProduitController::class, 'getTotalVentesProduit']);
Route::get('/produits/filter/nom/{nom}', [ProduitController::class, 'filterProduitsByNom']);
Route::get('/produits/filter/marque/{marque}', [ProduitController::class, 'filterProduitsByMarque']);
Route::get('/produits/filter/prix-min/{prixMin}', [ProduitController::class, 'filterProduitsByPrixMin']);
Route::get('/produits/filter/prix-max/{prixMax}', [ProduitController::class, 'filterProduitsByPrixMax']);
Route::get('/produits/filter/quantite-stock/{quantiteStock}', [ProduitController::class, 'filterProduitsByQuantiteStock']);
Route::get('/produits/filter/categorie/{idCategorie}', [ProduitController::class, 'filterProduitsByCategorie']);
Route::get('/produits/en-stock', [ProduitController::class, 'getProduitsEnStock']);
// Routes pour Ventes
Route::get('/ventes', [VenteController::class, 'getAllVentes']);
Route::get('/ventes/{idVente}', [VenteController::class, 'getVenteById']);
Route::post('/ventes', [VenteController::class, 'addVente']);
Route::put('/ventes/{idVente}', [VenteController::class, 'updateVente']);
Route::delete('/ventes/{idVente}', [VenteController::class, 'deleteVente']);
Route::get('/ventes/{idVente}/client', [VenteController::class, 'getVenteClient']);
Route::get('/ventes/{idVente}/produit', [VenteController::class, 'getVenteProduit']);
Route::get('/ventes/{idVente}/montant-total', [VenteController::class, 'getMontantTotalVente']);
Route::get('/ventes/filter/date/{dateVente}', [VenteController::class, 'filterVentesByDate']);
Route::get('/ventes/filter/date-range/{startDate}/{endDate}', [VenteController::class, 'filterVentesByDateRange']);
Route::get('/ventes/filter/client/{idClient}', [VenteController::class, 'filterVentesByClient']);
Route::get('/ventes/filter/produit/{idProduit}', [VenteController::class, 'filterVentesByProduit']);
Route::get('/ventes/total-ventes/date/{dateVente}', [VenteController::class, 'getTotalVentesByDate']);
Route::get('/ventes/total-ventes/date-range/{startDate}/{endDate}', [VenteController::class, 'getTotalVentesByDateRange']);
Route::get('/ventes/montant-total/date-range/{startDate}/{endDate}', [VenteController::class, 'getMontantTotalVentesByDateRange']);
Categorie
et Produit
Dans ce tutoriel, nous allons explorer comment utiliser les factories et les seeders dans Laravel pour générer et insérer des données de test dans la base de données. Nous utiliserons les modèles Categorie
et Produit
que nous avons créés précédemment.
Categorie
Exécutez la commande suivante pour générer une factory pour le modèle Categorie
:
php artisan make:factory CategorieFactory --model=Categorie
Cela générera un fichier CategorieFactory.php
dans le dossier database/factories
. Ouvrez ce fichier et définissez les attributs par défaut pour une catégorie :
namespace Database\Factories;
use App\Models\Categorie;
use Illuminate\Database\Eloquent\Factories\Factory;
class CategorieFactory extends Factory
{
protected $model = Categorie::class;
public function definition()
{
return [
'nom' => $this->faker->word, // Génère un mot aléatoire
'description' => $this->faker->sentence, // Génère une phrase aléatoire
];
}
}
Produit
Exécutez la commande suivante pour générer une factory pour le modèle Produit
:
php artisan make:factory ProduitFactory --model=Produit
Cela générera un fichier ProduitFactory.php
dans le dossier database/factories
. Ouvrez ce fichier et définissez les attributs par défaut pour un produit :
namespace Database\Factories;
use App\Models\Produit;
use App\Models\Categorie;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProduitFactory extends Factory
{
protected $model = Produit::class;
public function definition()
{
return [
'nom' => $this->faker->word, // Génère un mot aléatoire
'prix' => $this->faker->randomFloat(2, 10, 1000), // Génère un prix aléatoire entre 10 et 1000
'categorie_id' => Categorie::factory(), // Crée automatiquement une catégorie associée
];
}
}
Exécutez la commande suivante pour générer un seeder pour les catégories :
php artisan make:seeder CategorieSeeder
Cela générera un fichier CategorieSeeder.php
dans le dossier database/seeders
. Ouvrez ce fichier et utilisez la factory pour créer des catégories :
namespace Database\Seeders;
use App\Models\Categorie;
use Illuminate\Database\Seeder;
class CategorieSeeder extends Seeder
{
public function run()
{
// Créer 5 catégories en utilisant la factory
Categorie::factory()->count(5)->create();
}
}
Exécutez la commande suivante pour générer un seeder pour les produits :
php artisan make:seeder ProduitSeeder
Cela générera un fichier ProduitSeeder.php
dans le dossier database/seeders
. Ouvrez ce fichier et utilisez la factory pour créer des produits :
namespace Database\Seeders;
use App\Models\Produit;
use Illuminate\Database\Seeder;
class ProduitSeeder extends Seeder
{
public function run()
{
// Créer 20 produits en utilisant la factory
Produit::factory()->count(20)->create();
}
}
DatabaseSeeder
Le fichier DatabaseSeeder.php
est le point d'entrée principal pour exécuter tous les seeders. Ouvrez ce fichier (database/seeders/DatabaseSeeder.php
) et appelez les seeders que vous avez créés :
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
// Exécuter le seeder pour les catégories
$this->call(CategorieSeeder::class);
// Exécuter le seeder pour les produits
$this->call(ProduitSeeder::class);
}
}
Pour vider et remplir la base de données avec les nouvelles données, exécutez la commande suivante :
php artisan migrate:fresh --seed
Cette commande :
Vous pouvez vérifier que les données ont été correctement insérées en utilisant Tinker, un outil interactif fourni par Laravel :
php artisan tinker
Dans Tinker, exécutez les commandes suivantes pour afficher les catégories et les produits :
// Afficher toutes les catégories
\App\Models\Categorie::all();
// Afficher tous les produits
\App\Models\Produit::with('categorie')->get();
ProduitFactory
Si vous souhaitez personnaliser les données générées par la factory, vous pouvez ajouter des méthodes statiques dans la factory. Par exemple, pour créer des produits "en promotion" :
public function enPromotion()
{
return $this->state(function (array $attributes) {
return [
'prix' => $this->faker->randomFloat(2, 1, 50), // Prix réduit
];
});
}
Ensuite, vous pouvez utiliser cette méthode dans un seeder :
Produit::factory()->count(5)->enPromotion()->create();
Vous avez maintenant une compréhension approfondie de l'utilisation des factories et des seeders dans Laravel. Voici un résumé des étapes que nous avons suivies :
Categorie
et Produit
.DatabaseSeeder
.Avec ces outils, vous pouvez facilement générer des données de test pour développer et tester votre application. Bon développement !
Categorie
et Produit
Dans ce cours, nous allons explorer en détail la validation des données dans Laravel. Nous travaillerons sur deux modèles : Categorie
et Produit
. Nous inclurons également des colonnes supplémentaires pour le modèle Produit
(comme codebar
, quantitystock
, etc.) afin de rendre l'exemple plus réaliste.
La validation des données est une étape cruciale dans le développement d'une application web. Elle permet de s'assurer que les données soumises par les utilisateurs respectent les règles définies avant d'être stockées dans la base de données.
Dans Laravel, la validation peut être effectuée directement dans les contrôleurs ou via des classes de requête personnalisées (FormRequest
). Dans ce cours, nous utiliserons la validation directement dans les contrôleurs.
Categorie
Créez une migration pour la table categories
:
php artisan make:migration create_categories_table
Ouvrez le fichier de migration généré et définissez la structure de la table :
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id(); // Clé primaire auto-incrémentée
$table->string('nom')->unique(); // Nom unique de la catégorie
$table->text('description')->nullable(); // Description facultative
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Produit
Créez une migration pour la table produits
:
php artisan make:migration create_produits_table
Ouvrez le fichier de migration généré et définissez la structure de la table :
public function up()
{
Schema::create('produits', function (Blueprint $table) {
$table->id(); // Clé primaire auto-incrémentée
$table->string('nom'); // Nom du produit
$table->foreignId('categorie_id')->constrained()->onDelete('cascade'); // Relation avec categories
$table->string('codebar')->unique(); // Code-barres unique
$table->integer('quantitystock')->unsigned(); // Quantité en stock (non négative)
$table->decimal('prix', 8, 2); // Prix du produit
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Exécutez les migrations pour créer les tables dans la base de données :
php artisan migrate
Categorie
Créez un modèle Categorie
:
php artisan make:model Categorie
Ajoutez les règles de validation et la relation avec Produit
:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
use HasFactory;
protected $fillable = ['nom', 'description'];
// Une catégorie a plusieurs produits
public function produits()
{
return $this->hasMany(Produit::class);
}
}
Produit
Créez un modèle Produit
:
php artisan make:model Produit
Ajoutez les règles de validation et la relation avec Categorie
:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produit extends Model
{
use HasFactory;
protected $fillable = ['nom', 'categorie_id', 'codebar', 'quantitystock', 'prix'];
// Un produit appartient à une catégorie
public function categorie()
{
return $this->belongsTo(Categorie::class);
}
}
CategorieController
Créez un contrôleur CategorieController
:
php artisan make:controller CategorieController
Ajoutez la méthode store
pour valider et enregistrer une nouvelle catégorie :
namespace App\Http\Controllers;
use App\Models\Categorie;
use Illuminate\Http\Request;
class CategorieController extends Controller
{
// Afficher le formulaire de création
public function create()
{
return view('categories.create');
}
// Valider et enregistrer une nouvelle catégorie
public function store(Request $request)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255|unique:categories',
'description' => 'nullable|string',
]);
Categorie::create($validatedData);
return redirect()->route('categories.index')->with('success', 'Catégorie créée avec succès.');
}
}
ProduitController
Créez un contrôleur ProduitController
:
php artisan make:controller ProduitController
Ajoutez la méthode store
pour valider et enregistrer un nouveau produit :
namespace App\Http\Controllers;
use App\Models\Produit;
use App\Models\Categorie;
use Illuminate\Http\Request;
class ProduitController extends Controller
{
// Afficher le formulaire de création
public function create()
{
$categories = Categorie::all();
return view('produits.create', compact('categories'));
}
// Valider et enregistrer un nouveau produit
public function store(Request $request)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'categorie_id' => 'required|exists:categories,id',
'codebar' => 'required|string|max:50|unique:produits',
'quantitystock' => 'required|integer|min:0',
'prix' => 'required|numeric|min:0',
]);
Produit::create($validatedData);
return redirect()->route('produits.index')->with('success', 'Produit créé avec succès.');
}
}
categories/create.blade.php
Créez une vue pour ajouter une nouvelle catégorie :
<!-- resources/views/categories/create.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Ajouter une Catégorie</title>
</head>
<body>
<h1>Ajouter une Catégorie</h1>
@if ($errors->any())
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('categories.store') }}" method="POST">
@csrf
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" required><br>
<label for="description">Description :</label>
<textarea name="description" id="description"></textarea><br>
<button type="submit">Enregistrer</button>
</form>
<a href="{{ route('categories.index') }}">Retour à la liste</a>
</body>
</html>
produits/create.blade.php
Créez une vue pour ajouter un nouveau produit :
<!-- resources/views/produits/create.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Ajouter un Produit</title>
</head>
<body>
<h1>Ajouter un Produit</h1>
@if ($errors->any())
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('produits.store') }}" method="POST">
@csrf
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" required><br>
<label for="categorie_id">Catégorie :</label>
<select name="categorie_id" id="categorie_id" required>
@foreach ($categories as $categorie)
<option value="{{ $categorie->id }}">{{ $categorie->nom }}</option>
@endforeach
</select><br>
<label for="codebar">Code-barres :</label>
<input type="text" name="codebar" id="codebar" required><br>
<label for="quantitystock">Quantité en Stock :</label>
<input type="number" name="quantitystock" id="quantitystock" min="0" required><br>
<label for="prix">Prix :</label>
<input type="number" step="0.01" name="prix" id="prix" min="0" required><br>
<button type="submit">Enregistrer</button>
</form>
<a href="{{ route('produits.index') }}">Retour à la liste</a>
</body>
</html>
Ajoutez les routes dans routes/web.php
:
use App\Http\Controllers\CategorieController;
use App\Http\Controllers\ProduitController;
// Routes pour Catégorie
Route::get('/categories/create', [CategorieController::class, 'create'])->name('categories.create');
Route::post('/categories', [CategorieController::class, 'store'])->name('categories.store');
// Routes pour Produit
Route::get('/produits/create', [ProduitController::class, 'create'])->name('produits.create');
Route::post('/produits', [ProduitController::class, 'store'])->name('produits.store');
Vous avez maintenant une application complète avec des fonctionnalités de validation des données pour les modèles Categorie
et Produit
. Voici un résumé des étapes que nous avons suivies :
categories
et produits
.Avec ces bases, vous pouvez facilement étendre votre application pour inclure des validations plus complexes ou des fonctionnalités supplémentaires. Bon développement !
Produit
Dans ce tutoriel, nous allons implémenter une gestion des sessions et de l'authentification dans une application Laravel. Nous allons restreindre les actions CRUD (Ajouter, Modifier, Supprimer, Afficher) sur le modèle Produit
afin que seuls les utilisateurs connectés puissent effectuer ces opérations.
L'authentification permet de vérifier si un utilisateur est autorisé à accéder à certaines parties d'une application. Dans notre cas, nous voulons que seuls les utilisateurs connectés puissent interagir avec les produits.
User
et Produit
.User
Laravel inclut déjà une migration par défaut pour la table users
. Si vous n'avez pas encore exécuté les migrations, vous pouvez le faire maintenant :
php artisan migrate
Produit
Créez une migration pour la table produits
:
php artisan make:migration create_produits_table
Ouvrez le fichier de migration généré et définissez la structure de la table :
public function up()
{
Schema::create('produits', function (Blueprint $table) {
$table->id(); // Clé primaire auto-incrémentée
$table->string('nom'); // Nom du produit
$table->decimal('prix', 8, 2); // Prix du produit
$table->integer('quantitystock')->unsigned(); // Quantité en stock
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Exécutez les migrations :
php artisan migrate
Laravel Breeze est un package simple pour configurer rapidement l'authentification. Installez-le avec Composer :
composer require laravel/breeze --dev
Publiez les fichiers nécessaires :
php artisan breeze:install
Compilez les assets :
npm install && npm run build
Exécutez les migrations pour créer la table users
:
php artisan migrate
Démarrer le serveur :
php artisan serve
Vous pouvez maintenant accéder aux pages d'inscription (/register
) et de connexion (/login
).
User
Le modèle User
est déjà inclus dans Laravel. Vous n'avez pas besoin de le créer manuellement.
Produit
Créez un modèle Produit
:
php artisan make:model Produit
Ajoutez les règles de validation et les attributs remplissables :
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produit extends Model
{
use HasFactory;
protected $fillable = ['nom', 'prix', 'quantitystock'];
}
ProduitController
Créez un contrôleur ProduitController
:
php artisan make:controller ProduitController
Ajoutez les méthodes CRUD avec des protections d'accès :
namespace App\Http\Controllers;
use App\Models\Produit;
use Illuminate\Http\Request;
class ProduitController extends Controller
{
public function __construct()
{
// Appliquer le middleware d'authentification à toutes les méthodes
$this->middleware('auth');
}
// Liste tous les produits
public function index()
{
$produits = Produit::all();
return view('produits.index', compact('produits'));
}
// Affiche le formulaire de création
public function create()
{
return view('produits.create');
}
// Enregistre un nouveau produit
public function store(Request $request)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'quantitystock' => 'required|integer|min:0',
]);
Produit::create($validatedData);
return redirect()->route('produits.index')->with('success', 'Produit créé avec succès.');
}
// Affiche un produit spécifique
public function show(Produit $produit)
{
return view('produits.show', compact('produit'));
}
// Affiche le formulaire d'édition
public function edit(Produit $produit)
{
return view('produits.edit', compact('produit'));
}
// Met à jour un produit existant
public function update(Request $request, Produit $produit)
{
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'quantitystock' => 'required|integer|min:0',
]);
$produit->update($validatedData);
return redirect()->route('produits.index')->with('success', 'Produit mis à jour avec succès.');
}
// Supprime un produit
public function destroy(Produit $produit)
{
$produit->delete();
return redirect()->route('produits.index')->with('success', 'Produit supprimé avec succès.');
}
}
produits/index.blade.php
Affiche la liste des produits :
<!-- resources/views/produits/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Produits</title>
</head>
<body>
<h1>Liste des Produits</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
<a href="{{ route('produits.create') }}">Ajouter un Produit</a>
<ul>
@foreach ($produits as $produit)
<li>
{{ $produit->nom }} - {{ $produit->prix }} € (Stock: {{ $produit->quantitystock }})
<a href="{{ route('produits.edit', $produit->id) }}">Éditer</a>
<form action="{{ route('produits.destroy', $produit->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
<a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
Déconnexion
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
@csrf
</form>
</body>
</html>
produits/create.blade.php
Formulaire pour ajouter un produit :
<!-- resources/views/produits/create.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Ajouter un Produit</title>
</head>
<body>
<h1>Ajouter un Produit</h1>
<form action="{{ route('produits.store') }}" method="POST">
@csrf
<label for="nom">Nom :</label>
<input type="text" name="nom" id="nom" required><br>
<label for="prix">Prix :</label>
<input type="number" step="0.01" name="prix" id="prix" min="0" required><br>
<label for="quantitystock">Quantité en Stock :</label>
<input type="number" name="quantitystock" id="quantitystock" min="0" required><br>
<button type="submit">Enregistrer</button>
</form>
<a href="{{ route('produits.index') }}">Retour à la liste</a>
</body>
</html>
Les autres vues (edit
, show
) peuvent être créées de manière similaire.
Ajoutez les routes dans routes/web.php
:
use App\Http\Controllers\ProduitController;
// Routes protégées par authentification
Route::middleware(['auth'])->group(function () {
Route::get('/produits', [ProduitController::class, 'index'])->name('produits.index');
Route::get('/produits/create', [ProduitController::class, 'create'])->name('produits.create');
Route::post('/produits', [ProduitController::class, 'store'])->name('produits.store');
Route::get('/produits/{produit}', [ProduitController::class, 'show'])->name('produits.show');
Route::get('/produits/{produit}/edit', [ProduitController::class, 'edit'])->name('produits.edit');
Route::put('/produits/{produit}', [ProduitController::class, 'update'])->name('produits.update');
Route::delete('/produits/{produit}', [ProduitController::class, 'destroy'])->name('produits.destroy');
});
// Routes d'authentification
Auth::routes();
Vous avez maintenant une application complète avec une gestion des sessions et de l'authentification. Voici un résumé des étapes que nous avons suivies :
User
et Produit
.Avec cette configuration, seuls les utilisateurs connectés peuvent ajouter, modifier, supprimer ou afficher la liste des produits. Bon développement !
Dans ce tutoriel, nous allons étendre notre application précédente en ajoutant la notion de rôles pour gérer les permissions des utilisateurs. Nous implémenterons deux rôles :
Nous allons mettre à jour les modèles, migrations, contrôleurs, vues et routes pour prendre en charge cette logique de rôle.
Les rôles permettent de définir des niveaux d'accès différents pour les utilisateurs. Par exemple :
Nous allons utiliser une colonne role
dans la table users
pour stocker le rôle de chaque utilisateur.
users
Ajoutez une colonne role
à la table users
pour stocker le rôle de l'utilisateur.
Exécutez la commande suivante pour créer une migration qui ajoute la colonne role
:
php artisan make:migration add_role_to_users_table --table=users
Ouvrez le fichier de migration généré et ajoutez la colonne role
:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('role')->default('manager'); // Valeur par défaut : 'manager'
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('role');
});
}
Exécutez la migration :
php artisan migrate
User
Ajoutez une méthode pour vérifier si un utilisateur a un rôle spécifique.
User
Ouvrez le fichier User.php
dans app/Models
et ajoutez la méthode suivante :
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $fillable = [
'name', 'email', 'password', 'role',
];
// Vérifie si l'utilisateur est un admin
public function isAdmin()
{
return $this->role === 'admin';
}
// Vérifie si l'utilisateur est un manager
public function isManager()
{
return $this->role === 'manager';
}
}
ProduitController
Modifiez le contrôleur pour restreindre les actions en fonction du rôle de l'utilisateur.
ProduitController
Ajoutez des vérifications de rôle dans les méthodes du contrôleur :
namespace App\Http\Controllers;
use App\Models\Produit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ProduitController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
// Liste tous les produits (accessible à tous les rôles)
public function index()
{
$produits = Produit::all();
return view('produits.index', compact('produits'));
}
// Affiche le formulaire de création (uniquement pour admin)
public function create()
{
if (!Auth::user()->isAdmin()) {
return redirect()->route('produits.index')->with('error', 'Vous n\'avez pas la permission d\'ajouter des produits.');
}
return view('produits.create');
}
// Enregistre un nouveau produit (uniquement pour admin)
public function store(Request $request)
{
if (!Auth::user()->isAdmin()) {
return redirect()->route('produits.index')->with('error', 'Vous n\'avez pas la permission d\'ajouter des produits.');
}
$validatedData = $request->validate([
'nom' => 'required|string|max:255',
'prix' => 'required|numeric|min:0',
'quantitystock' => 'required|integer|min:0',
]);
Produit::create($validatedData);
return redirect()->route('produits.index')->with('success', 'Produit créé avec succès.');
}
// Supprime un produit (uniquement pour admin)
public function destroy(Produit $produit)
{
if (!Auth::user()->isAdmin()) {
return redirect()->route('produits.index')->with('error', 'Vous n\'avez pas la permission de supprimer des produits.');
}
$produit->delete();
return redirect()->route('produits.index')->with('success', 'Produit supprimé avec succès.');
}
}
Ajoutez des conditions dans les vues pour afficher ou masquer les boutons en fonction du rôle de l'utilisateur.
produits/index.blade.php
Modifiez la vue pour afficher les boutons uniquement si l'utilisateur est un admin :
<!-- resources/views/produits/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Produits</title>
</head>
<body>
<h1>Liste des Produits</h1>
@if(session('success'))
<div>{{ session('success') }}</div>
@endif
@if(session('error'))
<div>{{ session('error') }}</div>
@endif
@if(Auth::user()->isAdmin())
<a href="{{ route('produits.create') }}">Ajouter un Produit</a>
@endif
<ul>
@foreach ($produits as $produit)
<li>
{{ $produit->nom }} - {{ $produit->prix }} € (Stock: {{ $produit->quantitystock }})
@if(Auth::user()->isAdmin())
<a href="{{ route('produits.edit', $produit->id) }}">Éditer</a>
<form action="{{ route('produits.destroy', $produit->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
@endif
</li>
@endforeach
</ul>
<a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
Déconnexion
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
@csrf
</form>
</body>
</html>
Aucune modification supplémentaire n'est nécessaire dans les routes, car les vérifications de rôle sont déjà gérées dans le contrôleur.
Vous pouvez créer des utilisateurs avec des rôles différents en utilisant Tinker :
php artisan tinker
Créez un utilisateur admin :
\App\Models\User::create([
'name' => 'Admin',
'email' => 'admin@example.com',
'password' => bcrypt('password'),
'role' => 'admin',
]);
Créez un utilisateur manager :
\App\Models\User::create([
'name' => 'Manager',
'email' => 'manager@example.com',
'password' => bcrypt('password'),
'role' => 'manager',
]);
Vous avez maintenant une application complète avec une gestion des rôles et des permissions. Voici un résumé des étapes que nous avons suivies :
role
dans la table users
.User
pour inclure des méthodes de vérification de rôle.ProduitController
pour appliquer des restrictions basées sur le rôle.Avec cette configuration, vous pouvez facilement étendre votre application pour inclure d'autres rôles ou permissions. Bon développement !
Client
et Comment
Dans ce tutoriel, nous allons créer une application complète pour gérer les rôles et permissions en utilisant deux modèles :
idclient
, nom
, email
, password
, role
) : Représente un utilisateur (client ou admin).idcomment
, date
, content
, idClient
) : Représente un commentaire ajouté par un client.Nous implémenterons les fonctionnalités suivantes :
clients
Créez une migration pour la table clients
:
php artisan make:migration create_clients_table
Ouvrez le fichier de migration généré et définissez la structure de la table :
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->id(); // Clé primaire auto-incrémentée
$table->string('nom'); // Nom du client
$table->string('email')->unique(); // Email unique
$table->string('password'); // Mot de passe crypté
$table->enum('role', ['client', 'admin'])->default('client'); // Rôle : client ou admin
$table->timestamps(); // Colonnes created_at et updated_at
});
}
comments
Créez une migration pour la table comments
:
php artisan make:migration create_comments_table
Ouvrez le fichier de migration généré et définissez la structure de la table :
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id(); // Clé primaire auto-incrémentée
$table->text('content'); // Contenu du commentaire
$table->timestamp('date')->useCurrent(); // Date automatique
$table->foreignId('idClient')->constrained('clients')->onDelete('cascade'); // Relation avec clients
$table->timestamps(); // Colonnes created_at et updated_at
});
}
Exécutez les migrations :
php artisan migrate
Client
Créez un modèle Client
:
php artisan make:model Client
Ajoutez les relations et les attributs remplissables :
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Client extends Authenticatable
{
protected $fillable = ['nom', 'email', 'password', 'role'];
// Relation : Un client a plusieurs commentaires
public function comments()
{
return $this->hasMany(Comment::class, 'idClient');
}
// Vérifie si l'utilisateur est un admin
public function isAdmin()
{
return $this->role === 'admin';
}
// Vérifie si l'utilisateur est un client
public function isClient()
{
return $this->role === 'client';
}
}
Comment
Créez un modèle Comment
:
php artisan make:model Comment
Ajoutez les relations et les attributs remplissables :
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
use HasFactory;
protected $fillable = ['content', 'idClient'];
// Relation : Un commentaire appartient à un client
public function client()
{
return $this->belongsTo(Client::class, 'idClient');
}
}
Installez Laravel Breeze pour configurer rapidement l'authentification :
composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run build
php artisan migrate
CommentController
Créez un contrôleur CommentController
:
php artisan make:controller CommentController
Ajoutez les méthodes CRUD avec des vérifications de rôle :
namespace App\Http\Controllers;
use App\Models\Comment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CommentController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
// Ajouter un commentaire (uniquement pour les clients)
public function store(Request $request)
{
$validatedData = $request->validate([
'content' => 'required|string',
]);
$comment = new Comment();
$comment->content = $validatedData['content'];
$comment->idClient = Auth::user()->id;
$comment->save();
return redirect()->back()->with('success', 'Commentaire ajouté avec succès.');
}
// Supprimer un commentaire (client : ses propres commentaires, admin : tous les commentaires)
public function destroy(Comment $comment)
{
if (Auth::user()->isAdmin() || Auth::user()->id === $comment->idClient) {
$comment->delete();
return redirect()->back()->with('success', 'Commentaire supprimé avec succès.');
}
return redirect()->back()->with('error', 'Vous n\'avez pas la permission de supprimer ce commentaire.');
}
}
AdminController
Créez un contrôleur AdminController
pour gérer les actions réservées aux admins :
php artisan make:controller AdminController
Ajoutez les méthodes pour lister, modifier et supprimer les clients :
namespace App\Http\Controllers;
use App\Models\Client;
use Illuminate\Http\Request;
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
// Liste tous les clients (uniquement pour admin)
public function index()
{
if (!Auth::user()->isAdmin()) {
return redirect()->route('home')->with('error', 'Accès refusé.');
}
$clients = Client::all();
return view('admin.clients.index', compact('clients'));
}
// Supprimer un client (uniquement pour admin)
public function destroy(Client $client)
{
if (!Auth::user()->isAdmin()) {
return redirect()->route('home')->with('error', 'Accès refusé.');
}
$client->delete();
return redirect()->route('admin.clients.index')->with('success', 'Client supprimé avec succès.');
}
}
comments/create.blade.php
Formulaire pour ajouter un commentaire :
<!-- resources/views/comments/create.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Ajouter un Commentaire</title>
</head>
<body>
<h1>Ajouter un Commentaire</h1>
<form action="{{ route('comments.store') }}" method="POST">
@csrf
<label for="content">Contenu :</label>
<textarea name="content" id="content" required></textarea><br>
<button type="submit">Ajouter</button>
</form>
<a href="{{ route('home') }}">Retour</a>
</body>
</html>
admin/clients/index.blade.php
Liste des clients pour l'admin :
<!-- resources/views/admin/clients/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>Liste des Clients</title>
</head>
<body>
<h1>Liste des Clients</h1>
<ul>
@foreach ($clients as $client)
<li>
{{ $client->nom }} - {{ $client->email }}
<form action="{{ route('admin.clients.destroy', $client->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit">Supprimer</button>
</form>
</li>
@endforeach
</ul>
<a href="{{ route('home') }}">Retour</a>
</
Un Middleware est un filtre qui intercepte les requêtes HTTP avant qu'elles n'atteignent le contrôleur ou la route finale. Il peut modifier la requête, effectuer des vérifications (par exemple, l'authentification), ou même arrêter la requête si certaines conditions ne sont pas remplies.
Lorsque vous installez Laravel, plusieurs middleware sont déjà configurés pour vous dans le dossier app/Http/Middleware
. Voici quelques exemples courants :
Authenticate
: Vérifie si un utilisateur est connecté.RedirectIfAuthenticated
: Redirige un utilisateur s'il est déjà connecté.VerifyCsrfToken
: Protège contre les attaques CSRF en vérifiant le jeton CSRF.TrimStrings
: Supprime les espaces inutiles des chaînes de caractères dans les requêtes.EncryptCookies
: Chiffre les cookies pour plus de sécurité.Pour créer un middleware personnalisé, utilisez la commande Artisan suivante :
php artisan make:middleware NomDuMiddleware
Exemple :
php artisan make:middleware CheckAge
Cette commande générera un fichier dans le dossier app/Http/Middleware
.
Ajoutez votre middleware dans le fichier app/Http/Kernel.php
:
protected $routeMiddleware = [
'check.age' => \App\Http\Middleware\CheckAge::class,
];
Appliquez un middleware à une route :
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('check.age');
Modifiez le middleware pour accepter des paramètres :
public function handle(Request $request, Closure $next, $minAge)
{
if ($request->input('age') < $minAge) {
return redirect('/home');
}
return $next($request);
}
Utilisez-le avec des paramètres :
Route::get('/restricted', function () {
return view('restricted');
})->middleware('check.age:21');
Pour commencer, assurez-vous d'avoir installé PHP, Composer et Laravel sur votre machine. Ces outils sont nécessaires pour créer et exécuter une application Laravel.
Pour créer un nouveau projet Laravel, utilisez la commande suivante dans votre terminal :
composer create-project --prefer-dist laravel/laravel travel-api
Cette commande crée un nouveau projet Laravel nommé "travel-api".
Après avoir créé le projet, accédez au dossier du projet en utilisant la commande suivante :
cd travel-api
Cela vous permet de naviguer dans le répertoire où se trouve votre projet Laravel.
Ouvrez le fichier .env
situé à la racine de votre projet. Ce fichier contient les configurations de votre application, y compris celles de la base de données. Modifiez les lignes suivantes pour configurer votre base de données :
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=travel_db
DB_USERNAME=root
DB_PASSWORD=
Remplacez les valeurs par celles de votre propre base de données MySQL. Par exemple, si vous avez un mot de passe pour votre base de données, indiquez-le dans DB_PASSWORD
.
Pour gérer les voyages, nous aurons besoin de plusieurs entités, telles que les utilisateurs (User
), les voyages (Trip
) et les destinations (Destination
). Nous allons créer ces entités avec leurs migrations correspondantes.
Trip
Pour créer un modèle et une migration pour les voyages, utilisez la commande suivante :
php artisan make:model Trip -m
Cette commande crée un modèle nommé Trip
et une migration associée. La migration est un fichier qui définit la structure de la table dans la base de données.
Dans le fichier de migration généré (database/migrations/..._create_trips_table.php
), ajoutez les colonnes suivantes :
public function up()
{
Schema::create('trips', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->date('start_date');
$table->date('end_date');
$table->decimal('price', 8, 2);
$table->timestamps();
});
}
Explication des colonnes :
id
: Identifiant unique pour chaque voyage.title
: Titre du voyage.description
: Description optionnelle du voyage.start_date
: Date de début du voyage.end_date
: Date de fin du voyage.price
: Prix du voyage.timestamps
: Colonnes automatiques pour suivre la création et la mise à jour des enregistrements.Exécutez les migrations pour créer la table dans la base de données :
php artisan migrate
Destination
Pour créer un modèle et une migration pour les destinations, utilisez la commande suivante :
php artisan make:model Destination -m
Dans le fichier de migration généré (database/migrations/..._create_destinations_table.php
), ajoutez les colonnes suivantes :
public function up()
{
Schema::create('destinations', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('country');
$table->text('description')->nullable();
$table->timestamps();
});
}
Explication des colonnes :
id
: Identifiant unique pour chaque destination.name
: Nom de la destination.country
: Pays de la destination.description
: Description optionnelle de la destination.timestamps
: Colonnes automatiques pour suivre la création et la mise à jour des enregistrements.Exécutez les migrations pour créer la table dans la base de données :
php artisan migrate
Les contrôleurs sont responsables de gérer les requêtes HTTP et de renvoyer des réponses appropriées. Nous allons créer des contrôleurs pour gérer les voyages et les destinations.
Trip
Pour créer un contrôleur pour les voyages, utilisez la commande suivante :
php artisan make:controller Api/TripController --api
Cette commande crée un contrôleur API nommé TripController
avec des méthodes prédéfinies pour les opérations CRUD (Create, Read, Update, Delete).
Dans app/Http/Controllers/Api/TripController.php
, ajoutez le code suivant :
namespace App\Http\Controllers\Api;
use App\Models\Trip;
use Illuminate\Http\Request;
class TripController extends Controller
{
public function index()
{
return Trip::all();
}
public function store(Request $request)
{
$trip = Trip::create($request->all());
return response()->json($trip, 201);
}
public function show($id)
{
$trip = Trip::find($id);
if (!$trip) {
return response()->json(['message' => 'Voyage non trouvé'], 404);
}
return $trip;
}
public function update(Request $request, $id)
{
$trip = Trip::find($id);
if (!$trip) {
return response()->json(['message' => 'Voyage non trouvé'], 404);
}
$trip->update($request->all());
return response()->json($trip, 200);
}
public function destroy($id)
{
$trip = Trip::find($id);
if (!$trip) {
return response()->json(['message' => 'Voyage non trouvé'], 404);
}
$trip->delete();
return response()->json(['message' => 'Voyage supprimé'], 204);
}
}
Explication des méthodes :
index()
: Renvoie tous les voyages.store()
: Crée un nouveau voyage.show()
: Renvoie un voyage spécifique par son ID.update()
: Met à jour un voyage existant.destroy()
: Supprime un voyage.Destination
Pour créer un contrôleur pour les destinations, utilisez la commande suivante :
php artisan make:controller Api/DestinationController --api
Dans app/Http/Controllers/Api/DestinationController.php
, ajoutez le code suivant :
namespace App\Http\Controllers\Api;
use App\Models\Destination;
use Illuminate\Http\Request;
class DestinationController extends Controller
{
public function index()
{
return Destination::all();
}
public function store(Request $request)
{
$destination = Destination::create($request->all());
return response()->json($destination, 201);
}
public function show($id)
{
$destination = Destination::find($id);
if (!$destination) {
return response()->json(['message' => 'Destination non trouvée'], 404);
}
return $destination;
}
public function update(Request $request, $id)
{
$destination = Destination::find($id);
if (!$destination) {
return response()->json(['message' => 'Destination non trouvée'], 404);
}
$destination->update($request->all());
return response()->json($destination, 200);
}
public function destroy($id)
{
$destination = Destination::find($id);
if (!$destination) {
return response()->json(['message' => 'Destination non trouvée'], 404);
}
$destination->delete();
return response()->json(['message' => 'Destination supprimée'], 204);
}
}
Les routes définissent les points d'accès de votre API. Ouvrez le fichier routes/api.php
et ajoutez les routes suivantes :
use App\Http\Controllers\Api\TripController;
use App\Http\Controllers\Api\DestinationController;
Route::prefix('v1')->group(function () {
// Routes pour les voyages
Route::apiResource('trips', TripController::class);
// Routes pour les destinations
Route::apiResource('destinations', DestinationController::class);
});
Cela crée des routes pour les opérations CRUD sur les voyages et les destinations. Le préfixe v1
signifie que ces routes appartiennent à la version 1 de l'API.
Vous pouvez tester l'API en utilisant des outils comme Postman ou cURL.
GET /api/v1/trips
POST /api/v1/trips
avec un corps JSON comme suit :
{
"title": "Voyage à Paris",
"description": "Découvrez la ville lumière",
"start_date": "2023-12-01",
"end_date": "2023-12-10",
"price": 1200.00
}
GET /api/v1/trips/{id}
PUT /api/v1/trips/{id}
avec un corps JSON.DELETE /api/v1/trips/{id}
Si un voyage est lié à une destination, vous pouvez définir une relation dans les modèles.
Dans app/Models/Trip.php
:
public function destination()
{
return $this->belongsTo(Destination::class);
}
Cela signifie qu'un voyage appartient à une destination.
Dans app/Models/Destination.php
:
public function trips()
{
return $this->hasMany(Trip::class);
}
Cela signifie qu'une destination peut avoir plusieurs voyages.
Ensuite, mettez à jour les migrations pour ajouter une clé étrangère dans la table trips
:
$table->foreignId('destination_id')->constrained()->onDelete('cascade');
Cela lie chaque voyage à une destination et supprime automatiquement les voyages liés si la destination est supprimée.