PHP MySQL Deactivating premium membership after a certain amount of time? - php

I have just recently worked out how to use PayPal IPN to initiate a premium membership when users pay a certain amount for it. Once the user clicks upgrade account, they are directed to PayPal to pay, then the IPN kicks in to update the database to show that the user is premium. I was hoping to have this last for a certain amount of time before their account is returned to normal, yet not sure how to do that? For example, they upgrade, 2 years later, a MySQL update is triggered to return their account to average. Here is the IPN script I am using:
<?php
include 'core/init.php';
//DONT CHANGE THESE VARIABLES
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$receiver_email = $_POST['receiver_email'];
$username = $_POST['custom'];
if($payment_status =="Completed")
{
$purchase_check = mysql_query("SELECT premium FROM users WHERE username='$username'");
while($row = mysql_fetch_assoc($purchase_check))
{
$paid = $row['premium'];
}
if($paid=="0")
{
if($receiver_email=="aidan6141#hotmail.co.uk")
{
if($payment_amount=="6.99" && $payment_currency=="GBP")
{
$update_premium = mysql_query("UPDATE users SET premium='1' WHERE username='$username'");
}
}
}
}
else
{
echo "Access Denied!";
}
?>
I am thinking using my BASIC idea of PHP that I might add a value of "upgrade_date" to the database as a timestamp and then add into my code:
mysql_query("UPDATE users SET upgrade_date=CURDATE() WHERE username='$username'");
So updating the date when they upgrade shouldn't be an issue, the issue is how can I recall that information so in 2 years after the time stamp, they are issued back to an average member? I was also hoping to show a countdown date or something so they know how long they have left on their account?
Any help would be appreciated, thanks!

Why don't use unix timestamp instead of using boolean value in the database?
you can just say that the field premium in your database will save the expiration of premium membership
and then you can do the check to see if the current time stamp is greater than the value saved in the field premium then it's expired ... if it is Null or 0 he never been premium, and if it's less than the saved value then his membership is valid and then you can calculate the difference between current timestamp and the saved one to see how much longer it still has to expire.

Why not have in your DB
upgraded = tinyint: to store a 0 for not upgraded and a 1 for upgraded
upgraded_date = datetime: to store the date this was done
Then set-up a cron job to run (maybe a few times a day or just check as the user logs in) to check if the time has expired, if it has reset 'upgraded' to 0

you maybe need an else condition to check the years.
like that:
while($row = mysql_fetch_assoc($purchase_check))
{
$paid = $row['premium'];
$timestamp_start = $row['upgrade_date'];
$timestamp_end = date("Y/m/d");
$difference = abs($timestamp_end - $timestamp_start);
$years = floor($difference / (365*60*60*24));
}
if($paid=="0")
{
if($receiver_email=="aidan6141#hotmail.co.uk")
{
if($payment_amount=="6.99" && $payment_currency=="GBP")
{
$update_premium = mysql_query("UPDATE users SET premium='1' WHERE username='$username'");
}
}
}else if($years == 2){ do update here and set premium to 0}
else{do what you like here}
}
else
{
echo "Access Denied!";
}

Related

MySQL table not updating through PHP cron job at specified time

