Laravel 7

Ma première application Laravel

Je vous propose dans cet article de voir comment créer une simple application Laravel en détaillant toutes les étapes. Il s’adresse donc aux débutants qui désirent découvrir ce framework et peut-être aux moins débutants qui aimeraient se rafraichir un peu les idées !

Évidemment je ne vais pas exposer tous les aspects de Laravel ici mais juste les éléments essentiels à prendre en compte. Toutefois on arrivera à une application totalement fonctionnelle.

On va ainsi créer un simple gestionnaire de tâches.

Vous pouvez télécharger le code final de l’article.

Les prérequis

Laravel, qui en est actuellement à sa version 7, a besoin de quelques éléments côté serveur :

  • PHP >= 7.2.5  c’est la moindre des choses pour un framework PHP !
  • des extensions PHP (que du classique) :
    • BCMath
    • Ctype
    • Fileinfo
    • JSON
    • Mbstring
    • OpenSSL
    • PDO
    • Tokenizer
    • XML

Vous pouvez trouver tout ça facilement sur un serveur local comme WAMPP ou XAMPP mais franchement si vous ne voulez pas vous compliquer la vie utilisez Laragon !

On va aussi utiliser MySQL comme serveur de données.

Vous aurez aussi besoin de Composer pour gérer les librairies PHP.

Enfin pour le frontend il vous faudra node.js.

Vous avez tout ça ? Alors c’est parti !

Installation de Laravel

Si vous utilisez Laragon l’installation est d’une extrême simplicité :

Il suffit ensuite de préciser le nom :

Et c’est parti ! Vous obtenez :

  • un nouveau dossier todolist avec une installation fraîche de Laravel dernière version
  • une base de données MySQL du même nom
  • et un hôte local todolist.oo (chez moi c’est oo mais peut-être que pour vous ce sera une autre extension

Si vous n’utilisez pas Laragon c’est plus laborieux, dans la console entrez :

composer create-project --prefer-dist laravel/laravel todolist

Et évidemment il vous faudra créer manuellement la base. D’autre part vous n’aurez pas automatiquement un hôte local.

Laravel dispose d’un serveur PHP local léger qu’on démarre en utilisant l’outil Artisan de Laravel :

php artisan serve

Mais il vaut mieux utiliser un serveur plus complet comme celui proposé par Laragon.

Si tout se passe bien vous devez arriver sur cette page avec todolist.oo (ou l’extension que vous utilisez) :

Base de données

Vous avez créé la base de données mais il faut renseigner Laravel pour qu’il s’en serve. Pour ça on va utiliser le fichier de configuration .env qui se situe à la racine :

Si pour une raison quelconque ce fichier n’existe pas faite une copie de .env.example pour le créer.

Dans ce fichier on va préciser le nom de la base et les identifiants pour y accéder :

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=todolist
DB_USERNAME=root
DB_PASSWORD=

Pour l’instant la base est vide. Laravel dispose d’un outil de migration pour créer des tables, les modifier, créer des index…

On trouve ça dans le dossier database :

On y trouve deux fichiers de migration :

  • pour la table users
  • pour la table failed_jobs

Comme on ne se servira pas de la deuxième on va supprimer ce fichier. Il ne va donc plus nous rester que la migration pour la table users. Si on regarde un peu le code on a une fonction up :

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}

C’est ici qu’on a le code pour créer la table et ses colonnes. Je ne vais pas entrer dans le détail mais le code est explicite.

Pour créer la table à partir de cette migration on utilise encore Artisan :

Si on regarde dans la base on se retrouve avec deux tables :

On a bien notre table users mais aussi un table migrations qui mémorise les actions de migration de Laravel. c’est une table d’intendance que vous n’avez pas à toucher.

On a dans la table users les colonnes telles que définies dans la migration :

L’authentification

Laravel n’est pas équipé à la base d’un système d’authentification (c’était le cas avec les précédentes versions) mais on peut l’ajouter avec un package complémentaire, c’est ce qu’on va faire en utilisant Composer :

