仅当WooCommerce可预订产品存在预订时添加缓冲期
解决WooCommerce Bookings缓冲期仅在有预订时生效的问题
问题场景
- 使用WooCommerce Bookings时,后台设置的缓冲期会强制全局生效,哪怕当日该产品无任何预订,导致可选时段被无端限制
- 产品设置为可选整点开始的6小时时段,设2小时缓冲期后,原本7/8/9点等时段变成仅7/9/11点可选,不符合需求
- 期望效果:仅当产品当日已有预订时,才在该预订结束后添加缓冲期;无预订时,缓冲期完全不生效(比如已有8-12点的预订,后续预订最早只能从14点开始)
当前代码的问题
你的代码能正常获取产品ID和预订数据,但wc_bookings_get_time_slots过滤器未生效,核心原因:
- 该过滤器的作用对象是可用时段数组,不是预订实例,用
set_buffer_period完全不对 - 过滤器添加时机过早,
woocommerce_before_single_product钩子触发时,时段计算逻辑还没启动,后续过滤器会失效 - 没有针对当日预订判断,而是获取了所有历史预订,逻辑不准确
正确实现代码
add_filter('wc_bookings_get_available_time_slots', 'custom_conditional_buffer_time_slots', 10, 6); function custom_conditional_buffer_time_slots($slots, $product, $duration, $existing_bookings, $date, $resource_id) { // 设置缓冲时长(分钟),这里为2小时=120分钟 $buffer_after = 120; $buffer_after_sec = $buffer_after * 60; // 当日无预订时,直接返回所有可用时段 if (empty($existing_bookings)) { return $slots; } // 整理当日所有预订的「结束时间+缓冲期」的时间戳 $blocked_until_times = []; foreach ($existing_bookings as $booking) { $end_timestamp = strtotime($booking->get_end()); $blocked_until_times[] = $end_timestamp + $buffer_after_sec; } // 过滤掉缓冲期内的无效时段 $valid_slots = []; foreach ($slots as $slot) { $slot_start = strtotime($slot['start']); $is_valid = true; // 检查当前时段是否在所有缓冲期之后 foreach ($blocked_until_times as $blocked_time) { if ($slot_start < $blocked_time) { $is_valid = false; break; } } if ($is_valid) { $valid_slots[] = $slot; } } return $valid_slots; }
代码说明
- 用
wc_bookings_get_available_time_slots过滤器,这是WooCommerce Bookings官方用来过滤可用时段的正确钩子 - 直接使用钩子自带的
$existing_bookings参数,它就是当日该产品的所有预订集合,无需自己查询 - 仅在有当日预订时,才计算缓冲期并过滤时段;无预订时直接返回原有时段,完全不限制
- 逐个检查每个可选时段的起始时间,确保它在所有「预订结束+缓冲期」之后
内容的提问来源于stack exchange,提问作者clev
相关产品推荐
相关产品推荐

