PHP Form 'Cool down timer' - php

Ok basically I have a form that a user submits but I need a 'cool down timer' so that the user cannot submit it again for a given amount of time.
I could not find out how to do this in php which would be preferred if possible.
Thanks in advance.

You can store in database (example: MySQL) timestamp of last successful submit and on every submit check if value from database + cool down time smaller or equal to current timestamp.
You can get current timestamp in PHP with time().

You have to use sessions for that!
When the user submits the form you have to add the timestamp to his sessions:
$_SESSION['last_submit'] = time();
Now when he submits the form again simply compare the timestamps, e. g. :
if(isset($_SESSION['last_submit']) && ((time() - $_SESSION['last_submit']) < 60 * 5)) { //time in seconds! 60 seconds = 1 Minute and 1 minute * 5 = 5 minutes!
die('Wait a few');
}
$_SESSION['last_submit'] = time();
// regular form processing here!
What we do here is to check first: is a previous timestap set? And then if time() - lastsubmit is less then 5 minutes.
If these all return true, the form was submitted to "early" and we simply die. If not we refresh the sessions' s timestamp and can move on.
And of course don' t forget to start the session!
session_start();
On the very top of the page!
As I' ve read in a comment (thanks again!) a user just could use another browser or clear the cookies. To prevent this (as good as possible) you have to take the IP into account as well.
For this you have to use a server-side database! Store the client' s IP into this database with the timestamp along and then in your if statement you don' t need to get the timestamp from the session, but from the database. Use the client' s IP to get the assoc. timestamp.

Related

Adding time parts of an database result?

I'm trying to add a feature in my application that totals how much time a user spends in the system by the week, month, etc.
$select = "SELECT TOTAL_HRS FROM timeclock WHERE USERNAME = '$sessuser' AND CLOCK_OUT BETWEEN '$dbpast' AND '$dbnow'";
I have a MySql result of two sample time entries: 00:00hr:04min:08s and 00:00hr:12min:52s. Users can have more.
TOTAL_HRS is a varchar column, so when I put a sum() on it, it returns a 0.
Here's what I have so far:
while($row = $query->fetch_assoc()){
print_r($row);
$sanitized = preg_replace("/[^0-9:]+/", "", $row);
print_r($sanitized);
$joinarr = implode(':', $sanitized);
$parts = explode(':', $joinarr);
print_r($parts);
$zerodate = new DateTime('0000-01-01 00:00:00');
$addhrs += $parts[1];
$addmin += $parts[2];
print_r($addhrs);
$interval = $zerodate->add(new DateInterval('P' .$parts[0].'DT'.$parts[1].'H'.$parts[2].'M'.$parts[3].'S'));
$totalhrs = $interval->format('%D:%Hhr:%Imin:%Ss');
print_r($totalhrs);
}
I get funky junk in return: 0%Sat:%0012Sat, 01 Jan 0000 00:12:52 +0100:%001121:%st52
What I need to return back is: something like: 00:00hr:17min:00s. I don't plan on storing this, just want it to display on a page.
I need some help figuring this out. I'm sure there is a better way. I'm not that great at functions. Or should I send the results through jquery and handle them there? Which side is more efficient at handling DateTime? The help would be much appreciated. Thanks!
You can calculate the number of seconds between two datetime values using TIMESTAMPDIFF() and then sum that. e.g.
SELECT SUM(TIMESTAMPDIFF(SECOND,CLOCK_IN,CLOCK_OUT)) AS TOTAL_SECS
FROM timeclock
WHERE USERNAME = '$sessuser' AND CLOCK_OUT BETWEEN '$dbpast' AND '$dbnow'
see: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampdiff
You might currently be using TIMEDIFF() which gives you those "funky" values
I would do it like this:
Create a column in the database to save each session time on site. I would probably set it as an integer rather than a timestamp column. I just need it to return a number. I'd have a separate timestamp column to record the time of the visit.
Client side bind a javascript/jquery function to window.onload which saves to localstorage / sets a cookie to current timestamp when the page is loaded, use moment.js library to display total site time to user and have it count up in real time. Check to see if cookies already exist and if so process them before setting new values.
Either bind another function to window.onunload to save another cookie with the timestamp when the user navigates away from the site, or use setInterval to save the latest timestamp every minute or so while they are on the site.
On page load check if cookies/localstorage have values then subtract timestamp of page load from timestamp of page unload to get number of seconds they spent on site. Save that to database and use the timestamp of the unload event to set the timestamp of their visit.
Run relevant queries on the database to return total seconds on site in last day/week/month whatever and pass them to moment.js via ajax. It can displaying a counter like you describe from a string containing a value in seconds using about 2 lines of code.

