Une messagerie interne


Voici un petit comment faire une messagerie interne basée sur le comment faire un espace membre.

En effet, car qui dit messagerie interne, dit forcément espace membre :)
Je me vois mal envoyer des messages à personne.

Pour la suite de ce comment faire, je vous suggère donc de récupérer d'une part, les pages PHP, et d'autre part, la table SQL de cet espace membre.
Nous allons apporter quelques modifications à ces pages PHP tout en ajoutant de nouvelles pages PHP.



Les premières modifications que nous allons apporter aux pages du comment faire un espace membre concernent les pages index.php et inscription.php.
En effet, pour plus de simplicité afin de gérer notre messagerie interne, et en fait, pour mieux reconnaître le membre connecté à l'espace membre, nous allons utiliser son id (qu'il a dans la table membre) plutôt que son login pour effectuer divers opérations

On aura alors le code suivant pour la page index.php :

index.php
  1. <?php
  2. if (isset($_POST['connexion']) && $_POST['connexion'] == 'Connexion') { 
  3.    if ((isset($_POST['login']) && !empty($_POST['login'])) && (isset($_POST['pass']) && !empty($_POST['pass']))) { 
  4.  
  5.       $base = mysql_connect ('serveur', 'login', 'password'); 
  6.       mysql_select_db ('nom_base', $base); 
  7.  
  8.       $sql = 'SELECT id FROM membre WHERE login="'.mysql_escape_string($_POST['login']).'" AND pass_md5="'.md5(mysql_escape_string($_POST['pass'])).'"'; 
  9.       $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error()); 
  10.       $nb = mysql_num_rows($req); 
  11.  
  12.       if ($nb == 1) { 
  13.          $data = mysql_fetch_array($req); 
  14.  
  15.          session_start(); 
  16.          $_SESSION['login'] = $_POST['login']; 
  17.          // on enregistre en plus l'id du membre dans une variable de session 
  18.          $_SESSION['id'] = $data['id']; 
  19.  
  20.          mysql_free_result($req); 
  21.          mysql_close(); 
  22.  
  23.          header('Location: membre.php'); 
  24.          exit(); 
  25.       } 
  26.       elseif ($nb == 0) { 
  27.          $erreur = 'Compte non reconnu.'; 
  28.       } 
  29.       else { 
  30.          $erreur = 'Probème dans la base de données : plusieurs membres ont les mêmes identifiants de connexion.'; 
  31.       } 
  32.       mysql_free_result($req); 
  33.       mysql_close(); 
  34.    } 
  35.    else { 
  36.       $erreur = 'Au moins un des champs est vide.'; 
  37.    }  
  38. }  
  39. ?>
  40. <html>
  41. <head>
  42. <title>Accueil</title>
  43. </head>
  44.  
  45. <body>
  46. Connexion à l'espace membre :<br />
  47. <form action="index.php" method="post">
  48. Login : <input type="text" name="login" value="<?php if (isset($_POST['login'])) echo stripslashes(htmlentities(trim($_POST['login']))); ?>"><br />
  49. Mot de passe : <input type="password" name="pass" value="<?php if (isset($_POST['pass'])) echo stripslashes(htmlentities(trim($_POST['pass']))); ?>"><br />
  50. <input type="submit" name="connexion" value="Connexion">
  51. </form>
  52. <a href="inscription.php">Vous inscrire</a>
  53. <?php
  54. if (isset($erreur)) echo '<br /><br />',$erreur;  
  55. ?>
  56. </body>
  57. </html> 


Peu de commentaires à faire sur cette page, puisque nous avons en fait simplement ajouter une variable de session contenant l'id du membre qui se connecte.

Ensuite, cette modification doit également se répercuter sur la page inscription.php, puisque si le visiteur s'inscrit proprement, il est directement reconnu comme membre et il est directement redirigé vers l'espace membre.

Il faut donc également que les nouveaux inscris possèdent leur id en variable de session.

On aura alors le code suivant pour la page inscription.php :

