Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Looking in all posts with keywords "voting system, upvote, downvote", I can't find a satisfying solution for this issue, except accepting one of the available plugins, spend a lot of time undersanding it and try to modify its functionnalies so that they fit with the requirements. So, I am convinced in writing my own code to create a stack-exchange-like voting system for Wordpress. Without your suggestions I cannot find the starting point for the main part of the skeleton of my code.

My actual approach :

  • Create two custom fields: the first stores the number of post upvotes, and the second, the number of downvotes. It is possible to display votes state using get_post_meta function, and change vote state from front end using update_post_meta.
  • Find a way to store in the database the voted posts by a specific user and the state of vote(up, down or nothing). So that logged in users see if they already voted.
If (user is logged in )
{
Show the upvote or downvote state already done by this user;
Allow voting ;
}
else 
{
don't allow voting;
}

My question is: How to resolve the second issue. Is there a way to achieve it using the customizing features offered by Wordpress PHP functions (without using SQL queries, since I don't know how to use SQL). I observe that all the Up/Down voting plugins use SQL queries in their code which make me really scared. Should I learn SQL to achieve my goal?

I thank you very much for your usual help.

share|improve this question
1  
Another solution would use comment meta instead. See this tutorial –  JMau May 19 '13 at 21:33
    
Thank you very much @TweetPressFr, your tutorial is very interesting from first sight. I will dig into it tomorrow and provide with a feedback –  whiteletters and blankspaces May 19 '13 at 23:38
add comment

2 Answers

up vote 5 down vote accepted

A simple user meta row can handle that for you (the second issue), you can store the post id and the vote (up/down) in an array and that is just the same as post meta ex

/**
 * update user vote per post
 * @param  int $user_id 
 * @param  int $post_id 
 * @param  mixed $vote can be an integer 1 / -1 and can also be a string "up"/"down"
 * @return void
 */
function update_user_vote($user_id,$post_id,$vote){
    //get all saved user data    
    $user_votes = get_user_meta($user_id,'updown_votes',true);
    $user_votes[$post_id] = $vote;
    //update with the new vote
    update_user_meta($user_id,'updown_votes',$user_votes);
}

/**
 * get user vote of post
 * @param  int $user_id 
 * @param  int $post_id 
 * @return if user has voted the his vote will be returned , zero if no vote found for post by this user
 */
function get_user_vote($user_id,$post_id){
    //get all saved user data    
    $user_votes = get_user_meta($user_id,'updown_votes',true);
    return (isset($user_votes[$post_id])) ?  $user_votes[$post_id] : 0;
}

and all done with no SQL :)

share|improve this answer
    
Thank you very much, tomorrow in the first hour I will dig into your answer, your help is always appreciated and valuable. +1 –  whiteletters and blankspaces May 19 '13 at 23:33
1  
I was late accepting because of the big time I spent to understand and implement this. Thank you very much @Bainternet. –  whiteletters and blankspaces May 23 '13 at 11:34
add comment

Yes, you can do this with built in functions. You've got a very broad question and a working solution would be a fair bit of work, but there a couple of ways to handle this with core functions that seem workable to me.

Store everything in post meta.

You could do this with only the two fields you are already considering. Instead of saving a counter, save an array of user IDs. To get a count, just count the user IDs. With one "upvoted" array and one "downvoted" array, you have what you need.

To tell a user if they've voted just check the array for the user ID.

This is not going to be a good solution if you need to query for votes. That is, it won't work well if you need to find all the posts that a particular user has voted on. And it won't work well if you need to find all the votes for all the posts or for some large set of posts.

Use a combination of post meta and user meta

Similar to the above but you will use the *_user_meta functions to save an array of post IDs to the usermeta table in addition to the counters in $wpdb->postmeta.

It means double the database writes and double the reads but this would let you get "all posts voted on by a user" relatively easily. But, as with the other solution, if you need to search that user meta data this isn't going to work well.

Both options could have performance issues if the arrays get too large. The database column type is longtext, which will hold a lot of data, but the transfer processing time could become a problem.

I think you should probably be able to use comment meta instead of post meta but I think post meta is a better fit.

If I were going to do this with core tables and functions I would lean toward the second option, but if I were seriously considering something like this I would very seriously consider a dedicated table that I could construct and index specifically for this task. That would be the most flexible and efficient way to do it, as far as the kind of queries you could run. if you want the best answer, in my opinion, it involves learning SQL.

share|improve this answer
    
Thank you very much @s_ha_dum, frankly, you and Bainternet are big pillars of the comuunity tomorrow in the first hour I will dig into your answer, your help is always appreciated and valuable. +1 –  whiteletters and blankspaces May 19 '13 at 23:35
    
Dear S_HA_DUM, I implemented what you said (use of *_user_meta) based on the code provided by Bainternet. Nonetheless, I dont forget the performance drawbacks you talked about and then, I will maybe change the approach in the future to custom comment or completely learn SQL, create my own db tables. Thank you very much for your time and appreciated support –  whiteletters and blankspaces May 23 '13 at 11:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.