You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce购物车捆绑商品删除撤销、数量同步开发问题

捆绑商品删除后撤销同步恢复方案

手动往removed_cart_contents加数据不生效的核心原因有两个:

  • 原有代码直接调用WC()->cart->remove_cart_item()删除关联商品时,会重复触发woocommerce_cart_item_removed钩子造成递归执行,WooCommerce的会话保存逻辑会在钩子执行完成后重新覆写removed_cart_contents数据,手动追加的内容会被直接冲掉。
  • 递归执行会打断WooCommerce原生的已删除商品持久化流程,关联商品的恢复数据不会被写入购物车会话,点击撤销时自然只能恢复最先删除的单个商品。

正确实现代码如下,增加递归防护,同时保证关联商品的恢复数据被正确写入:

add_action( 'woocommerce_cart_item_removed', 'cart_remove_bundle_items', 10, 2 );
function cart_remove_bundle_items($removed_cart_item_key, $cart) {
    static $is_removing = false;
    // 递归触发时直接跳出,避免死循环
    if ($is_removing) return;

    $line_item = $cart->removed_cart_contents[ $removed_cart_item_key ];
    if (empty($line_item['bundle_id'])) return;
    $bundle_id = $line_item['bundle_id'];

    $is_removing = true;
    foreach( $cart->get_cart() as $key => $item ){
        if( $key !== $removed_cart_item_key && $item['bundle_id'] == $bundle_id ){
            // 提前把关联商品写入已删除列表,保证恢复数据留存
            $cart->removed_cart_contents[$key] = $item;
            // 执行删除操作,此时不会触发递归逻辑
            $cart->remove_cart_item($key);
        }
    }
    $is_removing = false;
}

代码生效后不需要额外编写恢复逻辑,WooCommerce原生撤销功能会自动识别removed_cart_contents内的同组关联商品,点击撤销时两个商品会同时恢复到购物车。


同bundle_id商品数量同步更新方案

使用woocommerce_update_cart_action_cart_updated钩子出现白屏、购物车清空的原因是:该钩子触发时WooCommerce尚未完成购物车数据合法性校验,在这个节点修改商品数量会打断原生校验流程,触发WooCommerce的异常商品清理逻辑,将所有商品判定为无效清空;如果没有做递归防护,还会出现死循环导致PHP内存溢出白屏。

正确实现需使用woocommerce_after_cart_item_quantity_update钩子,该钩子在单个商品数量更新完成、校验通过后触发,不会打断原生流程,搭配递归防护即可实现需求:

add_action( 'woocommerce_after_cart_item_quantity_update', 'sync_bundle_items_quantity', 10, 4 );
function sync_bundle_items_quantity($cart_item_key, $quantity, $old_quantity, $cart) {
    static $is_updating = false;
    if ($is_updating) return;

    $item = $cart->get_cart()[$cart_item_key] ?? null;
    if (empty($item['bundle_id'])) return;
    $bundle_id = $item['bundle_id'];
    // 强制数量最小为1,避免0值导致商品被删除
    $target_quantity = max(1, intval($quantity));

    $is_updating = true;
    foreach ($cart->get_cart() as $key => $cart_item) {
        if ($key !== $cart_item_key && $cart_item['bundle_id'] == $bundle_id) {
            // 第三个参数传false,不触发额外的更新钩子避免递归
            $cart->set_quantity($key, $target_quantity, false);
        }
    }
    $is_updating = false;
}

注意事项

  • 添加捆绑商品到购物车时,要保证每一组捆绑商品的bundle_id全局唯一,推荐用uniqid('bundle_')生成,不要用商品ID这类易重复的值,避免误关联不相关的商品。
  • 上述代码建议放在子主题的functions.php文件或者自定义功能插件中,不要直接写入父主题文件,避免主题更新时代码被覆盖。

内容的提问来源于stack exchange,提问作者Caluria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:21:55