IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel pour apprendre à utiliser le framework Laravel 4


précédentsommairesuivant

XVIII. Chapitre 18 : Un blog : les données

Il est temps d'utiliser tout ce que nous avons vu dans une application pratique. Il est habituel de présenter un blog dans ce genre de situation, d'une part parce que c'est une application qui permet de brasser pas mal de fonctionnalités, et d'autre part parce que c'est quelque chose de très utile.

Article mis à jour pour la version 4.1.26 de Laravel.

XVIII-A. Installer et configurer Laravel

Nous n'allons pas faire quelque chose de très complexe mais de suffisamment structuré pour être significatif. La première chose à faire est d'installer et de configurer Laravel. Nous avons déjà vu comment on fait cela dans les chapitres 2Chapitre 2 : Installation et 3Chapitre 3 : Architecture et configuration. Je pars donc du principe que vous avez une installation toute neuve de Laravel dans un dossier nommé blog auquel on accède avec cet URL : http://localhost/blog/public.

XVIII-A-1. La base de données

La structuration des données constitue la colonne vertébrale d'une application. Nous allons donc nous attarder sur ce point. Nous avons besoin pour notre blog de quatre tables : une pour les utilisateurs, une pour les catégories d'articles, une pour les articles et enfin une dernière pour les commentaires. Le but est de bâtir cette configuration :

Image non disponible

Voyons de plus près chacune des tables :

  • users : nous avons déjà eu affaire à cette table dans le chapitre sur l'authentificationChapitre 15 : Les bases de données 3/3. J'ai juste prévu en plus un champ pour l'email et un autre pour le statut de l'utilisateur, qui est soit administrateur (qui peut créer des articles et gérer le site), soit simple intervenant (qui peut commenter des articles). Les champs created_at et updated_at sont gérés automatiquement par Laravel, on les retrouve dans toutes les tables. Le pseudo et l'email doivent être uniques.
  • categories : ici j'ai prévu un titre et une description.
  • articles : c'est la table forcément la plus chargée, on trouve un titre, un texte d'introduction intro_text (qui apparaîtra sur la page de la catégorie), un texte de contenu de l'article full_text (qui apparaîtra quand on sélectionnera l'article). J'ai aussi prévu un champ allow_comment pour signaler si on peut ou non commenter l'article. On trouve aussi deux clés étrangères, une qui référence l'utilisateur qui a écrit l'article user_id et une autre qui référence la catégorie categorie_id. Je pars du principe qu'on utilise MySQL avec InnoDB.
  • comments : cette table accueillera les commentaires. Là j'ai prévu juste un titre et un champ pour le texte. On trouve aussi deux clés étrangères : une qui référence l'utilisateur qui a écrit le commentaire user_id et une autre qui référence l'article concerné article_id.
  • password_reminders : cette table sert pour la réinitialisation du mot de passe.

XVIII-A-2. Créer une migration

On va encore utiliser l'outil de migration pour créer ces tables (vous n'êtes évidemment pas obligé de l'utiliser). Commencez par créer une base nommée blog dans MySQL (si vous utilisez un autre serveur ce qui suit reste évidemment valable, par contre il faudra peut-être adapter certains types de données dans les tables). Ensuite créez une migration :

Image non disponible

Maintenant installez cette migration :

Image non disponible

Vous devez avoir une table migrations dans votre base :

Image non disponible

XVIII-A-3. Le schéma des tables

Dans le dossier app/database/migrations vous devez avoir un fichier avec ce code :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreateBlog extends Migration {
 
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        //
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
 
}

Il ne nous reste plus qu'à écrire le reste. Nous avons déjà vu ça au chapitre 133Chapitre 12 : Les formulaires. Mais à présent voyons un cas plus réaliste et complet. Voici le code :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreateBlog extends Migration {
 
    public function up()
    {
        Schema::create('users', function($table) {
            $table->increments('id')->unsigned();
            $table->string('username', 64)->unique();
            $table->string('password', 64);
            $table->string('email', 64)->unique();
            $table->enum('statut', array('user', 'admin'))->default('user');
            $table->string('remember_token', 100)->nullable();
            $table->timestamps();
        });
        Schema::create('categories', function($table) {
            $table->increments('id')->unsigned();
            $table->string('title', 128)->unique();
            $table->text('description')->nullable();
            $table->timestamps();
        });
        Schema::create('articles', function($table) {
            $table->increments('id')->unsigned();
            $table->string('title', 128);
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
            $table->integer('categorie_id')->unsigned();
            $table->foreign('categorie_id')->references('id')->on('categories')->onDelete('cascade')->onUpdate('cascade');
            $table->text('intro_text');
            $table->text('full_text');
            $table->enum('allow_comment', array('no', 'yes'))->default('yes');
            $table->timestamps();
        });
        Schema::create('comments', function($table) {
            $table->increments('id')->unsigned();
            $table->string('title', 128);
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
            $table->integer('article_id')->unsigned();
            $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade')->onUpdate('cascade');
            $table->text('text');
            $table->timestamps();
        });
    }
 
    public function down()
    {   
        Schema::table('articles', function($table) {
            $table->dropForeign('articles_categorie_id_foreign');
            $table->dropForeign('articles_user_id_foreign');
        });
        Schema::table('comments', function($table) {
            $table->dropForeign('comments_user_id_foreign');
            $table->dropForeign('comments_article_id_foreign');
        });
        Schema::drop('categories');     
        Schema::drop('users');
        Schema::drop('comments');       
        Schema::drop('articles');
    }
 
}

