header-context
2 months ago
attempt-details.php
9 months ago
attempt-table.php
9 months ago
contexts.php
3 years ago
header.php
11 months ago
instructor-feedback.php
11 months ago
attempt-table.php
203 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Attempt table |
| 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 | use Tutor\Models\QuizModel; |
| 13 | |
| 14 | // Data variable contains $attempt_list, $context. |
| 15 | extract( $data ); //phpcs:ignore WordPress.PHP.DontExtract.extract_extract |
| 16 | |
| 17 | $page_key = 'attempt-table'; |
| 18 | $table_columns = include __DIR__ . '/contexts.php'; |
| 19 | $enabled_hide_quiz_details = tutor_utils()->get_option( 'hide_quiz_details' ); |
| 20 | |
| 21 | if ( 'course-single-previous-attempts' == $context && is_array( $attempt_list ) && count( $attempt_list ) ) { |
| 22 | // Now attempt data is calculated based on the final grade calculation in settings. |
| 23 | $attempt_data = ( new QuizModel() )->get_quiz_attempt( $quiz_id, $user_id ); |
| 24 | include __DIR__ . '/header.php'; |
| 25 | } |
| 26 | ?> |
| 27 | |
| 28 | <?php if ( is_array( $attempt_list ) && count( $attempt_list ) ) : ?> |
| 29 | <div class="tutor-table-responsive tutor-dashboard-list-table <?php echo esc_attr( is_admin() ? '' : 'tutor-table-mobile tutor-mt-32' ); ?>"> |
| 30 | <table class="tutor-table tutor-table-quiz-attempts"> |
| 31 | <thead> |
| 32 | <tr> |
| 33 | <?php foreach ( $table_columns as $key => $column ) : ?> |
| 34 | <?php |
| 35 | /** |
| 36 | * Pro feature: Only for frontend |
| 37 | * |
| 38 | * @since 2.07 |
| 39 | */ |
| 40 | if ( 'details' === $key && ! is_admin() && ! current_user_can( 'tutor_instructor' ) && true === $enabled_hide_quiz_details ) { |
| 41 | continue; |
| 42 | } |
| 43 | ?> |
| 44 | |
| 45 | <th><?php echo $column; //phpcs:ignore -- contain safe data ?></th> |
| 46 | <?php endforeach; ?> |
| 47 | </tr> |
| 48 | </thead> |
| 49 | |
| 50 | <?php |
| 51 | $attempt_ids = array_column( $attempt_list, 'attempt_id' ); |
| 52 | $answers_array = \Tutor\Models\QuizModel::get_quiz_answers_by_attempt_id( $attempt_ids, true ); |
| 53 | ?> |
| 54 | |
| 55 | <tbody> |
| 56 | <?php foreach ( $attempt_list as $attempt ) : ?> |
| 57 | <?php |
| 58 | $course_id = is_object( $attempt ) && property_exists( $attempt, 'course_id' ) ? $attempt->course_id : 0; |
| 59 | $answers = isset( $answers_array[ $attempt->attempt_id ] ) ? $answers_array[ $attempt->attempt_id ] : array(); |
| 60 | $earned_percentage = QuizModel::calculate_attempt_earned_percentage( $attempt ); |
| 61 | |
| 62 | $attempt_result = QuizModel::get_attempt_result( $attempt->attempt_id ); |
| 63 | $is_result_pending = QuizModel::RESULT_PENDING === $attempt_result; |
| 64 | |
| 65 | $correct = 0; |
| 66 | $incorrect = 0; |
| 67 | $attempt_id = $attempt->attempt_id; |
| 68 | |
| 69 | if ( is_array( $answers ) && count( $answers ) > 0 ) { |
| 70 | foreach ( $answers as $answer ) { |
| 71 | if ( (bool) $answer->is_correct ) { |
| 72 | $correct++; |
| 73 | } elseif ( ! ( null === $answer->is_correct ) ) { |
| 74 | $incorrect++; |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | ?> |
| 79 | <tr> |
| 80 | <?php foreach ( $table_columns as $key => $column ) : ?> |
| 81 | <?php |
| 82 | /** |
| 83 | * Pro feature: Only for frontend |
| 84 | * |
| 85 | * @since 2.07 |
| 86 | */ |
| 87 | if ( 'details' === $key && ! is_admin() && ! current_user_can( 'tutor_instructor' ) && true === $enabled_hide_quiz_details ) { |
| 88 | continue; |
| 89 | } |
| 90 | ?> |
| 91 | <td data-title="<?php echo esc_attr( $column ); ?>"> |
| 92 | <?php if ( 'checkbox' == $key ) : ?> |
| 93 | <div class="tutor-d-flex"> |
| 94 | <input id="tutor-admin-list-<?php echo esc_attr( $attempt->attempt_id ); ?>" type="checkbox" class="tutor-form-check-input tutor-bulk-checkbox" name="tutor-bulk-checkbox-all" value="<?php echo esc_attr( $attempt->attempt_id ); ?>" /> |
| 95 | </div> |
| 96 | <?php elseif ( 'date' == $key ) : ?> |
| 97 | <?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $attempt->attempt_ended_at ) ) ); ?> |
| 98 | <?php elseif ( 'quiz_info' == $key ) : ?> |
| 99 | <div> |
| 100 | <div class="tutor-fs-7 tutor-fw-normal"> |
| 101 | <?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $attempt->attempt_ended_at ) ) ); ?> |
| 102 | </div> |
| 103 | <div class="tutor-mt-4"> |
| 104 | <?php |
| 105 | // For admin panel. |
| 106 | if ( is_admin() ) { |
| 107 | echo esc_html( get_the_title( $attempt->quiz_id ) ); |
| 108 | } else { |
| 109 | // For frontend. |
| 110 | echo esc_html( get_the_title( $attempt->quiz_id ) ); |
| 111 | ?> |
| 112 | <div class="tooltip-wrap tooltip-icon-custom" > |
| 113 | <i class="tutor-icon-circle-info-o tutor-color-muted tutor-ml-4 tutor-fs-7"></i> |
| 114 | <span class="tooltip-txt tooltip-right"> |
| 115 | <?php echo esc_html( get_the_title( $attempt->course_id ) ); ?> |
| 116 | </span> |
| 117 | </div> |
| 118 | <?php |
| 119 | } |
| 120 | ?> |
| 121 | </div> |
| 122 | <div class="tutor-fs-7 tutor-mt-8"> |
| 123 | <?php |
| 124 | $attempt_user = get_userdata( $attempt->user_id ); |
| 125 | $user_name = $attempt_user ? $attempt_user->display_name : ''; |
| 126 | ?> |
| 127 | <span class="tutor-color-secondary"><?php esc_html_e( 'Student:', 'tutor' ); ?></span> |
| 128 | <span class="tutor-fw-normal tutor-color-muted"><?php echo 'backend-dashboard-students-attempts' == $context ? esc_html( $user_name ) : esc_attr( isset( $attempt->display_name ) ? $attempt->display_name : $user_name ); ?></span> |
| 129 | </div> |
| 130 | <?php do_action( 'tutor_quiz/table/after/course_title', $attempt, $context ); ?> |
| 131 | </div> |
| 132 | <?php elseif ( 'course' == $key ) : ?> |
| 133 | <?php echo esc_html( get_the_title( $attempt->course_id ) ); ?> |
| 134 | <?php elseif ( 'question' == $key ) : ?> |
| 135 | <?php echo esc_html( count( $answers ) ); ?> |
| 136 | <?php elseif ( 'total_marks' == $key ) : ?> |
| 137 | <?php echo esc_html( isset( $attempt->total_marks ) ? round( $attempt->total_marks ) : '0' ); ?> |
| 138 | <?php elseif ( 'correct_answer' == $key ) : ?> |
| 139 | <?php echo esc_html( $correct ); ?> |
| 140 | <?php elseif ( 'incorrect_answer' == $key ) : ?> |
| 141 | <?php echo esc_html( $incorrect ); ?> |
| 142 | <?php elseif ( 'earned_marks' == $key ) : ?> |
| 143 | <?php echo esc_html( isset( $attempt->earned_marks ) ? round( $attempt->earned_marks ) . ' (' . $earned_percentage . '%)' : '0 (0%)' ); ?> |
| 144 | <?php elseif ( 'result' == $key ) : ?> |
| 145 | <?php |
| 146 | if ( $is_result_pending ) { |
| 147 | echo '<span class="tutor-badge-label label-warning">' . esc_html__( 'Pending', 'tutor' ) . '</span>'; |
| 148 | } else { |
| 149 | echo QuizModel::RESULT_PASS === $attempt_result |
| 150 | ? '<span class="tutor-badge-label label-success">' . esc_html__( 'Pass', 'tutor' ) . '</span>' |
| 151 | : '<span class="tutor-badge-label label-danger">' . esc_html__( 'Fail', 'tutor' ) . '</span>'; |
| 152 | } |
| 153 | ?> |
| 154 | <?php elseif ( 'details' == $key ) : ?> |
| 155 | <?php |
| 156 | $url_args = array( 'view_quiz_attempt_id' => $attempt->attempt_id ); |
| 157 | $admin_url = add_query_arg( $url_args, admin_url( 'admin.php?page=tutor_quiz_attempts' ) ); |
| 158 | $front_url = add_query_arg( $url_args, tutor()->current_url ); |
| 159 | $url = is_admin() ? $admin_url : $front_url; |
| 160 | $style = ''; |
| 161 | ?> |
| 162 | <div class="tutor-d-inline-flex tutor-align-center" style="<?php echo esc_attr( ! is_admin() ? $style : '' ); ?>"> |
| 163 | <a href="<?php echo esc_url( $url ); ?>" class="tutor-btn tutor-btn-tertiary tutor-btn-sm"> |
| 164 | <?php |
| 165 | if ( $is_result_pending && ( 'frontend-dashboard-students-attempts' === $context || 'backend-dashboard-students-attempts' === $context ) ) { |
| 166 | esc_html_e( 'Review', 'tutor' ); |
| 167 | } else { |
| 168 | esc_html_e( 'Details', 'tutor' ); |
| 169 | } |
| 170 | ?> |
| 171 | </a> |
| 172 | <?php |
| 173 | $current_page = tutor_utils()->get_current_page_slug(); |
| 174 | if ( ! is_admin() && $course_id && ( tutor_utils()->is_instructor_of_this_course( get_current_user_id(), $course_id ) || current_user_can( 'administrator' ) ) ) : |
| 175 | ?> |
| 176 | <!-- Don't show delete option on the spotlight section since JS not support --> |
| 177 | <?php if ( 'quiz-attempts' === $current_page || 'tutor_quiz_attempts' === $current_page ) : ?> |
| 178 | <a href="#" class="tutor-quiz-attempt-delete tutor-iconic-btn tutor-flex-shrink-0 tutor-ml-4" data-quiz-id="<?php echo esc_attr( $attempt_id ); ?>" data-tutor-modal-target="tutor-common-confirmation-modal"> |
| 179 | <i class="tutor-icon-trash-can-line" data-quiz-id="<?php echo esc_attr( $attempt_id ); ?>"></i> |
| 180 | </a> |
| 181 | <?php endif; ?> |
| 182 | <?php endif; ?> |
| 183 | </div> |
| 184 | <?php endif; ?> |
| 185 | </td> |
| 186 | <?php endforeach; ?> |
| 187 | </tr> |
| 188 | <?php endforeach; ?> |
| 189 | </tbody> |
| 190 | </table> |
| 191 | </div> |
| 192 | <?php else : ?> |
| 193 | <?php tutils()->render_list_empty_state(); ?> |
| 194 | <?php endif; ?> |
| 195 | <?php |
| 196 | // Load delete modal. |
| 197 | tutor_load_template_from_custom_path( |
| 198 | tutor()->path . 'views/elements/common-confirm-popup.php', |
| 199 | array( |
| 200 | 'message' => __( 'Would you like to delete Quiz Attempt permanently? We suggest you proceed with caution.', 'tutor' ), |
| 201 | ) |
| 202 | ); |
| 203 |