PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.0.2
Tutor LMS – eLearning and online course solution v3.0.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 1 year ago attempt-details.php 1 year ago attempt-table.php 1 year ago contexts.php 3 years ago header.php 3 years ago instructor-feedback.php 3 years ago
attempt-details.php
795 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 <div class="tooltip-wrap tooltip-icon tutor-d-flex tutor-align-center">
386 <?php
387 if ( 'h5p' === $answer->question_type ) {
388 ?>
389 <span class="tooltip-btn tutor-d-flex tutor-align-center">
390 <svg width="2e3" height="2e3" class="tutor-quiz-type-icon" version="1.1" viewBox="0 0 2e3 2e3" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
391 <metadata>
392 <rdf:RDF>
393 <cc:Work rdf:about="">
394 <dc:format>image/svg+xml</dc:format>
395 <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
396 <dc:title/>
397 </cc:Work>
398 </rdf:RDF>
399 </metadata>
400 <path d="m-5.2836 1004.2v-1e3h2009.7v2e3h-2009.7zm602.92 150v-90h160.78v180l185.4-0.166-5.0243-2.3086c-2.7634-1.2697-11.693-5.0995-19.843-8.5106-24.366-10.198-36.891-18.724-54.121-36.843-10.05-10.568-20.873-25.967-27.462-39.076-5.0966-10.139-13.346-31.394-13.809-35.581l-0.32475-2.9363 63.809-9.2284c35.095-5.0757 64.939-9.2468 66.321-9.2693 1.9741-0.032 3.1578 1.0489 5.5268 5.0472 9.524 16.075 29.045 28.375 48.934 30.835 39.402 4.8726 74.132-24.163 75.907-63.462 1.4168-31.358-16.291-56.906-46.942-67.723-8.1892-2.8901-25.607-3.543-35.585-1.3338-16.562 3.6667-34.105 15.999-41.818 29.397-1.9314 3.355-3.8993 6.1134-4.3731 6.1298-1.8758 0.065-131.66-18.014-132.04-18.393-0.33622-0.3346 56.264-250.94 59.022-261.33l0.86285-3.25h-124.44v208h-160.78v-208h-152.74v488h152.74v-90zm691.35 0.086v-89.914l61.046-0.4487c50.137-0.3686 63.102-0.7486 72.556-2.1265 45.532-6.6369 75.163-20.01 98.924-44.645 23.057-23.906 35.045-51.976 38.844-90.951 1.4392-14.766 0.7197-39.174-1.5623-53-10.033-60.784-46.103-98.57-106.52-111.58-22.373-4.8192-20.773-4.7584-135.41-5.1478l-108.27-0.3678v100.1h-220.85l-3.2413 13.75c-1.7827 7.5625-5.8428 24.699-9.0225 38.082-4.7451 19.971-5.4901 24.239-4.1566 23.813 0.89355-0.2855 6.3726-2.3074 12.176-4.4931 13.294-5.0069 37.711-11.701 47.748-13.09 9.7858-1.3545 38.914-1.3666 53.241-0.022 30.235 2.8372 56.58 11.691 79.31 26.652 12.878 8.4771 32.803 28.1 41.436 40.809 32.824 48.318 35.187 112.49 6.3454 172.29-3.2595 6.7578-8.3491 15.983-11.31 20.5-19.02 29.016-48.23 53.062-72.572 59.742-8.0702 2.2146-18.898 7.0389-20.084 8.9486-0.4308 0.6937 28.626 1.0224 90.365 1.0224h91zm0-244.09v-54h30.424c48.304 0 63.803 3.0493 76.569 15.065 11.117 10.463 16.624 23.326 16.581 38.724-0.045 16.066-3.6793 25.057-14.466 35.791-14.862 14.79-30.913 18.42-81.434 18.42h-27.673z" stroke-width="1.0024"/>
401 <path d="m445.74 1000.3v-243.31h150.85v209.25h163.02v-209.25h121.75l-1.307 5.4745c-2.5392 10.635-47.071 207.77-52.49 232.36-3.0226 13.718-4.9042 25.533-4.1815 26.256s30.515 5.3399 66.205 10.26l64.891 8.9462 9.8954-11.577c27.937-32.684 75.421-33.24 102.84-1.2047 35.938 41.985 4.7303 107.54-51.078 107.29-19.803-0.087-35.659-7.3743-50.547-23.231l-11.784-12.551-64.806 9.1844c-35.644 5.0515-65.351 9.7291-66.017 10.395-2.5401 2.5401 10.5 34.529 20.974 51.451 19.244 31.091 42.436 50.852 76.365 65.064 8.6293 3.6149 16.146 7.0049 16.703 7.5333 0.55756 0.5285-39.132 0.9609-88.2 0.9609h-89.213v-180.05h-163.02v180.05h-150.85z" fill="#fff" stroke="#fff" stroke-width="2.4331"/>
402 <path d="m1113.7 1241.5c1.2712-1.1737 7.9008-3.9462 14.732-6.1611 58.229-18.879 103.08-90.97 103.13-165.77 0.03-43.193-12.994-76.78-41.351-106.63-19.256-20.271-39.728-33.177-66.904-42.178-17.859-5.9149-22.878-6.4619-60.827-6.6287-38.795-0.17059-42.686 0.23875-62.676 6.5945-11.722 3.727-22.957 7.4073-24.967 8.1784-2.3603 0.90573-3.2737 0.22951-2.5802-1.9102 0.59044-1.8218 4.5292-18.367 8.7528-36.767l7.6793-33.455h220.99v-100.35l113.75 1.2124c106.04 1.1303 115.07 1.5628 133.21 6.383 50.455 13.403 80.167 40.402 95.377 86.669 5.6162 17.083 6.4237 23.632 6.601 53.528 0.1509 25.428-0.8842 38.073-4.0828 49.878-13.928 51.405-51.002 87.442-103.98 101.07-19.479 5.0099-65.583 8.1775-121.05 8.3168l-41.971 0.1053v180.05h-88.078c-50.624 0-87.095-0.9075-85.766-2.1341zm261.63-281.61c16.962-5.037 32.185-19.719 36.303-35.012 7.7315-28.713-8.2767-57.752-36.215-65.695-4.8411-1.3763-26.594-3.2014-48.34-4.0558l-39.538-1.5534v113.44l37.321-1.6092c22.552-0.97241 42.524-3.1542 50.468-5.5133z" fill="#fff" stroke="#fff" stroke-width="2.4331"/>
403 </svg>
404 </span>
405 <?php
406 } else {
407 echo wp_kses(
408 $question_type['icon'] ?? '',
409 tutor_utils()->allowed_icon_tags()
410 );
411 }
412 ?>
413 <span class="tooltip-txt tooltip-top">
414 <?php
415 if ( 'h5p' === $answer->question_type ) {
416 echo esc_html( 'H5P' );
417 } else {
418 echo esc_html( $type['name'] ?? '' );
419 }
420 ?>
421 </span>
422 </div>
423 </td>
424 <?php
425 break;
426
427 case 'questions':
428 ?>
429 <td class="questions" data-title="<?php echo esc_attr( $column ); ?>">
430 <span class="tutor-fs-7 tutor-fw-medium tutor-d-flex tutor-align-center">
431 <?php echo esc_html( stripslashes( $answer->question_title ) ); ?>
432 </span>
433 </td>
434 <?php
435 break;
436
437 case 'given_answer':
438 ?>
439 <td class="given-answer" data-title="<?php echo esc_attr( $column ); ?>">
440 <div>
441 <?php
442 // Single choice.
443 if ( 'single_choice' === $answer->question_type ) {
444 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
445 tutor_render_answer_list( $get_answers );
446 }
447
448
449 // True false or single choice.
450 if ( 'true_false' === $answer->question_type ) {
451 $get_answers = tutor_utils()->get_answer_by_id( $answer->given_answer );
452 $answer_titles = wp_list_pluck( $get_answers, 'answer_title' );
453 $answer_titles = array_map( 'stripslashes', $answer_titles );
454
455 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
456 implode( '</p><p>', $answer_titles ) . //phpcs:ignore
457 '</span>';
458 }
459
460 // Multiple choice.
461 elseif ( 'multiple_choice' === $answer->question_type ) {
462 $get_answers = tutor_utils()->get_answer_by_id( maybe_unserialize( $answer->given_answer ) );
463 tutor_render_answer_list( $get_answers );
464 }
465
466 // Fill in the blank.
467 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
468 $answer_titles = maybe_unserialize( $answer->given_answer );
469 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
470
471 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
472 }
473
474 // Open ended or short answer.
475 elseif ( 'open_ended' === $answer->question_type || 'short_answer' === $answer->question_type ) {
476 if ( $answer->given_answer ) {
477 echo wp_kses(
478 wpautop( stripslashes( $answer->given_answer ) ),
479 array(
480 'p' => true,
481 'span' => true,
482 )
483 );
484 }
485 }
486
487 // Ordering.
488 elseif ( 'ordering' === $answer->question_type ) {
489 $ordering_ids = maybe_unserialize( $answer->given_answer );
490 foreach ( $ordering_ids as $ordering_id ) {
491 $get_answers = tutor_utils()->get_answer_by_id( $ordering_id );
492 tutor_render_answer_list( $get_answers );
493 }
494 }
495
496 // Matching.
497 elseif ( 'matching' === $answer->question_type ) {
498
499 $ordering_ids = maybe_unserialize( $answer->given_answer );
500 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
501
502 $answers = array();
503
504 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
505 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
506 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
507 if ( tutor_utils()->count( $provided_answer_order ) ) {
508 foreach ( $provided_answer_order as $provided_answer_order ) {
509 if ( $is_image_matching ) {
510 $original_saved_answer->answer_view_format = 'text_image';
511 $original_saved_answer->answer_title = $provided_answer_order->answer_title;
512 $original_saved_answer->answer_two_gap_match = '';
513 $answers[] = $original_saved_answer;
514 } else {
515 $original_saved_answer->answer_two_gap_match = $provided_answer_order->answer_two_gap_match;
516 $answers[] = $original_saved_answer;
517 }
518 }
519 }
520 }
521
522 tutor_render_answer_list( $answers );
523 } elseif ( 'image_matching' === $answer->question_type ) {
524
525 $ordering_ids = maybe_unserialize( $answer->given_answer );
526 $original_saved_answers = QuizModel::get_answers_by_quiz_question( $answer->question_id );
527
528 $answers = array();
529
530 foreach ( $original_saved_answers as $key => $original_saved_answer ) {
531 $provided_answer_order_id = isset( $ordering_ids[ $key ] ) ? $ordering_ids[ $key ] : 0;
532 $provided_answer_order = tutor_utils()->get_answer_by_id( $provided_answer_order_id );
533 foreach ( $provided_answer_order as $p_answer ) {
534 if ( $p_answer->answer_title ) {
535 $original_saved_answer->answer_view_format = 'text_image';
536 $original_saved_answer->answer_title = $p_answer->answer_title;
537 $answers[] = $original_saved_answer;
538 }
539 }
540 }
541
542 tutor_render_answer_list( $answers );
543 } elseif ( 'image_answering' === $answer->question_type ) {
544
545 $ordering_ids = maybe_unserialize( $answer->given_answer );
546
547 $answers = array();
548
549 foreach ( $ordering_ids as $answer_id => $image_answer ) {
550 $db_answers = tutor_utils()->get_answer_by_id( $answer_id );
551 foreach ( $db_answers as $db_answer ) {
552 }
553 $db_answer->answer_title = $image_answer;
554 $db_answer->answer_view_format = 'text_image';
555 $answers[] = $db_answer;
556
557 }
558
559 tutor_render_answer_list( $answers );
560 }
561 ?>
562 </div>
563 </td>
564 <?php
565 break;
566
567 case 'correct_answer':
568 ?>
569 <td class="correct-answer" data-title="<?php echo esc_attr( $column ); ?>">
570 <div>
571 <?php
572 if ( ( $answer->question_type != 'open_ended' && $answer->question_type != 'short_answer' ) ) {
573
574 global $wpdb;
575
576 // True false.
577 if ( 'true_false' === $answer->question_type ) {
578 $correct_answer = $wpdb->get_var(
579 $wpdb->prepare(
580 "SELECT answer_title FROM {$wpdb->prefix}tutor_quiz_question_answers
581 WHERE belongs_question_id = %d
582 AND belongs_question_type='true_false'
583 AND is_correct = 1",
584 $answer->question_id
585 )
586 );
587
588 echo '<span class="tutor-fs-7 tutor-fw-medium tutor-color-black">' .
589 esc_html( $correct_answer ) .
590 '</span>';
591 }
592
593 // Single choice.
594 elseif ( 'single_choice' === $answer->question_type ) {
595 $correct_answer = $wpdb->get_results(
596 $wpdb->prepare(
597 "SELECT answer_title, image_id, answer_view_format
598 FROM {$wpdb->prefix}tutor_quiz_question_answers
599 WHERE belongs_question_id = %d
600 AND belongs_question_type='single_choice' AND
601 is_correct = 1",
602 $answer->question_id
603 )
604 );
605
606 tutor_render_answer_list( $correct_answer );
607 }
608
609 // Multiple choice.
610 elseif ( 'multiple_choice' === $answer->question_type ) {
611 $correct_answer = $wpdb->get_results(
612 $wpdb->prepare(
613 "SELECT answer_title, image_id, answer_view_format
614 FROM {$wpdb->prefix}tutor_quiz_question_answers
615 WHERE belongs_question_id = %d
616 AND belongs_question_type='multiple_choice'
617 AND is_correct = 1 ;",
618 $answer->question_id
619 )
620 );
621
622 tutor_render_answer_list( $correct_answer );
623 }
624
625 // Fill in the blanks.
626 elseif ( 'fill_in_the_blank' === $answer->question_type ) {
627 $correct_answer = $wpdb->get_var(
628 $wpdb->prepare(
629 "SELECT answer_two_gap_match FROM {$wpdb->prefix}tutor_quiz_question_answers
630 WHERE belongs_question_id = %d
631 AND belongs_question_type='fill_in_the_blank'",
632 $answer->question_id
633 )
634 );
635
636 $answer_titles = explode( '|', stripslashes( $correct_answer ) );
637 $get_db_answers_by_question = QuizModel::get_answers_by_quiz_question( $answer->question_id );
638
639 echo tutor_render_fill_in_the_blank_answer( $get_db_answers_by_question, $answer_titles ); //phpcs:ignore --contain safe data
640 }
641
642 // Ordering.
643 elseif ( 'ordering' === $answer->question_type ) {
644 $correct_answer = $wpdb->get_results(
645 $wpdb->prepare(
646 "SELECT answer_title, image_id, answer_view_format
647 FROM {$wpdb->prefix}tutor_quiz_question_answers
648 WHERE belongs_question_id = %d
649 AND belongs_question_type='ordering'
650 ORDER BY answer_order ASC;",
651 $answer->question_id
652 )
653 );
654
655 foreach ( $correct_answer as $ans ) {
656 tutor_render_answer_list( array( $ans ) );
657 }
658 }
659
660 // Matching.
661 elseif ( 'matching' === $answer->question_type ) {
662 $correct_answer = $wpdb->get_results(
663 $wpdb->prepare(
664 "SELECT answer_title, image_id, answer_two_gap_match, answer_view_format
665 FROM {$wpdb->prefix}tutor_quiz_question_answers
666 WHERE belongs_question_id = %d
667 AND belongs_question_type='matching'
668 ORDER BY answer_order ASC;",
669 $answer->question_id
670 )
671 );
672
673 if ( $is_image_matching ) {
674 array_map(
675 function( $ans ) {
676 $ans->answer_view_format = 'text_image';
677 $ans->answer_two_gap_match = '';
678 },
679 $correct_answer
680 );
681 }
682
683 tutor_render_answer_list( $correct_answer );
684 }
685
686 // Image matching.
687 elseif ( 'image_matching' === $answer->question_type ) {
688 $correct_answer = $wpdb->get_results(
689 $wpdb->prepare(
690 "SELECT answer_title, image_id, answer_two_gap_match
691 FROM {$wpdb->prefix}tutor_quiz_question_answers
692 WHERE belongs_question_id = %d
693 AND belongs_question_type='image_matching'
694 ORDER BY answer_order ASC;",
695 $answer->question_id
696 )
697 );
698
699 tutor_render_answer_list( $correct_answer, true );
700 }
701
702 // Image Answering.
703 elseif ( 'image_answering' === $answer->question_type ) {
704
705 $correct_answer = $wpdb->get_results(
706 $wpdb->prepare(
707 "SELECT answer_title, image_id, answer_two_gap_match
708 FROM {$wpdb->prefix}tutor_quiz_question_answers
709 WHERE belongs_question_id = %d
710 AND belongs_question_type='image_answering'
711 ORDER BY answer_order ASC;",
712 $answer->question_id
713 )
714 );
715
716 ! is_array( $correct_answer ) ? $correct_answer = array() : 0;
717
718 echo '<div class="answer-image-matched-wrap">';
719 foreach ( $correct_answer as $image_answer ) {
720 ?>
721 <div class="image-matching-item">
722 <p class="dragged-img-rap"><img src="<?php echo esc_url( wp_get_attachment_image_url( $image_answer->image_id ) ); ?>" /> </p>
723 <p class="dragged-caption"><?php echo esc_html( $image_answer->answer_title ); ?></p>
724 </div>
725 <?php
726 }
727 echo '</div>';
728 }
729 }
730 ?>
731 </div>
732 </td>
733 <?php
734 break;
735
736 case 'result':
737 ?>
738 <td class="result" data-title="<?php echo esc_attr( $column ); ?>">
739 <?php do_action( 'tutor_quiz_attempt_after_result_column', $answer, $answer_status ); ?>
740
741 <?php
742 if ( 'h5p' !== $answer->question_type ) {
743 switch ( $answer_status ) {
744 case 'correct':
745 echo '<span class="tutor-badge-label label-success">' . esc_html__( 'Correct', 'tutor' ) . '</span>';
746 break;
747
748 case 'pending':
749 echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>';
750 break;
751
752 case 'wrong':
753 echo '<span class="tutor-badge-label label-danger">' . esc_html__( 'Incorrect', 'tutor' ) . '</span>';
754 break;
755 }
756 }
757 ?>
758 </td>
759 <?php
760 break;
761
762 case 'manual_review':
763 ?>
764 <td class="tutor-text-center tutor-nowrap-ellipsis" data-title="<?php echo esc_attr( $column ); ?>">
765 <div class="tutor-manual-review-wrapper">
766 <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">
767 <i class="tutor-icon-mark"></i>
768 </a>
769
770 <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">
771 <i class="tutor-icon-times"></i>
772 </a>
773 </div>
774 </td>
775 <?php
776 }
777 ?>
778 <?php endforeach; ?>
779 </tr>
780
781 <?php do_action( 'tutor_quiz_attempt_details_loop_after_row', $answer, $answer_status ); ?>
782
783 <?php
784 }
785 ?>
786 </tbody>
787 </table>
788 </div>
789 <?php
790 do_action( 'tutor_quiz_attempt_details_loop_after' );
791 }
792 ?>
793
794 <?php echo is_admin() ? '</div>' : ''; ?>
795