Création d'un réseau social avec le mkframework


-I Préambule
-II Création et initialisation du projet
-III L'authentification
-IV Créons notre menu
-V Partie privée : le profil
-VI Partie privée : votre réseaux de contacts
-VII Partie privée : votre fil
-VIII Partie privée : administrez vos photos
-IX Profil partagé
-X Design/ esthétique
-XI Conclusion

VI Partie privée : votre réseaux de contacts

VI.A Introduction

A partir de là, le réseau de contacts va être nécessaire: que l'on choisisse de poster un
message, ou d'administrer ses photos, il nous faudra choisir avec qui les partager.
Avant de commencer cette partie, il nous faudrait ajouter quelques individus sur notre
application
Profitez de notre page d'inscription pour ajouter quelques personnes
Vicor Hugo, Albert Camus, Isaac Asimov, George Lucas, Steven Spielberg et Justin Bieber
Pour permettre de gérer nos groupes, nous allons utiliser la même technique que la
précédente: créer un CRUD, puis l'inclure dans notre page

VI.B Créons notre module groups

Rendez-vous sur le builder, sur la partie module CRUD intégrable

On se retrouve avec notre module permettant d'administrer nos groupes, on va le customiser, puis l'inclure

VI.C Permettre de forcer l'utilisateur

Ici, notre module va nous permettre d'administrer les groupes de l'utilisateur concerné, on va
donc ajouter une propriété et une méthode pour définir l'utilisateur, puis prendre en compte
cette propriété lors de l'enregistrement
Ajoutez au début du module "groups"

  
private $user_id;
public function 
setUserId($user_id){
   $this->user_id=(int)$user_id;
}
    


Et dans la méthode save()
Forçons le user_id avec cette propriété

  
//on force le user_id avec la propriete de notre module
$oGroups->user_id=$this->user_id;
$oGroups->save();
    


Changeons la requête faite pour récupérer les groupes filtré par utilisateur
Dans la méthode _list()
Remplacer

  
$tGroups
=model_Groups::getInstance()->findAll();
    


Par

  
$tGroups
=model_Groups::getInstance()->findListByUser$this->user_id);
    


Et ajoutons une requête dans notre classe modèle
Ajouter dans le fichier model/model_Groups.php la méthode suivante:

  
public function findListByUser($user_id){
   return $this->findMany('SELECT * FROM '.$this->sTable.' WHERE user_id=?',(int)$user_id);
}
    



VI.D Intégrer notre module groups

Éditons notre fichier module/mainPrivate/main.php
Dans notre méthode _friends, on va ajouter l'appel à notre module

  
public function _friends(){
   $oModuleGroups=new module_Groups();
   $oModuleGroups->setUserId_root::getAuth()->getAccount()->id );
   $oViewGroups=$oModuleGroups->_index();
   $this->oLayout->add('main',$oViewGroups);
}
    



Vous pouvez désormais ajouter des groupes, par exempes "potes écrivains" et "Réalisateurs"

A ce stade, vous pouvez administrer des groupes, c'est bien, maintenant, voyons comment ajouter des contacts

VI.E Créons un module contacts

Rendez-vous sur le builder, sur la partie "créer un module intégrable"
Ici, on va créer un module qui permettra de lister nos contacts ,d'en chercher de nouveaux,de leur proposer de devenir un de nos contacts et bien sur d'accepter ou de refuser.
Créons le module "contacts" avec les actions list,find,ask,accept et refuse

Cliquez sur le bouton "générer"
Dans notre module, nous allons d'abord ajouter une propriété pour définir l'utilisateur
Éditer le fichier module/contacts/main.php
Ajouter au début

  
private $user_id;
public function 
setUserId($user_id){
   $this->user_id=(int)$user_id;
}
    


Modifions la méthode _list()
Elle nous permettra de lister les contacts, mais également les demandes que l'utilisateur a faite (ou dont il fait l'objet).
Mais pour cela ajoutons des requêtes à notre modèle friends:
- pour récupérer nos contacts
- pour récupérer nos demandes en attente
- pour récupérer les demandes des autres utilisateurs à valider

Pour cela éditons notre fichier model/model_friends.php
Ajoutons en amont des constantes qui définirons les différents états pending, acceped et refused

  
const STATE_PENDING=0;
const 
STATE_ACCEPTED=1;
const 
STATE_REFUSED=2;
    


