Bonjour,
Je suis actuellement en train de créer un site avec un système de messagerie où chaque message se présente sous forme de conversation.
Le but de cette messagerie est donc que chacun des deux utilisateurs puisse lire la conversation. S'il décide de la supprimer, l'autre doit continuer à pouvoir la lire. Si l'un des deux envoie un nouveau message, la conversation s'affiche comme il faut, à partir de ce nouveau message pour celui qui l'avait supprimée auparavant.
Et bien entendu, qui dit messagerie dit notification en cas de nouveau message.
À partir de ces éléments, je vous fais part de ma structure en base de données, bien que j'envisage de la modifier afin de ne pas restreindre une conversation à deux utilisateurs.
J'ai donc actuellement une table "conversation", composée des champs suivants :
c_id,
c_user_one (utilisateur X - id du premier utilisateur à avoir engagé la conversation),
c_user_two (utilisateur Y - id du destinataire du premier message qui a créé la conversation),
c_status (qui permet de savoir si oui ou non la conversation est lue pour indiquer au destinataire du message le plus récent de la conversation qu'il a un nouveau message),
c_show_one (utilisateur X - pour afficher ou non la conversation - dans le cas où il l'a supprimée, il n'y a pas lieu d'afficher la conversation dans sa boîte de réception),
c_last_msg_id_one (utilisateur X - l'id du dernier message avant qu'il ne supprime la conversation),
c_show_two (utilisateur Y - même principe que c_show_one),
c_last_msg_id_two (utilisateur Y - même principe que c_last_msg_id_two)
Et j'ai une table "messages", composée des champs suivants :
msg_id,
msg_user_id (expéditeur du message),
msg_status (à l'insertion en base de données, il est à zéro, faisant ainsi passer le statut de la conversation correspondante à zéro également),
msg_conversation (l'id de la conversation à laquelle appartient le message)
Jusqu'à présent tout se déroule comme je le voulais. Le seul problème que je rencontre concerne la suppression d'une conversation.
En effet, pour afficher la boîte de réception d'un utilisateur, j'effectue ma requête, mais bloque sur un détail : comment, dans ma requête, déterminer si l'utilisateur est le "c_user_one", ou le "c_user_two" ? En effet, il se peut qu'il ait 5 conversations, mais pas toutes engagées par lui-même, ce qui fait que son id peut se retrouver dans la colonne "c_user_one", comme dans "c_user_two".
J'ai tenté une requête dynamique, en indiquant que si "c_user_one/two" = l'id de l'utilisateur alors la variable prenait une valeur différente, mais il ne l'applique pas à chacune des conversations et m'affiche donc toutes les conversations (vides du coup).
Donc j'en viens à vous demander, si mon problème vous parle, si quelqu'un voit une autre façon de procéder ou aurait une piste sur la façon de résoudre mon problème. :)
Ou encore, si mon message n'est pas assez clair, un petit signe et je clarifie tout ça !
D'avance merci pour votre réponse !
Je te propose une autre solution, qui devrait régler au moins deux soucis:
Le champ parent_message te permet de savoir si le message est en réponse a précédent (tu peux faire une hiérarchie complexe), ou pour faire plus simple tu peux simplement affecter un id unique a un fil de conversation si tu ne veux pas de hiérarchie de réponses.
La table de jointure user_message te permet de très facilement d'ajouter autant de destinataires que tu le veux (donc plus que 2), et permet a un destinataire de supprimer un message (en fait supprimer sa relation a un message) sans le supprimer de la bdd (en faisant un delete de son entré dans la table user_message seulement, les autres users y auront donc toujours acces).
Tout d'abord, merci Vallyan pour ta réponse, j'espérais y arriver pour valider ta réponse, malheureusement, je bloque toujours sur le "même souci" concernant la suppression d'une conversation par l'un des utilisateurs.
Ton idée de table à part pour établir un lien entre un utilisateur et un message pour que la suppression n'engendre pas la suppression du message est bonne. Bien que je ne supprimais pas le message avant non plus, cette façon de faire correspond à mes besoins pour les cas de conversations à plusieurs utilisateurs.
Lorsqu'un utilisateur envoie un message, je fais une vérification pour savoir si la conversation entre les deux existe déjà ou non. Dans le cas où elle existe, j'ajoute simplement le message à la suite, sinon je crée également la conversation afin de lier les utilisateurs.
En reprenant ton idée, j'ai créé la table user_message, en y ajoutant également le champ "conversation_id". Mais si un des utilisateurs supprime la conversation et donc son lien aux messages, je ne peux plus afficher cette conversation chez l'autre utilisateur puisque c'est la seule table où un lien est effectué entre les deux (ou plus) utilisateurs.
Avant, ce lien était fait dans la table "conversation" (voir mon message précédent reprenant la structure de ma table), mais j'avais un problème de boucle pour déterminer si l'utilisateur était le destinataire ou l'expéditeur puisque cette notion est variable.
L'affichage de la boîte de réception sous forme de fils de discussion fonctionnait nickel jusqu'à cette option de suppression d'une conversation qui me donne du fil à retordre.
J'espère que mon message est assez clair et que quelqu'un pourra m'apporter ses lumières :)
Déja, je pense que l'appartenance ou non d'un message a une conversation ne devrait pas se faire en cherchant dans la bdd. Sur quoi porterait cette recherche ? Ce que je suggere, c'est un formulaire avec un champ caché. Lors d'un nouveau message (nouvelle discussion), tu lui assignes une valeur unique (fonction uniqid() de php). Par contre lorsqu'il sagit d'une réponse a un message, tu passes l'uniqid du message précédant dans ton formulaire, pour conserver un meme ID pour tous les messages d'une conversation.
Ensuite pour ce qui est de la table user_message:
Pour commencer je ne comprends pas la logique d'y ajouter un champ conversation_id. Chaque message ne peut appartenir qu'a une seule conversation, or le conversation_id est déja un champ de ta table message (avec le titre, le contenu, etc ...).
D'autre part, Ce que je crois comprendre de ta réponse, c'est que lorsqu'un user supprime sa relation a un message (donc une entré de la table user_message), alors il est impossible de retrouver tous les destinataires intiaux si un autre user fait une réponse (tu veux que meme si on supprime un message, on puisse recevoir la réponse quand meme). Tu peux, pour cela modifier, la table user_message en ajoutant un champs (booléen) deleted. Par défaut il est a false pour un nouveau message, et peut passer a true si un user décide de supprimer ce message. sa relation avec le message est donc toujours la dans la base, mais le message ne s'affichera plus dans son inbox. Du coup lors d'une réponse, il est facile de retrouver tous les destinataires initiaux.
Une autre possibilité, peut-etre plus simple a coder, et de partir du principe que un user peut supprimer toute une conversation, et s'il y a un nouveau messgae, toute la conversation ré-apparait (ce qui au final me semble plus judicieux). Dans ce cas impossible de supprimer uniquement certains messages de la conversation. Le principe reste le meme:
Une table message
Eventuellement une table conversation
Une table user_conversation qui fait la jointure entre tes conversations et tes users, et qui précise si une conversation a ete supprimée par un user. Lors d'un nouveau message dans la conversation, tous les champs deleted sont remis a false.