Actually a really common case, I thought. But out-of-the-box WooCommerce Subscription does not support this feature of having only one active subscription. So we need to do it manually. I hope you have some experience with WooCommerce and programming. If not maybe you ask a friend to assist you.
So we will now add something to the functions.php of the currently active theme, which should be a child-theme. (If not read about child-themes on WordPress first).
add_filter('woocommerce_add_to_cart_validation', 'check_num_of_subscriptions', 10, 2); function check_num_of_subscriptions($valid, $product_id) { $product_to_add = wc_get_product($product_id); if ($product_to_add instanceof WC_Product_Subscription || $product_to_add instanceof WC_Product_Variable_Subscription) { // alternative use: $has_sub = wcs_user_has_subscription( '', '', 'active' ); if (has_active_subscription()) { // cart validation must fail, because user is not allowed to have multiple subscriptions return false; } else { return true; } } return $valid; } function has_active_subscription() { $user_id = get_current_user_id(); $active_subscriptions = get_posts(array( 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => $user_id, 'post_type' => 'shop_subscription', 'post_status' => 'wc-active' )); if (!empty($active_subscriptions)) return true; else return false; }
Ok what does this ?
Okay, so add_filter
is a given function that allows us to inject code into the WordPress system. As you can see it has 4 Parameter. Interesting for us are the first two. The first one is the hookname, in this case woocommerce_add_to_cart_validation
. This hook fires and event every time the user wants to add a certain product to the shopping cart. We can register to a hook and when this event is fired the function that we set as the second parameter is called. So check_num_of_subscriptions
(name is given by us).
Depending on the hookname our function will get different parameters. This you can find in the documentation of the Plugin, WooCommerce or WordPress.
Here we get $valid
and $product_id
. So with this product id we check if the product that the user wants to add is a subscription product. If it is a regular product we don't care, but if its a subscription product we now need to check if this user already has active subscriptions.
To do this I encapsulated this functionality in a new function - has_active_subscription()
. We check if the user has active subscriptions with the given function get_posts(..)
and we filter for user_id
, shop_subscription
and wc-active
. Thats it we return the result and its done.
However you might want to add a notice to the user that he can understand why the product could not be added to the shopping cart. You want to add this directly above the like with the return false;
so:
wc_add_notice( 'You can have only one active subscription.', 'notice' ); return false;
Hi, I stumbled across your post and I can’t seem to work it out.
Are any of the arrays you listed specific to your site that I might need to change? Any help would be appreciated. Thank you!
As far as I remember I just had WooCommerce and Subscriptions plugin installed.
maybe its something with `post_type` or `meta_key`
Hello, thank you for this article!
That’s what I was really looking for! Worked perfectly!
I have a question…
Is it possible to limit this function to a given category?
For example I have the below subscription categories:
– Lens (subscription)
– Mount Adapter (subscription)
I wanted to put this function only in the Lens category.
Kind regards.
If you adjust the functions `has_active_subscription()` so that it returns TRUE only when it has no active Subscription for this category it will work.
1. get category of the current product form `$product_to_add` and store it in `$cat_for_curr_prod`
2. call `has_active_subscription($cat_for_curr_prod)` so that you add the current cat to the fuction call.
3. in the `has_active_subscription($current_cat)` function you somehow need to check if there is an existing subscription that has `$current_cat` … if so … return false …. else … return true.
Hello Robin Henniges.
Sorry for the delay to answer.
Many thanks for the feedback!
I tried several times here but I could not put it to work …
Excuse me, would you be able to send me the source with the category limit function?
Kind regards.