仅当强制性类别的产品在购物车中时才允许结帐

Posted

技术标签:

【中文标题】仅当强制性类别的产品在购物车中时才允许结帐【英文标题】:Allow checkout only when a product of a mandatory category is in cart 【发布时间】:2017-01-31 08:41:37 【问题描述】:

如果他们的购物篮中没有特定的产品类别,我想阻止任何客户前进到结账处。我还想通过错误消息告诉他们他们需要添加某个产品。我找到了一些代码,但无法正常工作。我已将它作为代码 sn-p 添加到我的 Wordpress 安装中,但是即使我打开了调试,它也不起作用并且没有错误消息。这是我在 Github 中找到的代码,可能需要修改才能使其正常工作:

function sv_wc_prevent_checkout_for_category() 

    // set the slug of the category for which we disallow checkout
    $category = 'sibling';

    // get the product category
    $product_cat = get_term_by( 'slug', $category, 'product_cat' );

    // sanity check to prevent fatals if the term doesn't exist
    if ( is_wp_error( $product_cat ) ) 
        return;
    

    $category_name = '<a href="' . get_term_link( $category, 'product_cat' ) . '">' . $product_cat->name . '</a>';

    // check if this category is the only thing in the cart
    if ( sv_wc_is_category_alone_in_cart( $category ) ) 

        // render a notice to explain why checkout is blocked
        wc_add_notice( sprintf( 'Hi there! Looks like your cart only contains products from the %1$s category &ndash; you must purchase a product from another category to check out.', $category_name ), 'error' );
    

add_action( 'woocommerce_check_cart_items', 'sv_wc_prevent_checkout_for_category' );

/**
 * Checks if a cart contains exclusively products in a given category
 * 
 * @param string $category the slug of the product category
 * @return bool - true if the cart only contains the given category
 */
function sv_wc_is_category_alone_in_cart( $category ) 

    // check each cart item for our category
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) 

        // if a product is not in our category, bail out since we know the category is not alone
        if ( ! has_term( $category, 'product_cat', $cart_item['data']->id ) ) 
            return false;
        
    

    // if we're here, all items in the cart are in our category
    return true;

因此,如果“兄弟”类别是购物车中唯一的商品,我希望停止结帐(带有错误消息)。我有一个“标准”类别,在客户结账之前必须在购物篮中。希望这是有道理的。

【问题讨论】:

【参考方案1】:

我已将 LoicTheAztec 的答案改编为使用 2 个类别。它似乎正在工作。我没有改编文本has_mandatory_categorytext函数,.如果您可以按照代码进行操作,则可以自己动手做,但我只关注功能。还有另一个答案here,但我更喜欢这个答案,而另一个对我不起作用。

// Function that define the 2 mandatory product categories cat1 & cat2
 function your_mandatory_category_slug() $category = 'cat1';    return $category; 
 function your_mandatory_category_slug2() $category = 'cat2';    return $category; 
// Conditional function that returns true if the mandatory product category is in cart
function has_mandatory_category1()
    $category_needed = your_mandatory_category_slug();
    $has_cat = false;
    foreach ( WC()->cart->get_cart() as $item ) 
        if ( has_term($category_needed, 'product_cat', $item['product_id'] ) ) 
            $has_cat = true;
            break;
        
    
    return $has_cat;
 
// Conditional function that returns true if the mandatory product category is in cart
function has_mandatory_category2()
    $category_needed = your_mandatory_category_slug2();
    $has_cat = false;
    foreach ( WC()->cart->get_cart() as $item ) 
        if ( has_term($category_needed, 'product_cat', $item['product_id'] ) ) 
            $has_cat = true;
            break;
        
    
    return $has_cat;
 





// Function that redirect from checkout to mandatory product category archives pages
function mandatory_category_checkout_redirect() 
    // If cart is not empty on checkout page
    if( !WC()->cart->is_empty() && is_checkout() )
        $category_needed = your_mandatory_category_slug();
        $category_needed2 = your_mandatory_category_slug2();
        if ( !has_mandatory_category1() )
            wp_redirect( get_term_link( $category_needed, 'product_cat' ) );
        if ( !has_mandatory_category2() )
            wp_redirect( get_term_link( $category_needed2, 'product_cat' ) );
    

add_action('template_redirect', 'mandatory_category_checkout_redirect');

【讨论】:

【参考方案2】:

使用 Woocommerce v2.6.12 对我的 Wordpress 安装很有帮助。

我想添加两个强制性产品类别,将来可能会增加 3 或 4 个。我试着改变:

