如何在WooCommerce Bookings中排除ID946产品参与未支付状态Google日历同步
WooCommerce Bookings 日历同步规则适配问题
业务场景
- 部分支持到场付费的单次课程产品,需要将未支付状态的预订同步到Google日历
- 多人参与类产品(ID:946)要求所有参与者完成支付后才允许同步到日历,需将该产品排除在「未支付状态即同步」的规则外
原有基础功能代码
用户最初实现全产品未支付状态同步的代码:
add_filter('woocommerce_booking_is_paid_statuses', 'woocommerce_booking_add_unpaid_to_is_paid_statuses'); function woocommerce_booking_add_unpaid_to_is_paid_statuses( $statuses ) { $statuses[]= 'unpaid'; return $statuses; }
此前自行修改的实现及报错
用户尝试增加产品判断逻辑后,运行出现致命错误:
修改的代码:
function woocommerce_bookings_kalendar( $statuses, $order ) { // 获取订单商品条目 $items = $order->get_items(); // 遍历所有商品 foreach ( $items as $item ) { $product_id = $item['product_id']; if ( $product_id == 946 ) { $statuses[]= 'unpaid'; return $statuses; } } } add_filter('woocommerce_booking_is_paid_statuses', 'woocommerce_bookings_kalendar');
报错信息:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function woocommerce_bookings_kalendar()
问题根因
- 参数传递配置错误:WordPress的add_filter钩子默认仅给回调函数传递1个参数,用户的回调函数需要接收2个参数(状态列表、关联对象),但未在add_filter调用时声明允许的参数数量,导致系统无法把第二个参数传入函数,触发参数数量不足的致命错误
- 业务逻辑反向:用户的判断逻辑搞反了:原本要求排除946号产品的未支付同步,代码却写为匹配到946号产品时才添加未支付同步规则;且当订单中不存在946号产品时,函数没有返回值,会直接破坏原有状态列表的结构
- 对象获取方式不合理:原代码尝试从订单条目遍历取产品ID,但该钩子的回调入参是预订对象而非订单对象,本身就存在对象类型不匹配的问题
正确实现方案
基于钩子原生入参做判断,调整逻辑并修正参数配置,实现效果:
add_filter('woocommerce_booking_is_paid_statuses', 'exclude_unpaid_sync_for_booking_product_946', 10, 2); function exclude_unpaid_sync_for_booking_product_946( $statuses, $booking ) { // 从钩子传入的预订对象中获取关联产品ID $associated_product_id = $booking->get_product_id(); // 仅对非946的产品,添加未支付状态到可同步列表 if ( $associated_product_id !== 946 ) { $statuses[] = 'unpaid'; } // 无论是否添加状态,都返回完整的状态列表,避免破坏原有逻辑 return $statuses; }
实现说明
- 给add_filter指定了第4个参数
2,代表允许回调函数接收2个入参,解决参数不足的报错 - 直接使用钩子传入的预订对象取产品ID,避免了从订单、预订二次查询的兼容问题
- 逻辑完全匹配业务需求:946号产品不会把未支付状态加入可同步列表,其余产品保留原有的未支付同步能力
内容的提问来源于stack exchange,提问作者Lubo Masura
相关产品推荐
相关产品推荐

