Créer un forum avec le mkframework

Linux Pratique n° 090 | juillet 2015 | Michaël Bertocchi
Creative Commons
  • Actuellement 5 sur 5 étoiles
5
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
Vous allez découvrir ici un framework simple et productif en développant un mini forum.

Introduction

Le mkframework est un framework PHP sous licence LGPLv3, il se distingue des autres sur plusieurs points :

- il est rétrocompatible depuis 2009 ;

- il utilise une interface web plutôt que la ligne de commandes ;

- il est orienté sécurité.

Dans cet article, nous allons voir comment développer facilement un mini forum avec celui-ci. Vous pourrez apprécier son générateur web qui vous fera gagner un temps précieux.

1. L'application

Le mini forum que nous allons développer ici permettra de s'inscrire, d'ouvrir de nouvelles discussions et enfin de poster des réponses.

Pour cela, nous utiliserons une base MySQL. Commencez par exécuter la requête SQL suivante :

CREATE TABLE `topics` (

`id` int(11) NOT NULL auto_increment,

`titre` varchar(50) NOT NULL,

`texte` text NOT NULL,

`user_id` int(11) NOT NULL,

PRIMARY KEY  (`id`)

);

 

CREATE TABLE `posts` (

`id` int(11) NOT NULL auto_increment,

`texte` text NOT NULL,

`user_id` int(11) NOT NULL,

`topic_id` int(11) NOT NULL,

PRIMARY KEY  (`id`)

);

 

CREATE TABLE `users` (

`id` int(11) NOT NULL auto_increment,

`login` varchar(50) NOT NULL,

`mdp` varchar(50) NOT NULL,

PRIMARY KEY  (`id`)

);

Ici, nous avons trois tables : une première topics qui contiendra les discussions, une table posts qui contiendra les réponses et enfin user pour les utilisateurs de l'application.

2. Installons le framework

Rendez-vous à l'adresse http://mkframework.com, dirigez-vous sur la page de téléchargement et téléchargez la dernière archive. Désarchivez celle-ci dans le répertoire web de votre ordinateur (par exemple /var/www).

On partira du principe que le framework est installé dans le répertoire /var/www/mkframework.

Donnez les droits d'écriture au répertoire data/genere :

cd /var/www/mkframework

chmod 777 data/genere

Ouvrez votre navigateur à l'adresse http://localhost/mkframework.

Vous voyez le générateur web, aussi appelé le « builder ». En effet, lorsque vous téléchargez le framework, vous téléchargez le framework ainsi que son générateur web.

3. Codons notre application

Étape 1 : Créons l'application

Entrez dans le champ de saisie le nom de l'application, par exemple « forumLinuxPratique », puis validez avec le bouton Créer.

Le builder va créer une application vide dans le répertoire data/genere avec l'arborescence visible sur la Figure 1.

Figure 1

Étape 2 : Connectons l'application à notre base de données

Éditez le fichier conf/connexion.ini.php.

Vous voyez plusieurs exemples de profils de connexion, ici nous allons reprendre un profil de connexion MySQL via pdo comme suit :

;<?php die()?>

[db]

forum.dsn="mysql:dbname=forumDb;host=localhost"

forum.sgbd=pdo_mysql

forum.username=root

forum.password=root

Étape 3 : Générons la couche modèle

Le framework s'appuie sur une architecture MVC, il utilise un ORM pour interagir avec la base de données : nous avons donc besoin de classes model pour lier nos trois tables.

Cliquez sur le lien Créer la couche modèle, le builder va se connecter à notre base MySQL et lister les tables disponibles. Cochez-les toutes et validez.

Trois classes modèles vont être créées dans le répertoire model/ de votre application : model_topics.php, model_posts.php et model_users.php.

Quelques définitions

MVC (Model View Controller) : séparation entre « model », la couche modèle interagissant avec les données, « view », l'affichage et la mise en forme du contenu et « controller », le chef d'orchestre organisant l'ensemble.

ORM (Object Relation Mapping) : méthode consistant à interagir avec les données via des objets.

Étape 4 : Créons notre premier CRUD pour les topics

Dans un forum, on peut voir listées les différentes discussions. Nous allons demander au builder de nous générer un tableau listant les topics ainsi qu'un formulaire pour en ajouter.

Cliquez sur Créer un module CRUD. Sélectionnez la classe model_topics.php.

Le builder vous permet de choisir les actions qui seront générées sur le module : par défaut, les 4 lettres du CRUD (Create : ajout, Read : affichage/listage, Update : modification, Delete : suppression).

