Skip to content

Show "Mark Complete" button when quiz requirements are already met#3092

Open
faisalahammad wants to merge 2 commits intogocodebox:devfrom
faisalahammad:feature/3058-mark-complete-after-quiz
Open

Show "Mark Complete" button when quiz requirements are already met#3092
faisalahammad wants to merge 2 commits intogocodebox:devfrom
faisalahammad:feature/3058-mark-complete-after-quiz

Conversation

@faisalahammad
Copy link
Copy Markdown

Summary

Fixes #3058

This PR allows students to re-mark a lesson as complete after clicking "Mark Incomplete", without needing to retake the quiz. The button is shown only when the student has already met the quiz requirements (passed or attempted based on lesson settings).


Problem

When a lesson has an attached quiz:

  1. Student completes the quiz and the lesson is marked complete automatically
  2. Student clicks "Mark Incomplete" to reset their progress
  3. Bug: The "Mark Complete" button disappears. Only the "Take Quiz" button is visible
  4. Student is forced to retake the quiz even though they already passed it

This is frustrating for students who want to review a lesson without losing their quiz results.


Root Cause

The llms_show_mark_complete_button() function unconditionally returns false when a quiz exists:

Before (Problematic Code)

function llms_show_mark_complete_button( $lesson ) {
    $show = true;

    if ( llms_show_take_quiz_button( $lesson ) ) {
        $show = false;  // Always hides button when quiz exists
    }

    return apply_filters( 'llms_show_mark_complete_button', $show, $lesson );
}

The function never checks if the student has already met the quiz requirements. It blindly hides the button whenever a quiz is attached.


Solution

Check if the current user has already met the quiz requirements before hiding the button. This uses the same logic that exists in quiz_maybe_prevent_lesson_completion() in the lesson progression controller.

After (Fixed Code)

function llms_show_mark_complete_button( $lesson ) {
    $show = true;

    // If a quiz button should be shown, check if user already met quiz requirements.
    if ( llms_show_take_quiz_button( $lesson ) ) {
        $show = false;

        // Check if current user has already met quiz requirements.
        $user_id = get_current_user_id();
        if ( $user_id && $lesson->is_quiz_enabled() ) {
            $student = llms_get_student( $user_id );
            if ( $student ) {
                $quiz_id = $lesson->get( 'quiz' );
                $attempt = $student->quizzes()->get_best_attempt( $quiz_id );

                if ( $attempt ) {
                    $passing_required = llms_parse_bool( $lesson->get( 'require_passing_grade' ) );
                    // Show button if: passing not required, OR attempt is passing.
                    if ( ! $passing_required || $attempt->is_passing() ) {
                        $show = true;
                    }
                }
            }
        }
    }

    return apply_filters( 'llms_show_mark_complete_button', $show, $lesson );
}

How It Works

The fix adds these checks in order:

  1. Is user logged in? - Only check for authenticated users
  2. Is quiz enabled? - Double check the quiz is active
  3. Get best attempt - Find the student's highest scoring quiz attempt
  4. Check requirements:
    • If passing grade is NOT required: Show button (any attempt is enough)
    • If passing grade IS required: Show button only if the best attempt is passing

Decision Table

Scenario Before After
No quiz attached Button shown Button shown
Quiz not attempted yet Button hidden Button hidden
Quiz passed Button hidden Button shown
Quiz failed + passing required Button hidden Button hidden
Quiz failed + passing NOT required Button hidden Button shown
Unpublished quiz Button shown Button shown

Files Changed

includes/functions/llms-functions-progression.php

  • Modified llms_show_mark_complete_button() to check quiz completion status
  • Updated docblock with new behavior description and version tag

tests/phpunit/unit-tests/functions/class-llms-test-functions-progression.php

Added 4 new test cases:

Test Method Description
test_llms_show_mark_complete_button_quiz_not_attempted Quiz exists but no attempts - button should be hidden
test_llms_show_mark_complete_button_quiz_passed Quiz passed - button should be shown
test_llms_show_mark_complete_button_quiz_failed_passing_required Quiz failed and passing required - button hidden
test_llms_show_mark_complete_button_quiz_failed_passing_not_required Quiz failed but passing not required - button shown

Backward Compatibility

This change is fully backward compatible:

  • The llms_show_mark_complete_button filter still works as before
  • Third-party code using the filter will continue to work
  • No changes to function signatures or return types
  • No changes to database schema

Performance

The fix adds a database query to fetch the best quiz attempt. This query:

  • Only runs when viewing a lesson with an attached quiz
  • Only runs for logged-in users
  • Uses existing optimized get_best_attempt() method
  • Has minimal impact since it fetches only 1 record

Testing Instructions

Manual Testing

  1. Create a course with a quiz-enabled lesson
  2. Set "Require Passing Grade" to Yes
  3. Set passing grade to 50%
  4. Enroll as a student and take the quiz (pass with 60%+)
  5. Lesson should be marked complete automatically
  6. Click "Mark Incomplete" on the lesson
  7. Verify: "Mark Complete" button should now be visible alongside "Take Quiz"
  8. Click "Mark Complete" to re-complete the lesson without retaking quiz

Automated Tests

vendor/bin/phpunit tests/phpunit/unit-tests/functions/class-llms-test-functions-progression.php

Related


Note on Assignments

Assignments are provided by LifterLMS add-ons, not the core plugin. The same filter (llms_show_mark_complete_button) can be used by add-on developers to implement similar logic for assignments.

Fixes gocodebox#3058

When a lesson has an attached quiz, students who mark the lesson as
incomplete can now re-mark it as complete without retaking the quiz,
provided they have already met the quiz requirements.

Changes:
- Modified llms_show_mark_complete_button() to check quiz completion status
- Added 4 new unit tests for quiz completion scenarios
@ideadude ideadude moved this to Awaiting Review in Development Feb 2, 2026
@brianhogg brianhogg changed the base branch from trunk to dev February 2, 2026 15:10
@brianhogg brianhogg moved this from Awaiting Review to Approved in Development Feb 12, 2026
@brianhogg
Copy link
Copy Markdown
Contributor

@faisalahammad Will review internally but this looks good to me. Thanks!

@brianhogg
Copy link
Copy Markdown
Contributor

Note: will need a changelog before or after merge into dev

@faisalahammad
Copy link
Copy Markdown
Author

Hi @brianhogg,
Would you like me to add the changelog, or will you handle it from your end? Thank you.

@brianhogg
Copy link
Copy Markdown
Contributor

@faisalahammad If you're able to add one into each of the PRs that'd be great. I don't believe I can push to your branch to add one. Thanks!

@faisalahammad
Copy link
Copy Markdown
Author

@brianhogg
Could you please check and let me know if that works?

@brianhogg
Copy link
Copy Markdown
Contributor

@faisalahammad The CHANGELOG.md is built, the changelog files are the yml files described in this comment on the other PR:

#3093 (comment)

Sorry for any confusion and if it's a pain no worries, we can make a note to add the changelog(s) if/when the PRs are merged, or re-create the PRs from your diff. Thanks!

@faisalahammad faisalahammad force-pushed the feature/3058-mark-complete-after-quiz branch from 0b7d91b to b988a89 Compare February 19, 2026 13:20
@brianhogg brianhogg added this to the 10.0 milestone Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Approved

Development

Successfully merging this pull request may close these issues.

Show "Mark Complete" button for a Lesson when Quiz and/or Assignment have been completed

3 participants