Here is a complete solution that will display custom notices when normal products count doesn't match with subscription plans, warning the customer lightly. If products doesn't match your requirements, the customer will be redirected from checkout to shop page (avoiding checkout).
The code (commented):
// Replacing add to cart button link on shop and archives
add_filter( 'woocommerce_loop_add_to_cart_link', 'replacing_add_to_cart_button', 10, 2 );
function replacing_add_to_cart_button( $button, $product ) {
if( $product->is_type( 'variable-subscription' ) || $product->is_type( 'variable' ) ) return $button;
$button_text = __( 'View product', 'woocommerce' );
$button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
return $button;
}
// Counting cart items (utility function)
function counting_cart_items( $subscriptions_count = 0, $products_count = 0, $wc_cart = '' ) {
$cart_obj = $wc_cart != '' ? $wc_cart : WC()->cart;
foreach( $cart_obj->get_cart() as $cart_item ){
if ( $cart_item['data']->is_type( 'subscription' ) )
$subscriptions_count += intval( $cart_item['quantity'] );
else
$products_count += intval( $cart_item['quantity'] );
}
return array( 'subscrip' => $subscriptions_count, 'product' => $products_count );
}
// Displaying Notification messages (utility function)
function conditionally_display_notice( $subscriptions_count, $products_count ) {
$count = $subscriptions_count - $products_count;
if( $subscriptions_count < $products_count )
$txt = sprintf( _n( '%s subscription plan', '%s subscriptions plans', -$count, 'woocommerce' ), -$count );
elseif( $subscriptions_count > $products_count )
$txt = sprintf( _n( '%s product', '%s products', $count, 'woocommerce' ), $count );
if( $subscriptions_count != $products_count )
wc_add_notice( sprintf( __( "You need to add %s, to be able to checkout", "woocommerce" ), $txt ), "notice" );
}
// Checking and notifying when products are added to cart
add_filter( 'woocommerce_add_to_cart_validation', 'conditionally_check_add_to_cart', 10, 3 );
function conditionally_check_add_to_cart( $passed, $product_id, $quantity ) {
$items_count = counting_cart_items(); // Counting cart items
$product = wc_get_product( $product_id ); // Get an instance of the WC_Product object
// Get the total live count
if( $product->is_type( 'subscription' ) )
$items_count['subscrip'] += intval( $quantity );
else
$items_count['product'] += intval( $quantity );
// Notification messages
conditionally_display_notice( $items_count['subscrip'], $items_count['product'] );
return $passed;
}
// Conditionally checking and adding your subscription when a product is added to cart
add_action( 'woocommerce_before_main_content', 'display_notice_on_shop_archives' );
function display_notice_on_shop_archives( ) {
if( is_product() ) return;
$items_count = counting_cart_items(); // Counting cart items
// Notification messages
conditionally_display_notice( $items_count['subscrip'], $items_count['product'] );
wc_print_notices();
}
/*
// Conditionally checking and adding your subscription when a product is added to cart
add_action( 'woocommerce_add_to_cart', 'conditionally_check_add_to_cart', 10, 6 );
function conditionally_check_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
$items_count = counting_cart_items(); // Counting cart items
$product = wc_get_product( $product_id ); // Get an instance of the WC_Product object
// Get the updated count
if( $product->is_type( 'subscription' ) )
$items_count['subscrip'] += intval( $quantity );
else
$items_count['product'] += intval( $quantity );
// Notification messages
conditionally_display_notice( $items_count['subscrip'], $items_count['product'] );
}
*/
// Checking and validating when updating cart item quantities
add_filter( 'woocommerce_update_cart_validation', 'conditionally_check_cart_update', 10, 4 );
function conditionally_check_cart_update( $passed, $cart_item_key, $values, $updated_quantity ) {
$items_count = counting_cart_items(); // Counting cart items
// Get the updated count
if( $values['data']->is_type( 'subscription' ) )
$items_count['subscrip'] += intval( -$values['quantity'] + $updated_quantity );
else
$items_count['product'] += intval( -$values['quantity'] + $updated_quantity );
// Notification messages
conditionally_display_notice( $items_count['subscrip'], $items_count['product'] );
return $passed;
}
// Checking and validating when updating cart item quantities
add_filter( 'woocommerce_cart_item_removed', 'conditionally_check_removed_cart_item', 10, 2 );
function conditionally_check_removed_cart_item( $cart_item_key, $wc_cart ) {
$items_count = counting_cart_items( 0, 0, $wc_cart ); // Counting cart items
// Notification messages
conditionally_display_notice( $items_count['subscrip'], $items_count['product'] );
}
// Checking and conditionally redirecting to shop page
add_action( 'template_redirect', 'conditional_checkout_redirection');
function conditional_checkout_redirection(){
if ( is_checkout() ) {
$items_count = counting_cart_items(); // Counting cart items
if ( $items_count['subscrip'] != $items_count['product']) {
// redirecting to shop page
wp_redirect( get_permalink( woocommerce_get_page_id( 'shop' ) ) );
exit(); // always exit
}
}
}
code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works