I am working on an Android App which has a MySQL database which contains a table that has all the login details of each user.In that table I have column named "Status" which is initially assigned to 0 for every user.Everyday when the user logs in to his account and submits the data(clicks the submit button) the status is changed to 1.And every night at 12 AM the status should be reset to 0.Also, if the user doesnot submit the data until 10 AM for a day, a row should be automatically inserted to the MySQL table with a column value as "No Records" for the particular user whose status is still 0.So,I have a created a PHP file which runs as a cron job in cpanel. The PHP file checks the time every hour. And the current time 12 AM and 10 AM, it should do the required changes.But I am not getting the required result with my PHP script.The script is given below:
<?php
require "connection.php";
$get_time = "select date_format(NOW(), '%H:%i A') as current_daily_date from dual;";
$convert_time = mysqli_query($connect,$get_time);
$php_time = mysqli_fetch_assoc($convert_time);
$final_time = $php_time["current_daily_date"];
$dateTime = new DateTime('now', new DateTimeZone('Asia/Kolkata'));
$d = $dateTime->format("H:i A ");
$e = $dateTime->format("d/m/y");
echo $d;
$s = '00:00';
$g = strtotime($s);
$p = date('H:i A',$g);
echo $p;
$c = '10:00';
$q = strtotime($c);
$r = date('H:i A',$q);
echo $r;
if($d == $p) {
$run = "UPDATE login SET status = 0;";
$connect->query($run);
echo "Status updated";
}
else if($d == $r) {
$second_run = "INSERT into attendance (name,date,attendance) VALUES ((SELECT name from login where status = 0 ), '$e' , 'No Records');";
$connect->query($second_run);
echo "Marked as No Records";
}
else {
echo "Not the correct time to change the status.";
}
$connect->close();
?>
I have set my email for the cron job so that I get the output to my mail. But even at 12 AM ,the table did not update.
The output was:
00:00 AM 00:00 AM10:00 AMNot the correct time to change the status.
I don't know where I am going wrong.Can anyone please check and let me know what is the issue?
The format of the INSERT SELECT is incorrect:
$second_run = "INSERT into attendance (name,date,attendance) SELECT name, ****, **** from login where status = 0";
You don't need the VALUES bit and I'm not sure what the end segment was at all. You also are trying to insert 3 values whilst only providing one, I've put ****'s in there where you need to put your other values.
You should also turn on error reporting in your script if you didn't get any errors from it as this would have been an error.
error_reporting(E_ALL);
ini_set('display_errors', 1);

Last time a user was logged in / browsing the website

I'm trying to set up a notifications system that doesn't requiere cookies.
I'm using SQL to store my users's info, and they are then passed into $_SESSION['user_auth'] once they are logged in.
When a user logs in, I want to fetch the last time the user was online (for instance 05/05/2016 21:35:50) and then compare with the database if there's any more recent announcements, posterior to its "last time logged in".
Is this viable ?
How can I know the last time my user was browsing the website ? Do I need a new row in my 'users' table, if so, how to set this function up ?
Thanks for your suggestions
I've got a similar method I created and you can see the answer here
The basic idea is updating a lastActive column in the database and update this upon user login and set a session variable to the current time. Then at the top of each page is a function that checks a users activity. If the time between last login and current time is above 45minutes then the lastActive data in MySQL is updated.
You can use the following function to set and update the lastActive column and use your own methods for 'when' this function can be used.
function set_last_active($mysqli, $username) {
if ($stmt = $mysqli->prepare("UPDATE Users SET lastActive = Now() WHERE username = ?")) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->close();
}
}
This is what I use as a script at the top of each page:
<?php
include_once 'functions.php';
if(isset($_SESSION['username'], $_SESSION['user_id'], $_SESSION['lastActive'])) {
date_default_timezone_set("Europe/London");
$now = new DateTime();
$lastActive = $_SESSION['lastActive'];
$diff=$now->diff($lastActive);
$hours = $diff->format('%h');
$mins = $diff->format('%i');
$day = $diff->format('%d');
$month = $diff->format('%m');
$year = $diff->format('%y');
if($mins > 45 || $hours >= 1 || $day >= 1 || $month >= 1 || $year >= 1) {
$_SESSION['lastActive'] = $now;
set_last_active($mysqli, $_SESSION['username']);
}
}

Limiting number of incorrect login attempts with timestamp

