Système de votes : like - dislike

Résolu
Utilisateur anonyme - Modifié par dinolam le 20/07/2016 à 18:14
 Utilisateur anonyme - 29 juil. 2016 à 22:44
Bonjour,
Je suis en train de faire un système de votes pour liker ou disliker un contenu. Mon contenu est la réponse à une question posé par un utlisateur. L'utilisateur qui a posé sa question peut liker ou disliker la ou les réponse(s) obtenue(s) par d'autres utilisateurs. Un autre utilisateur peut liker ou disliker une ou plusieurs réponse(s) s'il la trouve pertinente ou non.
J'utilise 3 tables de BD en guise d’exemple : users, reponses, votes

-- Table users :

user_id
user_name

-- Table réponses :

reponse_id
reponse_txt
user_id (fk)

-- Table votes :

vote_id
vote_like (int)
vote_dislike (int)
user_id (fk)
reponse_id (fk)

Mon système de vote fonctionne quand je suis connecté et quand je clic sur like ou dislike. Mon problème est le fait que quand j'ai plusieurs réponses je ne peux pas liker ou disliker plus d'une réponse avec une même session utilisateur. Et même quand je change de session, je ne peux pas liker ou dislike car j'ai toujours le message "vous avez voté ce contenu auparavant".

Or j'aimerais que d'autres utilisateurs connectés puissent voter. Si un utilisateur n'est pas connecté on le lui demande. Voici le résumé de mon code ci-dessous :


<!-- Partie HTML boutons like - dislike -->
<div class="vote" id="<?=isset($row['reponse_id'])?$row['reponse_id']:'';?>">
<div class="vote_btn">
<div class="btn_like"><img src="thumbs-up.png" alt="like"></div><span class="votes_like">0</span>
</div>
<div class="vote_btn">
<div class="btn_dislike"><img src="thumb-down.png" alt="dislike"></div><span class="votes_dislike">0</span>
</div>
</div>

// Partie jquery
$(document).ready(function() {
    $.each($('.vote'), function(){
        var id = $(this).attr("id");
        //console.log(id);
        post_d = {'id':id, 'vote':'fetch'};
        $.post('vote.php', post_d,  function(response) {
            $('#'+id+' .votes_like').text(response.vote_like);
            $('#'+id+' .votes_dislike').text(response.vote_dislike);
        },'json');
    });
    $(".vote .vote_btn").click(function(e) {
        var click_button = $(this).children().attr('class');
        var id = $(this).parent().attr("id");
        if (click_button==='btn_dislike') {
            post_d = {'id':id, 'vote':'dislike'};
            $.post('vote.php', post_d, function(data) {
                $('#'+id+' .votes_dislike').text(data);
                alert("Merci de votre vote !");
            }).fail(function(err) {
                alert(err.statusText);
            });
        } else if(click_button==='btn_like') {
            post_d = {'id':id, 'vote':'like'};
            $.post('vote.php', post_d, function(data) {
                $('#'+id+' .votes_like').text(data);
                alert("Merci de votre vote !");
            }).fail(function(err) {
                alert(err.statusText);
            });
        }
    });
});