inscription.php
  1. <?php
  2. if (isset($_POST['inscription']) && $_POST['inscription'] == 'Inscription') { 
  3.    if ((isset($_POST['login']) && !empty($_POST['login'])) && (isset($_POST['pass']) && !empty($_POST['pass'])) && (isset($_POST['pass_confirm']) && !empty($_POST['pass_confirm']))) { 
  4.       if ($_POST['pass'] != $_POST['pass_confirm']) { 
  5.          $erreur = 'Les 2 mots de passe sont différents.'; 
  6.       } 
  7.       else { 
  8.          $base = mysql_connect ('serveur', 'login', 'password'); 
  9.          mysql_select_db ('nom_base', $base); 
  10.  
  11.          $sql = 'SELECT id FROM membre WHERE login="'.mysql_escape_string($_POST['login']).'"'; 
  12.          $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error()); 
  13.          $nb = mysql_num_rows($req); 
  14.  
  15.          if ($nb == 0) { 
  16.             $sql = 'INSERT INTO membre VALUES("", "'.mysql_escape_string($_POST['login']).'", "'.md5(mysql_escape_string($_POST['pass'])).'")'; 
  17.             mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error()); 
  18.  
  19.             // on récupère l'id de notre nouveau membre 
  20.             $id = mysql_insert_id(); 
  21.  
  22.             session_start(); 
  23.             $_SESSION['login'] = $_POST['login']; 
  24.             
  25.             // on stocke cet id dans une variable de session 
  26.             $_SESSION['id'] = $id; 
  27.             header('Location: membre.php'); 
  28.             exit(); 
  29.          } 
  30.          else { 
  31.             $erreur = 'Un membre possède déjà ce login.'; 
  32.          } 
  33.       } 
  34.    } 
  35.    else { 
  36.       $erreur = 'Au moins un des champs est vide.'; 
  37.    }  
  38. }  
  39. ?>
  40. <html>
  41. <head>
  42. <title>Inscription</title>
  43. </head>
  44.  
  45. <body>
  46. Inscription à l'espace membre :<br />
  47. <form action="inscription.php" method="post">
  48. Login : <input type="text" name="login" value="<?php if (isset($_POST['login'])) echo stripslashes(htmlentities(trim($_POST['login']))); ?>"><br />
  49. Mot de passe : <input type="password" name="pass" value="<?php if (isset($_POST['pass'])) echo stripslashes(htmlentities(trim($_POST['pass']))); ?>"><br />
  50. Confirmation du mot de passe : <input type="password" name="pass_confirm" value="<?php if (isset($_POST['pass_confirm'])) echo stripslashes(htmlentities(trim($_POST['pass_confirm']))); ?>"><br />
  51. <input type="submit" name="inscription" value="Inscription">
  52. </form>
  53. <?php
  54. if (isset($erreur)) echo '<br />',$erreur;  
  55. ?>
  56. </body>
  57. </html> 


Voila une bonne chose de faite :)

Concentrons maintenant sur le développement de notre messagerie interne, et réfléchissons à nos besoins (en terme de table SQL et de page PHP) pour amener à bien notre projet.

Qu'est ce qu'un message ?

Un message, c'est tout simplement :
- deux utilisateurs A et B (A étant l'auteur du message qui écrit à B étant le destinataire du message).
- un titre
- une date d'émission
- le message en lui-même :)

D'après cette petite réflexion, on peut décider de la structure de notre table SQL stockant les messages de notre messagerie interne.

Personnellement, je vous propose cette table :

table messages
  1. CREATE TABLE messages (
  2. id int(11) NOT NULL auto_increment,
  3. id_expediteur int(11) NOT NULL default '0',
  4. id_destinataire int(11) NOT NULL default '0',
  5. date datetime NOT NULL default '0000-00-00 00:00:00',
  6. titre text NOT NULL,
  7. message text NOT NULL,
  8. PRIMARY KEY (id)
  9. ) TYPE=MyISAM; 


En effet, nous avons :
- un attribut id qui nous permettra d'identifier chaque message de la messagerie
- un attribut id_expediteur qui correspondra à l'id d'une des entrées de la table membre (jointure)
- un attribut id_destinataire qui correspondra à l'id d'une des entrées de la table membre (jointure)
- une date
- un titre pour notre message
- et le message en lui-même

