Posts non-lus dans un forum

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 : Posts non-lus dans un forum

par momox » 31 juil. 2006, 00:54

Tout compte fait, j'ai réussi a comprendre comment faire plus simplement.
Au lieu d'un grignotage intempestif de ressources j'en suis quitte a un bon mal de tête.
Mon principe est assez simple en lui même.
Bon, on récupere le dernier post du forum et on en fait un vérification par rapport a la dernière visite de l'utilisateur.
Pour ce qui est des posts non lus, même methode sauf qu'il y a une petite nuance.
Pour ne pas marquer tous le posts d'un coup, on va marquer un cookie contanant la date de visite précedente.
Ensuite, a lecture d'un forum, on compare chaque message par rapport a l'ancienne date de visite qui est contenue dans un cookie.
Ensuite, si on lit un post, on met un marqueur dans la bdd contenant l'id du topic et l'id de l'utilisateur.
Donc ce que l'on fait ensuite quand on consulte un forum, c'est que l'on marque "lus" les topics dont la date du dernier message est inférieur a la date de dernière visite contenue dans le cookie.
Ensuite, a l'aide des conditions, on vérifie que les autres messages declarès non-lus par la condition ci-dessus ne sont pas marqués lus dans la bdd.
Ensuite, dans le cas ou un utilisateur aurait posté un message dans un topic que vous auriez précedemment lu, la requete inserant son message va supprimer la reference a la lecture du dit topic dans la bdd et cela va faire en sorte que le message sera a nouveau non-lu.
Ensuite, le dernier truc, le plus simple, c'est que si je veux marquer tous les messages comme lus, j'ai juste a supprimer le cookie car la bdd est mise a jour a chaque clic concernant la date de dernière visite.

Ouf, enfin réussi...
Si ca ne parait pas assez clair a certains, je peux leur expliquer des points donnés selon les zones d'ombres qu'il ne comprendraient pas dans ce que je viens de dire :)
@+

par momox » 31 juil. 2006, 00:19

Je fais remonter un peu le sujet par rapport a l'approche que naholyr m'avait faite...
La question que je me pose pour le moment est surtout au niveau des catégories, car comment savoir si un message est non-lu dans telle catégorie afin de le marquer?
C'est un peu bizarre comme question...
Et en plus, la requête que j'avais imaginé necessitait a mon gout trop de ressources... :gla:
@+

par naholyr » 14 juin 2006, 19:34

Il va alors falloir multiplier le nombre de lignes par le nombre d'utilisateurs, ou alors un post lu par quelqu'un apparait lu pour tout le monde.

Je ne sais pas quel système utiliser phpBB, mais personnellement je gèrerais ça avec une tierce table : posts_lus (user_id, post_id).

Définir qu'un post est lu : REPLACE INTO posts_lus (user_id,post_id) VALUES ($user_id, $post_id) (REPLACE est identique à INSERT, au détail près que si la ligne à insérer existe déjà pour une clé primaire ou unique, la ligne est supprimée avant insertion, ce qui évite de faire une requête de vérification en plus pour rien).
Définir qu'un post est non lu : DELETE FROM posts_lus WHERE user_id=$user_id AND post_id=$post_id
Savoir si un post est lu : SELECT 1 FROM posts_lus WHERE used_id=$user_id AND post_id=$post_id doit renvoyer une ligne.
Savoir qui a lu un post : SELECT user_id FROM posts_lus WHERE post_id=$post_id
Récupérer la liste des posts lus : SELECT post_id FROM posts_lus WHERE user_id=$user_id

Les inconvénients de cette approche :
- la table va grossir très rapidement, dès que quelqu'un lit un post, la table gagne une ligne. Ainsi elle ne fera que grossir, et ne maigrira a priori jamais (sauf suppression de post ou d'utilisateur).
- la fonction "marquer tous les posts comme lus" pour l'utilisateur est fortement consommatrice de ressources.
- la fonction "voir tous les sujets non lus" est également fortement consommatrice.

Une autre approche serait peut-être plus intelligente : une table posts_non_lus (user_id, post_id).

Définir qu'un post est non lu : REPLACE INTO posts_non_lus (user_id,post_id) VALUES ($user_id, $post_id).
Définir qu'un post est lu : DELETE FROM posts_non_lus WHERE user_id=$user_id AND post_id=$post_id.
Savoir si un post est lu : SELECT 1 FROM posts_lus WHERE used_id=$user_id AND post_id=$post_id ne doit rien renvoyer.
Marquer tous les sujets comme lus : DELETE FROM posts_non_lus WHERE user_id=$user_id.

Cette approche résout les problèmes de l'approche précédente (la taille variera continuellement, mais tendra idéalement vers 0), mais impose d'ajouter une opération couteuse au moment de l'envoi de chaque nouveau sujet :

Code : Tout sélectionner

$query = "INSERT INTO posts_non_lus (user_id, post_id) VALUES "; $q_users = mysql_unbuffered_query("SELECT id FROM users"); while ($row = mysql_fetch_row($q_users)) { $query .= " ({$row[0]}, $post_id),"; } mysql_query(substr($query,0,-1));
Deux requêtes dont une assez lourde, dont on peut diminuer l'impact grâce à unbufferd_query.

Les fonctions "savoir qui a lu tel post" et "quels posts a lu tel users" sont équivalentes à leurs homologues de l'approche précédente. Mais on peut considérer qu'elles sont moins souvent nécessaires que "savoir quels posts n'ont pas été lus par tel user".

Voilà une petite analyse de ce que je ferais, j'opterais probalement pour la seconde approche. À voir maintenant : comment font les forums "célebres" qui implémentent cette fonction.

par jojolapine » 14 juin 2006, 18:55

tu peux rajouter un champ lus de type enum('nonlus','lus') dans ta table de posts, et lorsque qq va sur la page voir_post_numero_tant.php, tu change le champ à 'lus'...

Posts non-lus dans un forum

par momox » 14 juin 2006, 16:27

Bijour tout le monde :D
Dans mon inexirable quête de savoir je me suis posé une question...
Comment faire un systéme de posts non-lus sur un forum de ma création, sachant que celui-ci est multi-catégories a la facon de punbb?
Il doit y avoir une méthode pour gerer les données que je ne dois pas saisir...
Il faut faire cela d'un certaine facon mais je n'arrive pas a comprendre la technique...
@+ et merci d'avance !