【问题标题】:Remove Canada from country list when specific products are in cart on Woocommerce当特定产品在 Woocommerce 的购物车中时,将加拿大从国家/地区列表中删除
【发布时间】:2018-11-15 14:30:56
【问题描述】:

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

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

特定产品:
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/ 本文为我提供了一种从结帐页面中删除特定国家/地区的方法How to remove specific country in WooCommerce 我已经组合并修改了这两个代码以尝试和完成我的任务。这是我的代码:

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

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

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

截图:

【问题讨论】:

  • 查看类似答案here
  • @Jamie_D 感谢该链接,但该部分在我的代码中工作正常(尽管我同意未优化),实际问题是从结帐中取消设置国家/地区的代码。它以某种方式打破了国家下拉字段。我已经用截图更新了我的问题
  • return $countryif 语句中移出是否有效?似乎现在它只在找到 2 个产品之一时返回列表,否则它什么也不返回(又名 null)。
  • return $country 移到 if 语句之外会使代码无用。它什么也没做
  • 您为什么不根据访问者国家/地区禁用这些产品的“添加到购物车”按钮?

标签: php wordpress woocommerce cart country


【解决方案1】:

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

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 文件中。经过测试和工作。

【讨论】:

  • 谢谢,这行得通!不知道有什么区别,但这段代码没有错误地完成这项工作
  • 更新: 好的,发现第一个 if( is_cart() || is_checkout() ) 是阻止错误的原因。谢谢@LoicTheAztec
  • 可能很简单,但您可能只想从运输下拉列表中删除 CA,而不是从帐单下拉列表中删除 CA,但这可能是一种非常罕见的情况......
  • @Jamie_D 你是对的,但对于这个网站来说,这很好。
【解决方案2】:

编辑自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;
  }

【讨论】:

  • 刚刚更新了我的答案......过早返回国家可能是问题(请参阅移动返回)
  • 是的...也试过了,但是代码什么也没做
  • 我开始认为woocommerce_countries 是错误的过滤器See
  • 它也适用于woocommerce_countries。无论如何,我都会赞成你的回答,因为它有帮助
【解决方案3】:

不幸的是,从 WooCommerce 3.6.2 开始,他们已经取消了在 任何 后端调用 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);

这表面上和Loic's answer一样;但是由于WC()->cart->get_cart() 不再可用,我们改为通过WC()->session->cart 访问购物车。

【讨论】:

  • 谢谢,这也有帮助
【解决方案4】:

你能试试下面的代码吗?

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。

【讨论】:

  • 谢谢你,但你的代码给出了这个错误Uncaught ArgumentCountError: Too few arguments to function woo_remove_canada_country(), 1 passed in wp-includes/class-wp-hook.php on line 286 and exactly 2 expected in wp-content/themes/genesis-sample/functions.php:370
【解决方案5】:

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

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    相关资源
    最近更新 更多