在 WooCommerce 2.6 和 3+ 中删除特定类别的运输统一费率方法

2021-12-22 00:00:00 php shipping wordpress woocommerce checkout

我需要 woocommerce 运输选项方面的帮助,我想隐藏特定产品类别的统一费率,我只想显示本地交付或本地取货选项.

对于所有其他类别,所有选项都应该有效.

我尝试使用该代码(添加到我的主题的 function.php 文件中):

function car_has_product_with_orange_cats() {全球 $woocommerce;$product_in_cart = 假;//开始获取购物车项目的循环foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {$_product = $values['data'];$terms = get_the_terms( $_product->id, 'product_cat' );//二级循环搜索,以防某些项目有多个类别如果($条款){foreach ($terms as $term) {$_categoryid = $term->term_id;如果($_categoryid == 16){//类别在购物车中!$product_in_cart = 真;}}}}返回 $product_in_cart;}//添加过滤器和函数以隐藏方法add_filter('woocommerce_available_shipping_methods', 'custom_shipping_methods', 10, 1);函数 custom_shipping_methods( $available_methods ){如果(cart_has_product_with_orange_cats()){foreach($available_methods as $key => $method){if( $key == 'local_delivery' || $key == 'local_pickup'){继续;}未设置($available_methods[$key]);}//删除你想要的费率}//返回没有您未设置的可用方法.返回 $available_methods;}

但它对我不起作用,可能是因为最新的 WooCommerce 版本或任何其他问题的代码已过时.

我怎样才能做到这一点?

谢谢.

解决方案

更新 (兼容WC 3+,也适用于可变产品)

<块引用>

此答案的完整功能测试和更正代码位于另一个线程上:
送货方式 - 本地提货隐藏统一费率时选项不可用

<小时><块引用>

重要提示:
woocommerce_available_shipping_methods hook 已弃用,因为 WC 版本 2.1+,您需要改用 woocommerce_package_rates 过滤器钩子.

WooCommerce 2.6+ 版引入了新的送货区域.因此,所有与运费相关的 WooCommerce 先前版本代码都过时,将不再起作用.

<块引用>

有关信息:
全球 $woocommerce;** 与 $woocommerce->cart已被 WC()->cart 取代.
您将使用 WC()->cart->get_cart()...

我们将不再需要您的自定义条件函数,因为 WordPress 中已经存在一个条件函数,您可以将其定位为 WooCommerce 产品类别.此函数接受术语 ID、术语 slug 或术语名称:

has_term( 'your_category', 'product_cat', $post_id )

所以我们可以在这段代码中使用has_term()条件函数:

add_filter( 'woocommerce_package_rates', 'conditional_hide_shipping_methods', 100, 2 );函数conditional_hide_shipping_methods( $rates, $package ){//在此处定义/替换您正确的类别 slug (!)$product_category = 'your_category';$prod_cat = 假;//浏览购物车中的每件商品,看看是否有属于您的类别foreach ( WC()->cart->get_cart() 作为 $cart_item ) {$product_id = $cart_item['product_id'];if ( has_term( $product_category, 'product_cat', $product_id ) ){$prod_cat = 真;}}$rates_arr = array();如果($prod_cat){foreach($rates as $key => $rate) {if ('free_shipping' === $rate->method_id || 'local_pickup' === $rate->method_id || 'local_delivery' === $rate->method_id) {$rates_arr[ $rate_id ] = $rate;休息;}}}返回 !empty( $rates_arr ) ?$rates_arr : $rates;}

<块引用>

在添加代码段之前,请确保清除您的 WooCommerce 缓存(WooCommerce > 系统状态 > 工具 > WC 瞬变 > 清除瞬变),因为运输方式已被缓存.

此代码位于活动子主题或主题的 function.php 文件中.

如果您有正确的设置您的送货区域...

<小时>

参考文献:

  • 隐藏其他运输方式免费送货时
  • WooCommerce - 隐藏其他运输免费送货时的方法
  • WooCommerce 2.6 -当达到特定金额触发免费送货时隐藏付费送货
  • WooCommerce 购物车 - 条件商品类别验证
  • 如何在 WooCommerce 2.6 中设置送货区域

I need help in woocommerce shipping options, I want to hide flat rate for a particular product category, where I only want to show local delivery or local pickup options.

For all others categories all options should work.

I have try to do it with that code (added in function.php file of my theme):

function cart_has_product_with_orange_cats() {

    global $woocommerce;
    $product_in_cart = false;

    // start of the loop that fetches the cart items
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
        $_product = $values['data'];
        $terms = get_the_terms( $_product->id, 'product_cat' );
        // second level loop search, in case some items have several categories

        if($terms){

            foreach ($terms as $term) {
                $_categoryid = $term->term_id;

                if ( $_categoryid == 16 ) {
                    //category is in cart!
                    $product_in_cart = true;
                }
            }   
        }
    }
    return $product_in_cart;
}

// add filter and function to hide method

add_filter( 'woocommerce_available_shipping_methods', 'custom_shipping_methods' , 10, 1 );

function custom_shipping_methods( $available_methods ){

    if ( cart_has_product_with_orange_cats() ) {

        foreach($available_methods as $key => $method){
            if( $key == 'local_delivery' || $key == 'local_pickup'){
                continue;
            }
            unset($available_methods[$key]);

        }
        // remove the rate you want
    }
    // return the available methods without the one you unset.
    return $available_methods;
}

But it isn't working for me, maybe because outdated code for latest WooCommerce version or any other issue.

How can I achieve this?

Thanks.

解决方案

Update (Compatible with WC 3+ and works with variable products too)

The fully functional tested and corrected code for this answer is located on another thread:
Shipping methods - Local Pickup option not available when Flat Rate is hidden


Important:
woocommerce_available_shipping_methods hook is deprecated since WC version 2.1+ and you will need to use instead woocommerce_package_rates filter hook.

WooCommerce version 2.6+ introduce NEW shipping zones. So all WooCommerce prior version's code related to shipping rates is outdated and will not work anymore.

For info:
global $woocommerce;** with $woocommerce->cart has been replaced by WC()->cart.
You will use instead WC()->cart->get_cart()

We will not need anymore your custom conditional function, because there is already a conditional function that exist in WordPress, that you can target for WooCommerce product categories. This function accept the term ID, the term slug or the term name:

has_term( 'your_category', 'product_cat', $post_id )

So we can use has_term() conditional function in this code:

add_filter( 'woocommerce_package_rates', 'conditional_hide_shipping_methods', 100, 2 );    
function conditional_hide_shipping_methods( $rates, $package ){

    // Define/replace here your correct category slug (!)
    $product_category = 'your_category';
    $prod_cat = false;

    // Going through each item in cart to see if there is anyone of your category        
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product_id = $cart_item['product_id'];
        if ( has_term( $product_category, 'product_cat', $product_id ) ){
            $prod_cat = true;
        }
    }

    $rates_arr = array();

    if ( $prod_cat ) {
        foreach($rates as $key => $rate) {
            if ('free_shipping' === $rate->method_id || 'local_pickup' === $rate->method_id || 'local_delivery' === $rate->method_id) {
                $rates_arr[ $rate_id ] = $rate;
                break;
            }
        }
    }
    return !empty( $rates_arr ) ? $rates_arr : $rates;
}

Before adding the snippet, make sure you clear your WooCommerce cache (WooCommerce > System Status > Tools > WC Transients > Clear transients), as shipping methods are cached.

This code goes on function.php file of your active child theme or theme.

This code should work if you have correctly set your shipping zones…


References:

  • Hide other shipping methods when FREE SHIPPING is available
  • WooCommerce - Hide other shipping methods when FREE SHIPPING is available
  • WooCommerce 2.6 - Hiding paid shipping when free shipping is triggered by reaching specific amount
  • WooCommerce Cart - Conditional Items categories validation
  • How to Setup Shipping Zones in WooCommerce 2.6

相关文章