PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.6.0
Tutor LMS – eLearning and online course solution v3.6.0
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 1 year ago attempt-details.php 1 year ago attempt-table.php 1 year ago contexts.php 3 years ago header.php 1 year ago instructor-feedback.php 3 years ago
attempt-details.php
772 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 //phpcs:ignore
24 extract( $data ); // $user_id, $attempt_id, $attempt_data(nullable), $context(nullable)
25
26 ! isset( $attempt_data ) ? $attempt_data = tutor_utils()->get_attempt( $attempt_id ) : 0;
27 ! isset( $context ) ? $context = null : 0;
28
29 if ( ! $attempt_id || ! $attempt_data || $user_id != $attempt_data->user_id ) {
30 tutor_utils()->tutor_empty_state( __( 'Attempt not found or access permission denied', 'tutor' ) );
31 return;
32 }
33
34 if ( isset( $user_id ) && $user_id > 0 ) {
35 $user = get_userdata( $user_id );
36 if ( ! $user ) {
37 return;
38 }
39 }
40
41 /**
42 * Render answer list
43 *
44 * @param array $answers answers.
45 * @param boolean $dump_data dump data.
46 *
47 * @return void
48 */
49 function tutor_render_answer_list( $answers = array(), $dump_data = false ) {
50 if ( ! empty( $answers ) ) {
51
52 echo '<div class="correct-answer-wrap">';
53
54 $multi_texts = array();
55 foreach ( $answers as $key => $ans ) {
56 $type = isset( $ans->answer_view_format ) ? $ans->answer_view_format : 'text_image';
57
58 if ( isset( $ans->answer_two_gap_match ) ) {
59 echo '<div class="matching-type">';
60 }
61
62 switch ( $type ) {
63 case 'text_image':
64 echo '<div class="text-image-type tutor-mb-4">';
65 if ( isset( $ans->image_id ) ) {
66 $img_url = wp_get_attachment_image_url( $ans->image_id );
67 if ( $img_url ) {
68 echo '<span class="image"><img src="' . esc_url( $img_url ) . '" /></span>';
69 }
70 }
71 if ( isset( $ans->answer_title ) ) {
72 echo '<span class="caption">' . esc_html( stripslashes( $ans->answer_title ) ) . '</span>';
73 }
74 echo '</div>';
75 break;
76
77 case 'text':
78 $ans_string = '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">'
79 . esc_html( stripslashes( $ans->answer_title ) ) .
80 '</span>';
81
82 if ( isset( $ans->answer_title ) && ! isset( $ans->answer_two_gap_match ) ) {
83 $multi_texts[ $ans->answer_title ] = $ans_string;
84 } else {
85 echo $ans_string; //phpcs:ignore -- contain safe data
86 }
87 break;
88
89 case 'image':
90 echo '<div class="image-type">';
91 if ( isset( $ans->image_id ) ) {
92 $img_url = wp_get_attachment_image_url( $ans->image_id );
93 if ( $img_url ) {
94 echo '
95 <span class="image">
96 <img src="' . esc_url( $img_url ) . '" />
97 <span>';
98 }
99 }
100 echo '</div>';
101 break;
102 }
103
104 if ( isset( $ans->answer_two_gap_match ) ) {
105 echo '<div class="image-match">' . esc_html( stripslashes( $ans->answer_two_gap_match ) ) . '</div>';
106 echo '</div>';
107 }
108 }
109 //phpcs:ignore
110 echo count( $multi_texts ) ? implode( ', ', wp_unslash( $multi_texts ) ) : '';
111
112 echo '</div>';
113 }
114 }
115
116 /**
117 * Render fill in the blank answer
118 *
119 * @param mixed $get_db_answers_by_question get db answers by question.
120 * @param mixed $answer_titles ans titles.
121 *
122 * @return void
123 */
124 function tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ) {
125
126 $spaces = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
127
128 // Loop through the answers.
129 foreach ( $get_db_answers_by_question as $db_answer ) {
130 $count_dash_fields = substr_count( $db_answer->answer_title, '{dash}' );
131
132 if ( $count_dash_fields ) {
133 $dash_string = array();
134 $input_data = array();
135 for ( $i = 0; $i < $count_dash_fields; $i++ ) {
136 $ans_title = ( ! empty( $answer_titles[ $i ] ) && ! ctype_space( $answer_titles[ $i ] ) ) ? $answer_titles[ $i ] : null;
137 $input_data[] = $ans_title ? "<span class='filled_dash_unser'>{$ans_title}</span>" : $spaces;
138 }
139
140 $answer_title = $db_answer->answer_title;
141
142 foreach ( $input_data as $index => $replace ) {
143 $replace = '<span style="text-decoration:underline;">' . $replace . '</span>';
144 $answer_title = preg_replace( '/{dash}/i', $replace, $answer_title, 1 );
145 }
146 echo wp_kses(
147 str_replace( '{dash}', "<span class='filled_dash_unser'>{$spaces}</span>", stripslashes( $answer_title ) ),
148 array(
149 'span' => array(
150 'style' => true,
151 'class' => true,
152 ),
153 )
154 );
155 }
156 }
157 }
158
159 // Prepare student data.
160 if ( ! isset( $user_data ) ) {
161 $user_data = get_userdata( $user_id );
162 }
163
164 // Prepare attempt meta info.
165 extract( QuizModel::get_quiz_attempt_timing( $attempt_data ) ); // $attempt_duration, $attempt_duration_taken;
166
167 // Prepare the correct/incorrect answer count for the first summary table.
168 $answers = QuizModel::get_quiz_answers_by_attempt_id( $attempt_id );
169 $correct = 0;
170 $incorrect = 0;
171 if ( is_array( $answers ) && count( $answers ) > 0 ) {
172 foreach ( $answers as $answer ) {
173 if ( (bool) isset( $answer->is_correct ) ? $answer->is_correct : '' ) {
174 $correct++;
175 } elseif ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
176 } else {
177 $incorrect++;
178 }
179 }
180 }
181
182 // Prepare the column list for the first summary table.
183 $page_key = 'attempt-details-summary';
184 $table_1_columns = include __DIR__ . '/contexts.php';
185
186 // Prepare the column list for the second table (eery single answer list).
187 $page_key = 'attempt-details-answers';
188 $table_2_columns = include __DIR__ . '/contexts.php';
189
190 require __DIR__ . '/header.php';
191
192 $attempt_info = @unserialize( $attempt_data->attempt_info );
193
194 if ( is_array( $attempt_info ) ) {
195 $attempt_type = '';
196 // Allowed duration.
197 if ( isset( $attempt_info['time_limit'] ) ) {
198 $attempt_duration = tutor_utils()->second_to_formated_time( $attempt_info['time_limit']['time_limit_seconds'], $attempt_info['time_limit']['time_type'] );
199 }
200 if ( 'days' === $attempt_info['time_limit']['time_type'] ) {
201 $attempt_type = 'hours';
202 }
203 if ( 'hours' === $attempt_info['time_limit']['time_type'] ) {
204 $attempt_type = 'minutes';
205 }
206 if ( 'minutes' === $attempt_info['time_limit']['time_type'] ) {
207 $attempt_type = 'minutes';
208 }
209
210 // Taken duration.
211 $seconds = strtotime( $attempt_data->attempt_ended_at ) - strtotime( $attempt_data->attempt_started_at );
212 $attempt_duration_taken = tutor_utils()->second_to_formated_time( $seconds, $attempt_type );
213 }
214 ?>
215
216 <?php echo is_admin() ? '<div class="tutor-admin-body">' : ''; ?>
217 <div class="tutor-table-responsive tutor-table-mobile tutor-mb-32">
218 <table class="tutor-table tutor-quiz-attempt-details">
219 <thead>
220 <tr>
221 <?php foreach ( $table_1_columns as $key => $column ) : ?>
222 <th><?php echo $column; //phpcs:ignore --contain safe data ?></th>
223 <?php endforeach; ?>
224 </tr>
225 </thead>
226
227 <tbody>
228 <tr>
229 <?php foreach ( $table_1_columns as $key => $column ) : ?>
230 <td data-title="<?php echo esc_attr( $column ); ?>">
231 <?php if ( 'user' == $key ) : ?>
232 <div class="tutor-d-flex tutor-align-center">
233 <?php
234 echo wp_kses(
235 tutor_utils()->get_tutor_avatar( $user_id ),
236 tutor_utils()->allowed_avatar_tags()
237 );
238 ?>
239 <div class="tutor-ml-16">
240 <div>
241 <?php
242 echo esc_html(
243 $user_data ? $user_data->display_name : ''
244 );
245 ?>
246 </div>
247 <a href="<?php echo esc_url( tutor_utils()->profile_url( $user_id, false ) ); ?>" class="tutor-iconic-btn">
248 <span class="tutor-icon-external-link"></span>
249 </a>
250 </div>
251 </div>
252
253 <?php elseif ( 'date' == $key ) : ?>
254 <?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $attempt_data->attempt_started_at ) ) ); ?>
255 <?php elseif ( 'qeustion_count' === $key ) : ?>
256 <?php echo esc_html( $attempt_data->total_questions ); ?>
257 <?php elseif ( 'quiz_time' === $key ) : ?>
258 <?php echo esc_html( $attempt_duration ); ?>
259 <?php elseif ( 'attempt_time' === $key ) : ?>
260 <?php echo esc_html( $attempt_duration_taken ); ?>
261 <?php elseif ( 'total_marks' === $key ) : ?>
262 <?php echo esc_html( $attempt_data->total_marks ); ?>
263 <?php elseif ( 'pass_marks' === $key ) : ?>
264 <?php
265 $pass_marks = ( $total_marks * $passing_grade ) / 100;
266 echo esc_html( number_format_i18n( $pass_marks, 2 ) );
267
268 $pass_mark_percent = $passing_grade;
269 echo esc_html( ' (' . $pass_mark_percent . '%)' );
270 ?>
271 <?php elseif ( 'correct_answer' === $key ) : ?>
272 <?php echo esc_html( $correct ); ?>
273 <?php elseif ( 'incorrect_answer' === $key ) : ?>
274 <?php echo esc_html( $incorrect ); ?>
275 <?php elseif ( 'earned_marks' === $key ) : ?>
276 <?php
277 echo esc_html( $attempt_data->earned_marks );
278 $earned_percentage = $attempt_data->earned_marks > 0 ? ( number_format( ( $attempt_data->earned_marks * 100 ) / $attempt_data->total_marks ) ) : 0;
279 echo esc_html( ' (' . $earned_percentage . '%)' );
280 ?>
281 <?php elseif ( 'result' === $key ) : ?>
282 <?php
283 $ans_array = is_array( $answers ) ? $answers : array();
284 $has_pending = count(
285 array_filter(
286 $ans_array,
287 function ( $ans ) {
288 return null === $ans->is_correct;
289 }
290 )
291 );
292
293 if ( $has_pending ) {
294 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
295 } elseif ( $earned_percentage >= $pass_mark_percent ) {
296 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Pass', 'tutor' ) . '</span>';
297 } else {
298 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Fail', 'tutor' ) . '</span>';
299 }
300 ?>
301 <?php endif; ?>
302 </td>
303 <?php endforeach; ?>
304 </tr>
305 </tbody>
306 </table>
307 </div>
308
309 <?php
310 // instructor feedback.
311 global $wp_query;
312 $query_vars = $wp_query->query_vars;
313 $page_name = isset( $query_vars['tutor_dashboard_page'] ) ? $query_vars['tutor_dashboard_page'] : '';
314 $attempt_info = unserialize( $attempt_data->attempt_info );
315 $feedback = is_array( $attempt_info ) && isset( $attempt_info['instructor_feedback'] ) ? $attempt_info['instructor_feedback'] : '';
316 // don't show on instructor quiz attempt since below already have feedback box area.
317 if ( '' !== $feedback && 'my-quiz-attempts' === $page_name ) {
318 ?>
319 <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">
320 <div class="tutor-in-title tutor-fs-6 tutor-fw-medium tutor-color-black">
321 <?php esc_html_e( 'Instructor Note', 'tutor' ); ?>
322 </div>
323 <div class="tutor-in-body tutor-fs-6 tutor-color-secondary tutor-pt-12 tutor-pt-sm-16">
324 <?php echo wp_kses_post( $feedback ); ?>
325 </div>
326 </div>
327 <?php } ?>
328
329 <?php
330 if ( is_array( $answers ) && count( $answers ) ) {
331 // Filter out not needed columns based on question type.
332 $table_2_columns = apply_filters( 'tutor_filter_attempt_answer_column', $table_2_columns, $answers );
333 $answers = apply_filters( 'tutor_filter_attempt_answers', $answers );
334 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>' : '';
335 ?>
336 <div class="tutor-table-responsive tutor-table-mobile tutor-mt-16">
337 <table class="tutor-table tutor-quiz-attempt-details tutor-mb-32 tutor-table-data-td-target">
338 <thead>
339 <tr>
340 <?php foreach ( $table_2_columns as $key => $column ) : ?>
341 <th><?php echo $column; //phpcs:ignore --contain safe data ?></th>
342 <?php endforeach; ?>
343 </tr>
344 </thead>
345
346 <tbody>
347 <?php
348 $answer_i = 0;
349 foreach ( $answers as $answer ) {
350 $answer_i++;
351 $question_type = tutor_utils()->get_question_types( $answer->question_type );
352 $question_settings = maybe_unserialize( $answer->question_settings );
353 $is_image_matching = isset( $question_settings['is_image_matching'] ) && '1' === $question_settings['is_image_matching'];
354 $answer_status = 'wrong';
355
356 // If already correct, then show it.
357 if ( (bool) $answer->is_correct ) {
358 $answer_status = 'correct';
359 }
360
361 // Image answering also needs review since the answer texts are not meant to match exactly.
362 elseif ( in_array( $answer->question_type, array( 'open_ended', 'short_answer', 'image_answering' ), true ) ) {
363 $answer_status = null === $answer->is_correct ? 'pending' : 'wrong';
364 }
365 ?>
366
367 <tr class="tutor-quiz-answer-status-<?php echo esc_html( $answer_status ); ?>">
368 <?php foreach ( $table_2_columns as $key => $column ) : ?>
369 <?php
370 switch ( $key ) {
371 case 'no':
372 ?>
373 <td class="no" data-title="<?php echo esc_attr( $column ); ?>">
374 <span class="tutor-fs-7 tutor-fw-medium tutor-color-black">
375 <?php echo esc_html( $answer_i ); ?>
376 </span>
377 </td>
378 <?php
379 break;
380
381 case 'type':
382 ?>
383 <td class="type" data-title="<?php echo esc_attr( $column ); ?>">
384 <?php $type = tutor_utils()->get_question_types( $answer->question_type ); ?>
385 <?php ob_start(); ?>
386 <div class="tooltip-wrap tooltip-icon tutor-d-flex tutor-align-center">
387 <?php
388 echo wp_kses(
389 $question_type['icon'] ?? '',
390 tutor_utils()->allowed_icon_tags()
391 );
392 ?>
393 <span class="tooltip-txt tooltip-top">
394 <?php
395 echo esc_html( $type['name'] ?? '' );
396 ?>
397 </span>
398 </div>
399 <?php echo wp_kses_post( apply_filters( 'tutor_question_type_icon', ob_get_clean(), $answer ) ); ?>
400 </td>
401 <?php
402 break;
403
404 case 'questions':
405 ?>
406 <td class="questions" data-title="<?php echo esc_attr( $column ); ?>">
407 <span class="tutor-fs-7 tutor-fw-medium tutor-d-flex tutor-align-center">
408 <?php echo esc_html( stripslashes( $answer->question_title ) ); ?>
409 </span>
410 </td>
411 <?php
412 break;
413
414 case 'given_answer':
415 ?>
416 <td class="given-answer" data-title="<?php echo esc_attr( $column ); ?>">
417 <div>
418 <?php
419 // Single choice.
420 if ( 'single_choice' === $answer->question_type ) {
421 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
422 tutor_render_answer_list( $get_answers );
423 }
424
425
426 // True false or single choice.
427 if ( 'true_false' === $answer->question_type ) {
428 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
429 $answer_titles = wp_list_pluck( $get_answers, 'answer_title' );
430 $answer_titles = array_map( 'stripslashes', $answer_titles );
431
432 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
433 implode( '</p><p>', $answer_titles ) . //phpcs:ignore
434 '</span>';
435 }
436
437 // Multiple choice.
438 elseif ( 'multiple_choice' === $answer->question_type ) {
439 $get_answers = tutor_utils()->get_answer_by_id( maybe_unserialize( $answer->given_answer ) );
440 tutor_render_answer_list( $get_answers );
441 }
442
443 // Fill in the blank.
444 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
445 $answer_titles = maybe_unserialize( $answer->given_answer );
446 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
447
448 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
449 }
450
451 // Open ended or short answer.
452 elseif ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
453 if ( $answer->given_answer ) {
454 echo wp_kses(
455 wpautop( stripslashes( $answer->given_answer ) ),
456 array(
457 'p' => true,
458 'span' => true,
459 )
460 );
461 }
462 }
463
464 // Ordering.
465 elseif ( 'ordering' === $answer->question_type ) {
466 $ordering_ids = maybe_unserialize( $answer->given_answer );
467 foreach ( $ordering_ids as $ordering_id ) {
468 $get_answers = tutor_utils()->get_answer_by_id( $ordering_id );
469 tutor_render_answer_list( $get_answers );
470 }
471 }
472
473 // Matching.
474 elseif ( 'matching' === $answer->question_type ) {
475
476 $ordering_ids = maybe_unserialize( $answer->given_answer );
477 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
478
479 $answers = array();
480
481 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
482 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
483 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
484 if ( tutor_utils()->count( $provided_answer_order ) ) {
485 foreach ( $provided_answer_order as $provided_answer_order ) {
486 if ( $is_image_matching ) {
487 $original_saved_answer->answer_view_format = 'text_image';
488 $original_saved_answer->answer_title = $provided_answer_order->answer_title;
489 $original_saved_answer->answer_two_gap_match = '';
490 $answers[] = $original_saved_answer;
491 } else {
492 $original_saved_answer->answer_two_gap_match = $provided_answer_order->answer_two_gap_match;
493 $answers[] = $original_saved_answer;
494 }
495 }
496 }
497 }
498
499 tutor_render_answer_list( $answers );
500 } elseif ( 'image_matching' === $answer->question_type ) {
501
502 $ordering_ids = maybe_unserialize( $answer->given_answer );
503 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
504
505 $answers = array();
506
507 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
508 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
509 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
510 foreach ( $provided_answer_order as $p_answer ) {
511 if ( $p_answer->answer_title ) {
512 $original_saved_answer->answer_view_format = 'text_image';
513 $original_saved_answer->answer_title = $p_answer->answer_title;
514 $answers[] = $original_saved_answer;
515 }
516 }
517 }
518
519 tutor_render_answer_list( $answers );
520 } elseif ( 'image_answering' === $answer->question_type ) {
521
522 $ordering_ids = maybe_unserialize( $answer->given_answer );
523
524 $answers = array();
525
526 foreach ( $ordering_ids as $answer_id => $image_answer ) {
527 $db_answers = tutor_utils()->get_answer_by_id( $answer_id );
528 foreach ( $db_answers as $db_answer ) {
529 }
530 $db_answer->answer_title = $image_answer;
531 $db_answer->answer_view_format = 'text_image';
532 $answers[] = $db_answer;
533
534 }
535
536 tutor_render_answer_list( $answers );
537 }
538 ?>
539 </div>
540 </td>
541 <?php
542 break;
543
544 case 'correct_answer':
545 ?>
546 <td class="correct-answer" data-title="<?php echo esc_attr( $column ); ?>">
547 <div>
548 <?php
549 if ( ( $answer->question_type != 'open_ended' && $answer->question_type != 'short_answer' ) ) {
550
551 global $wpdb;
552
553 // True false.
554 if ( 'true_false' === $answer->question_type ) {
555 $correct_answer = $wpdb->get_var(
556 $wpdb->prepare(
557 "SELECT answer_title FROM {$wpdb->prefix}tutor_quiz_question_answers
558 WHERE belongs_question_id = %d
559 AND belongs_question_type='true_false'
560 AND is_correct = 1",
561 $answer->question_id
562 )
563 );
564
565 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
566 esc_html( $correct_answer ) .
567 '</span>';
568 }
569
570 // Single choice.
571 elseif ( 'single_choice' === $answer->question_type ) {
572 $correct_answer = $wpdb->get_results(
573 $wpdb->prepare(
574 "SELECT answer_title, image_id, answer_view_format
575 FROM {$wpdb->prefix}tutor_quiz_question_answers
576 WHERE belongs_question_id = %d
577 AND belongs_question_type='single_choice' AND
578 is_correct = 1",
579 $answer->question_id
580 )
581 );
582
583 tutor_render_answer_list( $correct_answer );
584 }
585
586 // Multiple choice.
587 elseif ( 'multiple_choice' === $answer->question_type ) {
588 $correct_answer = $wpdb->get_results(
589 $wpdb->prepare(
590 "SELECT answer_title, image_id, answer_view_format
591 FROM {$wpdb->prefix}tutor_quiz_question_answers
592 WHERE belongs_question_id = %d
593 AND belongs_question_type='multiple_choice'
594 AND is_correct = 1 ;",
595 $answer->question_id
596 )
597 );
598
599 tutor_render_answer_list( $correct_answer );
600 }
601
602 // Fill in the blanks.
603 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
604 $correct_answer = $wpdb->get_var(
605 $wpdb->prepare(
606 "SELECT answer_two_gap_match FROM {$wpdb->prefix}tutor_quiz_question_answers
607 WHERE belongs_question_id = %d
608 AND belongs_question_type='fill_in_the_blank'",
609 $answer->question_id
610 )
611 );
612
613 $answer_titles = explode( '|', stripslashes( $correct_answer ) );
614 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
615
616 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
617 }
618
619 // Ordering.
620 elseif ( 'ordering' === $answer->question_type ) {
621 $correct_answer = $wpdb->get_results(
622 $wpdb->prepare(
623 "SELECT answer_title, image_id, answer_view_format
624 FROM {$wpdb->prefix}tutor_quiz_question_answers
625 WHERE belongs_question_id = %d
626 AND belongs_question_type='ordering'
627 ORDER BY answer_order ASC;",
628 $answer->question_id
629 )
630 );
631
632 foreach ( $correct_answer as $ans ) {
633 tutor_render_answer_list( array( $ans ) );
634 }
635 }
636
637 // Matching.
638 elseif ( 'matching' === $answer->question_type ) {
639 $correct_answer = $wpdb->get_results(
640 $wpdb->prepare(
641 "SELECT answer_title, image_id, answer_two_gap_match, answer_view_format
642 FROM {$wpdb->prefix}tutor_quiz_question_answers
643 WHERE belongs_question_id = %d
644 AND belongs_question_type='matching'
645 ORDER BY answer_order ASC;",
646 $answer->question_id
647 )
648 );
649
650 if ( $is_image_matching ) {
651 array_map(
652 function( $ans ) {
653 $ans->answer_view_format = 'text_image';
654 $ans->answer_two_gap_match = '';
655 },
656 $correct_answer
657 );
658 }
659
660 tutor_render_answer_list( $correct_answer );
661 }
662
663 // Image matching.
664 elseif ( 'image_matching' === $answer->question_type ) {
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_matching'
671 ORDER BY answer_order ASC;",
672 $answer->question_id
673 )
674 );
675
676 tutor_render_answer_list( $correct_answer, true );
677 }
678
679 // Image Answering.
680 elseif ( 'image_answering' === $answer->question_type ) {
681
682 $correct_answer = $wpdb->get_results(
683 $wpdb->prepare(
684 "SELECT answer_title, image_id, answer_two_gap_match
685 FROM {$wpdb->prefix}tutor_quiz_question_answers
686 WHERE belongs_question_id = %d
687 AND belongs_question_type='image_answering'
688 ORDER BY answer_order ASC;",
689 $answer->question_id
690 )
691 );
692
693 ! is_array( $correct_answer ) ? $correct_answer = array() : 0;
694
695 echo '<div class="answer-image-matched-wrap">';
696 foreach ( $correct_answer as $image_answer ) {
697 ?>
698 <div class="image-matching-item">
699 <p class="dragged-img-rap"><img src="<?php echo esc_url( wp_get_attachment_image_url( $image_answer->image_id ) ); ?>" /> </p>
700 <p class="dragged-caption"><?php echo esc_html( $image_answer->answer_title ); ?></p>
701 </div>
702 <?php
703 }
704 echo '</div>';
705 }
706 }
707 ?>
708 </div>
709 </td>
710 <?php
711 break;
712
713 case 'result':
714 ?>
715 <td class="result" data-title="<?php echo esc_attr( $column ); ?>">
716 <?php do_action( 'tutor_quiz_attempt_after_result_column', $answer, $answer_status ); ?>
717
718 <?php
719 if ( 'h5p' !== $answer->question_type ) {
720 switch ( $answer_status ) {
721 case 'correct':
722 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Correct', 'tutor' ) . '</span>';
723 break;
724
725 case 'pending':
726 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
727 break;
728
729 case 'wrong':
730 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Incorrect', 'tutor' ) . '</span>';
731 break;
732 }
733 }
734 ?>
735 </td>
736 <?php
737 break;
738
739 case 'manual_review':
740 ?>
741 <td class="tutor-text-center tutor-nowrap-ellipsis" data-title="<?php echo esc_attr( $column ); ?>">
742 <div class="tutor-manual-review-wrapper">
743 <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">
744 <i class="tutor-icon-mark"></i>
745 </a>
746
747 <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">
748 <i class="tutor-icon-times"></i>
749 </a>
750 </div>
751 </td>
752 <?php
753 }
754 ?>
755 <?php endforeach; ?>
756 </tr>
757
758 <?php do_action( 'tutor_quiz_attempt_details_loop_after_row', $answer, $answer_status ); ?>
759
760 <?php
761 }
762 ?>
763 </tbody>
764 </table>
765 </div>
766 <?php
767 do_action( 'tutor_quiz_attempt_details_loop_after' );
768 }
769 ?>
770
771 <?php echo is_admin() ? '</div>' : ''; ?>
772