MySQL table not updating through PHP cron job at specified time - php

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);

Related

How do I query an SQL database to before submitting second query in one process.php file?

I have a process booking script which takes information from a HTML booking form and sends it to a mySQL relational database.
It worked fine, however I have modified the code so that the first query checks to see whether the room they have selected is booked at any time during the date range they have specified. This can be seen in the first query $q
If it is already booked on any of the days the user submitted for that room, the script should echo an error, else it should fire the mysqli_multiquery and submit the data.
Both of these queries work directly in sql, however I am having trouble figuring out why the initial if statement does not work - 'if(mysqli_num_rows($result) == 0)'.
Here is the PHP file:
******** EDIT **********
When I submit a booking for a room that already prebooked for the requested date range, it is submitted instead of echoing the content in the else statement.
Here are the error messages:
Error messages displayed
******** EDIT TWO **********
Fixed! The problem was with a bad query.
<html>
<body>
<?php
$page_title = 'Process Booking Form';
require 'login-db.php'; // require once means that it well generate a fatal error if the file is not found and means that the file will only be read in when it has not previously been inclued which prevents wastefule duplicate disk accesses.
$dbc = new mysqli($hn, $un, $pw, $db);
if($dbc->connect_error) {
die ($dbc->connect_error);
}
if(isset($_POST['firstname']) &&
isset($_POST['lastname']) &&
isset($_POST['datefrom']) &&
isset($_POST['dateto']) &&
isset($_POST['specialevent']) &&
isset($_POST['roomnumber']))
{
$firstname = secure_post($dbc, 'firstname');
$lastname = secure_post($dbc, 'lastname'); //security
$datefrom = secure_post($dbc, 'datefrom');
$dateto = secure_post($dbc, 'dateto');
$specialevent = clean_string($dbc, 'specialevent');
$roomno = secure_post($dbc, 'roomnumber');
//validation
$error_message = "";
if(strlen($firstname) < 2 || strlen($firstname) > 20) {
$error_message .= 'Your first name does not appear to be valid.<br>';
}
if(strlen($lastname) < 2 || strlen($lastname) > 30) {
$error_message .= 'Your last name does not appear to be valid.<br>';
}
if(strlen($error_message) > 0) {
die($error_message);
}
//Query to find out if user selected dates are already booked for their chosen room
$q = "SELECT customerinfo.firstname, customerinfo.lastname, roominfo.roomnumber, roominfo.roomsize, roominfo.roomprice, bookings.datefrom, bookings.dateto, bookings.daterange
FROM customerinfo
LEFT JOIN bookings ON bookings.customer_id = customerinfo.customer_id
LEFT JOIN transactions ON customerinfo.customer_id = transactions.customer_id
LEFT JOIN transactionsdetails ON transactionsdetails.transactions_id = transactions.transactions_id
LEFT JOIN roominfo ON transactionsdetails.room_id = roominfo.room_id
WHERE roomnumber = $roomno
AND (bookings.datefrom BETWEEN $datefrom AND $dateto)
OR (roomnumber = $roomno
AND (bookings.dateto BETWEEN $datefrom AND $dateto))";
$result = mysqli_query($dbc, $q);
// $checkdates = mysqli_query($dbc, $checkdatessql);
if(mysqli_num_rows($result) == 0) {
//echo confirmation message to user
echo "Hello $firstname, your booking has been requested for room: $roomno. Your check-in date and time is $datefrom at 11:00am and your scheduled checkout date and time is $dateto at 15:00pm. Thank you for choosing to stay at Westworld.";
//submit customer information to the database
mysqli_multi_query($dbc,
"INSERT INTO customerinfo(firstname, lastname, specialevent) VALUES ('$firstname','$lastname','$specialevent');
SET #cusID := LAST_INSERT_ID();
INSERT INTO bookings(dateto, datefrom, daterange, customer_id) VALUES ('$dateto','$datefrom',DATEDIFF(dateto,datefrom), #cusID);
INSERT INTO transactions (customer_id, datebooked) VALUES (#cusID, CURDATE());
SET #roomID := (SELECT room_id FROM roominfo WHERE roomnumber = '$roomno');
INSERT INTO transactionsdetails (transactions_id, room_id) VALUES (LAST_INSERT_ID(), #roomID);");
} else {
//echo room error message
echo "The room you have selected is unavailable in that date range.";
}
$r->close();
$dbc->close();
};
function secure_post($dbc, $string) {
return htmlentities($dbc->real_escape_string($_POST[$string]));
}
function clean_string($dbc, $string) {
if (get_magic_quotes_gpc()) $string = stripslashes($string);
return htmlentities($dbc->real_escape_string($_POST[$string]));
}
?>
</body>
Well, add a "print_r(mysqli_num_rows($result));" and see what comes out. It may return a string, as mentioned in the documentation. I don't know what you use in your $datefrom and other variables, which you are using within your querys without any escaping (great idea) but when it is a valid date ('YYYY-MM-DD'), then you need to escape it.
Whatever it is, you should REALLY switch to PDO. there you can use prepared statements and let PDO map the variables for you (you still write the same SQL-command but instead of "$test" you write ":test" and then say ":test should be replaced by $test and it's a string"). MUCH safer and companies won't fire you on the spot ;)
Next time try to keep the code simple like one simple select-query, then the mysqli_num_rows, then one return and nothing else. Don't post more than you need to for people to understand your problem.

Telegram bot can't receive data from table with mysqli

I'm creating bot for Telegram.
And everything was OK, until I started to connect my bot with my database.
So, I've created table with fields "date","day","schedule".
And I want to make my bot to get a schedule by data from table.
But it can't. And I don't know why.
Here is a part of my code which belongs to DB connection.
<?php
//Connect to db with my params
$db = new mysqli('###', '###', '###', '###');
//Receive today's date
$date = date('Y-m-d');
/*
* Schedule - is what I'm looking for(some text in the table), knu - table's name
* date - table's field with date(format YYYY-MM-DD)
*/
$query = "SELECT schedule FROM knu WHERE `date` = '$date'";
$res = $db->query($query);
$row = $res->fetch_assoc();
//Send message to user
if($message == "a")
{
$date = date('Y-m-d');
$answer = $row;
sendMessage($chatId, $answer);
}
And this code doesn't work. I've tried a lot of times with different ways but still no answer with my bot.
What's wrong with my code and how to make it work?
$row isn't a string, it's an array. You probably want $answer['schedule'] or even just $row['schedule'] allowing you to remove the line $answer = $row;.

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.

Error in script sending automatic birthday wish to a registered user in php

I have written the script of sending automatic e-mail for a given date. I have already set up the cron job to execute this once a day for a given time. But it is not working. Can anyone show me the error here. I'm really new to this.
What I'm really supposed to do is to send an automatic email to a user on their birthday
<?php
$host="mysql117.000webhost.com/";//hostname
$username="abc";//mysql_username
$password="123";//mysql_password
$dbname="abc";//Database name
$tbl_name="customer_info";//table name
$date = date("2005-09-23"); //here my date format in my DB is 2010-09-30
$link = mysqli_connect('$host','$username','$password','$dbname');
if($link && mysqli_select_db('$dbname', $link))
{
$grabBday = "SELECT b_day,DATE_FORMAT(b_day,'2015-%m-%d') FROM customer_info where b_day = '2002-09-24'";
//here it will take the name of the person whose bday is on a particular date,I just hard coded this date to check if this is working
if($rs = mysqli_query($link, $grabBday))
{
while(mysqli_fetch_array($rs))
{
mail('abc92#yahoo.com', 'HAPPY BIRTHDAY', 'Many Happy Returns of the day');
}
}
} ?>
I am seeing logical difference as you are searching where b_day=$date where $date='2015-09-23' but dob can be '2002-09-23' or '1997-09-23' etc. so you will not get desired output, so you can change your query as per below if everything other than it is fine.
SELECT * FROM
tbl_name
WHERE CONCAT(YEAR(CURDATE()),DATE_FORMAT(b_day,'-%m-%d')) = $date

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