[RESOLU] forum : comment repérer pour un user les messages non lus ?

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] forum : comment repérer pour un user les messages non lus ?

Re: [RESOLU] forum : comment repérer pour un user les messag

par moresk24 » 11 juin 2014, 06:39

ok, alors je ferai attention à cela dorénavant o)

Re: [RESOLU] forum : comment repérer pour un user les messag

par Ryle » 10 juin 2014, 23:13

En fait, la plupart des SGBD sont sensibles aux types des données. Dans un champ texte, ils attendent une chaine de caractères, dans un champ date ils attendent une date formatée, dans un champ numérique, ils attendent des nombres.

Les apostrophes en SQL servent à délimiter les chaînes de caractères (char, varchar, text, date, ...). Du coup, si tu mets un nombre entre apostrophe, le moteur de base de données peut considérer qu'il ne s'agit plus d'un nombre mais d'une chaine et considérer que ce format est incompatible par rapport au type de la colonne en base (pour une opération mathématique tu fais 2+3, pas '2'+'3' :))

Aujourd'hui certains SGBD comme MySQL ou MySQLi tolèrent cette syntaxe et font les conversions nécessaires aux mêmes. Mais du coup :
- le sgbd doit faire un travail de conversion supplémentaire (bon, ok, ça se compte en pouillème de millisecondes, mais c'est pas une raison ;))
- le jour où tu dois travailler sur oracle, sql server ou db2, tes requêtes ne fonctionneront plus et tu risques de passer un certain temps à t'arracher les cheveux avant de comprendre pourquoi (alors que tu peux prendre de bonnes habitudes des maintenant :))

Re: [RESOLU] forum : comment repérer pour un user les messag

par moresk24 » 10 juin 2014, 21:09

je prends note de tout ceci o)

pkoi pas de parenthèse autour des variables contenant des nombres ?

Re: forum : comment repérer pour un user les messages non lu

par Ryle » 10 juin 2014, 17:51

SELECT me.idmessage, me.texte
FROM messages me 
LEFT JOIN messages-user mu ON me.idmessage = mu.idmessage
WHERE mu.idmessage IS NULL OR mu.idmessage=''
AND me.idmembre = '$un-id-de-membre' 
Attention à la syntaxe de cette requête :
- l'opérateur AND est prioritaire sur le OR, du coup s'il n'y a pas de parenthèses autour, le moteur SQL retournera tous les résultats pour lesquels idmessage est null (quel que soit l'utilisateur) OU tous les idmessage vides pour le membre spécifié. Avec des parenthèse, on applique l'id du membre aux deux conditions :
( mu.idmessage IS NULL OR mu.idmessage='' ) AND me.idmembre = '$un-id-de-membre'
- en l'occurrence, le champ idmessage ne sera jamais vide. Soit il est null car par d'enregistrement trouvé dans la table, soit il est renseigné avec un id, donc on peut oublier le OU et les parenthèses ;)
- à éviter également, les apostrophes autour des nombres. idmembre est certainement un champ numérique, du coup, pas d'apostrophes pour la valeur qu'on lui envoi :
me.idmembre = $un-id-de-membre

:)

Re: forum : comment repérer pour un user les messages non lu

par moresk24 » 10 juin 2014, 12:38

ah oui en effet, je dois chercher les messages qui n'ont pas de correspondance ds la table associative.
ok ça me va parfaitement.

j'ai créé la table associative, 3 fonctions (AjoutLu, RetireLu et IsLu) et mis les appels à ces fonctions où il le fallait. ça fonctionne. Et enfin avec cette dernière requête imbriquée je vais pouvoir sortir la liste des messages à lire pour l'utilisateur lamda.
Tout ce que je voulais ;-)

merci bcp pour cette aide messieurs, je peux cliquer sur 'RESOLU'

Stève

Re: forum : comment repérer pour un user les messages non lu

par yann18 » 10 juin 2014, 10:46

dans la table messages-user tu n'as plus besoin du champ lu car cette table contient tous les messages lus.
Cette requête pour sélectionner les 'messages non lu' d'un utilisateur est elle la bonne ?
avec une requête imbriqée, tu vas selectionner tous les messages de la table messages qui n'ont aucune correspondance dans la table messages-user:
SELECT * FROM messages WHERE idmessage NOT IN (SELECT idmessage FROM messages-user)
ou avec une jointure à gauche:

SELECT me.idmessage, me.texte
FROM messages me 
LEFT JOIN messages-user mu ON me.idmessage = mu.idmessage
WHERE mu.idmessage IS NULL OR mu.idmessage=''
AND me.idmembre = '$un-id-de-membre' 

Re: forum : comment repérer pour un user les messages non lu

par moresk24 » 09 juin 2014, 20:43

