I am trying to get a list of all persons booked (I have created a CPT (custom post type) and I am attaching that to the booking and to the order, to keep a clear record for the client and get the names of the persons booked on a certain date, but in between specific times. I was able to get the date easily, but I am having a lot of trouble filtering the results by time. The solution uses WooCommerce Bookings, custom code and ACF.
This is the code where I define the array of bookings for the date:
function get_bookings_for_selected_date($selected_date, $product_or_resource_id = 0, $check_in_cart = true, $status = '') {
$args = array(
'status' => get_wc_booking_statuses(),
'object_type' => 'product_or_resource',
);
if (!$check_in_cart) {
$args['status'] = array_diff($args['status'], array('in-cart'));
}
if ($status) {
$args['status'] = array($status);
}
if ($product_or_resource_id) {
if (get_post_type($product_or_resource_id) === 'bookable_resource') {
$args['resource_id'] = absint($product_or_resource_id);
} else {
$args['product_id'] = absint($product_or_resource_id);
}
}
$dts = apply_filters('woocommerce_bookings_in_date_range_query', WC_Booking_Data_Store::get_booking_ids_by($args));
$data = array();
$header = array();
$header[] = array("Booking_ID", "Order_ID", "Persons", "Creation_Date", "booking_date", "First_Name", "Last_Name", "Email", "Phone", "Diver IDs", "Cost", "Status");
$selected_date_timestamp = strtotime($selected_date);
foreach ($dts as $dt) {
$booking = new WC_Booking($dt);
$order = new WC_Order($booking->order_id);
// Compare the selected date with the booking start date
if (date('Y-m-d', $booking->start) !== $selected_date) {
continue; // Skip to the next iteration if dates don't match
}
// Get associated Diver IDs from the order
$diver_ids = get_post_meta($booking->order_id, 'associated_diver_ids', true);
$booking_date = date('Y-m-d H:i T', $booking->start); // Format start date with time
$row = array(
"" . $booking->id,
"" . $booking->order_id,
"" . $booking->person_counts[158],
"" . date('m/d/Y', $booking->date_created),
"" . $booking_date,
"" . $order->get_billing_first_name(),
"" . $order->get_billing_last_name(),
"" . $order->get_billing_email(),
"" . $order->get_billing_phone(),
"" . $diver_ids, // Use the diver IDs from the order
"" . $booking->cost,
"" . $booking->status,
);
$data[] = $row;
}
// Merge with header, which can be used later for CSV export
$data = array_merge($header, $data);
return $data;
}
Then I call them into the page here:
function update_manifest_content_field($content) {
// Get the selected date from the ACF field "manifest_date"
$selected_date = get_field('manifest_date', get_the_ID());
$morning_dive_start = get_field('morning_dive_start', get_the_ID());
$morning_dive_end = get_field('morning_dive_end', get_the_ID());
// Check if a date is selected
if ($selected_date) {
// Product IDs to query
$product_ids = array(2121, 2448, 2438, 2291);
// Get bookings data using the custom function for the specific date and status
$bookings_data = get_bookings_for_selected_date($selected_date, $product_ids, true, 'paid');
// Get bookings data using the custom function for the specific date and status
$bookings_data = get_bookings_for_selected_date($selected_date, $product_ids, true, 'paid');
// Define the array to hold diver titles for the morning dive
$diver_titles_morning = [];
// Assuming you have $morning_dive_start and $morning_dive_end already defined
foreach ($bookings_data as $booking) {
$booking_start_time1 = date('H:i T', strtotime($booking['booking_date']));
echo "BOOKING TIME Option 1: $booking_start_time <br><br>";
$booking_start_time2 = date_i18n('H:i T', $booking->start);
echo "BOOKING TIME Option 2: $booking_start_time2 <br><br>";
//Define Start and End Time
$morning_dive_start_time = strtotime('07:00');
$morning_dive_end_time = strtotime('12:00');
// Test start and end timestamp
echo "START" . $morning_dive_start_time . "<br><br>";
echo "END" . $morning_dive_end_time . "<br><br>";
// Check if the booking start time falls within the specified range
if ($booking_start_time2 >= $morning_dive_start_time && $booking_start_time <= $morning_dive_end_time) {
$associated_diver_ids = get_post_meta($booking[1], 'associated_diver_ids', true);
if (is_array($associated_diver_ids)) {
foreach ($associated_diver_ids as $diver_id) {
$diver_title = get_the_title($diver_id);
if ($diver_title) {
$diver_titles_morning[] = $diver_title;
}
}
}
}
}
// Remove duplicate titles, if any
$diver_titles_morning = array_unique($diver_titles_morning);
print_r($diver_titles_morning);
print_r($bookings_data);
My problem is the if statement for filtering the time.
The array for $bookings_data returns this:
[0] => Array ( [0] => Booking_ID [1] => Order_ID [2] => Persons [3] => Creation_Date [4] => booking_date [5] => First_Name [6] => Last_Name [7] => Email [8] => Phone [9] => Diver IDs [10] => Cost [11] => Status )
[0] => 3820 [1] => 3821 [2] => [3] => 11/20/2023 [4] => 2023-11-22 13:00 UTC [5] => Wade [6] => Taylor1 [7] => [email protected] [8] => [9] => Array [10] => 0 [11] => paid
So I know that [4] brings in the correct data. I just can't seem to filter it correctly. When I call the time:
$booking_start_time1 = date('H:i T', strtotime($booking['booking_date']));
echo "BOOKING TIME Option 1: $booking_start_time <br><br>";
$booking_start_time2 = date_i18n('H:i T', $booking->start);
echo "BOOKING TIME Option 2: $booking_start_time2 <br><br>";
I get this: BOOKING TIME Option 1: (empty) - It doesn't like the call to get $booking['booking_date'] which always returns empty. BOOKING TIME Option 2: 14:17 +11 (this is the current time for my clock on my computer instead of the $booking->start value)
Basically I need to know: Is there another way that I could filter by time, or am I trying to filter in the wrong way? Time seems to be so complicated in php.
I was able to get an answer from another PHP coder Lombervid on Discord that really helped. Seeing as I hate it when questions are asked and not answered online I thought I'd share the fix.
I knew the there was
$booking[4]
, but didn't think to use it.But this worked: