quiz-reviews.php
342 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Quiz Review Frontend |
| 4 | * |
| 5 | * @since v.1.4.0 |
| 6 | * |
| 7 | * @author Themeum |
| 8 | * @url https://themeum.com |
| 9 | * @package Tutor |
| 10 | * |
| 11 | * @package TutorLMS/Templates |
| 12 | * @version 1.4.3 |
| 13 | */ |
| 14 | ?> |
| 15 | |
| 16 | <?php |
| 17 | $attempt_id = (int) sanitize_text_field($_GET['attempt_id']); |
| 18 | $attempt = tutor_utils()->get_attempt($attempt_id); |
| 19 | |
| 20 | if ( ! $attempt){ |
| 21 | ?> |
| 22 | <h1><?php _e('Attempt not found', 'tutor'); ?></h1> |
| 23 | <?php |
| 24 | return; |
| 25 | } |
| 26 | |
| 27 | $quiz_attempt_info = tutor_utils()->quiz_attempt_info($attempt->attempt_info); |
| 28 | $answers = tutor_utils()->get_quiz_answers_by_attempt_id($attempt->attempt_id); |
| 29 | |
| 30 | $user_id = tutor_utils()->avalue_dot('user_id', $attempt); |
| 31 | $user = get_userdata($user_id); |
| 32 | ?> |
| 33 | |
| 34 | |
| 35 | <div class="tutor-quiz-attempt-review-wrap"> |
| 36 | <h2 class="attempt-review-title"> <i class="tutor-icon-list"></i> <?php _e('View Attempts', 'tutor'); ?></h2> |
| 37 | <div class="tutor-quiz-attempt-info-row"> |
| 38 | <div class="attempt-view-top"> |
| 39 | <div class="attempt-info-col"> |
| 40 | <div class="attempt-user-details"> |
| 41 | <div class="attempt-user-avatar"> |
| 42 | <img src="<?php echo esc_url(get_avatar_url($user_id)) ?>" alt="<?php echo esc_attr($user->display_name); ?>"> |
| 43 | </div> |
| 44 | <div class="attempt-info-content"> |
| 45 | <h5><?php echo __('Attempt By', 'tutor'); ?></h5> |
| 46 | <h4><?php echo $user->display_name; ?></h4> |
| 47 | </div> |
| 48 | </div> |
| 49 | </div> |
| 50 | <div class="attempt-info-col"> |
| 51 | <div class="attempt-info-content"> |
| 52 | <h5><?php echo __('Quiz', 'tutor'); ?></h5> |
| 53 | <h4> |
| 54 | <?php |
| 55 | echo "<a href='" .admin_url("post.php?post={$attempt->quiz_id}&action=edit")."'>".get_the_title($attempt->quiz_id)."</a>"; |
| 56 | ?> |
| 57 | </h4> |
| 58 | </div> |
| 59 | </div> |
| 60 | |
| 61 | <div class="attempt-info-col"> |
| 62 | <div class="attempt-info-content"> |
| 63 | <h5><?php echo __('Attempt At', 'tutor'); ?></h5> |
| 64 | <h4> |
| 65 | <?php echo date_i18n(get_option('date_format'), strtotime($attempt->attempt_started_at)).' '.date_i18n(get_option('time_format'), strtotime($attempt->attempt_started_at)); ?> |
| 66 | </h4> |
| 67 | </div> |
| 68 | </div> |
| 69 | |
| 70 | <div class="attempt-info-col"> |
| 71 | <div class="attempt-info-content"> |
| 72 | <h5><?php echo __('Status', 'tutor'); ?></h5> |
| 73 | <h4> |
| 74 | <?php |
| 75 | $status = ucwords(str_replace('quiz_', '', $attempt->attempt_status)); |
| 76 | echo $status; |
| 77 | ?> |
| 78 | </h4> |
| 79 | </div> |
| 80 | </div> |
| 81 | </div> |
| 82 | |
| 83 | <div class="attempt-view-bottom"> |
| 84 | <div class="attempt-info-col"> |
| 85 | <div class="attempt-info-content"> |
| 86 | <h5><?php echo __('Course', 'tutor'); ?></h5> |
| 87 | <h4> |
| 88 | <?php |
| 89 | $quiz = tutor_utils()->get_course_by_quiz($attempt->quiz_id); |
| 90 | if ($quiz) { |
| 91 | echo "<a href='".admin_url( "post.php?post={$quiz->ID}&action=edit" ) . "'>". get_the_title( $quiz->ID )."</a>"; |
| 92 | } |
| 93 | ?> |
| 94 | </h4> |
| 95 | </div> |
| 96 | </div> |
| 97 | |
| 98 | <div class="attempt-info-col"> |
| 99 | <div class="attempt-info-content"> |
| 100 | <h5><?php echo __('Result', 'tutor'); ?></h5> |
| 101 | <h4> |
| 102 | <?php |
| 103 | $pass_mark_percent = tutor_utils()->get_quiz_option($attempt->quiz_id, 'passing_grade', 0); |
| 104 | $earned_percentage = $attempt->earned_marks > 0 ? ( number_format(($attempt->earned_marks * 100) / $attempt->total_marks)) : 0; |
| 105 | $output = ''; |
| 106 | if ($earned_percentage >= $pass_mark_percent){ |
| 107 | $output .= '<span class="result-pass">'.__('Pass', 'tutor').'</span>'; |
| 108 | }else{ |
| 109 | $output .= '<span class="result-fail">'.__('Fail', 'tutor').'</span>'; |
| 110 | } |
| 111 | |
| 112 | $output .= "".$attempt->earned_marks." out of {$attempt->total_marks}"; |
| 113 | $output .= "<div>Marks earned ({$earned_percentage}%)</div>"; |
| 114 | echo $output; |
| 115 | ?> |
| 116 | </h4> |
| 117 | </div> |
| 118 | </div> |
| 119 | |
| 120 | <div class="attempt-info-col"> |
| 121 | <div class="attempt-info-content"> |
| 122 | <h5><?php echo __('Quiz Time', 'tutor'); ?></h5> |
| 123 | <h4> |
| 124 | <?php |
| 125 | $time_limit_seconds = tutor_utils()->avalue_dot('time_limit.time_limit_seconds', $quiz_attempt_info); |
| 126 | echo tutor_utils()->seconds_to_time_context($time_limit_seconds); |
| 127 | ?> |
| 128 | </h4> |
| 129 | </div> |
| 130 | </div> |
| 131 | |
| 132 | <div class="attempt-info-col"> |
| 133 | <div class="attempt-info-content"> |
| 134 | <h5><?php echo __('Attempt Time', 'tutor'); ?></h5> |
| 135 | <h4> |
| 136 | <?php |
| 137 | $attempt_time_sec = strtotime($attempt->attempt_ended_at) - strtotime($attempt->attempt_started_at); |
| 138 | echo tutor_utils()->seconds_to_time_context($attempt_time_sec); |
| 139 | ?> |
| 140 | </h4> |
| 141 | </div> |
| 142 | |
| 143 | </div> |
| 144 | |
| 145 | </div> |
| 146 | |
| 147 | </div> |
| 148 | |
| 149 | |
| 150 | <div class="attempt-review-notice-wrap"> |
| 151 | <?php |
| 152 | if (is_array($answers) && count($answers)) { |
| 153 | $question_no = 0; |
| 154 | $required_review = array(); |
| 155 | |
| 156 | foreach ($answers as $answer){ |
| 157 | $question_no++; |
| 158 | if ($answer->question_type === 'open_ended' || $answer->question_type === 'short_answer'){ |
| 159 | $required_review[] = $question_no; |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | if (count($required_review)){ |
| 164 | echo '<p class="attempt-review-notice"> <i class="tutor-icon-warning-2"></i> <strong>Reminder: </strong> Please review answers for question no. '.implode(', ', $required_review).' </p>'; |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | |
| 169 | ?> |
| 170 | |
| 171 | <?php if ((bool) $attempt->is_manually_reviewed ){ |
| 172 | ?> |
| 173 | <p class="attempt-review-at"> |
| 174 | <span class="circle-arrow">↻ </span> |
| 175 | <strong> |
| 176 | <?php _e('Manually reviewed at: ', 'tutor'); ?> |
| 177 | </strong> |
| 178 | <?php echo date_i18n(get_option('date_format'), strtotime($attempt->manually_reviewed_at)).' '.date_i18n(get_option('time_format'), strtotime($attempt->manually_reviewed_at)); ?> |
| 179 | </p> |
| 180 | <?php |
| 181 | } ?> |
| 182 | |
| 183 | </div> |
| 184 | <?php |
| 185 | if (is_array($answers) && count($answers)){ |
| 186 | |
| 187 | ?> |
| 188 | <div class="quiz-attempt-answers-wrap"> |
| 189 | |
| 190 | <div class="attempt-answers-header"> |
| 191 | <h3><?php _e('Quiz Overview', 'tutor'); ?></h3> |
| 192 | </div> |
| 193 | |
| 194 | <table class="wp-list-table"> |
| 195 | <tr> |
| 196 | <th><?php _e('Type', 'tutor'); ?></th> |
| 197 | <th><?php _e('No.', 'tutor'); ?></th> |
| 198 | <th><?php _e('Question', 'tutor'); ?></th> |
| 199 | <th><?php _e('Given Answers', 'tutor'); ?></th> |
| 200 | <th><?php _e('Correct/Incorrect', 'tutor'); ?></th> |
| 201 | <th><?php _e('Manual Review', 'tutor'); ?></th> |
| 202 | </tr> |
| 203 | <?php |
| 204 | $answer_i = 0; |
| 205 | foreach ($answers as $answer){ |
| 206 | $answer_i++; |
| 207 | $question_type = tutor_utils()->get_question_types($answer->question_type); |
| 208 | ?> |
| 209 | <tr> |
| 210 | <td><?php echo $question_type['icon']; ?></td> |
| 211 | <td><?php echo $answer_i; ?></td> |
| 212 | <td><?php echo stripslashes($answer->question_title); ?></td> |
| 213 | <td> |
| 214 | <?php |
| 215 | if ($answer->question_type === 'true_false' || $answer->question_type === 'single_choice' ){ |
| 216 | $get_answers = tutor_utils()->get_answer_by_id($answer->given_answer); |
| 217 | $answer_titles = wp_list_pluck($get_answers, 'answer_title'); |
| 218 | $answer_titles = array_map('stripslashes', $answer_titles); |
| 219 | echo '<p>'.implode('</p><p>', $answer_titles).'</p>'; |
| 220 | }elseif ($answer->question_type === 'multiple_choice'){ |
| 221 | $get_answers = tutor_utils()->get_answer_by_id(maybe_unserialize($answer->given_answer)); |
| 222 | $answer_titles = wp_list_pluck($get_answers, 'answer_title'); |
| 223 | $answer_titles = array_map('stripslashes', $answer_titles); |
| 224 | echo '<p>'.implode('</p><p>', $answer_titles).'</p>'; |
| 225 | }elseif ($answer->question_type === 'fill_in_the_blank'){ |
| 226 | $answer_titles = maybe_unserialize($answer->given_answer); |
| 227 | $get_db_answers_by_question = tutor_utils()->get_answers_by_quiz_question($answer->question_id); |
| 228 | foreach ($get_db_answers_by_question as $db_answer); |
| 229 | $count_dash_fields = substr_count($db_answer->answer_title, '{dash}'); |
| 230 | if ($count_dash_fields){ |
| 231 | $dash_string = array(); |
| 232 | $input_data = array(); |
| 233 | for($i=0; $i<$count_dash_fields; $i++){ |
| 234 | //$dash_string[] = '{dash}'; |
| 235 | $input_data[] = isset($answer_titles[$i]) ? "<span class='filled_dash_unser'>{$answer_titles[$i]}</span>" : "______"; |
| 236 | } |
| 237 | $answer_title = $db_answer->answer_title; |
| 238 | foreach($input_data as $replace){ |
| 239 | $answer_title = preg_replace('/{dash}/i', $replace, $answer_title, 1); |
| 240 | } |
| 241 | echo str_replace('{dash}', '_____', $answer_title); |
| 242 | } |
| 243 | |
| 244 | }elseif ($answer->question_type === 'open_ended' || $answer->question_type === 'short_answer'){ |
| 245 | |
| 246 | if ($answer->given_answer){ |
| 247 | echo wpautop(stripslashes($answer->given_answer)); |
| 248 | } |
| 249 | |
| 250 | }elseif ($answer->question_type === 'ordering'){ |
| 251 | |
| 252 | $ordering_ids = maybe_unserialize($answer->given_answer); |
| 253 | foreach ($ordering_ids as $ordering_id){ |
| 254 | $get_answers = tutor_utils()->get_answer_by_id($ordering_id); |
| 255 | $answer_titles = wp_list_pluck($get_answers, 'answer_title'); |
| 256 | $answer_titles = array_map('stripslashes', $answer_titles); |
| 257 | echo '<p>'.implode('</p><p>', $answer_titles).'</p>'; |
| 258 | } |
| 259 | |
| 260 | }elseif ($answer->question_type === 'matching'){ |
| 261 | |
| 262 | $ordering_ids = maybe_unserialize($answer->given_answer); |
| 263 | $original_saved_answers = tutor_utils()->get_answers_by_quiz_question($answer->question_id); |
| 264 | |
| 265 | foreach ($original_saved_answers as $key => $original_saved_answer){ |
| 266 | $provided_answer_order_id = isset($ordering_ids[$key]) ? $ordering_ids[$key] : 0; |
| 267 | $provided_answer_order = tutor_utils()->get_answer_by_id($provided_answer_order_id); |
| 268 | if(tutils()->count($provided_answer_order)){ |
| 269 | foreach ($provided_answer_order as $provided_answer_order); |
| 270 | echo $original_saved_answer->answer_title ." - {$provided_answer_order->answer_two_gap_match} <br />"; |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | }elseif ($answer->question_type === 'image_matching'){ |
| 275 | |
| 276 | $ordering_ids = maybe_unserialize($answer->given_answer); |
| 277 | $original_saved_answers = tutor_utils()->get_answers_by_quiz_question($answer->question_id); |
| 278 | |
| 279 | echo '<div class="answer-image-matched-wrap">'; |
| 280 | foreach ($original_saved_answers as $key => $original_saved_answer){ |
| 281 | $provided_answer_order_id = isset($ordering_ids[$key]) ? $ordering_ids[$key] : 0; |
| 282 | $provided_answer_order = tutor_utils()->get_answer_by_id($provided_answer_order_id); |
| 283 | foreach ($provided_answer_order as $provided_answer_order); |
| 284 | ?> |
| 285 | <div class="image-matching-item"> |
| 286 | <p class="dragged-img-rap"><img src="<?php echo wp_get_attachment_image_url( $original_saved_answer->image_id); ?>" /> </p> |
| 287 | <p class="dragged-caption"><?php echo $provided_answer_order->answer_title; ?></p> |
| 288 | </div> |
| 289 | <?php |
| 290 | } |
| 291 | echo '</div>'; |
| 292 | }elseif ($answer->question_type === 'image_answering'){ |
| 293 | |
| 294 | $ordering_ids = maybe_unserialize($answer->given_answer); |
| 295 | |
| 296 | echo '<div class="answer-image-matched-wrap">'; |
| 297 | foreach ($ordering_ids as $answer_id => $image_answer){ |
| 298 | $db_answers = tutor_utils()->get_answer_by_id($answer_id); |
| 299 | foreach ($db_answers as $db_answer); |
| 300 | ?> |
| 301 | <div class="image-matching-item"> |
| 302 | <p class="dragged-img-rap"><img src="<?php echo wp_get_attachment_image_url( $db_answer->image_id); ?>" /> </p> |
| 303 | <p class="dragged-caption"><?php echo $image_answer; ?></p> |
| 304 | </div> |
| 305 | <?php |
| 306 | } |
| 307 | echo '</div>'; |
| 308 | } |
| 309 | |
| 310 | ?> |
| 311 | </td> |
| 312 | |
| 313 | <td> |
| 314 | <?php |
| 315 | |
| 316 | if ( (bool) isset( $answer->is_correct ) ? $answer->is_correct : '' ) { |
| 317 | echo '<span class="tutor-status-approved-context"><i class="tutor-icon-mark"></i> '.__('Correct', 'tutor').'</span>'; |
| 318 | } else { |
| 319 | if ($answer->question_type === 'open_ended' || $answer->question_type === 'short_answer'){ |
| 320 | echo '<p style="color: #878A8F;"><span style="color: #ff282a;">*</span> '.__('Review Required', 'tutor').'</p>'; |
| 321 | }else { |
| 322 | echo '<span class="tutor-status-blocked-context"><i class="tutor-icon-line-cross"></i> '.__('Incorrect', 'tutor').'</span>'; |
| 323 | } |
| 324 | } |
| 325 | ?> |
| 326 | </td> |
| 327 | |
| 328 | <td style="white-space: nowrap"> |
| 329 | <a href="javascript:;" data-attempt-id="<?php echo $attempt_id; ?>" data-attempt-answer-id="<?php echo $answer->attempt_answer_id; ?>" data-mark-as="correct" title="<?php _e('Mark as correct', 'tutor'); ?>" class="quiz-manual-review-action"><i class="tutor-icon-mark"></i> </a> |
| 330 | <a href="javascript:;" data-attempt-id="<?php echo $attempt_id; ?>" data-attempt-answer-id="<?php echo $answer->attempt_answer_id; ?>" data-mark-as="incorrect" title="<?php _e('Mark as In correct', 'tutor'); ?>" class="quiz-manual-review-action"><i class="tutor-icon-line-cross"></i></a> |
| 331 | </td> |
| 332 | </tr> |
| 333 | <?php |
| 334 | } |
| 335 | ?> |
| 336 | </table> |
| 337 | </div> |
| 338 | |
| 339 | <?php |
| 340 | } |
| 341 | ?> |
| 342 | </div> |