// Partie php : vote.php
// connexion à la BD
require_once('db.php');
$session_id = $_SESSION['client_id'];
if($_POST) {
$vote_type = trim($_POST["vote"]);
$reponse_id = filter_var(trim($_POST["id"]), FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
die();
}
$sql = "SELECT COUNT(*) AS nbr FROM votes WHERE reponse_id='$reponse_id' AND user_id='$session_id'";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
$query = $req->fetch(PDO::FETCH_ASSOC);
switch ($vote_type) {
case 'like':
if ($query['nbr'] >= 1) {
header('HTTP/1.1 500 Vous avez vote auparavant !');
exit();
} else {
$sql = "
SELECT vote_like
FROM votes v
INNER JOIN reponses rp
ON rp.reponse_id = v.reponse_id
WHERE v.reponse_id<>'$reponse_id'
AND user_id='$session_id'
";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
$rows1 = $req->fetch(PDO::FETCH_ASSOC);
if($rows1) {
$sql = "
UPDATE votes v
SET vote_like=vote_like+1
WHERE NOT EXISTS (SELECT reponse_id FROM reponse rp WHERE rp.reponse_id = v.reponse_id)
AND user_id='$session_id'
";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
} else {
$sql = "INSERT INTO votes (user_id, reponse_id, vote_like) VALUES ('$session_id', '$reponse_id', 1)";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
}
}
echo ($rows1["vote_like"]+1);
break;
case 'dislike':
if ($query['nbr'] >= 1) {
header('HTTP/1.1 500 Vous avez vote ce contenu auparavant !');
exit();
} else {
$sql = "SELECT vote_dislike FROM votes WHERE reponse_id='$reponse_id'";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
$rows2 = $req->fetch(PDO::FETCH_ASSOC);
if ($rows2["vote_dislike"]) {
$sql = "UPDATE votes SET vote_dislike=vote_dislike+1 WHERE reponse_id='$reponse_id'";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
} else {
$sql = "INSERT INTO votes (user_id, reponse_id, vote_dislike) VALUES ('$session_id', '$reponse_id', 1)";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
}
}
echo ($rows2["vote_dislike"]+1);
break;
case 'fetch':
$sql = "SELECT vote_like, vote_dislike FROM votes WHERE reponse_id='$reponse_id'";
$req = $db->prepare($sql);
$req->execute() or die(print_r($db->errorInfo()));
$rows3 = $req->fetch(PDO::FETCH_ASSOC);
$vote_like = ($rows3["vote_like"])?$rows3["vote_like"]:0;
$vote_dislike = ($rows3["vote_dislike"])?$rows3["vote_dislike"]:0;
$env_rep = array('vote_like'=>$vote_like, 'vote_dislike'=>$vote_dislike);
echo json_encode($env_rep);
break;
}
}


Merci par avance !

3 réponses

cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 1
22 juil. 2016 à 01:21
Bonsoir,

C'est lié à la chose qui vérifie si un vote a déjà été fait.
Je n'ai pas le temps de vérifier tout le code en détail mais à mon avis le mieux serait de lier chaque vote à un identifiant unique attribué à chaque réponse ainsi qu'à l'identifiant de la personne connectée. Cela permet donc par exemple à une même personne de voter pour 2 réponses, par exemple si elle trouve que les 2 sont utiles.

Bonne nuit
0
Utilisateur anonyme
22 juil. 2016 à 10:13
Bonjou @cocodu67,

Merci d'avoir pris le temps de me répondre.
Pour répondre à ce que tu venais de dire, j'ai un enregistrement dans ma table votes à chaque vote. Chaque vote a son ID unique.

Cdlt,
0
cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 1
29 juil. 2016 à 22:07
Bonsoir,

Désolé j'ai totalement oublié cette discussion. Moi d'habitude quand un requête SQL ne fonctionne pas comme il faut je regarde toutes les valeurs que ça a (chez toi session id et reponse id), je vais dans un SGBD (moi j'utilise SQLYog), je lance la requête avec les bonnes valeurs, souvent le résultat affiché me montre ce qui va pas.

Tu prend une réponse au hasard, par exemple si sa $reponse_id est à 54 et que ton $session_id est CompteDeTestet que t'as déjà voté ailleurs, t'auras le message qui te dit que t'as déjà voté pour la question même si tu l'as pas fais.

Tu lances donc
SELECT COUNT(*) AS nbr FROM votes WHERE reponse_id='54' AND user_id='CompteDeTestet';

Et avec ce que ça affichera normalement tu devrais comprendre pourquoi ça considère que t'as déjà voté.

Bonne nuit
0
Utilisateur anonyme
29 juil. 2016 à 22:44
Bonjour @cocodu67,

Merci encore pour ta réponse.
Le problème vient de ma requête SQL.
C'est corrigé !

Merci bcp !
0
Rejoignez-nous