Guide très facile Laravel — OFPPT Notes دليل Laravel سهل جدا — ملاحظات OFPPT
Guide facile étape par étape. Copie. Colle. Ça marche. On va créer une petite application Laravel avec login, modules et calcul de note.
دليل سهل خطوة بخطوة. انسخ. الصق. وسيعمل. سنبني تطبيقا صغيرا بـ Laravel فيه دخول، وحدات، وحساب النقطة.
1. Avant de commencer 1. قبل أن نبدأ
▼Avant d’écrire du code, installe ces outils. Ils vont aider Laravel à marcher sur ton PC.
قبل كتابة الكود، ثبت هذه الأدوات. هي تساعد Laravel أن يعمل في حاسوبك.
| Outilالأداة | Ce qu’il fautما نحتاجه |
|---|---|
| PHP (XAMPP) | 8.2+ |
| Composer | 2.x |
| VS Code | stableمستقر |
cmd, puis Entrée.
أين نكتب؟ → في CMD. اضغط Windows + R، اكتب cmd، ثم Entrée.
php -v
composer -v
Si tu vois des numéros, c’est bon. PHP et Composer sont prêts. إذا رأيت أرقاما، فهذا جيد. PHP و Composer جاهزان.
php ou composer, ce n’est pas grave. Ajoute le dossier PHP de XAMPP au PATH Windows. Ferme CMD. Ouvre CMD encore une fois.
⚠ إذا لم يعرف Windows الأمر php أو composer، لا مشكلة. أضف مجلد PHP الخاص بـ XAMPP إلى PATH. أغلق CMD. افتحه من جديد.
2. Créer ton projet 2. أنشئ مشروعك
▼Pas besoin de cd ni de mkdir. Tu crées le dossier avec Windows. Puis tu ouvres CMD déjà dedans.
لا تحتاج cd ولا mkdir. أنشئ المجلد بويندوز. ثم افتح CMD وهو داخل المجلد.
- Clic droit sur le Bureau (ou Documents) → Nouveau → Dossier. Donne-lui un nom (exemple :
laravel projet). - زر يمين على سطح المكتب (أو المستندات) → جديد → مجلد. سمّه (مثال:
laravel projet). - Ouvre ce dossier (double-clic). Il peut être vide. C’est normal.
- افتح هذا المجلد (نقرتان). يمكن أن يكون فارغا. هذا عادي.
- Clique en haut dans la barre d’adresse (le chemin). Efface. Tape
cmd. Appuie sur Entrée. - انقر أعلى في شريط العنوان (المسار). امسح. اكتب
cmd. ثم Entrée.
Tape cmd ici, puis Entrée. CMD s’ouvre dans ton dossier.
اكتب cmd هنا ثم Entrée. يفتح CMD داخل مجلدك.
composer create-project laravel/laravel first-app
cd first-app
code .
php artisan serve
composer create-projecttélécharge Laravel et crée first-app.composer create-projectيحمل Laravel وينشئ first-app.code .ouvre le projet dans VS Code.code .يفتح المشروع في VS Code.php artisan servelance le site ici : http://127.0.0.1:8000.php artisan serveيشغل الموقع هنا: http://127.0.0.1:8000.
key:generate. Laravel le fait tout seul. Pour la base, on verra à l’étape 4.
💡 لا تحتاج key:generate. Laravel يفعلها وحده. القاعدة في الخطوة 4.
Tu dois voir la page de bienvenue Laravel. Si tu la vois, le projet marche. يجب أن ترى صفحة الترحيب Laravel. إذا رأيتها، فالمشروع يعمل.
.env avant migrate.
✅ في البداية، Laravel يستعمل SQLite. إذا طلب الأستاذ MySQL، انتظر الخطوة 4. سنغير .env قبل migrate.
first-app.
⚠ لا تغلق CMD عندما يكون الموقع يعمل. لكتابة أمر آخر، افتح CMD ثاني. ثم ادخل إلى first-app.
3. Trouver les bons dossiers 3. نجد المجلدات الصحيحة
▼Dans VS Code, ouvre le projet first-app. Voici les endroits importants. Ne t’inquiète pas. On va les utiliser un par un.
في VS Code، افتح مشروع first-app. هذه هي الأماكن المهمة. لا تقلق. سنستعملها واحدا واحدا.
Exemple : VS Code montre les dossiers du projet. مثال: VS Code يعرض مجلدات المشروع.
4. Préparer la base de données 4. نجهز قاعدة البيانات
▼La base de données garde les informations. Choisis une seule option : A pour SQLite, ou B pour MySQL. Après, on crée les tables.
قاعدة البيانات تحفظ المعلومات. اختر اختيارا واحدا فقط: أ لـ SQLite، أو ب لـ MySQL. بعد ذلك ننشئ الجداول.
Option A — SQLite (le plus simple) الخيار أ — SQLite (الأسهل)
DB_CONNECTION=sqlite dans .env. Le fichier de la base est database/database.sqlite. Va directement aux migrations plus bas.
لا تحتاج أن تغير شيئا. Laravel فيه DB_CONNECTION=sqlite في .env. ملف القاعدة هو database/database.sqlite. اذهب مباشرة إلى Migrations في الأسفل.
Option B — MySQL avec XAMPP الخيار ب — MySQL مع XAMPP
- Ouvre XAMPP Control Panel. Clique Start pour Apache. Clique Start pour MySQL.
- افتح XAMPP Control Panel. اضغط Start أمام Apache. واضغط Start أمام MySQL.
Quand Apache et MySQL sont verts, c’est bon. عندما يصبح Apache و MySQL باللون الأخضر، فهذا جيد.
- Ouvre http://127.0.0.1/phpmyadmin. Clique Nouvelle base. Écris
first_app. Choisisutf8mb4_unicode_ci. Clique Créer. - افتح http://127.0.0.1/phpmyadmin. اضغط قاعدة جديدة. اكتب
first_app. اخترutf8mb4_unicode_ci. اضغط إنشاء.
Le nom doit être first_app. On va mettre le même nom dans .env.
يجب أن يكون الاسم first_app. سنكتب نفس الاسم في .env.
.env, à la racine du projet. Remplace les lignes DB par ceci :
أين نلصق؟ → في VS Code. افتح .env في أصل المشروع. عوض أسطر DB بهذا:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=first_app
DB_USERNAME=root
DB_PASSWORD=
DB_PASSWORD=. Si tu as créé un mot de passe pour root, écris-le ici. Avec DB_CONNECTION=mysql, Laravel utilise MySQL.
⚠ مع XAMPP، كلمة مرور MySQL غالبا فارغة. لذلك اترك DB_PASSWORD=. إذا وضعت كلمة مرور لـ root، اكتبها هنا. مع DB_CONNECTION=mysql، Laravel يستعمل MySQL.
.env, lance php artisan config:clear. Cela dit à Laravel : relis les réglages.
بعد تغيير .env، شغل php artisan config:clear. هذا يقول لـ Laravel: اقرأ الإعدادات من جديد.
first-app. Fais ceci seulement si tu as choisi MySQL.
أين نكتب؟ → في CMD، داخل مجلد first-app. افعل هذا فقط إذا اخترت MySQL.
php artisan config:clear
Créer les fichiers des tables إنشاء ملفات الجداول
Même code pour SQLite et MySQL. 1) On crée 3 fichiers. 2) On colle le code. 3) On lance migrate. C’est tout.
نفس الكود لـ SQLite و MySQL. 1) ننشئ 3 ملفات. 2) نلصق الكود. 3) نشغل migrate. هذا كل شيء.
first-app.
أين نكتب؟ → في CMD. ادخل إلى مجلد first-app.
cd first-app
php artisan make:migration create_modules_table
php artisan make:migration create_calculs_table
php artisan make:migration create_notes_modules_table
Table modulesجدول modules
database/migrations/..._create_modules_table.php. Efface tout. Colle ce code.
أين نلصق؟ → في VS Code. افتح database/migrations/..._create_modules_table.php. امسح كل شيء. الصق هذا الكود.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('modules', function (Blueprint $table) {
$table->id();
$table->string('code');
$table->string('nom');
$table->integer('coefficient');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('modules');
}
};
Table calculsجدول calculs
database/migrations/..._create_calculs_table.php. Remplace tout par ce code.
أين نلصق؟ → في VS Code. افتح database/migrations/..._create_calculs_table.php. عوض كل شيء بهذا الكود.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('calculs', function (Blueprint $table) {
$table->id();
$table->decimal('note_annee1', 5, 2);
$table->decimal('note_eff', 5, 2);
$table->decimal('moyenne_annee2', 5, 2);
$table->decimal('note_finale', 5, 2);
$table->boolean('reussi');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('calculs');
}
};
Table notes_modulesجدول notes_modules
database/migrations/..._create_notes_modules_table.php. Remplace tout par ce code.
أين نلصق؟ → في VS Code. افتح database/migrations/..._create_notes_modules_table.php. عوض كل شيء بهذا الكود.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('notes_modules', function (Blueprint $table) {
$table->id();
$table->foreignId('calcul_id')->constrained('calculs')->cascadeOnDelete();
$table->foreignId('module_id')->constrained('modules')->cascadeOnDelete();
$table->decimal('note', 5, 2);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('notes_modules');
}
};
first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan migrate
Si migrate réussit, les tables sont créées.
إذا نجح migrate، فهذا يعني أن الجداول أُنشئت.
first_app. Avec SQLite, Laravel écrit dans database/database.sqlite.
✅ مع MySQL، انظر في phpMyAdmin داخل قاعدة first_app. مع SQLite، Laravel يكتب في database/database.sqlite.
modules et calculs. Après, crée notes_modules. Ce fichier a besoin des deux autres tables.
⚠ مهم: أنشئ أولا modules و calculs. بعد ذلك أنشئ notes_modules. هذا الملف يحتاج الجدولين الآخرين.
5. Créer les models 5. إنشاء Models
▼first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan make:model Module
php artisan make:model Calcul
php artisan make:model NoteModule
app/Models/Module.php. Colle ce code.
أين نلصق؟ → في VS Code. أنشئ أو افتح app/Models/Module.php. الصق هذا الكود.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Module extends Model
{
protected $fillable = ['code', 'nom', 'coefficient'];
}
app/Models/Calcul.php. Colle ce code.
أين نلصق؟ → في VS Code. افتح app/Models/Calcul.php. الصق هذا الكود.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Calcul extends Model
{
protected $fillable = [
'note_annee1', 'note_eff', 'moyenne_annee2', 'note_finale', 'reussi',
];
public function notesModules()
{
return $this->hasMany(NoteModule::class);
}
}
app/Models/NoteModule.php. Colle ce code.
أين نلصق؟ → في VS Code. افتح app/Models/NoteModule.php. الصق هذا الكود.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class NoteModule extends Model
{
protected $table = 'notes_modules';
protected $fillable = ['calcul_id', 'module_id', 'note'];
public function module()
{
return $this->belongsTo(Module::class);
}
public function calcul()
{
return $this->belongsTo(Calcul::class);
}
}
protected $table = 'notes_modules';. Sinon Laravel cherche le mauvais nom : note_modules.
⚠ اترك هذا السطر: protected $table = 'notes_modules';. بدونه Laravel يبحث عن اسم خاطئ: note_modules.
6. Faire le login 6. إنشاء صفحة الدخول
▼first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan make:controller AuthController
app/Http/Controllers/AuthController.php. Colle ce code.
أين نلصق؟ → في VS Code. افتح app/Http/Controllers/AuthController.php. الصق هذا الكود.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthController extends Controller
{
public function showLogin()
{
return view('auth.login');
}
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->route('calcul.index')->with('success', 'Connexion réussie.');
}
return back()->withErrors([
'email' => 'Email ou mot de passe incorrect.',
])->onlyInput('email');
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('login')->with('success', 'Déconnexion réussie.');
}
}
resources/views/auth/. Dedans, crée login.blade.php. Colle ce code.
أين نلصق؟ → في VS Code. أنشئ المجلد resources/views/auth/. داخله، أنشئ login.blade.php. الصق هذا الكود.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - OFPPT Notes</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light d-flex align-items-center min-vh-100">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-5">
<div class="card shadow">
<div class="card-header bg-primary text-white text-center">
<h1 class="h4 mb-0">Connexion OFPPT Notes</h1>
</div>
<div class="card-body p-4">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="mb-3">
<label class="form-label fw-bold">Email</label>
<input type="email" name="email" class="form-control" value="{{ old('email') }}" required autofocus>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Mot de passe</label>
<input type="password" name="password" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary w-100">Se connecter</button>
</form>
<p class="text-muted small text-center mt-3 mb-0">
Compte test : <strong>admin@ofppt.ma</strong> / <strong>password</strong>
</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
7. Ajouter, modifier, supprimer les modules 7. إضافة وتعديل وحذف الوحدات
▼first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan make:controller ModuleController
app/Http/Controllers/ModuleController.php. Colle ce code.
أين نلصق؟ → في VS Code. افتح app/Http/Controllers/ModuleController.php. الصق هذا الكود.
<?php
namespace App\Http\Controllers;
use App\Models\Module;
use Illuminate\Http\Request;
class ModuleController extends Controller
{
public function index()
{
$modules = Module::orderBy('id')->get();
return view('modules.index', compact('modules'));
}
public function create()
{
return view('modules.create');
}
public function store(Request $request)
{
$request->validate([
'code' => 'required|string|max:50',
'nom' => 'required|string|max:255',
'coefficient' => 'required|integer|min:1|max:10',
]);
Module::create($request->only('code', 'nom', 'coefficient'));
return redirect()->route('modules.index')->with('success', 'Module ajouté.');
}
public function edit($id)
{
$module = Module::findOrFail($id);
return view('modules.edit', compact('module'));
}
public function update(Request $request, $id)
{
$request->validate([
'code' => 'required|string|max:50',
'nom' => 'required|string|max:255',
'coefficient' => 'required|integer|min:1|max:10',
]);
Module::findOrFail($id)->update($request->only('code', 'nom', 'coefficient'));
return redirect()->route('modules.index')->with('success', 'Module modifié.');
}
public function destroy($id)
{
Module::findOrFail($id)->delete();
return redirect()->route('modules.index')->with('success', 'Module supprimé.');
}
}
index, create, edit. Pour le moment, colle juste le controller.
صفحات Blade تأتي في الخطوة 9: index و create و edit. الآن الصق فقط الـ controller.
8. Calculer la note finale 8. حساب النقطة النهائية
▼Voici la formule. Laravel va la calculer pour nous : (Note1A × 1 + Note2A × 3 + EFF) ÷ 9. Si le résultat est 10/20 ou plus, l’étudiant réussit.
هذه هي الصيغة. Laravel سيحسبها لنا: (Note1A × 1 + Note2A × 3 + EFF) ÷ 9. إذا كانت النتيجة 10/20 أو أكثر، فالطالب ناجح.
first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan make:controller CalculController
app/Http/Controllers/CalculController.php. Colle ce code.
أين نلصق؟ → في VS Code. افتح app/Http/Controllers/CalculController.php. الصق هذا الكود.
<?php
namespace App\Http\Controllers;
use App\Models\Calcul;
use App\Models\Module;
use App\Models\NoteModule;
use Illuminate\Http\Request;
class CalculController extends Controller
{
public function index()
{
$modules = Module::all();
$calculs = Calcul::orderBy('id', 'desc')->limit(5)->get();
return view('calcul.index', compact('modules', 'calculs'));
}
public function store(Request $request)
{
$request->validate([
'note_annee1' => 'required|numeric|min:0|max:20',
'note_eff' => 'required|numeric|min:0|max:100',
'notes' => 'required|array',
'notes.*' => 'required|numeric|min:0|max:20',
]);
$modules = Module::all();
if ($modules->count() == 0) {
return redirect()->route('modules.create')
->with('success', 'Ajoute d’abord au moins un module.');
}
$totalNotes = 0;
$totalCoef = 0;
foreach ($modules as $module) {
if (!isset($request->notes[$module->id])) continue;
$totalNotes += $request->notes[$module->id] * $module->coefficient;
$totalCoef += $module->coefficient;
}
if ($totalCoef == 0) {
return back()->withErrors(['notes' => 'Aucune note de module valide.']);
}
$moyenneAnnee2 = $totalNotes / $totalCoef;
$noteFinale = round(($request->note_annee1 * 1 + $moyenneAnnee2 * 3 + $request->note_eff) / 9, 2);
$reussi = $noteFinale >= 10;
$calcul = Calcul::create([
'note_annee1' => $request->note_annee1,
'note_eff' => $request->note_eff,
'moyenne_annee2' => round($moyenneAnnee2, 2),
'note_finale' => $noteFinale,
'reussi' => $reussi,
]);
foreach ($modules as $module) {
NoteModule::create([
'calcul_id' => $calcul->id,
'module_id' => $module->id,
'note' => $request->notes[$module->id],
]);
}
return redirect()->route('calcul.index')->with([
'note_finale' => $noteFinale,
'moyenne_annee2' => round($moyenneAnnee2, 2),
'reussi' => $reussi,
]);
}
public function destroy($id)
{
Calcul::findOrFail($id)->delete();
return redirect()->route('calcul.index')->with('success', 'Calcul supprimé.');
}
}
9. Créer les pages Blade 9. إنشاء صفحات Blade
▼Maintenant on crée les pages que l’utilisateur voit. Pour chaque fichier : 1) crée le fichier. 2) colle le code complet. 3) enregistre.
الآن ننشئ الصفحات التي يراها المستخدم. لكل ملف: 1) أنشئ الملف. 2) الصق الكود كاملا. 3) احفظ.
layout.blade.php
resources/views/layout.blade.php. C’est la page de base.
أين نلصق؟ → في VS Code. أنشئ أو افتح resources/views/layout.blade.php. هذه هي الصفحة الأساسية.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title') - OFPPT Notes</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="d-flex flex-column min-vh-100 bg-light">
<header class="bg-primary text-white py-3">
<div class="container">
<h1 class="h3 mb-1">OFPPT – Calcul Note Finale</h1>
</div>
</header>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<div class="navbar-nav me-auto">
<a class="nav-link" href="{{ route('calcul.index') }}">Calcul</a>
<a class="nav-link" href="{{ route('modules.index') }}">Modules</a>
<a class="nav-link" href="{{ route('modules.create') }}">Ajouter</a>
</div>
<div class="d-flex align-items-center gap-3">
<span class="text-white small">{{ Auth::user()->name }}</span>
<form action="{{ route('logout') }}" method="POST" class="mb-0">
@csrf
<button type="submit" class="btn btn-outline-light btn-sm">Déconnexion</button>
</form>
</div>
</div>
</nav>
<main class="container my-4 flex-grow-1">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if ($errors->any())
<div class="alert alert-danger"><ul class="mb-0">@foreach ($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul></div>
@endif
@yield('content')
</main>
<footer class="bg-primary text-white text-center py-3 mt-auto">
<div class="container small">Formule : (Note1A × 1 + Note2A × 3 + EFF) ÷ 9 | Seuil ≥ 10/20</div>
</footer>
</body>
</html>
modules/index.blade.php
resources/views/modules/index.blade.php. Cette page montre la liste des modules.
أين نلصق؟ → في VS Code. أنشئ resources/views/modules/index.blade.php. هذه الصفحة تعرض قائمة الوحدات.
@extends('layout')
@section('title', 'Modules')
@section('content')
<div class="d-flex justify-content-between align-items-center mb-3">
<h2 class="text-primary mb-0">Liste des modules</h2>
<a class="btn btn-primary" href="{{ route('modules.create') }}">+ Ajouter</a>
</div>
@if ($modules->count() == 0)
<p>Aucun module.</p>
@else
<table class="table table-bordered table-striped bg-white">
<thead class="table-primary"><tr><th>ID</th><th>Code</th><th>Nom</th><th>Coef</th><th>Actions</th></tr></thead>
<tbody>
@foreach ($modules as $module)
<tr>
<td>{{ $module->id }}</td>
<td>{{ $module->code }}</td>
<td>{{ $module->nom }}</td>
<td>{{ $module->coefficient }}</td>
<td>
<a class="btn btn-sm btn-secondary" href="{{ route('modules.edit', $module->id) }}">Modifier</a>
<form class="d-inline" action="{{ route('modules.destroy', $module->id) }}" method="POST" onsubmit="return confirm('Supprimer ?')">
@csrf @method('DELETE')
<button class="btn btn-sm btn-danger">Supprimer</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endif
@endsection
modules/create.blade.php
resources/views/modules/create.blade.php. Cette page ajoute un module.
أين نلصق؟ → في VS Code. أنشئ resources/views/modules/create.blade.php. هذه الصفحة تضيف وحدة.
@extends('layout')
@section('title', 'Ajouter module')
@section('content')
<h2 class="text-primary mb-3">Ajouter un module</h2>
<form action="{{ route('modules.store') }}" method="POST" class="card card-body shadow-sm">
@csrf
<div class="mb-3"><label class="form-label fw-bold">Code</label>
<input type="text" class="form-control" name="code" value="{{ old('code') }}" required></div>
<div class="mb-3"><label class="form-label fw-bold">Nom</label>
<input type="text" class="form-control" name="nom" value="{{ old('nom') }}" required></div>
<div class="mb-3"><label class="form-label fw-bold">Coefficient</label>
<input type="number" class="form-control" name="coefficient" min="1" max="10" value="{{ old('coefficient', 1) }}" required></div>
<button class="btn btn-primary">Enregistrer</button>
<a class="btn btn-secondary" href="{{ route('modules.index') }}">Annuler</a>
</form>
@endsection
modules/edit.blade.php
resources/views/modules/edit.blade.php. Cette page modifie un module.
أين نلصق؟ → في VS Code. أنشئ resources/views/modules/edit.blade.php. هذه الصفحة تعدل وحدة.
@extends('layout')
@section('title', 'Modifier module')
@section('content')
<h2 class="text-primary mb-3">Modifier le module</h2>
<form action="{{ route('modules.update', $module->id) }}" method="POST" class="card card-body shadow-sm">
@csrf @method('PUT')
<div class="mb-3"><label class="form-label fw-bold">Code</label>
<input type="text" class="form-control" name="code" value="{{ old('code', $module->code) }}" required></div>
<div class="mb-3"><label class="form-label fw-bold">Nom</label>
<input type="text" class="form-control" name="nom" value="{{ old('nom', $module->nom) }}" required></div>
<div class="mb-3"><label class="form-label fw-bold">Coefficient</label>
<input type="number" class="form-control" name="coefficient" min="1" max="10" value="{{ old('coefficient', $module->coefficient) }}" required></div>
<button class="btn btn-primary">Mettre à jour</button>
<a class="btn btn-secondary" href="{{ route('modules.index') }}">Annuler</a>
</form>
@endsection
calcul/index.blade.php
resources/views/calcul/index.blade.php. Cette page calcule la note finale.
أين نلصق؟ → في VS Code. أنشئ resources/views/calcul/index.blade.php. هذه الصفحة تحسب النقطة النهائية.
@extends('layout')
@section('title', 'Calcul')
@section('content')
<h2 class="mb-3 text-primary">Calculer la note finale</h2>
@if ($modules->count() == 0)
<a class="btn btn-primary" href="{{ route('modules.create') }}">Ajouter un module</a>
@else
<form action="{{ route('calcul.store') }}" method="POST" class="card card-body shadow-sm mb-4">
@csrf
<div class="mb-3">
<label class="form-label fw-bold">Note 1ère année (/20)</label>
<input type="number" class="form-control" name="note_annee1" min="0" max="20" step="0.01" value="{{ old('note_annee1') }}" required>
</div>
<div class="mb-3">
<label class="form-label fw-bold">EFF (/100)</label>
<input type="number" class="form-control" name="note_eff" min="0" max="100" step="0.01" value="{{ old('note_eff') }}" required>
</div>
<h3 class="h5 text-primary">Modules 2ème année</h3>
<table class="table table-bordered">
<thead class="table-primary"><tr><th>Code</th><th>Module</th><th>Coef</th><th>Note /20</th></tr></thead>
<tbody>
@foreach ($modules as $module)
<tr>
<td>{{ $module->code }}</td>
<td>{{ $module->nom }}</td>
<td>{{ $module->coefficient }}</td>
<td><input type="number" class="form-control" name="notes[{{ $module->id }}]" min="0" max="20" step="0.01" value="{{ old('notes.'.$module->id) }}" required></td>
</tr>
@endforeach
</tbody>
</table>
<button class="btn btn-primary">Calculer</button>
</form>
@endif
@if (session('note_finale') !== null)
<div class="card card-body shadow-sm mb-4">
<p>Moyenne 2A : <strong>{{ session('moyenne_annee2') }}</strong></p>
<p>Note finale : <strong>{{ session('note_finale') }} / 20</strong></p>
@if (session('reussi'))
<p class="text-success fw-bold">RÉUSSI</p>
@else
<p class="text-danger fw-bold">AJOURNÉ</p>
@endif
</div>
@endif
@if ($calculs->count() > 0)
<h2 class="h5 text-primary">Derniers calculs</h2>
<table class="table table-bordered bg-white">
<thead class="table-primary"><tr><th>#</th><th>1A</th><th>2A</th><th>EFF</th><th>Finale</th><th>Résultat</th><th></th></tr></thead>
<tbody>
@foreach ($calculs as $calcul)
<tr>
<td>{{ $calcul->id }}</td>
<td>{{ $calcul->note_annee1 }}</td>
<td>{{ $calcul->moyenne_annee2 }}</td>
<td>{{ $calcul->note_eff }}</td>
<td>{{ $calcul->note_finale }}</td>
<td>@if($calcul->reussi)<span class="badge text-bg-success">Réussi</span>@else<span class="badge text-bg-danger">Ajourné</span>@endif</td>
<td>
<form action="{{ route('calcul.destroy', $calcul->id) }}" method="POST" onsubmit="return confirm('Supprimer ?')">
@csrf @method('DELETE')
<button class="btn btn-sm btn-danger">Supprimer</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endif
@endsection
10. Relier les adresses du site 10. ربط عناوين الموقع
▼routes/web.php. Efface tout le fichier. Colle ce code.
أين نلصق؟ → في VS Code. افتح routes/web.php. امسح الملف كله. الصق هذا الكود.
<?php
use App\Http\Controllers\AuthController;
use App\Http\Controllers\CalculController;
use App\Http\Controllers\ModuleController;
use Illuminate\Support\Facades\Route;
Route::get('/login', [AuthController::class, 'showLogin'])->name('login');
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
Route::middleware('auth')->group(function () {
Route::get('/', [CalculController::class, 'index'])->name('calcul.index');
Route::post('/calculer', [CalculController::class, 'store'])->name('calcul.store');
Route::delete('/calculs/{id}', [CalculController::class, 'destroy'])->name('calcul.destroy');
Route::get('/modules', [ModuleController::class, 'index'])->name('modules.index');
Route::get('/modules/create', [ModuleController::class, 'create'])->name('modules.create');
Route::post('/modules', [ModuleController::class, 'store'])->name('modules.store');
Route::get('/modules/{id}/edit', [ModuleController::class, 'edit'])->name('modules.edit');
Route::put('/modules/{id}', [ModuleController::class, 'update'])->name('modules.update');
Route::delete('/modules/{id}', [ModuleController::class, 'destroy'])->name('modules.destroy');
});
11. Ajouter des données et tester 11. إضافة بيانات وتجربة الدخول
▼On va créer un compte pour tester. Email : admin@ofppt.ma. Mot de passe : password.
سننشئ حسابا للتجربة. البريد: admin@ofppt.ma. كلمة المرور: password.
first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan make:seeder UserSeeder
php artisan make:seeder ModuleSeeder
database/seeders/UserSeeder.php. Ce fichier crée l’utilisateur test.
أين نلصق؟ → في VS Code. افتح database/seeders/UserSeeder.php. هذا الملف ينشئ مستخدم التجربة.
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class UserSeeder extends Seeder
{
public function run(): void
{
User::create([
'name' => 'Admin OFPPT',
'email' => 'admin@ofppt.ma',
'password' => Hash::make('password'),
]);
}
}
database/seeders/ModuleSeeder.php. Ce fichier ajoute des modules de test.
أين نلصق؟ → في VS Code. افتح database/seeders/ModuleSeeder.php. هذا الملف يضيف وحدات للتجربة.
<?php
namespace Database\Seeders;
use App\Models\Module;
use Illuminate\Database\Seeder;
class ModuleSeeder extends Seeder
{
public function run(): void
{
$modules = [
['code' => 'M204', 'nom' => 'Développement front-end', 'coefficient' => 3],
['code' => 'M205', 'nom' => 'Développement back-end', 'coefficient' => 3],
['code' => 'M203', 'nom' => 'Gestion des données', 'coefficient' => 2],
['code' => 'M202', 'nom' => 'Approche agile', 'coefficient' => 2],
['code' => 'EGTS202', 'nom' => 'Français', 'coefficient' => 2],
];
foreach ($modules as $m) {
Module::create($m);
}
}
}
database/seeders/DatabaseSeeder.php. Ce fichier lance les deux seeders.
أين نلصق؟ → في VS Code. افتح database/seeders/DatabaseSeeder.php. هذا الملف يشغل الـ seeders الاثنين.
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
UserSeeder::class,
ModuleSeeder::class,
]);
}
}
first-app.
أين نكتب؟ → في CMD، داخل first-app.
php artisan migrate:fresh --seed
php artisan serve
Ouvre http://127.0.0.1:8000. Connecte-toi. Ajoute un module. Modifie un module. Calcule une note. Puis déconnecte-toi.
افتح http://127.0.0.1:8000. ادخل بالحساب. أضف وحدة. عدل وحدة. احسب نقطة. ثم اخرج.
migrate:fresh efface toutes les données. C’est OK pour apprendre sur ton PC. Ne fais pas ça sur un vrai site.
⚠ انتبه: migrate:fresh يمسح كل البيانات. هذا عادي للتعلم في حاسوبك. لا تفعل هذا في موقع حقيقي.
12. Corriger les erreurs simples 12. إصلاح الأخطاء البسيطة
▼| Si tu vois çaإذا رأيت هذا | Fais çaافعل هذا |
|---|---|
| La table n’existe pasالجدول غير موجود | php artisan migrate |
| 419 Page Expired | Ajoute @csrf dans le formulaireأضف @csrf داخل النموذج |
| Method Not Allowed | @method('PUT') / DELETE |
| Laravel ne trouve pas layoutLaravel لم يجد layout | resources/views/layout.blade.php |
| notes_modules error | protected $table = 'notes_modules'; |
| Le login ne marche pasالدخول لا يعمل | php artisan migrate:fresh --seed |
| SQLSTATE / Access denied (MySQL)SQLSTATE / Access denied (MySQL) | Regarde .env. Il faut DB_CONNECTION=mysql. Il faut aussi la base first_app. Démarre MySQL dans XAMPP. Puis lance php artisan config:clearانظر إلى .env. يجب أن يكون DB_CONNECTION=mysql. ويجب أن توجد قاعدة first_app. شغل MySQL في XAMPP. ثم شغل php artisan config:clear |
| Unknown database 'first_app'Unknown database 'first_app' | Crée la base dans phpMyAdmin. Le nom doit être le même que DB_DATABASE.أنشئ القاعدة في phpMyAdmin. يجب أن يكون الاسم مثل DB_DATABASE. |
.env à l’étape 4.
📌 SQLite و MySQL يعملان معا. كود Migrations و Models يبقى نفسه. تغير فقط .env في الخطوة 4.
Bravo, c’est fini. Tu as une application complète : login, modules, calcul OFPPT. Guide MD : GUIDE-FIRST-APP-LARAVEL.md
أحسنت، انتهينا. لديك تطبيق كامل: دخول، وحدات، حساب OFPPT. الدليل MD: GUIDE-FIRST-APP-LARAVEL.md