Composer a ajouté la librairie dans le fichier composer.json :

"require": {
    ...
    "laravel/ui": "^2.1"
},

Et l’a chargée dans le dossier vendor :

Ce package ajoute des commandes à Artisan :

On a plusieurs possibilités pour le frontend (bootstrap, vue, react), on va faire simple avec juste bootstrap :

On va suivre les conseils et compiler les assets :

npm install
npm run dev

On va avoir la création d’un dossier node_modules avec toutes les dépendances. Ça prend un certain temps parce qu’il y a beaucoup de dépendances.

D’autre part le package ajoute une migration et on va créer la table correspondante :

On a maintenant 3 tables dans la base :

On a en plus une page pour le login :

Et une pour l’inscription :

Il est d’autre part possible de réinitialiser le mot de passe. Vous pouvez explorer tout ça…

Les langues

Évidemment à la base tout est en anglais mais Laravel sait très bien gérer l’aspect linguistique. Vous avez toutes les traductions de base ici.

Vous pouvez récupérer le dossier fr et le copier là :

Ensuite vous changez la locale dans config/app.php :

'locale' => 'fr',

Vous aurez ainsi en français les messages pour l’authentification et la validation. Mais ça ne va pas changer automatiquement les textes dans les formulaires. Voyons déjà où sont ces formulaires. Toutes les vues (ficheirs qui génèrent les pages HTML) de Laravel sont dans le dossier resources/views :

La package qu’on a installé à ajouté ici les vues du dossier auth. regardons un peu le code, par exemple dans la vue du login on trouve cette ligne :

<div class="card-header">{{ __('Login') }}</div>

Qui correspond au titre du formulaire de login :

Je peux faire un changement brutal :

<div class="card-header">Connexion</div>

Après tout si je veux mon site exclusivement en français ça ne pose aucun problème. Mais si je veux conserver la possibilité d’avoir plusieurs langue je dois trouver une méthode plus élégante…

Je crée un fichier resources/lang/fr.json :

Avec ce code :

{
  "Login": "Connexion"
}

On obtient le même résultat mais maintenant le site est multilingues !

Il faut évidemment passer en revue tous les textes à traduire et compléter le fichier JSON. C’est un peu laborieux à faire mais heureusement il existe des packages qui facilitent la vie, comme par exemple celui-ci !

Pour ne pas alourdir cet article on va garder les textes en anglais dans l’authentification mais rien ne vous empêche de les modifier !

Les données

Il est maintenant temps de se poser la question des données nécessaires pour notre application. On va partir sur cette base, pour chaque tâche on a avoir :

  • un titre (« Tondre la pelouse« )
  • un texte de détail (« Ne pas oublier de demander la tondeuse au voisin la veille »)
  • une date de création
  • une date de modification
  • un état (a priori deux états : à faire et fait)

On va donc créer une table pour mémoriser tout ça. On a vu qu’avec Laravel on utilise une migration pour ça. d’autre part Laravel est équipé d’un ORM efficace : Eloquent. Chaque table est représenté par une classe qui permet de manipuler les données. On dispose ainsi d’un modèle pour chaque table à manipuler. On va demander à Artisan de créer à la fois une table et son modèle Eloquent associé :

On trouve le modèle ici :

On a déjà le modèle par défaut User pour gérer les données de la table users.

La migration a été créée ici :

Par défaut on a ce code :

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
    });
}

On a :

  • une clé id
  • deux colonnes (created_at et updated_at) créée par la méthode timestamps.

On va ajouter les colonnes nécessaires :

Schema::create('tasks', function (Blueprint $table) {
    $table->id();
    $table->timestamps();
    $table->string('title');
    $table->text('detail');
    $table->boolean('state')->default(false);
});

Et on lance la migration :

On doit trouver la table dans la base avec ses colonnes :

Le contrôleur et les routes

