Trying to filter by WooCommerce Bookings Start Time

103 Views Asked by At

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.

1

There are 1 best solutions below

0
On

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:

$diver_titles_morning = []; // Initialize an empty array to store diver titles

foreach ($bookings_data as $booking) {
    $booking_start_time = strtotime(substr($booking[4], -5)); // Get the timestamp of the booking start time
    
    $morning_dive_start_time = strtotime('07:00');
    $morning_dive_end_time = strtotime('12:00');
    
    if ($booking_start_time >= $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;
                }
            }
        }
    }
}

$diver_titles_morning = array_unique($diver_titles_morning); // Remove duplicate titles, if any
print_r($diver_titles_morning); // Print the diver titles for the morning bookings