Il ne reste plus qu'à lancer la migration :

Image non disponible

Vous devez avoir vos tables dans la base :

Image non disponible

Pour le détail de la syntaxe du schéma vous pouvez consulter la documentation. Remarquez aussi que pour la suppression des tables, j'ai commencé par supprimer les clés étrangères pour éviter de rencontrer des erreurs dans MySQL.

XVIII-A-4. Des données

Nous allons avoir besoin de quelques données pour tester notre site. Nous allons utiliser une fonctionnalité déjà vueChapitre 12 : Les formulaires avec les seeds. Il faut créer un fichier par table, en donnant à chacun un nom judicieux et les placer dans le dossier app/database/seeds. Pour la table users on aura donc le fichier UserTableSeeder.php :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
<?php
class UserTableSeeder extends Seeder {
 
    public function run()
    {
        DB::table('users')->insert(
 
            array(
                array(
                    'id' => 1,
                    'username' => 'admin',
                    'password' => Hash::make('admin'),
                    'email' => 'admin@plop.fr',
                    'statut' => 'admin',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime,
                ),
 
                array(
                    'id' => 2,
                    'username' => 'Dupont',
                    'password' => Hash::make('dupont'),
                    'email' => 'dupont@plop.fr',
                    'statut' => 'user',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime,
                ),
 
                array(
                    'id' => 3,
                    'username' => 'Durand',
                    'password' => Hash::make('durand'),
                    'email' => 'durand@plop.fr',
                    'statut' => 'user',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime,
                )
            )
        );
    }
}

Ici on crée trois utilisateurs dont un administrateur. On crée aussi un fichier CategorieTableSeeder.php pour les catégories :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
<?php
 
class CategorieTableSeeder extends Seeder {
 
    public function run()
    {
        DB::table('categories')->insert(
 
            array (
                array(
                    'id' => 1,
                    'title' => 'Catégorie 1',
                    'description' => 'blablabla',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime
                ),
                array(
                    'id' => 2,
                    'title' => 'Catégorie 2',
                    'description' => 'blablabla',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime
                ),
                array(
                    'id' => 3,
                    'title' => 'Catégorie 3',
                    'description' => 'blablabla',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime
                ),
                array(
                    'id' => 4,
                    'title' => 'Catégorie 4',
                    'description' => 'blablabla',
                    'created_at' => new DateTime,
                    'updated_at' => new DateTime
                )
            )
        );
    }
 
}

On crée aussi un fichier ArticleTableSeeder.php pour les articles :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
<?php
 
class ArticleTableSeeder extends Seeder {
 
    public function run()
    {
        DB::table('articles')->insert(
 
            array (
                array(
                    'id' => 1,
                    'title' => 'Article 1',
                    'user_id' => '1',
                    'categorie_id' => '1',
                    'intro_text' => 'Intro 1',
                    'full_text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 2,
                    'title' => 'Article 2',
                    'user_id' => '1',
                    'categorie_id' => '1',
                    'intro_text' => 'Intro 2',
                    'full_text' => 'blablabla',
                    'created_at' => '2013-02-02 00:00:00',
                    'updated_at' => '2013-02-02 00:00:00'
                ),
                array(
                    'id' => 3,
                    'title' => 'Article 3',
                    'user_id' => '1',
                    'categorie_id' => '2',
                    'intro_text' => 'Intro 3',
                    'full_text' => 'blablabla',
                    'created_at' => '2013-02-06 00:00:00',
                    'updated_at' => '2013-02-06 00:00:00'
                ),
                array(
                    'id' => 4,
                    'title' => 'Article 4',
                    'user_id' => '1',
                    'categorie_id' => '2',
                    'intro_text' => 'Intro 4',
                    'full_text' => 'blablabla',
                    'created_at' => '2013-02-05 00:00:00',
                    'updated_at' => '2013-02-05 00:00:00'
                ),
                array(
                    'id' => 5,
                    'title' => 'Article 5',
                    'user_id' => '1',
                    'categorie_id' => '3',
                    'intro_text' => 'Intro 5',
                    'full_text' => 'blablabla',
                    'created_at' => '2013-01-01 00:00:00',
                    'updated_at' => '2013-01-01 00:00:00'
                ),
                array(
                    'id' => 6,
                    'title' => 'Article 6',
                    'user_id' => '1',
                    'categorie_id' => '4',
                    'intro_text' => 'Intro 6',
                    'full_text' => 'blablabla',
                    'created_at' => '2013-02-04 00:00:00',
                    'updated_at' => '2013-02-04 00:00:00'
                )
            )
 
        );
    }
 
}

