Making an auction script start and stop auctions at specific times. - php

I am building a simple auction application. I need auctions to start and end at certain times. Should the page that displays the open auctions just run a query to find all auctions where current time is after the start time and before the end time? Or would it bet better to have a script that sets a "active" column to True? If this is the case would I have to have some type of cronjob setup?

No cron and no "active" column is required. Just list auctions using something like:
select *
from auctions
where
start < now()
and end > now()
When user is placing a bid use the following:
update auctions set
bid = $bid,
highest_bidder = $bidding_user_id
where
id = $this_auction_id
and start < now()
and end > now()
and bid < $bid
Then check if query has affected a row. If yes - bid is successful, current user is highest bidder. If no - bid is too low or auction has finished. You can figure out that later by fetching auction row again and checking bidder id.

Just set a "close_time" field in the mysql table with your auction. When you add the row, populate that field with a time() + whatever to set the close_time to represent some point in the future.
Then setup a script which runs a simple query:
'UPDATE auctions_table SET active = FALSE WHERE active = TRUE AND close_time <= UNIX_TIMESTAMP()'
Save that query to a php page called something like close_active_auctions.php and set that up on a cron for once every 10 seconds or so (or however often you need).

Related

How to calculate the total time logged in the system?

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

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.

MySQL event scheduler refresh error PHP

I have this code in my php, but everytime I refresh the page it says Event 'expired' already exist. any way that it would not pop up anymore?
$auto = mysql_query("CREATE EVENT expired ON SCHEDULE EVERY 1 MINUTE DO UPDATE stocks SET status='expired' WHERE expdate < NOW() ") or die (mysql_error());
Thanks
By the looks of it, every time you refresh the page it will attempt to create a new event with the name expired.
If you only want to create one event and never worry about it again (and based on that query, it looks like you do), you should just do it once in the database directly.
However, if you really want to keep it in your code, you could use IF NOT EXISTS: https://dev.mysql.com/doc/refman/5.1/en/create-event.html
CREATE EVENT IF NOT EXISTS expired ON SCHEDULE EVERY 1 MINUTE DO UPDATE stocks SET status='expired' WHERE expdate < NOW()
However, if all you want to do is determine the state of a stock at a give time, it might make more sense to use MySQL's IF logic to derive a status at any point (and not actually have a status field in your table): https://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if
SELECT *, IF(expdate < NOW(), "expired", IF(expdate < NOW() + INTERVAL 10 DAYS), "critical", "fine")) AS status FROM stocks

Daily cron to poll mysql and update status based on timestamp

I have a db full of email users that lists the date and time they signed up in a column called signup_date using the DATETIME type (it uses now() ) and I also have an expire_date column which lists the same format but exactly a year later using ADDDATE(NOW(), INTERVAL 365 DAY)
I have added a status column with values being either 0 or 1. I guess this can be an ENUM type. Upon registration, status is set to 1 for active.
What I want is that if the timestamp of the expire_date is older than the current time, the cron should execute an update on that row of the user setting the status to 0. In postfix, I altered the query and appended the status=1 so that it will select the user with only status of 1. If the status isn't 1, then the user will not be found and won't be able to log in. This cron can run daily. I'm not too anal about having it run every second. Users can renew their emails within the next day. So this is my simple way of expiring emails, if they are not active or so after a year. What I need help with is constructing the cron. Should this be done with just php or does some bash need to be used? Im unclear of how to structure the script. Thanks.
Why maintain an additional flag column? You can calculate the status on the fly
SELECT *
FROM table_name
WHERE expire_date > NOW()
This will return only unexpired rows
If you need status to be produced as a column you can do
SELECT *, (expire_date > NOW()) status
FROM table_name

What's the easiest way to count specific value in a specific date (mysql-php)?

(sorry for bad english and poor skill)
Hello! I've got a mysql database which contains four columns and a cron job as a script, which requesting a status of a user every 10 minutes.
DataBase columns:
ID UID STATUS CHECK_AT
ID - just a sequence number (1,2,3 and so on). Each time a script writing something into the DB, the number grows up.
UID - Key value. Let's say it's ID of a user. All DB contains about 3-5 differents UID
STATUS - with values 1 or 0. Let's say 1 is online, 0 is offline. Online status timeout is 10 minutes.
CHECK_AT - Time and date of script work, like 2013-10-01 00:30:01
Logic: every 10 minutes script is checking specific UIDs (written in other table) for online (1) or offline (0).
What I;m trying to do:
To output summary online time of specific UIDs for a day; week; month etc
I guess it should be elementary, like
select count(id) from DB_NAME where date(check_at) = '2013-10-01';
for a one day
select count(uid) from user_activity where date(check_at) between '2013-10-01' and '2013-10-07';
For a few days and so on.
But, my skill is to low to know, how I can count only online time (status=1) for a date.
Can you give me some advices, please?
you could add your conditions in WHERE clause like:
select count(id) from your_table where date(check_at) = '2013-10-01' AND status = 1;
OR
select count(uid) from user_activity where
date(check_at) between '2013-10-01' AND '2013-10-07'
AND status = 1;

Categories