LLMS_Table_Students
LLMS_Table_Students class
Source Source
File: includes/admin/reporting/tables/llms.table.students.php
class LLMS_Table_Students extends LLMS_Admin_Table { /** * Unique ID for the Table * * @var string */ protected $id = 'students'; /** * Value of the field being filtered by * * Only applicable if $filterby is set. * * @since 3.31.0 * @var string */ protected $filter = ''; /** * Field results are filtered by * * @since 3.31.0 * @var string */ protected $filterby = 'course_membership'; /** * Is the Table Exportable? * * @var boolean */ protected $is_exportable = true; /** * Determine if the table is filterable * * @since 3.31.0 * @var boolean */ protected $is_filterable = true; /** * If true, tfoot will add ajax pagination links * * @var boolean */ protected $is_paginated = true; /** * Determine of the table is searchable * * @var boolean */ protected $is_searchable = true; /** * Results sort order * * 'ASC' or 'DESC' * Only applicable of $orderby is not set. * * @var string */ protected $order = 'ASC'; /** * Field results are sorted by * * @var string */ protected $orderby = 'name'; /** * Number of records to display per page * * @var int */ protected $per_page = 25; /** * Retrieve data for the columns * * @since 3.2.0 * @since 3.15.0 Unknown. * @since 3.36.0 Added "Last Seen" column. * @since 3.36.1 Fixed "Last Seen" column displaying wrong date when the student last login date was saved as timestamp. * @since 4.7.0 Speed up the query used to retrieve the last seen column by avoiding the found rows calculation. * @since 6.0.0 Don't access `LLMS_Events_Query` properties directly * Use `LLMS_Student::get_awards_count()` for retrieving the number of earned achievements and certificates. * * @param string $key The column id / key. * @param LLMS_Student $student Instance of the LLMS_Student. * @return mixed */ public function get_data( $key, $student ) { switch ( $key ) { case 'achievements': $url = LLMS_Admin_Reporting::get_current_tab_url( array( 'stab' => 'achievements', 'student_id' => $student->get_id(), ) ); $value = '<a href="' . esc_url( $url ) . '">' . $student->get_awards_count( 'achievement' ) . '</a>'; break; case 'certificates': $url = LLMS_Admin_Reporting::get_current_tab_url( array( 'stab' => 'certificates', 'student_id' => $student->get_id(), ) ); $value = '<a href="' . esc_url( $url ) . '">' . $student->get_awards_count( 'certificate' ) . '</a>'; break; case 'completions': $courses = $student->get_completed_courses(); $value = count( $courses['results'] ); break; case 'enrollments': $url = LLMS_Admin_Reporting::get_current_tab_url( array( 'stab' => 'courses', 'student_id' => $student->get_id(), ) ); $enrollments = $student->get_courses( array( 'limit' => 1, ) ); $value = '<a href="' . esc_url( $url ) . '">' . $enrollments['found'] . '</a>'; break; case 'id': $id = $student->get_id(); if ( current_user_can( 'list_users' ) ) { $value = '<a href="' . esc_url( get_edit_user_link( $id ) ) . '">' . $id . '</a>'; } else { $value = $id; } break; case 'last_seen': $query = new LLMS_Events_Query( array( 'actor' => $student->get_id(), 'per_page' => 1, 'sort' => array( 'date' => 'DESC', ), 'no_found_rows' => true, ) ); if ( $query->has_results() ) { $events = $query->get_events(); $last = array_shift( $events ); $value = $last->get( 'date' ); } else { $value = $student->get( 'last_login' ); } $value = $value ? date_i18n( get_option( 'date_format' ), is_numeric( $value ) ? $value : strtotime( $value ) ) : '–'; break; case 'memberships': $url = LLMS_Admin_Reporting::get_current_tab_url( array( 'stab' => 'memberships', 'student_id' => $student->get_id(), ) ); $value = '<a href="' . esc_url( $url ) . '">' . count( $student->get_membership_levels() ) . '</a>'; break; case 'name': $first = $student->get( 'first_name' ); $last = $student->get( 'last_name' ); if ( ! $first || ! $last ) { $value = $student->get( 'display_name' ); } else { $value = $last . ', ' . $first; } $url = LLMS_Admin_Reporting::get_current_tab_url( array( 'student_id' => $student->get_id(), ) ); $value = '<a href="' . esc_url( $url ) . '">' . $value . '</a>'; break; case 'overall_grade': $value = $student->get_overall_grade( true ); if ( is_numeric( $value ) ) { $value .= '%'; } break; case 'overall_progress': $value = $this->get_progress_bar_html( $student->get_overall_progress( true ) ); break; case 'registered': $value = $student->get_registration_date(); break; default: $value = $key; } return $this->filter_get_data( $value, $key, $student ); } /** * Retrieve data for a cell in an export file * * Should be overridden in extending classes. * * @since 3.15.0 * @since 3.26.1 Unknown. * * @param string $key The column id / key. * @param LLMS_Student $student Instance of the LLMS_Student. * @return mixed */ public function get_export_data( $key, $student ) { switch ( $key ) { case 'id': $value = $student->get_id(); break; case 'courses_cancelled': case 'courses_enrolled': case 'courses_expired': $status = explode( '_', $key ); $status = array_pop( $status ); $courses = $student->get_courses( array( 'status' => $status, ) ); $titles = array(); foreach ( $courses['results'] as $id ) { $titles[] = get_the_title( $id ); } $value = implode( ', ', $titles ); break; case 'email': $value = $student->get( 'user_email' ); break; case 'memberships_cancelled': case 'memberships_enrolled': case 'memberships_expired': $status = explode( '_', $key ); $status = array_pop( $status ); $memberships = $student->get_memberships( array( 'status' => $status, ) ); $titles = array(); foreach ( $memberships['results'] as $id ) { $titles[] = get_the_title( $id ); } $value = implode( ', ', $titles ); break; case 'name_first': $value = $student->get( 'first_name' ); break; case 'name_last': $value = $student->get( 'last_name' ); break; case 'overall_grade': $value = $student->get_overall_grade( false ); if ( is_numeric( $value ) ) { $value .= '%'; } break; case 'overall_progress': $value = $student->get_overall_progress( false ) . '%'; break; case 'billing_address_1': case 'billing_address_2': case 'billing_city': case 'billing_state': case 'billing_zip': case 'billing_country': case 'phone': $value = $student->get( $key ); break; default: $value = $this->get_data( $key, $student ); } return $this->filter_get_data( $value, $key, $student, 'export' ); } /** * Get the Text to be used as the placeholder in a searchable tables search input * * @since 3.2.0 * @since 3.15.0 Unknown. * * @return string */ public function get_table_search_form_placeholder() { return apply_filters( 'llms_table_get_' . $this->id . '_search_placeholder', __( 'Search students by name or email...', 'lifterlms' ) ); } /** * Get HTML for the filters displayed in the head of the table * * This overrides the LLMS_Admin_Table method. * * @since 3.31.0 * @since 3.37.2 Unknown. * * @return string */ public function get_table_filters_html() { $select_id = sprintf( '%1$s-%2$s-filter', $this->id, 'course-membership' ); $additional_data = array(); // Limit Course/Membership results based on instructor access. if ( ! current_user_can( 'view_others_lifterlms_reports' ) && current_user_can( 'view_lifterlms_reports' ) ) { $instructor = llms_get_instructor(); if ( $instructor ) { $additional_data[] = sprintf( 'data-instructor_id="%d"', $instructor->get( 'id' ) ); } } $additional_data = implode( ' ', $additional_data ); ob_start(); ?> <div class="llms-table-filters"> <div class="llms-table-filter-wrap"> <label class="screen-reader-text" for="<?php echo $select_id; ?>"> <?php _e( 'Choose Course/Membership', 'lifterlms' ); ?> </label> <select data-post-type="llms_membership,course" class="llms-posts-select2 llms-table-filter" id="<?php echo $select_id; ?>" name="course_membership" style="min-width:200px;max-width:500px;"<?php echo $additional_data; ?>></select> </div> </div> <?php return ob_get_clean(); } /** * Retrieve an array of query arguments to pass to the LLMS_Student_Query * * @since 3.28.0 * @since 3.31.0 Added logic to setup the query args in order to allow the filtering by Course or Membership. * * @return array */ private function get_query_args() { $query_args = array( 'page' => $this->get_current_page(), 'post_id' => array(), 'per_page' => $this->get_per_page(), 'sort' => $this->get_sort(), ); if ( 'status' === $this->get_filterby() && 'any' !== $this->get_filter() ) { $query_args['statuses'] = array( $this->get_filter() ); } elseif ( 'course_membership' === $this->get_filterby() && '' !== $this->get_filter() ) { $query_args['post_id'] = absint( $this->get_filter() ); $query_args['statuses'] = 'enrolled'; } if ( $this->get_search() ) { $query_args['search'] = $this->get_search(); } return $query_args; } /** * Execute a query to retrieve results from the table * * @since 3.2.0 * @since 3.28.0 Unknown. * @since 6.0.0 Don't access `LLMS_Student_Query` properties directly. * * @param array $args Array of query args. * @return void */ public function get_results( $args = array() ) { // Current user can't access this report. if ( ! current_user_can( 'view_others_lifterlms_reports' ) && ! current_user_can( 'view_lifterlms_reports' ) ) { return; } $this->parse_args( $args ); $query_args = $this->get_query_args(); if ( current_user_can( 'view_others_lifterlms_reports' ) ) { $query = new LLMS_Student_Query( $query_args ); } elseif ( current_user_can( 'view_lifterlms_reports' ) ) { $instructor = llms_get_instructor(); if ( ! $instructor ) { return; } $query = $instructor->get_students( $query_args ); } $this->max_pages = $query->get_max_pages(); $this->is_last_page = $query->is_last_page(); $this->tbody_data = $query->get_students(); } /** * Setup the array of sort arguments to pass to the LLMS_Student_Query for the table * * @since 3.28.0 * * @return array */ private function get_sort() { $sort = array(); switch ( $this->get_orderby() ) { case 'id': $sort = array( 'id' => $this->get_order(), ); break; case 'name': $sort = array( 'last_name' => $this->get_order(), 'first_name' => 'ASC', 'id' => 'ASC', ); break; case 'overall_grade': $sort = array( 'overall_grade' => $this->get_order(), 'last_name' => 'ASC', 'first_name' => 'ASC', 'id' => 'ASC', ); break; case 'overall_progress': $sort = array( 'overall_progress' => $this->get_order(), 'last_name' => 'ASC', 'first_name' => 'ASC', 'id' => 'ASC', ); break; case 'registered': $sort = array( 'registered' => $this->get_order(), 'last_name' => 'ASC', 'first_name' => 'ASC', 'id' => 'ASC', ); break; } return $sort; } /** * Parse arguments passed to get_results() method & setup table class variables. * * @since 3.28.0 * @since 3.31.0 Added logic to parse 'filterby' and 'filter' args when this table is filterable. * * @param array $args Array of arguments. * @return void */ protected function parse_args( $args = array() ) { if ( ! $args ) { $args = $this->get_args(); } $args = $this->clean_args( $args ); if ( isset( $args['page'] ) ) { $this->current_page = absint( $args['page'] ); } $this->order = isset( $args['order'] ) ? $args['order'] : $this->get_order(); $this->orderby = isset( $args['orderby'] ) ? $args['orderby'] : $this->get_orderby(); $this->per_page = isset( $args['per_page'] ) ? $args['per_page'] : $this->get_per_page(); if ( $this->is_filterable ) { $this->filterby = isset( $args['filterby'] ) ? $args['filterby'] : $this->get_filterby(); $this->filter = isset( $args['filter'] ) ? $args['filter'] : $this->get_filter(); } if ( isset( $args['search'] ) ) { $this->search = $args['search']; } } /** * Define the structure of arguments used to pass to the get_results method * * @since 2.3.0 * @since 3.28.0 Unknown. * * @return array */ public function set_args() { return array( 'per_page' => apply_filters( 'llms_table_' . $this->id . '_per_page', $this->per_page ), ); } /** * Define the structure of the table * * @since 3.2.0 * @since 3.15.0 Unknown. * @since 3.36.0 Add "Last Seen" column. * * @return array */ public function set_columns() { return array( 'id' => array( 'exportable' => true, 'sortable' => true, 'title' => __( 'ID', 'lifterlms' ), ), 'email' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Email', 'lifterlms' ), ), 'name' => array( 'sortable' => true, 'title' => __( 'Name', 'lifterlms' ), ), 'name_last' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Last Name', 'lifterlms' ), ), 'name_first' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'First Name', 'lifterlms' ), ), 'registered' => array( 'exportable' => true, 'sortable' => true, 'title' => __( 'Registration Date', 'lifterlms' ), ), 'last_seen' => array( 'exportable' => true, 'sortable' => false, 'title' => __( 'Last Seen', 'lifterlms' ), ), 'overall_progress' => array( 'exportable' => true, 'sortable' => true, 'title' => __( 'Progress', 'lifterlms' ), ), 'overall_grade' => array( 'exportable' => true, 'sortable' => true, 'title' => __( 'Grade', 'lifterlms' ), ), 'enrollments' => array( 'sortable' => false, 'title' => __( 'Enrollments', 'lifterlms' ), ), 'completions' => array( 'sortable' => false, 'title' => __( 'Completions', 'lifterlms' ), ), 'certificates' => array( 'sortable' => false, 'title' => __( 'Certificates', 'lifterlms' ), ), 'achievements' => array( 'sortable' => false, 'title' => __( 'Achievements', 'lifterlms' ), ), 'memberships' => array( 'sortable' => false, 'title' => __( 'Memberships', 'lifterlms' ), ), 'billing_address_1' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Billing Address 1', 'lifterlms' ), ), 'billing_address_2' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Billing Address 2', 'lifterlms' ), ), 'billing_city' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Billing City', 'lifterlms' ), ), 'billing_state' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Billing State', 'lifterlms' ), ), 'billing_zip' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Billing Zip', 'lifterlms' ), ), 'billing_country' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Billing Country', 'lifterlms' ), ), 'phone' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Phone', 'lifterlms' ), ), 'courses_enrolled' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Courses (Enrolled)', 'lifterlms' ), ), 'courses_cancelled' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Courses (Cancelled)', 'lifterlms' ), ), 'courses_expired' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Courses (Expired)', 'lifterlms' ), ), 'memberships_enrolled' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Memberships (Enrolled)', 'lifterlms' ), ), 'memberships_cancelled' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Memberships (Cancelled)', 'lifterlms' ), ), 'memberships_expired' => array( 'exportable' => true, 'export_only' => true, 'title' => __( 'Memberships (Expired)', 'lifterlms' ), ), ); } /** * Set the table's title. * * @since 3.28.0 * * @return string */ protected function set_title() { return __( 'Students', 'lifterlms' ); } }
Expand full source code Collapse full source code View on GitHub
Methods Methods
- get_data — Retrieve data for the columns
- get_export_data — Retrieve data for a cell in an export file
- get_query_args — Retrieve an array of query arguments to pass to the LLMS_Student_Query
- get_results — Execute a query to retrieve results from the table
- get_sort — Setup the array of sort arguments to pass to the LLMS_Student_Query for the table
- get_table_filters_html — Get HTML for the filters displayed in the head of the table
- get_table_search_form_placeholder — Get the Text to be used as the placeholder in a searchable tables search input
- parse_args — Parse arguments passed to get_results() method & setup table class variables.
- set_args — Define the structure of arguments used to pass to the get_results method
- set_columns — Define the structure of the table
- set_title — Set the table's title.
Changelog Changelog
Version | Description |
---|---|
3.37.2 | The post filter on the students table now limits post results based on instructor access. |
3.36.1 | Fixed "Last Seen" column displaying wrong date when the student last login date was saved as timestamp. |
3.36.0 | Add "Last Seen" column. |
3.31.0 | Allow filtering the table by Course or Membership |
3.28.0 | Unknown. |
3.2.0 | Introduced. |