Et on crée un dernier pour les commentaires CommentTableSeeder.php :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
<?php
 
class CommentTableSeeder extends Seeder {
 
    public function run()
    {
        DB::table('comments')->insert(
 
            array(
                array(
                    'id' => 1,
                    'title' => 'Commentaire 1',
                    'user_id' => '2',
                    'article_id' => '1',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 2,
                    'title' => 'Commentaire 2',
                    'user_id' => '2',
                    'article_id' => '1',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 3,
                    'title' => 'Commentaire 3',
                    'user_id' => '3',
                    'article_id' => '3',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 4,
                    'title' => 'Commentaire 4',
                    'user_id' => '2',
                    'article_id' => '4',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 5,
                    'title' => 'Commentaire 5',
                    'user_id' => '3',
                    'article_id' => '4',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 6,
                    'title' => 'Commentaire 6',
                    'user_id' => '3',
                    'article_id' => '5',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                ),
                array(
                    'id' => 7,
                    'title' => 'Commentaire 7',
                    'user_id' => '2',
                    'article_id' => '1',
                    'text' => 'blablabla',
                    'created_at' => '2013-02-01 00:00:00',
                    'updated_at' => '2013-02-01 00:00:00'
                )
            )
        );
    }
 
}

Et il faut renseigner le fichier DatabaseSeeder.php en appelant nos classes dans le bon ordre pour ne pas rencontrer des exceptions de la part de MySQL :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?php
 
class DatabaseSeeder extends Seeder {
 
    public function run()
    {
        $this->call('UserTableSeeder');
        $this->call('CategorieTableSeeder');
        $this->call('ArticleTableSeeder');
        $this->call('CommentTableSeeder');
    }
 
}

Il ne reste plus qu'à utiliser Artisan :

Image non disponible

XVIII-A-5. Les modèles

Nous avons vu en étudiant l'authentificationChapitre 15 : Les bases de données 3/3 que Laravel possède déjà un modèle pour les utilisateurs. Il nous faut compléter ce modèle pour faire fonctionner nos relations. Voici donc le fichier app/models/User complété :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
<?php
 
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
 
class User extends Eloquent implements UserInterface, RemindableInterface {
 
    protected $table = 'users';
 
    protected $hidden = array('password');
 
    public function getAuthIdentifier()
    {
        return $this->getKey();
    }
 
    public function getAuthPassword()
    {
        return $this->password;
    }
 
    public function getRememberToken()
    {
        return $this->remember_token;
    }
 
    public function setRememberToken($value)
    {
        $this->remember_token = $value;
    }
 
    public function getRememberTokenName()
    {
        return 'remember_token';
    }
 
    public function getReminderEmail()
    {
        return $this->email;
    }
 
    public function articles()
    {
        return $this->hasMany('Article');
    }
 
    public function comments()
    {
        return $this->hasMany('Comment');
    }
 
}

Nous avons également besoin d'un modèle pour les catégories (app/models/Categorie) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
class Categorie extends Eloquent {
 
    public function articles()
    {
        return $this->hasMany('Article');
    }
}

Un autre pour les articles (app/models/Article) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class Article extends Eloquent {
 
    public function comments()
    {
        return $this->hasMany('Comment');
    }
 
    public function categorie()
    {
        return $this->belongsTo('Categorie');
    }
 
    public function user()
    {
        return $this->belongsTo('User');
    }
}

Et un dernier modèle pour les commentaires (app/models/Comment) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class Comment extends Eloquent {
 
    public function article()
    {
        return $this->belongsTo('Article');
    }
 
    public function user()
    {
        return $this->belongsTo('User');
    }
}

XVIII-B. Migration pour l'authentification

On peut créer automatiquement une migration en utilisant Artisan :

Image non disponible

Ce qui a pour effet de créer la migration :

Image non disponible

Avec ce code :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
<?php
 
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreatePasswordRemindersTable extends Migration {
 
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('password_reminders', function(Blueprint $table)
        {
            $table->string('email')->index();
            $table->string('token')->index();
            $table->timestamp('created_at');
        });
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('password_reminders');
    }
 
}

Il nous faut finalement lancer la migration pour créer cette table dans la base :

Image non disponible
Image non disponible

Nous avons à présent tout ce qui nous est nécessaire pour stocker et manipuler les données. La prochaine étape sera de définir l'aspect du blog.


précédentsommairesuivant

Copyright © 2017 Laravel. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.