Remove Canada from country list when specific products are in cart on Woocommerce

ⅰ亾dé卋堺 提交于 2019-12-13 17:52:32

问题


I want to do something simple: do not ship a particular product to Canada.

Here's the easiest way to do it in my opinion: if that particular product is present in the cart, remove Canada from checkout page.

Particular products:
1- https://constructioncovers.com/product/insulated-cement-curing-blankets/ (ID: 12616)
2- https://constructioncovers.com/product/insulated-construction-tarps/ (ID: 15631)

My research:
This article gave me a way to find products in cart and perform any action if condition is true: https://businessbloomer.com/woocommerce-easily-check-product-id-cart/ This article gave me a way to remove specific country from checkout page How to remove specific country in WooCommerce I have combined and modified the two codes to try and accomplish my task. Here's my code:

function unset_country_on_condition( $country ) {
    $product_id = 15631;
    $product_id_2 = 12616; 
    $product_cart_id = WC()->cart->generate_cart_id( $product_id );
    $product_cart_id_2 = WC()->cart->generate_cart_id( $product_id_2 );
    $in_cart = WC()->cart->find_product_in_cart( $product_cart_id );
    $in_cart_2 = WC()->cart->find_product_in_cart( $product_cart_id_2 );
    if ( $in_cart || $in_cart_2 ) {
        unset($country["CA"]);
        return $country;
    }
}
add_filter( 'woocommerce_countries', 'unset_country_on_condition', 10, 1 );

But the above function doesn't work
. It makes the country dropdown empty resulting in a site-wide warning notice.

Can someone point out what I am doing wrong?

Screenshots:


回答1:


The following code will remove "Canada" from allowed countries when specific products are in cart:

add_filter( 'woocommerce_countries', 'products_disable_country', 10, 1 );
function products_disable_country( $countries ) {
    if( is_cart() || is_checkout() ) {

        $products = array(15631, 12616);

        foreach( WC()->cart->get_cart() as $item ){
            if( in_array( $item['product_id'], $products ) ){
                unset($countries["CA"]);
                return $countries;
            }
        }
    }

    return $countries;
}

Code goes in function.php file of your active child theme (active theme). tested and work.




回答2:


Edited from this answer

   add_filter( 'woocommerce_countries', 'unset_country_on_condition', 10, 1 );
   function unset_country_on_condition( $countries ) {

    // Set here your to add product IDS (in the array)
    $product_ids = array( 15631, 12616 );
    $is_in_cart = false;

    // Iterating through cart items and check
    foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item )
        if( in_array( $cart_item['data']->get_id(), $product_ids ) ){
            $is_in_cart = true; // We set it to "true"
            break; // At least one product, we stop the loop
        }

    if( $is_in_cart ){
        unset($countries["CA"]);
    }
    return $countries;
  }



回答3:


Unfortunately, as of WooCommerce 3.6.2, they have removed the ability to check the cart in any backend calls, according to the ticket I opened. I was running a similar filter on woocommerce_countries, to restrict certain items in the cart to only be purchasable at certain locations, and got a fatal error after I updated a few days ago.

WC have said they won't fix the issue, as it's intended behaviour to speed things up. However, you can still access the cart in this filter by doing the following:

function vnm_disable_country_for_products($countries) {
    // get_cart() will fail here in WC > 3.6.2, but we can still access a basic cart via the session:

    $cartArray = WC()->session->cart;

    if (is_array($cartArray) && !empty($cartArray)) {

        $noSaleCountry = 'CA';
        $limitingProducts = array(12616, 15631);

        foreach ($cartArray as $itemArray) {
            if (in_array($itemArray['product_id'], $limitingProducts)) {

            unset($countries[$noSaleCountry]);

        }
    }

    return $countries;
}

add_filter('woocommerce_countries', 'vnm_disable_country_for_products', 10, 1);

This is ostensibly the same as Loic's answer; however as WC()->cart->get_cart() is no longer available, we're accessing the cart via WC()->session->cart instead.




回答4:


Can you try following code.

global $product_check; //declare a global variable
function remove_canada_insulated_blankets_traps(){
    $product_ids = array(12616,15631);
    foreach($product_ids as $product_id){
        $product_cart_id = WC()->cart->generate_cart_id( $product_id );
        $in_cart = WC()->cart->find_product_in_cart( $product_cart_id );
        $product_check[$in_cart]; //global variable is converted into an array storing ids
    }
}
add_action( 'woocommerce_before_cart', 'remove_canada_insulated_blankets_traps' );

//pass the global variable into following function as another argument
function woo_remove_canada_country( $countries, $product_check ){
    if( count(product_check) > 0 ){ //check count of the array
        unset($countries['CA']); //unset country
    }
    return $countries; 
}
add_filter( 'woocommerce_countries', 'woo_remove_canada_country', 10, 2 );

Notice the change in last argument of 'woocommerce_countries' filter. Since additional argument is passed to the function the last argument is changed to 2 instead of 1.



来源:https://stackoverflow.com/questions/53321692/remove-canada-from-country-list-when-specific-products-are-in-cart-on-woocommerc

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