Ensuite ajoutons nos 3 requêtes
Pour écrire une requête avec l'orm, choisissez d'abord si vous souhaitez récupérer un ou
plusieurs enregistrements, vous utiliserez findOne ou findMany auxquels vous passerez votre
requête comme premier argument (dont les paramètres seront remplacés par un point
d'interrogation) et vos paramètres comme autres arguments

  
   
public function findListAcceptedByUser($user_id){
       return $this->findMany(
           'SELECT *, Friends.id as friend_id FROM '.$this->sTable.',Users
           WHERE
           (Friends.state='
.self::STATE_ACCEPTED.'
           and Users.id=Friends.user_id2 and Friends.user_id=?)
           or
           (Friends.state='
.self::STATE_ACCEPTED.'
           and Users.id=Friends.user_id and Friends.user_id2=?)
           '
           ,(int)$user_id
           
,(int)$user_id
       
);
   }
   public function findListPendingByUser($user_id){
       return $this->findMany(
           'SELECT * FROM '.$this->sTable.',Users
           WHERE Users.id=Friends.user_id2
           AND Friends.user_id=?
           AND Friends.state=? '
           ,(int)$user_id
           
,self::STATE_PENDING
       
);
   }
   public function findListToValidateByUser($user_id){
       return $this->findMany(
           'SELECT *, Friends.id as friend_id
           FROM '
.$this->sTable.',Users
           WHERE Users.id=Friends.user_id
           AND Friends.user_id2=?
           AND Friends.state=? '
           ,(int)$user_id
           
,self::STATE_PENDING
       
);
}
    


Revenons à notre contrôleur pour récupérer le résultat de ces requêtes
Éditer le fichier module/contacts/main.php

  
public function _list(){
   $oViewContactsAccepted=$this->getList(model_Friends::getInstance()->findListAcceptedByUser($this->user_id));
   $oViewContactsPending=$this->getList(model_Friends::getInstance()->findListPendingByUser($this->user_id));
   $oViewContactsToValidate=$this->getList(model_Friends::getInstance()->findListToValidateByUser($this->user_id));
  
   $oView
=new _view('contacts::list');
   $oView->oViewContactsAccepted=$oViewContactsAccepted;
   $oView->oViewContactsPending=$oViewContactsPending;
   $oView->oViewContactsToValidate=$oViewContactsToValidate;
   return $oView;
}
public function 
getList($tContacts){
   $oView=new _view('contacts::listembedded');
   $oView->tContacts=$tContacts;
   return $oView;
}
    


Coté vue, nous listerons ces contacts
Créez un fichier module/contacts/view/listembedded.php

  
<?php if($this->tContacts):?>
<table>
<?php foreach($this->tContacts as $oContact):?>
<tr>
<td><?php echo $oContact->lastname ?></td>
<td><?php echo $oContact->firstname ?></td>
</tr>
<?php endforeach;?>
</table>
<?php else:?>
Aucun pour le moment
<?php endif;?>
   


Éditez le fichier module/contacts/view/list.php

  
<h1>Mes contacts</h1>
<?
php echo $this->oViewContactsAccepted->show()?>

<h1>Mes demandes de contacts envoy&eacute;es</h1>
<?php echo $this->oViewContactsPending->show()?>

<h1>Les demandes de contacts &agrave; valider</h1>
<?php echo $this->oViewContactsToValidate->show()?>
   

Intégrons-le à notre module mainPrivate, pour cela, éditer le fichier module/mainPrivate/main.php
Ajoutez à la fin de la méthode _friends() (en dessous de l'inclusion du module groups)

  
$oModuleContacts
=new module_contacts();
$oModuleContacts->setUserId_root::getAuth()->getAccount()->id );
$oViewContacts=$oModuleContacts->_list();
$this->oLayout->add('main',$oViewContacts);
    



Comme vous pouvez le voir, le module "contacts" a été ajouté à la suite du module "groups", ceci grâce aux appels successifs à $this->oLayout->add() qui a ajouté les vues à l'emplacement "main"
Nous allons ensuite permettre de rechercher des utilisateurs et de leur demander de figurer parmi vos contacts.
Commençons par ajouter dans notre couche modèle une requête recherchant dans la liste des utilisateurs.
Éditez le fichier model/model_Users.php
Ajouter la méthode suivante:

  
public function findListByPattern($sPattern){
   $sPattern='%'.$sPattern.'%';
   return $this->findMany('SELECT * FROM '.$this->sTable.' WHERE lastname like ? or firstname like ?',$sPattern,$sPattern);
}
    


On effectue une recherche en base de donnée avec la commande like et en encadrant du signe pourcentage
Éditons ensuite le contrôleur pour faire l'appel et récupérez la liste des utilisateurs trouvé
Éditons le fichier module/contacts/main.php

  
public function _find(){
   $tUserFound=null;
   if(_root::getRequest()->isPost() and _root::getParam('pattern')){
       $tUserFound=model_Users::getInstance()->findListByPattern_root::getParam('pattern') );
   }
   $oView=new _view('contacts::find');
   $oView->tUserFound=$tUserFound;
   return $oView;
}
    


