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