Check value between two times in my database php - php

I have a booking form where the users can book a certain facility, on a certain date and between two times. I have come to a point where my PHP code will prevent the user from booking the same pitch on the same date and from the same start or end time.
However the user can go between a time and book the same facility on the same date as another user. e.g. if one user has booked from 9 to 12 on the 1st May another user can come in and book the 10 or 11 slot.
Is there any way of preventing the user from booking a time between the time another user has already booked???
<?php
include "config.php";
//Booking point
if(isset($_POST['booking']))
{
//get values for variables
$pitchID = $_POST['pitchID'];
$start_date = $_POST['start_date'];
$start_hour = $_POST['start_hour'];
$end_hour = $_POST['end_hour'];
$booking_age = $_POST['booking_age'];
$pitch_size = $_POST['pitch_size'];
$light_tokens = $_POST['light_tokens'];
/* $q = $db->prepare("SELECT * FROM booking WHERE start_date = ?, start_hour = ?, end_hour=?, pitchID=?");
$query = $q->execute(array($start_date, $start_hour, $end_hour, $pitchID));
$count = $q->rowCount(); */
$q = $db->prepare("SELECT * FROM booking WHERE start_date = ? AND start_hour = ? AND pitchID = ?");
$query = $q->execute(array($start_date, $start_hour, $pitchID));
$count = $q->rowCount();
if($count == 0){
$query = $db->prepare("INSERT INTO booking SET pitchID = ?, start_date = ?, start_hour = ?, end_hour = ?, booking_age = ?, pitch_size = ?, light_tokens = ?, userID='$userID'");
$query = $query->execute(array($pitchID,$start_date,$start_hour,$end_hour,$booking_age,$pitch_size,$light_tokens));
if($query){
echo "Your booking has been made";
header("Location:home2_template.html");
return;
} else {
echo "Fail";
} //else fail
} else {
echo "This booking already exists";
} //else count
} //if booking
?>

If you only can reserve one day, try this
select * from booking
where (start_date='new_date'
and (
(start_hour <='new_start_hour' and end_hour>='new_start_hour')
or
(start_hour<= 'new_end_hour' and end_hour>='new_end_hour')
)
) and pitchID = ?

Related

Is it a good way to count unique visitors?

<?php
$date = date("Y-m-d"); //Return current date in yyyy-mm-dd format
$userIP = $_SERVER['REMOTE_ADDR'];// Stores remote user ip address
$query = "SELECT * FROM `unique_visitors` WHERE `date` = '$date'";
$result = mysqli_query($connection,$query);
if($result->num_rows == 0)// this block will execute when there is no record of current date in database
{
$insertQuery = "INSERT INTO `unique_visitors` (`date`,`ip`) VALUES ('$date','$userIP')";
mysqli_query($connection,$insertQuery);
}
else
{
$row = $result->fetch_assoc();//Extracts result row from result object
if(!preg_match('/'.$userIP.'/i',$row['ip']))//Will execute When Current ip is not in databse
{
$newIP = "$row[ip] $userIP"; //Combine previous and current user ip address with a separator for updating in database
$updateQuery = "UPDATE `unique_visitors` SET `ip`='$newIP', `views`=`views`+1 WHERE `date` = '$date' ";
mysqli_query($connection,$updateQuery);
}
}
?>
Is there a better way to count unique visitors in my website or this simple code is fine to insert into my website?
Here is the basic PHP/mysqli code for the approach you taken. You have to create an unique index for two fields, date and ip. And everything would work with just a single query.
<?php
$userIP = $_SERVER['REMOTE_ADDR'];// Stores remote user ip address
$sql = "INSERT INTO unique_visitors (date, ip, views) VALUES (curdate(),?,1)
ON DUPLICATE KEY UPDATE views = views + 1";
$stmt = $connection->prepare($sql);
$stmt->bind_param("s", $userIP);
$stmt->execute();
$sql = "SELECT count(*) FROM unique_visitors WHERE date = curdate()";
$result = $connection->query($sql);
$visitors = $result->fetch_row()[0];

Change the amount of data in SQL via PHP