Laravel est basé sur le modèle MVC :

  • Modèle : c’est Eloquent qui se charge de cet aspect et on a créé un modèle (Task) pour nos tâches,
  • Vue : on a déjà des vues pour la partie authentification, on a devoir en créer aussi pour nos tâches,
  • Contrôleur : c’est le chef d’orchestre de l’application, on va créer à présent un contrôleur pour gérer toutes les actions nécessaires pour les tâches.
php artisan make:controller TaskController --resource

On trouve ce contrôleur ici :

C’est un contrôleur de ressource, ce qui signifie qu’il est déjà équipé de 7 fonctions pour les actions suivantes :

Verbe URI Action Route
GET /tasks index tasks.index
GET /tasks/create create tasks.create
POST /tasks store tasks.store
GET /tasks/{task} show tasks.show
GET /tasks/{task}/edit edit tasks.edit
PUT/PATCH /tasks/{task} update tasks.update
DELETE /tasks/{task} destroy tasks.destroy

On va créer aussi les routes pour accéder à ces actions dans le fichier routes/web.php :

Route::resource('tasks', 'TaskController')->middleware('auth');

Si vous utilisez la commande php artisan route:list vous obtenez toutes les routes de l’application et en particulier les 7 pour le contrôleur :

Maintenant que tout ça est en place on va coder ces actions et créer les vues correspondantes !

Un petit mot sur le middleware auth que j’ai ajouté pour ces routes. Un middleware est une étape pour la requête HTTP qui arrive, ça permet d’accomplir des vérifications, ici on demande que l’accès à ces routes soir limitées aux utilisateurs authentifiés. Ceux qui ne le sont pas seront automatiquement renvoyés à la page de connexion. Pour la suite de ce tutoriel vous devrez donc créer un utilisateur avec les formulaires qu’on a déjà mis en place.

Créer une tâche

Le formulaire

Pour la création d’une tâche on va avoir besoin d’un formulaire. On crée un dossier tasks et la vue create :

Avec ce code :

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Création d'une tâche</div>
                <div class="card-body">
                    <form action="{{ route('tasks.store') }}" method="post">
                        @csrf
                        @if (session()->has('message'))
                            <div class="alert alert-success" role="alert">
                                {{ session('message') }}
                            </div>
                        @endif
                        <div class="form-group">
                            <label for="title">Titre</label>
                            <input type="text" class="form-control @error('title') is-invalid @enderror" id="title" name="title" placeholder="Titre de la tâche" value="{{ old('title') }}">
                            @error('title')
                                <div class="invalid-feedback">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label for="description">Détail</label>
                            <textarea class="form-control @error('detail') is-invalid @enderror" id="detail" name="detail" placeholder="Détail de la tâche">{{ old('detail') }}</textarea>
                            @error('detail')
                                <div class="invalid-feedback">{{ $message }}</div>
                            @enderror
                        </div>
                        <button type="submit" class="btn btn-primary">Envoyer</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

Il y a beaucoup à dire sur ce code mais je ne vais pas entrer dans les détails.

On a une vue de base layouts.app qui comporte la structure de base de la page. La commande @extends permet de dire qu’on prend cette vue comme base. Laravel utilise Blade comme gestionnaire de template. Toute vue qui utilise Blade doit comporter blade dans son nom.

Le formulaire est défini avec ce code :

<form action="{{ route('tasks.store') }}" method="post">

On utilise l’helper route qui, à partir du nom de la route, génère l’url. Pour insérer des éléments avec PHP on utilise des accolades.

On a ensuite cette commande Blade :

@csrf

On demande ici à Blade d’insérer un token dans un champ caché qui va permettre à Laravel de contrer les attaques CSRF, le code généré ressemble à ça :

<input type="hidden" name="_token" value="sUTuW5dYrt2l2iPgAJ5EVXn5UwMjEGFLAZaH4jHz">

C’est automatique et on n’a pas besoin de s’en préoccuper ensuite. Un middleware se charge à l’arrivée de ce contrôle de sécurité.

On a aussi dans la page pas mal de code qui concerne la validation mais je vais en parler plus loin.

On va compléter le code de la fonction create du contrôleur TaskController pour appeler la vue :

