Disable some states if specific products are in cart in Woocommerce

拜拜、爱过 提交于 2019-12-12 23:10:19

问题


Using woocommerce, I managed to change the states to the counties here in Ireland, including the following code in the function.php

function  wc_ie_counties_add_counties( $states ) {
    $states['IE'] = array(
        'Carlow' => 'Carlow',
        'Cavan' => 'Cavan',
        'Clare' => 'Clare',
        'Cork' => 'Cork',
        'Donegal' => 'Donegal',
        'Dublin' => 'Dublin',
        'Galway' => 'Galway',
        'Kerry' => 'Kerry',
        'Kildare' => 'Kildare',
        'Kilkenny' => 'Kilkenny',
        'Laois' => 'Laois',
        'Leitrim' => 'Leitrim',
        'Limerick' => 'Limerick',
        'Longford' => 'Longford',
        'Louth' => 'Louth',
        'Mayo' => 'Mayo',
        'Meath' => 'Meath',
        'Monaghan' => 'Monaghan',
        'Offaly' => 'Offaly',
        'Roscommon' => 'Roscommon',
        'Sligo' => 'Sligo',
        'Tipperary' => 'Tipperary',
        'Waterford' => 'Waterford',
        'Westmeath' => 'Westmeath',
        'Wexford' => 'Wexford',
        'Wicklow' => 'Wicklow',
    );
    return $states;
}
add_filter( 'woocommerce_states', 'wc_ie_counties_add_counties' );

But I would like to remove a few counties if a specific product id is in the cart.

Example: If product id 581 and/or 590 is/are in the cart, display only Dublin, Cavan and Carlow states.

Thank you,


回答1:


Using your actual code you need to set 2 arrays of states, one restricted and one completed. We will also need to check in cart items for product IDs 581 and/or 590. If one of this products is in cart we set the restricted array of states, if not we set the complete array of states.

The code:

add_filter( 'woocommerce_states', 'wc_ie_counties_add_counties' );
function  wc_ie_counties_add_counties( $states ) {
    // HERE your product IDS
    $products_ids = array( 581, 590 );

    $cart = WC()->cart; // The Cart object
    $found = false;

    $states_partial = array(
        'Carlow' => 'Carlow',
        'Cavan' => 'Cavan',
        'Dublin' => 'Dublin'
    );

    $states_complete = array(
        'Carlow' => 'Carlow',
        'Cavan' => 'Cavan',
        'Clare' => 'Clare',
        'Cork' => 'Cork',
        'Donegal' => 'Donegal',
        'Dublin' => 'Dublin',
        'Galway' => 'Galway',
        'Kerry' => 'Kerry',
        'Kildare' => 'Kildare',
        'Kilkenny' => 'Kilkenny',
        'Laois' => 'Laois',
        'Leitrim' => 'Leitrim',
        'Limerick' => 'Limerick',
        'Longford' => 'Longford',
        'Louth' => 'Louth',
        'Mayo' => 'Mayo',
        'Meath' => 'Meath',
        'Monaghan' => 'Monaghan',
        'Offaly' => 'Offaly',
        'Roscommon' => 'Roscommon',
        'Sligo' => 'Sligo',
        'Tipperary' => 'Tipperary',
        'Waterford' => 'Waterford',
        'Westmeath' => 'Westmeath',
        'Wexford' => 'Wexford',
        'Wicklow' => 'Wicklow'
    );

    // Checking cart items
    foreach( $cart->get_cart() as $cart_item ) {
        if( in_array( $cart_item['product_id'], $products_ids ) ){
            $found = true;
            break;
        }
    }

    $states['IE'] = $found ? $states_partial : $states_complete;

    return $states;
}

Code goes in function.php file of the active child theme (or active theme).

It should works…


