Search code examples
phpwordpresswoocommercetaxonomy-termsproduct-variations

has_term() conditional function usage with WooCommerce cart and order items


I have created various products in WordPress using the WooCommerce plugin Now, for each category of products, I have considered some personal fields For example, products in the online game category have a password field, while products in the software category have a software ID field. Through the following code, I have defined in the template function that, for example, if the product was in the category with the address clash, it should display the desired fields:

add_filter('woocommerce_checkout_fields', 'add_custom_field_based_on_product_category');

function add_custom_field_based_on_product_category($fields) {

$target_category = 'clash-of-clans';

$has_same_category_product = false;

foreach (WC()->cart->get_cart() as $cart_item) {
    $product = $cart_item['data'];
    if (has_term($target_category, 'product_cat', $product->get_id())) {
        $has_same_category_product = true;
        break;
    }
}

// If a product in the same category is in the cart, add the custom field
if ($has_same_category_product) {
    $fields['billing']['billing_custom_field'] = array(
        'type' => 'text',
        'label' => 'password',
        'required' => true,
        'class' => array('form-row-wide'),
        'clear' => true,
    );
}

return $fields;
}

The code that I add to the function works correctly, but when I add a feature like the number of diamonds to the product, the fields are not displayed and the display condition is false. How do I set the condition for same product features as well?


Solution

  • To make it work for product variations too, you need to replace in your code:

        $product = $cart_item['data'];
        if (has_term($target_category, 'product_cat', $product->get_id())) {
    

    with:

        if (has_term($target_category, 'product_cat', $cart_item['product_id'])) {
    

    Why?

    Because product variations don't handle any custom taxonomy as product categories, tags or any other. Instead, the parent variable product handle custom taxonomies as product categories, tags or any other.

    So When using in cart items $cart_item['product_id'] on a product variation, it refers to the parent variable product ID and then works with has_term() conditional function (and also works for other product types).

    But $product = $cart_item['data'] and $product->get_id() will not work in has_term() conditional function when the cart item is a product variation.


    To resume

    1) For cart items

    For car items, you will use $cart_item['product_id'] like:

    $targeted_terms = array('boxes', 'bulbs'); // Term(s) slug(s) to find
    $taxonomy       = 'product_cat'; // for product tags use 'product_tag'
    $term_found     = false; // Initializing
    
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( has_term( $targeted_terms, $taxonomy, $cart_item['product_id'] ) ) {
            $term_found = true;
            break; // Stop the loop
        }
    }
    
    if ( $term_found ) {
        // Do something
    }
    
    2) For order items

    For order items, you will use WC_Order_Item get_product_id() method:

    $targeted_terms = array('boxes', 'bulbs'); // Term(s) slug(s) to find
    $taxonomy       = 'product_cat'; // for product tags use 'product_tag'
    $term_found     = false; // Initializing
    
    foreach ( $order->get_items() as $item ) {
        if ( has_term( $targeted_terms, $taxonomy, $item->get_product_id() ) ) {
            $term_found = true;
            break; // stop the loop
        }
    }
    
    if ( $term_found ) {
        // Do something
    }