PHP / MYSQL Voting system for user blog/forum - php

I have a blog/forum system which has upvotes/downvote and each comment can also have an upvote/downvote like the reddit/stackoverflow system.
Which is the best way to ensure that a user who has already upvoted can't upvote it again?
I did consider the possibility of making a new row with an seperate upvote table.But if a post has 30 comments then the script would end up doing 30 database queries which can also put a tremendous load on my server. Another possibility would be to make a row for each upvote of user,query them together and check with post_id which is again infeasible.
So which is the best way for upvote/downvote system and what do sites like stumbleupon/reddit do? As in the moment he log's in, the he can see a red color maybe to the posts he has already upvoted

I believe that the best way to do it is to make a separate table for up/down votes, where you save user's id and is it up or down vote, and include reputation to comments/posts/whatever table.
If a user tries to do up/down vote you only need to check one comment (why 30?). Then you simply check in the separate table if the user has already voted for that comment/post. If so, you can remove vote (for example like in SO – if you press up vote twice, your upvote will be removed), or if person pressed a different button (f.e. downvote after upvote) you can just change his vote. The reason why I offered you to add reputation column to your posts/comments table and update it after all up,down votes is that then you will not need to get count(*) of reputation from that separate table and your comment/post reputation will be easy and fast to recieve, especially, if your database has many rows.

Related

select users who currently view same page

I find several partial solutions in answers on this question, but common answer seems to be absent.
So, I have a table users with columns user_id, user_name. On each static page of website I want to display all user names of users who currently view this page.
Should I have a table views with columns user_id, webpage_link?
If yes, when I shall update data in column webpage_link? How to connect code from following answer with mysql database Is there a way to detect if a browser window is not currently active? ? (If it is ok for this purpose.)
To make updates very often is not very good. So, the user can view several pages (for example, in 2 or more tabs). What type of webpage_link column shall be in this case?
With every http request, you get a $path variable. if you also have a logged in user, you can store which page this user requested last (e.g. in a table like you described, but only storing the relative path).
You update this information on a per-request-basis in some sort of front-controller. (just make sure you put it where it is called for every authenticated page). When the users session times out, you remove the row of that user from the table.
this case is a little more difficult. you could store the last n pages/paths the user has requested and leave the rest as above. You don't have to change the table structure for that, just allow for multiple rows per user. (the combination user_id+path should be unique, though)
Hope that helps to get you started

disable multiple voting on user comments

Description:
I am creating comment/reply functionality to a web app that I built. I have a post that I want to link these comments too. To decrease spam and encourage community involvement I want to implement a voting system on each comment/reply.
Problem:
I know how to set up the database and I know how to show upvotes/downvotes. The only thing I don't know what to do is to keep the vote... voted even if the user refreshes the page. I don't want a user to be able to vote up more than once on a single post. Something like the voting on this site, it tracks that you have already voted with a yellow upvote.
What I have thought of:
Place post id in cookie with the user_id appended to it. A simple check of the cookie can stop the user from voting again
Place a unique constraint in table post id... but this is where I get confused. Should I have a separate table just for voted posts? Database schema idea ( I think ) here: https://stackoverflow.com/a/12350981/185672
Keep all the ids in a session array and check against all voted on ids... but that would get huge.
Combination of cookie and database to reduce number of db calls.
In the future there may be 1000s of votes cast by a single user.
edit:
I figured out that storing the results in a database is a must. How can I check for every reply/comment if the user has valid voting privileges without making 1000s of calls?
Resources:
Helped with some further spamming problems, but didn't answer initial question:
https://stackoverflow.com/a/2333085/185672
Old solution that explains how to count votes but not keep the "upvote" checked.
http://www.9lessons.info/2009/08/vote-with-jquery-ajax-and-php.html
Bonus question:
If you guys know of a great script that can allow me to sync up a commenting system ( with votes ) into my already built app?
Also, I tried to find duplicates, but I just can't.
Yeah, just keep a separate table to track user votes. Since you know which user is requesting the page, you can easily join the votes table to determine the current user's eligibility to vote on each post on the page. For each post, if they're eligible, output one version of html, if they're not then output another.
Once the ajax request asks for the php file that does the vote, you can then check once more that that user is eligible to vote - I.e they're changing their vote, or they haven't voted before.
Take yahoo's news stories for example - when you request a page that you've made a comment on, your own comment has disabled voting buttons. With some hacking of the page inside the browser's dev tools, you can enable the buttons. You can even click on them and vote for your own post - though only once.
So, you can see that they got 2/3rds of it right, and output html based on the user's eligibility to vote. They also prevent multiple voting (server-side), they just don't do a server-side check to ensure you're not voting for your own comment.
Stack Overflow on the other hand, always shows the same html - but when you click to vote for your own comment, the server-side code baulks at the idea and the response is basically 'bugger-off! you can't do that' having received a negative result from the server, the javascript on the page pops up the message, rather than updating the vote count.
I suggest you create a "hidden field" in your page that stores information about the upvote/downvote by the user. This is how you would use it:
If the user upvotes/downvotes, the javsvscript on the on the shows the upvote, sets the field to maybe true to indicate the vote status and would also send an AJAX request to the server where the server would record the vote status in the user profile database.
Then whenever the post is re-loaded for a particular user, the server sets the hidden field server-side to true or false, depending on the vote record that is stored in the database. The JS would, on load, check the hidden field and set the vote on the page accordingly (you might need an extra hidden field to indicate whether it is an up or down vote).

