I. Présentation du tutoriel ▲
Dans ce tutoriel, nous allons apprendre à utiliser le framework pour créer une application de microblogging (comme le célèbre oiseau).
II. Le modèle de données ▲
Voici les tables à créer pour notre tutoriel.
Ci-dessous le script SQL de création de la base de données « microblogging » :
CREATE
TABLE
members (
id int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
login varchar
(
50
)
NOT
NULL
,
pass varchar
(
50
)
NOT
NULL
,
picture varchar
(
50
)
NOT
NULL
,
description varchar
(
200
)
NOT
NULL
,
nb_posts int
(
11
)
NOT
NULL
,
nb_followers int
(
11
)
NOT
NULL
,
nb_subscriptions int
(
11
)
DEFAULT
NULL
,
shortname varchar
(
50
)
DEFAULT
NULL
,
PRIMARY
KEY
(
id)
)
;
CREATE
TABLE
posts(
id int
(
11
)
NOT
NULL
auto_increment
,
text
varchar
(
300
)
NOT
NULL
,
member_id int
(
11
)
NOT
NULL
,
dateCreation datetime
NOT
NULL
,
post_id_parent int
(
11
)
NULL
,
nb_retweets int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
CREATE
TABLE
hashtags (
id int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
name
varchar
(
20
)
NOT
NULL
,
nb_posts int
(
11
)
NOT
NULL
,
dateLastUse datetime
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
CREATE
TABLE
hashtags_posts (
id int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
post_id int
(
11
)
NOT
NULL
,
hashtag_id int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
CREATE
TABLE
mentions (
id int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
member_id int
(
11
)
NOT
NULL
,
post_id int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
CREATE
TABLE
followers (
id int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
member_id int
(
11
)
NOT
NULL
,
follower_member_id int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
III. L'application de base ▲
III-A. Création de l'application ▲
Rendez-vous sur l'adresse du builder : http://localhost/mkframework
Renseignez « microblogging » puis validez avec le bouton « Créer ».
III-B. Présentation de l'arborescence▲
Éditez le fichier conf/connexion.ini.php.
Renseignez votre profil de connexion :
microblogging.dsn="mysql:dbname=microblogging;host=localhost"
microblogging.sgbd=pdo_mysql
microblogging.hostname=localhost
microblogging.database=microblogging
microblogging.username=root
microblogging.password=root
Connexion à une base de données « microblogging » via « pdo_mysql », avec l'utilisateur « root » et le mot de passe « root » également (à modifier en fonction des paramètres de votre base de données).
III-C. Génération de la couche modèle ▲
Cliquez sur « générer la couche modèle ».
Sélectionnez votre connexion à la base de données (« microblogging ») :
Cochez les tables créées précédemment.
Validez avec le bouton « générer ».
Un fichier par table va être créé dans le répertoire « model » de votre projet.
IV. Les modules ▲
IV-A. Introduction ▲
Pour cette application, nous allons créer plusieurs modules afin de gérer les différentes fonctionnalités.
Un module, si l'on compare aux autres frameworks (Zend framework, Symfony…), est composé d'un contrôleur et de ses vues.
IV-B. Module public et d'authentification ▲
IV-B-1. Introduction ▲
Cette application va nécessiter une authentification, c'est-à-dire un formulaire avec un nom d'utilisateur/mot de passe pour identifier le membre. Pour cela nous allons créer un module qui contiendra trois pages (aussi appelées « actions ») (login/logout/inscription).
IV-B-2. Création d'un module d'authentification▲
Le « builder » contient un formulaire pour créer des modules et des modules d'authentification, celui-ci créé :
- un sous-répertoire dans le répertoire « module » de votre projet ;
- un fichier contrôleur main.php ;
- un sous-répertoire « view » contenant les fichiers de vues nécessaires.
Cliquez sur « Créer un module d'authentification avec inscription ».
Vous allez voir s'afficher une page d'erreur vous indiquant que vous ne possédez pas de classe modèle éligible pour créer ce module, et vous demandant d'ajouter deux méthodes à la classe modèle contenant vos comptes de connexion.
Une méthode getListAccount() qui retournera l'ensemble des comptes dans un tableau indexé ainsi qu'une méthode hashPassword() qui hachera votre mot de passe.
Ajoutez ces deux méthodes à votre classe modèle model_members.php puis retournez sur ce menu : il n'y a plus d'erreur.
Saisissez dans le champ « module » : « auth », sélectionnez vers quel module diriger une fois authentifié, et indiquez via les menus déroulants les champs de login et de mot de passe.
Cliquez ensuite sur « Générer ».
Le builder va créer :
- un répertoire « module/auth » ;
- un fichier module/auth/main.php (contenant le contrôleur du module) ;
- un sous répertoire « module/auth/view » ;
- et deux fichiers de vues login.php et inscription.php dans le répertoire « module/auth/view ».
Vous allez également lire que vous devez modifier le fichier de paramétrage pour activer l'authentification sur l'ensemble du site en passant la variable « enabled » à 1 dans la section [auth] du fichier conf/site.ini.php.
IV-B-3. Test du module d'authentification ▲
Profitez-en pour tester ce départ : cliquez sur le lien inscription, saisissez un nom d'utilisateur et un mot de passe et enregistrez-le.
Par exemple « login » comme nom d'utilisateur et « pass » comme mot de passe.
Vous pouvez désormais vous authentifier avec votre nouveau compte.
IV-C. Module profil ▲
IV-C-1. Introduction ▲
Actuellement, lorsque l'on se connecte, on arrive sur une page vide, on va donc créer un module de profil qui nous permettra de voir et modifier notre profil (avatar, informations…). Pour cela, nous allons utiliser le builder.
Cliquez sur « Editer le projet » en face de votre projet.
Cliquez ensuite sur « Créer un module CRUD », puis sur la classe modèle « model_members.php ».
Vous avez un formulaire de création de CRUD, modifiez « members » (nom de la table) par « profil ».
Décochez les cases « Formulaire d'ajout », « Formulaire de suppression » (nous n'en avons pas besoin).
Décochez ensuite les champs « nb_posts », « nb_followers », « nb_subscriptions », « login » et « pass ».
Pour le champ « picture », dans le menu déroulant, sélectionnez « upload ».
Puis cliquez sur « Créer ».
IV-C-2. Un peu de ménage ▲
Nous allons supprimer l'action et la vue inutile de ce module, éditez le fichier module/profil/main.php et supprimez la méthode _list().
idem pour le fichier module/profil/view/list.php.
IV-C-3. Visualisation de son profil ▲
Nous souhaitons par défaut que ce module affiche notre profil en lecture, pour cela on va modifier notre module CRUD.
Éditez le fichier module/profil/main.php.
On remplace notre action _index() (page par défaut) :
public function _index(){
//on considere que la page par defaut est la page de listage
$this
->
_list();
}
Par :
public function _index(){
//on considere que la page par defaut est la page d'affichage de profil
$this
->
_show();
}
On édite ensuite la méthode _show(), où l'on force l'id du membre affiché par celui de notre membre connecté.
L'appel à _root::getAuth()>getAccount() nous retourne l'objet du membre connecté.
public function _show(){
//recuperation de l'id de notre membre connecte
$member_id
=
_root::
getAuth()->
getAccount()->
id;
$oMembers
=
model_members::
getInstance()->
findById( $member_id
);
$oView
=
new _view('
profil::show
'
);
$oView
->
oMembers=
$oMembers
;
$this
->
oLayout>
add('
main
'
,
$oView
);
}
On modifie ensuite la vue pour y ajouter un bouton d'édition du profil.
Fichier module/profil/view/show.php.
<table class
=
"tb_show"
>
<tr>
<th>shortname</th>
<td><?php echo $this->oMembers->shortname ?></td>
</tr>
<tr>
<th>picture</th>
<td><?php echo $this->oMembers->picture ?></td>
</tr>
<tr>
<th>description</th>
<td><?php echo $this->oMembers->description ?></td>
</tr>
</table>
<p style
=
"textalign:right"
>
<a href
=
"<?php echo $this>getLink('profil::edit')?>"
>
Editer</a></p>
IV-C-4. L'édition de son profil ▲
Nous allons ensuite, comme pour la méthode d'affichage, forcer le membre édité par celui connecté. Éditez la méthode _edit() toujours dans module/profil/main.php.
Remplacez :
public function _edit(){
$tMessage
=
$this
->
save();
$oMembers
=
model_members::
getInstance()->
findById( _root::
getParam('
id
'
) );
$oView
=
new _view('
profil::edit
'
);
$oView
->
oMembers=
$oMembers
;
$oView
->
tId=
model_members::
getInstance()->
getIdTab();
$oPluginXsrf
=
new plugin_xsrf();
$oView
->
token=
$oPluginXsrf
->
getToken();
$oView
->
tMessage=
$tMessage
;
$this
->
oLayout->
add('
main
'
,
$oView
);
}
Par :
public function _edit(){
$tMessage
=
$this
->
save();
//recuperation de l'id de notre membre connecte
$member_id
=
_root::
getAuth()->
getAccount()->
id;
$oMembers
=
model_members::
getInstance()->
findById( $member_id
);
$oView
=
new _view('
profil::edit
'
);
$oView
->
oMembers=
$oMembers
;
$oView
->
tId=
model_members::
getInstance()->
getIdTab();
$oPluginXsrf
=
new plugin_xsrf();
$oView
->
token=
$oPluginXsrf
->
getToken();
$oView
->
tMessage=
$tMessage
;
$this
->
oLayout->
add('
main
'
,
$oView
);
}
Il faut également forcer la redirection post-modification vers la page d'affichage du profil.
Et forcer à toujours modifier (supprimer l'ajout de membre).
Remplacez dans la méthode save() :
$iId
=
_root::
getParam('
id
'
,
null);
if($iId
==
null){
$oMembers
=
new row_members;
}
else{
$oMembers
=
model_members::
getInstance()->
findById( _root::
getParam('
id
'
,
null) );
}
Par :
//recuperation de l'id de notre membre connecte
$member_id
=
_root::
getAuth()->
getAccount()->
id;
$oMembers
=
model_members::
getInstance()->
findById( $member_id
);
Et :
//une fois enregistre on redirige (vers la page liste)
_root::
redirect('
profil::list
'
);
Par :
//une fois enregistre on redirige (vers la page d'affichage)
_root::
redirect('
profil::show
'
);
Ici vous pouvez éditer votre profil, choisir une image, définir un shortname et une description et valider.
Mais lorsque le profil s'affiche, on voit le chemin de l'image et non l'image, modifions un peu la vue.
Éditez le fichier module/profil/view/show.php.
<div style
=
"float:right;border:2px solid gray"
><img style
=
"width:100px"
src
=
"<?php echo $this->oMembers->picture ?>"
/></div>
<table class
=
"tb_show"
>
<tr>
<th>shortname</th>
<td><?php echo $this->oMembers->shortname ?></td>
</tr>
<tr>
<th>description</th>
<td><?php echo $this->oMembers->description ?></td>
</tr>
</table>
<div style
=
"clear:both"
></div>
<p style
=
"textalign:right"
>
<a href
=
"<?php echo $this->getLink('profil::edit')?>"
>
Editer</a></p>
IV-C-5. Comment forcer ce module lorsque l'on se connecte ▲
IV-D. Module posts ▲
IV-D-1. Introduction ▲
Passons aux posts : la partie principale de l'application, pour faire simple nous allons d'abord créer un module CRUD que nous modifierons pour répondre à notre besoin.
Rendez-vous sur le builder et cliquez sur « Créer un module CRUD », sélectionnez le modèle model_post.php .
Déselectionnez les cases « Formulaire de modification », « Formulaire de suppression » et « Page affichage de détail ».
Désélectionnez tous les champs sauf « ext ».
IV-D-2. Amélioration du modèle model_posts ▲
Ajoutez la méthode suivante dans le fichier model_post.php.
Dans la classe model_posts :
public function findAllOwnerAndFollowed($members_id
){
return $this
->
findMany('
SELECT posts.* FROM
'
.
$this
->
sTable.
'
LEFT OUTER JOIN followers ON
followers.member_id=posts.member_id WHERE posts.member_id=? OR followers.follower_member_id=? ORDER BY posts.id DESC
'
,
$members_id
,
$members_id
);
}
Dans la classe row_posts on va ajouter une méthode pour récupérer son auteur.
Ajoutez la méthode suivante dans la classe row_posts :
public function findMember(){
return model_members::
getInstance()->
findById($this
->
member_id);
}
Modifiez également la méthode d'enregistrement pour ajouter la date à l'insertion en base. Dans la méthode save() de la classe row_posts juste avant l'appel à la méthode save() de la classe parente.
Ajoutez :
$this
->
dateCreation=
date('
Y-m-d H:i:s
'
);
Ce qui donne :
IV-D-3. Visualisation de son fil (avec post des abonnements + les siens) ▲
Il faut utiliser la méthode précédemment ajoutée pour afficher uniquement les posts de l'utilisateur.
Modifiez le fichier main.php du module posts pour remplacer dans la méthode _list() :
$tPosts
=
model_posts::
getInstance()->
findAll();
Par :
$tPosts
=
model_posts::
getInstance()->
findAllOwnerAndFollowed(_root::
getAuth()->
getAccount()->
id);
Modifions la vue liste.
Éditez le fichier module/posts/view/list.php :
<
h1>
Tweets<
/h1
>
<
table class
=
"
tb_posts
"
>
<?php
if
($this
->
tPosts):
?>
<?php
foreach
($this
->
tPosts as
$oPosts
):
?>
<?php
$oMember
=
$oPosts
->
findMember();
$oDate
=
new
plugin_datetime($oPosts
->
dateCreation);
$sDate
=
$oDate
->
toString('d/m/Y &\a\g\r\a\v\e; H\hi'
);
$sText
=
$oPosts
->
text;
?>
<
tr <?php
echo plugin_tpl::
alternate(array
(''
,
'class="alt"'
))?>
>
<
td style
=
"
width:22px
"
><img style
=
"
width:20px
"
src
=
"
<?php
echo $oMember
->
picture?>
"
/
></td
>
<
td>
<
div style
=
"
float:right;color:gray
"
>
<?php
echo $sDate
?>
<
/div
>
<
strong>
<?php
echo $oMember
->
shortname?>
<
/strong
>
<
a style
=
"
color:#444
"
href
=
"
<?php
echo _root::
getLink('profil::showother'
,
array
('name'
=>
$oMember
->
login))?>
"
>
@<?php
echo $oMember
->
login?>
<
/a
><br/
>
<?php
echo $sText
?>
<
/td
>
<
/tr
>
<?php
endforeach
;
?>
<?php
else
:
?>
Aucun posts
<?php
endif
;
?>
<
/table
>
<
p><a href
=
"
<?php
echo $this
->
getLink('posts::new'
) ?>
"
>
Nouveau message<
/a
></p
>
IV-D-4. Poster ▲
Si vous utilisez le lien « new », vous allez ajouter un enregistrement dans la table posts, mais sans indiquer son auteur, on va forcer l'auteur à l'enregistrement.
Modifions la méthode save() dans le fichier main.php du module « posts ».
Vous allez ajouter une ligne pour forcer le member_id avant l'enregistrement :
//on force l'id du membre
$oPosts
->
member_id=
_root::
getAuth()->
getAccount()->
id;
Elle ressemblera à ceci :
public function save(){
if(!
_root::
getRequest()->
isPost() ){
//si ce n'est pas une requete POST on ne soumet pas
return null;
}
$oPluginXsrf
=
new plugin_xsrf();
if(!
$oPluginXsrf
->
checkToken( _root::
getParam('
token
'
) ) ){
//on verifie que le token est valide
return array('
token
'
=>
$oPluginXsrf
->
getMessage() );
}
$iId
=
_root::
getParam('
id
'
,
null);
if($iId
==
null){
$oPosts
=
new row_posts;
}
else{
$oPosts
=
model_posts::
getInstance()->
findById( _root::
getParam('
id
'
,
null) );
}
$tId
=
model_posts::
getInstance()->
getIdTab();
$tColumn
=
model_posts::
getInstance()->
getListColumn();
foreach($tColumn
as $sColumn
){
if(isset($_FILES
[
$sColumn
]
) and $_FILES
[
$sColumn
][
'
size
'
]
>
0
){
$sNewFileName
=
_root::
getConfigVar('
path.upload
'
).
$sColumn
.
'
_
'
.
date('
Ymdhis
'
);
$oPluginUpload
=
new plugin_upload($_FILES
[
$sColumn
]
);
$oPluginUpload
->
saveAs($sNewFileName
);
$oPosts
->
$sColumn
=
$oPluginUpload
->
getPath();
continue;
}
else if( _root::
getParam($sColumn
,
null) ===
null ){
continue;
}
else if( in_array($sColumn
,
$tId
)){
continue;
}
$oPosts
->
$sColumn
=
_root::
getParam($sColumn
,
null) ;
}
//on force l'id du membre
$oPosts
->
member_id=
_root::
getAuth()->
getAccount()->
id;
if($oPosts
->
save()){
//une fois enregistre on redirige (vers la page liste)
_root::
redirect('
posts::list
'
);
}
else{
return $oPosts
->
getListError();
}
}
IV-E. Module hashtags ▲
IV-E-1. Récupération du hashtag par son nom ▲
Ajoutez une méthode dans model_hashtags.php.
IV-E-2. Modification du modèle hashtags pour récupérer les hashtags d'un post ▲
Éditez le fichier model_hashtags.php.
Et ajoutons une méthode pour récupérer les hashtags :
IV-E-3. Ajout d'une méthode pour prendre en compte les hashtags ▲
Toujours le même fichier modèle model_hashtags.
Nous allons ajouter une méthode qui recevra un tableau de hashtags et créera les liens SQL entre ceux-ci et notre post :
public function addForPost($sHashtag
,
$post_id
){
//recherche du hashtag par son nom
$oHashtag
=
$this
->
findByName($sHashtag
);
if($oHashtag
){
//si on trouve le hashtag en base, on incremente sa notoriete
$oHashtag
->
nb_posts=
$oHashtag
->
nb_posts+
1
;
}
else{
//si on ne le trouve pas on créé ce hashtag
$oHashtag
=
new row_hashtags;
$oHashtag
->
name=
$sHashtag
;
$oHashtag
->
nb_posts=
1
;
}
//dans les deux cas on indique au hashtag sa dernière utilisation
$oHashtag
->
dateLastUse=
date('
Ymd H:i:s
'
);
$oHashtag
->
save();
//enfin on sauvegarde le lien post/hashtag
$oHashtagPost
=
new row_hashtags_posts;
$oHashtagPost
->
post_id=
$post_id
;
$oHashtagPost
->
hashtag_id=
$oHashtag
->
id;
$oHashtagPost
->
save();
}
IV-E-4. À l'enregistrement d'un post, enregistrer les hashtags ▲
On va prendre en compte ici les méthodes ajoutées précédemment.
Dans la classe model_post, profitons de la méthode save() pour prendre en compte les hashtags.
Éditez la classe row_posts :
public function save(){
if(!
$this
->
isValid()){
return false;
}
$this
>
dateCreation=
date('
Ymd H:i:s
'
);
parent::
save();
//on en profite pour enregistrer les tags et les mentions
//les hashtags
$tHashtags
=
model_hashtags::
getInstance()->
findAllHashtags($this
->
text);
if($tHashtags
){
foreach($tHashtags
as $sHashtag
){
$sHashtag
=
trim($sHashtag
);
model_hashtags::
getInstance()->
addForPost($sHashtag
,
$this
->
id);
}
}
return true;
}
IV-E-5. Visualisation des hastags les plus populaires ▲
Créons un module pour voir les hashtags.
Passez par le builder pour créer un module « hashtags » avec deux actions « list » et « show ».
Éditez ensuite le fichier module/hashtags/main.php pour afficher le menu.
Modifiez la méthode before() :
public function before(){
$this
->
oLayout=
new _layout('
template1
'
);
$this
->
oLayout->
addModule('
menu
'
,
'
menu::list
'
);
}
Modifiez également la méthode _list() pour récupérer les hashtags et les ajouter à la vue :
public function _list(){
//recuperons la liste des hashtags
$tHastags
=
model_hashtags::
getInstance()>
findAll();
$oView
=
new _view('
hashtags::list
'
);
//assignons le tableau d'hashtag a la vue
$oView
->
tHastags=
$tHastags
;
$this
->
oLayout->
add('
main
'
,
$oView
);
}
Modifiez également la vue list module/hashtags/view/list.php.
Pour lister les hashtags :
<
h1>
Hashtags<
/h1
>
<
table class
=
"
tb_posts
"
>
<?php
if
($this
->
tHastags):
?>
<?php
foreach
($this
->
tHastags as
$oHastags
):
?>
<
tr <?php
echo plugin_tpl::
alternate(array
(''
,
'class="alt"'
))?>
>
<
td><strong><a href
=
"
<?php
echo _root::
getLink('hashtags::show'
,
array
('name'
=>
$oHastags
->
name))?>
"
>
#<?php
echo $oHastags
->
name ?>
<
/a
></strong
>
<
br /
><strong>
<?php
echo $oHastags
->
nb_posts ?>
<
/strong
>
TWEETS <
br/
>
<
i>
dernier tweet le <?php
echo $oHastags
->
dateLastUse ?>
<
/i
>
<
/td
>
<
/tr
>
<?php
endforeach
;
?>
<?php
endif
;
?>
<
/table
>
IV-E-6. Affichage des hashtags et surtout des posts associés ▲
Occupons-nous de la page pour afficher les hashtags et ses posts associés.
Au départ on ajoute une méthode dans le modèle posts pour lister les posts associés à un hashtag.
Ouvrez le fichier model_posts.php :
public function findByHashtag($uId
){
return $this
->
findMany('
SELECT posts.* FROM
'
.
$this
->
sTable.
'
,hashtags_posts WHERE posts.id=hashtags_posts.post_id AND hashtag_id=?
'
,
$uId
);
}
Ensuite ajoutez une méthode pour retourner les posts liés à un hashtag.
Dans le module module/posts/main.php :
IV-F. Module mentions ▲
IV-F-1. Modification du modèle mention pour récupérer les mentions d'un post ▲
Comme pour les hashtags, nous ajoutons une méthode dans la couche modèle pour trouver les mentions contenues dans un post.
Dans le modèle model/model_mentions.php :
IV-F-2. Ajout d'une méthode pour prendre en compte les mentions ▲
Également comme pour les hashtags, on ajoute une méthode pour enregistrer ces mentions :
public function addForPost($sLogin
,
$post_id
){
//recuperons le membre indique par la mention par son nom
$oMember
=
model_members::
getInstance()->
findByLogin($sLogin
);
if($oMember
){
//si on trouve le membre, on cree une mention
$oMention
=
new row_mentions;
//le lien avec le membre de la mention
$oMention
->
member_id=
$oMember
->
id;
//le lien vers le post a l'origine de la mention
$oMention
->
post_id=
$post_id
;
$oMention
->
save();
}
}
IV-F-3. À l'enregistrement du post, enregistrement de la/des mention(s) ▲
Toujours comme pour les hashtags, on va profiter de l'enregistrement du post pour lier celui-ci à ses mentions.
Éditez model/model_posts.php.
Et dans la méthode save().
En ajoutant la partie suivante :
//les mentions
$tMentions
=
model_mentions::
getInstance()->
findAllMention($this
->
text);
if($tMentions
){
foreach($tMentions
as $sLogin
){
model_mentions::
getInstance()->
addForPost($sLogin
,
$this
->
id);
}
}
Ce qui donnera :
public function save(){
if(!
$this
->
isValid()){
return false;
}
$this
->
dateCreation=
date('
Y-m-d H:i:s
'
);
parent::
save();
//on incremente notre nombre de posts
$oMember
=
$this
->
findMember();
$oMember
->
nb_posts=
$oMember
->
nb_posts+
1
;
$oMember
->
save();
//on en profite pour enregistrer les tags et les mentions
//les tags
$tHashtags
=
model_hashtags::
getInstance()->
findAllHashtags($this
->
text);
if($tHashtags
){
foreach($tHashtags
as $sHashtag
){
$sHashtag
=
trim($sHashtag
);
model_hashtags::
getInstance()->
addForPost($sHashtag
,
$this
->
id);
}
}
//les mentions
$tMentions
=
model_mentions::
getInstance()->
findAllMention($this
->
text);
if($tMentions
){
foreach($tMentions
as $sLogin
){
model_mentions::
getInstance()->
addForPost($sLogin
,
$this
->
id);
}
}
return true;
}
IV-F-4. Modification de notre modele posts pour lister les posts mentionnant notre membre ▲
Ajoutons une méthode pour lister les posts par rapport à une mention.
Éditez le fichier modèle model_posts.php et ajoutez la méthode :
IV-F-5. Ajout d'une méthode au module posts pour retourner une vue des posts par mention ▲
Ajoutons une méthode au module qui retournera une vue des posts par mention :
IV-F-6. Visualisation de nos mentions ▲
Pour cela créons un module « mentions »: utiliser le générateur web pour créer un module avec une action « list » seulement.
Ajoutons la prise en compte du menu.
Dans la méthode before() du module mentions module/mentions/main.php :
$this
->
oLayout->
addModule('
menu
'
,
'
menu::list
'
);
Ensuite modifions la vue _list() pour afficher les mentions :
public function _list(){
//recuperons le compte utilisateur de l'utilisateur connecte
$oMember
=
_root::
getAuth()->
getAccount();
$oView
=
new _view('
mentions::list
'
);
//assignons a la vue notre objet membre
$oView
->
oMember=
$oMember
;
$this
->
oLayout->
add('
main
'
,
$oView
);
//recuperons la liste des posts par mention (a nous meme)
$oModulePost
=
new module_posts;
$oViewPost
=
$oModulePost
->
listByMention($oMember
->
id);
$this
->
oLayout->
add('
main
'
,
$oViewPost
);
}
Éditons la vue module/mentions/view/list.php :
IV-G. Module abonnements ▲
IV-G-1. Liste des membres ▲
Dans le module profil, on va modifier la méthode _show().
En ajoutant la récupération de tous les membres :
//listons les membres du site
$tMember
=
model_members::
getInstance()->
findAll();
$oView
->
tMember=
$tMember
;
Ce qui donnera :
public function _show(){
//recuperation de l'id de notre membre connecte
$member_id
=
_root::
getAuth()->
getAccount()->
id;
$oMembers
=
model_members::
getInstance()->
findById( $member_id
);
$oView
=
new _view('
profil::show
'
);
$oView
->
oMembers=
$oMembers
;
//listons les membres du site
$tMember
=
model_members::
getInstance()->
findAll();
$oView
->
tMember=
$tMember
;
$this
->
oLayout->
add('
main
'
,
$oView
);
}
Modifions également la vue pour lister ces membres avec un lien pour les suivre.
Éditez la vue module/profil/view/show.php :
<
table class
=
"
tb_subscriptions
"
>
<?php
foreach
($this
->
tMember as
$oMember
):
?>
<?php
if
($oMember
->
id==
$this
->
oMembers->
id) continue
?>
<
tr>
<
td style
=
"
width:22px
"
><img style
=
"
width:20px
"
src
=
"
<?php
echo $oMember
->
picture?>
"
/
></td
>
<
td><strong>
<?php
echo $oMember
->
shortname?>
<
/strong
>
@
<?
php echo $oMember
->
login?>
<
/td
>
<
td style
=
"
width:100px;text-align:right
"
>
<
a class
=
"
btn
"
href
=
"
<?php
echo _root::
getLink('profil::follow'
,
array
('member_id'
=>
$oMember
->
id))?>
"
>
Suivre<
/a
>
<
/td
>
<
/tr
>
<?php
endforeach
;
?>
<
/table
>
<
div style
=
"
clear:both;height:10px
"
></div
>
Ici on boucle sur les membres et on affiche un lien « suivre » uniquement si le compte n'est pas le nôtre.
IV-G-2. Ajout d'un autre membre pour pouvoir tester nos abonnements ▲
Via la page d'inscription, créez un second compte, ici dupot/pass.
Ainsi sur la page précédente, vous pouvez voir l'utilisateur ajouté, et on peut cliquer sur le bouton « suivre », dont on va écrire le code.
IV-G-3. Permettre de « suivre » un autre membre ▲
Nous allons ajouter cette méthode _follow dans notre module profil qui va ajouter un abonnement entre notre membre et un autre.
Éditez le fichier module/profil/main.php.
Et ajoutez deux méthodes pour suivre et arrêter de suivre un membre :
public function _follow(){
//on s'abonne au membre
model_followers::
getInstance()->
followForMember(_root::
getParam('
member_id
'
),
_root::
getAuth()->
getAccount()->
id);
//on recalcule son nombre d'abonnes
model_members::
getInstance()->
calculFollower(_root::
getParam('
member_id
'
));
//on calcul notre nombre d'abonnement
model_members::
getInstance()->
calculSubscription(_root::
getAuth()->
getAccount()->
id);
_root::
redirect('
profil::index
'
);
}
public function _unfollow(){
//on se desabonne du membre
model_followers::
getInstance()->
unfollowForMember(_root::
getParam('
member_id
'
),
_root::
getAuth()->
getAccount()->
id);
//on recalcule son nombre d'abonnes
model_members::
getInstance()->
calculFollower(_root::
getParam('
member_id
'
));
//on recalcule notre nombre d'abonnements
model_members::
getInstance()->
calculSubscription(_root::
getAuth()->
getAccount()->
id);
_root::
redirect('
profil::show
'
);
}
IV-G-4. Modification de notre modèle model_followers pour ajouter un abonnement ▲
Éditez le fichier modèle model_followers.php, et ajoutez-y une méthode « followForMember » :
public function followForMember($member_id
,
$follower_member_id
){
$this
->
unfollowForMember($member_id
,
$follower_member_id
);
$oFollow
=
new row_followers;
$oFollow
->
member_id=
_root::
getParam('
member_id
'
);
$oFollow
->
follower_member_id=
_root::
getAuth()->
getAccount()->
id;
$oFollow
->
save();
}
public function unfollowForMember($member_id
,
$follower_member_id
){
$this
->
execute
('
DELETE FROM followers WHERE member_id=? AND follower_member_id=?
'
,
$member_id
,
$follower_member_id
);
}
IV-G-5. Modification de notre modèle members pour y ajouter le calcul des abonnés et celui des abonnements ▲
Modifiez le fichier modèle model_members.php et ajoutez-y deux méthodes « calculFollower » et « calculSubscription ».
public function calculFollower($member_id
){
$oRow
=
$this
->
findOne('
SELECT COUNT(*) as total FROM followers WHERE member_id=?
'
,
$member_id
);
$nb
=
$oRow
->
total;
$this
->
execute
('
UPDATE members SET nb_followers=? WHERE id=?
'
,
$nb
,
$member_id
);
}
public function calculSubscription($member_id
){
$oRow
=
$this
->
findOne('
SELECT COUNT(*) as total FROM followers WHERE follower_member_id=?
'
,
$member_id
);
$nb
=
$oRow
->
total;
$this
->
execute
('
UPDATE members SET nb_subscriptions=? WHERE id=?
'
,
$nb
,
$member_id
);
}
IV-G-6. Affichage du nombre d'abonnements et d'abonnés sur notre profil ▲
Modifions notre vue profil/show.
Et ajoutez dans module/profil/view/show.php :
<
table class
=
"
profil
"
>
<
tr>
<
td>
<
strong>
<?php
echo $this
->
oMembers->
nb_posts?>
<
/strong
>
<
br /
>
POSTS<
/td
>
<
td>
<
strong>
<?php
echo $this
->
oMembers->
nb_followers?>
<
/strong
>
<
br /
>
ABONNES<
/td
>
<
td style
=
"
width:450px
"
>
<
strong>
<?php
echo $this
->
oMembers->
nb_subscriptions?>
<
/strong
>
<
br /
>
ABBONNEMENTS<
/td
>
<
/tr
>
<
/table
>
V. Création de notre menu▲
Le builder permet facilement de générer un menu à partir de vos modules existants.
Cliquez sur « Créer un module menu ».
Vous voyez listé vos modules ainsi que les méthodes « actions » disponibles.
Cochez la méthode _list() pour le module « posts » et indiquez dans la colonne libellée « Votre fil ».
Faites de même pour la méthode _list() du module « hashtags » avec comme libellé « Hashtag », idem pour la méthode _list() du module « mentions » avec « Mention » et enfin « Votre profil » pour le couple _index / profil.
Cliquez sur « Générer le menu ».
Le builder va créer un module menu, il ne vous reste plus qu'à l'inclure dans vos modules « posts », « hashtags », « mentions » et « profil ».
Éditez les fichiers main.php de ces quatre modules et ajoutez dans les méthodes before() :
$this
->
oLayout->
addModule('
menu
'
,
'
menu::list
'
);
VI. Modification du module profil pour afficher celui des autres membres ▲
VI-A. Ajout d'une action pour afficher le profil d'un autre membre ▲
Modifiez le module profil module/profil/main.php et ajoutez-y :
public function _showother(){
$oMembers
=
model_members::
getInstance()->
findByLogin(_root::
getParam('
name
'
));
if($oMembers
){
$oView
=
new _view('
profil::showother
'
);
$oView
->
oMembers=
$oMembers
;
$oModulePosts
=
new module_posts;
$oViewPosts
=
$oModulePosts
->
listLastByMember($oMembers
->
id);
$oView
->
oViewPosts=
$oViewPosts
;
}
else{
$oView
=
new _view('
profil::showothernotfound
'
);
}
$this
->
oLayout->
add('
main
'
,
$oView
);
}
VI-B. Modification du modèle posts pour récupérer les derniers posts d'un membre ▲
Éditez le fichier modèle model_posts et ajoutez la méthode :
VI-C. Modification du module posts pour afficher les derniers posts d'un membre ▲
Ajoutons une action à notre module posts pour qu'il retourne une vue contenant les posts d'un membre.
Éditez le fichier module/posts/main.php :
public function listLastByMember($member_id
){
$tPosts
=
model_posts::
getInstance()->
findAllLastByMember($member_id
);
$oView
=
new _view('
posts::list2
'
);
$oView
->
tPosts=
$tPosts
;
return $oView
;
}
Créez une nouvelle vue pour lister les posts d'un autre membre.
Créez un fichier module/posts/view/list2.php :
<
table class
=
"
tb_posts
"
style
=
"
width:620px
"
>
<?php
if
($this
->
tPosts):
?>
<?php
foreach
($this
->
tPosts as
$oPosts
):
?>
<?php
$oMember
=
$oPosts
->
findMember();
$oDate
=
new
plugin_datetime($oPosts
->
dateCreation);
$sDate
=
$oDate
->
toString('d/m/Y &\a\g\r\a\v\e; H\hi'
);
$tHashtags
=
model_hashtags::
getInstance()->
findAllHashtags($oPosts
->
text);
$sText
=
$oPosts
->
text;
foreach
($tHashtags
as
$sHashtags
){
$sLink
=
'<a href="'
._
root::
getLink('hashtags::show'
,
array
('name'
=>
$sHashtags
)).
'">#'
.
$sHashtags
.
'</a>'
;
$sText
=
preg_replace('/#'
.
$sHashtags
.
'/'
,
$sLink
,
$sText
);
}
$tMentions
=
model_mentions::
getInstance()->
findAllMention($oPosts
->
text);
foreach
($tMentions
as
$sMention
){
$sLink
=
'<a href="'
._
root::
getLink('profil::showother'
,
array
('name'
=>
$sMention
)).
'">@'
.
$sMention
.
'</a>'
;
$sText
=
preg_replace('/@'
.
$sMention
.
'/'
,
$sLink
,
$sText
);
}
?>
<
tr <?php
echo plugin_tpl::
alternate(array
(''
,
'class="alt"'
))?>
>
<
td style
=
"
width:22px
"
><img style
=
"
width:20px
"
src
=
"
<?php
echo $oMember
->
picture?>
"
/
></td
>
<
td>
<
div style
=
"
float:right;color:gray
"
>
<?php
echo $sDate
?>
<
/div
>
<
strong>
<?php
echo $oMember
->
shortname?>
<
/strong
>
<
span style
=
"
color:#444
"
>
@<?php
echo $oMember
->
login?>
<
/span
><br/
>
<?php
echo $sText
?>
<
/td
>
<
/tr
>
<?php
endforeach
;
?>
<?php
else
:
?>
Aucun posts
<?php
endif
;
?>
<
/table
>
VI-D. Création d'une vue pour afficher un profil ▲
Modifiez le module module/profil/view/showother.php.
<
div class
=
"
popup
"
>
<
h1 class
=
"
close
"
><a href
=
"
<?php
echo _root::
getLink('posts::list'
)?>
"
>
Fermer<
/a
></h1
>
<
div style
=
"
margin:auto;width:100px;background:#fff;margin-top:20px
"
><img style
=
"
width:100px
"
src
=
"
<?php
echo $this
->
oMembers->
picture ?>
"
/
></div
>
<
p style
=
"
text-align:center;font-weight:bold;font-size:14px
"
>
<?php
echo $this
->
oMembers->
shortname ?>
<
/p
>
<
p style
=
"
text-align:center;font-size:14px
"
>
@<?php
echo $this
->
oMembers->
login ?>
<
/p
>
<
p style
=
"
text-align:center
"
>
<?php
echo $this
->
oMembers->
description ?>
<
/p
>
<
table class
=
"
profil
"
style
=
"
width:640px
"
>
<
tr>
<
td>
<
strong>
<?php
echo $this
->
oMembers->
nb_posts?>
<
/strong
>
<
br /
>
POSTS<
/td
>
<
td>
<
strong>
<?php
echo $this
->
oMembers->
nb_followers?>
<
/strong
>
<
br /
>
ABONNES<
/td
>
<
td style
=
"
width:450px
"
>
<
strong>
<?php
echo $this
->
oMembers->
nb_subscriptions?>
<
/strong
>
<
br /
>
ABBONNEMENTS<
/td
>
<
/tr
>
<
/table
>
<?php
echo $this
->
oViewPosts->
show()?>
<
/div
>
Créez également une vue dans le cas où l'on ne trouve pas le membre.
Créez un fichier de vue module/posts/view/showothernotfound.php.
<
div class
=
"
popup
"
>
<
h1 class
=
"
close
"
><a href
=
"
<?php
echo _root::
getLink('posts::list'
)?>
"
>
Fermer<
/a
></h1
>
<
div style
=
"
margin:auto;width:100px;background:#fff;margin-top:20px;background:#444;text-align:center;color:white;font-size:14px;font-weight:bold
"
>
?<
/div
>
<
p style
=
"
text-align:center;font-size:14px
"
>
@<?php
echo _root::
getParam('name'
)?>
introuvable :(<
/p
>
<
/div
>
VII. Cosmétique ▲
Juste en modifiant la feuille de style, on obtient un résultat plus sympathique.
Le CSS :
*{
font-family:
arial;
font-size:
12
px;
}
img{
border:
none
;
}
a{
color:
darkblue;
}
body{
background:
#bbb
;
margin:
0
px;
}
.main
{
margin:
0
px auto
;
width:
700
px;
background:
#fff
;
border:
2
px solid
#444
;
box-shadow:
1
px 1
px 12
px #555
;
}
.main
.menu
{
background:
#444
;
height:
30
px;
}
.main
.menu
ul{
margin:
0
px;
padding:
0
px;
height:
30
px;
}
.main
.menu
a{
text-decoration:
none
;
color:
white
;
font-weight:
bold
;
}
.main
.menu
li{
padding:
0
px 20
px;
margin:
0
px;
list-style:
none
;
display:
inline-block
;
height:
23
px;
padding-top:
7
px;
}
.main
.menu
.selectionne
{
background:
#222
;
}
.main
.content
form .textarea
,
.main
.content
form .input
{
width:
100
%;
}
.tb_list
{
border-collapse:
collapse
;
}
.tb_list
th,
.tb_list
td{
border:
1
px solid
gray
;
}
.tb_list
th{
text-align:
left
;
}
.tb_list
td{
vertical-align:
top
;
}
.tb_list
.alt
td{
background:
#eee
;
}
.profil
{
border-collapse:
collapse
;
width:
680
px;
margin:
10
px;
}
.profil
td{
border:
1
px solid
#777
;
padding:
8
px;
color:
#777
;
}
.profil
td strong{
color:
#000
;
}
.tb_posts
{
margin:
4
px;
margin-top:
20
px;
width:
680
px;
border-collapse:
collapse
;
}
.tb_posts
td{
padding:
6
px;
padding-bottom:
20
px;
border-top:
1
px solid
#ccc
;
}
.tb_posts
strong{
font-size:
14
px;
}
.tb_posts
a{
text-decoration:
none
;
}
.tb_subscriptions
{
margin:
4
px;
margin-top:
20
px;
width:
680
px;
border-collapse:
collapse
;
}
.tb_subscriptions
td{
padding:
6
px;
padding-bottom:
20
px;
border-top:
1
px solid
#ccc
;
}
.profil
{
border-collapse:
collapse
;
width:
678
px;
margin:
10
px;
margin-top:
5
px;
}
.profil
td{
border:
1
px solid
#777
;
padding:
8
px;
color:
#777
;
}
.profil
td strong{
color:
#000
;
}
.btn
,
.btnDisabled
{
border:
2
px solid
#196160
;
background:
#2a9190
;
display:
inline-block
;
text-decoration:
none
;
padding:
2
px 6
px;
color:
white
;
font-weight:
bold
;
text-align:
center
;
}
.btnDisabled
{
border-color:
#444
;
background:
#2a9190
;
}
.popup
{
margin:
20
px;
width:
650
px;
border:
3
px solid
gray
}
.popup
.close
{
background:
gray
;
margin-top:
0
px;
text-align:
right
;
}
.popup
.close
a{
color:
white
;
text-decoration:
none
;
}
h1{
font-size:
14
px;
padding-left:
8
px;
color:
#444
;
}
.tbCenter
{
margin:
auto
;
}
VIII. Conclusion▲
Dans ce tutoriel vous avez pu voir qu'il était assez simple de créer un site aussi complexe qu'une application de microblogging.
Le MkFramework, depuis sa publication en 2009 sur le site de Developpez, n'a cessé d'évoluer et de s'améliorer. Je prends en compte toutes les remarques et axes d'améliorations que l'on me soumet via le forumForum du projet MkFramework de Developpez.
Une barre de debug a fait son apparition, ainsi que des améliorations du générateur web…
De plus, vous pouvez maintenanttélécharger des applicationsPage des applications MkFramework (sous licence LGPLv3) développées en utilisant le framework.
J'espère vous avoir convaincus de donner une chance à ce framework qui se veut simple à utiliser.
IX. Remerciements▲
Je souhaiterais remercier zoom61Page personnelle de zoom61 pour son soutien, et f-lebPage personnelle de f-leb pour sa correction orthographique.