at path:
ROOT
/
wp-content
/
plugins
/
tutor
/
classes
/
Quiz_Attempts_List.php
run:
R
W
Run
Addons.php
11.79 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Admin.php
26.61 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Ajax.php
17.03 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Announcements.php
2.79 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Assets.php
24.27 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Backend_Page_Trait.php
4.39 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
BaseController.php
1.47 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Config.php
3.16 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Container.php
4.85 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Course.php
94.45 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Course_Embed.php
2.55 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Course_Filter.php
8.68 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Course_List.php
14.68 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Course_Settings_Tabs.php
1.16 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Course_Widget.php
8.2 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Custom_Validation.php
513 By
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Dashboard.php
1.23 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Earnings.php
10.43 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
FormHandler.php
7.16 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Frontend.php
2.94 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Gutenberg.php
4.62 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Icon.php
11.49 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Input.php
9.08 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Instructor.php
13.2 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Instructors_List.php
13.09 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Lesson.php
19.92 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Options_V2.php
67.77 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Permalink.php
2 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Post_types.php
18.3 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Private_Course_Access.php
2.52 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Q_And_A.php
10.78 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Question_Answers_List.php
2.55 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Quiz.php
35.16 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
QuizBuilder.php
12.53 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Quiz_Attempts_List.php
7.28 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
RestAPI.php
7.97 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Reviews.php
3.72 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Rewrite_Rules.php
5.18 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Shortcode.php
14.18 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Singleton.php
1.08 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Student.php
10.44 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Students_List.php
3.03 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Taxonomies.php
8.2 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Template.php
14.52 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Theme_Compatibility.php
683 By
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Tools.php
3.33 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Tools_V2.php
18.56 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Tutor.php
36.45 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
TutorEDD.php
4.69 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Tutor_Base.php
1.48 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Tutor_Setup.php
33.34 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Upgrader.php
12.49 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
User.php
14.9 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Utils.php
270.91 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Video_Stream.php
3.94 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
WhatsNew.php
4.83 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Withdraw.php
9.49 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
Withdraw_Requests_List.php
6.24 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
WooCommerce.php
24.76 KB
2026-04-14 05:34:26
R
W
Run
Delete
Rename
error_log
up
📄
Quiz_Attempts_List.php
Save
<?php /** * Quiz attempt list management * * @package Tutor\QuestionAnswer * @author Themeum <support@themeum.com> * @link https://themeum.com * @since 1.0.0 */ namespace TUTOR; if ( ! defined( 'ABSPATH' ) ) { exit; } use Tutor\Cache\QuizAttempts; use Tutor\Models\QuizModel; /** * Quiz attempt class * * @since 1.0.0 */ class Quiz_Attempts_List { const QUIZ_ATTEMPT_PAGE = 'tutor_quiz_attempts'; /** * Trait for utilities * * @var $page_title */ use Backend_Page_Trait; /** * Bulk Action * * @var $bulk_action */ public $bulk_action = true; /** * Handle dependencies * * @since 1.0.0 * * @param boolean $register_hook should register hook or not. */ public function __construct( $register_hook = true ) { if ( ! $register_hook ) { return; } /** * Handle bulk action * * @since 2.0.0 */ add_action( 'wp_ajax_tutor_quiz_attempts_bulk_action', array( $this, 'quiz_attempts_bulk_action' ) ); add_action( 'wp_ajax_tutor_quiz_attempts_count', array( $this, 'get_quiz_attempts_stat' ) ); /** * Delete quiz attempt cache * * @since 2.1.0 */ add_action( 'tutor_quiz/attempt_ended', array( new QuizAttempts(), 'delete_cache' ) ); add_action( 'tutor_quiz/attempt_deleted', array( new QuizAttempts(), 'delete_cache' ) ); add_action( 'tutor_quiz/answer/review/after', array( new QuizAttempts(), 'delete_cache' ) ); } /** * Page title fallback * * @since 3.5.0 * * @param string $name Property name. * * @return string */ public function __get( $name ) { if ( 'page_title' === $name ) { return esc_html__( 'Quiz Attempts', 'tutor' ); } } /** * Get the attempts stat from specific instructor context * * @since 2.0.0 * @since 3.8.0 refactor and query optimize. * * @return array */ public function get_quiz_attempts_stat() { global $wpdb; if ( wp_doing_ajax() ) { tutor_utils()->checking_nonce(); } $count_obj = (object) array( 'pass' => 0, 'fail' => 0, 'pending' => 0, ); $is_ajax_action = 'tutor_quiz_attempts_count' === Input::post( 'action' ); $user_id = get_current_user_id(); $course_id = Input::post( 'course_id', 0, Input::TYPE_INT ); $date = Input::post( 'date', '' ); $search = Input::post( 'search', '' ); if ( $is_ajax_action ) { $current_params = compact( 'course_id', 'date', 'search' ); $attempt_cache = new QuizAttempts( $current_params ); $cached_attempts = $attempt_cache->get_cache(); if ( $attempt_cache->has_cache() && $attempt_cache->is_same_query() && isset( $cached_attempts['result'] ) ) { $count_obj = $cached_attempts['result']; } else { $course_filter = $course_id ? $wpdb->prepare( ' AND quiz_attempts.course_id = %d', $course_id ) : ''; $date_filter = empty( $date ) ? '' : $wpdb->prepare( ' AND DATE(quiz_attempts.attempt_started_at) = %s ', $date ); $user_clause = User::is_admin() ? '' : $wpdb->prepare( ' AND quiz.post_author = %d', $user_id ); $search_term_raw = $search; $search_filter = '%' . $wpdb->esc_like( $search ) . '%'; //phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $results = $wpdb->get_results( $wpdb->prepare( "SELECT result, COUNT( DISTINCT attempt_id) AS total FROM {$wpdb->prefix}tutor_quiz_attempts quiz_attempts INNER JOIN {$wpdb->posts} quiz ON quiz_attempts.quiz_id = quiz.ID INNER JOIN {$wpdb->users} AS users ON quiz_attempts.user_id = users.ID INNER JOIN {$wpdb->posts} AS course ON course.ID = quiz_attempts.course_id WHERE result IS NOT NULL AND ( users.user_email = %s OR users.display_name LIKE %s OR quiz.post_title LIKE %s OR course.post_title LIKE %s ) {$user_clause} {$course_filter} {$date_filter} GROUP BY result", $search_term_raw, $search_filter, $search_filter, $search_filter ) ); //phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared foreach ( $results as $row ) { if ( isset( $count_obj->{$row->result} ) ) { $count_obj->{$row->result} = (int) $row->total; } } $attempt_cache->data = $count_obj; $attempt_cache->set_cache(); } } $all = $count_obj->pass + $count_obj->fail + $count_obj->pending; $pass = $count_obj->pass; $fail = $count_obj->fail; $pending = $count_obj->pending; $response = compact( 'all', 'pass', 'fail', 'pending' ); return $is_ajax_action ? wp_send_json_success( $response ) : $response; } /** * Available tabs that will visible on the right side of page navbar * * @since 2.0.0 * * @param string $user_id selected quiz_attempts id | optional. * @param int $course_id selected quiz_attempts id | optional. * @param string $date selected date | optional. * @param string $search search by user name or email | optional. * * @return array */ public function tabs_key_value( $user_id, $course_id, $date, $search ): array { $url = apply_filters( 'tutor_data_tab_base_url', get_pagenum_link() ); $stats = $this->get_quiz_attempts_stat(); $tabs = array( array( 'key' => '', 'title' => __( 'All', 'tutor' ), 'value' => $stats['all'], 'url' => $url . '&data=all', ), array( 'key' => 'pass', 'title' => __( 'Pass', 'tutor' ), 'value' => $stats['pass'], 'url' => $url . '&data=pass', ), array( 'key' => 'fail', 'title' => __( 'Fail', 'tutor' ), 'value' => $stats['fail'], 'url' => $url . '&data=fail', ), array( 'key' => 'pending', 'title' => __( 'Pending', 'tutor' ), 'value' => $stats['pending'], 'url' => $url . '&data=pending', ), ); return $tabs; } /** * Prepare bulk actions that will show on dropdown options * * @since 2.0.0 * * @return array */ public function prepare_bulk_actions(): array { $actions = array( $this->bulk_action_default(), $this->bulk_action_delete(), ); return $actions; } /** * Handle bulk action for instructor delete * * @since 2.0.0 * * @return void send wp_json response */ public function quiz_attempts_bulk_action() { // check nonce. tutor_utils()->checking_nonce(); // Check if user is privileged. if ( ! User::has_any_role( array( User::ADMIN, User::INSTRUCTOR ) ) ) { wp_send_json_error( tutor_utils()->error_message() ); } $bulk_action = Input::post( 'bulk-action', '' ); $bulk_ids = Input::post( 'bulk-ids', '' ); $bulk_ids = explode( ',', $bulk_ids ); $bulk_ids = array_map( function( $id ) { return (int) trim( $id ); }, $bulk_ids ); // prevent instructor to remove quiz attempt from admin. $bulk_ids = array_filter( $bulk_ids, function ( $attempt_id ) { $attempt = tutor_utils()->get_attempt( $attempt_id ); $user_id = get_current_user_id(); $course_id = $attempt && is_object( $attempt ) ? $attempt->course_id : 0; return $course_id && tutor_utils()->can_user_edit_course( $user_id, $course_id ); } ); switch ( $bulk_action ) { case 'delete': QuizModel::delete_quiz_attempt( $bulk_ids ); break; } wp_send_json_success(); } /** * Get bulk action as an array * * @since 2.0.0 * * @return array */ public function get_bulk_actions() { $actions = array( 'delete' => 'Delete', ); return $actions; } }