$category = 'slug1';

$category = 'slug1', 'slug2';

$category = array('slug1','slug2');

没有成功。有没有办法让这段代码与多个 slug 一起工作?

【讨论】:

这不是一个答案,而是一个问题。删除您的答案,然后打开一个新问题。【参考方案3】:

在这里,您有一个可以成功的解决方案。特别是有两个主要功能(最后一个)

    第一个函数(N°3)在购物车页面上显示您的消息,当购物车中有东西但不是强制性产品类别时。还在强制性产品存档页面上显示消息(当客户从结帐被重定向时很有用,见下文)。 第二个功能 (N°4) 当客户尝试结帐并且他的购物车没有缺少强制性产品类别时将客户重定向到产品强制性类别存档页面。

your_mandatory_category_slug() 函数中在您的强制类别 slug 之前定义。

这是代码:

// Function that define the mandatory product category
 function your_mandatory_category_slug()

     // DEFINE HERE the SLUG of the needed product category
    $category = 'clothing';
    return $category;
 


// Conditional function that returns true if the mandatory product category is in cart
function has_mandatory_category()
    $category_needed = your_mandatory_category_slug();
    $has_cat = false;

    // Iterrating each item in cart and detecting…
    foreach ( WC()->cart->get_cart() as $item ) 

        // Detects if the needed product category is in cart items
        if ( has_term($category_needed, 'product_cat', $item['product_id'] ) ) 
            $has_cat = true;
            break;
        
    
    return $has_cat;
 


// Function that display a message if there is not in cart a mandatory product category
function mandatory_category_display_message() 
        $category_needed = your_mandatory_category_slug();

    // check that cart is not empty (for cart and product category archives)
    if( !WC()->cart->is_empty() && ( is_cart() || is_product_category( $category_needed ) ) )
        $category_obj = get_term_by( 'slug', $category_needed, 'product_cat' );
        if ( is_wp_error( $category_obj ) ) return;

        // Display message when product category is not in cart items
        if ( !has_mandatory_category() ) 
            $category_name = $category_obj->name;
            $category_url = get_term_link( $category_needed, 'product_cat' );

            // render a notice to explain why checkout is blocked
            wc_add_notice( sprintf( __( '<strong>Reminder:</strong> You have to add in your cart, a product from "%1$s" category, to be allowed to check out. Please return <a href="%2$s"> here to "%1$s" product page</a>', 'your_theme_domain'), $category_name, $category_url ), 'error' );
        
    

add_action( 'woocommerce_before_main_content', 'mandatory_category_display_message', 30 ); // for product mandatory category archives pages
add_action( 'woocommerce_check_cart_items', 'mandatory_category_display_message' ); // for cat page


// Function that redirect from checkout to mandatory product category archives pages
function mandatory_category_checkout_redirect() 

    // If cart is not empty on checkout page
    if( !WC()->cart->is_empty() && is_checkout() )
        $category_needed = your_mandatory_category_slug();

        // If missing product category => redirect to the products category page
        if ( !has_mandatory_category() )
            wp_redirect( get_term_link( $category_needed, 'product_cat' ) );
    

add_action('template_redirect', 'mandatory_category_checkout_redirect');

这在您的活动子主题(或主题)的 function.php 文件中或任何插件文件中。

此代码经过测试且功能齐全。

【讨论】:

洛伊克!极好的!这是一种享受。非常感谢。 使用 Woocommerce v2.6.12 安装 Wordpress 就像一个魅力。我想添加两个强制性产品类别,将来可能会增加 3 个或 4 个。我尝试更改: $category = 'slug1';$category = 'slug1', 'slug2';$category = array('slug1', 'slug2'); 没有成功。有没有办法让这段代码与多个 slug 一起工作? @ResulCimen 您应该针对您的要求提出一个新问题……然后在此处通过链接通知我。 这太棒了,添加我的预订网站,它工作得很好 最新的 woocommerce 版本是否仍然有效?

以上是关于仅当强制性类别的产品在购物车中时才允许结帐的主要内容,如果未能解决你的问题,请参考以下文章

如果 WooCommerce 结帐中存在某些产品类别,请删除其他产品

特定产品类别的强制性优惠券,避免在 Woocommerce 中结帐

Woocommerce 在结帐页面下订单后替换购物车中的产品

在购物车和结帐的 WooCommerce 产品名称中附加自定义字段值

在 Woocommerce 结帐页面中将产品添加到购物车的复选框字段

从结帐页面 woocommerce 更新购物车中的产品