Ensuite, en ce qui concerne les pages PHP à réaliser, nous devons :
- modifier la page membre.php de l'espace membre afin qu'elle affiche les messages qu'a reçu le membre qui se connecte à l'espace membre
- créer une page lire.php qui permettra de lire les messages
- créer une page envoyer.php qui permettra au membre d'envoyer des messages privés aux autres membres du site
- créer une page supprimer.php qui permettra de supprimer les messages de sa "boite" interne

Pour notre page membre.php, nous devons donc lancer une requête SQL qui ira chercher le titre, l'auteur mais aussi la date des messages qu'aura le membre qui se connecte à l'espace membre.
Et c'est là que va intervenir notre variable de session contenant l'id du membre qui se connecte.
En effet, cette variable va nous donner un énorme service puisque je vous le rappelle, dans notre table SQL messages, nous stockons les auteurs et les destinataires des messages avec l'id des membres et non leur login.

Nous aurons donc pour la page membre.php :

membre.php
  1. <?php
  2. session_start();  
  3. // on vérifie toujours qu'il s'agit d'un membre qui est connecté  
  4. if (!isset($_SESSION['login'])) { 
  5.    // si ce n'est pas le cas, on le redirige vers l'accueil 
  6.    header ('Location: index.php'); 
  7.    exit();  
  8. }  
  9. ?>
  10.  
  11. <html>
  12. <head>
  13. <title>Espace membre</title>
  14. </head>
  15.  
  16. <body>
  17. Bienvenue<?php echo stripslashes(htmlentities(trim($_SESSION['login']))); ?>!<br /><br />
  18. <?php
  19. $base = mysql_connect ('serveur', 'login', 'password');  
  20. mysql_select_db ('nom_base', $base);  
  21.  
  22. // on prépare une requete SQL cherchant tous les titres, les dates ainsi que l'auteur des messages pour le membre connecté  
  23. $sql = 'SELECT titre, date, membre.login as expediteur, messages.id as id_message FROM messages, membre WHERE id_destinataire="'.$_SESSION['id'].'" AND id_expediteur=membre.id ORDER BY date DESC';  
  24. // lancement de la requete SQL  
  25. $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());  
  26. $nb = mysql_num_rows($req);  
  27.  
  28. if ($nb == 0) { 
  29.    echo 'Vous n\'avez aucun message.';  
  30. }  
  31. else { 
  32.    // si on a des messages, on affiche la date, un lien vers la page lire.php ainsi que le titre et l'auteur du message 
  33.    while ($data = mysql_fetch_array($req)) { 
  34.       echo $data['date'] , ' - <a href="lire.php?id_message=' , $data['id_message'] , '">' , stripslashes(htmlentities(trim($data['titre']))) , '</a> [ Message de ' , stripslashes(htmlentities(trim($data['expediteur']))) , ' ]<br />'; 
  35.    }  
  36. }  
  37. mysql_free_result($req);  
  38. mysql_close();  
  39. ?>
  40. <br /><a href="envoyer.php">Envoyer un message</a>
  41. <br /><br /><a href="deconnexion.php">Déconnexion</a>
  42. </body>
  43. </html> 


Passons maintenant à la page lire.php.

La page lire.php est un peu particulière.
Cette page doit être sécurisée.

En effet, vous avez remarquez que dans la page membre.php, nous faisons un lien vers la page lire.php afin que les membres puissent lire les messages qu'ils ont reçu.
Or, afin d'identifier le message que le membre veut lire, nous passons en argument au script lire.php l'id du message.
Il est alors facile d'imaginer que les visiteurs pourront modifier simplement cet argument puisque celui-ci sera visible dans la barre d'adresse du navigateur.

Il est donc impératif de vérifier, à chaque lecture de message, si le message est bien destiné au membre qui est actuellement connecté à l'espace membre.

Sans tenir compte de ce problème, une requête SQL de la forme :

select
  1. <?php
  2. $sql = 'SELECT titre, date, message, membre.login as expediteur FROM messages, membre WHERE id_expediteur=membre.id AND messages.id="'.$_GET['id_message'].'"';  
  3. ?> 


aurait suffit.

Une méthode simple et qui ne coûte pas cher afin d'éviter ce problème est de carrément spécifier dans la requête SQL que l'id_destinataire doit avoir la même valeur que notre variable de session contenant l'id du membre connecté.