Php session in a chat, browser crash

I'm Italian, and i'm not good in English, but I Try to explain what i want to ask to you :)
I'd want to ask you a question about PHP and Sessions stored on the server.
I'm making a Play by chat online game using php and mysql.
What I need is to detect, using php, expired sessions for inactivity.
While an user is logging into the game, I update a table on a DB . This column that I update is the timestamp of the latest action done by the user. Then, i start a session for the client X. If this column is empty, it means that the user is logged off .
If an user do the logout correctly ( a button inside the game ), with php i destroy the session and i update the column of the DB with an empty timestamp, so the user results correctly logged off, but if there is a crash of the browser?
How can I detect that a session has been destroyed by the crash of the browser?
Thank you :)
you could store the connection ID in a seperate table, run a loop that periodically checks those connections for messages the client periodically would sent to denote activity
if the time difference is larger than the message update interval by a certain margin, you would drop the connection and/or update the tables
You have to set a "timeout", for example 10 minutes (600sec)
So, for any action of a user you check if he is current active by the difference of date_last_action and now().
For exampre.
Login : 2014-03-27 15:49:00
Last action: 2014-03-27 15:51:00 (only 2 minutes from the last action
[login])
Last action: 2014-03-27 16:21:00 (over time, so clear the db record,
delete his session)
$date_now = time();
$date= DATA VALUE OF LAST CURRENT USER ACTION;
$date1 = time();
$date2 = mktime($hh,$ii,$ss,$mm,$gg,$aaaa);
$dateDiff = $date1 - $date2;
$fullDays = floor($dateDiff/(60*60*24));
$fullHours = floor(($dateDiff-($fullDays*60*60*24))/(60*60));
$fullMinutes = floor(($dateDiff-($fullDays*60*60*24)-($fullHours*60*60))/60);
$deadline_in_minutes=10;
if($fullMinutes>$deadline_in_minutes)
{
//do logout clear session
}
Ciao!

Limit the access of a function to once every 24 hours (PHP and MySQL)

I would like to limit the access of a function i've created to once every 24 hour based on the users IP address.
I would also like the PHP script to delete the MySQL record if it's older than 24 hours.
If the user already has used the function within 24 hours, show them a message and prevent the script from continue running.
If the user already has used the function but 24 hours has passed since he used the function, delete the MySQL record and let the script continue running.
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$con=mysqli_connect("domain.com.mysql","domain_com","domain_password","domain_database");
$result = mysqli_query($con,"SELECT * FROM ipblock WHERE ip='".$ip."'");
while($row = mysqli_fetch_array($result));
if($ip == $row['ip']) //and code for checking how old the record is
{
// The user has used the function within 24 hours, kill the script.
echo "Come back in 24 hours";
exit;
}
else
{
// Looks clear, let them use the function
$MyFunction = true;
}
?>
I'm lost and as you can see i am also missing some statements for deleting old records (-24 hours)..
Could anyone provide me with an example of how to do this?
Thanks
Firstly store the IP and Access time as a pair in a table. Then you check is simple to see if there are any records in existence where the IP matches and the timestamp is less than 24 hours ago.
Before the function runs, complete an INSERT ... ON DUPLICATE UPDATE, and have the IP address as the primary key in the table.
The removal of old entries is then less of a priority and you can schedule this to be whenever convinient and remove entries where the access time is greater than 24 hours ago.
Store the access time as a myqsl date time, and do the comparison using the where clause:
WHERE accesstime >= DATE_SUB(NOW(), INTERVAL 1 DAY)
I'd create a table with function load
Store IP address and timestamp
When user loads the page, before running the function, select for IP adress and timestamp < 24 hours previous.
If you run the function: Store the users IP
No need to delete older records. But you could lik this to the verification function: delete all events older than 24 hours whenever the function is called for. Or set a cronjob to run every 12 hours to delete all older function load records
Basically, you can just create a timestamp field in the database. Then you compare using timediff() the stored values with the value of now().

