CoursePress - Reset Student Progress on Incomplete Courses

We are creating courses that are open-ended, where anyone can enroll at any time and there is no set time to complete a course. While it is open-ended, we still want to make sure students stay engaged - so we are looking to send reminders if a student hasn't logged in for 2 weeks and 4 weeks. If a student hasn't logged in for 6 weeks, we will reset the student's progress on incomplete courses.

I see that course progress seems to be held in user meta according to class.student.completion.php .. I will handle the time-based login logic separately, I just need to figure out how to tell which courses have not been completed, and how to properly reset a single student's progress on the incomplete course.

Thanks in advance!

  • Vaughan

    Hi Madmen,

    Hope you're well?

    If you check the DB, and run the following query.

    SELECT *
    FROM  wp_usermeta
    WHERE  meta_key LIKE  '%course_200%'
    LIMIT 0 , 30

    Where 200 is the course ID,

    It should throw some results back. if it doesn't list a row as course_200_completed in the results.

    then that course has not been completed.

    So as above, if it's incomplete the results would be listed as

    meta_key

    sandbox1_5__course_200_progress

    but if the course is complete, then you'll see 2 meta_keys such as

    sandbox1_5__course_200_progress
    sandbox1_5__course_200_completed

    so if you know the course ID, you can then simply check if that meta key exists for that user id

    $course_id = 200;
    $sql = $wpdb->query("SELECT * FROM wp_usermeta WHERE meta_key LIKE '%course_{$course_id}_completed%'");

    If $sql is then false, you know that course is not completed.

    However, let me just ask one of our developers to see if there's a quicker way of doing this for you, i'm sure there is, but I can't figure it out.

    Hope this helps

  • Hoang Ngo

    Hi there,

    I think we can try to clear the progress by this code

    delete_user_option( USER_ID, '_course_COURSE_ID_completed' );
    delete_user_option( USER_ID, '_course_COURSE_ID_progress' );

    But I think this is not a good solution, we can try something more "natural", however, this will require plugin code changes. So when you update the plugin, you will need to re-update the changes.
    In the file /coursepress/includes/classes/class.student.completion.php, there is a function called get_completion_data. So you can update it like this

    public static function get_completion_data( $student_id, $course_id ) {
    
    			/**
    			 * check the last time this user logged in
    			 * the student_id is user_id, so you can use that for getting the key you using to track last time login
    			 */
    			//assume we have a last time login format Y-m-d
    			$last_login = '2015-01-01';
    			if(strtotime('+6 weeks',$last_login) < time()){
    				//we return a blank array, as this using for resetting
    				return array();
    			}
    			/**
    			 * Done here
    			 */
    
    			$session_data = CoursePress_Session::session( 'coursepress_student', null, false, '+10 minutes' ); // Keep completion data for only 10 minutes
    
    			$in_session = isset( $session_data ) && isset( $session_data[ $student_id ]['course_completion'][ $course_id ]['unit'] );
    			//$in_session = isset( $_SESSION['coursepress_student'][ $student_id ]['course_completion'][ $course_id ] );
    
    			if ( $in_session && ! empty( $session_data[ $student_id ]['course_completion'][ $course_id ]['unit'] ) ) {
    				// Try the session first...
    				//$course_progress = $_SESSION['coursepress_student'][ $student_id ]['course_completion'][ $course_id ];
    				$course_progress = $session_data[ $student_id ]['course_completion'][ $course_id ];
    			} else {
    				// Otherwise it should be in user meta
    				$course_progress = get_user_option( '_course_' . $course_id . '_progress', $student_id );
    				if ( empty( $course_progress ) ) {
                        if( is_array( $session_data ) && !empty($session_data[ $student_id ]['course_completion'][ $course_id ]) ) {
                            //If we are here, there are no unit completion data.
                            //Let's keep basic course information from session.
                            $course_progress = $session_data[ $student_id ]['course_completion'][ $course_id ];
                            $in_session = true;
                        } else {
    					$course_progress = array();
        				$in_session = false;
    			        }
    				}
    			}
    
                /********** CHANGE ****/
                /*$course_progress = get_user_option( '_course_' . $course_id . '_progress', $student_id );
                if ( empty( $course_progress ) ) {
                    $course_progress = array();
                }
                $in_session = false;*/
                /****** END CHANGE *****/
    
    			if ( ! $in_session ) {
    				//$_SESSION['coursepress_student'][ $student_id ]['course_completion'][ $course_id ] = $course_progress;
    				if( ! is_array( $session_data ) ) {
    					$session_data = array();
    				}
    				$session_data[ $student_id ]['course_completion'][ $course_id ] = $course_progress;
    				CoursePress_Session::session( 'coursepress_student', $session_data );
    			}
    
    			// Check that we're on the right version or upgrade
    			if ( ! self::_check_version( $student_id, $course_id, $course_progress ) ) {
    				$course_progress = self::get_completion_data( $student_id, $course_id );
    			};
    
    			return $course_progress;
    		}

    I added some comment there, hope it helps :slight_smile:

    Best regards,
    Hoang

  • madmen

    Can we bring up to the developers that the previous recommendation isn't a good one? The proposed solution just masks what is output when using that one function (and it requires modifying core plugin code). This feels like a bandaid. Wouldn't it be a better solution to update the information in the database?

    If this isn't in plans for implementation, can someone help me craft a function to run that would properly (and efficiently) clear out the course completion data? It seems to me like the initial thoughts from Vaughn were on the right track for doing this.

    Thanks for the help as always!

  • Vaughan

    Hi,

    At this moment in time the request isn't a high priority due to other priorities taking precedent over features. We mayrevisit this feature in future, but at this time, I can only recommend (if you need this functionality quickly) to advertise on our jobs board for a developer who may be able to add the functionality that's required in this thread. Our jobs board can be found at the below location if you choose to godown this road, otherwise it might take a lot longer before we start working on new features.

    https://premium.wpmudev.org/wordpress-development/

    Apologies for the inconvenience.

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.