PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.7.2
Tutor LMS – eLearning and online course solution v2.7.2
4.0.1 4.0.0 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 2 years ago attempt-details.php 2 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
747 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 } elseif ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
175 } else {
176 $incorrect++;
177 }
178 }
179 }
180
181 // Prepare the column list for the first summary table.
182 $page_key = 'attempt-details-summary';
183 $table_1_columns = include __DIR__ . '/contexts.php';
184
185 // Prepare the column list for the second table (eery single answer list).
186 $page_key = 'attempt-details-answers';
187 $table_2_columns = include __DIR__ . '/contexts.php';
188
189 require __DIR__ . '/header.php';
190
191 $attempt_info = @unserialize( $attempt_data->attempt_info );
192
193 if ( is_array( $attempt_info ) ) {
194 $attempt_type = '';
195 // Allowed duration.
196 if ( isset( $attempt_info['time_limit'] ) ) {
197 $attempt_duration = tutor_utils()->second_to_formated_time( $attempt_info['time_limit']['time_limit_seconds'], $attempt_info['time_limit']['time_type'] );
198 }
199 if ( 'days' == $attempt_info['time_limit']['time_type'] ) {
200 $attempt_type = 'hours';
201 }
202 if ( 'hours' == $attempt_info['time_limit']['time_type'] ) {
203 $attempt_type = 'minutes';
204 }
205 if ( 'minutes' == $attempt_info['time_limit']['time_type'] ) {
206 $attempt_type = 'minutes';
207 }
208
209 // Taken duration.
210 $seconds = strtotime( $attempt_data->attempt_ended_at ) - strtotime( $attempt_data->attempt_started_at );
211 $attempt_duration_taken = tutor_utils()->second_to_formated_time( $seconds, $attempt_type );
212 }
213 ?>
214
215 <?php echo is_admin() ? '<div class="tutor-admin-body">' : ''; ?>
216 <div class="tutor-table-responsive tutor-mb-32">
217 <table class="tutor-table tutor-quiz-attempt-details">
218 <thead>
219 <tr>
220 <?php foreach ( $table_1_columns as $key => $column ) : ?>
221 <th><?php echo $column; //phpcs:ignore --contain safe data ?></th>
222 <?php endforeach; ?>
223 </tr>
224 </thead>
225
226 <tbody>
227 <tr>
228 <?php foreach ( $table_1_columns as $key => $column ) : ?>
229 <td style="
230 <?php
231 if ( 'date' === $key ) :
232 esc_html_e( 'min-width:180px' );
233 endif;
234 ?>
235 ">
236 <?php if ( 'user' == $key ) : ?>
237 <div class="tutor-d-flex tutor-align-center">
238 <?php
239 echo wp_kses(
240 tutor_utils()->get_tutor_avatar( $user_id ),
241 tutor_utils()->allowed_avatar_tags()
242 );
243 ?>
244 <div class="tutor-ml-16">
245 <div>
246 <?php
247 echo esc_html(
248 $user_data ? $user_data->display_name : ''
249 );
250 ?>
251 </div>
252 <a href="<?php echo esc_url( tutor_utils()->profile_url( $user_id, false ) ); ?>" class="tutor-iconic-btn">
253 <span class="tutor-icon-external-link"></span>
254 </a>
255 </div>
256 </div>
257
258 <?php elseif ( 'date' == $key ) : ?>
259 <div>
260 <?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $attempt_data->attempt_started_at ) ) ); ?>
261 </div>
262 <div>
263 <?php echo esc_html( date_i18n( get_option( 'time_format' ), strtotime( $attempt_data->attempt_started_at ) ) ); ?>
264 </div>
265 <?php elseif ( 'qeustion_count' == $key ) : ?>
266 <?php echo esc_html( $attempt_data->total_questions ); ?>
267 <?php elseif ( 'quiz_time' == $key ) : ?>
268 <?php echo esc_html( $attempt_duration ); ?>
269 <?php elseif ( 'attempt_time' == $key ) : ?>
270 <?php echo esc_html( $attempt_duration_taken ); ?>
271 <?php elseif ( 'total_marks' == $key ) : ?>
272 <?php echo esc_html( $attempt_data->total_marks ); ?>
273 <?php elseif ( 'pass_marks' == $key ) : ?>
274 <?php
275 $pass_marks = ( $total_marks * $passing_grade ) / 100;
276 echo esc_html( number_format_i18n( $pass_marks, 2 ) );
277
278 $pass_mark_percent = $passing_grade;
279 echo esc_html( ' (' . $pass_mark_percent . '%)' );
280 ?>
281 <?php elseif ( 'correct_answer' == $key ) : ?>
282 <?php echo esc_html( $correct ); ?>
283 <?php elseif ( 'incorrect_answer' == $key ) : ?>
284 <?php echo esc_html( $incorrect ); ?>
285 <?php elseif ( 'earned_marks' == $key ) : ?>
286 <?php
287 echo esc_html( $attempt_data->earned_marks );
288 $earned_percentage = $attempt_data->earned_marks > 0 ? ( number_format( ( $attempt_data->earned_marks * 100 ) / $attempt_data->total_marks ) ) : 0;
289 echo esc_html( ' (' . $earned_percentage . '%)' );
290 ?>
291 <?php elseif ( 'result' == $key ) : ?>
292 <?php
293 $ans_array = is_array( $answers ) ? $answers : array();
294 $has_pending = count(
295 array_filter(
296 $ans_array,
297 function ( $ans ) {
298 return null === $ans->is_correct;
299 }
300 )
301 );
302
303 if ( $has_pending ) {
304 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
305 } elseif ( $earned_percentage >= $pass_mark_percent ) {
306 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Pass', 'tutor' ) . '</span>';
307 } else {
308 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Fail', 'tutor' ) . '</span>';
309 }
310 ?>
311 <?php endif; ?>
312 </td>
313 <?php endforeach; ?>
314 </tr>
315 </tbody>
316 </table>
317 </div>
318
319 <?php
320 // instructor feedback.
321 global $wp_query;
322 $query_vars = $wp_query->query_vars;
323 $page_name = isset( $query_vars['tutor_dashboard_page'] ) ? $query_vars['tutor_dashboard_page'] : '';
324 $attempt_info = unserialize( $attempt_data->attempt_info );
325 $feedback = is_array( $attempt_info ) && isset( $attempt_info['instructor_feedback'] ) ? $attempt_info['instructor_feedback'] : '';
326 // don't show on instructor quiz attempt since below already have feedback box area.
327 if ( '' !== $feedback && 'my-quiz-attempts' === $page_name ) {
328 ?>
329 <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">
330 <div class="tutor-in-title tutor-fs-6 tutor-fw-medium tutor-color-black">
331 <?php esc_html_e( 'Instructor Note', 'tutor' ); ?>
332 </div>
333 <div class="tutor-in-body tutor-fs-6 tutor-color-secondary tutor-pt-12 tutor-pt-sm-16">
334 <?php echo wp_kses_post( $feedback ); ?>
335 </div>
336 </div>
337 <?php } ?>
338
339 <?php
340 if ( is_array( $answers ) && count( $answers ) ) {
341 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>' : '';
342 ?>
343 <div class="tutor-table-responsive tutor-mt-16">
344 <table class="tutor-table tutor-quiz-attempt-details tutor-mb-32 tutor-table-data-td-target">
345 <thead>
346 <tr>
347 <?php foreach ( $table_2_columns as $key => $column ) : ?>
348 <th><?php echo $column; //phpcs:ignore --contain safe data ?></th>
349 <?php endforeach; ?>
350 </tr>
351 </thead>
352
353 <tbody>
354 <?php
355 $answer_i = 0;
356 foreach ( $answers as $answer ) {
357 $answer_i++;
358 $question_type = tutor_utils()->get_question_types( $answer->question_type );
359
360 $answer_status = 'wrong';
361
362 // If already correct, then show it.
363 if ( (bool) $answer->is_correct ) {
364 $answer_status = 'correct';
365 }
366
367 // Image answering also needs review since the answer texts are not meant to match exactly.
368 elseif ( in_array( $answer->question_type, array( 'open_ended', 'short_answer', 'image_answering' ) ) ) {
369 $answer_status = null === $answer->is_correct ? 'pending' : 'wrong';
370 }
371 ?>
372
373 <tr class="tutor-quiz-answer-status-<?php echo esc_html( $answer_status ); ?>">
374 <?php foreach ( $table_2_columns as $key => $column ) : ?>
375 <?php
376 switch ( $key ) {
377 case 'no':
378 ?>
379 <td class="no">
380 <span class="tutor-fs-7 tutor-fw-medium tutor-color-black">
381 <?php echo esc_html( $answer_i ); ?>
382 </span>
383 </td>
384 <?php
385 break;
386
387 case 'type':
388 ?>
389 <td class="type">
390 <?php $type = tutor_utils()->get_question_types( $answer->question_type ); ?>
391 <div class="tooltip-wrap tooltip-icon tutor-d-flex tutor-align-center">
392 <?php
393 echo wp_kses(
394 $question_type['icon'] ?? '',
395 tutor_utils()->allowed_icon_tags()
396 );
397 ?>
398 <span class="tooltip-txt tooltip-top">
399 <?php echo esc_html( $type['name'] ?? '' ); ?>
400 </span>
401 </div>
402 </td>
403 <?php
404 break;
405
406 case 'questions':
407 ?>
408 <td class="questions">
409 <span class="tutor-fs-7 tutor-fw-medium tutor-d-flex tutor-align-center">
410 <?php echo esc_html( stripslashes( $answer->question_title ) ); ?>
411 </span>
412 </td>
413 <?php
414 break;
415
416 case 'given_answer':
417 ?>
418 <td class="given-answer">
419 <?php
420 // Single choice.
421 if ( 'single_choice' === $answer->question_type ) {
422 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
423 tutor_render_answer_list( $get_answers );
424 }
425
426
427 // True false or single choice.
428 if ( 'true_false' === $answer->question_type ) {
429 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
430 $answer_titles = wp_list_pluck( $get_answers, 'answer_title' );
431 $answer_titles = array_map( 'stripslashes', $answer_titles );
432
433 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
434 implode( '</p><p>', $answer_titles ) . //phpcs:ignore
435 '</span>';
436 }
437
438 // Multiple choice.
439 elseif ( 'multiple_choice' === $answer->question_type ) {
440 $get_answers = tutor_utils()->get_answer_by_id( maybe_unserialize( $answer->given_answer ) );
441 tutor_render_answer_list( $get_answers );
442 }
443
444 // Fill in the blank.
445 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
446 $answer_titles = maybe_unserialize( $answer->given_answer );
447 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
448
449 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
450 }
451
452 // Open ended or short answer.
453 elseif ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
454 if ( $answer->given_answer ) {
455 echo wp_kses(
456 wpautop( stripslashes( $answer->given_answer ) ),
457 array(
458 'p' => true,
459 'span' => true,
460 )
461 );
462 }
463 }
464
465 // Ordering.
466 elseif ( 'ordering' === $answer->question_type ) {
467 $ordering_ids = maybe_unserialize( $answer->given_answer );
468 foreach ( $ordering_ids as $ordering_id ) {
469 $get_answers = tutor_utils()->get_answer_by_id( $ordering_id );
470 tutor_render_answer_list( $get_answers );
471 }
472 }
473
474 // Matching.
475 elseif ( 'matching' === $answer->question_type ) {
476
477 $ordering_ids = maybe_unserialize( $answer->given_answer );
478 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
479
480 $answers = array();
481
482 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
483 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
484 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
485 if ( tutor_utils()->count( $provided_answer_order ) ) {
486 foreach ( $provided_answer_order as $provided_answer_order ) {
487 }
488 $original_saved_answer->answer_two_gap_match = $provided_answer_order->answer_two_gap_match;
489 $answers[] = $original_saved_answer;
490 }
491 }
492
493 tutor_render_answer_list( $answers );
494 } elseif ( 'image_matching' === $answer->question_type ) {
495
496 $ordering_ids = maybe_unserialize( $answer->given_answer );
497 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
498
499 $answers = array();
500
501 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
502 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
503 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
504 foreach ( $provided_answer_order as $p_answer ) {
505 if ( $p_answer->answer_title ) {
506 $original_saved_answer->answer_view_format = 'text_image';
507 $original_saved_answer->answer_title = $p_answer->answer_title;
508 $answers[] = $original_saved_answer;
509 }
510 }
511
512 }
513
514 tutor_render_answer_list( $answers );
515 } elseif ( 'image_answering' === $answer->question_type ) {
516
517 $ordering_ids = maybe_unserialize( $answer->given_answer );
518
519 $answers = array();
520
521 foreach ( $ordering_ids as $answer_id => $image_answer ) {
522 $db_answers = tutor_utils()->get_answer_by_id( $answer_id );
523 foreach ( $db_answers as $db_answer ) {
524 }
525 $db_answer->answer_title = $image_answer;
526 $db_answer->answer_view_format = 'text_image';
527 $answers[] = $db_answer;
528
529 }
530
531 tutor_render_answer_list( $answers );
532 }
533 ?>
534 </td>
535 <?php
536 break;
537
538 case 'correct_answer':
539 ?>
540 <td class="correct-answer">
541 <?php
542 if ( ( $answer->question_type != 'open_ended' && $answer->question_type != 'short_answer' ) ) {
543
544 global $wpdb;
545
546 // True false.
547 if ( 'true_false' === $answer->question_type ) {
548 $correct_answer = $wpdb->get_var(
549 $wpdb->prepare(
550 "SELECT answer_title FROM {$wpdb->prefix}tutor_quiz_question_answers
551 WHERE belongs_question_id = %d
552 AND belongs_question_type='true_false'
553 AND is_correct = 1",
554 $answer->question_id
555 )
556 );
557
558 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
559 esc_html( $correct_answer ) .
560 '</span>';
561 }
562
563 // Single choice.
564 elseif ( 'single_choice' === $answer->question_type ) {
565 $correct_answer = $wpdb->get_results(
566 $wpdb->prepare(
567 "SELECT answer_title, image_id, answer_view_format
568 FROM {$wpdb->prefix}tutor_quiz_question_answers
569 WHERE belongs_question_id = %d
570 AND belongs_question_type='single_choice' AND
571 is_correct = 1",
572 $answer->question_id
573 )
574 );
575
576 tutor_render_answer_list( $correct_answer );
577 }
578
579 // Multiple choice.
580 elseif ( 'multiple_choice' === $answer->question_type ) {
581 $correct_answer = $wpdb->get_results(
582 $wpdb->prepare(
583 "SELECT answer_title, image_id, answer_view_format
584 FROM {$wpdb->prefix}tutor_quiz_question_answers
585 WHERE belongs_question_id = %d
586 AND belongs_question_type='multiple_choice'
587 AND is_correct = 1 ;",
588 $answer->question_id
589 )
590 );
591
592 tutor_render_answer_list( $correct_answer );
593 }
594
595 // Fill in the blanks.
596 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
597 $correct_answer = $wpdb->get_var(
598 $wpdb->prepare(
599 "SELECT answer_two_gap_match FROM {$wpdb->prefix}tutor_quiz_question_answers
600 WHERE belongs_question_id = %d
601 AND belongs_question_type='fill_in_the_blank'",
602 $answer->question_id
603 )
604 );
605
606 $answer_titles = explode( '|', stripslashes( $correct_answer ) );
607 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
608
609 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
610 }
611
612 // Ordering.
613 elseif ( 'ordering' === $answer->question_type ) {
614 $correct_answer = $wpdb->get_results(
615 $wpdb->prepare(
616 "SELECT answer_title, image_id, answer_view_format
617 FROM {$wpdb->prefix}tutor_quiz_question_answers
618 WHERE belongs_question_id = %d
619 AND belongs_question_type='ordering'
620 ORDER BY answer_order ASC;",
621 $answer->question_id
622 )
623 );
624
625 foreach ( $correct_answer as $ans ) {
626 tutor_render_answer_list( array( $ans ) );
627 }
628 }
629
630 // Matching.
631 elseif ( 'matching' === $answer->question_type ) {
632 $correct_answer = $wpdb->get_results(
633 $wpdb->prepare(
634 "SELECT answer_title, image_id, answer_two_gap_match, answer_view_format
635 FROM {$wpdb->prefix}tutor_quiz_question_answers
636 WHERE belongs_question_id = %d
637 AND belongs_question_type='matching'
638 ORDER BY answer_order ASC;",
639 $answer->question_id
640 )
641 );
642
643 tutor_render_answer_list( $correct_answer );
644 }
645
646 // Image matching.
647 elseif ( 'image_matching' === $answer->question_type ) {
648 $correct_answer = $wpdb->get_results(
649 $wpdb->prepare(
650 "SELECT answer_title, image_id, answer_two_gap_match
651 FROM {$wpdb->prefix}tutor_quiz_question_answers
652 WHERE belongs_question_id = %d
653 AND belongs_question_type='image_matching'
654 ORDER BY answer_order ASC;",
655 $answer->question_id
656 )
657 );
658
659 tutor_render_answer_list( $correct_answer, true );
660 }
661
662 // Image Answering.
663 elseif ( 'image_answering' === $answer->question_type ) {
664
665 $correct_answer = $wpdb->get_results(
666 $wpdb->prepare(
667 "SELECT answer_title, image_id, answer_two_gap_match
668 FROM {$wpdb->prefix}tutor_quiz_question_answers
669 WHERE belongs_question_id = %d
670 AND belongs_question_type='image_answering'
671 ORDER BY answer_order ASC;",
672 $answer->question_id
673 )
674 );
675
676 ! is_array( $correct_answer ) ? $correct_answer = array() : 0;
677
678 echo '<div class="answer-image-matched-wrap">';
679 foreach ( $correct_answer as $image_answer ) {
680 ?>
681 <div class="image-matching-item">
682 <p class="dragged-img-rap"><img src="<?php echo esc_url( wp_get_attachment_image_url( $image_answer->image_id ) ); ?>" /> </p>
683 <p class="dragged-caption"><?php echo esc_html( $image_answer->answer_title ); ?></p>
684 </div>
685 <?php
686 }
687 echo '</div>';
688 }
689 }
690 ?>
691 </td>
692 <?php
693 break;
694
695 case 'result':
696 ?>
697 <td class="result">
698 <?php
699 switch ( $answer_status ) {
700 case 'correct':
701 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Correct', 'tutor' ) . '</span>';
702 break;
703
704 case 'pending':
705 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
706 break;
707
708 case 'wrong':
709 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Incorrect', 'tutor' ) . '</span>';
710 break;
711 }
712 ?>
713 </td>
714 <?php
715 break;
716
717 case 'manual_review':
718 ?>
719 <td class="tutor-text-center tutor-nowrap-ellipsis">
720 <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">
721 <i class="tutor-icon-mark"></i>
722 </a>
723
724 <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">
725 <i class="tutor-icon-times"></i>
726 </a>
727 </td>
728 <?php
729 }
730 ?>
731 <?php endforeach; ?>
732 </tr>
733
734 <?php do_action( 'tutor_quiz_attempt_details_loop_after_row', $answer, $answer_status ); ?>
735
736 <?php
737 }
738 ?>
739 </tbody>
740 </table>
741 </div>
742 <?php
743 }
744 ?>
745
746 <?php echo is_admin() ? '</div>' : ''; ?>
747