public function create()
{
    return view('tasks.create');
}

Maintenant avec l’url todolist.oo/tasks/create on obtient la page avec le formulaire (si on est connecté !) :

La soumission

Pour créer effectivement la tâche on va devoir gérer la soumission du formulaire dans la méthode store du contrôleur :

use App\Task;

...

public function store(Request $request)
{
    $data = $request->validate([
        'title' => 'required|max:100',
        'detail' => 'required|max:500',
    ]);

    $task = new Task;
    $task->title = $request->title;
    $task->detail = $request->detail;
    $task->save();

    return back()->with('message', "La tâche a bien été créée !");
}

On commence par vérifier les entrée avec la validation. Les deux champs sont requis et on vérifie une longueur maximale.

Ensuite on utilise Eloquent pour créer la tâche.

Pour finir on revoie dans la vue.

Vous pouvez vérifier que la validation fonctionne  :

C’est la commande Blase @error qui permet de repérer les erreurs et d’ainsi permettre d’adapter l’affichage pour informer l’utilisateur.

Si la validation est bonne, la tâche est créée et on retourne la même vue (back) mais cette fois on flashe une information en session (ce qui signifie qu’elle ne sera valable que pour la prochaine requête) avec with :

return back()->with('message', "La tâche a bien été créée !");

Dans la vue on vérifie s’il y a une information en session et si c’est le cas on l’affiche :

@if (session()->has('message'))
    <div class="alert alert-success" role="alert">
        {{ session('message') }}
    </div>
@endif

On trouve les données dans la table :

Par défaut l’état est à 0 (false). Remarquez aussi le renseignement automatique des deux dates.

Modifier une tâche

Le formulaire

Pour la modification d’une tâche on va avoir besoin d’un formulaire. On crée la vue edit :

Évidemment cette vue va beaucoup ressembler à celle de la création mais il va falloir renseigner les champ on va ajouter la possibilité de modifier l’état :

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Modification d'une tâche</div>
                <div class="card-body">
                    <form action="{{ route('tasks.update', $task->id) }}" method="post">
                        @csrf
                        @method('put')
                        @if (session()->has('message'))
                            <div class="alert alert-success" role="alert">
                                {{ session('message') }}
                            </div>
                        @endif
                        <div class="form-group">
                            <label for="title">Titre</label>
                            <input type="text" class="form-control @error('title') is-invalid @enderror" id="title" name="title" placeholder="Titre de la tâche" value="{{ old('title', $task->title) }}">
                            @error('title')
                                <div class="invalid-feedback">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="form-group">
                            <label for="description">Détail</label>
                            <textarea class="form-control @error('detail') is-invalid @enderror" id="detail" name="detail" placeholder="Détail de la tâche">{{ old('detail', $task->detail) }}</textarea>
                            @error('detail')
                                <div class="invalid-feedback">{{ $message }}</div>
                            @enderror
                        </div>
                        <div class="form-group">
                          <div class="form-check">
                            <input class="form-check-input" type="checkbox" value="" id="state" name="state" @if(old('state', $task->state)) checked @endif>
                            <label class="form-check-label" for="state">
                              Tâche accomplie
                            </label>
                          </div>
                        </div>
                        <button type="submit" class="btn btn-primary">Envoyer</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Dans la déclaration du formulaire on a changé l’url :

<form action="{{ route('tasks.update', $task->id) }}" method="post">

On précise la route et il faut ajouter l’identifiant de la tâche à modifier ($task->id). remarquez que la route attend une méthode PUT mais que là on déclare une méthode POST. C’est parce que les navigateurs gèrent encore très mal ce genre de méthode alors on déclare un POST mais après on précise qu’on veut un PUT :

@method('put')

Ca crée un champ caché qui va servir à Laravel pour savoir de quelle méthode il s’agit :

<input type="hidden" name="_method" value="put">

Pour le reste ça ne change pas beaucoup de la création sauf la case à cocher ajoutée.

Dans le contrôleur on appelle la vue :

