Time/date difference with client and server? - php

I'm sorry if this has been asked before or if I'm not able to explain in a great way. I've spent hours trying to wrap my head around the issue and I just can't seem to fix this issue. The code is working fine locally, but when I upload it to my server there seems to be some sort of issue with how the server handles/checks differences in time between server and client. Not sure exactly how or what to think. I'm also aware that I'm inserting data into pdo statements incorrectly, I don't care about that at the moment. I will tidy all this up at a later point.
The part of the application that I'm experiencing issues with is when it checks an active shipment (it's a sort of game). I want to compare the timestamp from the database with the current time to see if the time has passed. In the case that the arrival time is past, then I want to set the status of the shipment to 'delivered' as well as add the data to another table called 'storage'.
function check_active_shipment(){
$pdo = pdo();
$username = $_SESSION['username'];
$statement = $pdo->prepare("SELECT * FROM shipments WHERE username LIKE '$username' AND status LIKE 'active' LIMIT 1");
$statement->execute();
$rows = $statement->fetch();
$id = $rows['id'];
if($rows['type'] == "purchase"){
if(time() >= strtotime($rows['arrival'])){
$statement = $pdo->prepare("UPDATE shipments SET status='delivered' WHERE id LIKE '$id'");
$statement->execute();
$statement = $pdo->prepare("INSERT INTO storage (username, crate_type_id, quantity) VALUES (?, ?, ?)");
$statement->bindParam(1, $username);
$statement->bindParam(2, $rows['crate_type_id']);
$statement->bindParam(3, $rows['quantity']);
$statement->execute();
//header("location:index.php");
}
}
else if($rows['type'] == "sale"){
if(time() >= strtotime($rows['arrival'])){
$statement = $pdo->prepare("UPDATE shipments SET status='delivered' WHERE id LIKE ?");
$statement->bindParam(1, $id);
$statement->execute();
$statement = $pdo->prepare("SELECT cash FROM users WHERE username LIKE ?");
$statement->bindParam(1, $username);
$statement->execute();
$user = $statement->fetch();
$cash = $user['cash'] + $rows['value'];
$statement = $pdo->prepare("UPDATE users SET cash=?");
$statement->bindParam(1, $cash);
$statement->execute();
//header("location:index.php");
}
}
}
Let me know if there is any information I'm missing to share.

Would getting the time from the server, rather than using the time() function solve you problem.
Either do a separate query
SELECT NOW()
or add it to your existing query
SELECT *, NOW() as curtime FROM shipments WHERE .....

Have you tried using the DateTime Class? Perhaps it behaves much like you had expected... Here's a snippet on how to use it in your case:
<?php
// ...SOME CODE...
if($rows['type'] == "purchase"){
// TRY USING DateTime CLASS
$arrival = new DateTime($rows['arrival']);
$arrivalTS = $arrival->getTimestamp();
if(time() >= $arrivalTS){
// REST OF THE CODE...
}
}else if($rows['type'] == "sale") {
// TRY USING DateTime CLASS AGAIN
$arrival = new DateTime($rows['arrival']);
$arrivalTS = $arrival->getTimestamp();
if (time() >= $arrivalTS) {
// REST OF THE CODE...
}
}

Related

How to generate a sequential number that restarts yearly in a web application

