• Resolved white020

    (@white020)


    Hi. I’ve been trying to optimize my own search engine system for several weeks now. The previous one was poor, so I built my own. Question to the author – Are there any ready-made functions in this plugin that I can use instead of this heavy code? It’s a pity that things are added that are not useful and the search engine remains unchanged… The main question is whether there is any other way to check the availability of an item?

    function wpbc_search_avy__show_search_results( $shortcode_attr  = array())
    {
    $defaults = array( 'is_silent' => false );
    $shortcode_attr = wp_parse_args( $shortcode_attr, $defaults );

    $found_resources = wpbc_search_avy__do_search();
    $is_include_field_type = true;
    $form_for_cost = wpbc_search_avy__get_form_fields__from__search_request( $is_include_field_type ); //'selectbox-one^visitors[resource_id]^' . '1'
    $is_include_field_type = false;
    $form_for_auto_fill = wpbc_search_avy__get_form_fields__from__search_request( $is_include_field_type ); //'visitors[resource_id]^' . '1'

    $resources_sorted_details_arr = wpbc_search_avy__search_results__get_sort_details_arr( $found_resources, $form_for_cost );
    $search_time_arr = wpbc_search_avy__get_search_time__from__search_request();

    if (!$shortcode_attr['is_silent']) {
    echo '<div class="booking_search_ajax_container wpbc_container wpbc_container_search wpbc_container_search_results">';
    }

    $search_type = isset($_GET['search_field__ctype']) ? $_GET['search_field__ctype'] : NULL;
    $search_text = isset($_GET['search_field__cr']) ? $_GET['search_field__cr'] : NULL;

    $check_in = $_POST['search_get__check_in_ymd'] ?? $_GET['search_get__check_in_ymd'] ?? null;
    $check_out = $_POST['search_get__check_out_ymd'] ?? $_GET['search_get__check_out_ymd'] ?? null;
    $has_dates = !empty($check_in) && !empty($check_out) && $check_in !== '2100-01-01' && $check_out !== '2100-01-01';

    $allVehicles = ofc_get_all_vehicles( $resources_sorted_details_arr['resource_obj__arr'] );

    $vehicles_list = [];
    foreach ($allVehicles as $post_id => $veh) {
    if (!empty($search_type)) {
    if (
    !is_array($veh['categories']) ||
    !isset($veh['categories'][$search_type]) ||
    $veh['categories'][$search_type] !== 'true'
    ) {
    continue;
    }
    }

    if (!empty($search_text)) {
    if (stripos($veh['title'], $search_text) === false) {
    continue;
    }
    }

    $bookingCost = wpbc_get_costs_i_hints__based_on_cost_calc( array(
    'form' => str_replace( '[resource_id]', $veh['resource']->booking_type_id, $form_for_cost ),
    'days_input_format' => wpbc_get_comma_seprated_dates_from_to_day(
    date_i18n( "d.m.Y", strtotime( $check_in ) ),
    date_i18n( "d.m.Y", strtotime( $check_out ) )
    ),
    'resource_id' => $veh['resource']->booking_type_id,
    'booking_form_type' => apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $veh['resource']->booking_type_id )
    ) );

    $vehicles_list[$post_id] = $veh;
    $vehicles_list[$post_id]['booking_cost'] = $bookingCost['total_cost'];
    }

    $sort_order = 'down';

    if (isset($_POST['search_field__sprice'])) {
    $sort_order = $_POST['search_field__sprice'];
    } elseif (isset($_GET['search_field__sprice'])) {
    $sort_order = $_GET['search_field__sprice'];
    }

    if ($sort_order === 'up') {
    usort($vehicles_list, fn($a, $b) => $a['booking_cost'] <=> $b['booking_cost']);
    } else {
    usort($vehicles_list, fn($a, $b) => $b['booking_cost'] <=> $a['booking_cost']);
    }

    $total_items = count($vehicles_list);
    $posts_per_page = 21;
    $max_num_pages = ceil($total_items / $posts_per_page);
    $paged = false;

    /* START AVAILABLY */
    $search_start = 10 * 3600;
    $search_end = 22 * 3600;
    $step_seconds = 3600;

    $available_param = isset($_GET['available']) ? $_GET['available'] : NULL;
    $show_only_available = ($available_param == '1');
    /* STOP AVAILABLY */

    if ($has_dates || $available_param) {
    $vehicles_page = $vehicles_list;

    if ( $has_dates ) {
    $dates = wpbc_get_dates_array_from_start_end_days($check_in, $check_out);
    }
    } else {
    if (isset($_POST['pos'])) {
    $paged = max(1, intval($_POST['pos']));
    } elseif (isset($_GET['pos'])) {
    $paged = max(1, intval($_GET['pos']));
    } else {
    $paged = 1;
    }
    $vehicles_page = array_slice($vehicles_list, ($paged - 1) * $posts_per_page, $posts_per_page, true);

    $dates = [ date('Y-m-d') ];
    }

    if (!$has_dates && !$available_param) {
    echo showPagination($paged, $max_num_pages);
    }

    if (!$shortcode_attr['is_silent']) {
    echo '<div class="ofc_grid">';
    }

    foreach ($vehicles_page as $i => &$veh)
    {
    $resource_id = $veh['resource']->booking_type_id;

    /* START AVAILABLY */
    $veh['available'] = false;
    $veh['availability_html'] = '';

    if ($has_dates) {
    $veh['available'] = true;
    $veh['availability_html'] = '<i class="fa-regular fa-check"></i> Available in selected range';

    foreach ($dates as $d) {
    $free_from = wpbc_fast_find_free_hour($resource_id, $d, $search_start, $search_end);

    if ($free_from === false) {
    $veh['available'] = false;
    $veh['availability_html'] =
    '<i class="fa-notdog fa-solid fa-xmark"></i> Unavailable on ' . date('d.m.Y', strtotime($d));
    break;
    }
    }

    if ($veh['available'] === true) {
    $free_from = wpbc_fast_find_free_hour($resource_id, $first_day, $search_start, $search_end);

    if ($free_from !== false) {
    $veh['availability_html'] = '<i class="fa-regular fa-check"></i> Available from ' . gmdate('H:i', $free_from);
    }
    }
    } else {
    $max_days = 60;
    $unavailable_until = null;
    $available_from_day = null;

    for ($i_day = 0; $i_day < $max_days; $i_day++) {
    $check_date = date('Y-m-d', strtotime("+$i_day days"));
    $free_from = wpbc_fast_find_free_hour($resource_id, $check_date, $search_start, $search_end);

    if ($free_from === false) {
    $unavailable_until = $check_date;
    continue;
    }

    $available_from_day = $check_date;
    break;
    }

    if ($unavailable_until && !$available_from_day) {
    $veh['available'] = false;
    $veh['availability_html'] =
    '<i class="fa-notdog fa-solid fa-xmark"></i> Unavailable until ' . date('d.m.Y', strtotime($unavailable_until));
    } elseif ($unavailable_until) {
    $veh['available'] = false;
    $veh['availability_html'] =
    '<i class="fa-notdog fa-solid fa-xmark"></i> Unavailable until ' . date('d.m.Y', strtotime($available_from_day));
    } else {
    $veh['available'] = true;
    $veh['availability_html'] = '<i class="fa-regular fa-check"></i> Available from ' . gmdate('H:i', $free_from);
    }
    }

    if ($show_only_available && !$veh['available']) {
    continue;
    }
    /* STOP AVAILABLY */

    $price_for_month = !empty($veh['price_for_month']) ? '<div class="ofc_priceMonth"><div>Cost (for month):</div><div>'. $veh['price_for_month'] .' EUR</div></div>' : '';

    echo '
    <a href="'. $veh['url'] .'" class="ofc_item">
    <div class="ofc_image"><img src="'. $veh['image_url'] .'" alt="' . $veh['title'] . '" loading="lazy" /></div>
    <div class="ofc_main_content">
    <div class="ofc_title">'. $veh['title'] .' <span class="ofc_year">('. $veh['year'] .'r)</span></div>
    <div class="ofc_content">
    <div class="ofc_att"><span class="ofc_att_icon"><i class="fa-sharp fa-solid fa-chart-fft"></i></span> <span class="ofc_att_value">'. $veh['power'] .' KM</span></div>
    <div class="ofc_att"><span class="ofc_att_icon"><i class="fa-regular fa-gas-pump"></i></span> <span class="ofc_att_value">'. $veh['fuel_type'] .'</span></div>
    <div class="ofc_att"><span class="ofc_att_icon"><i class="fa-regular fa-engine"></i></span> <span class="ofc_att_value">'. $veh['engine_capacity'] .'L</span></div>
    </div>
    <div class="ofc_hr"></div>
    <div class="ofc_prices">
    '. $price_for_month .'
    <div class="ofc_priceDay"><div>Cost ('. ($has_dates ? 'per dates' : 'per day') .'):</div><div>'. $veh['booking_cost'] .' EUR</div></div>
    <div class="ofc_status '. ($vehicles_page[$i]['available'] ? 'ofc_yes' : 'ofc_no') .'">'. $vehicles_page[$i]['availability_html'] .'</div>
    </div>
    </div>
    </a>
    ';
    }

    if (!$shortcode_attr['is_silent']) {
    echo '</div>';
    }

    // Pagination
    if (!$has_dates && !$available_param) {
    echo showPagination($paged, $max_num_pages);
    }

    if (!$shortcode_attr['is_silent']) {
    echo '</div>';
    }
    }

    Second question: Is there anything I can do about the link added after clicking the search button in the URL? It’s too long

    &search_field__cr=&search_field__ctype=&search_field__sprice=up&search_field__display_check_in=&search_field__display_check_out=&search_time=&search_get__check_in_ymd=2100-01-01

    • This topic was modified 6 days, 8 hours ago by white020.
Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Support Dmytro

    (@dimasereda)

    Hello.

    1) Booking Calendar already has a search availability engine, so you do not need to manually scan all bookings/resources in the search results template. For checking availability of resources for selected dates/times, use the existing search functions, especially wpbc_search_avy__do_search() or wpbc_search_avy__search_available_in(). For a single resource/date-time check, wpbc_api_is_dates_booked() can also be used, but it returns true when unavailable.

    2) The long URL appears because your search form submits to a separate results page using GET parameters. This is needed to pass and restore search criteria. If you want to avoid changing the URL, use the Ajax search mode instead of the separate search-results page mode.

    Please note, this search availability functionality available in the Pro versions. This forum is only about the support of the Booking Calendar Free version. If you will have any questions about the paid version, then contact here https://wpbookingcalendar.com/contact/ or via Booking Calendar support email address.

    If you need some additional functionality, you can suggest it for us for future developments, so we can add it to the roadmap.

    Kind Regards.

    Thread Starter white020

    (@white020)

    Thank you for your reply. How can I determine the time a resource is available based on its ID? It’s currently performing a lot of calculations that are burdening the server.

    Plugin Support Dmytro

    (@dimasereda)

    Hello.

    You do not need to manually calculate availability for every resource/hour. Booking Calendar already calculates availability per resource/date/time.

    If you only need to check whether a resource is available for a specific time range, use wpbc_search_avy__search_available_in( array( $resource_id ), array( $date ), 1, array( $start_seconds, $end_seconds ) ).

    If you need to display the available time intervals, call wpbc_get_availability_per_days_arr() once for the resource/date, then read $availability['dates'][$date][$resource_id]->booked_time_slots['merged_seconds'] or use wpbc_get__booking_obj__merged_seconds_arr(). This gives the merged busy intervals, so you can calculate free intervals from your working hours without repeatedly querying/checking each hour.

    Please note that there is no single public function like “get first available hour by resource ID”; the recommended approach is to use the existing availability array and derive the free intervals from it.

    Once again this support forum is only about the support of the Booking Calendar Free version. Please check what support we are providing here https://wpbookingcalendar.com/faq/what-support-do-you-provide/

    Kind Regards.

Viewing 3 replies - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.