Hello i have a table in sql called premium now when "user" with premium (in the table that there is 1 number is premium and 0 is not) then in the code before you i have an avant that every hour when clicked need to get something in return in this case this is a table called userMana Now i want premium name Will receive more (that is paid money) then is this way correct?
The first part I tried and after that I used the bottom part
if (isset($_GET['daily'])) {
if ($user->checkHours($user->hourEvent)) {
$time = date("Y-m-d H:i:s", time());
$mysqli->prepare("UPDATE `users` SET `hourEvent` = ?, `userMana` = `userMana` + 10, `userCitizens` = `userCitizens` + 1 WHERE userId = ?")->execute([$time, $user->userId]);
header("Location: /אזור-משחק/בסיס");
} else if ($user->premium > 0) {
if ($user->checkHours($user->hourEvent)) {
$time = date("Y-m-d H:i:s", time());
$mysqli->prepare("UPDATE `users` SET `hourEvent` = ?, `userMana` = `userMana` + 101, `userCitizens` = `userCitizens` + 1 WHERE userId = ?")->execute([$time, $user->userId]);
header("Location: /אזור-משחק/בסיס");
}
}
}
################################ Separator ###########################
if (isset($_GET['daily'])) {
if ($user->checkHours($user->hourEvent)) {
$time = date("Y-m-d H:i:s", time());
$mysqli->prepare("UPDATE `users` SET `hourEvent` = ?, `userMana` = `userMana` + 10, `userCitizens` = `userCitizens` + 1 WHERE userId = ?")->execute([$time, $user->userId]);
header("Location: /אזור-משחק/בסיס");
}
if ($user->premium > 0 && $user->checkHours($user->hourEvent)) {
$time = date("Y-m-d H:i:s", time());
$mysqli->prepare("UPDATE `users` SET `hourEvent` = ?, `userMana` = `userMana` + 11, `userCitizens` = `userCitizens` + 1 WHERE userId = ?")->execute([$time, $user->userId]);
header("Location: /אזור-משחק/בסיס");
}
}
The first one will not work properly.
The else if condition will only be tested when $user->checkHours($user->hourEvent) returns false. But the nested if block is only executed when this same expression returns true. Unless the result of this changes between these two tests, the second one can never succeed. So premium users will never get a bonus.
The second version will give two bonuses to premium users. They'll first get the same bonus of 10 that everyone gets, then they'll get an additional 11 bonus because they're premium users. I think it would be clearer to write it like this:
$normal_bonus = 10;
$premium_bonus = 21;
if (isset($_GET['daily']) && $user->checkHours($user->hourEvent)) {
$bonus = $user->premium ? $premium_bonus : $normal_bonus;
$mysqli->prepare("UPDATE `users` SET `hourEvent` = ?, `userMana` = `userMana` + ?, `userCitizens` = `userCitizens` + 1 WHERE userId = ?")->execute([$time, $bonus, $user->userId]);
header("Location: /אזור-משחק/בסיס");
}
This removes lots of duplicate code between the cases, and only executes one query to add to userMana.

Notification for user group

