I'm trying to customize the booking experience. My products are tours spread over the year and scrolling through the calendar to find an available day isn't efficient. What I want is a drop down list that has the next available day for that tour. Is there any plugin or solution for my situation?
Hi The file is located in wp-content/plugins/woocommerce-bookings/templates/booking-form
The code in the post described works for the most part but there are some errors
Warning: reset() expects parameter 1 to be array, string given in /home/betaacademyofflo/public_html/wp-content/plugins/woocommerce-bookings/templates/booking-form/date-picker.php on line 54
Warning: Variable passed to each() is not an array or object in /home/betaacademyofflo/public_html/wp-content/plugins/woocommerce-bookings/templates/booking-form/date-picker.php on line 55
This error appears for every date available.
A tweak that I am trying to make is that currently the select list shows duplicates of each date I need it to just show the date once.
By each date once I mean just the start date my bookings have the same start and end date.
You can see an example here example list I have suppresed the errors for now.
heres the code so far pretty much the same as the OP version on wordress support.
<?php
$year = array();
$month = array();
$days = array();
$s;
$day1;
$i=0;
$j=0;
foreach ($availability_rules as $value) {
foreach ( $value as $value2) {
foreach ( $value2 as $value3) {
reset($value3);
while (list($key, $val) = each($value3)) {
$year[$i] = $key; //add year to array - $i is the count of how many course
reset($val);
while (list($key2, $val2) = each($val)) {
if($key2 < 10){
$month[$i] = '0'.$key2; //add the month value to another array - with leading 0
}else{
$month[$i] = $key2; //add the month value to another array
}
$s = "";
$j = 0;
reset($val2);
while (list($key3, $val3) = each($val2)) {
if($j==0||$j==1){
$s = $s . $key3 .',';
}else{
$s = $s . $key3;
}
if($j==0){
$day1[$i] = $key3; //add the day value to another array
}
$j++;
}
$days[$i] = $s;
}
$i++; //increments each time we loop through a year
}
}
}
}
$arrlength = 0;
$arrlength = count($year); //this is our total amount of courses
?>
<fieldset class="wc-bookings-date-picker <?php echo implode( ' ', $class ); ?>">
<legend><?php echo $label; ?>: </small></legend>
<select id="availableDates">
<option value="">Select Date</option>
<?php
if($arrlength==0){
echo "<option value=''>There are no dates</option>";
}else{
$todays_date = date("d-m-Y");
$today = strtotime($todays_date);
for($total_dates = $arrlength -1; $total_dates >= 0; $total_dates--){ //loop through total amount
$expiration_date =strtotime($day1[$total_dates].'-'.$month[$total_dates].'-'.$year[$total_dates]);
$actualdates = $day1[$total_dates]-$month[$total_dates]-$year[$total_dates];
$displaydates = $day1[$total_dates]/$month[$total_dates]/$year[$total_dates];
//$input = array( $day1[$total_dates]-$month[$total_dates]-$year[$total_dates]);
//$result = array_keys($input);
if ($expiration_date > $today) {
echo "<option value='$day1[$total_dates]-$month[$total_dates]-$year[$total_dates]'>$day1[$total_dates]/$month[$total_dates]/$year[$total_dates]</option>"; //pull in the index for each date array
}
}
}
?>
What I've tried;
Running an extra foreach on the final result did not work
tried array_unique did not work
Anny guidance here would be most aprreciated.
Related
i have time slots like
$timeslot = ['09:00-10:00', .... '23:00-00:00', '00:00-01:00'];
I have records with updated time as 23:15:00, 23:30:00, 00:15:00, 09:15:00 etc.
What i'm trying to find is the sum of records between each of the $timeslot. I'm not considering what day got updated, only time i'm looking for.
i tried with:-
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
foreach($data as $val) {
$cnt = 0;
foreach($timeslot as $slots) {
$slot = explode("-", $slots);
if( (strtotime($val) > strtotime($slot[0])) && (strtotime($val) <= strtotime($slot[1])) ) {
$up_time[$slot[0] . '-' . $slot[1]] = $cnt++;
}
}
}
echo '<pre>';print_r($up_time);echo '</pre>';
The expected output is:-
09:00-10:00 = 1
23:00-00:00 = 2
00:00-01:00 = 1
Strtotime is not required since your time can be compared as strings.
This code works as you expected.
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
$timeslot = ['09:00-10:00', '23:00-00:00', '00:00-01:00'];
$up_time = array();
foreach ($data as $val) {
$myTime = substr($val, 0, 5);
foreach ($timeslot as $slot) {
$times = explode("-", $slot);
if (substr($times[1], 0, 3) == "00:") {
$times[1] = "24:" . substr($times[1], 3);
}
if ($myTime >= $times[0] && $myTime <= $times[1]) {
if (!isset($up_time[$slot])) {
$up_time[$slot] = 1;
} else {
$up_time[$slot]++;
}
}
}
}
echo '<pre>';
print_r($up_time);
echo '</pre>';
The if with 'substr' is needed because for midnight you have '00' and not '24' so the computer thinks is an empty set (such as hours bigger then 23 and smaller then 0).
Comparison is made between string because bigger time is also a bigger string since you use 2 digits for hours.
You need to count equal slots so you need an array with an element for each slot and increment if duplicate or create an element if not found (the condition '!isset').
Update for modification request
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
// added unused slot 8:00-9:00
$timeslot = ['08:00-09:00','09:00-10:00', '23:00-00:00', '00:00-01:00'];
$up_time = array();
// new initialization
foreach ($timeslot as $slot) {
$up_time[$slot] = 0;
}
foreach ($data as $val) {
$myTime = substr($val, 0, 5);
foreach ($timeslot as $slot) {
$times = explode("-", $slot);
if (substr($times[1], 0, 3) == "00:") {
$times[1] = "24:" . substr($times[1], 3);
}
if ($myTime >= $times[0] && $myTime <= $times[1]) {
$up_time[$slot]++; // simplified
}
}
}
I'm working on a program to reserve seats for a show. I have a multidimensional array that is created using $row and $column variables. After making a few initial reservations, I need to pass integers into a function/some code to make further reservations.
I've tried looping through the array to find consecutive available seats (value "avail") but it ignores reserved seats or skips over them. I'll need to later use manhattan distance to reserve the best seats (from row 1, seat 6) first.
function to create the array:
//function to create seating chart data structure
function createChart($row, $column){
//create array for row values
$row_chart = array();
for($r=0; $r < $row; $r++){
$row_number = $r + 1;
$row_chart[$row_number] = array(); // array of cells for row $r
}
//create array for column values
$column_chart = array();
for($c=0; $c < $column; $c++){
$column_number = $c + 1;
//$location = $c_num;
$status = "avail";
foreach($row_chart as $key => $value){
$column_chart[$column_number] = $status; //add arrays of "seats" for each row
}
}
//nest the column array into the row array
foreach($row_chart as $key => $value){
foreach($column_chart as $k => $v){
$seating_chart[$key][$k] = $status;
}
}
//$seating_chart = array_combine($row_chart, $column_chart);
return $seating_chart;
}
function to make initial reservations:
$initial_reservation = "R1C4 R1C6 R2C3 R2C7 R3C9 R3C10";
$initial_reservation = explode(" ", $initial_reservation);
echo "<br> <br>";
print_r($initial_reservation);
$initial_res_length = count($initial_reservation);
echo "<br> <br>";
//echo $initial_res_length;
//split each seat up into integers to mark it reserved in the array
//issue for flexibility: find way to break up string by letters and numbers for larger charts
for($a = 0; $a < $initial_res_length; $a++){
$reso_row = substr($initial_reservation[$a], 1, 1);
//echo $reso_row . "<br>";
$reso_column = substr($initial_reservation[$a], 3, 2);
//echo $reso_column . "<br>";
$working_chart[$reso_row][$reso_column] = "reserved";
}
//echo "<br> <br>";
//echo "<pre>" . print_r($working_chart, 1) . "</pre>";
what I have so far in attempt to make further reservations:
//write some code to find consecutive seats
$seats_needed = 4;
$outer_array_length = count($working_chart);
//echo $outer_array_length;
for($d = 1; $d < $outer_array_length + 1; $d++){
for($e = 1; $e < $seats_needed + 1; $e++){
//issue: run through $seats_needed amount of times and executes the code block
//needed: check if $seats_needed amount of seats in available first then run reservation code
if($working_chart[$d][$e] === "avail"){
$working_chart[$d][$e] = "new reservation";
}
else{
echo "Sorry, not possible.";
}
}
break;
}
echo "<br> <br>";
echo "<pre>" . print_r($working_chart, 1) . "</pre>";
I'd like to be able to find a number of available seats ($seats_needed) first, and then loop through to reserve them.
I have initialized the $working_chart with :
$working_chart = createChart(10, 11);
I have written the attempt to make further reservations :
foreach(array_keys($working_chart) as $d ){
$maxColumn = count($working_chart[$d]) - $seats_needed + 1;
for($e = 1; $e <= $maxColumn ; $e++){
if(["avail"] === array_unique(array_slice($working_chart[$d], $e - 1 , $seats_needed))){
$working_chart[$d] = array_replace($working_chart[$d], array_fill($e, $seats_needed, "new reservation"));
break 2;
}
else{
echo "Sorry, not possible.";
}
}
}
I hope it can help you...
I am working on taxi app, after ride completes i have to draw map for which i use google map apis. let suppose my way-points are
array($coordinates1,$coordinates2,$coordinates3,$coordinates4,$coordinates5,$coordinates6,.........,$coordinates40)
the problem is that google map api accept only maximum of 23 way-points, for this purpose I have to skip many coordinates to pass, here my idea is to unset elements of array with equal intervals so that the route remain same. Please someone guide me how to remove many number of elements from an array with equal interval, just like i need 23 and total elements are 40 so that i need like
array($coordinates1,$coordinates4,$coordinates7,$coordinates9,$coordinates13,$coordinates16,.........,$coordinates39)
I have found a possible way, its a little bit lengthy but i got exact required result
$required_elements = 23;
$way = array();
for($ini=1;$ini<=78;$ini++)
{
$way[] = "Co-Ordinated:".$ini;
}
$total_elements = count($way);
list($way1, $way2) = array_chunk($way, ceil(count($way) / 2));
$differrence_element = $total_elements-$required_elements;
$skip_element = ceil($total_elements/$differrence_element);
$output = array();
if($total_elements > $required_elements)
{
$i=1;$j=0;
foreach($way as $x)
{
if($i == $skip_element)
{
$i=1;$j++;
continue;
}
else
{
$output[] = $way1[$j];
if(count($output) >= $required_elements) break;
$output[] = $way2[$j];
if(count($output) >= $required_elements) break;
$i++;$j++;
}
}
}
else
{
$output = $way;
}
$output1 = array();
$output2 = array();
$i=0;
foreach($output as $g)
{
if($i%2 == 0)
$output1[] = $g;
else
$output2[] = $g;
$i++;
}
$result = array_merge($output1,$output2);
print_r($way);
echo "<br><br><pre>";
print_r($result);
echo '</pre>';
Short question: I am trying to see if a variable ($y) is between multiple array values from a database ($ending[0] && $starting[0], $ending[1] && $starting[1], etc...). "If" $y is between any of those, echo "statement".
I'm using a for loop to increment a drop down in 30 minute intervals from 9am - 7pm.
If any of those times = a time saved within my database, it echoes "not available" instead.
Now I need to see "if" the dropdown time is "between" the start and end times in the database and make those "not available" as well.
Everything works if I manually identify which array keys to compare...but my question is: can I check the drop down value against all of the values in the arrays?
Example:
Start Dropdown: 09:00am 09:30am 10:00am etc up until 07:30pm. End Dropdown: 09:30am 10:00am 10:30am etc. up until 08:00pm. If there is a start and end time of 09:00am(start) 10:00am(end) saved in the database for an appointment, the dropdown will show "Not available" for the corresponding starting and end times, so a user cannot double book an appointment. What I am asking about, is how to identify all of the "in between" values...09:30am for example, cannot be a start or an end time, if the 09:00am-10:00am slot is already booked.
$sql_slots = "SELECT * FROM XXXXX WHERE date = '$query_date' ORDER BY XXXXX ASC";
$result_slots = mysqli_query($connection, $sql_slots);
$open = strtotime("9:00am");
$close = strtotime("9:30am");
$starting = array();
$ending = array();
while($row_result_slots = mysqli_fetch_assoc($result_slots)){
$starting[] = $row_result_slots['start_time'];
$ending[] = $row_result_slots['end_time'];
}
echo'
<select name="start_time">';
for($b = 0; $b <= 20; $b++){
$y = strtotime(($b*30) . " Minutes", $open);
$the_time = date("h:ia", $y);
// Here, instead of only comparing the first values in the array, I need to match it up against $ending[1] & $starting[1], $ending[2] & $starting[2], etc...
if(in_array($the_time, $starting) || ($y <= strtotime($ending[0]) && $y >= strtotime($starting[0]))){
echo "<option>Not Available<br></option>";
} else {
echo "<option>" . $the_time . "<br></option>";
}
}
echo'</select>';
How about that?
$sql_slots = "SELECT * FROM XXXXX WHERE date = '$query_date' ORDER BY XXXXX ASC";
$result_slots = mysqli_query($connection, $sql_slots);
$open = strtotime("9:00am");
$close = strtotime("9:30am");
$reserved = array();
while($row_result_slots = mysqli_fetch_assoc($result_slots)){
$start = $row_result_slots['start_time'];
while ($start <= $row_result_slots['end_time']) {
$reserved[$start] = true;
$start = date("Y/m/d h:i:s", strtotime($start . "+30 minutes"));
}
}
echo '<select name="start_time">';
for($b = 0; $b <= 20; $b++){
$y = strtotime(($b*30) . " Minutes", $open);
$the_time = date("h:ia", $y);
if(isset($reserved[$the_time]){
echo "<option>Not Available<br></option>";
} else {
echo "<option>" . $the_time . "<br></option>";
}
}
echo'</select>';
Below is what I came up with. This uses a do while loop and creates a reserved array that will fill all time between what is given in the appointment.
I updated the data to use my own array but updated your mysqli work with what should be correct. If not I left in my testing code for you to view if needed. I also used the disabled attribute on an option over outputting some text.
<?php
$sql_slots = "SELECT * FROM XXXXX WHERE date = '$query_date' ORDER BY XXXXX ASC";
$result_slots = mysqli_query($connection, $sql_slots);
$open = strtotime("9:00am");
$close = strtotime("7:00pm");
$space = 900; //15min * 60 seconds space between?
//This seems more normal for people to see.
//Simulate these appoinments
/*
$query_results = array(
array(
"start_time" => "9:00am",
"end_time" => "9:30am"
),
array(
"start_time" => "10:30am",
"end_time" => "11:30am"
),
array(
"start_time" => "11:45am",
"end_time" => "12:30pm"
)
);
*/
$reserved = array();
while($row_result_slots = mysqli_fetch_assoc($result_slots)){
//**NOTE**: Make sure these are times or use strtotime()
$next_slot = $reserved[] = strtotime($row_result_slots['start_time']);
$end_time = strtotime($row_result_slots['end_time']);
while($next_slot < $end_time){
$next_slot += $space;
$reserved[] = $next_slot;
}
}
/*
foreach($query_results as $appoinment) {
$next_slot = $reserved[] = strtotime($appoinment['start_time']);
$end_time = strtotime($appoinment['end_time']);
while($next_slot < $end_time){
$next_slot += $space;
$reserved[] = $next_slot;
}
}
*/
echo'<select name="start_time">';
$current = $open;
do {
$disabled = in_array($current, $reserved) ? 'disabled' : '';
echo '<option ' . $disabled . '>' . date("h:ia", $current) . '</option>';
$current += $space;
} while($current <= $close);
echo'</select>';
$array_of_time = array ();
$start_time = strtotime ("$app_date 07:00");
$end_time = strtotime ("$app_date 22:00");
$mins = 04 * 60;
while ($start_time <= $end_time)
{
$array_of_time[] = date ('h:i a', $start_time);
$start_time += $mins;
}
echo "<div style='width:700px' class='time_slot_div'>";
echo "<p class='time_slot_p'> Time Slot :</p>";
foreach($array_of_time as $key=>$value)
{
for($i = 0; $i < count($app_data); $i++)
{
$book_time=$app_data[$i]["appointment_time"];
if($value==$book_time)
{
echo "<a class='time_slot_a_book'>$value</a> ";
} else {
echo "<a href='#' onclick='get_time_value(\"$value\");' class='time_slot_a'>$value</a> ";
}
}
}
echo "</div>";
Here foreach loop can run as many time as it can as well as for loop also, but i want to show the links that are not matched with the foreach value and for loop value.
The foreach loop values like 7:20 am not from database but the for loop value like 7:20 am is from database so if 7:20 am==7:20 am then the if statement it run it is working fine, but the issue is that it is running 2 time if i get 2 value in for loop. It should run my div only once.
Use a array to store the item that has shown.
<?php
foreach($array_of_time as $key=>$value)
{
$tag_list = array();
for($i = 0; $i < count($app_data); $i++)
{
$book_time=$app_data[$i]["appointment_time"];
// shown, skip
if (isset($tag_list[$book_time]))
{
continue;
}
// mark as show
$tag_list[$book_time] = 1;
if ($value == $book_time)
{
echo "<a class='time_slot_a_book'>$value</a> ";
}
else
{
echo "<a href='#' onclick='get_time_value(\"$value\");' class='time_slot_a'>$value</a> ";
}
}
}