Editons ensuite la vue, fichier module/contacts/view/find.php

  
<hr/>
<
h1>Rechercher</h1>
<
form action="" method="POST">
<
p>Rechercher <input type="text" name="pattern" /> <input type="submit"
value="Rechercher"/></p>
</
form>
<?
php if(_root::getRequest()->isPost() and _root::getParam('pattern')):?>
   <h1>R&eacute;sultat(s) de recherche</h1>
   <?php if($this->tUserFound):?>
       <table>
       <?php foreach($this->tUserFound as $oUserFound):?>
           <tr>
           <td><?php echo $oUserFound->lastname?></td>
           <td><?php echo $oUserFound->firstname?></td>
           </tr>
       <?php endforeach;?>
       </table>
   <?php else:?>
       <p>Aucun r&eacute;sultats</p>
   <?php endif;?>
<?php 
endif;?>
   

Incluons cette recherche dans notre module mainPrivate
Ajoutez à la fin de la méthode _friends() ceci dans le fichier module/mainPrivate/main.php

  
$oViewFind
=$oModuleContacts->_find();
$this->oLayout->add('main',$oViewFind);
    


On peut désormais rechercher des utilisateurs, par exemple taper "ca"

Il trouve deux utilisateurs dont le nom ou le prénom contienne "ca"
Ajoutons maintenant un lien pour leur demander de figurer dans nos contacts.
Éditons la méthode _ask() de notre contrôleur module/contacts/main.php

  
public function _ask(){
   if(_root::getParam('id')){
       $oUserToAsk=model_Users::getInstance()->findById_root::getParam('id' ));
       if($oUserToAsk){
           //si l'utilisateur existe, on cree une demande
           $oNewContact=new row_Friends();
           $oNewContact->user_id=_root::getAuth()->getAccount()->id;
           $oNewContact->user_id2=$oUserToAsk->id;
           $oNewContact->state=model_Friends::STATE_PENDING;
           $oNewContact->save();
           _root::redirect('mainPrivate::friends');
       }
   }
}
    


Ici, en recevant l'id d'un utilisateur, on vérifie qu'il existe,on créé une demande de contact et enfin on redirige sur la page de contacts
Ajoutons un lien de demande de contact à la liste des utilisateurs trouvés
Éditons le fichier module/contacts/view/find.php et ajouter un lien

  
<hr/>
<
h1>Rechercher</h1>
<
form action="" method="POST">
<
p>Rechercher <input type="text" name="pattern" /> <input type="submit"
value="Rechercher"/></p>
</
form>
<?
php if(_root::getRequest()->isPost() and _root::getParam('pattern')):?>
<h1>R&eacute;sultat(s) de recherche</h1>
<?php if($this->tUserFound):?>
<table>
<?php foreach($this->tUserFound as $oUserFound):?>
<tr>
<td><?php echo $oUserFound->lastname?></td>
<td><?php echo $oUserFound->firstname?></td>
<td><a href="<?php echo _root::getLink('contacts::ask',
                                       array('id'=>$oUserFound->id))
                                       ?>">demander en contact</a></td>
</tr>
<?php endforeach;?>
</table>
<?php else:?>
<p>Aucun r&eacute;sultats</p>
<?php endif;?>
<?php 
endif;?>
   


En cliquant sur un de ces liens, on va faire notre demande de contacts, celle ci-va logiquement apparaître dans notre liste de demande de contacts

Si on se connecte avec un des utilisateurs à qui on a fait une demande de contact
On peut voir notre demande dans la liste des demandes à valider
Acceptons/refusons ces demandes :
Ajoutons ensuite deux liens permettant d'accepter ou de rejeter la demande
Commençons par ajouter l'action pour accepter
Éditez le fichier module/contacts/main.php

  
public function _accept(){
   $this->user_id=_root::getAuth()->getAccount()->id;
   $oContactAsked=model_Friends::getInstance()->findById_root::getParam   'id') );
   if($oContactAsked and $oContactAsked->user_id2==$this->user_id){
       //on check qu'on a bien trouve la demande et qu'elle nous est bien adresse
       $oContactAsked->accept();
       _root::redirect('mainPrivate::friends');
   }
}
    


