← All changes
|
inc/jwt/rest-api/version1/class-lp-rest-quiz-v1-controller.php
+94
-4
4.4.2
→
4.4.10
View file →
| @@ -112,8 +112,17 @@ | ||
| 112 | 112 | ); |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | 115 | /** |
| 116 | + * Allow guests/unauthenticated users to query the list endpoint (filtered by slug). | |
| 117 | + * Per-item visibility is still enforced by check_read_permission, which only | |
| 118 | + * allows preview items for guests. | |
| 119 | + */ | |
| 120 | + public function get_items_permissions_check( $request ) { | |
| 121 | + return true; | |
| 122 | + } | |
| 123 | + | |
| 124 | + /** | |
| 116 | 125 | * Checks if a course can be read. |
| 117 | 126 | * |
| 118 | 127 | * Correctly handles courses with the inherit status. |
| 119 | 128 | * |
| @@ -140,8 +149,20 @@ | ||
| 140 | 149 | if ( ! $post_status_obj || ! $post_status_obj->public ) { |
| 141 | 150 | return false; |
| 142 | 151 | } |
| 143 | 152 | |
| 153 | + // Allow guests and unenrolled users to read items marked as preview. | |
| 154 | + $course_id = $this->get_course_by_item_id( $post_id ); | |
| 155 | + if ( $course_id ) { | |
| 156 | + $course = learn_press_get_course( $course_id ); | |
| 157 | + if ( $course ) { | |
| 158 | + $item = $course->get_item( $post_id ); | |
| 159 | + if ( $item && $item->is_preview() ) { | |
| 160 | + return true; | |
| 161 | + } | |
| 162 | + } | |
| 163 | + } | |
| 164 | + | |
| 144 | 165 | $user_id = get_current_user_id(); |
| 145 | 166 | |
| 146 | 167 | if ( ! $user_id ) { |
| 147 | 168 | return false; |
| @@ -148,11 +169,8 @@ | ||
| 148 | 169 | } |
| 149 | 170 | |
| 150 | 171 | $user = learn_press_get_user( $user_id ); |
| 151 | 172 | |
| 152 | - // Get course ID by lesson ID assigned. | |
| 153 | - $course_id = $this->get_course_by_item_id( $post_id ); | |
| 154 | - | |
| 155 | 173 | if ( empty( $course_id ) ) { |
| 156 | 174 | return false; |
| 157 | 175 | } |
| 158 | 176 | |
| @@ -471,14 +489,18 @@ | ||
| 471 | 489 | } |
| 472 | 490 | |
| 473 | 491 | $duration = $quiz->get_duration(); |
| 474 | 492 | |
| 493 | + // Plugin's get_pagination() returns 0 when value <= 1 (treats 1 as "no pagination"). | |
| 494 | + // Override here so admins can set 1 question per page for step-by-step quizzes. | |
| 495 | + $pagination_raw = absint( get_post_meta( $quiz->get_id(), '_lp_pagination', true ) ); | |
| 496 | + | |
| 475 | 497 | $array = array( |
| 476 | 498 | 'passing_grade' => $quiz->get_passing_grade(), |
| 477 | 499 | 'negative_marking' => $quiz->get_negative_marking(), |
| 478 | 500 | 'instant_check' => $quiz->get_instant_check(), |
| 479 | 501 | 'retake_count' => (float) $quiz->get_retake_count(), |
| 480 | - 'questions_per_page' => $quiz->get_pagination(), | |
| 502 | + 'questions_per_page' => $pagination_raw > 0 ? $pagination_raw : 0, | |
| 481 | 503 | 'page_numbers' => get_post_meta( $quiz->get_id(), '_lp_pagination_numbers', true ) === 'yes', |
| 482 | 504 | 'review_questions' => $quiz->get_review_questions(), |
| 483 | 505 | 'support_options' => learn_press_get_question_support_answer_options(), |
| 484 | 506 | 'duration' => $duration ? $duration->get() : false, |
| @@ -494,8 +516,76 @@ | ||
| 494 | 516 | 'answered' => $answered, |
| 495 | 517 | 'show_correct_review' => $show_correct_review, |
| 496 | 518 | ) |
| 497 | 519 | ); |
| 520 | + | |
| 521 | + // Post-process FIB questions: the actual question content (with [fib] shortcodes) | |
| 522 | + // is stored in lp_question_answers.title — NOT post_content. Read it from there, | |
| 523 | + // strip `fill=` answers, replace shortcodes with {{FIB_<id>}} placeholders for | |
| 524 | + // the client. On reveal, attach `fib_answers` with per-blank correctness. | |
| 525 | + foreach ( $questions as &$q ) { | |
| 526 | + if ( ! isset( $q['type'] ) || $q['type'] !== 'fill_in_blanks' ) { | |
| 527 | + continue; | |
| 528 | + } | |
| 529 | + | |
| 530 | + $question_obj = $q['object'] ?? null; | |
| 531 | + if ( ! $question_obj || ! method_exists( $question_obj, 'get_data' ) ) { | |
| 532 | + continue; | |
| 533 | + } | |
| 534 | + | |
| 535 | + $question_id = $q['id'] ?? 0; | |
| 536 | + $answer_options = $question_obj->get_data( 'answer_options' ); | |
| 537 | + if ( empty( $answer_options ) || ! is_array( $answer_options ) ) { | |
| 538 | + continue; | |
| 539 | + } | |
| 540 | + | |
| 541 | + $first_answer = reset( $answer_options ); | |
| 542 | + $raw_content = $first_answer['title'] ?? ''; | |
| 543 | + $answer_id = $first_answer['question_answer_id'] ?? 0; | |
| 544 | + $user_answer = $answered[ $question_id ]['answered'] ?? ''; | |
| 545 | + $revealed = $show_check || $status === 'completed'; | |
| 546 | + | |
| 547 | + $q['content'] = apply_filters( | |
| 548 | + 'learn-press/question/fib/regex-content', | |
| 549 | + $raw_content, | |
| 550 | + $answer_id, | |
| 551 | + $revealed, | |
| 552 | + $user_answer | |
| 553 | + ); | |
| 554 | + | |
| 555 | + // FIB has no answer "options" in radio/checkbox sense; clear them. | |
| 556 | + $q['options'] = array(); | |
| 557 | + | |
| 558 | + if ( $revealed && method_exists( $question_obj, 'get_answer_data' ) ) { | |
| 559 | + $q['fib_answers'] = $question_obj->get_answer_data( | |
| 560 | + $raw_content, | |
| 561 | + $answer_id, | |
| 562 | + $user_answer | |
| 563 | + ); | |
| 564 | + } | |
| 565 | + } | |
| 566 | + unset( $q ); | |
| 567 | + | |
| 568 | + // Plugin's `learn_press_rest_prepare_user_questions()` only emits `explanation` | |
| 569 | + // when the user explicitly triggered instant_check on a question (it reads | |
| 570 | + // `$args['status']` which is never set in the defaults). For completed quizzes | |
| 571 | + // fill in explanations here so clients can render them on the review screen. | |
| 572 | + if ( $status === 'completed' ) { | |
| 573 | + foreach ( $questions as &$q ) { | |
| 574 | + if ( ! empty( $q['explanation'] ) ) { | |
| 575 | + continue; | |
| 576 | + } | |
| 577 | + $question_obj = $q['object'] ?? null; | |
| 578 | + if ( $question_obj && method_exists( $question_obj, 'get_explanation' ) ) { | |
| 579 | + $explanation = $question_obj->get_explanation(); | |
| 580 | + if ( $explanation ) { | |
| 581 | + $q['explanation'] = $explanation; | |
| 582 | + $q['has_explanation'] = true; | |
| 583 | + } | |
| 584 | + } | |
| 585 | + } | |
| 586 | + unset( $q ); | |
| 587 | + } | |
| 498 | 588 | |
| 499 | 589 | $output['questions'] = $questions; |
| 500 | 590 | } |
| 501 | 591 | |