Set the Course Progression conditionally for specific users.

Linear Progression in LearnDash forces users to consume your course content lesson by lesson. They cannot skip through the lessons.

Let’s say you have a course with Linear progression. All enrollees are forced to access the content in this way.

But what if you want to allow a small and specific set of users to hop through the lessons freely?

You can conditionally set the Course Progression to Free Form for some specific users.

Create a Group to hold the ‘Free Form’ allowed users.

Grab the Group ID.

Add any relevant users to the Group.

Grab the Course ID.

Add the following snippet to your theme’s functions.php:

add_filter('learndash_course_progression_enabled', function($setting, $course_id){

return learndash_is_user_in_group(get_current_user_id(), GROUP_ID) && $course_id == COURSE_ID ? false : $setting;

}, 10, 2);

Ensure to replace GROUP_ID with the actual ID of the Group and COURSE_ID with the real ID of the Course you want to apply this condition.

In the logic above, the learndash_course_progression_enabled filter expects a boolean value.

To allow free form, we need to force the returned value to false when the condition matches.

NOTE: It is NOT required to add the Course to the Group.

The Group is used to identify the users who should be allowed free-form progression instead of linear progression.

Check the documentation links below:

Redirect visitors from the course page to the product or landing page in LearnDash

You have a course set to Closed access mode. That means users will purchase the course either through a third-party eCommerce like WooCommerce, or a membership plugin like Paid Memberships Pro.

Sweet.

When a visitor clicks the course from the course list, they are taken to the single course page by default. Then, they click the ‘Take this course’ call to action to go to the purchase page.

Too many steps.

What if you want to cut the process to click the course > go to checkout?

What if you want to prevent visitors from seeing the course content before enrolling?

What if you want both?

You need to redirect the user to the value you set in the Button URL field in your course access mode setting.

But how?

Interestingly, the solution is straightforward. The steps are as follows

  1. Hook into the template_redirect action.
  2. Check if the current post is a course.
  3. Check if the current user is admin. //admin
  4. Check if the current user is not enrolled in the current course.
  5. Retrieve the course options (serialized array).
  6. Check if the access mode is set to Closed.
  7. Check if the Button URL field is not empty.

Now, with the steps defined, let’s get working.

NOTE: You can find the final code here: https://gist.github.com/j2machado/c45e979fca472e8cab2520ec0dce195a

1 – Hook into the template_redirect action.

The template_redirect action is fired before determining which template will be loaded. This is perfect to decide whether to allow the single course page to load, or redirect the user to our specific destination.

Create a function that will hold all the logic for this feature. I’ll call it obi_closed_course_reditect().

function obi_closed_course_reditect(){
//Code will go here

}

Then hook the function into the template_redirect action:

add_action('template_redirect', 'obi_closed_course_redirect');

Good. Your function is now hooked into the template_redirect action. As it doesn’t have any logic yet, nothing will happen.

2 – Check if the current post is a course.

Courses in LearnDash are defined with the ‘swfd-courses’ post type. The get_post_type() function allows you to retrieve the current post’s post type.

Set a conditional to check if the post is not a course. If true, return false.

if( 'sfwd-courses' != get_post_type() ){
     return
}

3 – Check if the current user is admin.

You are only interested in redirecting a user if they are non-logged-in visitors or regular users on your website but have not enrolled in your course yet.

You can achieve this by checking the user by their current capabilities. A unique capability for admins is ‘manage_options’. Then, filter users out like this:

if (current_user_can('manage_options'){
     return
}
if (current_user_can('manage_options'){
     return
}

4 – Check if the current user is not enrolled in the current course.

Give a current enrollee access to the single course page. LearnDash provides a function to check the current user enrollment status: ld_course_check_user_access().

if( ld_course_check_user_access( get_the_ID() , get_current_user_ID() )){
		return;
	}

5 – Retrieve the course options (serialized array).

The course options are stored in the database as metadata of the course post. The relevant meta key is ‘_sfwd-courses’. Use the get_post_meta() function to retrieve the course options and store them in a variable.

$courseOptionsSerialized = get_post_meta( get_the_ID(), '_sfwd-courses', true);

6- Check if the access mode is set to Closed.

The course options are stored in the $courseOptionsSerialized variable as a serialized array.

You can access any option within the array by key. The course access mode is stored in the database as course price type. You can get this value like this

$courseOptionsSerialized[‘sfwd-courses_course_price_type’];.

You can store that value in a variable as well, as follows:

$courseAccessMode = $courseOptionsSerialized['sfwd-courses_course_price_type'];

Then, create a conditional to filter out courses whose access mode is other than Closed.

if($courseAccessMode != "closed"){
		return;
	}

7 – Check if the Button URL field is not empty.

A course access mode can be set to Closed, but the Button URL is empty. Prevent the redirect if the Button URL value is not set.

if($courseProductURL == ""){
		return;
	}

Final Step!

Redirect the user after all conditions have been passed. You can use the wp_safe_redirect() function.

wp_safe_redirect( $courseProductURL );
exit;

You now have a redirection for your courses based on a set of conditions. The redirection works for all courses on your website.

You can find the final code here: https://gist.github.com/j2machado/c45e979fca472e8cab2520ec0dce195a