public function edit(Task $task)
{
    return view('tasks.edit', compact('task'));
}

Remarquez le paramètre qui est du type du modèle Task. C’est une façon de dire à Laravel : le paramètre transmis est un nombre mais en fait c’est l’identifiant d’une instance de Task. Du coup Eloquent peut aller chercher dans la table la tâche correspondante. Il suffit ensuite de transmettre ça à la vue.

Maintenant avec une url de la forme todolist.oo/tasks/1/edit on atteint le formulaire.

La soumission

Pour modifier effectivement la tâche on va devoir gérer la soumission du formulaire dans la méthode update du contrôleur :

public function update(Request $request, Task $task)
{
    $data = $request->validate([
        'title' => 'required|max:100',
        'detail' => 'required|max:500',
    ]);

    $task->title = $request->title;
    $task->detail = $request->detail;
    $task->state = $request->has('state');
    $task->save();

    return back()->with('message', "La tâche a bien été modifiée !");        
}

On a la même validation que pour la création. D’ailleurs il faudrait pour bien faire mutualiser ce code pour éviter cette redondance qui n’est jamais une bonne chose (principe DRY). Laravel dispose d’une stratégie élégante pour la validation avec les Form Request, vous pouvez trouver les détails dans la documentation.

On met à jour les valeurs de la tâche. Pour la case à cocher il faut savoir qu’on ne retrouve une valeur que si elle est cochée. Donc on va vérifier si la valeur existe pour mettre à jour dans la table.

Voir une tâche

On va partir du principe qu’on aura un tableau avec juste le titre des tâches et pas le détail? Il faut donc prévoir de pouvoir afficher chaque tâche.

On crée la vue :

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Fiche d'une tâche</div>
                <div class="card-body">
                    <h4>Titre</h4>
                    <p>{{ $task->title }}</p>
                    <h4>Détail</h4>
                    <p>{{ $task->detail }}</p>
                    <h4>Etat</h4>
                    <p>
                      @if($task->state)
                        La tâche a été accomplie !
                      @else
                        La tâche n'a pas encore été accomplie.
                      @endif
                    </p>
                    <h4>Date de création</h4>
                    <p>{{ $task->created_at->format('d/m/Y') }}</p>
                    @if($task->created_at != $task->updated_at)
                      <h4>Dernière mise à jour</h4>
                      <p>{{ $task->updated_at->format('d/m/Y') }}</p>
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

On complète le contrôleur :

public function show(Task $task)
{
    return view('tasks.show', compact('task'));
}

Et avec une url de la forme todolist.oo/tasks/1 on affiche les éléments d’une tâche :

On affiche la date de mise à jour que si elle est différente de celle de la création.

Liste des tâches

Maintenant qu’on sait créer, modifier et afficher des tâches on va voir comment afficher en afficher la liste en prévoyant des boutons pour les différentes actions.

Au niveau du contrôleur on va récupérer toutes les tâches et les envoyer dans une vue :

public function index()
{
    $tasks = Task::all();

    return view('tasks.index', compact('tasks'));
}

Comme il n’y aura pas de très nombreuses tâches on ne prévoie pas de pagination mais Laravel sait très bien s’occuper de ça également.

On crée la vue :

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Liste des tâches
                  <a href="{{ route('tasks.create') }}" role="button" class="btn btn-primary btn-sm float-right">Créer une tâche</a>
                </div>
                <div class="card-body">
                    <table class="table table-borderless table-striped table-hover table-sm">
                      <thead>
                        <tr>
                          <th>#</th>
                          <th>Titre</th>
                          <th>Etat</th>
                          <th></th>
                          <th></th>
                          <th></th>
                        </tr>
                      </thead>
                      <tbody>
                        @foreach($tasks as $task)
                          <tr>
                            <td>{{ $task->id }}</td>
                            <td>{{ $task->title }}</td>
                            <td>@if($task->state) Accomplie @else A faire @endif</td>
                            <td><a href="{{ route('tasks.show', $task->id) }}" role="button" class="btn btn-primary btn-sm">Voir</a></td>
                            <td><a href="{{ route('tasks.edit', $task->id) }}" role="button" class="btn btn-warning btn-sm">Modifier</a></td>
                            <td><a role="button" class="btn btn-danger btn-sm"
                                onclick="event.preventDefault(); document.getElementById('destroy{{ $task->id }}').submit();">
                                Supprimer</a>
                            </td>
                            <form id="destroy{{ $task->id }}" action="{{ route('tasks.destroy', $task->id) }}" method="POST" style="display: none;">
                                @csrf
                                @method('DELETE')
                            </form>
                          </tr>
                        @endforeach
                      </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