Allowing only one vote per person on a voting system

I'm working on a little posting system so I can post posts on my site and people can like and dislike it.
It looks like this:
At the moment you can upvote and downvote as many times as you would like. I know how to make the images not clickable with JavaScript but I also need a way to do this in PHP because someone could just make the buttons clickable again with fireBug or the Chrome Console.
This is probable the first thing i'm actually making in PHP so i'm still a beginner. Thanks for any suggestions.
I am not going to just write code for you, and there are probably dozens of workable examples on script sites. Here are a few tips to get you pointed in the right direction:
Session variables - $_SESSION[] - Check if it is set, and then set them after a vote. As long as they don't close the browser, they won't be able to vote again.
Cookies - $_COOKIE[] - Same as session, but can remain even if they close and open their browser again.
IP Address - $_SERVER['REMOTE_ADDR'] - Keep a record in a MySQL table of IPs and votes.
Login system - Only allow authenticated users to vote, and then keep track of the votes in the database.
Any combination of the above is acceptable. Hope that gets you pointed in the right direction.
Since you're going to learn this, I'm not going to post any complete code. I can give an overview, though.
The best way to do this is to store votes in a database table (probably MySQL):
| vote_id | user_id | post_id | vote |
Where:
vote_id is an auto-increment column that creates a unique ID for each vote
user_id is an identifier of who the user is that submitted this vote
post_id is an identifier for the post the user is voting on
vote determines whether this vote was up or down.
Now, you can form queries to determine whether or not somebody has already voted on the post, and act accordingly.
You need to validate it on the server-side i.e. in PHP code. You can do that either by IP address (if non-logged in user / guest) or by username (for logged in user)
There is no way you can stop users by client-side validation.

How to count how many people read an article

I am programming a Blog. I am interested how to add a counter to the side to see how many people read the different articles.
I understood that if you have a Website counter, than you would normally save the IP and the Date in the database so you only count the person once.
But how would I make sure that a person reading a specific article is only counted once for that article?
The database would turn very big if I would save each Visitor IP for each Article. It came now into my mind to maybe create a Session for every Visitor. Within this Session I save each ArticleID the Person read. So before I update the counter in the database, I check if it already exists in Session - if not increment counter and save in Session otherwise dont.
Is this the right approach or is there another way to do it?
It depends on which data you want to save. You can save:
Number of hits (count all people/bots/... who opened the pages), this makes fake impression of readers, because doing a refresh will count me twice.
Number of unique visitors, create a session for the user. and increment the counter only once in the session. This can be improved by setting permanent cookie, but looks like overkill for me. and by the way, I can open the article and don't read it!
Number of people interact with the article. You can put some javascript capture (mouse scrolling, clicks on article text, ...) , split text into parts with "read more" ... etc.
If I were you, I will name it "number of views", and use solution 2. And combine this with google analytics (or similar solution) to know more details about visitors.
Google analytics is better way
But if you want to do it by programming then follow the steps.
i) In your table from the data of particular article comes just add one column no_of_view or whatever you want to give..
ii) In the starting of page write down the code of php for ::
from the url you can get the id of current article.
then from select query get the value of column no_of_view for particular ID (article)
then fire a query for update that record for no_of_view column with +1
If you want to get that more accurate then add ipaddress column and date also....
I prefer to use Google Analitycs API for such tasks. It' hard to implement for the first time - but once made it will help you on any project.
You can read here - http://code.google.com/intl/en/apis/analytics/docs/gdata/home.html
I would set a cookie on the user's browser and send it to the server. If the cookie is new, it's a new user reading the article for the first time.
I think, you can execute an ajax function, when user click on article to update column in database table field name 'number_of_click' as per article id and other relevant reference
and show it by simple query 'SELECT no_of_click FROM article WHERE id='{$individual_article_id} ....'';

how to restrict user not to vote an article more than once?

in my application a user can post his/her article that other users can response upon ans vote up and down also like stackoverflow has for posted question ans answers.
How can I restrict user so that he/she can't vote twice ?
Just store user id in the voting table.
So, you can always check if particular user already voted.
article-id, user-id, vote time and vote value columns is enough
Two methods:
Client Side: Set into cookie (article IDs for last 5 or 10 votes ) and do not allow to vote again. This is easily hackable but allows you to implement without any database changes!
Server side: track each and every vote up and vote down in a table like <{userID}, {vote UP/DOWN}, {articleID}>
StackOverflow uses database to store all this data. They also lock your vote after some period so you cannot undo your action.
I think the best way to do that is to store all votes and user ids in database, and if it gets bigger you can remove old records from the database after one week/month/etc and restrict voting on items that are older than a week/month/etc, so no one will be able to vote twice on the same item.
You will need to use some kind of server side scripting to remember users by IP or some other unique data. You'll have to store the IP or other data and remember it. When the user tries to up/down vote again, you'll have to check against that to see if you should let them do so. You should let them do the opposite though, in case they want to change their vote. You can do this with PHP and MySQL (and lots of other things).

Categories