Nous aurons donc pour la page lire.php le code suivant :

lire.php
  1. <?php
  2. session_start();  
  3. // on vérifie toujours qu'il s'agit d'un membre qui est connecté  
  4. if (!isset($_SESSION['login'])) { 
  5.    // si ce n'est pas le cas, on le redirige vers l'accueil 
  6.    header ('Location: index.php'); 
  7.    exit();  
  8. }  
  9. ?>
  10.  
  11. <html>
  12. <head>
  13. <title>Espace membre</title>
  14. </head>
  15.  
  16. <body>
  17. <a href="membre.php">Retour à l'accueil</a><br /><br />
  18. <?php
  19. // on teste si notre paramètre existe bien et qu'il n'est pas vide  
  20. if (!isset($_GET['id_message']) || empty($_GET['id_message'])) { 
  21.    echo 'Aucun message reconnu.';  
  22. }  
  23. else { 
  24.    $base = mysql_connect ('serveur', 'login', 'password'); 
  25.    mysql_select_db ('nom_base', $base); 
  26.    
  27.    // on prépare une requete SQL selectionnant la date, le titre et l'expediteur du message que l'on souhaite lire, tout en prenant soin de vérifier que le message appartient bien au membre connecté 
  28.    $sql = 'SELECT titre, date, message, membre.login as expediteur FROM messages, membre WHERE id_destinataire="'.$_SESSION['id'].'" AND id_expediteur=membre.id AND messages.id="'.$_GET['id_message'].'"'; 
  29.    // on lance cette requete SQL à MySQL 
  30.    $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error()); 
  31.    $nb = mysql_num_rows($req); 
  32.  
  33.    if ($nb == 0) { 
  34.       echo 'Aucun message reconnu.'; 
  35.    } 
  36.    else { 
  37.       // si le message a été trouvé, on l'affiche 
  38.       $data = mysql_fetch_array($req); 
  39.       echo $data['date'] , ' - ' , stripslashes(htmlentities(trim($data['titre']))) , '</a> [ Message de ' , stripslashes(htmlentities(trim($data['expediteur']))) , ' ]<br /><br />'; 
  40.       echo nl2br(stripslashes(htmlentities(trim($data['message'])))); 
  41.       
  42.       // on affiche également un lien permettant de supprimer ce message de la boite de réception 
  43.       echo '<br /><br /><a href="supprimer.php?id_message=' , $_GET['id_message'] , '">Supprimer ce message</a>'; 
  44.    } 
  45.    mysql_free_result($req); 
  46.    mysql_close();  
  47. }  
  48. ?>
  49. <br /><br /><a href="deconnexion.php">Déconnexion</a>
  50. </body>
  51. </html> 


Passons maintenant à la page envoyer.php.
Pour cette page, il n'y a aucune difficulté.

En effet, il s'agit juste de proposer un formulaire contenant 3 champs :
- un menu déroulant avec tous les membres du site afin de spécifier le destinataire du message
- un champ de type text pour donner le titre du message
- une zone de texte permettant d'écrire son message

Nous ferons toutefois attention à ne pas mentionner le nom du membre connecté dans la liste des destinataires potentiels.
En effet, ça serait dommage que l'on puisse écrire à soit même :)

Nous aurons alors le code suivant pour la page envoyer.php :

