0
votes

I building my ecommerce for sell wine with wordpress 4.2.2 and woocommerce 2.3.11 I bought the "Product Bundle" (v. 4.9.5) plugin for woocommerce.

I already insert this function in my function.php file

add_action( 'woocommerce_check_cart_items', 'woocommerce_check_cart_quantities' );
function woocommerce_check_cart_quantities() {
    $multiples = 6;
    $total_products = 0;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
        $total_products += $values['quantity'];
    }
    if ( ( $total_products % $multiples ) > 0 )
        wc_add_notice( sprintf( __('You need to buy in quantities of %s products', 'woocommerce'), $multiples ), 'error' );
}

because I need to sell bottles on multiple of 6.
Now I have this problem with the product bundled, because in the cart also the parent item is counted.
If I create a bundle with 6 bottle, in the cart I have the message "You need to buy in quantities of %s products" because the total count is 7 (6 bottles plus 1 bundle).
I write to woothemes support and I recive this answer:

By default, Bundle contents are not counted. A Bundle will be counted as one item, no matter how many products it contains.

When using Product Bundles and needed to count the content, you need to use the WC()->cart->get_cart_contents_count() method to count all the cart items.

------ UPDATE -------

I try to add in my function the code from the answers, so now my function.php look like this:

<?php
/**
 * Child-Theme functions and definitions
 */

 // check that cart items quantities totals are in multiples of 6
add_action( 'woocommerce_check_cart_items', 'woocommerce_check_cart_quantities' );
function woocommerce_check_cart_quantities() {
    $multiples = 6;
    $total_products = 0;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
        $total_products += $values['quantity'];
    }
    if ( ( $total_products % $multiples ) > 0 )
        wc_add_notice( sprintf( __('You need to buy in quantities of %s products', 'woocommerce'), $multiples ), 'error' );
}

function so_28359520_remove_bundles_counting(){
     global $woocommerce_bundles;
     remove_filter( 'woocommerce_cart_contents_count',  array( $woocommerce_bundles->display, 'woo_bundles_cart_contents_count' ) );
}
add_action( 'init', 'so_28359520_remove_bundles_counting' );


function so_28359520_cart_contents_count( $count ) {
    $cart = WC()->cart->get_cart();
    $subtract = 0;
    foreach ( $cart as $key => $value ) {
        if ( isset( $value[ 'stamp' ] ) && ! isset( $value[ 'bundled_by' ] ) ) {
            $subtract += $value[ 'quantity' ];
        }
    }
    return $count - $subtract;
}
add_filter( 'woocommerce_cart_contents_count',  'so_28359520_cart_contents_count' );

?>

but nothing happen. I also try a fresh wordpress and woocommerce installation with default theme (twenty thirteen and also twnty fifteen) for test if there is some javascript in the theme that interfering and change the quantity, but the result is the same. If I have 1 bundles with 6 bottles I get the message from the first function.

2
What PHP error do you get?helgatheviking
with the function cit_update_cart_count() I get PHP Fatal error: Call to a member function get_cart() on a non-object in ..\wp-content\themes\Wine-child\functions.php on line 20 so I discard that functionWolftrick
Well that means that WC()->cart isn't an object, most likely because the init hook happens before the cart is initialized. Probably for the best to discard that function.helgatheviking

2 Answers

1
votes

I already answered this here. You need to disable Bundle's function and write your own to skip counting the bundle containers.

function so_28359520_remove_bundles_counting(){
     global $woocommerce_bundles;
     remove_filter( 'woocommerce_cart_contents_count',  array( $woocommerce_bundles->display, 'woo_bundles_cart_contents_count' ) );
}
add_action( 'init', 'so_28359520_remove_bundles_counting' );


function so_28359520_cart_contents_count( $count ) {

    $cart = WC()->cart->get_cart();

    $subtract = 0;

    foreach ( $cart as $key => $value ) {

        if ( isset( $value[ 'stamp' ] ) && ! isset( $value[ 'bundled_by' ] ) ) {
            $subtract += $value[ 'quantity' ];
        }
    }

    return $count - $subtract;

}
add_filter( 'woocommerce_cart_contents_count',  'so_28359520_cart_contents_count' );

One thing to note, is that Javascript could be updating the count in your menu/widgets and not taking this in to account for some reason. However, when I "view source" I am getting the desired counts (ie: a bundle of 6 bottles is showing a count of 6).

Or as an alternative, you could modify your counting function to not count the bundle container. Untested:

add_action( 'woocommerce_check_cart_items', 'woocommerce_check_cart_quantities' );
function woocommerce_check_cart_quantities() {
    $multiples = 6;
    $total_products = 0;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
        if ( isset( $value[ 'stamp' ] ) && ! isset( $value[ 'bundled_by' ] ) ) {
            continue; // skip the bundle container
        } else {
            $total_products += $values['quantity'];
        }
    }
    if ( ( $total_products % $multiples ) > 0 )
        wc_add_notice( sprintf( __('You need to buy in quantities of %s products', 'woocommerce'), $multiples ), 'error' );
}
0
votes

I was having issues with this until I realised I needed to use WC()->cart->get_cart_contents_count() rather than WC()->cart->cart_contents_count

Just thought I'd put this here in case anyone else was pulling their hair out...