Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save thisissandip/b5aa32e34c45d4f6803c38731a9dfe5c to your computer and use it in GitHub Desktop.

Select an option

Save thisissandip/b5aa32e34c45d4f6803c38731a9dfe5c to your computer and use it in GitHub Desktop.
Show fully booked WooCommerce Bookings time slots on the product page as disabled “FULL” slots for fixed duration product
/**
* Show fully booked WooCommerce Bookings time slots
*
* By default, WooCommerce Bookings hides time slots once they are fully booked.
* This snippet keeps those slots visible on the product booking calendar and labels
* them as "FULL", while leaving them disabled so customers cannot select or
* book them.
*
* Notes:
* - Applies to fixed duration booking slots on the classic booking form.
* - Does not apply to customer-defined duration bookings with start/end dropdowns.
* - The FULL slots intentionally do not include a data-value attribute, so the
* Bookings JavaScript cannot select them for checkout.
*/
add_filter( 'wc_bookings_get_time_slots_html', 'custom_bookings_show_full_time_slots', 10, 4 );
function custom_bookings_show_full_time_slots( $html, $available_blocks, $blocks, $product ) {
if (
! is_a( $product, 'WC_Product_Booking' ) ||
'customer' === $product->get_duration_type() ||
! in_array( $product->get_duration_unit(), array( 'hour', 'minute' ), true )
) {
return $html;
}
if ( empty( $blocks ) || ! is_array( $blocks ) ) {
return $html;
}
ksort( $blocks );
$html = '';
foreach ( $blocks as $block => $booked_slots ) {
if ( ! is_numeric( $block ) ) {
continue;
}
$block = absint( $block );
$quantity = isset( $available_blocks[ $block ] ) && is_array( $available_blocks[ $block ] ) ? $available_blocks[ $block ] :
array();
$available = isset( $quantity['available'] ) ? max( 0, absint( $quantity['available'] ) ) : 0;
$booked = isset( $quantity['booked'] ) ? absint( $quantity['booked'] ) : absint( $booked_slots );
$time_label = esc_html( date_i18n( wc_bookings_time_format(), $block ) );
$block_attr = esc_attr( date( 'Hi', $block ) );
if ( $available > 0 ) {
$value = esc_attr( get_time_as_iso8601( $block ) );
if ( $booked > 0 ) {
$remaining = sprintf(
_n( '%d left', '%d left', $available, 'woocommerce-bookings' ),
$available
);
$html .= sprintf(
'<li class="block" data-block="%1$s" data-remaining="%2$d"><a href="#" data-value="%3$s" data-remaining="%4$s">%5$s <small
class="booking-spaces-left">(%6$s)</small></a></li>',
$block_attr,
$available,
$value,
esc_attr( $remaining ),
$time_label,
esc_html( $remaining )
);
} else {
$html .= sprintf(
'<li class="block" data-block="%1$s"><a href="#" data-value="%2$s">%3$s</a></li>',
$block_attr,
$value,
$time_label
);
}
continue;
}
$html .= sprintf(
'<li class="block fully_booked" data-block="%1$s"><a href="#" class="wc-bookings-slot-full" aria-disabled="true"
tabindex="-1">%2$s <small class="booking-spaces-left">(%3$s)</small></a></li>',
$block_attr,
$time_label,
esc_html__( 'FULL', 'woocommerce-bookings' )
);
}
return $html;
}
add_action( 'wp_enqueue_scripts', 'custom_bookings_full_time_slot_styles', 20 );
function custom_bookings_full_time_slot_styles() {
wp_add_inline_style(
'wc-bookings-styles',
'.wc-bookings-booking-form .block-picker li.fully_booked a.wc-bookings-slot-full {
opacity: .7;
text-decoration: none !important;
cursor: not-allowed;
pointer-events: none;
}
.wc-bookings-booking-form .block-picker li.fully_booked a.wc-bookings-slot-full .booking-spaces-left {
font-weight: 700;
}'
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment