How to restrict lessons based on EDD variable price with LearnDash

LearnDash and Easy Digital Downloads are a great combination for setting up a course, and are what I ended up using for Making Pro Plugins.

But what if you want to sell tiers or packages of your course, so only certain customers can access certain lessons?  Fortunately this is relatively easy to do with a bit of customization!

Install LearnDash and Easy Digital Downloads

You’ll need to purchase a LearnDash license and also install the free version of Easy Digital Downloads (EDD).

LearnDash also has an EDD integration which you’ll need to install, and once done you’ll see a checkbox in EDD to enrol people who purchase the download into your course:

learndash-easy-digital-downloads

Add a variable price in Easy Digital Downloads

When adding the download via Downloads > Add New, you’ll see a section to enable variable pricing.  Check it and put in the tiers of your course:

easy-digital-downloads-variable-pricing

In my case, the “Starter Package” includes only certain modules, whereas the “Growth Package” includes everything.  So, if the student purchased the Starter Package which is the price ID of 1 (shown on the right), I want to disable access to certain lessons.

Restrict access to lessons based on variable price purchased

There’s no direct way to completely disable the lesson, but what we can do is use the “Make Lesson visible on specific date” field to disable access to the lesson only for students who didn’t purchase the full package:

learndash-lesson-access-fromWe can’t set this to some date in the future manually because it would disable access for everyone.  Instead, we can use the ld_lesson_access_from WordPress filter that LearnDash gives to set it to some date far in the future if a particular student doesn’t have access.

First, we need a function to detect if the customer purchased the higher or lower package.  I’ve named mine mpp_is_growth_package to return true if they did purchase the higher package, and false otherwise:

define( 'MPP_EDD_ITEM_ID', 12 );
define( 'MPP_GROWTH_PACKAGE_PRICE_ID', 2 );
function mpp_is_growth_package() {
	// Assume if this is a manually added person (no purchases) that they have access to everything
	if ( ! edd_count_purchases_of_customer() )
		return true;

	foreach ( edd_get_users_purchases( get_current_user_id(), -1 ) as $post ) {
		foreach( edd_get_payment_meta_cart_details( $post->ID, true ) as $item ) {
			if ( MPP_EDD_ITEM_ID == $item['item_number']['id'] and MPP_GROWTH_PACKAGE_PRICE_ID == $item['item_number']['options']['price_id'] )
				return true;
		}
	}

	return false;
}

Replace 12 in the MPP_EDD_ITEM_ID with the ID of your download, which you can find when you hover over it in the All Downloads listing:

easy-digital-downloads-id

I also added a constant for the price ID of the full package in MPP_GROWTH_PACKAGE_PRICE_ID (which is 2).  Change this if the full-access tier is a different price ID for you.

The function checks if they have any purchases at all. If not, I assume I’ve added the student manually (perhaps to demo it) and will give them full access. Otherwise, I go through all of their purchases and if they bought the growth package (price ID of 2), I return true.

Next, make note the IDs of the lessons that you want to disable access for.  You can find this by going to LearnDash then Lessons, then Edit each of the lessons you want to disable:

learndash-find-lesson-id

For me I want to disable access to those on the Starter Package for lesson IDs of 55, 62 and 170.

We can now use the ld_lesson_access_from filter to set the date to (say) 10,000 days in the future.  This will always be 10,000 days from today so it’ll never hit:

function mpp_set_lesson_access_time( $return, $lesson_id, $user_id ) {
	$growth_package_lesson_ids = array( 55, 62, 170 );
	if ( mpp_is_growth_package() or ! in_array( $lesson_id, $growth_package_lesson_ids ) )
		return $return;

	// access 10000 days in the future
	return current_time( 'timestamp' ) + ( 60 * 60 * 24 * 10000 );
}
add_filter( 'ld_lesson_access_from', 'mpp_set_lesson_access_time', 10, 3 );

Could probably set it to less than 10,000 days, but just to be safe!

This function checks if they have the higher package or this is one of the lessons everyone can access, in which case we just let them have full access. Otherwise, we set the access time in the future, which effectively disables access for them.  A student who has purchased the Starter Package will then see something like this in the lesson listing:

 

learndash-lessons-disabled-by-easy-digital-downloads-variable-price

and also when they try to click on a disabled lesson:

learndash-lesson-disabled

Change the “cannot access” message

While we’ve now disabled access, people might get a little confused that they have to wait until 2044 in order to access the lesson.  We can change that message to something else using the learndash_lesson_available_from_text filter:

function mpp_no_access_message( $content, $post, $lesson_access_from ) {
	return 'Not available in the starter package.';
}
add_filter( 'learndash_lesson_available_from_text', 'mpp_no_access_message', 10, 3 );

You can change this message to whatever you want. Also, you’ll need to copy the templates/course.php file from the LearnDash plugin into learndash/course.php in your child theme, then search for the “Available on:” part (currently line 131) and change it to:

<?php echo apply_filters( 'learndash_lesson_available_from_text', sprintf( __( 'Available on: %s ', 'learndash' ), learndash_adjust_date_time_display($lesson['lesson_access_from'] ) ), $lesson['post'], $lesson['lesson_access_from'] ); ?>

This will then allow the filter we added above to change the text on the lessons listing page.

You’re all set!  Now you can sell two packages of your course and restrict access to certain lessons.