@@ -1924,7 +1929,7 @@ class="wp-block-button__link button quiz-submit complete sensei-course-theme__bu
@@ -2417,6 +2422,75 @@ public static function is_quiz_awaiting_grade_for_user( $lesson_id = null, $user
return $lesson_status && 'ungraded' === $lesson_status->comment_approved;
}
+
+ /**
+ * Returns the HTML for the next lesson button or the contact Teacher button based on condition.
+ * If none of the conditions are met, returns null.
+ *
+ * @param ?int $lesson_id The lesson ID.
+ * @param ?int $user_id The user ID.
+ *
+ * @return string|null Next lesson or Contact Teacher button if condition holds, null otherwise.
+ */
+ private static function maybe_get_button_html_for_quiz_footer( $lesson_id = null, $user_id = null ) {
+ if ( empty( $lesson_id ) ) {
+ $lesson_id = Sensei()->quiz->get_lesson_id();
+ }
+
+ if ( empty( $user_id ) ) {
+ $user_id = get_current_user_id();
+ }
+
+ if ( empty( $lesson_id ) || empty( $user_id ) || 'lesson' !== get_post_type( $lesson_id ) || 'quiz' !== get_post_type() ) {
+ return null;
+ }
+
+ $lesson_status = \Sensei_Utils::user_lesson_status( $lesson_id, $user_id );
+
+ $is_complete = $lesson_status && in_array( $lesson_status->comment_approved, [ 'complete', 'graded', 'passed', 'failed' ], true );
+
+ if ( ! $is_complete ) {
+ return null;
+ }
+
+ $is_pass_required = Sensei()->lesson->lesson_has_quiz_with_questions_and_pass_required( $lesson_id );
+ $is_reset_allowed = self::is_reset_allowed( $lesson_id );
+
+ if ( $is_pass_required && 'failed' === $lesson_status->comment_approved ) {
+
+ if ( $is_reset_allowed ) {
+ return null;
+ }
+
+ $block = new Sensei_Block_Contact_Teacher();
+ $button = self::get_primary_button_anchor_html( __( 'Contact teacher', 'sensei-lms' ), '#' );
+ return $block->render_contact_teacher_block( [], $button );
+ }
+
+ $prev_next_urls = sensei_get_prev_next_lessons( $lesson_id );
+ $next_lesson_url = $prev_next_urls['next']['url'] ?? null;
+
+ if ( $next_lesson_url ) {
+ return self::get_primary_button_anchor_html( __( 'Continue to next lesson', 'sensei-lms' ), $next_lesson_url );
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the HTML for a primary button anchor.
+ *
+ * @param string $button_text The button text.
+ * @param string $url The URL.
+ *
+ * @return string The HTML for the primary button anchor.
+ */
+ private static function get_primary_button_anchor_html( $button_text, $url ) {
+ return '
' .
+ esc_html( $button_text ) .
+ '';
+ }
+
}
/**
diff --git a/tests/unit-tests/test-class-quiz.php b/tests/unit-tests/test-class-quiz.php
index 6a896a45d7..227d47a254 100644
--- a/tests/unit-tests/test-class-quiz.php
+++ b/tests/unit-tests/test-class-quiz.php
@@ -2096,4 +2096,356 @@ public function testQuizFooterActions_WhenInProgressButInLearningMode_DoesNotRen
/* Assert */
$this->assertStringNotContainsString( 'Pending teacher grade', $result );
}
+
+ public function testActionButtons_WhenPassedInLearningMode_ShowsTheNextLessonButton() {
+ /* Arrange */
+ $user_id = $this->factory->user->create();
+ $course_id = $this->factory->course->create();
+ $lesson_1 = $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 1,
+ ],
+ ]
+ );
+ $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 2,
+ ],
+ ]
+ );
+
+ $quiz_id = $this->factory->maybe_create_quiz_for_lesson( $lesson_1 );
+ $course_enrolment = Sensei_Course_Enrolment::get_course_instance( $course_id );
+ $course_enrolment->enrol( $user_id );
+
+ wp_set_current_user( $user_id );
+
+ // Enable course theme;
+ update_post_meta( $course_id, Sensei_Course_Theme_Option::THEME_POST_META_NAME, Sensei_Course_Theme_Option::SENSEI_THEME );
+
+ $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_1, 'passed' );
+ update_comment_meta( $comment_id, 'grade', 2 );
+
+ $this->go_to( get_permalink( $quiz_id ) );
+
+ WP_Block_Supports::$block_to_render = [
+ 'attrs' => [],
+ 'blockName' => 'sensei-lms/quiz-actions',
+ ];
+
+ global $sensei_question_loop;
+ $sensei_question_loop['total_pages'] = 1;
+
+ /* Act */
+ $result = ( new \Sensei\Blocks\Course_Theme\Quiz_Actions() )->render();
+
+ /* Assert */
+ $this->assertStringContainsString( 'Continue to next lesson', $result );
+ }
+
+ public function testActionButtons_WhenFailedInLearningModeButPassRequired_DoesNotShowTheNextLessonButton() {
+ /* Arrange */
+ $user_id = $this->factory->user->create();
+ $course_id = $this->factory->course->create();
+ $lesson_1 = $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 1,
+ '_quiz_has_questions' => 1,
+ ],
+ ]
+ );
+ $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 2,
+ ],
+ ]
+ );
+
+ $quiz_id = $this->factory->maybe_create_quiz_for_lesson( $lesson_1 );
+ $this->factory->question->create(
+ [
+ 'quiz_id' => $quiz_id,
+ 'question_type' => 'multiple-choice',
+ 'question_right_answers' => [ ' ', ' ', ' ' ],
+ 'question_wrong_answers' => [ ' ' ],
+ ]
+ );
+
+ $course_enrolment = Sensei_Course_Enrolment::get_course_instance( $course_id );
+ $course_enrolment->enrol( $user_id );
+
+ wp_set_current_user( $user_id );
+
+ // Enable course theme;
+ update_post_meta( $course_id, Sensei_Course_Theme_Option::THEME_POST_META_NAME, Sensei_Course_Theme_Option::SENSEI_THEME );
+
+ $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_1, 'failed' );
+ update_comment_meta( $comment_id, 'grade', 2 );
+ update_post_meta( $quiz_id, '_pass_required', 'on' );
+
+ $this->go_to( get_permalink( $quiz_id ) );
+
+ WP_Block_Supports::$block_to_render = [
+ 'attrs' => [],
+ 'blockName' => 'sensei-lms/quiz-actions',
+ ];
+
+ global $sensei_question_loop;
+ $sensei_question_loop['total_pages'] = 1;
+
+ /* Act */
+ $result = ( new \Sensei\Blocks\Course_Theme\Quiz_Actions() )->render();
+
+ /* Assert */
+ $this->assertStringContainsString( 'Contact teacher', $result );
+ }
+
+ public function testActionButtons_WhenFailedInLearningModeButPassNotRequired_ShowsTheNextLessonButton() {
+ /* Arrange */
+ $user_id = $this->factory->user->create();
+ $course_id = $this->factory->course->create();
+ $lesson_1 = $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 1,
+ '_quiz_has_questions' => 1,
+ ],
+ ]
+ );
+ $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 2,
+ ],
+ ]
+ );
+
+ $quiz_id = $this->factory->maybe_create_quiz_for_lesson( $lesson_1 );
+ $this->factory->question->create(
+ [
+ 'quiz_id' => $quiz_id,
+ 'question_type' => 'multiple-choice',
+ 'question_right_answers' => [ ' ', ' ', ' ' ],
+ 'question_wrong_answers' => [ ' ' ],
+ ]
+ );
+
+ $course_enrolment = Sensei_Course_Enrolment::get_course_instance( $course_id );
+ $course_enrolment->enrol( $user_id );
+
+ wp_set_current_user( $user_id );
+
+ // Enable course theme;
+ update_post_meta( $course_id, Sensei_Course_Theme_Option::THEME_POST_META_NAME, Sensei_Course_Theme_Option::SENSEI_THEME );
+
+ $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_1, 'failed' );
+ update_comment_meta( $comment_id, 'grade', 2 );
+ update_post_meta( $quiz_id, '_pass_required', 0 );
+
+ $this->go_to( get_permalink( $quiz_id ) );
+
+ WP_Block_Supports::$block_to_render = [
+ 'attrs' => [],
+ 'blockName' => 'sensei-lms/quiz-actions',
+ ];
+
+ global $sensei_question_loop;
+ $sensei_question_loop['total_pages'] = 1;
+
+ /* Act */
+ $result = ( new \Sensei\Blocks\Course_Theme\Quiz_Actions() )->render();
+
+ /* Assert */
+ $this->assertStringContainsString( 'Continue to next lesson', $result );
+ }
+
+ public function testActionButtons_WhenPassedButNotInLearningMode_DoesNotShowTheNextLessonButton() {
+ /* Arrange */
+ $user_id = $this->factory->user->create();
+ $course_id = $this->factory->course->create();
+ $lesson_1 = $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 1,
+ '_quiz_has_questions' => 1,
+ ],
+ ]
+ );
+ $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 2,
+ ],
+ ]
+ );
+
+ $quiz_id = $this->factory->maybe_create_quiz_for_lesson( $lesson_1 );
+ $this->factory->question->create(
+ [
+ 'quiz_id' => $quiz_id,
+ 'question_type' => 'multiple-choice',
+ 'question_right_answers' => [ ' ', ' ', ' ' ],
+ 'question_wrong_answers' => [ ' ' ],
+ ]
+ );
+
+ $course_enrolment = Sensei_Course_Enrolment::get_course_instance( $course_id );
+ $course_enrolment->enrol( $user_id );
+
+ wp_set_current_user( $user_id );
+
+ $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_1, 'passed' );
+ update_comment_meta( $comment_id, 'grade', 2 );
+ update_post_meta( $quiz_id, '_pass_required', 0 );
+
+ $this->go_to( get_permalink( $quiz_id ) );
+
+ WP_Block_Supports::$block_to_render = [
+ 'attrs' => [],
+ 'blockName' => 'sensei-lms/quiz-actions',
+ ];
+
+ global $sensei_question_loop;
+ $sensei_question_loop['total_pages'] = 1;
+
+ /* Act */
+ $result = ( new \Sensei\Blocks\Course_Theme\Quiz_Actions() )->render();
+
+ /* Assert */
+ $this->assertStringNotContainsString( 'Continue to next lesson', $result );
+ }
+
+ public function testActionButtons_WhenPassedButNextLessonHasLowerOrder_DoesNotShowTheNextLessonButton() {
+ /* Arrange */
+ $user_id = $this->factory->user->create();
+ $course_id = $this->factory->course->create();
+ $lesson_1 = $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 2,
+ '_quiz_has_questions' => 1,
+ ],
+ ]
+ );
+ $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 1,
+ ],
+ ]
+ );
+
+ $quiz_id = $this->factory->maybe_create_quiz_for_lesson( $lesson_1 );
+ $this->factory->question->create(
+ [
+ 'quiz_id' => $quiz_id,
+ 'question_type' => 'multiple-choice',
+ 'question_right_answers' => [ ' ', ' ', ' ' ],
+ 'question_wrong_answers' => [ ' ' ],
+ ]
+ );
+
+ $course_enrolment = Sensei_Course_Enrolment::get_course_instance( $course_id );
+ $course_enrolment->enrol( $user_id );
+
+ wp_set_current_user( $user_id );
+
+ // Enable course theme;
+ update_post_meta( $course_id, Sensei_Course_Theme_Option::THEME_POST_META_NAME, Sensei_Course_Theme_Option::SENSEI_THEME );
+
+ $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_1, 'passed' );
+ update_comment_meta( $comment_id, 'grade', 2 );
+ update_post_meta( $quiz_id, '_pass_required', 0 );
+
+ $this->go_to( get_permalink( $quiz_id ) );
+
+ WP_Block_Supports::$block_to_render = [
+ 'attrs' => [],
+ 'blockName' => 'sensei-lms/quiz-actions',
+ ];
+
+ global $sensei_question_loop;
+ $sensei_question_loop['total_pages'] = 1;
+
+ /* Act */
+ $result = ( new \Sensei\Blocks\Course_Theme\Quiz_Actions() )->render();
+
+ /* Assert */
+ $this->assertStringNotContainsString( 'Continue to next lesson', $result );
+ }
+
+ public function testActionButtons_WhenQuizPassedButOnLessonPage_DoesNotShowTheNextLessonButton() {
+ /* Arrange */
+ $user_id = $this->factory->user->create();
+ $course_id = $this->factory->course->create();
+ $lesson_1 = $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 1,
+ '_quiz_has_questions' => 1,
+ ],
+ ]
+ );
+ $this->factory->lesson->create(
+ [
+ 'meta_input' => [
+ '_lesson_course' => $course_id,
+ '_order_' . $course_id => 2,
+ ],
+ ]
+ );
+
+ $quiz_id = $this->factory->maybe_create_quiz_for_lesson( $lesson_1 );
+ $this->factory->question->create(
+ [
+ 'quiz_id' => $quiz_id,
+ 'question_type' => 'multiple-choice',
+ 'question_right_answers' => [ ' ', ' ', ' ' ],
+ 'question_wrong_answers' => [ ' ' ],
+ ]
+ );
+
+ $course_enrolment = Sensei_Course_Enrolment::get_course_instance( $course_id );
+ $course_enrolment->enrol( $user_id );
+
+ wp_set_current_user( $user_id );
+
+ // Enable course theme;
+ update_post_meta( $course_id, Sensei_Course_Theme_Option::THEME_POST_META_NAME, Sensei_Course_Theme_Option::SENSEI_THEME );
+
+ $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_1, 'passed' );
+ update_comment_meta( $comment_id, 'grade', 2 );
+ update_post_meta( $quiz_id, '_pass_required', 0 );
+
+ $this->go_to( get_permalink( $lesson_1 ) );
+
+ WP_Block_Supports::$block_to_render = [
+ 'attrs' => [],
+ 'blockName' => 'sensei-lms/quiz-actions',
+ ];
+
+ global $sensei_question_loop;
+ $sensei_question_loop['total_pages'] = 1;
+
+ /* Act */
+ $result = ( new \Sensei\Blocks\Course_Theme\Quiz_Actions() )->render();
+
+ /* Assert */
+ $this->assertStringNotContainsString( 'Continue to next lesson', $result );
+ }
}