当特定产品在 Woocommerce 的购物车中时,从国家/地区列表中删除加拿大

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

我想做一些简单的事情:不要将特定产品运送到加拿大。

我认为这是最简单的方法:如果该特定产品存在于购物车中,请从结帐页面中删除加拿大。

特定产品:
1- https://constructioncovers.com/product/insulated-cement-curing-blankets/ (ID: 12616)
2- https://constructioncovers.com/product/insulated-construction-tarps/ (ID: 15631)

我的研究:
这篇文章为我提供了一种在购物车中查找产品并在条件为真时执行任何操作的方法:https://businessbloomer.com/woocommerce-easily-check-product-id-cart/ This article gave me a way to remove specific country from checkout page 我合并并修改了这两个代码以尝试完成我的任务。这是我的代码:

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 );

但是上面的功能不起作用
。它使国家/地区下拉列表为空,从而导致在整个站点范围内发出警告通知。

有人可以指出我做错了什么吗?

截图:

编辑自

   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;
  }

你能试试下面的代码吗?

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 );

注意 'woocommerce_countries' 过滤器最后一个参数的变化。由于将附加参数传递给函数,因此最后一个参数更改为 2 而不是 1。

当特定产品在购物车中时,以下代码将从允许的国家/地区删除 "Canada":

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;
}

代码进入您的活动子主题(活动主题)的 function.php 文件。测试和工作。

不幸的是,从 WooCommerce 3.6.2 开始,他们已经删除了在 any 后端调用 according to the ticket I opened 中检查购物车的功能。我是 运行 woocommerce_countries 上的一个类似过滤器,用于限制购物车中的某些商品只能在某些位置购买,几天前更新后出现致命错误。

WC 表示他们不会解决这个问题,因为这是加快速度的预期行为。但是,您仍然可以通过执行以下操作访问此过滤器中的购物车:

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);

这在表面上与 相同;然而,由于 WC()->cart->get_cart() 不再可用,我们将改为通过 WC()->session->cart 访问购物车。

由于 woocommerce API 发生了变化,因此需要进行一些改动。 https://github.com/woocommerce/woocommerce/issues/23758

购物车像以前一样不可用。

add_filter('woocommerce_countries', 'products_disable_country', 10, 1);
function products_disable_country( $countries ) {
    global $woocommerce;
  // is_cart & is_checkout does not to be working anymore.
  //   if( is_cart() || is_checkout() ) {

        $products = array(15631, 12616);
        // but you can get the cart via the session
        $cart = $woocommerce->session->cart; 
        foreach( $cart as $item ){
            if( in_array( $item['product_id'], $products ) ){
                unset($countries["CA"]);
                return $countries;
            }
        }
    // }

    return $countries;
}