envoyer.php
  1. <?php
  2. session_start();  
  3. // on vérifie toujours qu'il s'agit d'un membre qui est connecté  
  4. if (!isset($_SESSION['login'])) { 
  5.    // si ce n'est pas le cas, on le redirige vers l'accueil 
  6.    header ('Location: index.php'); 
  7.    exit();  
  8. }  
  9.  
  10. // on teste si le formulaire a bien été soumis  
  11. if (isset($_POST['go']) && $_POST['go'] == 'Envoyer') { 
  12.    if (empty($_POST['destinataire']) || empty($_POST['titre']) || empty($_POST['message'])) { 
  13.       $erreur = 'Au moins un des champs est vide.'; 
  14.    } 
  15.    else { 
  16.       $base = mysql_connect ('serveur', 'login', 'password'); 
  17.       mysql_select_db ('nom_base', $base); 
  18.       
  19.       // si tout a été bien rempli, on insère le message dans notre table SQL 
  20.       $sql = 'INSERT INTO messages VALUES("", "'.$_SESSION['id'].'", "'.$_POST['destinataire'].'", "'.date("Y-m-d H:i:s").'", "'.mysql_escape_string($_POST['titre']).'", "'.mysql_escape_string($_POST['message']).'")'; 
  21.       mysql_query($sql) or die('Erreur SQL !'.$sql.'<br />'.mysql_error()); 
  22.  
  23.       mysql_close(); 
  24.  
  25.       header('Location: membre.php'); 
  26.       exit(); 
  27.    }  
  28. }  
  29. ?>
  30.  
  31. <html>
  32. <head>
  33. <title>Espace membre</title>
  34. </head>
  35.  
  36. <body>
  37. <a href="membre.php">Retour à l'accueil</a><br /><br />
  38. Envoyer un message :<br /><br />
  39.  
  40. <?php
  41. $base = mysql_connect ('serveur', 'login', 'password');  
  42. mysql_select_db ('nom_base', $base);  
  43.  
  44. // on prépare une requete SQL selectionnant tous les login des membres du site en prenant soin de ne pas selectionner notre propre login, le tout, servant à alimenter le menu déroulant spécifiant le destinataire du message  
  45. $sql = 'SELECT membre.login as nom_destinataire, membre.id as id_destinataire FROM membre WHERE id <> "'.$_SESSION['id'].'" ORDER BY login ASC';  
  46. // on lance notre requete SQL  
  47. $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());  
  48. $nb = mysql_num_rows ($req);  
  49.  
  50. if ($nb == 0) { 
  51.    // si aucun membre n'a été trouvé, on affiche tout simplement aucun formulaire 
  52.    echo 'Vous êtes le seul membre inscrit.';  
  53. }  
  54. else { 
  55.    // si au moins un membre qui n'est pas nous même a été trouvé, on affiche le formulaire d'envoie de message 
  56.    ?>
  57.    <form action="envoyer.php" method="post">
  58.    Pour :<select name="destinataire">
  59.    <?php
  60.    // on alimente le menu déroulant avec les login des différents membres du site 
  61.    while ($data = mysql_fetch_array($req)) { 
  62.       echo '<option value="' , $data['id_destinataire'] , '">' , stripslashes(htmlentities(trim($data['nom_destinataire']))) , '</option>'; 
  63.    } 
  64.    ?>
  65.    </select><br />
  66.    Titre : <input type="text" name="titre" value="<?php if (isset($_POST['titre'])) echo stripslashes(htmlentities(trim($_POST['titre']))); ?>"><br />
  67.    Message : <textarea name="message"><?php if (isset($_POST['message'])) echo stripslashes(htmlentities(trim($_POST['message']))); ?></textarea><br />
  68.    <input type="submit" name="go" value="Envoyer">
  69.    </form>
  70.    <?php
  71. }  
  72. mysql_free_result($req);  
  73. mysql_close();  
  74. ?>
  75. </select>
  76.  
  77. <br /><br /><a href="deconnexion.php">Déconnexion</a>
  78. <?php
  79. // si une erreur est survenue lors de la soumission du formulaire, on l'affiche  
  80. if (isset($erreur)) echo '<br /><br />',$erreur;  
  81. ?>
  82. </body>
  83. </html> 


Reste enfin à nous concentrer sur la page supprimer.php.

Comme vous l'avez remarqué, dans la page lire.php, nous affichons un lien permettant de supprimer le message en cours de lecture.
Et comme pour la page lire.php, nous passons en argument au script supprimer.php l'id du message qui doit être effacé.
Nous devons alors donc bien vérifier dans la page supprimer.php que le message qui est en cours de suppression appartient bien au membre qui essaye de le supprimer.

Nous utiliserons la même technique que pour vérifier que le message en cours de lecture appartient bien au membre qui essaye de le lire, c'est-à-dire que nous utiliserons la variable de session contenant l'id du membre.

On aura alors pour supprimer.php :

supprimer.php
  1. <?php
  2. session_start(