1

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,

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399

2 Answers2

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.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • @LeandroAndrade I have added an update Here (2nd code) fro product categories, that will work with product variations (variable products) too… – LoicTheAztec Feb 19 '18 at 17:17
  • My Hero!!! Yes it worked now including variable products, I just got an error related to the wc_add_notice, but I fixed. Again, you saved my day. Thank you very much! – Leandro Andrade Feb 19 '18 at 17:33
  • Sorry for bother you again, but for some reason this function breaks the admin order page. It gets all blank. I see the error is coming from the foreach ( WC()->cart->get_cart() as $cart_item ) – Leandro Andrade Feb 20 '18 at 16:30
0

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

  • Yes that is the way using product categories instead… but as you asked for Product IDs… I have answered for product IDs – LoicTheAztec Feb 19 '18 at 16:03
  • You did great, I just didnt pay attention to the amount of products the site has. Sorry for disturb you again, but my code is not working very well. It seems like it doesnt work for products with variables. So you have any idea about it? – Leandro Andrade Feb 19 '18 at 17:06