基于其他商品数量自动移除WooCommerce迷你购物车商品X
WooCommerce迷你购物车移除商品后自动移除指定商品的解决方案
需求说明
当顾客从WooCommerce迷你购物车移除商品后,若商品X(ID:13387)的留存条件不再满足,则自动将其移除。留存条件为:购物车中同时属于商品分类15和51的商品总数量至少为8。
目前购物车页面的逻辑已正常生效,但Ajax驱动的迷你购物车无法实现该功能,以下是问题分析及修复方案:
现有代码问题分析
- PHP函数名不匹配:定义的函数是
bierfass_ajax_product_remove,但注册Ajax钩子时用的是my_ajax_product_remove,导致Ajax请求无法触发正确的处理函数。 - 条件判断逻辑错误:原代码检查的是单个商品的数量≥8,而需求是所有符合分类条件的商品总数量≥8。
- 未先处理用户触发的商品移除操作:原Ajax函数没有先执行用户点击的商品移除,直接检查条件,导致逻辑顺序错误。
修复后的完整代码
1. 通用检查函数(复用购物车页面逻辑)
将购物车页面的检查函数改造为可复用的函数,同时修正总数量统计逻辑:
function check_and_remove_product_x() { $product_x_id = 13387; $cart = WC()->cart; if ( ! $cart ) return; // 统计同时属于分类15和51的商品总数量 $qualified_total = 0; foreach ( $cart->get_cart() as $cart_item ) { if ( has_term( 51, 'product_cat', $cart_item['product_id'] ) && has_term( 15, 'product_cat', $cart_item['product_id'] ) ) { $qualified_total += $cart_item['quantity']; } } // 条件不满足则移除商品X if ( $qualified_total < 8 ) { foreach( $cart->get_cart() as $cart_item_key => $cart_item ) { if ( $cart_item['product_id'] == $product_x_id ) { $cart->remove_cart_item( $cart_item_key ); break; } } } } // 保留购物车和结账页面的钩子 add_action( 'woocommerce_before_cart', 'check_and_remove_product_x' ); add_action( 'woocommerce_before_checkout_form', 'check_and_remove_product_x' );
2. 修正后的Ajax处理函数
function bierfass_ajax_product_remove() { // 先处理用户请求移除的商品 if ( isset( $_POST['cart_item_key'] ) && ! empty( $_POST['cart_item_key'] ) ) { WC()->cart->remove_cart_item( $_POST['cart_item_key'] ); } // 执行商品X的检查移除逻辑 check_and_remove_product_x(); // 更新购物车并生成迷你购物车内容 WC()->cart->calculate_totals(); WC()->cart->maybe_set_cart_cookies(); ob_start(); woocommerce_mini_cart(); $mini_cart = ob_get_clean(); // 返回符合WooCommerce规范的响应数据 $data = array( 'fragments' => apply_filters( 'woocommerce_add_to_cart_fragments', array( '.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>' ) ), 'cart_hash' => apply_filters( 'woocommerce_add_to_cart_hash', WC()->cart->get_cart_for_session() ? md5( json_encode( WC()->cart->get_cart_for_session() ) ) : '', WC()->cart->get_cart_for_session() ) ); wp_send_json( $data ); die(); } // 注册正确的Ajax钩子 add_action( 'wp_ajax_product_remove', 'bierfass_ajax_product_remove' ); add_action( 'wp_ajax_nopriv_product_remove', 'bierfass_ajax_product_remove' );
3. 修正后的JS代码
$(document).on('click', '.mini_cart_item a.remove', function (e) { e.preventDefault(); var cart_item_key = $(this).attr("data-cart_item_key"), product_container = $(this).parents('.mini_cart_item'); // 添加加载动画 product_container.block({ message: null, overlayCSS: { cursor: 'none' } }); $.ajax({ type: 'POST', dataType: 'json', url: wc_add_to_cart_params.ajax_url, data: { action: "product_remove", cart_item_key: cart_item_key }, success: function (response) { if (!response || response.error) return; // 更新购物车片段 if (response.fragments) { $.each(response.fragments, function (key, value) { $(key).replaceWith(value); }); } // 触发WooCommerce购物车更新事件 $(document.body).trigger('wc_fragment_refresh'); $(document.body).trigger('wc_update_cart'); }, error: function() { // 加载失败时移除加载动画 product_container.unblock(); } }); });
关键修复点说明
- 统一逻辑复用:将检查逻辑抽离为通用函数,避免代码冗余,确保购物车页面和迷你购物车逻辑一致。
- 修正数量统计:改为统计所有符合分类条件的商品总数量,而非单个商品数量。
- 修复函数名匹配:确保Ajax钩子注册的函数名和定义的函数一致。
- 调整逻辑顺序:先执行用户触发的商品移除,再检查并移除商品X,符合操作流程。
- 规范响应格式:确保返回的片段选择器和WooCommerce默认格式一致,避免更新失败。
内容的提问来源于stack exchange,提问作者cinquecentooo
相关产品推荐
相关产品推荐