Lors d'une acceptation, on récupère d'abord la demande de contact, on vérifie que la demande concerne bien l'utilisateur connecté, si c'est le cas on l'accepte. Et on redirige sur la page contacts.
Dirigeons nous vers la couche modèle pour ajouter cette methode accept()
Éditer le fichier model/model_Friends.php

  
class row_Friends extends abstract_row{
   protected $sClassModel='model_Friends';
   (...)
   public function accept(){
       model_Friends::getInstance()->accept($this);
   }
}
    


Pour éviter d'alourdir notre classe row, on fait appel à sa classe mère
Pour rappel: la classe model_** execute les requêtes et retourne un tableau d'objet row_**
Donc ajoutons cette méthode accept, dans le même fichier, ajouter dans la classe model_Friends cette methode accept()

  
class model_Friends extends abstract_model{
(...)
public function 
accept($oContactAsked){
   $oContactAsked->state=self::STATE_ACCEPTED;
   $oContactAsked->save();
}
    


Ici on modifie l'état de la demande pour la valider, puis on enregistre.
Faisons de même pour le refus, ce qui donnera pour la classe row_Friends

  
class row_Friends extends abstract_row{
   protected $sClassModel='model_Friends';
   public function accept(){
       model_Friends::getInstance()->accept($this);
   }
   public function refuse(){
       model_Friends::getInstance()->refuse($this);
   }
   (...)
}
    


Et pour la classe model_Friends

  
class model_Friends extends abstract_model{
   protected $sClassRow='row_Friends';
   protected $sTable='Friends';
   protected $sConfig='socialnetwork';
   protected $tId=array('id');
   const STATE_PENDING=0;
   const STATE_ACCEPTED=1;
   const STATE_REFUSED=2;
   (...)
   public function accept($oContactAsked){
       $oContactAsked->state=self::STATE_ACCEPTED;
       $oContactAsked->save();
   }
   public function refuse($oContactAsked){
       $oContactAsked->state=self::STATE_REFUSED;
       $oContactAsked->save();
   }
}
    


Sans oublier l'action dans le module Contacts
Éditer le fichier module/contacts/main.php pour modifier notre méthode _refuse()

  
public function _refuse(){
   $this->user_id=_root::getAuth()->getAccount()->id;
   $oContactAsked=model_Friends::getInstance()->findById_root::getParam('id') );
   if($oContactAsked and $oContactAsked->user_id2==$this->user_id){
       //on check qu'on a bien trouve la demande et qu'elle nous est bien adresse
       $oContactAsked->refuse();
       _root::redirect('mainPrivate::friends');
   }
}
    


Vous noterez que c'est quasiment la même action que _accept()
Maintenant, il ne reste plus qu'à ajouter des liens vers ces actions
Modifions le fichier module/contacts/main.php

  
public function _list(){
   $oViewContactsAccepted=$this->getList(model_Friends::getInstance()->findListAcceptedByUser($this->user_id));
   $oViewContactsPending=$this->getList(model_Friends::getInstance()->findListPendingByUser($this->user_id));
   $oViewContactsToValidate=$this->getListToValidate(model_Friends::getInstance()->findListToValidateByUser($this->user_id));
  
   $oView
=new _view('contacts::list');
   $oView->oViewContactsAccepted=$oViewContactsAccepted;
   $oView->oViewContactsPending=$oViewContactsPending;
   $oView->oViewContactsToValidate=$oViewContactsToValidate;
   return $oView;
}
public function 
getList($tContacts){
   $oView=new _view('contacts::listembedded');
   $oView->tContacts=$tContacts;
   return $oView;
}
public function 
getListToValidate($tContacts){
   $oView=new _view('contacts::listembeddedToValidate');
   $oView->tContacts=$tContacts;
   return $oView;
}
    


Éditez le fichier module/contacts/listembeddedToValidate.php

  
<?php if($this->tContacts):?>
<table>
<?php foreach($this->tContacts as $oContact):?>
<tr>
              <td><?php echo $oContact->lastname ?></td>
              <td><?php echo $oContact->firstname ?></td>
              <td>
                   <a href="<?php echo _root::getLink('contacts::accept',
                               array('id'=>$oContact->friend_id))
                               ?>">Accepter</a>
               </td>
               <td>
                   <a href="<?php echo _root::getLink('contacts::refuse',
                               array('id'=>$oContact->friend_id))
                               ?>">Refuser</a>

               </td>
          
</tr>
<?php endforeach;?>
</table>
<?php else:?>
Aucun pour le moment
<?php endif;?>
   

Ainsi, si on se connecte avec les comptes des utilisateurs à qui on a demandé nos deux liens
Connecté en Albert Camus

On va l'accepter
De nouveau connecté à john doe

