'Modify "get_cart_contents_count()" to count only specific product IDs in WooCommerce cart

I have 3 ticket products in WooCommerce and want to add a name field per ticket product purchased - so if a customer buys three tickets 3 name fields are displayed to fill out in the checkout.

The code below works:

// Custom WooCommerce Checkout Fields based on Quantity
add_action( 'woocommerce_before_order_notes', 'person_details' );

function person_details($checkout) {

    global $woocommerce;

    $count = WC()->cart->get_cart_contents_count();

    $i = 1;

    for($k=2; $k<= $count; $k++) {
        $i++;

        print ('<h3>Please enter details of attendee '.$i.'</h3>');

        woocommerce_form_field( 'cstm_full_name'.$i, array(
            'type'          => 'text',
            'class'         => array('my-field-class form-row-wide'),
            'label'         => __('Full name'),
            'placeholder'   => __('Enter full name'),
            ),
        $checkout->get_value( 'cstm_full_name'.$i ));

        echo '<div class="clear"></div>';
    }
}

But this includes all products added to cart - how can I target specific Product IDs to be only be part of the cart count?

$count = WC()->cart->get_cart_contents_count();


Solution 1:[1]

As an alternative and most recommended way, you can use WC_Cart::get_cart_item_quantities() and in_array() in your callback function to get the cart item quantity from specific product IDs in cart

So you get:

function action_woocommerce_before_order_notes( $checkout ) {
    // True
    if ( WC()->cart ) {
        // Specific product IDs
        $product_ids = array( 30, 823, 53, 57 );

        // Initialize
        $count = 0;

        // Loop trough cart items quantities
        foreach ( WC()->cart->get_cart_item_quantities() as $product_id => $cart_item_quantity ) {
            // Checks if a value exists in an array
            if ( in_array( $product_id, $product_ids ) ) {
                $count += $cart_item_quantity;
            }
        }

        // Result
        echo '<p style="color: red; font-size: 25px;">Count = ' . $count . '</p>';
    }
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );

OR

You could use the woocommerce_cart_contents_count filter hook, which allows you to customize the get_cart_contents_count() function to your needs:

function filter_woocommerce_cart_contents_count( $array_sum ) {
    // True
    if ( WC()->cart ) {
        // Specific product IDs
        $product_ids = array( 30, 823, 53, 57 );

        // Loop trough cart items quantities
        foreach ( WC()->cart->get_cart_item_quantities() as $product_id => $cart_item_quantity ) {
            // Checks if a value NOT exists in an array
            if ( ! in_array( $product_id, $product_ids ) ) {
                $array_sum -= $cart_item_quantity;
            }
        }
    }

    return $array_sum;
}
add_filter( 'woocommerce_cart_contents_count', 'filter_woocommerce_cart_contents_count', 10, 1 );

function action_woocommerce_before_order_notes( $checkout ) {
    // True
    if ( WC()->cart ) {
        // Get number of items in the cart.
        $count = WC()->cart->get_cart_contents_count();

        // Result
        echo '<p style="color: red; font-size: 25px;">Count = ' . $count . '</p>';
    }
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );

Note: although the advantage here is that you can continue to use the get_cart_contents_count() function in this way, the disadvantage is that this function would also display the modified result when used for other purposes

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1