I'm new to PHP and I'm hoping to make a script where a user will get a "coin" every hour that they go on the page. For instance, if a user logs in twice during the same hour, they will only get one coin. But if they refresh the page during the next hour, they get another coin. However, they do not get coins when they do not refresh the page, even if many hours go by.
How would I even start going about doing this? Any help would be extremely appreciated.
Easy... :) If you are using MySQL or something to store the coins, get the time too, when the coin was credited. And each time the page is called, check the time. A pseudo code would be like this:
load(coins);
timeDiff = timeNow - timeLastCredited;
if (timeDiff > 1 hour)
coins++;
save(coins);
In case of PHP, I guess you may do like this:
$coins = getCoins(); // Assuming this function will load the current coins count from DB.
$lastCredit = getLastCoinCreditedTime(); // Should return a DateTime integer.
$timeDiff = microtime() - strtotime($lastCredit);
if ($timeDiff > 60*60*60*1000)
saveCoins($coins+1); // Assuming this function saves the new number of coins.
I'd do it this way:
On each page load (refresh, login, whatever), check to see if the user has already received a coin for the current hour. To do this, you need to know what the current hour is:
$hour = (new DateTime())->format("Y-m-d-h");
This will give a value like "2013-03-25-11" during the 11:00 hour. I'm including the date, since we don't to want skip giving a coin in, say, the 11 o'clock hour just because they were online yesterday at 11:05.
Then you can either:
Add one to their coin total whenever you have a new $hour value (ie. it's not recorded in your database) and save the $hour value, or
Save the $hour value in the database and count the total number of coins earned with a query like SELECT COUNT(DISTINCT hour) FROM table;
The first approach is useful if they're spending the coins on something (ie. you can add/subtract from their "coin account"); the second is useful if you just want a grand total of the number of coins (ie. the total number earned, ever).
I'm going to assume that you have a users table in a database.
If that is the case, you can use a column in the database to update the latest time that a user has gone on the page with php and a query on that page. Then you can set up a cron job that runs every hour that will query the users table and see if the user has viewed the page within the last hour. If the user has viewed the page within the last hour, increment the amount of coins associated with that user.
Related
I am using CodeIgniter and I am calculating the total time from the dates.
Explanation:
What I am doing is, Every login I am inserting the last_Ativity date and time in the database using below code.
$data_login= array('emp_id' =>$result->id ,'last_activity' =>date("Y-m-d H:i:s", STRTOTIME(date('h:i:sa'))));
$this->db->insert('tbl_current_login',$data_login);
last_activity time continuously updating if the user still in the system . (I am using ajax to update the datetime. I haven't shared that code).
Now I have to calculate the total time of the specific user for a single day(current date).
For example- emp_id 26 logged in twice so I have to calculate the time
First-time login date and time:-2018-09-17 07:27:55
Second-time login date and time:- 2018-09-17 07:35:22
It will increase depending upon how many time the user logged in.
I am confused about the time. Am I on the right path to calculate the total hour login in the system?
Should I use an MYSQL query or PHP to calculate? I need some idea.
Would you help me out in this?
This is what I would do
last_activity time continuously updating if the user still in the system . (I am using ajax to update the datetime. I haven't shared that code).
Before you update the row.
check if a row for activity exists
if it does, get the timestamps for the date and subtract the current time (the one you are changing last_activity to, from the one stored in the DB) take that number and add it to an integer column named something like elapsed time (you would have to add this to the DB)
if not then enter a row with 0 elapsed time ( depending how you put the first row in, maybe on login) this may never be an issue.
For the timestamps, you would do a select to get the current row. Take the datetime field and use either
$time = strtotime($row['last_activity']);
OR
$time = (new DateTime($row['last_activity']))->getTimestamp();
Then you simply do the same thing to the date you are going to replace that with and then subtract to get the difference in seconds.
$elapsed = time() - $time;
And then add that to the current rows value, and save it. This way you can keep track of a running total in seconds of the time they spend during that session.
Then when you need to count the total time its a simple matter of doing
SELECT SUM(elapsed_time) FROM {table} WHERE DATE(last_Ativity) = :date
If you were dealing with just two date time fields in the DB it would be easier to just get the difference of those, but sense you already have code to constantly update the last active field this would require less work in the long run IMO.
Option2
The other option is to add another Datetime field to put a start time or login time in. Then when you query you can convert them to their timestamps and subtract to get the difference.
This makes the SQL harder (when doing the SUM ), I can't really think off the top of my head how I would calculate the elapsed time on multiple rows and then sum them up. But it does simplify the PHP quite a bit. So which ever way works best for what you need. Think about if you need the utility to know when they logged in, or if you just want an easier way to calculate the time they spend.
Something like that.
Assuming that the only log happens based on user actions, and so, after 15 minutes (for example) the user is assumed logged out
And assuming you'd want daily total, the solution should be something like this:
SELECT
first.emp_id,
SUM(TIMESTAMPDIFF(MINUTE,first.last_acivity, DATE_ADD(IFNULL(last.last_acivity, first.last_acivity), INTERVAL 15 MINUTE))) as logged_minutes
FROM
(
SELECT
la1.*
FROM
last_acivity la1
LEFT JOIN last_acivity la2 ON
la1.emp_id = la2.emp_id AND la1.last_acivity < la2.last_acivity
AND la2.activity =< #date0
WHERE
la1.last_acivity >= #date0
AND la2.login_id IS NULL
) first
LEFT JOIN
(
SELECT
la1.*
FROM
last_acivity la1
LEFT JOIN last_acivity la2 ON
la1.emp_id = la2.emp_id AND la1.last_acivity > la2.last_acivity
AND la2.activity =< #date0
WHERE
la1.last_acivity >= #date0
AND la2.login_id IS NULL
) last
ON
first.emp_id = last.emp_id
GROUP BY
emp_id
In this query need to set the date seperately:
SET #date0 = DATE(NOW()) ;
To get the first record of the day, or the last, we need to LEFT join the table to itself, on the same emp_id BUT witn with an inequality, which will get for each emp record its ancestors or predecessors
When we add the NULL condition we bring the we get the edge case: first or last
What's left then is just calculating the minutes between the 2 tables
Since I assumed no log out record occurs, I treated the case when the first and last logins are the same, or no last login
I have a table called profile_views on my site that counts how many times a person views a users profile. What i am trying to do is let users see how many visiters they've had to their profile in that week, and every week I on Monday I want the table to be emptied so the count can restart from 0.
I am trying to create a php if statement that says every week on monday carry out the delete mysql query. I have got it to perform only if the day is monday, however I am trying to find a way to execute it only once, preferably at 00:00AM monday morning, because I dont want it deleting results in the table constantly throughout the whole of monday.
<?php
$today=date(l); // Find what today is? using date function
// If today is Monday displays message "Today is Monday" and displays image1.gif
if($today==Tuesday) { // Compare $today with name of the day.
$result = mysql_query("DELETE FROM ptb_profile_views;")
or die(mysql_error());
}
?>
What you are looking for is named cron - use it to invoke your PHP script on desired weekday at desired time.
Setup Cron - based on our requirement
http://www.sophos.com/en-us/support/knowledgebase/12176.aspx
http://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
you could set up a cron job to automatically execute the script, but a better way (the way I do it) is to just leave the entries in the database and when displaying the number of visitors in the last week, change your query to return only entries within the last week. this might be much easier.
A method without cron jobs:
You can set a variable $ran and store it somewhere (maybe in a file?). Then every Monday, run and store the $ran into the file as true.
If it's any other day, set $ran back to false. This will ensure that the script will only run on Monday, and only run once.
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.
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).
I want to set up online detection on my website.
I have a row in my user table where the last login datetime is stored. Every time a user visits the site, his login date updates and user online row sets to 1 (1 - online, 0 - offline).
How to change the online row to 0 (offline) if the last login was 10 or more minutes ago? The aim is to find difference between dates.
cronjob every 10 minutes?
UDPATE users SET online = 0 WHERE login_date > (NOW() - INTERVAL 10 minute);
just to each user add a last_seen timestamp to there row so that when you do your user is authed check you can update the time
if(logged_in())
{
update_user();
}
function update_user()
{
//UPDATE users SET last_seen = unix_timestamp() WHERE uid = X;
}
Then you can do for you users:
SELECT * FROM users WHERE last_seen > (unix_timestamp()-300)
To get the last 5 mins.
If you want to show the users who have been online within last 10 mins then the best method is to include the datetime condition in the sql query.
Save the last login time as timestamp, then you can easily compare it with the current time and tell how much time has passed since.
Depending on the size of your user table, you can run the check of those who are still supposedly online every time somebody calls your website.
A different approach is to store active users in buckets, labeled with the last login time, you can then easily reset all users that are in buckets older than 10 minutes.