PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.9.9
Tutor LMS – eLearning and online course solution v3.9.9
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-table.php
tutor / views / quiz Last commit date
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