Creating a delay between posting comments

Im adding a comment section to my forums and i want to add a delay, Maybe 30 seconds or so to stop people spamming along with a captcha .
Whats the best way to do this? Only way i can think is using cookies, any other suggestions?
You could use PHP sessions to do something like this, but not sure how 'fool' proof it is.
The idea would be do something:
if(isset($_POST['cmdComment'])){
$_SESSION['comment_posted'] = time();
}
Then you could have a function say checkTime() which you could put inside there to subtract the session value from the time it is now. If the difference is >= 30 seconds, then continue with the post and set the $_SESSION['comment_posted'] to the new time, otherwise ignore the post request.
When a user post their comment, write the current timestamp in a session and add it additional 30 seconds:
$_SESSION['postedTime'] = time() + 30;
When you want to check if 30 seconds are passed, get the current timestamp and compare them: if the current timestamp is bigger then one in session, then 30 seconds are passed:
$timestamp = time();
if($timestamp > $_SESSION['postedTime'])
{
// allow posting
}
else
{
// decline
}
For more security, you could insert user's IP + post timestamp in the database.
When the comment is inserted in the database, make sure to keep track of the user and timestamp.
When the user goes to post again, check if the last comment he posted was 30seconds before.
Deal with this accordingly
A forum usually has members, well atleast I don't know any that do not have it.
Now if you post a comment I assume you put that in a table called something like Comment with an ID, POST_ID, USER_ID, MESSAGE, POST_DATETIME
Atleast thats how I would do it.
Now you have the datetime when the user last commented on the a certain post. Now you can query your database whether he or she can comment again

time count after registry

I saw some website that after you have registered, you can use the service like posting a comment immediately.
You may have to wait for 5 or 10 minutes to be able to start, like this StackOverflow website.
Once you have asked question, you have to wait 20 minutes to select your answer.
If I want to do it in JavaScript or PHP can anyone show me how to do it? I assume you have to compare the time with current time-stamp, but don't know how to exactly implement it. Thanks in advance!
Assuming you have a datetime string stored in a variable, you could do something like:
// TODO: get a datetime string into $time
$minutes = 5;
if (strtotime($time) + $minutes * 60 < time()) {
// It's been 5 minutes since $time
}
In PHP:
$wait_time = 10*60; //10 minutes * 60 seconds
if(time() > $start_time + $wait_time) {
}
sure, you'll want to compare the date of posting, with the current date, but then formulate the conditions that will validate a new post or the selection of the same.
Each question that is posted will require server side storage, if not exclusively in a db then there will need to be at least a record in a table linking the question to the user.
Once a question has been posted you could either have the server side script that loads the question carry out the following tasks.
Get the question entry
Is the person that posted the question the current requesting user
[yes]
Is the request time minus the post time greater than (number of mins * 60)
[yes]
Include select answer buttons (html objects or buttons)
Alternatively you could always show the buttons and carry out the above logic and return some indication that the user must wait x minutes before they can select an answer.
You have to store the creation time (of whatever object or saving) along with the item being created in the database. So for example, if you create a question on SO, they probably store the time you posted the question. Then when you go to view your question, they probably get the difference between the current time and the time stored.
So say that you want to implement a 20 minute wait after posting a question before you can select an answer. Then you upload a question at 5:00 PM. When you attempt to view your question at 5:05PM the same day, the difference in time is 5:05PM - 5:00PM, which is 5 minutes. Take 20 minutes - 5 minutes to get the time the user must wait, and send that back to the page.
From javascript you can get that time limit (15min), and create a setTimeout method to "unlock" the answer feature. The code would look something like this:
<input type="hidden" id="waitfor" value="15">
$(document).ready(function () {
var waitfor = $('#waitfor').val();
timer = setTimeout(function () {
// let the user know they can post an answer
}, waitfor * 60 * 1000);
});
Also, I'd let the user post an answer whenever they'd like, but prevent it being submitted on the client side if it hasn't been 20 minutes.

Categories