Redirecting users from restricted content to login form and back

TLDR;

The whole code is available in a gist here: https://gist.github.com/actual-saurabh/0d5a8ea8d0e90c729a91f86bcf378faf

Requirements

You should be comfortable with copy pasting code and editing some text inside it to be able to use it. This code is theme independent and would work on almost all sites.

Plugin Conflicts

If you have a plugin that extends the login mechanism or post-login redirects, they may interfere with this recipe and it may not work.

That also means that this may not work that well with WooCommerce and you’d need to modify the recipe for that. If you do end up with a recipe for LifterLMS + WooCommerce sites, get in touch with us to publish it here.

Background

When a user lands on a lesson (or another piece of restricted content) on your site, they are either shown a notice or redirected to the course (membership, etc) to buy it and gain access.

This is fine for your prospective members (visitors) but some LifterLMS users find this unsatisfactory for existing members or students.

When students get links to such lessons (restricted content) in an email and click that to reach the lesson, one of two things can happen. If the student is logged in, they’ll see the lesson and things will go on smoothly.

Things are a bit complicated if the student isn’t logged in. There is no way for us to differentiate between anonymous visitors until they login. So, such students (coming from an email) will also be treated like casual visitors.

At this point, a student may not realise what’s going on and attempt to sign up for the course or membership again. That will tell them that they’re already signed up for a course (if they use their registered email address) or create a duplicate sign up (if they use a new email address).

What they need to do is go to the login screen and login. Now, even when the student logs in, they’ll be redirected to the Student Dashboard.

To go back to the lesson (from the email), they would need to open the email again, click on the link again and this time, they’ll be on the lesson as intended by the course creator.

What would have been much easier is if we could do something to the link in the email so that instead of all this, the user was redirected to a login screen and as soon as they login, redirect them back to the lesson seamlessly.

Goals

  • Add a parameter ?login=1 at the end of a restricted URL when adding it to emails intended for registered students who definitely have access when logged in.
  • When such a student clicks this link and lands on the restricted page, redirect them to the login screen.
  • On the login screen, inform the student that they need to login to access the restricted content.
  • After logging in, redirect the user back to the restricted content where they have complete access now.

Here’s a preview of what to expect from this recipe:

Instructions

Planning

  • In the template loader class which handles restrictions, there is a lifterlms_content_restricted action that we can hook into. This way our code is only executed for restricted content.
  • On this hook we check for the custom parameter. If such a parameter isn’t there, we skip the rest of the code and the restriction works according to the settings.
  • If such a parameter is there, we filter the redirection url (llms_restricted_by_{$reason}_redirect) and notice (llms_restricted_by_{$reason}_message).
  • We change the redirection url to the student dashboard (login form) url that we can get from the llms_person_my_courses_url() function.
  • To this url, we add the original restricted content’s permalink as a parameter.
  • On login, we check if this redirection parameter is present and use that to filter the login form redirection (llms_student_dashboard_login_redirect) and take the user to the restricted content instead.

Hook into Restricted Content Action

LifterLMS hooks a method of its LLMS_Template_Loader class into the template_include filter to manage its own template loading and restrictions.

Inside this hook, LifterLMS checks if the page about to be loaded is restricted, and if so, triggers the lifterlms_content_restricted action. At this action hook, a single parameter is passed which is an array of information about the restriction.

array(
	'content_id' => 0,
	'is_restricted' => false,
	'reason' => 'accessible',
	'restriction_id' => 0,
);

The content_id key contains the post ID of the restricted content and the reason which is sufficient for our recipe.

The reason can be any one of the default ones. The thing to note is that the filters for the redirection url and the message displayed in the notice use the reason in a standard naming format.

So, using the reason, we can filter the appropriate message and url.

add_action( 'lifterlms_content_restricted', 'llms_maybe_email_unit_redirect', 10, 1);

function llms_maybe_email_unit_redirect( $restriction ){

	// do nothing in case the ?login parameter isn't set
	if( empty( llms_filter_input( INPUT_GET, 'login' ) ) ){
		return;
	}
	
	// otherwise, filter the restriction
	add_filter( 'llms_restricted_by_' . $restriction['reason'] . '_redirect', 'llms_email_unit_login_redirect', 10, 2 );
	add_filter( 'llms_restricted_by_' . $restriction['reason'] . '_message', 'llms_email_unit_login_message', 10, 2 );
}

