PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.1
Tutor LMS – eLearning and online course solution v4.0.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 / templates / dashboard / my-quiz-attempts.php
tutor / templates / dashboard Last commit date
account 4 days ago components 4 days ago courses 4 days ago discussions 4 days ago elements 4 days ago instructor 4 days ago my-courses 1 year ago my-quiz-attempts 4 days ago quiz-attempts 4 days ago student 4 days ago wishlist 4 days ago announcements.php 4 days ago courses.php 4 days ago create-course.php 4 days ago dashboard.php 4 days ago discussions.php 4 days ago index.php 3 years ago logged-in.php 3 years ago my-courses.php 4 days ago my-quiz-attempts.php 4 days ago quiz-attempts.php 4 days ago registration.php 4 days ago wishlist.php 4 days ago
my-quiz-attempts.php
196 lines
1 <?php
2 /**
3 * My Quiz Attempts
4 *
5 * @package Tutor\Templates
6 * @subpackage Dashboard
7 * @author Themeum <support@themeum.com>
8 * @link https://themeum.com
9 * @since 1.1.2
10 */
11
12 defined( 'ABSPATH' ) || exit;
13
14 use Tutor\Components\Button;
15 use Tutor\Components\ConfirmationModal;
16 use Tutor\Components\Constants\Variant;
17 use Tutor\Components\DropdownFilter;
18 use Tutor\Components\EmptyState;
19 use Tutor\Components\Pagination;
20 use Tutor\Components\Sorting;
21 use Tutor\Helpers\QueryHelper;
22 use TUTOR\Input;
23 use Tutor\Models\QuizModel;
24 use TUTOR\Quiz_Attempts_List;
25
26 if ( Input::has( 'attempt_id', Input::GET_REQUEST ) ) {
27 // Load single attempt details if ID provided.
28 include __DIR__ . '/my-quiz-attempts/attempts-details.php';
29 return;
30 }
31
32 $url = get_pagenum_link( 1, false );
33 $item_per_page = tutor_utils()->get_option( 'pagination_per_page' );
34 $current_page = max( 1, Input::get( 'current_page', 1, Input::TYPE_INT ) );
35 $current_user_id = get_current_user_id();
36 $offset = ( $current_page - 1 ) * $item_per_page;
37 $quiz_attempt_obj = new Quiz_Attempts_List( false );
38 $quiz_model = new QuizModel();
39
40
41 // Filter params.
42 $order_filter = QueryHelper::get_valid_sort_order( Input::get( 'order', 'DESC' ) );
43 $course_id = isset( $course_id ) ? $course_id : array();
44 $result_filter = Input::get( 'result', '' );
45
46 $quizzes = QuizModel::get_attempted_quizzes( $current_user_id, $course_id, $offset, $item_per_page, $order_filter, array( 'status' => $result_filter ) );
47 $all_quizzes = QuizModel::get_attempted_quizzes( $current_user_id, $course_id, 0, 0, $order_filter );
48
49 $quiz_attempts_list = array();
50 $quiz_attempts_count = 0;
51 $nav_links = array();
52
53 if ( tutor_utils()->count( $quizzes ) ) {
54 $quiz_attempts_count = isset( $quizzes['total_count'] ) ? $quizzes['total_count'] : 0;
55 $results = isset( $quizzes['results'] ) ? $quizzes['results'] : array();
56 $quiz_attempts_list = $quiz_model->get_formatted_quiz_attempt_list_by_quiz_id( $results, $result_filter );
57 }
58
59 if ( tutor_utils()->count( $all_quizzes ) ) {
60 $nav_links = $quiz_attempt_obj->get_quiz_attempts_nav_data( $quiz_attempts_count, $url, $result_filter, '', 0, '', '', $order_filter, $all_quizzes );
61 }
62
63 ?>
64 <div class="tutor-my-quiz-attempts-wrapper" x-data="tutorQuizAttempts()">
65 <div class="tutor-quiz-attempts">
66 <div class="tutor-quiz-students-attempts-filter tutor-flex tutor-justify-between tutor-surface-l1 tutor-px-6 tutor-py-5 tutor-sm-p-5 tutor-items-center tutor-border-b">
67 <div class="tutor-quiz-students-attempts-filter-item">
68 <?php
69 if ( isset( $nav_links['options'] ) ) {
70 DropdownFilter::make()
71 ->options( $nav_links['options'] )
72 ->query_param( 'result' )
73 ->render();
74 }
75 ?>
76 </div>
77 <div class="tutor-quiz-students-attempts-filter-item tutor-flex tutor-items-center tutor-gap-4">
78 <?php
79
80 if ( Input::has_any( array( 'result', 'order' ), Input::GET_REQUEST ) ) {
81 Button::make()
82 ->tag( 'a' )
83 ->attr( 'href', tutor_utils()->tutor_dashboard_url( 'courses/my-quiz-attempts' ) )
84 ->attr( 'class', 'tutor-text-brand' )
85 ->label( __( 'Clear all', 'tutor' ) )
86 ->variant( Variant::LINK )
87 ->render();
88 }
89 Sorting::make()->order( $order_filter )->render();
90
91 ?>
92 </div>
93 </div>
94 <?php if ( $quiz_attempts_count ) : ?>
95 <div class="tutor-quiz-attempts-header">
96 <div class="tutor-quiz-attempts-header-item"><?php esc_html_e( 'Quiz info', 'tutor' ); ?></div>
97 <div class="tutor-quiz-attempts-header-item"><?php esc_html_e( 'Marks', 'tutor' ); ?></div>
98 <div class="tutor-quiz-attempts-header-item"><?php esc_html_e( 'Time', 'tutor' ); ?></div>
99 <div class="tutor-quiz-attempts-header-item"><?php esc_html_e( 'Result', 'tutor' ); ?></div>
100 </div>
101 <div class="tutor-quiz-attempts-list">
102 <?php
103 foreach ( $quiz_attempts_list as $quiz_index => $quiz_attempt ) :
104 $attempts = $quiz_attempt['attempts'];
105 $attempts_count = count( $attempts );
106 $quiz_id = $quiz_attempt['quiz_id'] ?? 0;
107 $course_id = $quiz_attempt['course_id'] ?? 0;
108 $first_attempt = $attempts[0];
109 $remaining_attempts = array_slice( $attempts, 1 );
110 ?>
111 <div x-data="{ expanded: false }" class="tutor-quiz-attempts-item-wrapper" :class="{ 'tutor-quiz-previous-attempts': expanded }">
112 <!-- First Attempt (Always Visible with Quiz Title & Expand Button) -->
113 <?php
114 tutor_load_template(
115 'shared.components.student-quiz-attempt-row',
116 array(
117 'attempt' => $first_attempt,
118 'quiz_title' => $quiz_attempt['quiz_title'] ?? '',
119 'course_title' => $quiz_attempt['course_title'] ?? '',
120 'course_id' => $course_id,
121 'show_quiz_title' => true,
122 'show_course' => true,
123 'quiz_id' => $quiz_id,
124 'attempts_count' => $attempts_count,
125 'attempt_id' => $first_attempt['attempt_id'] ?? 0,
126 'quiz_attempt_obj' => $quiz_attempt_obj,
127 )
128 );
129 ?>
130
131 <!-- Additional Attempts (Collapsible) -->
132 <?php if ( ! empty( $remaining_attempts ) ) : ?>
133 <div x-show="expanded" x-collapse x-cloak class="tutor-quiz-previous-attempts">
134 <div class="tutor-text-tiny tutor-text-subdued tutor-py-4 tutor-px-6 tutor-quiz-previous-attempts-title">
135 <?php esc_html_e( 'Previous Attempts', 'tutor' ); ?>
136 </div>
137 <?php foreach ( $remaining_attempts as $key => $attempt ) : ?>
138 <?php
139 tutor_load_template(
140 'shared.components.student-quiz-attempt-row',
141 array(
142 'attempt' => $attempt,
143 'attempt_number' => count( $remaining_attempts ) - $key,
144 'quiz_id' => $quiz_id,
145 'attempt_id' => $attempt['attempt_id'] ?? 0,
146 'course_id' => $course_id,
147 'quiz_attempt_obj' => $quiz_attempt_obj,
148 'is_previous' => true,
149 )
150 );
151 ?>
152 <?php endforeach; ?>
153 </div>
154 <?php endif; ?>
155
156 <div class="tutor-quiz-item-actions" x-show="!expanded" x-cloak>
157 <?php
158 $quiz_attempt_obj->render_details_button( $first_attempt );
159 $quiz_attempt_obj->render_student_attempt_popover( $first_attempt, $attempts_count, $quiz_id, false, false );
160 ?>
161 </div>
162 </div>
163 <?php endforeach; ?>
164 <?php
165 Pagination::make()
166 ->current( $current_page )
167 ->total( $quiz_attempts_count )
168 ->limit( $item_per_page )
169 ->attr( 'class', 'tutor-p-6' )
170 ->render();
171 ?>
172 </div>
173 <?php else : ?>
174 <?php
175 EmptyState::make()
176 ->title( __( 'No Quiz Attempts Found', 'tutor' ) )
177 ->icon( tutor_utils()->get_themed_svg( 'images/illustrations/quiz-empty.svg' ) )
178 ->render();
179 ?>
180 <?php endif; ?>
181
182 <div x-data="tutorQuizRetryAttempt()">
183 <?php
184 ConfirmationModal::make()
185 ->id( 'tutor-retry-modal' )
186 ->title( __( 'Retake Quiz?', 'tutor' ) )
187 ->icon( tutor_utils()->get_themed_svg( 'images/illustrations/quiz-retry.svg' ), 80, 80, ConfirmationModal::ICON_TYPE_HTML )
188 ->message( __( 'Retrying this quiz will reset your current attempt. Your answers and score from this attempt will be lost.', 'tutor' ) )
189 ->confirm_handler( 'retryMutation?.mutate({...payload?.data})' )
190 ->confirm_text( __( 'Retry Quiz', 'tutor' ) )
191 ->mutation_state( 'retryMutation' )
192 ->render();
193 ?>
194 </div>
195 </div>
196