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