The same with Product Categories instead of Product IDs (based on author's code):

add_action('woocommerce_states', 'my_check_category_in_cart');
function my_check_category_in_cart( $states ) {
    // HERE your product categories
    $products_categories = array( 'baths','curved-radiators','cabinets','mirrors','sinks',
        'storage-units','toilets','vanity-units','column-radiators','curved-radiators',
        'designer-radiators','flat-panel-radiators','heated-towel-radiators');

    $is_in_cart = false;

    // Loop through all products in the Cart
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        // Check for product categories
        if ( has_term( $products_categories, 'product_cat', $cart_item['product_id'] )  ) {
            $is_in_cart = true;
            break;
        }
    }

    if ( $is_in_cart ) {

        $states['IE']  = array(
            'Carlow' => 'Carlow',
            'Dublin' => 'Dublin',
            'Kildare' => 'Kildare',
            'Kilkenny' => 'Kilkenny',
            'Laois' => 'Laois',
            'Longford' => 'Longford',
            'Louth' => 'Louth',
            'Meath' => 'Meath',
            'Offaly' => 'Offaly',
            'Westmeath' => 'Westmeath',
            'Wexford' => 'Wexford',
            'Wicklow' => 'Wicklow'
        );
        // Display a custom notice
        if( is_checkout() && WC()->customer->get_billing_country() == 'IE' )
            wc_add_notice( 'One of the products below can only be delivered inside Leinster area', 'notice' );

    } else {
        $states['IE'] = array(
            'Carlow' => 'Carlow',
            'Cavan' => 'Cavan',
            'Clare' => 'Clare',
            'Cork' => 'Cork',
            'Donegal' => 'Donegal',
            'Dublin' => 'Dublin',
            'Galway' => 'Galway',
            'Kerry' => 'Kerry',
            'Kildare' => 'Kildare',
            'Kilkenny' => 'Kilkenny',
            'Laois' => 'Laois',
            'Leitrim' => 'Leitrim',
            'Limerick' => 'Limerick',
            'Longford' => 'Longford',
            'Louth' => 'Louth',
            'Mayo' => 'Mayo',
            'Meath' => 'Meath',
            'Monaghan' => 'Monaghan',
            'Offaly' => 'Offaly',
            'Roscommon' => 'Roscommon',
            'Sligo' => 'Sligo',
            'Tipperary' => 'Tipperary',
            'Waterford' => 'Waterford',
            'Westmeath' => 'Westmeath',
            'Wexford' => 'Wexford',
            'Wicklow' => 'Wicklow'
        );
    }
    return $states;
}

Code goes in function.php file of the active child theme (or active theme).

Now it should works for product variations (on variable products) too.




回答2:


I used your code LoicTheAztec, and it works perfectly, but then I realized it would take me ages to add all the products and update it all the time I included a new one.

So using your code and a bit of other that I found. I came up with this one that does the something but based on categories.

add_action('woocommerce_states', 'my_check_category_in_cart');

    function my_check_category_in_cart($states) {

    // Set $cat_in_cart to false
    $cat_in_cart = false;

    // Loop through all products in the Cart        
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {

        $product = $cart_item['data'];

        $products_categ = array( 'baths','curved-radiators','cabinets','mirrors','sinks','storage-units','toilets','vanity-units','column-radiators','curved-radiators','designer-radiators','flat-panel-radiators','heated-towel-radiators');

        // If Cart has category "download", set $cat_in_cart to true
        if ( has_term( $products_categ, 'product_cat', $product->get_id() )  ) {
            $prod_id = $product_id;
            $cat_in_cart = true;
            break;
        }
    }

    // Do something if category "download" is in the Cart      
    if ( $cat_in_cart ) {

        add_action('woocommerce_before_checkout_form', 'my_check_category_in_cart_msg');

    function my_check_category_in_cart_msg() {
     wc_print_notice( 'One of the products below can only be delivered inside Leinster area', 'notice' );
    }
       $states_complete = array(
            'Carlow' => 'Carlow',
            'Dublin' => 'Dublin',
            'Kildare' => 'Kildare',
            'Kilkenny' => 'Kilkenny',
            'Laois' => 'Laois',
            'Longford' => 'Longford',
            'Louth' => 'Louth',
            'Meath' => 'Meath',
            'Offaly' => 'Offaly',
            'Westmeath' => 'Westmeath',
            'Wexford' => 'Wexford',
            'Wicklow' => 'Wicklow'
        );



    }

        else{

            $states_complete = array(
            'Carlow' => 'Carlow',
            'Cavan' => 'Cavan',
            'Clare' => 'Clare',
            'Cork' => 'Cork',
            'Donegal' => 'Donegal',
            'Dublin' => 'Dublin',
            'Galway' => 'Galway',
            'Kerry' => 'Kerry',
            'Kildare' => 'Kildare',
            'Kilkenny' => 'Kilkenny',
            'Laois' => 'Laois',
            'Leitrim' => 'Leitrim',
            'Limerick' => 'Limerick',
            'Longford' => 'Longford',
            'Louth' => 'Louth',
            'Mayo' => 'Mayo',
            'Meath' => 'Meath',
            'Monaghan' => 'Monaghan',
            'Offaly' => 'Offaly',
            'Roscommon' => 'Roscommon',
            'Sligo' => 'Sligo',
            'Tipperary' => 'Tipperary',
            'Waterford' => 'Waterford',
            'Westmeath' => 'Westmeath',
            'Wexford' => 'Wexford',
            'Wicklow' => 'Wicklow'
        );

        }

            $states['IE'] = $states_complete;

        return $states;

    }

I dont know if it is the correct approach, but it is working too.

Thank you so much



来源:https://stackoverflow.com/questions/48866551/disable-some-states-if-specific-products-are-in-cart-in-woocommerce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!