• Resolved sdwarwick

    (@sdwarwick)


    I have wanted to re-direct folks after the last lesson in a course to the course overview page. This has turned out to be more complicated than I thought, so here is a short writeup on how I did it. This requires adding custom functions in your functions.php file and I use a “meta” tag on the final lesson to indicate where I want to jump to after the lesson has been marked complete. It would be really, really nice if I didn’t have to go through all of this to do something this simple.

    1) use the action ‘lifterlms_after_mark_complete_lesson’ to add a small script after the form that changes the post variable “mark-complete”, I change it to ‘custom-mark-complete’ by injecting the following script:

    
    add_action('lifterlms_after_mark_complete_lesson', 'customizeForm');  
    function customizeForm()
    {
     echo '<script> 
            formtype = document.getElementsByName("mark-complete");
    	formtype[0].setAttribute("name", "custom-mark-complete"); 
    	</script>';
    
    return;
    }
    

    2) then, I copied your entire mark-complete function into my own functions.php file, change the name and add it as an action that runs before your current mark-complete function: I make a few changes..

    – I check if it is a custom-mark-complete first to avoid triggering the nonce

    – After the lesson has been marked complete, I add a check for a meta value associated with the lesson. I’ve defined the meta value as redirectAfterMarkComplete which will hold the value of where I want to redirect as a URL.

    5) if this meta value exists, it overrides all other processing and jumps there.

    this fixes the basic problem for the case where the next-lesson doesn’t exist.
    a far better solution would be for you to define a hook for the case where next-lesson doesn’t exist

    
    
    add_action( 'init', 'custom_mark_complete' ,5 );  // run this before the regular mark_complete
    
    function custom_mark_complete() {
    	
    		$request_method = strtoupper( getenv( 'REQUEST_METHOD' ) );
    		if ( 'POST' !== $request_method ) {
    			return;
    		}
    
    		// required fields
    		if ( ! isset( $_POST['custom-mark-complete'] ) ) {
    			return;
    		}
    		
    		// verify nonce
    		if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'mark_complete' ) ) {
    			return;
    		}
    	
    		$lesson_id = absint( $_POST['custom-mark-complete'] );
    		if ( ! $lesson_id || ! is_numeric( $lesson_id ) ) {
    			llms_add_notice( __( 'An error occurred, please try again.', 'lifterlms' ), 'error' );
    		} else {
    
    			if ( llms_mark_complete( get_current_user_id(), $lesson_id, 'lesson', 'lesson_' . $lesson_id ) ) {
    
    				llms_add_notice( sprintf( __( 'Congratulations! You have completed %s', 'lifterlms' ), get_the_title( $lesson_id ) ) );
    
    				if ( apply_filters( 'lifterlms_autoadvance', true ) ) {
    									
    					$redirectValue = get_post_meta( $lesson_id, 'redirectAfterMarkComplete', true );   // this checks to see if there is a special redirect defined
    				
    					if ($redirectValue) {   // if so,  go there!
    							wp_redirect( $redirectValue);
    							exit;
    					}
    					
    					$lesson = new LLMS_Lesson( $lesson_id );  // else go to next lesson as planned
    					$next_lesson_id = $lesson->get_next_lesson();
    					if ( $next_lesson_id ) {
    						wp_redirect( apply_filters( 'llms_lesson_complete_redirect', get_permalink( $next_lesson_id ) ) );
    						exit;
    					}
    					
    					
    				}
    
    			}
    
    		}
    
    	}
    
    • This topic was modified 7 years, 7 months ago by sdwarwick.
Viewing 5 replies - 1 through 5 (of 5 total)
  • @sdwarwick,

    I’m sorry that this has been so painful for you and now I understand that the issue is very simply because we have a check in the code that prevents redirects from breaking at the conclusion of a course.

    3.6.2 has a new action after_llms_mark_complete that comes at the end of the mark complete action

    I think the easiest solution given your needs would be to hook into this action and redirect there:

    
    <?php
    add_action( 'after_llms_mark_complete', 'my_llms_custom_complete_redirect', 10, 4 );
    
    function my_llms_custom_complete_redirect( $student_id, $object_id, $object_type, $trigger ) {
    
    	// this action will run when courses, lessons, sections, etc... are completed
    	// since we're only dealing with lessons we'll skip the rest of the function
    	// if the object isn't a lesson
    	if ( 'lesson' !== $object_type ) {
    		return;
    	}
    
    	// this is excerted from the rest of your code
    
    	$redirectValue = get_post_meta( $object_id, 'redirectAfterMarkComplete', true );   // this checks to see if there is a special redirect defined
    
    	if ($redirectValue) {   // if so,  go there!
    		wp_redirect( $redirectValue);
    		exit;
    	}	
    	
    }
    

    This will run before it gets to the redirect function in the mark complete handler function. You can look for you custom meta value here and if there isn’t one let the core function do it’s think.

    Take care,

    Thread Starter sdwarwick

    (@sdwarwick)

    yes, this is all about how “get_next_lesson” works and how you deal with what happens if there isn’t a next lesson.

    I am actually surprised that this is not a very common concern, but so be it.

    I’d be interested in perhaps chatting sometime to discuss the broader use of custom meta variables as an intermediate approach to providing “post level” special processing. I’m using it a lot now.. my “hide mark complete” is activated from a meta variable in the lesson. it seems like a nice low-overhead mechanism for control at the user-interface level. in addition, it doesn’t require tying special processing to a specific post/lesson ID.

    @sdwarwick,

    Please see my edit above!

    Let me remind you that LifterLMS is open-source: https://github.com/gocodebox/lifterlms#contributing

    Take care,

    Thread Starter sdwarwick

    (@sdwarwick)

    I’ve confirmed that this new hook works as desired, thanks for the sample code. for those reading this, please look to using the new hook rather than the workaround as described in the initial post

    @sdwarwick

    You’re welcome

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘Dealing with end-of-course redirect’ is closed to new replies.