Do note that we’re filtering the redirect (and hence overriding any restriction settings) only when there’s a restriction and only when the login parameter is present.

Filtering Redirection URL

Both the redirection url and message filters provide the original value as well as the restriction information.

So, we can get the url of the restricted content using get_permalink() on the content_id key of the restriction info.

Next, we retrieve the dashboard url from the llms_person_my_courses() function and add the url of the original restricted content to a redir parameter.

function llms_email_unit_login_redirect( $url, $restriction ){

	$redirect_back_to = get_permalink( $restriction['content_id'] );
  
	// intercept redirection by sending the dashboard url instead with a redirect paramater
	$url = add_query_arg( array( 'redirect' => esc_url($redirect_back_to) ), llms_person_my_courses_url() );
	
	return $url;
}

If your student dashboard is at https://mysite.com/my-courses/, this new url will look like https://mysite.com/my-courses/?redirect=url/of/the.original/restricted/content/lesson.

Filtering the Restriction Notice

At this point a message is also created that is displayed as a notice to the user. Notices in LifterLMS are persistent across redirects because they use the session object. So, the notice will be displayed no matter what page the user is redirected to next. We’ll use the restriction’s content_id parameter to get the title of the restricted content and add that to a custom message:

function llms_email_unit_login_message( $message, $restriction ){

	return 'Please login to view <em>'. get_the_title( $restriction['content_id'] ) . '</em>.';
}

Handling Login Redirection

This much code will redirect the user to the login form. However, it will not modify where a user is taken to after logging in.

To do that, there is a lifterlms_login_redirect filter but that only works after the user has submitted the form and logged in. By default this redirect url is picked up from a hidden input field in the form.

There is no reliable way to filter what’s displayed in the form. However, since there’s no form action explicitly defined, the form is submitted back to the same url.

This means that on the lifterlms_login_redirect filter, we can check for the redirect parameter that we added to the dashboard url, which is in fact the permalink (url) to the original and use that for the final redirection!

// hook into login form's redirection
add_filter( 'llms_student_dashboard_login_redirect', 'llms_maybe_redirect_to_unit' );

function llms_maybe_redirect_to_unit( $url ){

	// since the login form's action is going to be current url, we can expect it in the querystring if redirection was set.
	$unit_redirect = llms_filter_input( INPUT_GET, 'redirect' );

	// do nothing in case the ?redir_login
  	return empty( $unit_redirect ) ? $url : $unit_redirect;
}

Restriction Bypass?

Do note that if the user doesn’t have access even after logging in (due to drip or because they aren’t enrolled and shouldn’t have been using the link anyway), they will still experience the standard restrictions. So, the link is safe to use!

That’s all the code we need. We can go ahead and implement it!

Implementation

You could use a snippets plugin: https://wordpress.org/plugins/code-snippets/. Also see: https://www.wpbeginner.com/plugins/how-to-easily-add-custom-code-in-wordpress-without-breaking-your-site/.

Or you could place all LifterLMS related customisations into a child theme or custom plugin: https://lifterlms.com/docs/how-do-i-add-custom-code-to-lifterlms-or-lifterlms-launchpad/.

Conclusion

Custom Login Links

With this code, you basically also add the ability to create custom login redirects. Just stick the url you want users to go to after logging in as ?redirect=url/to/redirect/to to the login form url.

Maybe that’s the only useful part of the recipe for you! This sub-recipe could be used creatively to redirect users to different screens in different contexts on loggin in.

Hopefully this recipe turns out to be useful in improving your users’ experience and remove one more friction. Let us know in the comments if you do use it. Feel free to ask any questions too.

Want the functionality, but don’t know code?

Contact your developer or one of the experts here https://lifterlms.com/experts/ with a link to this recipe.

Are you a developer who needs help?

If you are or your client is a premium LifterLMS customer, you can get support from the development team. Otherwise, you could get help from the community on Slack.

Leave a Comment

Your email address will not be published. Required fields are marked *