Action uncanny-learndash-groups

learndash_quiz_completed

Fires when a user completes a LearnDash quiz, providing quiz and user data.

add_action( 'learndash_quiz_completed', $callback, 10, 2 );

Description

Fires after a quiz has been completed by a user. Developers can use this hook to perform actions based on quiz completion, such as awarding points, triggering notifications, or updating user progress. Note that `$quizdata` and `$user_id` are passed to the hook.


Usage

add_action( 'learndash_quiz_completed', 'your_function_name', 10, 2 );

Parameters

$quizdata (mixed)
This parameter contains an array or object of data related to the completed quiz.
$user_id (mixed)
This parameter is an array containing all the quiz data for the user and quiz, including attempts, scores, and completion status.

Examples

add_action( 'learndash_quiz_completed', 'my_learndash_quiz_completed_handler', 10, 2 );

/**
 * Handles the learndash_quiz_completed action hook.
 *
 * This function is triggered when a user completes a LearnDash quiz.
 * It can be used to perform custom actions, such as sending notifications,
 * updating user points, or triggering other integrations.
 *
 * @param array $quizdata The quiz completion data.
 * @param WP_User $user The user object for the user who completed the quiz.
 */
function my_learndash_quiz_completed_handler( $quizdata, $user ) {
    // Ensure we have valid data and a user object.
    if ( ! is_array( $quizdata ) || ! $user instanceof WP_User ) {
        error_log( 'my_learndash_quiz_completed_handler: Invalid data received.' );
        return;
    }

    $quiz_id = isset( $quizdata['quiz'] ) ? intval( $quizdata['quiz'] ) : 0;
    $user_id = $user->ID;

    // Example: Log the quiz completion event.
    $quiz_title = get_the_title( $quiz_id );
    $user_login = $user->user_login;
    $completion_time = isset( $quizdata['time'] ) ? date( 'Y-m-d H:i:s', $quizdata['time'] ) : 'N/A';
    $score = isset( $quizdata['score'] ) ? $quizdata['score'] : 'N/A';
    $passed = isset( $quizdata['pass'] ) && true === $quizdata['pass'] ? 'Yes' : 'No';

    $log_message = sprintf(
        'LearnDash Quiz Completed: User "%s" (ID: %d) completed quiz "%s" (ID: %d) at %s. Score: %s. Passed: %s.',
        $user_login,
        $user_id,
        $quiz_title,
        $quiz_id,
        $completion_time,
        $score,
        $passed
    );

    // Log the message to the WordPress debug log.
    error_log( $log_message );

    // Example: Award points if the quiz was passed.
    if ( isset( $quizdata['pass'] ) && true === $quizdata['pass'] ) {
        $points_to_award = 5; // Define how many points to award.
        $current_points = get_user_meta( $user_id, 'user_quiz_points', true );
        $current_points = is_numeric( $current_points ) ? intval( $current_points ) : 0;
        $new_points = $current_points + $points_to_award;

        update_user_meta( $user_id, 'user_quiz_points', $new_points );

        error_log( sprintf(
            'LearnDash Quiz Completed: Awarded %d points to user "%s" (ID: %d) for passing quiz "%s" (ID: %d). New total: %d points.',
            $points_to_award,
            $user_login,
            $user_id,
            $quiz_title,
            $quiz_id,
            $new_points
        ) );
    }

    // Example: Send a custom email notification to the user.
    // You would typically use wp_mail() here and construct your email content.
    // For simplicity, we'll just log a message indicating an email would be sent.
    $email_subject = sprintf( 'Congratulations on completing "%s"!', $quiz_title );
    $email_body = sprintf(
        'Hi %s,

Congratulations on successfully completing the quiz "%s". You achieved a score of %s and %s.

Well done!

Sincerely,
Your Website Team',
        $user->display_name,
        $quiz_title,
        $score,
        ( $passed === 'Yes' ? 'passed' : 'did not pass' )
    );

    error_log( sprintf(
        'LearnDash Quiz Completed: Would send email to user "%s" (ID: %d) with subject "%s".',
        $user_login,
        $user_id,
        $email_subject
    ) );
    // In a real scenario, you would use:
    // wp_mail( $user->user_email, $email_subject, $email_body );
}

Placement

This code should be placed in the functions.php file of your active theme, a custom plugin, or using a code snippets plugin.


Source Code

src/classes/reports/learndash-progress-report.php:423

public static function mark_a_quiz_complete( $quiz_id, $course_id, $user_id ) {
		$usermeta       = get_user_meta( $user_id, '_sfwd-quizzes', true );
		$quizz_progress = empty( $usermeta ) ? array() : $usermeta;

		$quiz_meta = get_post_meta( $quiz_id, '_sfwd-quiz', true );

		// 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 = array(
			'quiz'             => $quiz_id,
			'score'            => 100,
			'count'            => 0,
			'pass'             => true,
			'rank'             => '-',
			'time'             => time(),
			'pro_quizid'       => $quiz_meta['sfwd-quiz_quiz_pro'],
			'course'           => $course_id,
			'points'           => 0,
			'total_points'     => 0,
			'percentage'       => 100,
			'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;

		$quizdata_pass = true;

		// Then we add the quiz entry to the activity database.
		learndash_update_user_activity(
			array(
				'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,
			)
		);

		do_action( 'learndash_quiz_completed', $quizdata, get_user_by( 'ID', $user_id ) );
		update_user_meta( $user_id, '_sfwd-quizzes', $quizz_progress );
	}

Scroll to Top