How to limit user's comments/requests per hour in php - php

I have a site that has few request options (for example add photo, add comment). I want to limit of requests made by use per certain time, for example so he can't post more than 5 comments within hour, he can't add more than 5 photos per hour etc.
My idea was to make/update session variable every time form action is sent, so it sums up to 5 (and if session var == 5 it would deny action on every form). My idea seems good in my mind, but i just can't find the way to reset certain session variable 1 hour from it's initation). Looking forward for any ideas

Do it from SQL using simple SQL commands you can get the number of items done in the past hour and thus no need to use session variables (which will die if a user reset it's session)
Check the number of "posts" for a specific element in the current hour
SELECT
COUNT(*)
FROM
my_elements_table
WHERE
HOUR(createdon) = HOUR(NOW())
AND DATE(createdon) = CURDATE()
AND createdby = the_user_you_are_checking
Check the number of "posts" for a specific element in the past hour
SELECT
COUNT(*)
FROM
my_elements_table
WHERE
DATE_ADD(createdon, INTERVAL 1 HOUR) > NOW()
AND createdby = the_user_you_are_checking
Obviously, adapt the SQL based on your database fields and tables but you should have a good starting point with that.

I guess you store data about the comments and the photos in a database, at least you have to do it about the comments, but I guess you do it for the photos as well. In that case I would save a timestamp for when the comment/photo was created and an ID of the user who created it, along with the rest of the information.
When a user then tries to add another photo or comment, you count the number of comments and photos in the db that were created by that particular user within the last 60 minutes. If it exceeds five, you discard the request, otherwise you add the information.

Well if you got users, you store them in a database, don't you ? Then why not just store the last time they commented something in the database and use that to check if they can comment ?

Make 5 variables in the session containing the time of the actions and every time a user is trying to post check to see first if all 5 have something recorded and if all of them have data check the time recorded.If all times are within one hour from the current time then deny access.

Another solution would be to query your database to return comments posted within your specified time frame and if the result count is higher than allowed, don't allow new comment.
Something like: "SELECT created_on FROM tblComments WHERE user_id=x"
With this I am making an assumption that you are storing comments in a database and that you have a field containing the post time.

Related

How to stop the code if database value changed before a specific period

I am using PHP and mySQL, in my 'users' table, I have HWID value. With every login, the HWID updates. How do I limit their ability in login to only use 1 HWID in 3 days? If HWID got updated with a different value within 3 days, it stops them from logging in?
One way to accomplish that would be to have an additional field in your users table called something like update_date that keeps track of when the last time the HWID was updated. If the update_date field is still within 3 days of the last updated time, then do not let them log in.
If you provide some of your code we could take a look and work from there.

Automatically update data in sql for a webpage

So I'm a software Development student and for my web class I created a project that uses among other things Php and SQL; In this project, users can create posts and other users can comment on them.
The thing is I want posts to only be available for a certain period of time.
Then I have an SQL table named 'Posts' and they have a column named 'Status' (you know, if the status it's 0 they're not available and else they are.)
When a user creates a post I make SQL:
INSERT INTO posts *All the post data*, I set the Status to 1 and make a TIMESTAMP to register the date of creation of the post. I want that a week after the date registered in the Timestamp changes the status column to 0 but I don't want it to be with a page request (I need it to be automatic) and I want the user to be notified via email or something.
Can it be made with some python CGI that checks the date, updates the Status and sends the email or is there a better/easier way to do it?
Thanks a lot for your help :)
You dont need the status 0/1 AND the timestamp column, if all you want to do is show a post for a set period of time.
Just use the timestamp column and amend the queries that fetch the posts to only show those posts that are < 7 days old (or any period you decide)
EG
SELECT * from posts where timestamp_col < DATE_SUB(NOW(), INTERVAL 7 DAY)
or something similiar that meets your needs
Turns out the best way to solve this was using Cron Jobs.
I run a PHP script every day and I modify the posts which are exactly 7 days old, using
UPDATE Posts SET Status = 0 WHERE DATE(timestamp_col) = DATE_SUB(NOW(), INTERVAL 7 DAY)
And then I iterate through the affected rows emailing the users.

PHP Login/Logout If Session Timeout = true Do Something

