2 comments

  1. 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 🙂

  2. 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.

Comments are closed.