I'm doing work for a non-profit where people can order informational pamphlets from them. The pamphlets can be ordered individually or as a pack. The pack is set up as one product with id 1076
.
When a customer orders the pack, they can only order the pack on its own.
The code I have clears the cart of any other products and leaves just the pack when the pack is added to the cart. It then disables the Add to Cart button for all products when the pack is in the cart. And finally it changes the popup error message when people click on the greyed out Add to Cart button.
How do I ensure that wc_print_notice()
only outputs a notice in cart page just once?
Here's the code I have so far (it's been cobbled together from several sources so it's probably inefficient)
// Remove conditionally cart items based on a specific product (item)
function remove_cart_items_conditionally( $cart ) {
// HERE define your specific product ID
$specific_product_id = 1076;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$cart_items = $cart->get_cart(); // Cart items array
$items_count = count($cart_items); // Different cart items count
// Continue if cart has at least 2 different cart items
if ( $items_count < 2 )
return;
$last_item = end($cart_items); // Last cart item data array
$is_last_item = false; // Initializing
// Check if the specific product is the last added item
if ( in_array($specific_product_id, array( $last_item['product_id'], $last_item['variation_id'] ) ) ) {
$is_last_item = true;
}
// Loop through cart items
foreach ( $cart_items as $cart_item_key => $cart_item ) {
// Remove all others cart items when specific product ID is the last added to cart
if ( ! in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) && $is_last_item ) {
$cart->remove_cart_item( $cart_item_key );
wc_print_notice( 'Individual resources have been removed as the full pack already contains all the resources', 'notice' );
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'remove_cart_items_conditionally', 10, 1 );
// Disable the add to cart button if specified product is in the cart
function disable_add_to_cart_if_product_is_in_cart ( $is_purchasable, $product ){
$specific_product_id = 1076;
// Loop through cart items checking if the product is already in cart
foreach ( WC()->cart->get_cart() as $cart_item ){
if ( in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
return false;
}
}
return $is_purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'disable_add_to_cart_if_product_is_in_cart', 10, 2 );
// Change disabled add to cart button popup message to something relevant
function customizing_product_variation_message( $translated_text, $untranslated_text, $domain )
{
if ( in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
if ($untranslated_text == 'Sorry, this product is unavailable. Please choose a different combination.') {
$translated_text = __( 'The full pack in the cart already contains this resource', $domain );
}
}
return $translated_text;
}
add_filter( 'gettext', 'customizing_product_variation_message', 10, 3 );
my code is made from this answer threads:
Remove conditionally Woocommerce cart items based on a specific product
Disable Woocommerce add to cart button if the product is already in cart
Customizing product variations message on single product pages