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