PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.1.9
Tutor LMS – eLearning and online course solution v2.1.9
3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / views / quiz / attempt-details.php
tutor / views / quiz Last commit date
header-context 3 years ago attempt-details.php 3 years ago attempt-table.php 3 years ago contexts.php 3 years ago header.php 3 years ago instructor-feedback.php 3 years ago
attempt-details.php
746 lines
1 <?php
2 /**
3 * Attempt details page
4 *
5 * @package Tutor\Views
6 * @subpackage Tutor\Quiz
7 * @author Themeum <support@themeum.com>
8 * @link https://themeum.com
9 * @since 1.0.0
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 use Tutor\Models\QuizModel;
17
18 $enabled_hide_quiz_details = tutor_utils()->get_option( 'hide_quiz_details' );
19 if ( ! is_admin() && ! current_user_can( 'tutor_instructor' ) && true === $enabled_hide_quiz_details ) {
20 exit;
21 }
22
23 extract( $data ); // $user_id, $attempt_id, $attempt_data(nullable), $context(nullable)
24
25 ! isset( $attempt_data ) ? $attempt_data = tutor_utils()->get_attempt( $attempt_id ) : 0;
26 ! isset( $context ) ? $context = null : 0;
27
28 if ( ! $attempt_id || ! $attempt_data || $user_id != $attempt_data->user_id ) {
29 tutor_utils()->tutor_empty_state( __( 'Attempt not found or access permission denied', 'tutor' ) );
30 return;
31 }
32
33 if ( isset( $user_id ) && $user_id > 0 ) {
34 $user = get_userdata( $user_id );
35 if ( ! $user ) {
36 return;
37 }
38 }
39
40 /**
41 * Render answer list
42 *
43 * @param array $answers answers.
44 * @param boolean $dump_data dump data.
45 *
46 * @return void
47 */
48 function tutor_render_answer_list( $answers = array(), $dump_data = false ) {
49 if ( ! empty( $answers ) ) {
50
51 echo '<div class="correct-answer-wrap">';
52
53 $multi_texts = array();
54 foreach ( $answers as $key => $ans ) {
55 $type = isset( $ans->answer_view_format ) ? $ans->answer_view_format : 'text_image';
56
57 if ( isset( $ans->answer_two_gap_match ) ) {
58 echo '<div class="matching-type">';
59 }
60
61 switch ( $type ) {
62 case 'text_image':
63 echo '<div class="text-image-type tutor-mb-4">';
64 if ( isset( $ans->image_id ) ) {
65 $img_url = wp_get_attachment_image_url( $ans->image_id );
66 if ( $img_url ) {
67 echo '<span class="image"><img src="' . esc_url( $img_url ) . '" /></span>';
68 }
69 }
70 if ( isset( $ans->answer_title ) ) {
71 echo '<span class="caption">' . esc_html( stripslashes( $ans->answer_title ) ) . '</span>';
72 }
73 echo '</div>';
74 break;
75
76 case 'text':
77 $ans_string = '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">'
78 . esc_html( $ans->answer_title ) .
79 '</span>';
80
81 if ( isset( $ans->answer_title ) && ! isset( $ans->answer_two_gap_match ) ) {
82 $multi_texts[ $ans->answer_title ] = $ans_string;
83 } else {
84 echo $ans_string; //phpcs:ignore -- contain safe data
85 }
86 break;
87
88 case 'image':
89 echo '<div class="image-type">';
90 if ( isset( $ans->image_id ) ) {
91 $img_url = wp_get_attachment_image_url( $ans->image_id );
92 if ( $img_url ) {
93 echo '
94 <span class="image">
95 <img src="' . esc_url( $img_url ) . '" />
96 <span>';
97 }
98 }
99 echo '</div>';
100 break;
101 }
102
103 if ( isset( $ans->answer_two_gap_match ) ) {
104 echo '<div class="image-match">' . esc_html( stripslashes( $ans->answer_two_gap_match ) ) . '</div>';
105 echo '</div>';
106 }
107 }
108 //phpcs:ignore
109 echo count( $multi_texts ) ? implode( ', ', wp_unslash( $multi_texts ) ) : '';
110
111 echo '</div>';
112 }
113 }
114
115 /**
116 * Render fill in the blank answer
117 *
118 * @param mixed $get_db_answers_by_question get db answers by question.
119 * @param mixed $answer_titles ans titles.
120 *
121 * @return void
122 */
123 function tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ) {
124
125 $spaces = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
126
127 // Loop through the answers.
128 foreach ( $get_db_answers_by_question as $db_answer ) {
129 $count_dash_fields = substr_count( $db_answer->answer_title, '{dash}' );
130
131 if ( $count_dash_fields ) {
132 $dash_string = array();
133 $input_data = array();
134 for ( $i = 0; $i < $count_dash_fields; $i++ ) {
135 $ans_title = ( ! empty( $answer_titles[ $i ] ) && ! ctype_space( $answer_titles[ $i ] ) ) ? $answer_titles[ $i ] : null;
136 $input_data[] = $ans_title ? "<span class='filled_dash_unser'>{$ans_title}</span>" : $spaces;
137 }
138
139 $answer_title = $db_answer->answer_title;
140
141 foreach ( $input_data as $index => $replace ) {
142 $replace = '<span style="text-decoration:underline;">' . $replace . '</span>';
143 $answer_title = preg_replace( '/{dash}/i', $replace, $answer_title, 1 );
144 }
145 echo wp_kses(
146 str_replace( '{dash}', "<span class='filled_dash_unser'>{$spaces}</span>", stripslashes( $answer_title ) ),
147 array(
148 'span' => array(
149 'style' => true,
150 'class' => true,
151 ),
152 )
153 );
154 }
155 }
156 }
157
158 // Prepare student data.
159 if ( ! isset( $user_data ) ) {
160 $user_data = get_userdata( $user_id );
161 }
162
163 // Prepare attempt meta info.
164 extract( QuizModel::get_quiz_attempt_timing( $attempt_data ) ); // $attempt_duration, $attempt_duration_taken;
165
166 // Prepare the correct/incorrect answer count for the first summary table.
167 $answers = QuizModel::get_quiz_answers_by_attempt_id( $attempt_id );
168 $correct = 0;
169 $incorrect = 0;
170 if ( is_array( $answers ) && count( $answers ) > 0 ) {
171 foreach ( $answers as $answer ) {
172 if ( (bool) isset( $answer->is_correct ) ? $answer->is_correct : '' ) {
173 $correct++;
174 } else {
175 if ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
176 } else {
177 $incorrect++;
178 }
179 }
180 }
181 }
182
183 // Prepare the column list for the first summary table.
184 $page_key = 'attempt-details-summary';
185 $table_1_columns = include __DIR__ . '/contexts.php';
186
187 // Prepare the column list for the second table (eery single answer list).
188 $page_key = 'attempt-details-answers';
189 $table_2_columns = include __DIR__ . '/contexts.php';
190
191 require __DIR__ . '/header.php';
192
193 $attempt_info = @unserialize( $attempt_data->attempt_info );
194
195 if ( is_array( $attempt_info ) ) {
196 $attempt_type = '';
197 // Allowed duration.
198 if ( isset( $attempt_info['time_limit'] ) ) {
199 $attempt_duration = tutor_utils()->second_to_formated_time( $attempt_info['time_limit']['time_limit_seconds'], $attempt_info['time_limit']['time_type'] );
200 }
201 if ( 'days' == $attempt_info['time_limit']['time_type'] ) {
202 $attempt_type = 'hours';
203 }
204 if ( 'hours' == $attempt_info['time_limit']['time_type'] ) {
205 $attempt_type = 'minutes';
206 }
207 if ( 'minutes' == $attempt_info['time_limit']['time_type'] ) {
208 $attempt_type = 'minutes';
209 }
210
211 // Taken duration.
212 $seconds = strtotime( $attempt_data->attempt_ended_at ) - strtotime( $attempt_data->attempt_started_at );
213 $attempt_duration_taken = tutor_utils()->second_to_formated_time( $seconds, $attempt_type );
214 }
215 ?>
216
217 <?php echo is_admin() ? '<div class="tutor-admin-body">' : ''; ?>
218 <div class="tutor-table-responsive tutor-mb-32">
219 <table class="tutor-table tutor-quiz-attempt-details">
220 <thead>
221 <tr>
222 <?php foreach ( $table_1_columns as $key => $column ) : ?>
223 <th><?php echo $column; //phpcs:ignore --contain safe data ?></th>
224 <?php endforeach; ?>
225 </tr>
226 </thead>
227
228 <tbody>
229 <tr>
230 <?php foreach ( $table_1_columns as $key => $column ) : ?>
231 <td style="
232 <?php
233 if ( 'date' === $key ) :
234 esc_html_e( 'min-width:180px' );
235 endif;
236 ?>
237 ">
238 <?php if ( 'user' == $key ) : ?>
239 <div class="tutor-d-flex tutor-align-center">
240 <?php
241 echo wp_kses(
242 tutor_utils()->get_tutor_avatar( $user_id ),
243 tutor_utils()->allowed_avatar_tags()
244 );
245 ?>
246 <div class="tutor-ml-16">
247 <div>
248 <?php
249 echo esc_html(
250 $user_data ? $user_data->display_name : ''
251 );
252 ?>
253 </div>
254 <a href="<?php echo esc_url( tutor_utils()->profile_url( $user_id, false ) ); ?>" class="tutor-iconic-btn">
255 <span class="tutor-icon-external-link"></span>
256 </a>
257 </div>
258 </div>
259
260 <?php elseif ( 'date' == $key ) : ?>
261 <div>
262 <?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $attempt_data->attempt_started_at ) ) ); ?>
263 </div>
264 <div>
265 <?php echo esc_html( date_i18n( get_option( 'time_format' ), strtotime( $attempt_data->attempt_started_at ) ) ); ?>
266 </div>
267 <?php elseif ( 'qeustion_count' == $key ) : ?>
268 <?php echo esc_html( $attempt_data->total_questions ); ?>
269 <?php elseif ( 'quiz_time' == $key ) : ?>
270 <?php echo esc_html( $attempt_duration ); ?>
271 <?php elseif ( 'attempt_time' == $key ) : ?>
272 <?php echo esc_html( $attempt_duration_taken ); ?>
273 <?php elseif ( 'total_marks' == $key ) : ?>
274 <?php echo esc_html( $attempt_data->total_marks ); ?>
275 <?php elseif ( 'pass_marks' == $key ) : ?>
276 <?php
277 $pass_marks = ( $total_marks * $passing_grade ) / 100;
278 echo esc_html( number_format_i18n( $pass_marks, 2 ) );
279
280 $pass_mark_percent = $passing_grade;
281 echo esc_html( ' (' . $pass_mark_percent . '%)' );
282 ?>
283 <?php elseif ( 'correct_answer' == $key ) : ?>
284 <?php echo esc_html( $correct ); ?>
285 <?php elseif ( 'incorrect_answer' == $key ) : ?>
286 <?php echo esc_html( $incorrect ); ?>
287 <?php elseif ( 'earned_marks' == $key ) : ?>
288 <?php
289 echo esc_html( $attempt_data->earned_marks );
290 $earned_percentage = $attempt_data->earned_marks > 0 ? ( number_format( ( $attempt_data->earned_marks * 100 ) / $attempt_data->total_marks ) ) : 0;
291 echo esc_html( ' (' . $earned_percentage . '%)' );
292 ?>
293 <?php elseif ( 'result' == $key ) : ?>
294 <?php
295 $ans_array = is_array( $answers ) ? $answers : array();
296 $has_pending = count(
297 array_filter(
298 $ans_array,
299 function( $ans ) {
300 return null === $ans->is_correct;
301 }
302 )
303 );
304
305 if ( $has_pending ) {
306 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
307 } elseif ( $earned_percentage >= $pass_mark_percent ) {
308 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Pass', 'tutor' ) . '</span>';
309 } else {
310 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Fail', 'tutor' ) . '</span>';
311 }
312 ?>
313 <?php endif; ?>
314 </td>
315 <?php endforeach; ?>
316 </tr>
317 </tbody>
318 </table>
319 </div>
320
321 <?php
322 // instructor feedback.
323 global $wp_query;
324 $query_vars = $wp_query->query_vars;
325 $page_name = isset( $query_vars['tutor_dashboard_page'] ) ? $query_vars['tutor_dashboard_page'] : '';
326 $attempt_info = unserialize( $attempt_data->attempt_info );
327 $feedback = is_array( $attempt_info ) && isset( $attempt_info['instructor_feedback'] ) ? $attempt_info['instructor_feedback'] : '';
328 // don't show on instructor quiz attempt since below already have feedback box area.
329 if ( '' !== $feedback && 'my-quiz-attempts' === $page_name ) {
330 ?>
331 <div class="tutor-quiz-attempt-note tutor-instructor-note tutor-my-32 tutor-py-20 tutor-px-24 tutor-py-sm-32 tutor-px-sm-36">
332 <div class="tutor-in-title tutor-fs-6 tutor-fw-medium tutor-color-black">
333 <?php esc_html_e( 'Instructor Note', 'tutor' ); ?>
334 </div>
335 <div class="tutor-in-body tutor-fs-6 tutor-color-secondary tutor-pt-12 tutor-pt-sm-16">
336 <?php echo wp_kses_post( $feedback ); ?>
337 </div>
338 </div>
339 <?php } ?>
340
341 <?php
342 if ( is_array( $answers ) && count( $answers ) ) {
343 echo 'course-single-previous-attempts' != $context ? '<div class="tutor-fs-6 tutor-fw-medium tutor-color-black tutor-mt-24">' . esc_html__( 'Quiz Overview', 'tutor' ) . '</div>' : '';
344 ?>
345 <div class="tutor-table-responsive tutor-mt-16">
346 <table class="tutor-table tutor-quiz-attempt-details tutor-mb-32">
347 <thead>
348 <tr>
349 <?php foreach ( $table_2_columns as $key => $column ) : ?>
350 <th><?php echo $column; //phpcs:ignore --contain safe data ?></th>
351 <?php endforeach; ?>
352 </tr>
353 </thead>
354
355 <tbody>
356 <?php
357 $answer_i = 0;
358 foreach ( $answers as $answer ) {
359 $answer_i++;
360 $question_type = tutor_utils()->get_question_types( $answer->question_type );
361
362 $answer_status = 'wrong';
363
364 // If already correct, then show it.
365 if ( (bool) $answer->is_correct ) {
366 $answer_status = 'correct';
367 }
368
369 // Image answering also needs review since the answer texts are not meant to match exactly.
370 elseif ( in_array( $answer->question_type, array( 'open_ended', 'short_answer', 'image_answering' ) ) ) {
371 $answer_status = null === $answer->is_correct ? 'pending' : 'wrong';
372 }
373 ?>
374
375 <tr class="tutor-quiz-answer-status-<?php echo esc_html( $answer_status ); ?>">
376 <?php foreach ( $table_2_columns as $key => $column ) : ?>
377 <?php
378 switch ( $key ) {
379 case 'no':
380 ?>
381 <td class="no">
382 <span class="tutor-fs-7 tutor-fw-medium tutor-color-black">
383 <?php echo esc_html( $answer_i ); ?>
384 </span>
385 </td>
386 <?php
387 break;
388
389 case 'type':
390 ?>
391 <td class="type">
392 <?php $type = tutor_utils()->get_question_types( $answer->question_type ); ?>
393 <div class="tooltip-wrap tooltip-icon tutor-d-flex tutor-align-center">
394 <?php
395 echo wp_kses(
396 $question_type['icon'] ?? '',
397 tutor_utils()->allowed_icon_tags()
398 );
399 ?>
400 <span class="tooltip-txt tooltip-top">
401 <?php echo esc_html( $type['name'] ?? '' ); ?>
402 </span>
403 </div>
404 </td>
405 <?php
406 break;
407
408 case 'questions':
409 ?>
410 <td class="questions">
411 <span class="tutor-fs-7 tutor-fw-medium tutor-d-flex tutor-align-center">
412 <?php echo esc_html( stripslashes( $answer->question_title ) ); ?>
413 </span>
414 </td>
415 <?php
416 break;
417
418 case 'given_answer':
419 ?>
420 <td class="given-answer">
421 <?php
422 // Single choice.
423 if ( 'single_choice' === $answer->question_type ) {
424 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
425 tutor_render_answer_list( $get_answers );
426 }
427
428
429 // True false or single choice.
430 if ( 'true_false' === $answer->question_type ) {
431 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
432 $answer_titles = wp_list_pluck( $get_answers, 'answer_title' );
433 $answer_titles = array_map( 'stripslashes', $answer_titles );
434
435 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
436 implode( '</p><p>', $answer_titles ) . //phpcs:ignore
437 '</span>';
438 }
439
440 // Multiple choice.
441 elseif ( 'multiple_choice' === $answer->question_type ) {
442 $get_answers = tutor_utils()->get_answer_by_id( maybe_unserialize( $answer->given_answer ) );
443 tutor_render_answer_list( $get_answers );
444 }
445
446 // Fill in the blank.
447 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
448 $answer_titles = maybe_unserialize( $answer->given_answer );
449 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
450
451 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
452 }
453
454 // Open ended or short answer.
455 elseif ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
456 if ( $answer->given_answer ) {
457 echo wp_kses(
458 wpautop( stripslashes( $answer->given_answer ) ),
459 array(
460 'p' => true,
461 'span' => true,
462 )
463 );
464 }
465 }
466
467 // Ordering.
468 elseif ( 'ordering' === $answer->question_type ) {
469 $ordering_ids = maybe_unserialize( $answer->given_answer );
470 foreach ( $ordering_ids as $ordering_id ) {
471 $get_answers = tutor_utils()->get_answer_by_id( $ordering_id );
472 tutor_render_answer_list( $get_answers );
473 }
474 }
475
476 // Matching.
477 elseif ( 'matching' === $answer->question_type ) {
478
479 $ordering_ids = maybe_unserialize( $answer->given_answer );
480 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
481
482 $answers = array();
483
484 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
485 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
486 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
487 if ( tutor_utils()->count( $provided_answer_order ) ) {
488 foreach ( $provided_answer_order as $provided_answer_order ) {
489 }
490 $original_saved_answer->answer_two_gap_match = $provided_answer_order->answer_two_gap_match;
491 $answers[] = $original_saved_answer;
492 }
493 }
494
495 tutor_render_answer_list( $answers );
496 } elseif ( 'image_matching' === $answer->question_type ) {
497
498 $ordering_ids = maybe_unserialize( $answer->given_answer );
499 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
500
501 $answers = array();
502
503 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
504 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
505 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
506 foreach ( $provided_answer_order as $provided_answer_order ) {
507 }
508
509 if ( $provided_answer_order->answer_title ) {
510 $original_saved_answer->answer_view_format = 'text_image';
511 $original_saved_answer->answer_title = $provided_answer_order->answer_title;
512 $answers[] = $original_saved_answer;
513 }
514 }
515
516 tutor_render_answer_list( $answers );
517 } elseif ( 'image_answering' === $answer->question_type ) {
518
519 $ordering_ids = maybe_unserialize( $answer->given_answer );
520
521 $answers = array();
522
523 foreach ( $ordering_ids as $answer_id => $image_answer ) {
524 $db_answers = tutor_utils()->get_answer_by_id( $answer_id );
525 foreach ( $db_answers as $db_answer ) {
526 }
527 $db_answer->answer_title = $image_answer;
528 $db_answer->answer_view_format = 'text_image';
529 $answers[] = $db_answer;
530
531 }
532
533 tutor_render_answer_list( $answers );
534 }
535 ?>
536 </td>
537 <?php
538 break;
539
540 case 'correct_answer':
541 ?>
542 <td class="correct-answer">
543 <?php
544 if ( ( $answer->question_type != 'open_ended' && $answer->question_type != 'short_answer' ) ) {
545
546 global $wpdb;
547
548 // True false.
549 if ( 'true_false' === $answer->question_type ) {
550 $correct_answer = $wpdb->get_var(
551 $wpdb->prepare(
552 "SELECT answer_title FROM {$wpdb->prefix}tutor_quiz_question_answers
553 WHERE belongs_question_id = %d
554 AND belongs_question_type='true_false'
555 AND is_correct = 1",
556 $answer->question_id
557 )
558 );
559
560 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
561 esc_html( $correct_answer ) .
562 '</span>';
563 }
564
565 // Single choice.
566 elseif ( 'single_choice' === $answer->question_type ) {
567 $correct_answer = $wpdb->get_results(
568 $wpdb->prepare(
569 "SELECT answer_title, image_id, answer_view_format
570 FROM {$wpdb->prefix}tutor_quiz_question_answers
571 WHERE belongs_question_id = %d
572 AND belongs_question_type='single_choice' AND
573 is_correct = 1",
574 $answer->question_id
575 )
576 );
577
578 tutor_render_answer_list( $correct_answer );
579 }
580
581 // Multiple choice.
582 elseif ( 'multiple_choice' === $answer->question_type ) {
583 $correct_answer = $wpdb->get_results(
584 $wpdb->prepare(
585 "SELECT answer_title, image_id, answer_view_format
586 FROM {$wpdb->prefix}tutor_quiz_question_answers
587 WHERE belongs_question_id = %d
588 AND belongs_question_type='multiple_choice'
589 AND is_correct = 1 ;",
590 $answer->question_id
591 )
592 );
593
594 tutor_render_answer_list( $correct_answer );
595 }
596
597 // Fill in the blanks.
598 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
599 $correct_answer = $wpdb->get_var(
600 $wpdb->prepare(
601 "SELECT answer_two_gap_match FROM {$wpdb->prefix}tutor_quiz_question_answers
602 WHERE belongs_question_id = %d
603 AND belongs_question_type='fill_in_the_blank'",
604 $answer->question_id
605 )
606 );
607
608 $answer_titles = explode( '|', stripslashes( $correct_answer ) );
609 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
610
611 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
612 }
613
614 // Ordering.
615 elseif ( 'ordering' === $answer->question_type ) {
616 $correct_answer = $wpdb->get_results(
617 $wpdb->prepare(
618 "SELECT answer_title, image_id, answer_view_format
619 FROM {$wpdb->prefix}tutor_quiz_question_answers
620 WHERE belongs_question_id = %d
621 AND belongs_question_type='ordering'
622 ORDER BY answer_order ASC;",
623 $answer->question_id
624 )
625 );
626
627 foreach ( $correct_answer as $ans ) {
628 tutor_render_answer_list( array( $ans ) );
629 }
630 }
631
632 // Matching.
633 elseif ( 'matching' === $answer->question_type ) {
634 $correct_answer = $wpdb->get_results(
635 $wpdb->prepare(
636 "SELECT answer_title, image_id, answer_two_gap_match, answer_view_format
637 FROM {$wpdb->prefix}tutor_quiz_question_answers
638 WHERE belongs_question_id = %d
639 AND belongs_question_type='matching'
640 ORDER BY answer_order ASC;",
641 $answer->question_id
642 )
643 );
644
645 tutor_render_answer_list( $correct_answer );
646 }
647
648 // Image matching.
649 elseif ( 'image_matching' === $answer->question_type ) {
650 $correct_answer = $wpdb->get_results(
651 $wpdb->prepare(
652 "SELECT answer_title, image_id, answer_two_gap_match
653 FROM {$wpdb->prefix}tutor_quiz_question_answers
654 WHERE belongs_question_id = %d
655 AND belongs_question_type='image_matching'
656 ORDER BY answer_order ASC;",
657 $answer->question_id
658 )
659 );
660
661 tutor_render_answer_list( $correct_answer, true );
662 }
663
664 // Image Answering.
665 elseif ( 'image_answering' === $answer->question_type ) {
666
667 $correct_answer = $wpdb->get_results(
668 $wpdb->prepare(
669 "SELECT answer_title, image_id, answer_two_gap_match
670 FROM {$wpdb->prefix}tutor_quiz_question_answers
671 WHERE belongs_question_id = %d
672 AND belongs_question_type='image_answering'
673 ORDER BY answer_order ASC;",
674 $answer->question_id
675 )
676 );
677
678 ! is_array( $correct_answer ) ? $correct_answer = array() : 0;
679
680 echo '<div class="answer-image-matched-wrap">';
681 foreach ( $correct_answer as $image_answer ) {
682 ?>
683 <div class="image-matching-item">
684 <p class="dragged-img-rap"><img src="<?php echo esc_url( wp_get_attachment_image_url( $image_answer->image_id ) ); ?>" /> </p>
685 <p class="dragged-caption"><?php echo esc_html( $image_answer->answer_title ); ?></p>
686 </div>
687 <?php
688 }
689 echo '</div>';
690 }
691 }
692 ?>
693 </td>
694 <?php
695 break;
696
697 case 'result':
698 ?>
699 <td class="result">
700 <?php
701 switch ( $answer_status ) {
702 case 'correct':
703 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Correct', 'tutor' ) . '</span>';
704 break;
705
706 case 'pending':
707 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
708 break;
709
710 case 'wrong':
711 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Incorrect', 'tutor' ) . '</span>';
712 break;
713 }
714 ?>
715 </td>
716 <?php
717 break;
718
719 case 'manual_review':
720 ?>
721 <td class="tutor-text-center tutor-nowrap-ellipsis">
722 <a href="javascript:;" data-back-url="<?php echo esc_url( $back_url ); ?>" data-attempt-id="<?php echo esc_attr( $attempt_id ); ?>" data-attempt-answer-id="<?php echo esc_attr( $answer->attempt_answer_id ); ?>" data-mark-as="correct" data-context="<?php echo esc_attr( $context ); ?>" title="<?php esc_attr_e( 'Mark as correct', 'tutor' ); ?>" class="quiz-manual-review-action tutor-mr-12 tutor-icon-rounded tutor-color-success">
723 <i class="tutor-icon-mark"></i>
724 </a>
725
726 <a href="javascript:;" data-back-url="<?php echo esc_url( $back_url ); ?>" data-attempt-id="<?php echo esc_attr( $attempt_id ); ?>" data-attempt-answer-id="<?php echo esc_attr( $answer->attempt_answer_id ); ?>" data-mark-as="incorrect" data-context="<?php echo esc_attr( $context ); ?>" title="<?php esc_attr_e( 'Mark as In correct', 'tutor' ); ?>" class="quiz-manual-review-action tutor-icon-rounded tutor-color-danger">
727 <i class="tutor-icon-times"></i>
728 </a>
729 </td>
730 <?php
731 }
732 ?>
733 <?php endforeach; ?>
734 </tr>
735 <?php
736 }
737 ?>
738 </tbody>
739 </table>
740 </div>
741 <?php
742 }
743 ?>
744
745 <?php echo is_admin() ? '</div>' : ''; ?>
746