What is the correct way to let the user verify the captcha after 4 unsuccessfully login attempts within the last 15 minutes. I have got everything running fine but not timestamp part of the query. To be more specific it can display captcha after 4 failed attempts when user try to log in 5th time or so on, irrespective of whether 15min or 30min have passed...
$query1 = "SELECT login_attempts from users WHERE email = '$email' AND last_login < NOW() - INTERVAL 15 MINUTE";
$result1 = mysqli_query($dbc, $query1) OR die(mysqli_error());
$row = mysqli_fetch_array($result1);
$fail = (int)$row['login_attempts'];
If my understanding is correct, You have to check if the 4th last unsuccessful login attempt is before 15 minutes.
For achieving this, you have to store the time-stamps of last four unsuccessful logins in the database.
Create a field called unsuccesful_login_timestamps as text or varchar with large size in your db. We will store the UNIX timestamps of last four unsuccessful logins in comma separated form in this field.
When a user attempts to login, implement the following logic
If username and password is valid, let user login (You can clear the unsuccesful_login_timestamps field if login is succesful if you want). Else, run the following code.
$last_login_string = {{ get unsuccesful_login_timestamps value for this user from database }}
$last_login_string = update_last_login($last_login_string);
$fourth_last_login = get_4th_last_login($last_login_string);
$time_difference = time() - $fourth_last_login;
{{Update unsuccesful_login_timestamps in db with $last_login_string}}
if($time_difference <900){
//show captcha
}else{
//no_need_for_captcha
}
//Method to update last 4 unsuccessful logins by removing
// the last one from the starting and append the latest time in the end
function update_last_login($last_login_string){
$time_array = array();
if(strlen($last_login_string) > 0){
$time_array = explode(",",$last_login_string);
$size = count($time_array);
if($size ==0){ //first attempt
$last_login_string = time();
}else if($size == 4){ //>=4th attempt
$time_array[4]=time();
array_shift($time_array);
$last_login_string = implode(",",$time_array);
}else{ // >0, but <4 attempts
$time_array[$size]=time();
$last_login_string = implode(",",$time_array);
}
return $last_login_string;
}else{
return time();
}
}
function get_4th_last_login($last_login_string){
$time_array = array();
$time_array = explode(",",$last_login_string);
if($size !=4){
$last_login_time time();
}else{
$last_login_time = $time_array[0];
}
return $last_login_time;
}
I'm not terribly familiar with MySQL myself, but DATE_SUB may work:
SELECT login_attempts from users WHERE email = '$email' AND last_login BETWEEN DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND NOW()
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
EDIT: This answer is assuming that you are storing a timestamp (using time() or $_SERVER['REQUEST_TIME']) as the value of the last_login column in the users table.
What you can do is declare a $time variable using $_SERVER['REQUEST_TIME'] and do something like this:
$time = $_SERVER['REQUEST_TIME'] - 900; // Current time minus 900 seconds (15 minutes)
$query1 = "SELECT login_attempts from users WHERE email = '$email' AND last_login < $time";
If you want to change the time duration, just change the 900 to whatever value (in seconds) you want.

Struggling with simple database update

This is a cronjob to check where a users subscription has expired. There are 4 different types of subscription.
However I'm completely lost as to why it doesn't update the database when I run the command.
Below is the script:
$sub = mysql_query("SELECT turboexpires,platinumexpires,goldexpires,silverexpires FROM $tab[user] WHERE id='$id'");
$expire = mysql_fetch_array($sub);
echo "".$expire['0']."";
echo "".$time."";
if($expire[0] <= $time){ mysql_query("UPDATE $tab[user] SET turbo='no' AND turboexpires='0' WHERE id='$id'"); }
if($expire[1] <= '$time'){ mysql_query("UPDATE $tab[user] SET platinum='no', platinumexpires='0' WHERE id='$id'"); }
if($expire[2] <= '$time'){ mysql_query("UPDATE $tab[user] SET gold='no', goldexpires='0' WHERE id='$id'"); }
if($expire[3] <= '$time'){ mysql_query("UPDATE $tab[user] SET silver='no', silverexpires='0' WHERE id='$id'"); }
I put the echo's in to check that they were working and they are.
$expire[0] comes back with a unix timestamp, in this case a past one.
$time comes back with the current unix timestamp.
I also tried removing the '' around $time as shown above with no luck.
However, when I then proceed with the command nothing happens in the database.
Hopefully an easy problem, I've just been looking at it for so long I'm completely lost!
Thanks for any help!
P.S yes I know I need to upgrade to mysqli, it's on the todo list haha!

Run php script monthly on windows based server

