WooCommerce Memberships: Restricting Content

Shortcode [wcm_restrict]

The easiest way to restrict content is with the help of WooCommerce Memberships shortcodes. The advantage of this method is that you can use it in your content editor in WordPress admin and directly in the code as well. In the post editor it will look like this:

We begin with the public content.

[wcm_restrict]
This text or HTML is available for members with any active plan.
[/wcm_restrict]

This content is availale for everyone again.

How to implement the same in the code? Easily-breezy — with the standard WordPress do_shortcode() function.

echo do_shortcode( 'We begin with the public content. [wcm_restrict]This text or HTML is available for members with any active plan.[/wcm_restrict] This content is availale for everyone.');

The shortcode has some useful parameters as well, I will describe them in a second.

Allow to view the content for users with specific active plans

We begin with the public content.

[wcm_restrict plans="premium_silver, premium_gold"]
This piece of content is only visible to premium members with premium_silver or premium_gold active plans
[/wcm_restrict]

This content is availale for everyone again.

plans parameter accepts plan IDs, plan slugs (multiple comma-separated plans are allowed).

Delayed access

[wcm_restrict delay="5 week"]
This piece of content will be available for any active plan users after 5 weeks they've registered.
[/wcm_restrict]

You can also pass to this parameter such time values as 20 days, 3 weeks, 1 month, 2 years.

But it also can accept the exact date parameter. In fact it understands several date formats but my recommendation is the ISO (yyyy-mm-dd), like in the example below:

[wcm_restrict delay="2017-05-25"]
This piece of content will be available for any active plan users at May 25, 2017
[/wcm_restrict]

Start after trial

I think everything should be clear with start_after_trial shortcode parameter:

[wcm_restrict start_after_trial="yes"]
This piece of content will be available to any plan members when their membership moves from "Free Trial" to "Active" status.
[/wcm_restrict]

The only thing that needs proper understanding is using both delay and start_after_trial parameters in the same shortcode:

[wcm_restrict delay="5 days" start_after_trial="yes"]
This piece of the content will be available for all members 5 days after their trial period ends
[/wcm_restrict]

wc_memberships_restrict()

wc_memberships_restrict( $content, $membership_plans = null, $delay = null, $exclude_trial = false )
$content
(string) Piece of text or HTML code you would like to restrict.
$membership_plans
(int|string|array) Membership plan ID, slug or an array of ID or slugs for multiple plans.
$delay
(string) Time delay in content access after the user membership plan becomes active. Accepts time values like 2 months, 5 days, 1 year or the exact date like 2017-05-02 (yyyy-mm-dd — recommended) or May 2, 2017.
$exclude_trial
(bool) If true — the content is restricted for trial members.

Let’s look at the example with all the parameters in one place:

$content = 'This is the piece of content, we would like to restrict.';
wc_memberships_restrict( $content, array( 5101, 'premium_gold' ), '1 week', true );

Now let me explain: in the above example we have a piece of content, and only non-trial users with the membership plan with id 5101 or with the plan premium_gold can access it after 1 week their membership become active.

If user doesn’t have this membership, function returns nothing. If a user membership is in the trial period (or one week has not passed yet), the function prints the message that the content is the part of user’s membership but not yet — and this message can be customized with the wc_memberships_get_content_delayed_message filter.

Conditional Functions

wc_memberships_is_user_active_member()

This is a very simple conditional function and it is similar to wc_memberships_is_user_member(), the only difference is that it returns true for active memberships only (trial users are also included).

wc_memberships_is_user_active_member( $user_id = null, $plan )
$user_id
(int) By default — current user.
$plan
(int|string|object) Membership Plan slug, post object or its post ID
if( wc_memberships_is_user_active_member( null, 'premium_gold' ) ) {
	// do stuff for the current user with active "premium_gold" plan (even in trial period)
} 

wc_memberships_user_can()

This is the only standard WooCommerce Memberships function that allows you to check easily if user can view a specific post, page, product or another custom post type element. This function can be used to check if the user can buy a specific product as well.

wc_memberships_user_can( $user_id, $action, $target, $when = '' )
$user_id
(int) User ID is required, you can pass the current user ID by the get_current_user_id() function.
$action
(int|string) Only one of the following values view or purchase (products only).
$target
(array) Currently this parameter supports only a simple array like array( 'post' => id ) — for any custom post types except product or array( 'product' => id ) — for products only (do not forget to replace ‘id’ with the actual value of the post/product ID).
$when
(int|string) UTC timestamp to compare for content access (defaults to now)

And the example:

if( wc_memberships_user_can( get_current_user_id(), 'view' , array( 'post' => 32 ) ) ) {
	echo 'Yes'; // Yes - the current user can view the post/page/product with ID 32
} else {
	echo 'No';
}

current_user_can() / user_can()

wc_memberships_user_can() function is great, but you can do completely the same with already familiar (I hope ?) functions like current_user_can() and user_can().

Let me show you an example – let’s check if the current user can view a post with a certain ID.

if( current_user_can( 'wc_memberships_view_restricted_post_content', $post_id ) ) {
	// show content
}

But you can also do this check for any user, just pass a user ID as a first function parameter.

if( user_can( $user_id, 'wc_memberships_view_restricted_post_content', $post_id ) ) {
	// show content
}

Restricted Taxonomy Access

Currently I know only one working way to check if a user can view restricted taxonomy term content or not.

if( current_user_can( 'wc_memberships_view_restricted_taxonomy_term', 'category', $term_id ) ) {
	// show something
}

Do not forget to replace the second parameter category with you custom taxonomy name if you are going to use it for taxonomy terms. You can also use user_can() function to restrict content for a certain user.

Previously I used the function below to check this, but it has stopped working in the latest WooCommerce Memberships version. I just leave it here in case you need it.

/**
@param int $user_id Default: Current User 
@param string $taxonomy Taxonomy name
@param int $term_id

@return bool true if user can view the specific taxonomy term, false - otherwise
*/
if( function_exists( 'wc_memberships' ) ) {
	function rudr_if_user_can_view_term( $user_id = null, $taxonomy, $term_id ) {
	
		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}

		if ( ! $user_id ) {
			return null;
		}
		
		$r = wc_memberships()->get_rules_instance()->get_taxonomy_term_content_restriction_rules( $taxonomy, $term_id );
		return wc_memberships()->get_rules_instance()->user_has_content_access_from_rules( $user_id, $r, $term_id );
	}
}

And this is how to use it:

if( rudr_if_user_can_view_term( null, 'category', 30 ) ) {
	// do stuff if current user can view category with ID 30
}

If you have any question or recommendation to this post, I will be glad to have a conversation with you in comments below.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X