[RESOLU] Créer une messagerie privé à la manière Facebook

Eléphant du PHP | 386 Messages

02 oct. 2013, 21:13

Bonjour,

J'ai une question :

Comment rendre une messagerie privé en conversations (comme Facebook) qui lient 2 membres ?
J'ai pensé à créer 2 tables : "messages" et "conversations"

Ensuite je ne trouve plus comment faire :(

Merci pour votre aide

Mammouth du PHP | 504 Messages

02 oct. 2013, 22:36

hello,

En fait te faut, par exemple.

Une table amis qui lient les deux amis.

Une message qui contient le message de départ, id_sender, id_receiver (par exemple)

Et une qui comprend les reply du message de depart: id_message_depart, id_sender, id_receveiver, date (order by date à l'affichage)

Eléphant du PHP | 79 Messages

03 oct. 2013, 01:56

Bonjour,

N'étant pas sur facebook j'ai quelques questions à te poser pour comprendre ta question. Quand tu parles de messagerie privée, c'est un messagerie instantané ou bien des messages que tu postes sur un "mur" avec lequel des gens peuvent participer ?

ciao

Eléphant du PHP | 386 Messages

03 oct. 2013, 17:05

Merci pour vos réponses

Je remplacerais la table amis par la table membre.
Je préfère un système de messagerie sans que les membres soient amis.

Donc une table messages : msg_id - msg_sender - msg_receiver
Et une table reponses : id_msg_depart - msg_sender - msg_receiver - msg_date

Comment lier ces 2 tables pour faire une liste de conversations, comme quand on clique sur
l'icone des messages dans Facebook :

Image

orenx22 : C'est une messagerie interne avec liste de conversations (voir photo) qui renvois vers la conversation en détail avec la liste des messages.

Merci

Eléphant du PHP | 79 Messages

03 oct. 2013, 18:11

J'exploiterai ce genre de relation personnellement :

Image
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `mydb` ;

-- -----------------------------------------------------
-- Table `mydb`.`membre`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`membre` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `mail` VARCHAR(45) NOT NULL ,
  `mdp` VARCHAR(45) NOT NULL ,
  `session` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  `nom` TEXT NULL ,
  `prenom` TEXT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `mydb`.`contact`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`contact` (
  `membre` INT NOT NULL ,
  `ami` INT NOT NULL ,
  `date` TIMESTAMP NOT NULL ,
  PRIMARY KEY (`membre`, `ami`) ,
  INDEX `fk_membre_has_membre_membre1_idx` (`ami` ASC) ,
  INDEX `fk_membre_has_membre_membre_idx` (`membre` ASC) ,
  CONSTRAINT `fk_membre_has_membre_membre`
    FOREIGN KEY (`membre` )
    REFERENCES `mydb`.`membre` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_membre_has_membre_membre1`
    FOREIGN KEY (`ami` )
    REFERENCES `mydb`.`membre` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `mydb`.`message`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `mydb`.`message` (
  `expediteur` INT NOT NULL ,
  `destinataire` INT NOT NULL ,
  `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  `contenu` TEXT NOT NULL ,
  PRIMARY KEY (`expediteur`, `destinataire`) ,
  INDEX `fk_membre_has_membre_membre3_idx` (`destinataire` ASC) ,
  INDEX `fk_membre_has_membre_membre2_idx` (`expediteur` ASC) ,
  CONSTRAINT `fk_membre_has_membre_membre2`
    FOREIGN KEY (`expediteur` )
    REFERENCES `mydb`.`membre` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_membre_has_membre_membre3`
    FOREIGN KEY (`destinataire` )
    REFERENCES `mydb`.`membre` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

USE `mydb` ;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

un membre possède un id unique, un mail et mot de passe pour s'identifier, et quelques informations personnelles tels que nom, prénom et une valeur 'session' qui va permettre de savoir si le membre est connecter ou non.

Un membre a une liste de contact qui regroupe les membres avec lesquels il est ami depuis une date donnée.

Un membre (expéditeur) envoi un message à un contact (destinataire), ce message est daté et contient du texte.

Voilà, n'hésite pas à passer du temps sur ton administration MYSQL et d’exécuter toutes les requêtes sql que tu auras besoin avant de commencer à coder.

Exemple :

- créer un membre
- faire une demande à un membre pour l'ajouter au contact
- sélectionner la liste des contacts d'un membre
- envoyer un message
- sélectionner la liste des messages d'un membre ordonné par date

En espérant t'avoir aider, n'hésite pas a me pm si tu veux plus d'aider.

Ciao

Eléphant du PHP | 386 Messages

03 oct. 2013, 19:59

orenx22 : Je t'ai envoyé un mp ;)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

03 oct. 2013, 21:13

salut,

pour le fil de discussion tu as oublié l'auto jointure sur la table message :mrgreen:

@noco44530 : dommage de ne pas faire participer les autres de tes questions (et des réponses associées ;) )


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 386 Messages

03 oct. 2013, 22:13

Ce que je voudrais, c'est une sorte de messagerie interne regroupée en conversation (comme sur Facebook)
Ça dois bien exister en php/sql ce genre de chose ^^

Mammouth du PHP | 504 Messages

03 oct. 2013, 23:10

@ nico, je ne comprend pas trop, ce que tu veux exactement. dans ce qu'i est là, tu as tout ce qu'il te faut.

Je crois que ton soucis est plutot la "notion d'affichage" des données (en fait la logique d'affichage).

Je vais essayé de faire simple:

on a la table_message: msg_id - msg_sender - msg_receiver (il manque la date et je mettrai également le tout premier message de l'utilisateur A vers le l'utilisateur B)
et la table_réponse ( qui elle ne contient que les reply au message de départ) id_msg_depart - msg_sender - msg_receiver - msg_date (il manque date et corps de message)

Tu dois partir du principe que lorsque l'utilisateur envoi ou se met sur sa messagerie, il est logué, donc un id_membre_en_cours.

Donc en fait sa boite de reception est pour lui msg_receiver.

Donc tu SELECT * FROM table_message WHERE msg_receiver = id_membre_en_cours ORDER BY date DESC

=> tu as tout les sujets et personnes qui ont envoyés un message à ton utilisateur qui consulte sa boite de reception.

et en ensuite quand il clique sur l'un des "sujets de messages", il accéde au fil de sa discution
=> SELECT * FROM table_réponse WHERE id_msg_depart = msg_id ORDER BY date DESC

Voili, voilou... . Si tu veux faire un mur comme fb, le principe est le meme sauf que tu rajoute de l'ajax pour l'insertion et l'affichage des données.

Eléphant du PHP | 386 Messages

04 oct. 2013, 00:20

Et le principe de conversations groupées ?

Par exemple :

Je suis le membre1
J'envois un message au membre2 = "Salut"
Il me renvois = "Ca va"

J'aimerais que ces messages sont groupés en une conversation et que le dernier message soit affiché chez les 2 membres concernés.

Mammouth du PHP | 504 Messages

04 oct. 2013, 01:11

oui, c'est groupé là.

table_message: msg_id - msg_sender - msg_receiver - messagedébutconversation
1 - membre1 - membre2 - Salut

table_reply: id_msg_depart - msg_sender - msg_receiver - msgreply - msg_date
1 - membre2 - membre1 - ça va - 03/10/13
1 - membre1 - membre2 - Et toi ? - 04/10/13
etc..etc...

Tu as dans ta table reply le chemin de la conversation en fonction du sujet ou message de départ id_msg_depart

La table_message te sert à stocker le tout premier message qui enclenche la conversation ensuite. En suite toute les reponses à cette conversation (en gros le bouton reply ou le textarea qui est juste sous ce message) vont envoyer tous tes reply dans la table table_reply avec comme clef id_msg_depart.

Si le membre envoi un nouveau message le 05/10/13 (qui n'est pas un reply mais un nouveau message, tu auras:

table_message: msg_id - msg_sender - msg_receiver - messagedébutconversation
1 - membre1 - membre2 - Salut
2 - membre1 - membre3 - tu vas au ski? (nouveau sujet ou nouveau message, tu mets ce que tu veux dans le champ -))

table_reply: id_msg_depart - msg_sender - msg_receiver - msgreply - msg_date
1 - membre2 - membre1 - ça va - 03/10/13
1 - membre1 - membre2 - Et toi ? - 04/10/13
2 - membre3 - membre1 - Oui à tignes - 05/10/13

Tu affiches qui a ecrit à qui et le premier ou dernier message
comme sur fb:
la photo: c'est le membre qui t'a envoyé un message (msg_receiver)
le fil d'info: la dernier reply du dernier sujet evoqué avec le membre.

Je peux difficilement faire plus simple. ou si peut etre:

tu traitres dans tes select d'abord la table_message ORDER BY date DESC. un fois cela fait pour l'affichage final, tu prends en considération la date du dernier reply (relié à table_message id_msg_depart) adressé au membre dans table_reply. et tu affiches le tous en fonction de la date la plus récente des reply mais par id_msg_depart.

Eléphant du PHP | 386 Messages

04 oct. 2013, 02:04

Merci beaucoup :D

J'ai ajouté un champ à "table_reply" :

- reply_id : AUTO_INCREMENT, pour compter le nombre de message dans la conversation.

Je vais faire un schéma sur papier pour mieux faire la requête et je vais faire comme tu as dit, ensuite je posterais la requête que j'aurais fait.

Eléphant du PHP | 386 Messages

04 oct. 2013, 03:02

Pour l'instant je sais juste comment faire pour afficher les premiers messages reçus (messagedébutconversation)
Pour grouper les messages et afficher le dernier message de la conversation (fil d'infos), là c'est un peu dur pour moi :?

Pourrais-tu m'aider pour la fin de la requête ?
Voici celle que j'ai créé :
<?php
$req = $connect->prepare('
SELECT * FROM msg 
LEFT JOIN users ON msg_sender = users.id 
WHERE msg_receiver = :id ORDER BY msg_date DESC');
$req->execute(array(':id'=>$_SESSION['id']));
if($req->rowCount() == 0){
echo '<li id="noMsg">Votre boite de réception est vide.</li>';
} else {
while($msg = $req->fetch()){
echo '<li>';
echo '<a href="messages/'.$msg['msg_id'].'" class="msgBox_nonlu">';
echo '<img src="../img/upload/'.$msg['id'].'-mini.jpg" class="floatl avatarMsg" height="50" width="50" alt="" />';
echo '<div style="line-height: 17px;">';
echo '<div class="author">'.ucfirst($msg['prenom']).' '.ucfirst($msg['nom']).'</div>';
echo '<div class="message">'.$msg['first_message'].'</div>';
echo '<div class="time">'.getRelativeTime($msg['msg_date']).'</div>';
echo '</div>';
echo '</a>';
echo '</li>';
} } $req->closeCursor(); ?>
Voilà
Merci beaucoup d'avance :)