Reports
Class for all reports related functions
Description
Source
File: bp-integrations/learndash/buddypress/Reports.php
class Reports { protected $isRealJoins = false; /** * Constructor * * @since BuddyBoss 1.0.0 */ public function __construct() { add_action('bp_ld_sync/init', [$this, 'init']); } /** * Add actions once integration is ready * * @since BuddyBoss 1.0.0 */ public function init() { add_action('bp_enqueue_scripts', [$this, 'registerReportsScript']); // add plugable templates to report actions add_action('bp_ld_sync/reports', [$this, 'showReportFilters'], 10); add_action('bp_ld_sync/reports', [$this, 'showReportUserStats'], 20); add_action('bp_ld_sync/reports', [$this, 'showReportCourseStats'], 20); add_action('bp_ld_sync/reports', [$this, 'showReportTables'], 30); add_action('bp_ld_sync/reports', [$this, 'showReportExport'], 40); add_filter('bp_ld_sync/reports_generator_params', [$this, 'forceOwnReportResults'], 99); add_filter('bp_ld_sync/reports_generator_params', [$this, 'courseReportResults'], 99); add_filter('bp_ld_sync/report_filters', [$this, 'removeCourseFilterIfOnlyOne']); add_filter('bp_ld_sync/report_filters', [$this, 'removeUserFilterIfStudent']); add_filter('learndash_user_activity_query_fields', [$this, 'reportAdditionalActivityFields'], 10, 2); add_filter('learndash_user_activity_query_tables', [$this, 'reportAdditionalActivityTables'], 10, 2); add_filter('learndash_user_activity_query_where', [$this, 'reportAdditionalActivityWheres'], 10, 2); add_filter('learndash_user_activity_query_where', [$this, 'reportAdditionalActivityGroups'], 15, 2); add_filter('bp_ld_sync/report_columns', [$this, 'removeUserColumnIfSelected'], 10, 2); add_filter('bp_ld_sync/report_columns', [$this, 'removeCourseColumnIfSelected'], 10, 2); add_filter('bp_ld_sync/report_columns', [$this, 'removePointsColumnIfNotAssigned'], 10, 2); add_action( 'bp_ld_sync/export_report_column', [ $this, 'export_report_column' ], 10, 2 ); } /** * Add scripts when it's on the reports page * * @since BuddyBoss 1.0.0 */ public function registerReportsScript() { if (! bp_is_groups_component() || ! bp_is_current_action('reports')) { return; } wp_enqueue_script('bp-ld-reports-datatable', '//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js', ['jquery'], false, true); wp_enqueue_style('bp-ld-reports-datatable', '//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css', [], false); wp_enqueue_script( 'bp-ld-reports', bp_learndash_url($filePath = '/assets/scripts/bp-learndash.js'), ['jquery', 'bp-ld-reports-datatable'], filemtime(bp_learndash_path($filePath)), true ); $per_page = bp_ld_sync('settings')->get('reports.per_page', 20); wp_localize_script('bp-ld-reports', 'BP_LD_REPORTS_DATA', [ 'current_group' => groups_get_current_group()->id, 'nonce' => wp_create_nonce('bp_ld_report'), 'ajax_url' => admin_url('admin-ajax.php'), 'table_columns' => $this->getCurrentTableColumns(), 'config' => [ 'perpage' => ( '' === $per_page ) ? 20 : $per_page ], 'text' => [ 'processing' => __('Loading…', 'buddyboss'), 'emptyTable' => __('No result found…', 'buddyboss'), 'paginate_first' => __('First', 'buddyboss'), 'paginate_last' => __('Last', 'buddyboss'), 'paginate_next' => __('Next', 'buddyboss'), 'export_failed' => __('Export failed, please refresh and try again.', 'buddyboss'), 'export_ready' => __('Export is ready.', 'buddyboss'), ] ]); wp_enqueue_style( 'bp-ld-reports', bp_learndash_url($filePath = '/assets/styles/bp-learndash.css'), [], filemtime(bp_learndash_path($filePath)) ); } /** * Output report filters html * * @since BuddyBoss 1.0.0 */ public function showReportFilters() { $filters = $this->getReportFilters(); require bp_locate_template('groups/single/reports-filters.php', false, false); } /** * Output report user stats html * * @since BuddyBoss 1.0.0 */ public function showReportUserStats() { if (empty($_GET['user'])) { return; } $courseId = bp_ld_sync()->getRequest('course'); $course = $courseId? get_post($courseId) : null; $group = groups_get_current_group(); $user = get_user_by('ID', $_GET['user']); require bp_locate_template('groups/single/reports-user-stats.php', false, false); } /** * Output report course stats html * * @since BuddyBoss 1.0.0 */ public function showReportCourseStats() { if (! empty($_GET['user']) || empty($_GET['course'])) { return; } $course = get_post($_GET['course']); $group = groups_get_current_group(); $ldGroupId = bp_ld_sync('buddypress')->helpers->getLearndashGroupId($group->id); $ldGroup = get_post($ldGroupId); $ldGroupUsers = learndash_get_groups_users($ldGroupId); $ldGroupUsersCompleted = array_filter($ldGroupUsers, function($user) use ($course) { return learndash_course_completed($user->ID, $course->ID); }); $courseHasPoints = !! $coursePoints = get_post_meta($course->ID, 'course_points', true); $averagePoints = $courseHasPoints? count($ldGroupUsersCompleted) * $coursePoints : 0; require bp_locate_template('groups/single/reports-course-stats.php', false, false); } /** * Output report results tables * * @since BuddyBoss 1.0.0 */ public function showReportTables() { $generator = $this->getCurrentGenerator(); $completed_table_title = $generator->completed_table_title ?: __('Completed', 'buddyboss'); $incompleted_table_title = $generator->incompleted_table_title ?: __('Incomplete', 'buddyboss'); require bp_locate_template('groups/single/reports-tables.php', false, false); } /** * Filter to sort the report by Course * * @since BuddyBoss 1.0.0 */ public function courseReportResults( $params ) { if ( ! empty( $_REQUEST['course'] ) && is_string( $_REQUEST['course'] ) ) { $params['course_ids'] = absint( $_REQUEST['course'] ); } return $params; } /** * Only allow non admin/mod to view his own reports * * @since BuddyBoss 1.0.0 */ public function forceOwnReportResults($params) { if (! $currentGroup = groups_get_current_group()) { return $params; } $userId = bp_loggedin_user_id(); $groupId = $currentGroup->id; if (groups_is_user_admin($userId, $groupId) || groups_is_user_mod($userId, $groupId) || is_user_admin() ) { return $params; } $params['user_ids'] = [bp_loggedin_user_id()]; return $params; } /** * Output report export button html * * @since BuddyBoss 1.0.0 */ public function showReportExport() { require bp_locate_template('groups/single/reports-export.php', false, false); } /** * Remove the filter if only 1 option available * * @since BuddyBoss 1.0.0 */ public function removeCourseFilterIfOnlyOne($filters) { if (! $currentGroup = groups_get_current_group()) { return $filters; } if (count(bp_learndash_get_group_courses($currentGroup->id)) < 2) { unset($filters['course']); } return $filters; } /** * Remove user filter is nond admin/mod are viewing reports tab * * @since BuddyBoss 1.0.0 */ public function removeUserFilterIfStudent($filters) { if (! $currentGroup = groups_get_current_group()) { return $filters; } // admin can always view if (learndash_is_admin_user()) { return $filters; } $userId = bp_loggedin_user_id(); $groupId = $currentGroup->id; if (! groups_is_user_admin($userId, $groupId) && ! groups_is_user_mod($userId, $groupId)) { unset($filters['user']); } return $filters; } /** * Sub filter for ld's activity sql query on fields * * @since BuddyBoss 1.0.0 */ public function reportAdditionalActivityFields($strFields, $queryArgs) { return apply_filters('bp_ld_sync/reports/activity_fields', $strFields, $queryArgs); } /** * Sub filter for ld's activity sql query on joins * * @since BuddyBoss 1.0.0 */ public function reportAdditionalActivityTables($strJoins, $queryArgs) { // Learndash Bug https://screencast.com/t/iBajWvdt if (! $this->isRealJoins()) { $this->isRealJoins = true; return $strJoins; } return apply_filters('bp_ld_sync/reports/activity_joins', $strJoins, $queryArgs); } /** * Sub filter for ld's activity sql query on wheres * * @since BuddyBoss 1.0.0 */ public function reportAdditionalActivityWheres($strWheres, $queryArgs) { return apply_filters('bp_ld_sync/reports/activity_wheres', $strWheres, $queryArgs); } /** * Sub filter for ld's activity sql query on group_by * * @since BuddyBoss 1.0.0 */ public function reportAdditionalActivityGroups($strWheres, $queryArgs) { return apply_filters('bp_ld_sync/reports/activity_groups', $strWheres, $queryArgs); } /** * Remove the user column if a user is selected in the filter * * @since BuddyBoss 1.0.0 */ public function removeUserColumnIfSelected($columns, $args) { if ($args['user']) { unset($columns['user']); } return $columns; } /** * Remove the course column if a course is selected in the filter * * @since BuddyBoss 1.0.0 */ public function removeCourseColumnIfSelected($columns, $args) { if ($args['course']) { unset($columns['course']); } return $columns; } /** * Remove the points column if all courses doesn't have points * * @since BuddyBoss 1.0.0 */ public function removePointsColumnIfNotAssigned($columns, $args) { $shouldRemove = false; if ($args['course']) { $shouldRemove = '' === get_post_meta($args['course'], 'course_points', true); } else { $groupCourses = bp_ld_sync('buddypress')->courses->getGroupCourses($args['group']); $shouldRemove = array_sum(array_map(function($course) use ($args) { return get_post_meta($args['course'], 'course_points', true) ?: 0; }, $groupCourses)) > 0; } if (! in_array($args['step'], ['all', learndash_get_post_type_slug('course')])) { unset($columns['points']); } if ($shouldRemove) { unset($columns['points']); } return $columns; } /** * Add status columns to export * * @since BuddyBoss 1.0.0 */ public function export_report_column( $columns, $report_generator ) { if ( ! empty( $report_generator->args['step'] ) && in_array( $report_generator->args['step'], array( 'forum' ) ) ) { $columns['status'] = $report_generator->column( 'status' ); } return $columns; } /** * Get available report generators * * @since BuddyBoss 1.0.0 */ public function getGenerators() { return apply_filters('bp_ld_sync/reports_generators', [ 'all' => [ 'name' => __('All Steps', 'buddyboss'), 'class' => '\Buddyboss\LearndashIntegration\Buddypress\Generators\AllReportsGenerator' ], learndash_get_post_type_slug('course') => [ 'name' => __('Courses', 'buddyboss'), 'class' => 'Buddyboss\LearndashIntegration\Buddypress\Generators\CoursesReportsGenerator' ], learndash_get_post_type_slug('lesson') => [ 'name' => __('Lessons', 'buddyboss'), 'class' => 'Buddyboss\LearndashIntegration\Buddypress\Generators\LessonsReportsGenerator' ], learndash_get_post_type_slug('topic') => [ 'name' => __('Topics', 'buddyboss'), 'class' => 'Buddyboss\LearndashIntegration\Buddypress\Generators\TopicsReportsGenerator' ], learndash_get_post_type_slug('quiz') => [ 'name' => __('Quizzes', 'buddyboss'), 'class' => 'Buddyboss\LearndashIntegration\Buddypress\Generators\QuizzesReportsGenerator' ], learndash_get_post_type_slug('essays') => [ 'name' => __('Essays', 'buddyboss'), 'class' => 'Buddyboss\LearndashIntegration\Buddypress\Generators\EssaysReportsGenerator' ], learndash_get_post_type_slug('assignment') => [ 'name' => __('Assignments', 'buddyboss'), 'class' => 'Buddyboss\LearndashIntegration\Buddypress\Generators\AssignmentsReportsGenerator' ], ]); } /** * Get available report filters * * @since BuddyBoss 1.0.0 */ protected function getReportFilters() { $filters = apply_filters('bp_ld_sync/report_filters', [ 'user' => [ 'name' => __('User', 'buddyboss'), 'position' => 10, 'options' => $this->getGroupUsersList() ], 'course' => [ 'name' => __('Course', 'buddyboss'), 'position' => 20, 'options' => $this->getGroupCoursesList() ], 'step' => [ 'name' => __('Step', 'buddyboss'), 'position' => 30, 'options' => $this->getStepTypes() ], ]); return wp_list_sort($filters, 'position', 'ASC', true); } /** * Get group's member list for filter * * @since BuddyBoss 1.0.0 */ protected function getGroupUsersList() { $generator = bp_ld_sync('buddypress')->sync->generator(groups_get_current_group()->id); $members = learndash_get_groups_users($generator->getLdGroupId()); array_unshift($members, (object) [ 'ID' => '', 'display_name' => __('All Students', 'buddyboss') ]); return wp_list_pluck($members, 'display_name', 'ID'); } /** * Get group's course list for filter * * @since BuddyBoss 1.0.0 */ protected function getGroupCoursesList() { $ldGroupId = bp_ld_sync( 'buddypress' )->helpers->getLearndashGroupId( groups_get_current_group()->id ); $courseIds = learndash_group_enrolled_courses( $ldGroupId ); /** * Filter to update course lists */ $courses = array_map( 'get_post', apply_filters( 'bp_ld_learndash_group_enrolled_courses', $courseIds, $ldGroupId ) ); array_unshift( $courses, (object) [ 'ID' => '', 'post_title' => __( 'All Courses', 'buddyboss' ) ] ); return wp_list_pluck( $courses, 'post_title', 'ID' ); } /** * Get list of steps available from all generators * * @since BuddyBoss 1.0.0 */ protected function getStepTypes() { return wp_list_pluck($this->getGenerators(), 'name'); } /** * Get the table columns on the current generator * * @since BuddyBoss 1.0.0 */ protected function getCurrentTableColumns() { return array_map([$this, 'getGeneratorColumns'], $this->getGenerators()); } /** * Get the class name for the current generator based on request value * * @since BuddyBoss 1.0.0 */ protected function getCurrentGenerator() { $step = bp_ld_sync()->getRequest('step', 'all'); $generator = $this->getGenerators()[$step]; return new $generator['class']; } /** * Convert generator columns to datatable js format by current generator * * @since BuddyBoss 1.0.0 */ protected function getGeneratorColumns($generator) { $columns = (new $generator['class'])->getColumns(); return array_map([$this, 'standarlizeGeneratorColumns'], $columns, array_keys($columns)); } /** * Convert generator columns to datatable js format * * @since BuddyBoss 1.0.0 */ protected function standarlizeGeneratorColumns($column, $key) { return [ 'title' => $column['label'], 'data' => $key, 'name' => $key, 'orderable' => $column['sortable'] ]; } /** * Fix bug on LD where they typed the action name wrong * * @since BuddyBoss 1.0.0 */ protected function isRealJoins() { if (in_array(current_filter(), ['learndash_user_activity_query_joins', 'learndash_user_activity_query_join'])) { return true; } return $this->isRealJoins; } }
Changelog
Version | Description |
---|---|
BuddyBoss 1.0.0 | Introduced. |
Methods
- __construct — Constructor
- courseReportResults — Filter to sort the report by Course
- export_report_column — Add status columns to export
- forceOwnReportResults — Only allow non admin/mod to view his own reports
- getCurrentGenerator — Get the class name for the current generator based on request value
- getCurrentTableColumns — Get the table columns on the current generator
- getGeneratorColumns — Convert generator columns to datatable js format by current generator
- getGenerators — Get available report generators
- getGroupCoursesList — Get group's course list for filter
- getGroupUsersList — Get group's member list for filter
- getReportFilters — Get available report filters
- getStepTypes — Get list of steps available from all generators
- init — Add actions once integration is ready
- isRealJoins — Fix bug on LD where they typed the action name wrong
- registerReportsScript — Add scripts when it's on the reports page
- removeCourseColumnIfSelected — Remove the course column if a course is selected in the filter
- removeCourseFilterIfOnlyOne — Remove the filter if only 1 option available
- removePointsColumnIfNotAssigned — Remove the points column if all courses doesn't have points
- removeUserColumnIfSelected — Remove the user column if a user is selected in the filter
- removeUserFilterIfStudent — Remove user filter is nond admin/mod are viewing reports tab
- reportAdditionalActivityFields — Sub filter for ld's activity sql query on fields
- reportAdditionalActivityGroups — Sub filter for ld's activity sql query on group_by
- reportAdditionalActivityTables — Sub filter for ld's activity sql query on joins
- reportAdditionalActivityWheres — Sub filter for ld's activity sql query on wheres
- showReportCourseStats — Output report course stats html
- showReportExport — Output report export button html
- showReportFilters — Output report filters html
- showReportTables — Output report results tables
- showReportUserStats — Output report user stats html
- standarlizeGeneratorColumns — Convert generator columns to datatable js format
Questions?
We're always happy to help with code or other questions you might have! Search our developer docs, contact support, or connect with our sales team.