Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/issue 2802 - Include private lessons in course completion count #2879

Open
wants to merge 22 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e945d55
Include private lessons in course completion check
JuanchoPestana Feb 1, 2020
bf41506
Fix sniffer issues in current function
JuanchoPestana Feb 1, 2020
705ad6e
01. Course archive - fix lesson count
JuanchoPestana Apr 23, 2020
0599aaa
02. Single course - fix display private lessons
JuanchoPestana Apr 23, 2020
5a443e2
Merge branch 'master' into fix/issue-2802
JuanchoPestana Apr 23, 2020
35733ba
03. Private course - fix is_enrolled() function
JuanchoPestana Apr 23, 2020
f23ddb8
03. Private Course - fix sniffer issue
JuanchoPestana Apr 23, 2020
77dfb74
04. Single course - fix lesson count
JuanchoPestana Apr 23, 2020
052c056
05. My courses - fix private lessons not appearing
JuanchoPestana Apr 24, 2020
22d7d6a
06. Single course - fix completion status not working in private courses
JuanchoPestana Apr 24, 2020
bc236c5
07. Grading - fix dropdown not including private lessons
JuanchoPestana Apr 24, 2020
d71fc30
08. Learners Management - fix table does not include private courses
JuanchoPestana Apr 24, 2020
4cc55d6
09. Learners Management - fix table does not include private lessons
JuanchoPestana Apr 24, 2020
8b31c65
10. Dashboard - fix at a glance widget
JuanchoPestana Apr 24, 2020
cc70f3a
11. New Lesson - fix lesson prerequisite dropdown
JuanchoPestana Apr 24, 2020
b383d97
12. New Course - fix course prerequisite dropdown
JuanchoPestana Apr 24, 2020
eeb9657
13. New Lesson - fix add lesson to course order
JuanchoPestana Apr 24, 2020
b6f04e8
14. Single course module - fix error in module progress calculation
JuanchoPestana Apr 24, 2020
e19e69d
15. Modules - fix table not displaying private lessons
JuanchoPestana Apr 24, 2020
459d059
16. Authors - fix lesson count
JuanchoPestana Apr 24, 2020
53f7338
17. Teacher Notification - fix error on sending notification
JuanchoPestana Apr 24, 2020
ff62493
17. Teacher Notification - fix sniffer issue
JuanchoPestana Apr 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions includes/admin/class-sensei-learners-main.php
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ private function get_edit_start_date_form( $user_activity, $post_id, $post_type,
private function get_courses( $args ) {
$course_args = array(
'post_type' => 'course',
'post_status' => 'publish',
'post_status' => array( 'publish', 'private' ),
'posts_per_page' => $args['per_page'],
'offset' => $args['offset'],
'orderby' => $args['orderby'],
Expand Down Expand Up @@ -709,7 +709,7 @@ private function get_courses( $args ) {
private function get_lessons( $args ) {
$lesson_args = array(
'post_type' => 'lesson',
'post_status' => 'publish',
'post_status' => array( 'publish', 'private' ),
'posts_per_page' => $args['per_page'],
'offset' => $args['offset'],
'orderby' => $args['orderby'],
Expand Down
7 changes: 4 additions & 3 deletions includes/class-sensei-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -963,11 +963,12 @@ public function glance_items( $items = array() ) {

if ( $num_posts ) {

$published = intval( $num_posts->publish );
$post_type = get_post_type_object( $type );
$published = intval( $num_posts->publish );
$published_as_private = intval( $num_posts->private );
$post_type = get_post_type_object( $type );

$text = '%s ' . $post_type->labels->singular_name;
$text = sprintf( $text, number_format_i18n( $published ) );
$text = sprintf( $text, number_format_i18n( $published + $published_as_private ) );

if ( current_user_can( $post_type->cap->edit_posts ) ) {
$items[] = sprintf( '<a class="%1$s-count" href="edit.php?post_type=%1$s">%2$s</a>', $type, $text ) . "\n";
Expand Down
21 changes: 17 additions & 4 deletions includes/class-sensei-course.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ public function course_prerequisite_meta_box_content() {
'order' => 'DESC',
'exclude' => $post->ID,
'suppress_filters' => 0,
'post_status' => array( 'publish', 'private' ),
);
$posts_array = get_posts( $post_args );

Expand Down Expand Up @@ -1096,7 +1097,7 @@ public function course_count( $post_status = 'publish' ) {
* @param string $fields (default: 'all'). WP only allows 3 types, but we will limit it to only 'ids' or 'all'
* @return array{ type WP_Post } $posts_array
*/
public function course_lessons( $course_id = 0, $post_status = 'publish', $fields = 'all' ) {
public function course_lessons( $course_id = 0, $post_status = array( 'publish', 'private' ), $fields = 'all' ) {

if ( is_a( $course_id, 'WP_Post' ) ) {
$course_id = $course_id->ID;
Expand Down Expand Up @@ -1243,7 +1244,7 @@ public function course_author_lesson_count( $author_id = 0, $course_id = 0 ) {
'author' => $author_id,
'meta_key' => '_lesson_course',
'meta_value' => $course_id,
'post_status' => 'publish',
'post_status' => array( 'publish', 'private' ),
'suppress_filters' => 0,
'fields' => 'ids', // less data to retrieve
);
Expand All @@ -1262,12 +1263,18 @@ public function course_author_lesson_count( $author_id = 0, $course_id = 0 ) {
*/
public function course_lesson_count( $course_id = 0 ) {

// Only get private posts if user has proper capabilities.
$post_status = array( 'publish' );
if ( current_user_can( 'read_private_posts' ) ) {
$post_status[] = 'private';
}

$lesson_args = array(
'post_type' => 'lesson',
'posts_per_page' => -1,
'meta_key' => '_lesson_course',
'meta_value' => $course_id,
'post_status' => 'publish',
'post_status' => $post_status,
'suppress_filters' => 0,
'fields' => 'ids', // less data to retrieve
);
Expand Down Expand Up @@ -2845,7 +2852,12 @@ public static function load_single_course_lessons_query() {
return;
}

$course_lessons_post_status = isset( $wp_query ) && $wp_query->is_preview() ? 'all' : 'publish';
$course_lessons_post_status = isset( $wp_query ) && $wp_query->is_preview() ? 'all' : array( 'publish' );

// Only get private posts if user has proper capabilities.
if ( current_user_can( 'read_private_posts' ) && ! $wp_query->is_preview() ) {
$course_lessons_post_status[] = 'private';
}

$course_lesson_query_args = array(
'post_status' => $course_lessons_post_status,
Expand Down Expand Up @@ -2892,6 +2904,7 @@ public static function load_single_course_lessons_query() {
'fields' => 'ids',
'meta_key' => '_lesson_course',
'meta_value' => intval( $course_id ),
'post_status' => $course_lessons_post_status,
)
);
if ( ! empty( $course_lesson_order ) ) {
Expand Down
2 changes: 1 addition & 1 deletion includes/class-sensei-grading.php
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ public function lessons_drop_down_html( $course_id = 0, $selected_lesson_id = 0
'order' => 'ASC',
'meta_key' => '_lesson_course',
'meta_value' => $course_id,
'post_status' => 'publish',
'post_status' => array( 'publish', 'private' ),
'suppress_filters' => 0,
'fields' => 'ids',
);
Expand Down
4 changes: 2 additions & 2 deletions includes/class-sensei-lesson.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public function lesson_prerequisite_meta_box_content() {
'order' => 'ASC',
'exclude' => $post->ID,
'suppress_filters' => 0,
'post_status' => [ 'publish', 'draft' ],
'post_status' => array( 'publish', 'draft', 'private' ),
);
$posts_array = get_posts( $post_args );
// Build the HTML to Output
Expand Down Expand Up @@ -438,7 +438,7 @@ public function add_lesson_to_course_order( $lesson_id = 0 ) {
return;
}

if ( ! in_array( get_post_status( $lesson_id ), array( 'publish', 'future', 'pending' ), true ) ) {
if ( ! in_array( get_post_status( $lesson_id ), array( 'publish', 'future', 'pending', 'private' ), true ) ) {
return;
}

Expand Down
16 changes: 13 additions & 3 deletions includes/class-sensei-modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -980,9 +980,14 @@ public function get_user_module_progress( $module_id = 0, $course_id = 0, $user_
*/
public function calculate_user_module_progress( $user_id = 0, $module_id = 0, $course_id = 0 ) {

$post_status = array( 'publish' );
if ( user_can( $user_id, 'read_private_posts' ) ) {
$post_status[] = 'private';
}

$args = array(
'post_type' => 'lesson',
'post_status' => 'publish',
'post_status' => $post_status,
'posts_per_page' => -1,
'tax_query' => array(
array(
Expand Down Expand Up @@ -1284,7 +1289,7 @@ public function taxonomy_column_headings( $columns ) {
public function taxonomy_column_content( $column_data, $column_name, $term_id ) {

$args = array(
'post_status' => 'publish',
'post_status' => array( 'publish', 'private' ),
'posts_per_page' => -1,
'tax_query' => array(
array(
Expand Down Expand Up @@ -1693,7 +1698,12 @@ public function get_lessons_query( $course_id, $term_id ) {

}

$course_lessons_post_status = isset( $wp_query ) && $wp_query->is_preview() ? 'all' : 'publish';
$course_lessons_post_status = isset( $wp_query ) && $wp_query->is_preview() ? 'all' : array( 'publish' );

// Only get private posts if user has proper capabilities.
if ( current_user_can( 'read_private_posts' ) && ! $wp_query->is_preview() ) {
$course_lessons_post_status[] = 'private';
}

$args = array(
'post_type' => 'lesson',
Expand Down
2 changes: 1 addition & 1 deletion includes/class-sensei-teacher.php
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ public function notify_admin_teacher_course_creation( $new_status, $old_status,

$course_id = $post->ID;

if ( 'publish' == $old_status || 'course' != get_post_type( $course_id ) || 'auto-draft' == get_post_status( $course_id )
if ( 'publish' == $old_status || 'private' === $old_status || 'course' != get_post_type( $course_id ) || 'auto-draft' == get_post_status( $course_id )
|| 'trash' == get_post_status( $course_id ) || 'draft' == get_post_status( $course_id ) ) {

return false;
Expand Down
30 changes: 16 additions & 14 deletions includes/class-sensei-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -1499,9 +1499,10 @@ public static function has_started_course( $course_id = 0, $user_id = 0 ) {
* and then updates the course metadata with that information.
*
* @since 1.7.0
* @param integer $course_id Course ID
* @param integer $user_id User ID
* @return mixed boolean or comment_ID
* @param integer $course_id Course ID.
* @param integer $user_id User ID.
* @param bool $trigger_completion_action
* @return mixed boolean or comment_ID.
*/
public static function user_complete_course( $course_id = 0, $user_id = 0, $trigger_completion_action = true ) {
global $wp_version;
Expand All @@ -1514,15 +1515,16 @@ public static function user_complete_course( $course_id = 0, $user_id = 0, $trig
$course_status = 'in-progress';
$course_metadata = array();
$course_completion = Sensei()->settings->settings['course_completion'];
$lessons_completed = $total_lessons = 0;
$lessons_completed = 0;
$total_lessons = 0;
$lesson_status_args = array(
'user_id' => $user_id,
'status' => 'any',
'type' => 'sensei_lesson_status', /* FIELD SIZE 20 */
);

// Grab all of this Courses' lessons, looping through each...
$lesson_ids = Sensei()->course->course_lessons( $course_id, 'publish', 'ids' );
// Grab all of this Courses' lessons (publish and private status), looping through each...
$lesson_ids = Sensei()->course->course_lessons( $course_id, array( 'publish', 'private' ), 'ids' );
$total_lessons = count( $lesson_ids );
// ...if course completion not set to 'passed', and all lessons are complete or graded,
// ......then all lessons are 'passed'
Expand All @@ -1534,11 +1536,11 @@ public static function user_complete_course( $course_id = 0, $user_id = 0, $trig
// ...if all lessons 'passed' then update the course status to complete
// The below checks if a lesson is fully completed, though maybe should be Utils::user_completed_lesson()
$all_lesson_statuses = array();
// In WordPress 4.1 get_comments() allows a single query to cover multiple comment_post_IDs
// In WordPress 4.1 get_comments() allows a single query to cover multiple comment_post_IDs.
if ( version_compare( $wp_version, '4.1', '>=' ) ) {
$lesson_status_args['post__in'] = $lesson_ids;
$all_lesson_statuses = self::sensei_check_for_activity( $lesson_status_args, true );
// Need to always return an array, even with only 1 item
// Need to always return an array, even with only 1 item.
if ( ! is_array( $all_lesson_statuses ) ) {
$all_lesson_statuses = array( $all_lesson_statuses );
}
Expand All @@ -1548,18 +1550,18 @@ public static function user_complete_course( $course_id = 0, $user_id = 0, $trig
foreach ( $lesson_ids as $lesson_id ) {
$lesson_status_args['post_id'] = $lesson_id;
$each_lesson_status = self::sensei_check_for_activity( $lesson_status_args, true );
// Check for valid return before using
// Check for valid return before using.
if ( ! empty( $each_lesson_status->comment_approved ) ) {
$all_lesson_statuses[] = $each_lesson_status;
}
}
}
foreach ( $all_lesson_statuses as $lesson_status ) {
// If lessons are complete without needing quizzes to be passed
// If lessons are complete without needing quizzes to be passed.
if ( 'passed' != $course_completion ) {
// A user cannot 'complete' a course if a lesson...
// ...is still in progress
// ...hasn't yet been graded
// ...hasn't yet been graded.
$lesson_not_complete_stati = array( 'in-progress', 'ungraded' );
if ( ! in_array( $lesson_status->comment_approved, $lesson_not_complete_stati, true ) ) {
$lessons_completed++;
Expand All @@ -1575,14 +1577,14 @@ public static function user_complete_course( $course_id = 0, $user_id = 0, $trig
$course_status = 'complete';
}

// Update meta data on how many lessons have been completed
// Update meta data on how many lessons have been completed.
$course_metadata['complete'] = $lessons_completed;
// update the overall percentage of the course lessons complete (or graded) compared to 'in-progress' regardless of the above
// Update the overall percentage of the course lessons complete (or graded) compared to 'in-progress' regardless of the above.
$course_metadata['percent'] = self::quotient_as_absolute_rounded_percentage( $lessons_completed, $total_lessons );

$activity_logged = self::update_course_status( $user_id, $course_id, $course_status, $course_metadata );

// Allow further actions
// Allow further actions.
if ( 'complete' == $course_status && true === $trigger_completion_action ) {
do_action( 'sensei_user_course_end', $user_id, $course_id );
}
Expand Down
4 changes: 2 additions & 2 deletions includes/enrolment/class-sensei-course-enrolment.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public function is_enrolled( $user_id, $check_cache = true ) {
return $is_enrolled;
}

// Users can only be enrolled in a published course.
if ( 'publish' !== get_post_status( $this->course_id ) ) {
// Users can only be enrolled in a published course. Or in a private one.
if ( ! in_array( get_post_status( $this->course_id ), array( 'publish', 'private' ), true ) ) {
return false;
}

Expand Down
1 change: 1 addition & 0 deletions includes/shortcodes/class-sensei-shortcode-courses.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ protected function setup_course_query() {
'orderby' => $this->orderby,
'order' => $this->order,
'posts_per_page' => $this->number,
'post_status' => array( 'publish', 'private' ),

);

Expand Down