I need your help to run following php script automatically on 05th day of the every month. Currently I run this manually. Is this possible using schedule task?
Also I don't have admin access to the web server. Therefore cannot use third party automation tools.
PS:
Is it possible to schedule this in a local machine with windows 7 xampp environment and then later update remote db?
session_start();
if($_SESSION['log'] != "log" || $_SESSION['type'] != "***"){
header("Location: ***.php");
}
require_once('conf.php');
date_default_timezone_set('Asia/Kolkata');
$date = date("j"); //get current date
$today = date("d-m-Y");
$now = date("F j, Y, g:i a"); // March 10, 2001, 5:16 pm
if ($date === 5){
//get interest rate
$sql = mysql_query("SELECT Rate FROM Interest WHERE Ref = 'Loan' ORDER BY Date DESC LIMIT 1");
$r = mysql_fetch_assoc($sql);
$rate = $r['Rate'];
//check for not settled loans
$check = mysql_query("SELECT LID FROM Registry WHERE Status = 0");
if (mysql_num_rows($check) > 0){
while ($list = mysql_fetch_assoc($check)) { // while there are rows to be fetched...
//*** Start Transaction ***//
mysql_query("BEGIN");
$loanID = $list['LID'];
//get loan data
$sql = mysql_query("SELECT Registry.Amount, SUM(Account.Total) AS Paid, SUM(Account.Interest) AS intPaid FROM Registry LEFT JOIN Account ON Registry.LID = Account.LID WHERE Registry.Status = 0 AND Account.Auto = 0 AND (Account.LID = '$loanID') GROUP BY Account.LID");
$r = mysql_fetch_assoc($sql);
$amount = $r['Amount']; //loan amount
$paid = $r['Paid']; //sum of paid
$intPaid = $r['intPaid']; //sum of interest paid
//get sum of monthly automatically updated interest
$sql = mysql_query("SELECT SUM(Interest) AS Interest FROM Account WHERE Payment = 0 AND Auto = 1 AND LID = '$loanID'");
$r = mysql_fetch_assoc($sql);
$autoInt = $r['Interest'];
$total = ($amount + $autoInt); //total to be paid
$balance = ($total - $paid); //with no interest
if ($paid >= $balance){
// echo "Loan completed <br/>";
}else{
$int = ($balance * $rate) / 100;
$update = mysql_query("INSERT INTO Account (LID, Date, Interest, Total, Auto) VALUES ('$loanID', NOW(), '$int', '$int', 1)") or die(mysql_error());
if (! $update){
//*** RollBack Transaction ***//
mysql_query("ROLLBACK");
// $_SESSION['error'] = "Interest saving failed.!";
echo "Loan ID: " . $loanID . ", Interest: Rs. " . $int . "/= - Update Failed.!<br>";
}else{
//*** Commit Transaction ***//
mysql_query("COMMIT");
// $_SESSION['error'] = "Interest saved successfully";
echo "Loan ID: " . $loanID . ", Interest: Rs. " . $int . "/= - Update Succeeded.!<br>";
}
}
}
}
}else{
echo "Monthly Interest can be update only by 05th day of the month.!";
}
I dont think at needs admin permissions
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/at.mspx?mfr=true
EDIT:
or even try MySQL Events
http://dev.mysql.com/doc/refman/5.1/en/events.html
It looks all database work which should be easily do able
If it is a publicly accesseable web server, you can use a cronjob service like https://www.cronjobservice.net/. After registration you enter an url and the time they shall call it. I advice using multiple of those services for the case one fails. (your script must execute on first call and exit on subsequent calls from other services.)
Please be sure to properly deal with .htaccess and make sure to have no security relevant output.
Have you asked the peoples that are hosting your site if they have a solution?
Most hosting companies have solutions for this (even on Windows servers)
If the hosting company has no solution for this (what I seriously doubt) you can call the script externally from another server that has cron possibilities or have it called by the first visitor on that day.
I any case you will want to include a check in your script that your script only runs on the set date (you already have that) and also make sure that calling the script more than once on that day is no problem.
PS : if the script is called by the first visitor you will have to consider the fact that you could not have any visitor that particular day, so the script will have to run whenever the next visitor comes along.
If you don't have administrative access to Windows, you won't be able to create a scheduled task. Your only alternative is to create some sort of custom task component in your application that checks / stores the last time a script was run. The problem with this is that it relies on user activity and it may not run on the exact date that you want it to.
The other alternative is to find Linux hosting so that you can avail of Cron.

Categories