Merci pour cette explication claire.
je comprends l'intérêt ds mon cas d'utiliser ce type de fonctionnement

Mais alors, parlons code :
Cette requête pour sélectionner les 'messages non lu' d'un utilisateur est elle la bonne ?

SELECT idmessage, texte
FROM messages
JOIN messages-user
ON messages.idmessage = messages-user.idmessage
WHERE idmembre = '$un-id-de-membre' AND messages-user.lu = '0'

Merci

Re: forum : comment repérer pour un user les messages non lu

par yann18 » 09 juin 2014, 20:06

et lorsque qu'un message est rajouté à ce topic (sujet ?) il faut détruite toutes les lignes ayant l'id_topic pour que de nouveau il soit 'à lire' ?

bon :
je crée une table topic_lu ( champs : id, id_topic, idmembre)

lorsqu'un membre accède au forum, je liste les topics et avec une requete 'JOIN' je recherche les éventuels enregistrement ds la table topic_lu ; quand il n'y a pas de correspondance entre l'id_topic de la table topic (qui est la tables sujets chez moi) et de la table topic_lu pour cet id_topic et l'idmembre du membre connecté alors c que le topic contient un (au moins) message non lu
quand le membre ouvre ce topic et donc lit les message qu'il contient, je crée ds la table l'enregistrement => 'id_topic, idmembre'.
quand un utilisateur lambda rajoute un message à un topic :
- je supprime toutes les lignes de la table topic_lu qui ont l'idtopic de ce topic pour obligé le site à le donner comme à lire aux autres membres)
- j'ajoute l'enregistrement 'id_topic, idmembre' de ce membre lambda dans la table 'topic_lu' afin que ça ne soit pas un topic 'à lire' pour ce membre lambda, vu que c lui qu'il l'aura alimenté. (et je fais même pareil à la création d'un topic, afin que le créateur d'un topic n'ait pas ds sa liste 'nouveau message' ce topic).

Mais bon.... je vois pas bien ou est et à koi sert alors ma table associative (auquel je ne comprends pas grand chose)

malgré tout... suis je sur la bonne voie ?...

Merci de l'aide o)
je suis désolé je n'ai pas vu ton dernier message donc mon dernier message ne répond pas complètement à ta question mais le dernier intervenant l'a déjà fait.

Re: forum : comment repérer pour un user les messages non lu

par Ryle » 09 juin 2014, 19:47

Pour répondre au fonctionnement de la table associative :

En fait les tables associatives répondent à un besoin relationnel de type N::N, c'est à dire que pour chacun des enregistrements d'une table (chacun de tes utilisateurs) on peut retrouver de 0 à N correspondance dans une autre table (un utilisateur peut avoir lu ou non, tout ou partie ou même aucun des messages de ton forum).

Pour des relations 1::N (ou 0::N), on ajoute simplement un champ dans la seconde table, faisant référence à la clé primaire de la première :
Un utilisateur appartient à une et une seule société (1), mais une société peut employer de 1 à N collaborateurs. On ajoute donc un id_société dans la table des utilisateurs pour savoir dans quelle société il travail.

Pour les relations N::N, on utilise une table intermédiaire de relation dans laquelle on va retrouver uniquement deux informations : la clé primaire de la première table et la clé primaire de la seconde table (id_utilisateur, id_message). On ajoutera ensuite un enregistrement dans cette table pour chaque relation entre un utilisateur et un message.
En gros, si l'utilisateur n°5 lit le message 42, tu ajoutes un enregistrement (5, 42), s'il lit ensuite le 65, tu ajoutes de même (5, 65). Tu peux ainsi connaitre les messages lus par cet utilisateurs (tous les messages dont l'id est associé à l'utilisateur 5 dans cette table). Et de même, tu peux retrouver les messages non lus en cherchant tous les messages qui n'ont aucune référence dans cette table pour l'utilisateur d'id 5.

Tu pourrais même ainsi gérer la notion de "marquer le message comme non lu" en retirant l'enregistrement correspondant de cette table.

J'espère que c'est plus clair comme ça :)

