set status on record automatically after certain datetime - php

I have a form that users fill in to post their job advertisements and one of the fields they enter is the number of days to keep job 'open'.
I want to be able to automatically change the status of the job to 'closed' after the days that they have entered have elapsed.
The job table is already set up with status and expiry, I just need to know how to automatically change the status from 'open' to 'closed'.
I have little knowledge of MySQL and the queries that I would need to run.

Suggest that you don't keep status as a field in the database, but rather derive that status from the expiry date in your business or presentation tier. This could be done in your SQL code or in client code(PHP).
Some pseudocode:
INSERT INTO JobAd (Description, ExpiryDate)
VALUES (#Description, #Today + DaysToLive)
...
SELECT *
, CASE WHEN ExpiryDate<#today
THEN 'Expired'
ELSE 'Good to go'
END AS JobStatus
FROM JobAd ORDER BY JobStatus, ExpiryDate
When you pull those jobs out, use PHP to write the status back to the user, based partially on ExpiryDate. Again, this could be done in SQL or PHP.
Having the status derived means you won't have to create a maintenance process/task to go update an attribute in the database.

Related

Update sql post on specific date "behind the scenes"?

I have a php website with a news section and the posts are stored in an SQL database. Each post has an expiration date (i.e. 2016-03-01) and an active column that is set to true or false. Active = true shows post.
I want the active column to change from true to false on the expiration date so that the post is no longer visible on the page. I know how to do this with basic php but that requires an input from the website, i.e. a push of a button or the page to be loaded, for it to update.
Is there a way for the database (or php) to do this behind the scenes and update the post on that specific date?
I suppose you are using MySQL server. If this is the case, you can use events. You can define events to execute queries every hour, minute, etc.
CREATE EVENT remove_expired_posts
ON SCHEDULE
EVERY 1 DAY
DO
UPDATE posts SET active = 0 WHERE expiration_date <= NOW();
More generally though, you can avoid this and add an additional condition when selecting the posts to be shown:
SELECT * FROM posts WHERE active = 1 AND expiration_date > NOW();
The tip from #YUNOWORK worked fine. My web hotel didn't have crontab installed but I am now testing a web service that does the same thing. Works really great!
I'm using www.cronless.com right now. It's free and does what I want.

How to detect when a user is not online?

Well I've a admin dashboard which is PHP-Coded.
Now I want to know about my ONLINE users. For which I created a table in data base called "ONLINE". When a visitor/user comes to my site its IP is save on my database & on dashboard, show me 1 user online.
The problem starts from here. I want that when a visitor/user leave my site (close the site, close the tab, and whole browser). This saved IP (in ONLINE table) of the user, migrate or transfer to another table in data base named "VISITORS".
Detecting a user exit is a bit fuzzy. You can use javascript to send an exit notification to your server such as:
window.onbeforeunload = function() {
... insert your ajax code here ...
}
There are a lot of conditions where that won't fire though, so a better way is to use check-in code. You can make a php script that inserts/updates the ONLINE table(assumes the IP field on your table is set to be a UNIQUE or PRIMARY key, also requires you to create a TIMESTAMP field on the table - I named it last_check_in):
<?php
... connect to database ...
$statement = $db->prepare("INSERT INTO `ONLINE` SET `IP` = ?, `last_check_in` = NOW() ON DUPLICATE KEY UPDATE `last_check_in` = NOW()");
$statement->execute([$_SERVER['REMOTE_ADDR']]);
Then you can put an ajax call on a timer(here's jquery's ajax page: http://api.jquery.com/jquery.ajax/ and you can use setTimeout in your callback to schedule the next update) to make the page check in.
Then you can change your query that shows online users to only show users who have checked in recently:
<YOUR QUERY> WHERE <your WHERE stuff> AND `last_checkin` > NOW() - INTERVAL 1 MINUTE
This would actually allow you to just use one table instead of two, but if you're set on using two tables, you can write another script that moves users who haven't checked in over and put that on a cron timer.
So, to "figure out if a user left" you need to store some kind of last-activity-timestamp and determine a threshold time period for what you consider "active". This could be 30 minutes, or 15, or an hour; it's really up to you.
You can accomplish two goals with one task by using MySQL to handle your sessions. Whenever you create or update a session, you can also store the IP Address and the timestamp when the session is being updated. If the user logs out, session_destroy() will be called, which will call destroy() in your session handler, where you can "move" the IP to the table for non-logged-in users. Using a custom session handler gives you a straightforward place to put all of the logic.
Use one table "VISITORS".
For Example, period is 1 hour.
Add field:
FirstActivityInHour (DateTime, TimeStamp or Int (minutes part))
LastActivityInHour (DateTime, TimeStamp or Int (minutes part))
If visitors leave site - you can not track this action, no action. You can track last action.
If LastActivityInHour near now moment - visitor online. Non-optimal query example (FirstActivityInHour, LastActivityInHour - DateTime):
SELECT ...
FROM "Visitors"
WHERE
LastActivityInHour > DATE_SUB(NOW(), INTERVAL 10 MINUTE)
AND
DATE_ADD(FirstActivityInHour, INTERVAL 1 HOUR) > NOW();

Send confirmation mail to last inserted row

I am trying to create a simple Support Request system which users can insert their email address in a form though jQuery - Ajax and PHP into MySQL database.
After that I need to send a Confirmation Email to the inserted email owner "
every time that a new request inserted into the database". I was thinking about using the Ajax call from database but I am not sure how to select
1- latest inserted row AND
2- Not selected rows to do this( there might be a situation to have two insert at exact same time then the
SELECT email FROM tbl-request ORDER BY id DESC LIMIT 1;
might return Only the last inserted however there where at least two new entries)?
can you please let me know if there is solution to do this through MySQL Trigger or jQuery Ajax
suffii you can add a new colum to the table eg. status which contain 0 as a default value.
Now every time you send a email then update this value to 1.
so you can select the rows for which an email is not sent yet like this..
SELECT email FROM tbl-request where status=0;
It will select only the latest entry containing status = 0.
There can be many way But as my point of view this also can be a better and simplest way
you can do this using cron job.
Run a cron job line every 5 mins and set a flag to check if mail is sent or not. after sending mail set the flag to 1.
We can easily save the last time we checked in a database or file. This method of doing it would allow you to have the emailer system separate from how the record is inserted, which is what I gather you want given that you're suggesting use of Triggers or AJAX to handle it. This method will work even without access to write the database from the PHP script.
At the end of the email script run:
$fh=#fopen('last-email','w');
if (!empty($fh)){
fwrite($fh,time());
fclose($fh);
}
At the start run
$last_email_time=file_get_contents('last-email');
Then add a timestamp field to your table; this will automatically append the time the record was last edited or added.
Then your query will be:
$last_time_as_sql_date=date('Y-m-d H:i:s', $last_email_time);
$query="SELECT email FROM tbl-request WHERE timestamp>'$last_time_as_sql_date' ORDER BY timestamp DESC LIMIT 1;"
How you actually run the script depends more on your implementation; if on a server back end you could run every 5 minutes using crontab -e
*/5 * * * * php /path/to/script.php
You could send the mail from PHP at the moment the request is inserted, but you may want to keep those processes separated.
To do so, an easy fix would be to add a field 'ConfirmationMailed' or something to indicate that that mail was sent. That way you can just query for requests that weren't emailed yet.
A little bit more flexible would be to create a separate table tblRequestCommunication in which you store the communications about the request.
That table could have:
Id (PK), Date, RequestId
Subject
Content
CommunicationType
The communication type could be an enum or a reference to a separate type table in which you store the types of communication to send. One of those types could be 'Automated confirmation message', and in the table you can even store the exact date time, subject and content of that message.
Now, in your query, all you have to do is search for requests without such a confirmation:
SELECT r.email
FROM
tbl-request r
WHERE NOT EXISTS
( SELECT 'x' FROM tblRequestCommunication c
WHERE c.RequestId = r.RequestId
AND c.CommunicationTypeId = 1 /* Automated confirmation */)
This structure will allow you to expand this system for other types as well, for instance an automated mail when the request was closed:
SELECT r.email
FROM
tbl-request r
WHERE
r.State = 'Closed'
AND NOT EXISTS
( SELECT 'x' FROM tblRequestCommunication c
WHERE c.RequestId = r.RequestId
AND c.CommunicationTypeId = 14 /* Close notification */)
Also, you can store 'manual' e-mails and phone reports that are linked to the request in the same table, so you've got a full history of communication.
So, it's a bit of work to create one or two extra tables and change the query, but the abilities of your system will be a lot larger.

requesting unique id every page load

I'm creating a page that needs to select a Unique ID for every page load. It's basically a purchase order system, but the PO will be just the UID, so it's important that no user can get the same ID. I tried doing just calling upon last ID, then adding 1 and submitting, but that could create conflict if two or more users are entering at the same time. What's the best way to pull a UID for each page load? Any solutions?
Thanks
Lloyd
UniqId() is one way, but results in large numbers. As V Patel says, there's also "Auto Increment" and this is probably the option you want.
In MySQL set up a table (say "PurchaseOrders") with a field "po_id" and set that to be the primary key and auto increment. Add another field "po_status" (TinyInt*1) and another "po_lastused" (Date*1). Status will be 0=draft, 1=final, 2=shipped etc. LastUsed is the last time the user accessed the details.
When you want to create a new purchase order, INSERT INTO PurchaseOrders(po_status, po_lastused) VALUES(0, NOW()); Note: you've not specified the actual purchase order
You can get the po_id through asking for the "last insert id" (http://php.net/manual/en/mysqli.insert-id.php, http://php.net/manual/en/function.mysql-insert-id.php, http://www.php.net/manual/en/pdo.lastinsertid.php, depending on your coding library)
Store the po_id in a session variable so that when the user returns, you know their po_id(*2)
Each time a user access a purchase order, if "last updated" was more then 5 minutes ago, update the timer.
Periodically deleted all purchase orders that are draft and where last updated is older than your session (e.g. after a day)
This way, you'll end up with nice purchase order numbers that are easily quotable.
*1 For the purists, You can also use Enum for the status, and int for dates - depends on your preference. You can also set the date to be automatically updated. But I'm keeping it simple.)
*2 Again, for the purists, there is more security you could implement here to ensure the "other" users can't access someone else's purchase order, but this is enough to start.
You can use the uniqid function to get a unique key. Run it through hexdec if you need an integer.
PHP has one:
http://php.net/manual/en/function.uniqid.php
Use auto increment feature of the database in use, especially if you like it to be a number and don't need it till you want to persist it.

automatically update mysql field based on value of other field

I have a mysql table for subscription details
It has a start_date, end_date and status field
Now, what i would like to do is whenever end_date of subscription is reached, i would like the status field to change from active to inactive
for example when end_date > curdate, update subscription table set status=inactive
Is there a way to run a check at the end of each day to check and update this?
how can i do this?
Why not just create a view and calculate the status. Then use the view instead of the table:
CREATE VIEW vwSubscription
AS
SELECT
start_date,
end_date,
IF(end_date > curdate, 'inactive', status) as status
FROM subscription
you can use the cron job in linux based server to check and manipulate the data in db with php
what you need to write is a script that runs in the background like this
while (true) {
echo 'updating';
//check rows here
echo 'done';
sleep(10);
}
Just execute it in the shell (php -f script.php) and put that in the background and it will do what you want. Just remember that memory is important. Make sure you unset($var) everything on each cycle so your memory usage doesn't go through the roof.

Categories