Décochez les cases de modification et de suppression, ici on permettra juste d'ajouter un topic et de visualiser ses réponses : on ne permettra pas que l'auteur puisse modifier le sujet de la discussion (après d'éventuelles réponses qui perdraient de leur cohérence si on changeait a posteriori le sujet).

Validez le formulaire visible en Figure 2, le builder vous liste les fichiers et répertoires qu'il vient de générer.

Figure 2

Il vous affiche également un lien vous permettant de voir (si besoin) le module en question. En cliquant dessus, on peut voir le tableau de listage des éléments (Figure 3), ainsi que le formulaire d'ajout (Figure 4).

Figure 3

Figure 4

Étape 5 : Ajoutons un module d'authentification

Pour accéder et répondre au forum, nous allons demander à l'utilisateur de s'authentifier : pour cela, nous avons besoin d'un formulaire d'inscription ainsi qu'un formulaire de login.

Ici encore, le builder va nous faire gagner du temps : cliquez sur Créer un module d'authentification avec inscription.

Un formulaire s'affiche (Figure 5), un menu déroulant apparaît pour sélectionner la classe modèle des utilisateurs, sélectionnez model_users.php.

Sélectionnez ensuite le champ de login « login » et de mot de passe « mdp », le générateur vous affiche un message vous invitant à copier deux méthodes dans votre classe model.

Figure 5

Le générateur vous indique non seulement quelle classe model modifier, mais il vous affiche également un lien permettant d'y accéder via « l'explorateur de projet ».

En cliquant dessus, vous pourrez donc plus facilement ajouter ces deux méthodes (Figure 6).

Figure 6

Il vous suffit alors de cliquer sur le lien Éditer en fin de classe model pour y coller les deux méthodes demandées.

Cliquez ensuite sur le bouton Réactualiser la page. La page change pour vous indiquer quelle classe model sera utilisée, ainsi que le nom du module qui sera créé.

Modifiez le module vers lequel on sera redirigé après authentification par Module topics action list afin qu'au login, l'utilisateur arrive sur la liste des topics. Validez.

Le builder vous indique les fichiers/répertoires créés et vous demande de modifier un paramètre de votre application.

Comme précédemment, un lien vous permet d'accéder directement au fichier via l'explorateur du projet : cliquez dessus.

Et comme indiqué, modifiez, dans la section [auth] la variable « enabled » à 1 (Figure 7).

Figure 7

Désormais, si vous cliquez sur Voir le site, vous êtes automatiquement redirigé vers la page d'authentification (Figure 8). Il vous faut désormais vous identifier pour continuer sur le site.

Figure 8

Cliquez sur le lien S'inscrire, créez un compte et identifiez-vous.

Vous arrivez sur la page « list » du module « topics » comme indiqué précédemment dans le formulaire.

Étape 6 : Rendre l'auteur propriétaire des topics

En l'état, si vous ajoutez un topic, il n'aura pas d'auteur, on souhaiterait au contraire qu'il soit enregistré automatiquement avec l'ID de l'utilisateur connecté.

Pour cela, on va modifier notre module topics. Éditez le fichier module/topics/main.php.

Modifiez la méthode processSave() pour ajouter le code pour forcer l'utilisateur à l'enregistrement d'un nouveau topic.

private function processSave(){

             if(!_root::getRequest()->isPost() ){ //si ce n'est pas une requete POST on ne soumet pas

                   return null;

             }

 

             (...)

 

             $iId=_root::getParam('id',null);

             if($iId==null){

                   $oTopics=new row_topics;

                   //on force l'utilisateur

                   $oTopics->user_id=_root::getAuth()->getAccount()->id;

             }else{

                   $oTopics=model_topics::getInstance()->findById( _root::getParam('id',null) );

}

Ajoutez un topic de test et validez.

Nous allons afficher dans ce tableau le nom de l'auteur du topic, pour cela nous allons modifier la requête récupérant les topics.

Éditez le fichier model/model_topics.php, méthode findAll pour ajouter une jointure récupérant l'utilisateur :

public function findAll(){

             return $this->findMany('SELECT topics.*,users.login FROM '.$this->sTable.'

INNER JOIN users ON users.id=topics.user_id');

      }

Modifiez ensuite la vue module/topics/view/list.php pour ajouter le nom de l'auteur (champ « login ») :

<?php foreach($this->tTopics as $oTopics):?>

                    <tr <?php echo plugin_tpl::alternate(array('','class="alt"'))?>>

                           <td><?php echo $oTopics->titre ?></td>

                           <td><?php echo $oTopics->texte ?></td>

                           <td><?php echo $oTopics->login ?></td>

                    </tr>

             <?php endforeach;?>

Désormais, si vous créez un autre compte et ajoutez un topic, vous verrez le nom de l'auteur s'enregistrer.

Nous allons maintenant permettre d'entrer dans une discussion pour y poster un commentaire.

Mais pour cela, il nous faudrait d'abord améliorer la requête de récupération du topic affiché. Éditez le fichier model/model_topics.php et modifiez la méthode findById() ainsi :

public function findById($uId){

             return $this->findOne('SELECT topics.*,users.login FROM '.$this->sTable.' INNER JOIN users ON users.id=topics.user_id WHERE topics.id=?',$uId );

      }

Ainsi, on va récupérer les champs du topic ainsi que le nom de son auteur.

Modifiez le code HTML pour avoir un affichage plus proche d'un forum :

Ajoutez ce bloc CSS public/css/main.css :

.tb_post{

border:1px solid #444;

background:#eee;

}

.tb_post .login{

float:left;

width:150px;

padding:10px;

color:#444;

}

.tb_post .login h2{

margin:0px;

}

.tb_post .text{

float:right;

width:400px;

padding:10px;

background:#fff;

}

.clear{

clear:both;

}

.answer{

text-align:right;

}

.answer a{

float:right;

background:#444;

padding:4px 10px;

color:white;

text-decoration:none;

}

Pour la vue topics/view/show.php (Figure 9) :

Figure 9

<div class="tb_post">

       <div class="login"><h2><?php echo $this->oTopics->login ?></h2></div>

       <div class="text">

              <h2><?php echo $this->oTopics->titre ?></h2>

              <?php echo $this->oTopics->texte ?>

       </div>

       <div class="clear"></div>

</div>

 

<p>

       <a href="<?php echo $this->getLink('topics::list')?>">Retour</a>

</p>

Et pour la vue topics/view/list.php :

<?php if($this->tTopics):?>

      <?php foreach($this->tTopics as $oTopics):?>

                   <div class="tb_post">

                         <div class="login"><h2><?php echo $oTopics->login ?></h2></div>

                         <div class="text">

                                <h2><a href="<?php echo $this->getLink('topics::show',array('id'=>$oTopics->id)) ?>"><?php echo $oTopics->titre ?></a></h2>

                                <?php echo $oTopics->texte ?>

                         </div>

                         <div class="clear"></div>

                   </div>

      <?php endforeach;?>

<?php else:?>

      <p>Aucune ligne</p>

<?php endif;?>

 

<p class="answer"><a href="<?php echo $this->getLink('topics::new') ?>">Nouvelle discussion</a></p>

Notez le lien vers l'affichage de la discussion sur le titre de la discussion (Figure 10).

Figure 10

Étape 7 : Permettre d'ajouter des posts sur des discussions

Dans un forum, on crée des discussions, puis les autres utilisateurs viennent échanger des posts sur celles-ci.

Pour permettre ceci sur notre application, nous allons utiliser les modules embarqués : ce sont des modules (comme le précédent « topics »), mais qui retournent leur vue plutôt que les ajouter au layout.

Nous allons simplement les générer avec le builder. Cliquez sur Créer un module CRUD intégrable, sélectionnez la classe modèle model_posts.php.

Comme précédemment avec le module topics, vous êtes face à un formulaire, décochez l'action de suppression et d'affichage du détail.

Concernant les champs, décochez les champs user_id et topic_id, sélectionnez textarea pour le champ texte et enfin générez.

Le builder vous affiche un exemple de code pour inclure ce module intégrable dans un autre (Figure 11).

Figure 11

Nous voulons qu'en cliquant sur une discussion on voit la discussion ainsi que ses posts.

Éditez le module topics, action show() :

public function _show(){

             $oTopics=model_topics::getInstance()->findById( _root::getParam('id') );

 

             $oView=new _view('topics::show');

             $oView->oTopics=$oTopics;

 

 

             $this->oLayout->add('main',$oView);

       }

Actuellement, on récupère l'enregistrement du topic via son ID, on instancie une vue (fichier module/topic/view/show.php), on lui assigne l'objet topic, puis on ajoute la vue à notre layout à l'emplacement main.

On va ajouter ensuite notre module intégrable « posts » en récupérant le code du builder, mais en lui précisant l'adresse à laquelle on se trouve :

public function _show(){

             $oTopics=model_topics::getInstance()->findById( _root::getParam('id') );

 

             $oView=new _view('topics::show');

             $oView->oTopics=$oTopics;

 

             $this->oLayout->add('main',$oView);

 

             //instancier le module

             $oModulePosts=new module_posts();

 

             //si vous souhaitez indiquer au module integrable des informations sur le module parent

             //on indique ici les variables de contexte:

             //on est dans le module topics, action show, et on a le parametre id du topic dans l'url

             $oModulePosts->setRootLink('topics::show',array('id'=>_root::getParam('id')));

 

             //recupere la vue du module

             $oViewModule=$oModulePosts->_index();

 

             //assigner la vue retournee a votre layout

             $this->oLayout->add('main',$oViewModule);

      }

On souhaiterait également que les posts ajoutés soient liés au topic ainsi qu'à l'utilisateur connecté :

//instancier le module

             $oModulePosts=new module_posts();

 

             //on force ici l'id du topic

             $oModulePosts->topic_id=_root::getParam('id');

             //et ici le user

             $oModulePosts->user_id=_root::getAuth()->getAccount()->id;

Modifions le module posts en conséquence pour utiliser ces deux variables. Éditez le fichier module/posts/main.php et ajoutez deux propriétés « public » topic_id et user_id :

<?php

class module_posts extends abstract_moduleembedded{

 

      public static $sModuleName='posts';

      public static $sRootModule;

      public static $tRootParams;

 

      public $topic_id;

      public $user_id;

Maintenant, nous allons modifier l'action de listage pour filtrer sur le topic.

Remplacez dans la méthode _list() :

$tPosts=model_posts::getInstance()->findAll();

par

$tPosts=model_posts::getInstance()->findListByTopic($this->topic_id);

Petite parenthèse : ajoutons cette méthode dans la classe modèle correspondante model_posts, on en profite pour faire une jointure et ainsi récupérer l'utilisateur.

public function findListByTopic($topic_id){

             return $this->findMany('SELECT posts.*,users.login FROM '.$this->sTable.'

INNER JOIN users ON posts.user_id=users.id WHERE topic_id=?',$topic_id);

      }

Fin de parenthèse.

Et enfin forçons le topic et le « user » lors de l'enregistrement en éditant la méthode processSave() du module.

private function processSave(){

             if(!_root::getRequest()->isPost() or _root::getParam('formmodule')!=self::$sModuleName ){ //si ce n'est pas une requete POST on ne soumet pas

                    return null;

             }

 

             (...)

 

             $iId=module_posts::getParam('id',null);

             if($iId==null){

                    $oPosts=new row_posts;

                    //on force le topic id

                    $oPosts->topic_id=$this->topic_id;

                    //on force le user

                    $oPosts->user_id=$this->user_id;

             }else{

                    $oPosts=model_posts::getInstance()->findById( module_posts::getParam('id',null) );

}

On peut améliorer un peu l'affichage en modifiant le HTML de la vue module/posts/view/list.php.

Par exemple :

<?php if($this->tPosts):?>

      <?php foreach($this->tPosts as $oPosts):?>

      <div class="tb_post">

             <div class="login"><h2><?php echo $oPosts->login ?></h2></div>

             <div class="text"><?php echo $oPosts->texte ?></div>

             <div class="clear"></div>

      </div>

      <?php endforeach;?>

<?php else:?>

      <p>Aucune ligne</p>

<?php endif;?>

 

<p class="answer"><a href="<?php echo module_posts::getLink('new') ?>">R&eacute;pondre</a></p>

Libre à vous d'améliorer le code HTML et CSS afin d'avoir un forum plus sympa.

Conclusion

Vous avez pu découvrir ici comment créer un modeste forum en peu de temps avec le mkframework en vous aidant du générateur web qui vous permet de gagner un temps précieux.

Bien sûr, ce framework permet de faire bien plus que ça, je vous invite à lui donner sa chance, et rejoindre ses utilisateurs. Vous avez à disposition de nombreuses ressources pour faciliter sa prise en main : des tutoriels, des vidéos, un podcast, des diapos…

Régulièrement, de nouveaux utilisateurs « débutants » confirment que la simplicité de celui-ci ainsi que son générateur leur ont permis de créer leurs applications web.

Tags : forum, framework, PHP