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 usingupdate_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?
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
and all done with no SQL 🙂
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
ID
s. To get a count, just count the userID
s. 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 postID
s to theusermeta
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
.