WPML多语言站点下WooCommerce编程添加商品到购物车功能失效
故障原因
- WPML多语言站点下所有商品、分类、标签都会生成独立的内容ID,你代码中硬编码的
catalog标签、赠品ID92271仅对应默认英文站点的内容,翻译站点下判断标签、判断赠品是否存在的逻辑全部失效,最终导致重复添加赠品、赠品无法自动删除的问题 woocommerce_before_calculate_totals钩子单次请求会触发多次,未加执行次数限制也会导致重复执行赠品添加逻辑,触发报错
修复后完整代码
add_action( 'woocommerce_before_calculate_totals', 'wc_auto_add_dvd_gift_to_cart' ); function wc_auto_add_dvd_gift_to_cart( $cart ) { if (is_admin() && !defined('DOING_AJAX')) return; // 防止钩子重复执行 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; $parent_gift_id_0 = 0; // 可变赠品的父产品ID,简单赠品填0 $default_gift_id = 92271; // 默认语言下的赠品ID $trigger_tag_slug = 'catalog'; // 触发赠品的标签slug // WPML适配:获取当前语言下的赠品ID $product_gift_id_0 = apply_filters( 'wpml_object_id', $default_gift_id, 'product', true ); // WPML适配:获取当前语言下的触发标签ID $trigger_tag = get_term_by( 'slug', $trigger_tag_slug, 'product_tag' ); $valid_tag_ids = []; if ( $trigger_tag ) { $current_lang_tag_id = apply_filters( 'wpml_object_id', $trigger_tag->term_id, 'product_tag', true ); $valid_tag_ids = [ $trigger_tag->term_id, $current_lang_tag_id ]; } $has_required = $gift_key = false; // 初始化变量 foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { // 判断购物车商品是否包含触发标签(适配多语言) if( ! empty( $valid_tag_ids ) && has_term( $valid_tag_ids, 'product_tag', $cart_item['product_id'] ) ) { $has_required = true; } // 判断当前语言的赠品是否已在购物车 if( $cart_item['data']->get_id() == $product_gift_id_0 ) { $gift_key = $cart_item_key; } } // 无触发商品但有赠品:删除赠品 if ( ! $has_required && $gift_key ) { $cart->remove_cart_item( $gift_key ); } // 有触发商品但无赠品:添加赠品 elseif ( $has_required && ! $gift_key ) { if( $parent_gift_id_0 == 0 ) { // 简单赠品 $cart->add_to_cart( $product_gift_id_0 ); } else { // 可变赠品,适配父产品ID的多语言转换 $current_lang_parent_gift_id = apply_filters( 'wpml_object_id', $parent_gift_id_0, 'product', true ); $cart->add_to_cart( $current_lang_parent_gift_id, 1, $product_gift_id_0 ); } } }
修改说明
- 新增钩子执行次数限制:避免单次请求内多次触发赠品添加逻辑,解决「无法添加另一件赠品」的报错
- 新增WPML ID适配逻辑:通过WPML官方提供的
wpml_object_id过滤器,自动获取当前语言下对应的赠品ID、触发标签ID,兼容所有翻译站点的判断逻辑 - 优化标签判断规则:同时兼容默认语言和当前语言的标签ID,避免极端场景下判断失效的问题
内容的提问来源于stack exchange,提问作者J.K.
相关产品推荐
相关产品推荐

