I got four giftboxes. The customer can only put products tagged with fits-in-giftbox
into them. The boxes have space for 4, 9, 16 or 24 pieces. All other products will be packed separately.
I need to count how many times each of these boxes have been added to cart and calculate the total number of pieces they can fit.
I then need to calculate how many fits-in-giftbox
tagged products the customer adds to their cart and match that number with how many pieces all giftboxes can hold.
Example: Customer puts one box-4 (holds 4 products) and one box-24 (holds 24 products) in the cart. In total, the customer can now add 28 products tagged with fits-in-giftbox.
Customer adds 18 products tagged with fits-in-giftbox
. There are now 10 pieces left.
Expected output: "You have added three (3) giftboxes to your cart. Please add an additional XX products to fill your boxes."
OR: "You have added two (2) giftboxes which can hold 8 pieces. You have added 12 products to your cart. The exceeding four (4) products will be packed separately unless you add another giftbox to your cart."
OR: "You have added one giftbox to your cart but no giftbox products. Unless you do, these products will be packed separately."
I hope this makes sense. Feels like I am going in circles here..
This is the code I need help with:
function product_tag_count( $term ) {
$tag_count = 0;
foreach( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( $term, 'product_tag', $cart_item['product_id'] ) )
$tag_count += $cart_item['quantity'];
}
return $tag_count == 0 ? false : $tag_count;
}
function display_cart_counters() {
ob_start();
$link = wc_get_checkout_url();
$title = __( 'Checkout and Pay', 'woocommerce' );
$tag_count = __( '0 products', 'woocommerce');
echo '<a class="product-cart-count" href="' . $link . '" title="' . $title . '">' . $tag_count . '</a>';
return ob_get_clean();
}
add_filter( 'woocommerce_add_to_cart_fragments', 'counters_add_to_cart_fragment', 30, 1 );
function counters_add_to_cart_fragment( $fragments ) {
ob_start();
// count the number of giftboxes
$giftbox4 = 'giftbox-4';
$fits_in_giftbox4 = '4';
$count_giftbox4 = product_tag_count( $giftbox4 );
$giftbox9 = 'giftbox-9';
$fits_in_giftbox9 = '9';
$count_giftbox9 = product_tag_count( $giftbox9 );
$giftbox16 = 'giftbox-16';
$fits_in_giftbox16 = '16';
$count_giftbox16 = product_tag_count( $giftbox16 );
$giftbox24 = 'giftbox-24';
$fits_in_giftbox24 = '24';
$count_giftbox24 = product_tag_count( $giftbox24 );
// get the total number of giftboxes
$count_giftboxes_total = ( $count_giftbox4 + $count_giftbox9 + $count_giftbox16 + $count_giftbox24 );
// count how many products that fits into giftboxes
$fits_in_giftbox = 'goes-into-box';
$count_fits_in_giftbox = product_tag_count( $fits_in_giftbox );
// count the cart as a whole
$cart_count = WC()->cart->get_cart_contents_count();
// calculate the difference between cart as a whole and giftbox products
$difference_between_cart_and_giftbox_products = ( $cart_count - $count_fits_in_giftbox );
// calculate boxes VS giftbox products
$fits_into_boxes_vs_giftbox_products = ( $count_giftboxes_total - $count_fits_in_giftbox );
// this is what I need help with.. how do I get the total pieces of all boxes added to cart?
// first check, is there space left or not?
if ( $count_giftboxes_total < $count_fits_in_giftbox ) {
$output = sprintf (_n( 'You have %d product to much. This will be packed separately unless you add another giftbox.', 'You have %d products to many. These will be packed separately unless you add another giftbox.' ), 'woocommerce');
} elseif () {
$output = sprintf (_n( 'You have %d product to much. This will be packed separately unless you add another giftbox.', 'You have %d products to many. These will be packed separately unless you add another giftbox.' ), 'woocommerce');
} elseif () {
$output = sprintf (_n( 'You have %d product to much. This will be packed separately unless you add another giftbox.', 'You have %d products to many. These will be packed separately unless you add another giftbox.' ), 'woocommerce');
} else {
$output = sprintf (_n( 'You have %d product to much. This will be packed separately unless you add another giftbox.', 'You have %d products to many. These will be packed separately unless you add another giftbox.' ), 'woocommerce');
}
$checkout_link = wc_get_checkout_url();
$link_title = __( 'Go to Checkout', 'woocommerce' );
?>
<div class="product-wrapper">
<?php echo $output; ?>
<br>
<a class="product-cart-count" href="<?php echo $link; ?>"
title="<?php echo $title ?>">Go to Checkout & Pay</a>
</div>
<?php
$fragments['a.product-cart-count'] = ob_get_clean();
return $fragments;
}
add_action( 'woocommerce_before_shop_loop', 'count_products_and_boxes');
add_action( 'woocommerce_before_add_to_cart_form', 'count_products_and_boxes');
function count_products_and_boxes() {
echo display_cart_counters();
}
This will adjust the message based on the number of giftboxes in cart and the number of products they can contain. Messages are changed:
Note that I used the product ID for the 4 giftboxes, otherwise you'll make it unnecessarily complicated.
function display_cart_counters() {
// Settings
$term = 'fits-in-giftbox';
$taxonomy = 'product_tag';
// Giftbox IDs. Important, these should not contain the term 'fits-in-giftbox' !!
// Contents => Product ID
$giftbox_ids = array(
4 => 218,
9 => 220,
16 => 813,
24 => 815
);
// Initialize
$count_fits_in_giftbox = 0;
$count_giftboxes = 0;
$count_giftboxes_total = 0;
$count_not_term = 0;
$message = '';
// True
if ( WC()->cart ) {
// Loop trough cart items quantities
foreach( WC()->cart->get_cart_item_quantities() as $product_id => $cart_item_quantity ) {
// Contains the definite term
if ( has_term( $term, $taxonomy, $product_id ) ) {
// Add the cart item quantity from this certain product to the counter
$count_fits_in_giftbox += $cart_item_quantity;
// The box ID is in the cart
} elseif( in_array( $product_id, $giftbox_ids ) ) {
// Add 1 * cart item quantity to counter
$count_giftboxes += 1 * $cart_item_quantity;
// Add contens * the cart item quantity to the counter
$count_giftboxes_total += ( array_search ( $product_id, $giftbox_ids ) * $cart_item_quantity );
// Does not contain the particular term and is not a gift box
} else {
// Add the cart item quantity from this certain product to the counter
$count_not_term += $cart_item_quantity;
}
}
}
// Singular or plural
$s_o_p_giftbox = _n( '%d giftbox', '%d giftboxes', $count_giftboxes, 'woocommerce' );
$s_o_p_product = _n( '%d product', '%d products', $count_fits_in_giftbox, 'woocommerce' );
// Additional message for untagged products
if ( $count_not_term >= 1 ) {
$untagged_product_message = ' You also added %s untagged products, these will be packaged separately.';
} else {
$untagged_product_message = '';
$count_not_term = '';
}
// When the cart contains products, but no giftbox(es)
if ( $count_giftboxes == 0 && $count_fits_in_giftbox >= 1 ) {
$message = sprintf(
__( 'You have added ' . $s_o_p_giftbox . ' to your cart but ' . $s_o_p_product . '. Unless you do, these products will be packed separately.' . $untagged_product_message . '', 'woocommerce' ),
$count_giftboxes,
$count_fits_in_giftbox,
$count_not_term
);
// When the cart contains giftbox(es), but no products
} elseif ( $count_giftboxes >= 1 && $count_fits_in_giftbox == 0 ) {
$message = sprintf(
__( 'You have added ' . $s_o_p_giftbox . ' to your cart but no giftbox products. Unless you do, these products will be packed separately.' . $untagged_product_message . '', 'woocommerce' ),
$count_giftboxes,
$count_not_term
);
// When there are more products in cart than giftboxes can contain
} elseif( $count_giftboxes_total < $count_fits_in_giftbox ) {
$message = sprintf(
__( 'You have added ' . $s_o_p_giftbox . ' which can hold %d pieces. You have added ' . $s_o_p_product . ' to your cart. The exceeding %d products will be packed separately unless you add another giftbox to your cart.' . $untagged_product_message . '', 'woocommerce' ),
$count_giftboxes,
$count_giftboxes_total,
$count_fits_in_giftbox,
$count_fits_in_giftbox - $count_giftboxes_total,
$count_not_term
);
// When there are less products in cart than giftboxes can contain
} elseif( $count_giftboxes_total > $count_fits_in_giftbox ) {
$message = sprintf(
__( 'You have added ' . $s_o_p_giftbox . ' which can hold %d pieces. You have added ' . $s_o_p_product . ' to your cart. Please add an additional %d products to fill your boxes.' . $untagged_product_message . '', 'woocommerce' ),
$count_giftboxes,
$count_giftboxes_total,
$count_fits_in_giftbox,
$count_giftboxes_total - $count_fits_in_giftbox,
$count_not_term
);
}
return $message;
}
// Refreshing on cart ajax events
function filter_woocommerce_add_to_cart_fragments( $fragments ) {
$fragments['div.display-cart-counters'] = '<div class="display-cart-counters">' . display_cart_counters() . '</div>';
return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'filter_woocommerce_add_to_cart_fragments', 10, 1 );
// Display message via the desired hooks
function display_message() {
echo '<div class="display-cart-counters">' . display_cart_counters() . '</div>';
}
add_action( 'woocommerce_before_shop_loop', 'display_message', 10, 0 );
add_action( 'woocommerce_before_add_to_cart_form', 'display_message', 10, 0 );