phpwordpresspluginslearndash

Sync lesson completion status across all courses in LearnDash


My LearnDash plugin is configured to have shared course steps, so that I can use the same lessons across multiple courses. However, if a users marks a lesson as complete or incomplete in one particular course, it is not reflected across all courses (default setting). I want to make it such that any change in the completion status of a shared lesson is reflected across all courses containing that lesson.

This is the code that I used to achieve the desired result, but it always results in a critical error.

function sync_lesson_completion($lesson_id, $user_id, $course_id) {
    // Get the course that contains the lesson
    $course = get_post($course_id);
    
    // Check if the course has shared steps enabled
    $shared_steps_enabled = get_post_meta($course_id, '_sfwd-courses_sharedsteps_enabled', true);
    
    // Check if shared steps are enabled and the lesson is shared
    if ($shared_steps_enabled && !empty($lesson_id)) {
        // Get all the courses where the lesson is shared
        $shared_courses = learndash_get_courses_by_step($lesson_id, 'sfwd-lessons');
        
        // Loop through the shared courses
        foreach ($shared_courses as $shared_course_id) {
            // Skip the current course
            if ($shared_course_id == $course_id) {
                continue;
            }
            
            // Mark the lesson as completed for the user in the shared course
            learndash_update_user_activity($user_id, $lesson_id, 'sfwd-lessons', $shared_course_id, true);
        }
    }
}

// Hook into the lesson completion action
add_action('learndash_lesson_completed', 'sync_lesson_completion', 10, 3);

What am I doing wrong and how do I achieve the desired result?


Solution

  • There were a few issues with the code, but I needed something similar so I worked through your code and updated it. It now works.

    function nzf_sync_lesson_completion($lesson_data) {
      // Get the course that contains the lesson
      $lesson_id = $lesson_data['lesson']->ID;
      $course_id = $lesson_data['course']->ID;
      $user_id = $lesson_data['user']->ID;
    
      // Check if Learndash shared steps is enabled
      $shared_steps_enabled = learndash_is_course_shared_steps_enabled ();
    
      // Check if shared steps are enabled and the lesson exists
      if ($shared_steps_enabled && !empty($lesson_id)) {
        // Get all the courses where the lesson is shared
        $shared_courses = learndash_get_courses_for_step($lesson_id, true);
        
        // Loop through the shared courses
        foreach ($shared_courses as $shared_course_id => $value) {
            // Skip the current course
            if ($shared_course_id == $course_id) {
                continue;
            }
            
            // Mark the lesson as completed for the user in the shared course
            custom_learndash_mark_lesson_complete($shared_course_id, $lesson_id, $user_id);
        }
      }
    }
    add_action('learndash_lesson_completed', 'nzf_sync_lesson_completion', 10, 1);
    

    Here is the custom function to mark a lesson complete:

    function custom_learndash_mark_lesson_complete($id, $lesson_id, $user_id)
    {
      //retreive current course progress
      $user_progress['course'][$id] = learndash_user_get_course_progress($user_id, $id, 'legacy');
    
      if (isset($user_progress['course'][$id]['lessons'])) {
    
        //update lessons progress to complete
        $user_progress['course'][$id]['lessons'][$lesson_id] = 1;
    
      }
    
      $processed_course_ids = [];
    
      if ((isset($user_progress['course'])) && (!empty($user_progress['course']))) {
    
        $usermeta        = get_user_meta($user_id, '_sfwd-course_progress', true);
        $course_progress = empty($usermeta) ? [] : $usermeta;
    
        $course_changed = false; // Simple flag to let us know we changed the quiz data so we can save it back to user meta.
    
        foreach ($user_progress['course'] as $course_id => $course_data_new) {
    
            $processed_course_ids[intval($course_id)] = intval($course_id);
    
            if (isset($course_progress[$course_id])) {
                $course_data_old = $course_progress[$course_id];
            } else {
                $course_data_old = [];
            }
    
            $course_data_new = learndash_course_item_to_activity_sync($user_id, $course_id, $course_data_new,
                $course_data_old);
    
            $course_progress[$course_id] = $course_data_new;
    
            $course_changed = true;
        }
    
        if (true === $course_changed) {
            update_user_meta($user_id, '_sfwd-course_progress', $course_progress);
        }
      }
    
      if (!empty($processed_course_ids)) {
        foreach (array_unique($processed_course_ids) as $course_id) {
            learndash_process_mark_complete($user_id, $lesson_id, true, $course_id);
            learndash_update_group_course_user_progress($course_id, $user_id);
        }
      }
    }