Organisons ensuite nos contacts
On a des contacts, c'est bien, mais on aimerait bien les regrouper, les organiser par exemple dans les groupes précédemment créés
On va modifier l'action show de notre module groups qui actuellement ne sert pas à grand chose

Éditons la méthode _show() de son contrôleur dans le fichier module/Groups/main.php

  
public function _show(){
   $oGroups=model_Groups::getInstance()->findByIdmodule_Groups::getParam('id') );
   //recuperation de la liste des contacts
   $tContacts=model_Friends::getInstance()->findListAcceptedByUser($this->user_id);
   //recuperation d'un tableau contenant les membres de ce groupe
   $tIndexedMember=model_UsersGroup::getInstance()->findIndexedMemberTabByGroup$oGroups->id);
   $oView=new _view('Groups::show');
   $oView->oGroups=$oGroups;
   $oView->tContacts=$tContacts;
   $oView->tIndexedMember=$tIndexedMember;
   return $oView;
}
    


On récupère la liste des contacts de l'utilisateur ainsi que les membres de ce groupe
Créons cette méthode findIndexedMemberTabByGroup dans notre classe modèle.
Éditez le fichier model/model_UsersGroup.php
Y ajouter la méthode suivante:

  
public function findIndexedMemberTabByGroup($id){
   $tMember=$this->findMany('SELECT user_id FROM UsersGroup WHERE group_id=?',$id);
   $tIndexed=array();
   if($tMember){
       foreach($tMember as $oMember){
           $tIndexed$oMember->user_id ]=$oMember->user_id;
       }
   }
   return $tIndexed;
}
    


Occupons nous de la vue, où nous listerons les contacts et permettrons via une case à cocher, d'ajouter au groupe.
Éditez le fichier module/Groups/view/show.php

  
<h1><?php echo $this->oGroups->name ?></h1>
<form action="" method="POST">
<?php if($this->tContacts):?>
   <?php foreach($this->tContacts as $oContact):?>
   <input <?php if(isset($this->tIndexedMember$oContact->id])):
       ?>checked="checked"<?php
       
endif;?> type="checkbox" name="tContactId[]" value="<?php echo $oContact->id?>" /> <?php echo $oContact->lastname ?> <?php echo $oContact->firstname ?><br />
   <?php endforeach;?>
<?php 
endif;?>
<input type="submit" value="Modifier"/>
</form>
   

Revenons à notre contrôleur pour prendre en compte l'envoi de ce formulaire
Éditez le fichier module/Groups/main.php

  
public function _show(){
   $oGroups=model_Groups::getInstance()->findByIdmodule_Groups::getParam('id') );
   if(_root::getRequest()->isPost() and _root::getParam('tContactId')){
       model_UsersGroup::getInstance()->updateMemberForGroupWithTab($oGroups->id,_root::getParam('tContactId'));
   }
   //recuperation de la liste des contacts
   $tContacts=model_Friends::getInstance()->findListAcceptedByUser($this->user_id);
   //recuperation d'un tableau contenant les membres de ce groupe
   $tIndexedMember=model_UsersGroup::getInstance()->findIndexedMemberTabByGroup$oGroups->id);
   $oView=new _view('Groups::show');
   $oView->oGroups=$oGroups;
   $oView->tContacts=$tContacts;
   $oView->tIndexedMember=$tIndexedMember;
   return $oView;
}
    


On y a juste ajouté dans le cas d'une requête post, le traitement du tableau des cases à cocher par la méthode updateMemberForGroupWithTab() .
Ajoutons cette méthode dans notre classe modèle
Éditez le fichier model/model_UsersGroup.php et ajoutez dans la classe model_UsersGroup

  
public function updateMemberForGroupWithTab($group_id,$tContact){
   $this->execute('DELETE FROM UsersGroup WHERE group_id=?',(int)$group_id);
   if($tContact)
   foreach($tContact as $user_id){
       $oUsersGroup=new row_UsersGroup;
       $oUsersGroup->group_id=$group_id;
       $oUsersGroup->user_id=$user_id;
       $oUsersGroup->save();
   }
}
    


On commence par supprimer tous les membres avant de recréer ceux envoyés via le formulaire.
Ce qui donne:

Ici, nous pouvons ajouter des contacts, les organiser en groupe, on est prêt pour ajouter les fonctions suivantes.
Commençons par notre fil, où l'on va dans un premier temps permettre de diffuser des messages dont nous choisirons les groupes avec qui les partager.

Commençons par écrire le module de posts "page votre fil"

Lire la suite : VII Partie privée : votre fil



Téléchager le zip

Téléchargez l'archive du projet à cette étape en cliquant ici
A copier dans le répertoire data/genere du mkframework