wordpressfilterhooklearndash

Is there any function in Leandash to mark complete COURSE programmatically


I am working on Leandash Project , Now my requirement is some students have completed the course offline , So I have created a screen for a group leader in which the group leader can select group/user/course and also add date like this ( https://prnt.sc/1bfcq3a ) and can mark complete COURSE.

So my question is how do I mark complete COURSE. programmatically on link click.

here is my code , which is not working

jQuery(document).on('click', '.course_complete_save', function(event) {
    event.preventDefault();

    var selected_group_id = jQuery('#group_name_select_dropdown').val();
    var selected_user_id = jQuery('#user_name_select_dropdown').val();
    var selected_course_id = jQuery('#course_name_select_dropdown').val();
    var mark_complete_date = jQuery('#input_date_field').val();

    var params =  {"mark_complete_date":mark_complete_date,"selected_group_id":selected_group_id,"selected_user_id":selected_user_id,"selected_course_id":selected_course_id,action:"mark_complete_course_ajax"}

    jQuery.post(groupcustomisation.ajaxurl,params,function(data){
        if(data){
            jQuery(".mark_complete_success").empty().append("Mark Completed");
        }else{
            jQuery(".mark_complete_success").empty().append("No data Found");
        }

    });
});


<?php 
add_action('wp_ajax_nopriv_mark_complete_course_ajax', 'mark_complete_course_ajax');
add_action('wp_ajax_mark_complete_course_ajax', 'mark_complete_course_ajax');
function mark_complete_course_ajax() {

    $selected_group_id = $_POST['selected_group_id'];
    $selected_user_id = $_POST['selected_user_id'];
    $selected_course_id = $_POST['selected_course_id'];
    $mark_complete_date = $_POST['mark_complete_date'];

    learndash_process_mark_complete( $selected_user_id, $selected_course_id, true, $selected_course_id );
        
    echo "1";
         
    die();
}

Solution

  • Funny enough, i found myself needing solution to same problem minutes after you posted this yesterday and as you see, that function above failed to work and nothing useful online. In short, i spent the whole day on it trying to find why until i realized all lessons and quiz need to be marked as complete too and after writing the function that do exactly this based on my research on learndash source code as primary source, i decided to come back here and post the function just incase you haven't fix it

    Usage: sci_learndash_mark_course_complete($course_id, $user_id)
    

    Here's the function:

    /**
     * Mark learndash course as complete.
     *
     * @param int $id Course ID.
     * @param int $user_id User ID.
     */
    function sci_learndash_mark_course_complete($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
            $lesson_array                            = $user_progress['course'][$id]['lessons'];
            $lessons                                 = array_flip($lesson_array);
            $lessons                                 = array_fill_keys(array_keys($lesson_array), 1);
            $user_progress['course'][$id]['lessons'] = $lessons;
    
        }
    
    
        //update topics progress to complete
        if (isset($user_progress['course'][$id]['topics'])) {
            foreach($user_progress['course'][$id]['topics'] as $ldtopic_key => $ldtopic){
                if(count($ldtopic) > 0){
                    $new_ldtopic                                 = array_flip($ldtopic);
                    $new_ldtopic                                 = array_fill_keys(array_keys($ldtopic), 1);
                    $user_progress['course'][$id]['topics'][$ldtopic_key] = $new_ldtopic;
                }
            }
        
        }
    
        //update quiz progress to complete
        if (isset($user_progress['quiz'][$id])) {
            $quiz_array                           = $user_progress['course'][$id]['quiz'];
            $quiz                                 = array_flip($quiz_array);
            $quiz                                 = array_fill_keys(array_keys($quiz_array), 1);
            $user_progress['course'][$id]['quiz'] = $quiz;
        }else{
            $quiz_list = [];
            if ( isset($user_progress['course'][$id]['lessons'])  && count($user_progress['course'][$id]['lessons']) > 0 ) {
                $ld_lesson_keys = array_keys($user_progress['course'][$id]['lessons']);
                foreach($ld_lesson_keys as $course_lesson_id){
                        $topic_quizzes = learndash_get_lesson_quiz_list( $course_lesson_id );
                        if (!empty($topic_quizzes)){
                            foreach ($topic_quizzes as $topic_quiz) {
                                $quiz_list[$topic_quiz['post']->ID] = 1;
                            }
                        }
                }
            }
            if (!empty($quiz_list)){
                $user_progress['quiz'][$id] = $quiz_list;
            }
        }
    
        $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 ((isset($user_progress['quiz'])) && (!empty($user_progress['quiz']))) {
    
            $usermeta       = get_user_meta($user_id, '_sfwd-quizzes', true);
            $quizz_progress = empty($usermeta) ? [] : $usermeta;
            $quiz_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['quiz'] as $course_id => $course_quiz_set) {
                foreach ($course_quiz_set as $quiz_id => $quiz_new_status) {
                    $quiz_meta = get_post_meta($quiz_id, '_sfwd-quiz', true);
    
                    if (!empty($quiz_meta)) {
                        $quiz_old_status = !learndash_is_quiz_notcomplete($user_id, [$quiz_id => 1], false, $course_id);
    
                        // For Quiz if the admin marks a qiz complete we don't attempt to update an existing attempt for the user quiz.
                        // Instead we add a new entry. LD doesn't care as it will take the complete one for calculations where needed.
                        if ((bool)true === (bool)$quiz_new_status) {
                            if ((bool)true !== (bool)$quiz_old_status) {
    
                                if (isset($quiz_meta['sfwd-quiz_lesson'])) {
                                    $lesson_id = absint($quiz_meta['sfwd-quiz_lesson']);
                                } else {
                                    $lesson_id = 0;
                                }
    
                                if (isset($quiz_meta['sfwd-quiz_topic'])) {
                                    $topic_id = absint($quiz_meta['sfwd-quiz_topic']);
                                } else {
                                    $topic_id = 0;
                                }
    
                                // If the admin is marking the quiz complete AND the quiz is NOT already complete...
                                // Then we add the minimal quiz data to the user profile.
                                $quizdata = [
                                    'quiz'                => $quiz_id,
                                    'score'               => 0,
                                    'count'               => 0,
                                    'question_show_count' => 0,
                                    'pass'                => true,
                                    'rank'                => '-',
                                    'time'                => time(),
                                    'pro_quizid'          => absint($quiz_meta['sfwd-quiz_quiz_pro']),
                                    'course'              => $course_id,
                                    'lesson'              => $lesson_id,
                                    'topic'               => $topic_id,
                                    'points'              => 0,
                                    'total_points'        => 0,
                                    'percentage'          => 0,
                                    'timespent'           => 0,
                                    'has_graded'          => false,
                                    'statistic_ref_id'    => 0,
                                    'm_edit_by'           => get_current_user_id(), // Manual Edit By ID.
                                    'm_edit_time'         => time(), // Manual Edit timestamp.
                                ];
    
                                $quizz_progress[] = $quizdata;
    
                                if (true === $quizdata['pass']) {
                                    $quizdata_pass = true;
                                } else {
                                    $quizdata_pass = false;
                                }
    
                                // Then we add the quiz entry to the activity database.
                                learndash_update_user_activity(
                                    [
                                        'course_id'          => $course_id,
                                        'user_id'            => $user_id,
                                        'post_id'            => $quiz_id,
                                        'activity_type'      => 'quiz',
                                        'activity_action'    => 'insert',
                                        'activity_status'    => $quizdata_pass,
                                        'activity_started'   => $quizdata['time'],
                                        'activity_completed' => $quizdata['time'],
                                        'activity_meta'      => $quizdata,
                                    ]
                                );
    
                                $quiz_changed = true;
    
                                if ((isset($quizdata['course'])) && (!empty($quizdata['course']))) {
                                    $quizdata['course'] = get_post($quizdata['course']);
                                }
    
                                if ((isset($quizdata['lesson'])) && (!empty($quizdata['lesson']))) {
                                    $quizdata['lesson'] = get_post($quizdata['lesson']);
                                }
    
                                if ((isset($quizdata['topic'])) && (!empty($quizdata['topic']))) {
                                    $quizdata['topic'] = get_post($quizdata['topic']);
                                }
    
                                /**
                                 * Fires after the quiz is marked as complete.
                                 *
                                 * @param arrat $quizdata An array of quiz data.
                                 * @param WP_User $user WP_User object.
                                 */
                                do_action('learndash_quiz_completed', $quizdata, get_user_by('ID', $user_id));
    
                            }
                        } elseif (true !== $quiz_new_status) {
                            // If we are unsetting a quiz ( changing from complete to incomplete). We need to do some complicated things...
                            if (true === $quiz_old_status) {
    
                                if (!empty($quizz_progress)) {
                                    foreach ($quizz_progress as $quiz_idx => $quiz_item) {
    
                                        if (($quiz_item['quiz'] == $quiz_id) && (true === $quiz_item['pass'])) {
                                            $quizz_progress[$quiz_idx]['pass'] = false;
    
                                            // We need to update the activity database records for this quiz_id
                                            $activity_query_args = [
                                                'post_ids'      => $quiz_id,
                                                'user_ids'      => $user_id,
                                                'activity_type' => 'quiz',
                                            ];
                                            $quiz_activity       = learndash_reports_get_activity($activity_query_args);
                                            if ((isset($quiz_activity['results'])) && (!empty($quiz_activity['results']))) {
                                                foreach ($quiz_activity['results'] as $result) {
                                                    if ((isset($result->activity_meta['pass'])) && (true === $result->activity_meta['pass'])) {
    
                                                        // If the activity meta 'pass' element is set to true we want to update it to false.
                                                        learndash_update_user_activity_meta($result->activity_id, 'pass',
                                                            false);
    
                                                        // Also we need to update the 'activity_status' for this record
                                                        learndash_update_user_activity(
                                                            [
                                                                'activity_id'     => $result->activity_id,
                                                                'course_id'       => $course_id,
                                                                'user_id'         => $user_id,
                                                                'post_id'         => $quiz_id,
                                                                'activity_type'   => 'quiz',
                                                                'activity_action' => 'update',
                                                                'activity_status' => false,
                                                            ]
                                                        );
                                                    }
                                                }
                                            }
    
                                            $quiz_changed = true;
                                        }
    
                                        /**
                                         * Remove the quiz lock.
                                         *
                                         * @since 2.3.1
                                         */
                                        if ((isset($quiz_item['pro_quizid'])) && (!empty($quiz_item['pro_quizid']))) {
                                            learndash_remove_user_quiz_locks($user_id, $quiz_item['quiz']);
                                        }
                                    }
                                }
                            }
                        }
    
                        $processed_course_ids[intval($course_id)] = intval($course_id);
                    }
                }
            }
    
            if (true === $quiz_changed) {
                update_user_meta($user_id, '_sfwd-quizzes', $quizz_progress);
            }
        }
    
        if (!empty($processed_course_ids)) {
            foreach (array_unique($processed_course_ids) as $course_id) {
                learndash_process_mark_complete($user_id, $course_id);
                learndash_update_group_course_user_progress($course_id, $user_id);
            }
        }
    }