Avoir des amis sur un forum... On se sent tout de suite moins seul, c'est plus rapide pour communiquer et puis ça met une meilleure ambiance, bref, que du bonheur

.
J'imagine que la plupart d'entre vous a déjà au moins essayé ce système sur le site du zéro mais je vais quand même expliquer le principe.
Tout se passe sur une seule page que j'ai appelée amis.php, celle-ci comme beaucoup dans ce tuto, s'articule autour d'un switch.
Tout d'abord lorsque l'on arrive sur la page, un tableau liste les amis que l'on a, à partir de là il est possible de :
- Supprimer un ami
- Ajouter un ami
- Valider la demande d'ajout d'un ami
En effet pour avoir un ami, il faut que celui-ci soit d'accord, c'est pourquoi lorsque vous voulez ajouter un membre à votre liste, il est immédiatement prévenu (par MP par exemple) qu'il doit se rendre sur sa page de gestion des amis pour valider ou supprimer cette demande.
Avant tout, il nous faut une table dans la base de données, celle-ci (
forum_amis) comprend 4 champs :
- ami_from : contient l'id du membre qui demande à ajouter un ami
- ami_to : contient l'id de l'ami en question
- ami_confirm : retourne 1 si l'amitié est réciproque, 0 sinon
- ami_date : contient la date d'ajout
Voici le code à copier :
Code : SQL | CREATE TABLE `forum_amis` (
`ami_from` int(11) NOT NULL,
`ami_to` int(11) NOT NULL,
`ami_confirm` enum('0','1') collate latin1_general_ci NOT NULL,
`ami_date` int(11) NOT NULL,
PRIMARY KEY (`ami_to`,`ami_from`)
)
|
Allez on commence de suite
Déjà le début de la page est très classique, il faut simplement récupérer la valeur de
action qui se trouve dans l'url et s'assurer que le visiteur est bien connecté.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | <?php
session_start();
$titre="Gestion des amis";
include("includes/identifiants.php");
include("includes/debut.php");
include("includes/menu.php");
$action = isset($_GET['action'])?htmlspecialchars($_GET['action']):'';
echo '<p><i>Vous êtes ici</i> : <a href="./index.php">Index du forum</a> --> <a href="./amis.php">Gestion des amis</a>';
if ($id==0) erreur(ERR_IS_CO);
//Le titre
echo '<h1>Gestion des amis</h1><br /><br />';
?>
|
Comme prévu, rien de très compliqué ni de nouveau
Ajouter un ami
Pour ajouter un ami, on propose au membre un champ dans lequel il écrira le pseudo de cette personne, ensuite il faut lancer une série de tests pour s'assurer qu'il n'y a pas de problème.
Tout d'abord le formulaire :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13 | <?
switch($action)
{
case "add": //On veut ajouter un ami
if (!isset($_POST['pseudo']))
{
echo '<form action="amis.php?action=add" method="post">
<p><label for="pseudo">Entrez le pseudo</label>
<input type="text" name="pseudo" id="pseudo" />
<input type="submit" value="Envoyer" />
</p></form>';
}
?>
|
Comme vous voyez, on ne lance le formulaire que si la variable
$_POST['pseudo'] est vide, c'est-à-dire si on vient d'arriver sur la page.
Ensuite pour la batterie de tests, j'ai prévu 3 conditions :
- L'ami doit exister

- L'ami ne doit pas être déjà présent dans la liste d'ami, ni en cours de demande
- L'ami ne doit pas être le membre en question
On va donc traduire ça en php.
Code : PHP 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 | <?php
else
{
$pseudo_d = $_POST['pseudo'];
//On vérifie que le pseudo renvoit bien quelque chose :o
$query=$db->prepare('SELECT membre_id, COUNT(*) AS nbr FROM forum_membres
WHERE LOWER(membre_pseudo) = :pseudo GROUP BY membre_pseudo');
$query->bindValue(':pseudo',strtolower($pseudo_d),PDO::PARAM_STR);
$query->execute();
$data = $query->fetch();
$pseudo_exist = $data['nbr'];
$i = 0;
$id_to=$data['membre_id'];
if(!$pseudo_exist)
{
echo '<p>Ce membre ne semble pas exister<br />
Cliquez <a href="./amis.php?action=add">ici</a> pour réessayer</p>';
$i++;
}
$query->CloseCursor();
$query = $db->prepare('SELECT COUNT(*) AS nbr FROM forum_amis
WHERE ami_from = :id AND ami_to = :id_to
OR ami_from = :id AND ami_to = :id_to');
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->bindValue(':id_to', $id_to, PDO::PARAM_INT);
$query->execute();
$deja_ami=$query->fetchColumn();
$query->CloseCursor();
if ($deja_ami != 0)
{
echo '<p>Ce membre fait déjà parti de vos amis ou a déjà proposé son amitié :p<br />
Cliquez <a href="./amis.php?action=add">ici</a> pour réessayer</p>';
$i++;
}
if ($id_to == $id)
{
echo '<p>Vous ne pouvez pas vous ajouter vous même<br />
Cliquez <a href="./amis.php?action=add">ici</a> pour réessayer</p>';
$i++;
}
if ($i == 0)
{
$query=$db->prepare('INSERT INTO forum_amis (ami_from, ami_to, ami_confirm, ami_date)
VALUES(:id, :id_to, :conf, :temps)');
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->bindValue(':id_to', $id_to, PDO::PARAM_INT);
$query->bindValue(':conf','0',PDO::PARAM_STR);
$query->bindValue(':temps', time(), PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
echo '<p><a href="/voirprofil.php?m='.$data['membre_id'].'">'.stripslashes(htmlspecialchars($pseudo_d)).'</a>
a bien été ajouté à vos amis, il faut toutefois qu il donne son accord.<br />
Cliquez <a href="./index.php">ici</a> pour retourner à l index du forum<br />
Cliquez <a href="./amis.php">ici</a> pour retourner à la page de gestion des amis</p>';
}
}
?>
|
Comme vous le voyez, la variable
$i s'occupe de compter le nombre d'erreur. Même si je vois mal comment il peut y en avoir plusieurs en même temps

, cela permet de savoir si on peut lancer la requête ou non.
Voilà vous pouvez à présent demander à ajouter des amis ce qui est quand même un premier pas

.
On va à présent voir la validation de ces demandes.
Validation des demandes
Cette partie du switch se présente de la façon suivante :
On affiche un tableau qui liste les membres qui vous ont voulu comme ami mais dont vous n'avez pas encore validé la demande.
Pour chacun on propose un lien vers l'acceptation et un autre vers le refus.
De la même façon, il va falloir vérifier qu'on vient d'arriver sur la page (auquel cas on affiche le tableau) ou qu'on a déjà fait son choix (dans ce cas on lance les requêtes).
Code : PHP 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
case "check":
$add = (isset($_GET['add']))?htmlspecialchars($_GET['add']):0;
if (empty($add))
{
$query = $db->prepare('SELECT ami_from, ami_date, membre_pseudo FROM forum_amis
LEFT JOIN forum_membres ON membre_id = ami_from
WHERE ami_to = :id AND ami_confirm = :conf
ORDER BY ami_date DESC');
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->bindValue(':conf','0',PDO::PARAM_STR);
$query->execute();
echo '<table align="center"><tr>
<th class="pseudo"><strong>Pseudo</strong></th>
<th class="inscrit"><strong>Date d ajout</strong></th>
<th><strong>Action</strong></th></tr>';
if ($query->rowCount() == 0)
{
echo '<td colspan="3" align="center">Vous n avez aucune proposition</td>';
}
while ($data = $query->fetch())
{
echo '<tr><td><a href="./voirprofil.php?m='.$data['ami_from'].'&action=consulter">'.stripslashes(htmlspecialchars($data['membre_pseudo'])).'</a></td>
<td>'.date('d/m/Y',$data['ami_date']).'</td>
<td><a href="./amis.php?action=check&add=ok&m='.$data['ami_from'].'">Accepter</a> -
<a href="./amis.php?action=delete&m='.$data['ami_from'].'">Refuser</a>
</td></tr>';
}
$query->CloseCursor();
}
?>
|
Si vous étudiez un peu les deux liens, vous verrez que dans ce switch on ne va s'occuper que du cas où vous acceptez la demande de validation. On récupère la valeur de l'ami qui se trouve dans l'url sous le nom de
m. C'est par ailleur la présence, ou l'absence de cette variable qui nous indique si on doit afficher le tableau ou si on doit lancer les requêtes.
D'ailleurs on va voir les requêtes de suite
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | <?php
else
{
$membre = (int) $_GET['m'];
$query = $db->prepare('UPDATE forum_amis SET ami_confirm = :conf
WHERE ami_from = :membre AND ami_to = :id');
$query->bindValue(':conf','1',PDO::PARAM_STR);
$query->bindValue(':membre',$membre,PDO::PARAM_INT);
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->execute();
$query->closeCursor();
echo '<p>Le membre a bien été ajouté à votre liste d ami<br />
Cliquez <a href="./amis.php">ici</a> pour retourner à la liste des amis';
}
break;
?>
|
On change la valeur du champ
ami_confirm à 1 et le tour est joué !
Hep attends une minute, dans la base de données on aura tantôt des membres qui seront dans les listes en tant que ami_to ou ami_from !
Oui mais ça ne pose pas de problème, il suffira de s'arranger avec la requête pour ne pas oublier de cas. En fait à partir du moment où la demande est validée, la différence entre les champs
ami_to et
ami_from n'existe plus.
Allez on file vers la suppression et puis on aura gagné !
Supprimer un ami
Derrière ce titre très ambigu (

) se cache la dernière partie de notre switch.
La suppression d'un ami peut être de deux natures, soit vous voulez vous débarrasser d'un ami que vous avez depuis un moment et dont vous avez déjà validé la demande d'ajout. Soit vous voulez refuser une demande d'ajout.
L'avantage c'est qu'on a même pas besoin de faire la différence entre les deux, il suffit de récupérer la valeur de l'id du membre et de le virer de la base de données.
En revanche, comme il s'agit d'une suppression, il faut s'assurer que ce n'est pas une erreur en demandant une confirmation.
Code : PHP 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 | <?php
case "delete":
$membre = (int) $_GET['m'];
if (!isset($_GET['ok']))
{
echo '<p>Etes vous certain de vouloir supprimer ce membre ?<br />
<a href="./amis.php?action=delete&ok=ok&m='.$membre.'">oui</a> - <a href="./amis.php">non</a></p>';
}
else
{
$query = $db->prepare('DELETE FROM forum_amis WHERE ami_from = :membre AND ami_to = :id');
$query->bindValue(':membre',$membre,PDO::PARAM_INT);
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->execute();
$query->closeCursor();
$query = $db->prepare('DELETE FROM forum_amis WHERE ami_to = :membre AND ami_from = :id');
$query->bindValue(':membre',$membre,PDO::PARAM_INT);
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->execute();
$query->closeCursor();
echo '<p>Membre correctement supprimé :D <br />
Cliquez <a href="./amis.php">ici</a> pour retourner à la liste des amis</p>';
}
break;
?>
|
Vous voyez que comme on ignore si le membre se trouve au champ ami_to ou ami_from, on supprime les deux sans faire de distinction.
Il est tout de même important de prévenir l'ami en question, vous pouvez vous arranger pour qu'il reçoive le cas échéant un MP pour le prévenir. Il est en est d'ailleurs de même pour les demandes d'ajout, les validations etc...
Enfin on affiche la liste des amis
Je vais passer vite là dessus étant donné que c'est ce que l'on a fait dans le premier chapitre.
Code : PHP 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 | <?php
default:
$query = $db->prepare('SELECT (ami_from + ami_to - :id) AS ami_id, ami_date, membre_pseudo, online_id
FROM forum_amis
LEFT JOIN forum_membres ON membre_id = (ami_from + ami_to - :id)
LEFT JOIN forum_whosonline ON online_id = membre_id
WHERE (ami_from = :id OR ami_to = :id) AND ami_confirm = :conf ORDER BY membre_pseudo');
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->bindValue(':conf','1',PDO::PARAM_STR);
$query->execute();
echo '<table align="center"><tr>
<th class="pseudo"><strong>Pseudo</strong></th>
<th class="inscrit"><strong>Date d ajout</strong></th>
<th><strong>Action</strong></th>
<th><strong>Connecté</strong></th></tr>';
if ($query->rowCount() == 0)
{
echo '<td colspan="4" align="center">Vous n avez aucun ami pour l instant</td>';
}
while ($data = $query->fetch())
{
echo '<tr><td><a href="./voirprofil.php?m='.$data['ami_id'].'&action=consulter">'.stripslashes(htmlspecialchars($data['membre_pseudo'])).'</a></td>
<td>'.date('d/m/Y',$data['ami_date']).'</td>
<td><a href="./messagesprives.php?action=repondre&dest='.$data['ami_id'].'">Envoyer un MP</a><br />
<a href="./amis.php?action=delete&m='.$data['ami_id'].'">Supprimer</a></td>';
if (!empty($data['online_id'])) echo '<td>Oui</td>'; else echo '<td>Non</td>';
echo '</tr>';
}
echo '</table>';
$query->CloseCursor();
//On compte le nombre de demande en cours et on met quelques liens
$query=$db->prepare('SELECT COUNT(*) FROM forum_amis
WHERE ami_to = :id AND ami_confirm = :conf');
$query->bindValue(':id',$id,PDO::PARAM_INT);
$query->bindValue(':conf','0', PDO::PARAM_STR);
$query->execute();
$demande_ami=$query->fetchColumn();
//Cette ligne va permettre d'afficher 0 plutôt qu'un vide
if (empty($demande_ami)) $demande_ami=0;
echo '<br /><ul>
<li><a href="./amis.php?action=add">Ajouter un ami</a></li>
<li><a href="./amis.php?action=check">Voir les demandes d\'ajout ('.$demande_ami.')</a></li></ul>';
break;
}
?>
</div>
</body></html>
|
Alors un arrêt important sur cette requête, c'est une méthode assez astucieuse proposée par
tarekbouchkati dans les commentaires du tuto. En fait on ne veux pas récupérer les entrées de le base de donnée qui concerne le membre connecté en tant qu'ami (sinon on aurait son propre nom dans la liste d'amis puisqu'il n'est pas possible de faire la différence).
Avec cette méthode, on ne va garder que l'id qui n'est pas celle du membre et ainsi afficher le bon nom. C'est un peu étrange mais je vous laisse réfléchir à ce que donnerait le résultat de la requête en piochant indifféremment dans ami_from et ami_to.
Pour le reste c'est du classique, on récupère tout ce qui concerne le membre dans la table
forum_amis puis on affiche. Maintenant c'est à vous de personnaliser cette page comme ça vous arrange.
Si vous voulez connaitre le nombre de demandes d'amis en cours, il vous suffit d'utiliser la dernière requête de ce script
En général, il est très utile comme sur le SDZ de mettre dans le menu la liste des amis connectés ce qui n'est pas très compliqué si vous avez suivi jusque ici