On se retrouve avec un tableau des tâches et un bouton pour en créer une avec l’url todolist.oo/tasks :

Les boutons permettent d’accéder aux tâches qu’on a codé précédemment sauf la suppression. On va coder pour cela cette fonction dan sle contrôleur :

public function destroy(Task $task)
{
    $task->delete();
}

Je n’ai pas prévu de boîte de dialogue d’avertissement avant la suppression mais ça serait à ajouter dans une application réelle. Pour cette suppression j’ai prévu un formulaire caché pour chaque tâche et un peu de javascript pour la soumission. ce n’est évidemment pas la seule façon de faire mais ça ne concerne pas directement Laravel.

Organisation

Pour le moment l’url de base envoie sur la page par défaut de Laravel (vue welcome). d’autre part une fois qu’un utilisateur se connecte il est envoyé aussi sur une vue par défaut (sauf s’il est arrivé sur la page de connexion avec le middleware) :

Ce qu’on voudrait c’est que si l’utilisateur est conecté il arrive sur la liste des tâches et sinon sur la page de connexion.

Dans le fichier des routes (routes/web.php) on va changer le code ainsi :

Auth::routes();

Route::middleware('auth')->group(function () {
  Route::get('/', 'TaskController@index')->name('home');
  Route::resource('tasks', 'TaskController');
});

Maintenant les vues welcome et home peuvent être supprimées, elles ne sont plus appelées.

Les tests

Laravel permet de faire facilement de tests. Il utilise PHPUnit et on trouve par défaut le fichier de configuration phpunit.xml à la racine. Par défaut la base de donnée est du sqlite en mémoire :

<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>

Les fichiers de test se trouvent dans le dossier tests :

Supprimez le fichier Unit/ExampleTest.php. Il ne reste donc plus que Feature/ExampleTest.php. Lancez les tests :

php artisan test
   FAIL  Tests\Feature\ExampleTest
  ✕ basic test

  Tests:  1 failed

  Expected status code 200 but received 302. Failed asserting that 200 is identical to 302.

Regardons le code du test :

class ExampleTest extends TestCase
{
    public function testBasicTest()
    {
        $response = $this->get('/');
        $response->assertStatus(200);
    }
}

On ouvre la page d’accueil et on attend un code 200 et on se retrouve avec une redirection (302). Or on sait qu’un utilisateur doit être connecté pour ouvrir la page, donc il est logique d’avoir une redirection. On va changer le test :

$response->assertStatus(302);

Maintenant c’est bon !

Mais comment faire pour avoir la page pour un utilisateur connecté ? Il faut créer la base, créer un utilisateur, le connecter… Avec Laravel c’est facile, changez ainsi le code :

class ExampleTest extends TestCase
{
    use RefreshDatabase;
    
    public function testBasicTest()
    {
        $user = factory(\App\User::class)->create();
        $response = $this->actingAs($user)->get('/');
        $response->assertStatus(200);
    }
}

Cette fois on a bien un code 200 avec un utilisateur connecté !

On ne va pas tester toute l’application mais par exemple la création d’une tâche. On crée d’abord la classe de test :

php artisan make:test CreateTaskTest

On va prévoir cette fonction dans la classe :

class CreateTaskTest extends TestCase
{
    use RefreshDatabase;