I'm working on a event manager and I would like to create a notification system for a group of users.
When an admin creates a new event then php create a notification inside mysql with status 0 if not read and then it changes to status 1 if read.
The problem is that I'm using the group id instead of the user id, and when the first logged user click on the notification it updates the notification status so other users are not viewing the notification. Maybe inserting a row for each user into the database can solve this problem? do I need to use an array of user's ids?
This is what i've done so far:
session_start();
// admin id
$userid = $_SESSION['user_id'];
include('../../../config/database.php');
$event_title = $_POST['titleevent'];
$event_color = $_POST['eventcolor'];
$event_start = $_POST['startevent'];
$new_start_date = date('Y-m-d 00:00:00', strtotime($event_start));
$event_end = $_POST['endevent'];
$new_end_date = date('Y-m-d 23:59:00', strtotime($event_end));
$event_group = $_POST['usergroup'];
$event_description = $_POST['eventdescription'];
if ($create_event = mysqli_prepare($conn, "INSERT INTO user_events (event_title, event_description, event_start, event_end, event_color, event_group)
VALUES (?, ?, ?, ?, ?, ?)" )) {
mysqli_stmt_bind_param($create_event, 'sssssi', $event_title, $event_description, $new_start_date, $new_end_date, $event_color, $event_group);
mysqli_stmt_execute($create_event);
// get event id
$event_id = mysqli_insert_id($conn);
$event_start_date = date('d-m-Y', strtotime($new_start_date));
$notification = "Nuovo evento <span class='text-warning'><strong>$event_title</strong></span> inizia il $event_start_date";
$notification_status = "0";
$notification_category= "events";
$event_notification = mysqli_prepare($conn, "INSERT INTO event_notifications (e_notification_sent_by, e_notification_sent_to, e_notification_message, e_notification_time, e_notification_status, e_notification_category, e_notification_category_id) VALUES(?,?,?,now(),?,?,?)");
mysqli_stmt_bind_param($event_notification, 'iisisi', $userid, $event_group, $notification, $notification_status, $notification_category, $event_id);
mysqli_stmt_execute($event_notification);
mysqli_stmt_close($event_notification);
echo "event created";
mysqli_stmt_close($create_event);
}else{
echo "Ops, error";
}
Many thanks for you help
UPDATE i've managed to make it working using an array and foreach in this way:
$event_start_date = date('d-m-Y', strtotime($new_start_date));
$notification = "Nuovo evento <span class='text-warning'><strong>$event_title</strong></span> inizia il $event_start_date";
$notification_status = "0";
$notification_category= "events";
$sql = "SELECT user_join_id FROM user_group_join WHERE group_join_id='$event_group'";
$result= mysqli_query($conn,$sql);
$datas= array();
if(mysqli_num_rows($result) > 0){
while($row=mysqli_fetch_array($result, MYSQLI_ASSOC)){
$datas[]= $row;
}
}
foreach($datas as $data) {
$id_cliente = $data['user_join_id'];
$event_notification = mysqli_prepare($conn, "INSERT INTO user_notifications (notification_sent_by, notification_sent_to, notification_message, notification_time, notification_status, notification_category, notification_category_id) VALUES(?,?,?,now(),?,?,?)");
mysqli_stmt_bind_param($event_notification, 'iisisi', $userid, $id_cliente, $notification, $notification_status, $notification_category, $event_id);
mysqli_stmt_execute($event_notification);
mysqli_stmt_close($event_notification);
}
Now the question is how can i can i convert it with a prepared statement? And also it looks like i'm going to use a lot of server resources querying the database for each user id, is there any way to optimize the foreach loop?
Many thanks

Preventing double booking and booking before today php pdo

I have a booking form set up where the user can book different facilities but I can't get my head around how to prevent the user from booking a date that is before today or how to prevent them from double booking.
I did try and work with a datepicker but I am using the HTML5 standard datepicker and also using Twitter Bootstrap but I don't know how to restrict dates from the user.
Below includes my full form and the PHP included in it.
<?php
include "config.php";
//Booking point
if(isset($_POST['booking']))
{
//get values for variables
$pitchID = $_POST['pitchID'];
$start_date = $_POST['start_date'];
$start_hour = $_POST['start_hour'];
$end_hour = $_POST['end_hour'];
$booking_age = $_POST['booking_age'];
$pitch_size = $_POST['pitch_size'];
$light_tokens = $_POST['light_tokens'];
$q = $db->prepare("INSERT INTO booking SET pitchID = ?, start_date = ?, start_hour = ?, end_hour = ?, booking_age = ?, pitch_size = ?, light_tokens = ?");
$query = $q->execute(array($pitchID,$start_date,$start_hour,$end_hour,$booking_age,$pitch_size,$light_tokens));
$count = $q->rowCount();
if($count == 0)
{
echo "Your booking has been made";
header("Location:home2_template.html");
return;
}else {
echo "That booking already exists";
}
}
?>
To check if a date is before a certain date you could convert your dates to timestamp and check if one is lower than the other
$start_date = $_POST['start_date'];
if( strtotime($start_date) < time()) {
// Date is before today
} else {
// Date is after today
}

MySQLi prepared statement & foreach loop [duplicate]

This question already has answers here:
Best way to INSERT many values in mysqli?
(4 answers)
Closed 1 year ago.
I'm struggling to revise the following (which works) to use a prepared statement:
echo "<div class=\"debug\">
<h4>values \$_POSTed from *LINE-ITEMS TABLE* in input.php:</h4>
<table>";
foreach ($_POST['date'] as $i => $value) {
$invNum = $_POST['invNum'];
$date = $_POST['date'][$i];
$hours = $_POST['hours'][$i];
$rate = $_POST['rate'][$i];
$dateTotal = $_POST['dateTotal'][$i];
echo "<tr>
<td>".$i."</td>
<td>".$date."</td>
<td>".$hours."</td>
<td>".$rate."</td>
<td>".$dateTotal."</td>
</tr>";
$query = "INSERT INTO Invoice_Line_Items SET
INVOICE_NUMBER = '$invNum',
DATE = '$date',
HOURS = '$hours',
RATE = '$rate',
DATE_TOTAL = '$dateTotal'
ON DUPLICATE KEY UPDATE
INVOICE_NUMBER = VALUES(INVOICE_NUMBER),
DATE = VALUES(DATE),
HOURS = VALUES(HOURS),
RATE = VALUES(RATE),
DATE_TOTAL = VALUES(DATE_TOTAL)
";
} // END foreach
echo "</table></div>";
I've been trying to adapt the (working) prepared statement/query running above this in the same page, which inserts a single row into a different table. But this 2nd query (into a different db table) inserts data from multiple (dynamic # of) rows from a line-items table within the source form.
I've been hacking at it for hours but I can't quite sort out how to implement a prepared statement with the line-items loop. I thought it would be along these lines, but this is not inserting.
echo "<div class=\"debug\">
<h4>values \$_POSTed from *LINE-ITEMS TABLE* in input.php:</h4>
<table>";
// this is the line-items table in the form; don't I have to get these values before the query?
foreach ($_POST['date'] as $i => $value) {
$invNum = $_POST['invNum'];
$date = $_POST['date'][$i];
$hours = $_POST['hours'][$i];
$rate = $_POST['rate'][$i];
$dateTotal = $_POST['dateTotal'][$i];
// confirm vars/values
echo "<tr><td>".$i."</td><td>".$date."</td><td>".$hours."</td><td>".$rate."</td><td>".$dateTotal."</td></tr>";
$stmt = $mysqli->stmt_init();
$query = "INSERT INTO Invoice_Line_Items
INVOICE_NUMBER = '$invNum',
DATE = '$date',
HOURS = '$hours',
RATE = '$rate',
DATE_TOTAL = '$dateTotal'
ON DUPLICATE KEY UPDATE
INVOICE_NUMBER = VALUES(INVOICE_NUMBER),
DATE = VALUES(DATE),
HOURS = VALUES(HOURS),
RATE = VALUES(RATE),
DATE_TOTAL = VALUES(DATE_TOTAL)
";
if ($stmt->prepare($query)) {
$stmt -> bind_param("ssddd", $invNum, $date, $hours, $rate, $dateTotal);
$stmt -> execute();
$stmt->close();
} // if $stmt
} // END foreach
echo "</table></div>";
Can someone please shed some light? Much appreciated.
svs
You don't need
$stmt = $mysqli->stmt_init();
You should be able to just call
$stmt = $mysqli->prepare($query);
Another problem is you're setting the query up inside your loop. You shouldn't do that. Move $stmt outside the loop and only run execute inside once you've set your variables up. Finally, you need to add ? so MySQL knows the parameters
$query = "INSERT INTO Invoice_Line_Items
INVOICE_NUMBER = ?,
DATE = ?,
HOURS = ?,
RATE = ?,
DATE_TOTAL = ?
ON DUPLICATE KEY UPDATE
INVOICE_NUMBER = VALUES(INVOICE_NUMBER),
DATE = VALUES(DATE),
HOURS = VALUES(HOURS),
RATE = VALUES(RATE),
DATE_TOTAL = VALUES(DATE_TOTAL)
";
$invNum = $date = $hours = $rate = $dateTotal = '';
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ssddd", $invNum, $date, $hours, $rate, $dateTotal);
foreach ($_POST['date'] as $i => $value) {
$invNum = $_POST['invNum'];
$date = $_POST['date'][$i];
$hours = $_POST['hours'][$i];
$rate = $_POST['rate'][$i];
$dateTotal = $_POST['dateTotal'][$i];
$stmt->execute();
}

Categories