I have a script that will login and logout a user. It works perfectly. Now I have like a widget that counts how many users are registered and activated as well as how many users are online. I do this by having a field in my users database that says online = 1 or 0. When the person logs in, online = 1 and logs out online = 0. Now I haven't taken into account that this field is only being updated because the user is doing something. I haven't taken into account that the session would timeout.
How can I make a function that says something like if session timeout = true then update users set online=0 where username=$username and user_id=$user_id.
In your database table, add another column something like last_seen. Update this every time you see your users online. After a certain period of inactivity, they will be marked as inactive. In fact, I suggest you replace your online field with this.
For example,
ALTER TABLE users CHANGE COLUMN `online` `online` DATETIME; -- SAMPLE SQL query only
To check how many users are online:
SELECT * FROM users WHERE online>(NOW()-INTERVAL 1 HOUR); -- SELECTS all users online in the past hour.
If the user logs out, you can simply set the online = NOW()-INTERVAL 1 HOUR. Or, you can also retain your previous online field and you can check if the user is idle (using my suggestion) OR online=0.
Instead of trying to use a boolean value to see if somebody is logged in, try using a TIMESTAMP. Then you can perform more accurate logic based on how long somebody has been away. If the last time somebody has loaded a page on your website was 30 minutes ago, do you think they're online? Do you even think they're at their keyboard?
The session will only timeout if you want it to do so. This question is really a duplicate of 'How do I expire a PHP session?'
Code is only executed when a php page is served, so you will need to track the last time a user was active my using a session variable to track the last time a page was served to that user. Then, whenever serving any php page to the user, check to see if the timeout period has elapsed and log the user out if it has, see link for examples.
Add lastOnline field which stores the timestamp of last user activity.
Have some ajax function on the page which updates the timestamp every "n" seconds.
To check if user is online - check both: online field and timestamp. If timestamp was updates more than "n" seconds ago - user is offline even if online field is equal 1.

Online or offline function PHP

I'm working on a "community". And of course I would like to be able to tell if a user is online or offline.
I've created so that when you log in a row in my table UPDATE's to 1 (default is 0) and then they're online. And when they log out they're offline. But if they don't press the Log out button, they will be online until they press that button.
So what I would like to create is:
After 5 minutes of inactivity the row in my database should UPDATE to 0.
What I'm looking for is how to do this the easiest way. Should I make an mysql_query which UPDATE's the row to 1 every time a page is loaded. Or is there another way to do it?
Instead of using a boolean "Online" field, use a DateTime. When a user makes a request to the page, update the DateTime to NOW(). When you are gathering your list of current users online, your WHERE clause would be something like WHERE lastSeen > DATE_SUB(NOW(), INTERVAL 5 Minutes)
Update: To retrieve individual online status.
select if(lastSeen > date_sub(now(), interval 15 minutes), 1, 0) as status from table where userid=$userid
This tutorial is quite handy: Who Is Online Widget With PHP, MySQL & jQuery
Well, if you don't want to set up a cron job, that would execute some code every 5 minutes, you have no options. But, actually, I think the following approach would be much more efficient:
Change your 1/0 column to timestamp
On each user request update that timestamp to current DateTime.
When checking for active users, check if that timestamp is less than 5 minutes from now
This way you'll be having actual data on users and no recurring queries - just one additional update per request
If you will update the row only on page load, then some of information would be incorrect.
Let's assume that user have opened page and is writing really long text or something. He is doing it for half an hour now. And your database ny now is already updated and he is counted as offline user.
I would write javascript that pings you back each 5 minutes, if opened tab is active.
This ping updates database field 'last_activity' to NOW(). And to count online users, or check if user is online you'll need to compare 'last_activity' to NOW() minus five minutes.
Simpliest ways (IMHO):
You can count sessions in session_save_path() dir.
you can store last visit timestamp in DB, and count rows with (timestamp > current_timestamp - somedelay).

Is there any way to make MySql database "update itself"?

I have a mysql database, or more specific, a mysql table which I store IP adresses in.
This is because I limit the nr of messages being sent from my website.
I simply check if the IP is in the table, and if it is, I tell the user to "slow down".
Is there any way to make this MySql table only store a row (a record) for x minutes?
Other solutions are also appreciated...
No, but you can use a TIMESTAMP field to store when the row was inserted / modified and occasionally delete rows that are older than x minutes.
DELETE FROM your_table
WHERE your_timestamp < NOW() - interval 5 minute
To solve your actual problem though, I'd suggest having a table with a row for each user and the last time they sent a message. Assuming it is indexed correctly and your queries are efficient you probably won't ever need to delete any rows from this table, except perhaps if you use a foreign key to the user table and delete the corresponding user. When a user sends a message insert a row if it already exists, otherwise update the existing row (you can use for example the MySQL extension REPLACE for this if you wish).
I would recommend that you add a WHERE clause concerning time to the SELECT "simply check if the IP is in the table"
SELECT * FROM table WHERE ip = <whatever> and timestamp > NOW() - 3*60
Then maybe empty out that table once every night.
I'd make a column that has the timestamp of the last sent message and another that has the total number of posts. Before updating the table check if at least X minutes has passed since the last post. If so, change the total number of posts to 1, otherwise increment the value by 1.
One approach that doesn't involve deleting the IP addresses after a certain interval is to store the addresses as "temporal" data, i.e. records that are only valid for a certain period.
Simplest way to do that would be to add a timestamp column to the table and, when entering an IP, capture either the time it was entered into the table, or the time after which it is no longer being "limited".
The code that grabs IPs to be limited then checks the timestamp to see if it's either:
older than a certain threshold (e.g. if you recorded the IP more than an hour ago, ignore it) or
the current time is greater than the expiry date stored there (e.g. if an IP's timestamp says 2010-11-23 23:59:59 and that is in the past, ignore it)
depending on what you choose the timestamp to represent.
The other solutions here using a timestamp and a cron job are probably your best option, but if you insist on mysql handling this itself, you could use Events. They're like cron jobs, except mysql handles the scheduling itself. It requires 5.1+ though.

Categories