Après le nombre élevé d'enregistrement dans cette table n'est pas un soucis (enfin ça dépendra du nombre d'utilisateurs et de messages). Les BDD sont conçues pour gérer des millions d'enregistrements. C'est beaucoup d'insertions à chaque fois que quelqu'un consulte un topic puisque tous les messages qu'il découvre doivent être ajoutés, mais l'avantage, c'est que s'il ne lit que les messages de la première page, les autres ne seront pas marqués comme lus. :)

Re: forum : comment repérer pour un user les messages non lu

par yann18 » 09 juin 2014, 19:04

une fois cette table 'associative' créée... comment doit on la mettre à jour ?
encore une fois suis désolé logiquement il faut plutôt insérer l'id du message et l'id de l'utilisateur dans la table user-message(merci XTG ) et non mettre à jour. Dans le cas d'espère l'id de l'utilisateur est connu(stocké en session au moment de de l'authentification) et l'id du message est transmis dans l'url.

dans la page html où tu affiche l'ensemble des messages(y compris les messages lus):
<?php while ($row = $dbh->fetch() ) { ?>
<a href="message-lu.php?message_id=<?php echo $row['message_id']?>"><?php echo $row['sujet'] ?> </a>

<?php } ?>

côté php pour on récupère l'id du message transmis via l'url puis on insère cet id et l'id de l’utilisateur dans la table message-user.
<?php
//script d'insertion id message et id user
//message-user.php
 $dbh = new PDO('mysql:host=localhost;dbname=nom_bd;charset=utf8', 'user', 'password');  
$user_id=$_SESSION['user_id'];
if( isset($_GET['message_id']) ){
    $stmt = $dbh->prepare("INSERT INTO messages-user VALUES(:user_id, :message_id)");

    $stmt->execute(array(':user_id' => $user_id, ':message_id'=> $_GET['message_id']));


}
?
Pour afficher les messages non lus ou lus une simple requête avec jointure sur les tables :user, messages-user et messages.

Re: forum : comment repérer pour un user les messages non lu

par moresk24 » 09 juin 2014, 18:50

Si tu pars sur une table associative il faut créer un enregistrement uniquement quand l'utilisateur lit le topic.
Donc tu peux même dégager le champ booléen de cette table. ;)
et lorsque qu'un message est rajouté à ce topic (sujet ?) il faut détruite toutes les lignes ayant l'id_topic pour que de nouveau il soit 'à lire' ?

bon :
je crée une table topic_lu ( champs : id, id_topic, idmembre)

lorsqu'un membre accède au forum, je liste les topics et avec une requete 'JOIN' je recherche les éventuels enregistrement ds la table topic_lu ; quand il n'y a pas de correspondance entre l'id_topic de la table topic (qui est la tables sujets chez moi) et de la table topic_lu pour cet id_topic et l'idmembre du membre connecté alors c que le topic contient un (au moins) message non lu
quand le membre ouvre ce topic et donc lit les message qu'il contient, je crée ds la table l'enregistrement => 'id_topic, idmembre'.
quand un utilisateur lambda rajoute un message à un topic :
- je supprime toutes les lignes de la table topic_lu qui ont l'idtopic de ce topic pour obligé le site à le donner comme à lire aux autres membres)
- j'ajoute l'enregistrement 'id_topic, idmembre' de ce membre lambda dans la table 'topic_lu' afin que ça ne soit pas un topic 'à lire' pour ce membre lambda, vu que c lui qu'il l'aura alimenté. (et je fais même pareil à la création d'un topic, afin que le créateur d'un topic n'ait pas ds sa liste 'nouveau message' ce topic).

Mais bon.... je vois pas bien ou est et à koi sert alors ma table associative (auquel je ne comprends pas grand chose)

malgré tout... suis je sur la bonne voie ?...

Merci de l'aide o)

Re: forum : comment repérer pour un user les messages non lu

par xTG » 09 juin 2014, 18:14

Si tu pars sur une table associative il faut créer un enregistrement uniquement quand l'utilisateur lit le topic.
Donc tu peux même dégager le champ booléen de cette table. ;)

Re: forum : comment repérer pour un user les messages non lu

par moresk24 » 09 juin 2014, 18:11

bon, je suis désolé, mais je sèche....

une fois cette table 'associative' créée... comment doit on la mettre à jour ?
quand un User crée un nouveau message, que dois je faire par rapport à cette table 'messages-user', faut il par exemple créer ds cette table autant de ligne qu'il existe de membres sur ce forum pour chaque nouveau message ???

Pour interroger cette table faut il par exemple :

les messages qu'un membre n'a pas lu :
SELECT idmessage, texte
FROM messages
JOIN messages-user
ON messages.idmessage = messages-user.idmessage
WHERE idmembre = '$un-id-de-membre' AND messages-user.lu = '0'

pas facile tout ça ma fois....

Re: forum : comment repérer pour un user les messages non lu

par moresk24 » 09 juin 2014, 16:39

bon, faut donc que je me plonge ds la notion de table associative...

j'y vais de ce pas

A plus tard alors o)

Re: forum : comment repérer pour un user les messages non lu

par yann18 » 09 juin 2014, 16:35

bonjour,
puis dans un fichier css tu peux mettre en gras les titres des massages non lu
.lu_0  {
 font-weight:bold;
}
c'est koi le 33 ?.....

suis désolé ça n'a aucune signification, c'est une coquille
.lu_0  {
 font-weight:bold;
}