WordPress rating system : memorizing user choice

I made a rating system for my wordpress articles. You can downvote or upvote and it updates a gauge. Here is what it looks like : http://bit.ly/1eXiAzt

I adapted a wptuts tutorial which just gave the possibility to uplike. As a result, I have a few difficulties to make my script fully functional. Here is my problem :

Read More

I would want to memorize if the user has liked or disliked the article and adapt the css. Currently, both buttons have the same style when the user has already voted.

Here are my files :

functions.php :

<?php

// RATING //

$timebeforerevote = 1;

add_action('wp_ajax_nopriv_post-like', 'post_like');  
add_action('wp_ajax_post-like', 'post_like');
add_action('wp_ajax_nopriv_post-like', 'post_dislike');  
add_action('wp_ajax_post-like', 'post_dislike');

wp_enqueue_script('like_post', get_template_directory_uri().'/post-like.js', array('jquery'), '1.0', true );  
wp_localize_script('like_post', 'ajax_var', array(  
    'url' => admin_url('admin-ajax.php'),  
    'nonce' => wp_create_nonce('ajax-nonce')  
));

function post_like()  
{  
    // Check for nonce security  
    $nonce = $_POST['nonce'];  

    if ( ! wp_verify_nonce( $nonce, 'ajax-nonce' ) )  
        die ( 'Busted!');  

    if(isset($_POST['post_like']))  
    {  
        // Retrieve user IP address  
        $ip = $_SERVER['REMOTE_ADDR'];  
        $post_id = $_POST['post_id'];  

        // Get voters'IPs for the current post  
        $meta_IP = get_post_meta($post_id, "voted_IP");  
        $voted_IP = $meta_IP[0];  

        if(!is_array($voted_IP))  
            $voted_IP = array();  

        // Get votes count for the current post  
        $meta_count = get_post_meta($post_id, "votes_count", true);
        $meta_total = get_post_meta($post_id, "votes_total", true);  

        // Use has already voted ?  
        if(!hasAlreadyVoted($post_id))  
        {  
            $voted_IP[$ip] = time();  

            // Save IP and increase votes count  
            update_post_meta($post_id, "voted_IP", $voted_IP);  
            update_post_meta($post_id, "votes_count", ++$meta_count);
            update_post_meta($post_id, "votes_total", ++$meta_total);  

            // Display count (ie jQuery return value)  
            echo $meta_count; 
        }  
        else  
            echo "already";  
    }

    else if(isset($_POST['post_dislike']))
    {
              // Retrieve user IP address  
        $ip = $_SERVER['REMOTE_ADDR'];  
        $post_id = $_POST['post_id'];  

        // Get voters'IPs for the current post  
        $meta_IP = get_post_meta($post_id, "voted_IP");  
        $voted_IP = $meta_IP[0];  

        if(!is_array($voted_IP))  
            $voted_IP = array();  

        // Get votes count for the current post  
        $meta_count = get_post_meta($post_id, "votes_count", true);
        $meta_total = get_post_meta($post_id, "votes_total", true);  

        // Use has already voted ?  
        if(!hasAlreadyVoted($post_id))  
        {  
            $voted_IP[$ip] = time();  

            // Save IP and increase votes count  
            update_post_meta($post_id, "voted_IP", $voted_IP);  
            update_post_meta($post_id, "votes_count", --$meta_count);
            update_post_meta($post_id, "votes_total", ++$meta_total);  

            // Display count (ie jQuery return value)  
            echo $meta_count; 
        }  
        else  
            echo "already";  
    }
    exit;
}

function hasAlreadyVoted($post_id)  
{  
    global $timebeforerevote;  

    // Retrieve post votes IPs  
    $meta_IP = get_post_meta($post_id, "voted_IP");  
    $voted_IP = $meta_IP[0];  

    if(!is_array($voted_IP))  
        $voted_IP = array();  

    // Retrieve current user IP  
    $ip = $_SERVER['REMOTE_ADDR'];  

    // If user has already voted  
    if(in_array($ip, array_keys($voted_IP)))  
    {  
        $time = $voted_IP[$ip];  
        $now = time();  

        // Compare between current time and vote time  
        if(round(($now - $time) / 60) > $timebeforerevote)  
            return false;  

        return true;  
    }  

    return false;  
}