    public function test_auth_can_create_task()
    {
        $user = factory(\App\User::class)->create();

        $response = $this->actingAs($user)->post('/tasks', [
            'title' => 'Ma nouvelle tâche',
            'detail' => 'Tous les détails de ma nouvelle tâche',
        ]);

        $this->assertDatabaseHas('tasks', [
            'title' => 'Ma nouvelle tâche'
        ]);

        $this->get('/')
             ->assertSee('Ma nouvelle tâche');
    }
}

 

On fait les tests suivants :

  • un utilisateur authentifié soumet le fomulaire
  • la tâche est bien dans la table
  • on trouve la tâche dans la liste des tâches

On peut tester ainsi tous les aspects de l’application, je vous renvoie à la documentation détaillée pour tous les détails.

Conclusion

J’espère que ce petit exemple pourra donner envie de découvrir ce framework. Il est à la fois très chargé pour un débutant et frustrant pour quelqu’un de plus avancé mais son seul objectif est de permettre la découverte de Laravel au travers d’un exemple léger mais réaliste.

 

 

 

Print Friendly, PDF & Email

5 commentaires

  • eelisland

    Hello Maumau,

    Ce cours pouvait pas mieux tomber. Je fais pour le plaisir d’apprendre un site avec php, ajax, mysql, css sans framework depuis 2017 pour mes proches, j’y travail puis j’y reviens etc…
    J’utilise le module mod_auth_basic d’apache et je cherche un moyen d’ajouter un système d’authentification, après des recherches plus ou moins laborieuse je me suis finalement dirigé vers Laravel et bim https://laravel.sillo.org/ !
    Excellent ton site, merci beaucoup.

    j’ai lu que tu allais poster des nouveaux cours en septembre, alors je me permet de partager quelques une des choses qui sont dans ma liste de recherche:

    – J’ai des class, des tables, du javascript du css que j’ai écris et que je souhaite ajouter à Laravel, j’ai notament des class pour récupérer des informations d’un api en ligne type Wikimedia pour peupler mes tables, quelle est la meilleur approche pour intégrer tout ça à Laravel.

    – Et pour mes amis Anglais, j’ai mon fichier fr.json peuplé par le plugin by BestMomo, excellent, me reste plus qu’a créer la partie frontend pour sélectionner la langue et en faire une préférence de l’espace utisateur.

    – L’installation de base de Laravel semble sécurisé, mais ça mérite quand même de faire un point et de la comprendre, j’ai commencé à passer en revue le fichier config/session.php, c’est un tout petit début j’imagine.

    – Comment maintenir les mises à jour et patchs de sécurité de Laravel sur le long terme, avoir une vue d’ensemble de l’arborescence, de ce qui serait écrasé par une mise à jour, quelles sont les bonnes pratiques, ou tout simplement est-ce que toute cette partie est à la charge de l’admin.

    – J’utilise Apache, j’ai bien bossé sur mon fichier httpd.conf, mais moins sur mon php.ini et conf mysql, comment activer la compréssion des css, optimiser pour une meilleur expérience utilisateur, mais la je suis complètement hors sujet « Laravel ».

    Bon je vous laisse j’ai des cours à suivre 😉

    P.s: j’ai désactivé mon ad-block, même pas une petite banière de pub discrète pour payer les cafés ? Tu pousse le bouchon un peu loin… =))

    • bestmomo

      Salut,
      Ça en fait des choses ça 🙂
      Pour intégrer du code existant dans Laravel on peut adopter plusieurs démarches :

      – Pour les classes PHP existantes le plus simple est de créer un dossier App\Services et de tout mettre dedans
      – Si le code PHP et volumineux autant créer un package
      – Pour le Javascript et le CSS c’est une autre histoire, tout dépend du choix fait au niveau du préprocesseur et des librairies Javascript utilisées (ou pas)

      Pour la gestion des langues dans le frontend j’ai traité ça dans mon exemple d’album photo en ligne. Mais ça serait peut-être bien d’y consacrer un article spécifique.
      Pour la sécurité de Laravel j’ai évoqué ça dans mon cours sur Laravel 6.
      Pour l’installation, le déploiement et le maintien en forme de Laravel c’est aussi un sujet qui mérite à être développé.
      Sinon effectivement je n’ai mis aucun mouchard ni aucune publicité visible ou cachée sur mon blog, tant pis, je me paye mes cafés 😉

  • phildid

    Bonjour,
    cette première appli est très sympa, j’avoue que je n’aurais rien compris ici si je n’avais pas suivi le Laraguide de Thibaud Dauce sur YouTube (https://youtu.be/BQo-3ohwL5Y) . J’aurais quelques petites précisions et conseils à vous demander SVP .
    Je suis un quasi débutant avec Laravel. J’ai appris les bases de php au temps de php3/4, ainsi que MySql et utilisé à cette époque pas mal de CMS. C’est dire que je ne suis pas tout jeune. je me suis tjrs intéressé à la programmation internet sans être un professionnel, en fait je suis assistant éduc dans une école primaire. j’ai un peu travaillé la prog avec des gamins en particulier avec scratch. je connais le HTML5 et la css . je suis nul n javascript. j’avais déjà vu votre page mais c’était du chinois. à l’époque…
    Dernièrement, pendant le confinement j’ai décidé de m’y remettre en reprenant bootstrap et des framework css et puis je me suis intéressé d’un coup au MCV et du coup je suis tombé sur Laravel depuis je m’accroche aux branches.
    Je vois que vos tutos sont assez récents. Voyez-vous j’ai trouvé celui-ci très bien, mais comme vous le dites vous-même on peut pas tout voir en même temps.
    Comment vous dire, ce que je souhaiterais au final, depuis que pour la premiére fois je me suis offert un hebergement payant. C’est installer Laravel sur mon hébergement et construire un projet par étape car Laravel c’est assez lourd et cela ne vaut pas le coup de le mettre sur un serveur si on ne sait pas vraiment ou l’on va ou juste pour tester ceci ou cela
    L’idée en gros : Je veux commencer par une authentification complète, ajouter un petit blog, des petites applis diverses et variées sur une base de donnée), tout dans le même projet en évoluant au fur et à mesure, je ne suis pas pressé. (je suis un peu long…milles excuses)

    Mais voilà je m’aperçois que dans les tutos + ou – récents, que chaque projet est différent et qu’il y pas mal de manières de faire, d’utilisation; du coup je voudrais pas trop me perdre.
    Par exemple dans cette appli (et c’est bien compréhensible) le package est complet mais après register on tombe sur une 404, c’est normal on n’a pas la confirmation du mail d’enregistrement. Il y a aussi que cela aurait été intéressant d’avoir une tâche par user.
    Bon j’ai déjà vu 50 vidéos chez Thibaud Dauce…bla bla bla on peut pas tout avoir d’un coup, Laravel c’est énorme…

    Du coup je suis là, que me conseillez vous de voir sur votre site pour bien démarrer et espérer accrocher les wagons petit à petit, sans repasser par les bases. Peut être de commencer le tuto: ( Cours Laravel 6 –les données – l’authentification. Je vois qu’elle a l’air complète) Ce qui me plairait pour progresser c’est que les choses s’emboitent, je ne sais pas si je me fais bien comprendre, excusez-moi. En tout cas merci pour votre travail et de m’avoir lu jusque là.

    Phildid

    • bestmomo

      Bonsoir !

      Moi aussi je ne suis plus très jeune et quand j’ai commencé PHP c’était la version 3, à l’époque on n’utilisait pas encore le CSS et Javascript était très limité. Tout ça a bien changé depuis !

      Il me semble que ce qui serait le plus productif serait de partir sur un projet spécifique, quel qu’il soit, mais assez complet, et le construire peu à peu.

      J’ai proposé sur mon blog quelques exemples assez complets (un album photo, un site d’annonces, et récemment une boutique en ligne). Il peut aussi être intéressant de regarder un de ces projets pour avoir une méthodologie.

      En tout cas merci pour le retour !

      Maurice

Leave a Reply