I need to generate a code which consists of some arbitrary prefix, a year, and an incrementing number. The incrementing number must start at 1 at the first time when the number is generated that year.
This code needs to be added to the sqlite database and be available elsewhere in the PHP script.
What i have done now uses 4 accesses to the database:
$codePrefix = 'TEST';
$stmt = $db->prepare(
'INSERT INTO test (year)
VALUES(strftime("%Y", "now"))'
);
$stmt->execute();
$id = $db->lastInsertId();
$stmt = $db->prepare('SELECT `year` FROM `test` WHERE `id`=:id');
$stmt->bindValue(':id', $id);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$year = $result['year'];
$stmt = $db->prepare('SELECT Ifnull(Max(id), 0) `max_id` FROM `test`
WHERE `year`<:year');
$stmt->bindValue(':year', $year);
$result = $stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$previousMax = $result['max_id'];
$codeSuffix = $id-$previousMax;
$code = "{$codePrefix}-{$year}-{$codeSuffix}";
$stmt = $db->prepare('UPDATE `test` SET `code`=:code WHERE `id`=:id');
$stmt->bindParam(':code', $code);
$stmt->bindParam(':id', $id);
$stmt->execute();
Here i am abusing the fact that the id is an integer primary key, and autoincrements.
This works. But i feel that it is doing something very easy in a very complicated manner.
Is there a better solution? I need to assume that the midnight of the first of January can happen at any moment of the code, so i cannot do things like get the year information from PHP without hitting the database.
Before somebody asks, the reason i am using prepared statements even when no values are bound is because late on obviously more data will be inserted into the table.
Consider a pure SQL solution using the ROW_NUMBER window function. Below assigns to new field, new_id:
UPDATE test
SET new_id = 'TEST_' || test.[Year] || '_' || sub.rn
FROM (
SELECT id,
[Year],
ROW_NUMBER() OVER (PARTITION BY [Year] ORDER BY id) AS rn
FROM test
) AS sub
WHERE test.id = sub.id;

Stop User From Liking Post Multiple Times

I have a like button, which allows users to like posts on my site. If the user likes a post they have not liked before it will +1, if they press the same like button again it will -1. This is working on my virtual server on my laptop. However, the same code is not working on my live site. On my live site the user is able to like the same post multiple times, which is not what I want. I'm using a JQuery Ajax call to a PHP file that fires a some MySQL code.
Can anyone see anything obviously wrong with the PHP below?
include ("../con/config.php");
$postid = $_POST['postid'];
$userid = $_POST['userid'];
$query = $con->prepare("SELECT COUNT(*) AS CntPost FROM Likes WHERE UserID = ? AND PostID = ?");
$query->bind_param('ss',$userid,$postid);
$query->execute();
$result = $query->get_result();
$fetchdata = $result->fetch_assoc();
$count = $fetchdata['CntPost'];
if($count == 0){
$stmt = $con->prepare("INSERT INTO Likes(UserID,PostID) VALUES(?,?)");
$stmt->bind_param("ss", $userid, $postid);
$stmt->execute();
} else {
$stmt = $con->prepare("DELETE FROM Likes WHERE UserID = ? AND PostID = ?");
$stmt->bind_param("ss", $userid, $postid);
$stmt->execute();
}
// count numbers of likes in post
$query = $con->prepare("SELECT COUNT(*) AS CntLike FROM Likes WHERE PostID = ?");
$query->bind_param('s', $postid);
$query->execute();
$result = $query->get_result();
$fetchlikes = $result->fetch_assoc();
$totalLikes = $fetchlikes['CntLike'];
$return_arr = array("likes"=>$totalLikes,"type"=>$count);
echo json_encode($return_arr);
Managed to solve it. The issue was in the MySQL database column itself for the UserID. The number of chars for the column was not long enough and was truncating the UserID, which I populate using the sessionID. I amended this field in the database to allow for the length of a sessionID.
perhaps this statement
"SELECT COUNT(*) AS CntLike FROM Likes WHERE PostID = ?" need UserID in WHERE statement so you would know that specific UserID in that specific PostID

Slim Php Mysql Put method empty value,want to update 4 column,but only 1 column is updated but result indicate success

My goal is to update 4 column in my table in a single query.But end up only 1 column is updated,the other 3 is not.
My query is like this
$stmt = $this->conn->prepare("UPDATE users_info SET profile_image_path = ?,user_bio = ? ,gender = ?,date_of_birth = ? WHERE user_id = ?");
$stmt->bind_param("sssii",$profile_image_upload_url,$user_bio,$gender,$date_of_birth,$user_id);
$result = $stmt->execute();
$stmt->close();
return $result;
Here is my code for the query call
//update to database
global $user_id;
$db = new DBhandler();
$update_result = $db->callForQueryFunction($user_id,$user_bio,$date_of_birth,$gender,$profile_image_string);
$response = array();
if($update_result){
$response['error'] = false;
$response['message'] ="sucess";
}else{
$response['error'] = true;
$response['message'] ="fail";
}
After I run in advanced rest client ,with the the following query
user_bio=hihi&gender=f&profile_image_string=somestringhere&date_of_birth=2015-08-16
After run the query,the result is always "success",but in Mysql table only profile_image_path column is updated,the rest 3 column user_bio,date_of_birth and gender all are not updated.
Here is my database structure
I work for hours still haven't figure it out what's wrong with the code or my database structure.
Update:
I tried with bind_param for s with $date_of_birth,but still no luck with it
$stmt->bind_param("ssssi",$profile_image_upload_url,$user_bio,$gender,$date_of_birth,$user_id);
UPDATE
I actually using this example from Androidhive,the sample code is as below
/**
* Updating existing task
* method PUT
* params task, status
* url - /tasks/:id
*/
$app->put('/tasks/:id', 'authenticate', function($task_id) use($app) {
// check for required params
verifyRequiredParams(array('task', 'status'));
global $user_id;
$task = $app->request->put('task');
$status = $app->request->put('status');
But I use the same method as below to grab the value,but after var_dump() all the value is NULL.Here is my code
$app->put('/updateuserdetails','authenticate',function ()use ($app){
$user_bio = $app->request()->put('userbio');
$gender =$app->request()->put('gender');
$date_of_birth = $app->request()->put('dob');
$profile_image_string = $app->request()->put('profilestring');
I try this as well.The value of user_bio,gender,date_of_birth are all still null.
$app->post('/updateuserdetails','authenticate',function ()use ($app){
$user_bio = $app->request()->post('userbio');
$gender =$app->request()->post('gender');
$date_of_birth = $app->request()->post('dob');
$profile_image_string = $app->request()->post('profilestring');
I just cant figure out what is going wrong here
Update
After I test it in Postman by send data with x-www-form-urlencoded it come out with this error,which I cant get any solution
Try the following:
$stmt = $this->conn->prepare("UPDATE users_info SET profile_image_path = :image, user_bio = :bio, gender = :gender, date_of_birth = :dob WHERE user_id = :id");
$stmt->bindParam(":image", $profile_image_upload_url, PDO::PARAM_STR);
$stmt->bindParam(":bio", $user_bio, PDO::PARAM_STR);
$stmt->bindParam(":gender", $gender, PDO::PARAM_STR);
$stmt->bindParam(":dob", $date_of_birth, PDO::PARAM_STR);
$stmt->bindParam(":id", $user_id, PDO::PARAM_INT);
$result = $stmt->execute();
$stmt->close();
return $result;

HTML form insert not working in PHP and MySQL

This follows on from a previous question (html/php/sql form with insert/update) so use that for reference on the HTML form. When a client moves in, their client's active is changed to 1, the room's room_vacant is changed to 0, and an occupancy record is made.
As well as this, the first rental payment needs to be generated using all this information. The rent_occupancy_id is worked out through the user of lastInsertId(), as the last inserted id would've been the occupancy ID.
The rent_cost is generated whether the client moving in is on benefits on not. If a client is not on benefits, then the rent_cost = £126.57 but if they are then rent_cost = £20.03. The date_lastpaid is the same as the start_date of the client's occupancy record and the date_due is equal to a week ahead of the date_lastpaid.
The problem is that a rent record is not being created yet all the other changes for the other records etc. are being made. Any help would be much appreciated.
<?php
require("dbconnect.php");
//CLIENT
$id = $_POST['id'];
//UPDATES client's to 1/Yes to say that they're now an active client in JRH,
//where the selected client's ID is equal to :id
$stmt = $dbh->prepare("UPDATE client SET active = 1 WHERE client_id=:id");
$stmt->bindParam(':id', $id);
$stmt->execute();
//ROOM
$room_id = $_POST['room_id'];
$stmt = $dbh->prepare("UPDATE room SET room_vacant = 0 WHERE room_id = :room_id");
$stmt->bindParam(':room_id', $room_id);
$stmt->execute();
//OCCUPANCY
$id = $_POST['id'];
$room_id = $_POST['room_id'];
$start_date = $_POST['start_date'];
$stmt = $dbh->prepare("INSERT INTO occupancy (occupancy_client_id, occupancy_room_id, start_date) VALUES(:id, :room_id, :start_date)");
$stmt->bindParam(':id', $id);
$stmt->bindParam(':room_id', $room_id);
$stmt->bindParam(':start_date', $start_date);
$stmt->execute();
//Working out Rent Cost
$id = $_POST['id'];
$stmt=$dbh->prepare("SELECT * FROM client WHERE client_id=:id");
$stmt->bindParam(':id', $id);
$stmt->execute();
$row = $stmt->fetch();
//Works out whether a client has benefits or not,
//and then uses this information to generate a cost of the rent
if ($row['benefits'] == '0') {
$rent_cost = "126.57";
} else{
$rent_cost = "20.03";
}
//RENT INSERT
//
//As the occupancy record is being created above
//and the rent table needs a rent_occupancy_id to join,
//then we use lastInsertId() in order to get that occupancy id
$rent_occupancy_id = $dbh->lastInsertId();
$date_lastpaid = $_POST['start_date']; //As the client hasn't made a payment yet,
//we say that their last payment was the date they joined
$date_due = strtotime($date_lastpaid);
$date_due = strtotime('+1 week', $date_due);
$date_due = date('Y/m/d', $date_due);
$stmt = $dbh->prepare("INSERT INTO rent (rent_occupancy_id, rent_cost, date_lastpaid, date_due) VALUES (:rent_occupancy_id, :rent_cost, :date_lastpaid, :date_due)");
$stmt->BindParam(':rent_occupancy_id', $rent_occupancy_id);
$stmt->BindParam(':rent_cost', $rent_cost);
$stmt->BindParam(':date_lastpaid', $date_lastpaid);
$stmt->BindParam(':date_due', $date_due);
$stmt->execute();
?>
just change to lowercase first letter in bindParam();
$stmt->bindParam(':rent_occupancy_id', $rent_occupancy_id);
$stmt->bindParam(':rent_cost', $rent_cost);
$stmt->bindParam(':date_lastpaid', $date_lastpaid);
$stmt->bindParam(':date_due', $date_due);
$stmt->execute();

IF and ELSE statement not working

I am trying to award a user a badge if their points are 10,000. There is a field in the table called badge1 with a default value set to locked and a points row. I am running and if statement that if the users points are 10,000 then UPDATE the badge1 row from locked to unlocked. My code seems correct but It is neither updating the the field nor showing any errors.
<?php
$db = new PDO('mysql:host=hostname;dbname=databasename;charset=UTF-8', 'username', 'password');
$username = $_SESSION['username'];
$q = "SELECT Points FROM login_users WHERE username ='$username'");
$r = mysql_query($q);
$row = mysql_fetch_assoc($r);
$Points = $row['Points'];
if($Points == "10000") {
$awardBadge = $db->exec("UPDATE login_users SET badge1=unlocked WHERE username=?");
$Points->execute(array($username))
} else {
print "";
}
?>
UPDATE:
I managed to get it working.. however the problem is I am a bit new to converting old sql to PDO so this is not very secure but this is what works:
<?php
$connect = mysql_connect("host","username","password");
mysql_select_db("databasename");
$username = $_SESSION['jigowatt']['username'];
$q = "SELECT Points FROM login_users WHERE username = ('$username')";
$r = mysql_query($q);
$row = mysql_fetch_assoc($r);
$Points = $row['Points'];
?>
// Place somewhere
<?php
if($Points >= "10000") {
$result = mysql_query("UPDATE login_users SET maneki='unlocked' WHERE username='$username'");
} else {
print "Badge has not been unlocked";
}
?>
"10000" string should be an 10000 int
And also, you might want to make a choice here too. You're using 2 types of setting up a mysql-database connection. the old-fashioned mysql_function() way and the new fancy PDO method.
I think working with the PDO version is safer, since newer PHP versions will not support the old methods anymore... That... and it just looks dirty ;P
Try this:
<?php
session_start();
$dbSession = new PDO('mysql:host=***;dbname=***', '***', '***');
$selectQuery = $dbSession->prepare('
SELECT `User`.`Points`
FROM `login_users` AS `User`
WHERE `User`.`username` = :username
');
$selectQuery->bindParam(':username', $_SESSION['username'], PDO::PARAM_STR);
$user = $selectQuery->fetch(PDO::FETCH_ASSOC);
if ( !empty($user) && $user['Points'] == 10000 ) {
$updateQuery = $dbSession->prepare('
UPDATE `login_users`
SET `badge1` = \'unlocked\'
WHERE `username` = :username');
$updateQuery->bindParam(':username', $_SESSION['username'], PDO::PARAM_STR);
$updateQuery->execute();
}
?>
Usefull resources:
PHP Database Objects (PDO)
PHP Sessions
MySQL Datamanipulation
MySQL SELECT syntax
MySQL UPDATE syntax
Better check if >= 10000 and not yet awarded. That could you also be done in SQL so you don't need that logic in PHP.
UPDATE login_users SET badge1=unlocked WHERE points >= 10000 and badget1 <> unlocked
The issue is caused by $point value which actually is not equal to 10000, but is NULL.
So I propose to always use var_dump() to get the actual value of the variable in such cases.
one tip: check the PDO docs, before you write php code! You use PDO and mysql commands on same time for same job!?? why???
Try this if($Points == 10000) instead of if($Points == "10000")
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.
if($Points==10000){
$awardBadge = $db->prepare("UPDATE login_users SET badge1=unlocked WHERE username=?");
$awardBadge->execute(array($username));
}

Categories