function getPostDislikeLink($post_id)  
{  
    $themename = "twentyeleven";  


    if(hasAlreadyVoted($post_id))  
        $output .= 
    '<span title="'.__('Too kind !', $themename).'" class="like dislike alreadyvoted"></span>';  
    else  
        $output .= 

    '<a href="#" data-post_id="'.$post_id.'" class="idislike"> 
      <span  title="'.__('Too kind !', $themename).'"class="qtip like dislike"></span></a>';  

    return $output;  
}

function getPostLikeLink($post_id)  
{  
    $themename = "twentyeleven";  

    if(hasAlreadyVoted($post_id))  
        $output .= 
    '<span title="'.__('Nasty !', $themename).'" class="like alreadyvoted"></span>';  
    else  
        $output .= '<a href="#" data-post_id="'.$post_id.'" class="ilike"> 
      <span  title="'.__('Nasty !', $themename).'"class="qtip like"></span></a>';  


    return $output;  
}

function getPostTotalLike($post_id)
{
    $vote_count = get_post_meta($post_id, "votes_count", true); 
    $vote_total = get_post_meta($post_id, "votes_total", true);

    if(empty($vote_total)){
    $pourcentage = 'novotes';
    }

    else if ($vote_count < 0){
    $vote_count2 = abs($vote_count);
    $votesPositifs = $vote_total - $vote_count2;
    $pourcentage = ($votesPositifs * 100) / $vote_total;
    }

    else if($vote_count > 0){
    $pourcentage = ($vote_count * 100) / $vote_total;
    }

    else{
    $pourcentage = 50;
    }

    if($pourcentage == 'novotes'){
        $barometre = '<li class="level0"></li><li class="level0"></li><li class="level0"></li><li class="level0"></li>';
    }   

    else if($pourcentage < 30){
        $barometre = '<li class="level1"></li><li class="level0"></li><li class="level0"></li><li class="level0"></li>';
    }

    else if($pourcentage < 60){
        $barometre = '<li class="level1"></li><li class="level2"></li><li class="level0"></li><li class="level0"></li>';
    }

    else if($pourcentage < 85){
        $barometre = '<li class="level1"></li><li class="level2"></li><li class="level3"></li><li class="level0"></li>';
    }

    else{
        $barometre = '<li class="level1"></li><li class="level2"></li><li class="level3"></li><li class="level4"></li>';
    }

    $output2 .= '<ul>'.$barometre.'</ul>';
    return $output2;

}

function getStats($post_id)
{
    $vote_count = get_post_meta($post_id, "votes_count", true); 
    $vote_total = get_post_meta($post_id, "votes_total", true);

    $output3 = '<span>Score : '.$vote_count.' / Total votes : '.$vote_total.'</span>';
    return $output3;
}

?>

HTML :

    <div class="mechancete post-like">
        <?php echo getPostDislikeLink(get_the_ID());?>
        <?php echo getPostTotalLike(get_the_ID());?>
        <?php echo getPostLikeLink(get_the_ID());?>
        <?php echo getStats(get_the_ID());?>
   </div>

JS :

jQuery(document).ready(function() {

    jQuery(".post-like a.ilike").click(function(){

        heart = jQuery(this);

        post_id = heart.data("post_id");

        jQuery.ajax({
            type: "post",
            url: ajax_var.url,
            data: "action=post-like&nonce="+ajax_var.nonce+"&post_like=&post_id="+post_id,
            success: function(count){
                if(count != "already")
                {
                    heart.addClass("voted");
                    heart.siblings(".count").text(count);
                }
            }
        });

        return false;
    })

    jQuery(".post-like a.idislike").click(function(){

        heart = jQuery(this);

        post_id = heart.data("post_id");

        jQuery.ajax({
            type: "post",
            url: ajax_var.url,
            data: "action=post-like&nonce="+ajax_var.nonce+"&post_dislike=&post_id="+post_id,
            success: function(count){
                if(count != "already")
                {
                    heart.addClass("voted");
                    heart.siblings(".count").text(count);
                }
            }
        });

        return false;
    })

})

Thanks in advance for your help !

Related posts

Leave a Reply

1 comment

  1. Two main issues:

    • the CSS classes don’t match, you have ilike, like, idislike and dislike, make this consistent and meaningful to use with <a> and <span>.

    • you should use wp_send_json_success, so you can pass $count and $total as array values to update the counter when processing the successful response. And you need to assign a class to the counter container, so as to update its value.

    As sidenote: