1

With WooCommerce and WooCommerce Bookings plugins enabled, I am trying to add a text line above the product time picker section to advise the customer that they need to select one of the options.

I have found a function in the WooCommerce Bookings plugin located inside the "includes" folder on wc-bookings-functions.php php file, that I've copied into my theme's functions.php file, renaming it by prepending "de_" to the beginning of the function name and then added an add_filter.

When I do this, the function (original plugin or mine) doesn't work at all and either the original picker nor my version shows and nothing is returned.

The original function:

function wc_bookings_get_time_slots_html( $bookable_product, $blocks, $intervals = array(), $resource_id = 0, $from = 0, $to = 0 ) {
    $available_blocks = wc_bookings_get_time_slots( $bookable_product, $blocks, $intervals, $resource_id, $from, $to );
    $block_html       = '';

    // If customer defined, we show two dropdowns start/end time.
    if ( 'customer' === $bookable_product->get_duration_type() ) {
        $block_html .= wc_bookings_get_start_time_html( $bookable_product, $blocks, $intervals, $resource_id, $from, $to );
        $block_html .= wc_bookings_get_end_time_html( $bookable_product, $blocks, '', $intervals, $resource_id, $from, $to );
    } else {

        $block_html .= '<div class="please-select">Hi please select your session</div>';

        foreach ( $available_blocks as $block => $quantity ) {
            if ( $quantity['available'] > 0 ) {
                if ( $quantity['booked'] ) {
                    /* translators: 1: quantity available */
                    $block_html .= '<li class="block" data-block="' . esc_attr( date( 'Hi', $block ) ) . '"><a href="#" data-value="' . get_time_as_iso8601( $block ) . '">' . date_i18n( get_option( 'time_format' ), $block ) . ' <small class="booking-spaces-left">(' . sprintf( _n( '%d left', '%d left', $quantity['available'], 'woocommerce-bookings' ), absint( $quantity['available'] ) ) . ')</small></a></li>';
                } else {
                    $block_html .= '<li class="block" data-block="' . esc_attr( date( 'Hi', $block ) ) . '"><a href="#" data-value="' . get_time_as_iso8601( $block ) . '">' . date_i18n( get_option( 'time_format' ), $block ) . '</a></li>';
                }
            }
        }
    }

    return apply_filters( 'wc_bookings_get_time_slots_html', $block_html, $available_blocks, $blocks );
}

The function I have added to my functions.php file. With new function I have added de_:

function de_wc_bookings_get_time_slots_html( $bookable_product, $blocks, $intervals = array(), $resource_id = 0, $from = 0, $to = 0 ) {
    $available_blocks = wc_bookings_get_time_slots( $bookable_product, $blocks, $intervals, $resource_id, $from, $to );
    $block_html       = '';

    // If customer defined, we show two dropdowns start/end time.
    if ( 'customer' === $bookable_product->get_duration_type() ) {
        $block_html .= wc_bookings_get_start_time_html( $bookable_product, $blocks, $intervals, $resource_id, $from, $to );
        $block_html .= wc_bookings_get_end_time_html( $bookable_product, $blocks, '', $intervals, $resource_id, $from, $to );
    } else {

        $block_html .= '<div class="please-select">Hi please select your session</div>';

        foreach ( $available_blocks as $block => $quantity ) {
            if ( $quantity['available'] > 0 ) {
                if ( $quantity['booked'] ) {
                    /* translators: 1: quantity available */
                    $block_html .= '<li class="block" data-block="' . esc_attr( date( 'Hi', $block ) ) . '"><a href="#" data-value="' . get_time_as_iso8601( $block ) . '">' . date_i18n( get_option( 'time_format' ), $block ) . ' <small class="booking-spaces-left">(' . sprintf( _n( '%d left', '%d left', $quantity['available'], 'woocommerce-bookings' ), absint( $quantity['available'] ) ) . ')</small></a></li>';
                } else {
                    $block_html .= '<li class="block" data-block="' . esc_attr( date( 'Hi', $block ) ) . '"><a href="#" data-value="' . get_time_as_iso8601( $block ) . '">' . date_i18n( get_option( 'time_format' ), $block ) . '</a></li>';
                }
            }
        }
    }

    return apply_filters( 'wc_bookings_get_time_slots_html', $block_html, $available_blocks, $blocks );
}

And then the add_filter (de_ beginning of function)

add_filter('wc_bookings_get_time_slots_html','de_wc_bookings_get_time_slots_html', 10);

I was expecting the line:

$block_html .= '<div class="please-select">Hi please select your session</div>';

to be displayed above the available dates.

But nothing happens. When I click on a day, no dates or my text appears. If I remove my function and filter the original time slot picker appears as expected.

I've read the docs on using filters and thought I was doing this correctly.

I also tried changing the return apply_filters with a prepended "de_" in the name but it didn't make any change.

  • 2
    Unless the original function is wrapped in a function_exists check, and loads after yours, which is unlikely, you can't just copy it and change its internals. Also ** in a function name isn't valid. Have you checked your PHP error log? – Tom J Nowell Apr 2 at 17:08
  • I think the ** was the OP trying to make that part of the name bold, to show he isn't naming his function exactly the same – tmdesigned Apr 2 at 17:22
  • 1
    You probably want to remove the old filter viaremove_filter() (although note the caveat for that.) – Loren Rosen Apr 2 at 20:43
  • Can't immediately see your desired change, but I wonder if it might be more straightforward to just use the jQuery insertBefore function? – Loren Rosen Apr 2 at 20:49
  • ... actually, you need jQuery first too. – Loren Rosen Apr 2 at 21:05
0

First, in the original wc_bookings_get_time_slots_html() function, the following line:

$block_html .= '<div class="please-select">Hi please select your session</div>';

doesn't exist, so that is confusing for people trying to get what is the difference between the original function, and the one you copied (renamed and customized) in your active theme's function php file.

Now copying a plugin function to your theme (rename it and make customizations in it) will not do anything.

Instead use the available hook wc_bookings_get_time_slots_html, that will allow you to make your customization simply this way:

add_filter( 'wc_bookings_get_time_slots_html', 'filter_bookings_get_time_slots_html_callback', 10, 6 );
function filter_bookings_get_time_slots_html_callback( $bookable_product, $blocks, $intervals, $resource_id, $from, $to ) {
    if ( 'customer' !== $bookable_product->get_duration_type() ) {
        $block_html = '<div class="please-select">Hi please select your session</div>' . $block_html;
    }

    return $block_html;
}

Code goes in function.php file of your active child theme (or active theme). tested and works.

  • Hi, sorry for leaving this so long before replying. Everything went a bit crazy recently and I couldn't get the time to come back to this. Thank you for your answer. Strangely enough, I had a random phone call from a guy that runs a fishing hire company down in Torquay who had exactly the same issue on his website with the same plugin and he very kindly emailed the code he was using. – Digital Essence Apr 23 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.