Корзина WooCommerce - Проверка категорий условных товаров


У нас есть эксклюзивная категория X и другие регулярные категории Y. Что бы я хотел:

  • Когда кто-то заказывает что-либо из категории X, другие товары категории не могут быть добавлены в корзину и должны отображать предупреждение
  • категория Y продукты не следует смешивать с X.

Как я мог этого добиться?

Я получил этот код из другого поста, но он устарел и неудовлетворителен:

<?php

 // Enforce single parent category items in cart at a time based on first item in cart
function get_product_top_level_category ( $product_id ) {

    $product_terms            =  get_the_terms ( $product_id, 'product_cat' );
    $product_category         =  $product_terms[0]->parent;
    $product_category_term    =  get_term ( $product_category, 'product_cat' );
    $product_category_parent  =  $product_category_term->parent;
    $product_top_category     =  $product_category_term->term_id;

    while ( $product_category_parent  !=  0 ) {
            $product_category_term    =  get_term ( $product_category_parent, 'product_cat' );
            $product_category_parent  =  $product_category_term->parent;
            $product_top_category     =  $product_category_term->term_id;
    }

    return $product_top_category;
}

add_filter ( 'woocommerce_before_cart', 'restrict_cart_to_single_category' );
function restrict_cart_to_single_category() {
    global $woocommerce;
    $cart_contents    =  $woocommerce->cart->get_cart( );
    $cart_item_keys   =  array_keys ( $cart_contents );
    $cart_item_count  =  count ( $cart_item_keys );

    // Do nothing if the cart is empty
    // Do nothing if the cart only has one item
    if ( ! $cart_contents || $cart_item_count == 1 ) {
            return null;
    }

    // Multiple Items in cart
    $first_item                    =  $cart_item_keys[0];
    $first_item_id                 =  $cart_contents[$first_item]['product_id'];
    $first_item_top_category       =  get_product_top_level_category ( $first_item_id );
    $first_item_top_category_term  =  get_term ( $first_item_top_category, 'product_cat' );
    $first_item_top_category_name  =  $first_item_top_category_term->name;

    // Now we check each subsequent items top-level parent category
    foreach ( $cart_item_keys as $key ) {
            if ( $key  ==  $first_item ) {
                    continue;
            }
            else {
                    $product_id            =  $cart_contents[$key]['product_id'];
                    $product_top_category  =  get_product_top_level_category( $product_id );

                    if ( $product_top_category  !=  $first_item_top_category ) {
                            $woocommerce->cart->set_quantity ( $key, 0, true );
                            $mismatched_categories  =  1;
                    }
            }
    }

    // we really only want to display this message once for anyone, including those that have carts already prefilled
    if ( isset ( $mismatched_categories ) ) {
            echo '<p class="woocommerce-error">Only one category allowed in cart at a time.<br />You are currently allowed only <strong>'.$first_item_top_category_name.'</strong> items in your cart.<br />To order a different category empty your cart first.</p>';
    }
}
?>

Спасибо

Author: LoicTheAztec, 2016-07-15

1 answers

Как будто все поворачивается вокруг вашей эксклюзивной категории category X, вам нужно использовать условное обозначение для этой категории.

И у вас есть шанс, потому что есть специальная функция, которую вы можете использовать в сочетании с категориями товаров woocommerce. Допустим, что **cat_x** - это пуля для вашей эксклюзивной категории, как вы ее еще знаете product_cat является аргументом для получения категорий продуктов.

Так что с has_term () условная функция, вы собираетесь используйте это:

if ( has_term ('cat_x', 'product_cat', $item_id ) ) { // or $product_id
    // doing something when product item has 'cat_x'
} else {
    // doing something when product item has NOT 'cat_x'
}

Нам нужно запустить элементы корзины 2 раза в цикле foreach:

  • Чтобы определить, есть ли cat_x предмет в этой машине.
  • Чтобы удалить другие элементы, если cat_x обнаруживается для одного товара в корзине и для отправки правильных сообщений.

В приведенном ниже коде я перешел на более полезный крючок. Этот крючок проверит, что у вас есть в корзине. Идея состоит в том, чтобы удалить товары других категорий в корзине, когда есть товар 'cat_x' добавлен в корзину.

Код хорошо прокомментирован. В конце вы найдете различные уведомления, которые будут уволены. Вам нужно будет поместить свой реальный текст в каждый из них.

add_action( 'woocommerce_check_cart_items', 'checking_cart_items' );
function checking_cart_items() {

    global $woocommerce; // if needed, not sure (?)
    $special = false;
    $catx = 'cat_x';
    $number_of_items = sizeof( WC()->cart->get_cart() );

    if ( $number_of_items > 0 ) {

        // Loop through all cart products
        foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
            $item = $values['data'];
            $item_id = $item->id;

            // detecting if 'cat_x' item is in cart
            if ( has_term( $catx, 'product_cat', $item_id ) ) {
                if (!$special) {
                    $special = true;
                }
            }
        }

        // Re-loop through all cart products
        foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
            $item = $values['data'];
            $item_id = $item->id;

            if ( $special ) // there is a 'cat_x' item in cart
            { 
                if ( $number_of_items == 1 ) { // only one 'cat_x' item in cart
                    if ( empty( $notice ) ){
                        $notice = '1';
                    }
                }
                if ( $number_of_items >= 2 ) { // 'cat_x' item + other categories items in cart

                    // removing other categories items from cart
                    if ( !has_term( $catx, 'product_cat', $item_id ) ) {
                        WC()->cart->remove_cart_item( $cart_item_key ); // removing item from cart
                        if ( empty( $notice ) || $notice == '1' ){
                            $notice = '2';
                        }
                    }
                }
            } else { // Only other categories items

                if ( empty( $notice ) ){
                    $notice = '3';
                }
            }
        }

        // Firing woocommerce notices
        if ( $notice == '1' ) { // message for an 'cat_x' item only (alone)
            wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla one category X item in the cart</p>' ), 'success' );
        } elseif ( $notice == '2' ) { // message for an 'cat_x' item and other ones => removed other ones 
            wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla ther is already category X in the cart => Other category items has been removed</p>' ), 'error' );
        } elseif ( $notice == '3' ) { // message for other categories items (if needed)
            wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla NOT category X in the cart</p>' ), 'success' );
        }
    }
}       

Я не могу по-настоящему протестировать этот код (но он не выдает ошибок)...


@ редактировать

Мы можем использовать что-то другое, кроме уведомлений… все возможно. Но это хорошее стартовое решение для точной настройки.

Вам нужно будет заменить 'cat_x' по ваш реальный слиток категории (в начале)...

 3
Author: LoicTheAztec, 2016-07-15 20:21:30