Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions assets/icons/play-line-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/src/js/v3/shared/icons/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ export const icons = [
'play2',
'playFill',
'playLine',
'playLine2',
'plus',
'plusMinus',
'plusSquare',
Expand Down
14 changes: 10 additions & 4 deletions assets/src/scss/frontend/dashboard/_progress-card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,20 @@
&:focus-within {
background-color: $tutor-surface-l1-hover;

.tutor-progress-card-actions {
> .tutor-progress-card-actions {
opacity: 1;
visibility: visible;
}
}

&.tutor-active {
background-color: $tutor-surface-l1-hover;
}

&:focus-visible {
@include tutor-focus-ring();
border-radius: $tutor-radius-2xl !important;
z-index: $tutor-z-positive;
}

@include tutor-breakpoint-down(lg) {
Expand All @@ -134,10 +140,10 @@
@include tutor-flex(column, stretch, flex-start);
height: auto;
gap: $tutor-spacing-none;
padding: $tutor-spacing-4 $tutor-spacing-4 $tutor-spacing-5;

.tutor-progress-card-inner {
flex-direction: column;
gap: $tutor-spacing-none;
}

.tutor-progress-card-thumbnail {
Expand All @@ -155,7 +161,7 @@
}

&-header {
margin-bottom: $tutor-spacing-4;
margin-bottom: $tutor-spacing-6;
}

&-details {
Expand All @@ -168,7 +174,7 @@

&-actions {
position: static;
display: block;
display: flex;
visibility: visible;
opacity: 1;
padding: $tutor-spacing-6 0 0;
Expand Down
1 change: 1 addition & 0 deletions classes/Icon.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ final class Icon {
const PLAY_2 = 'play-2';
const PLAY_FILL = 'play-fill';
const PLAY_LINE = 'play-line';
const PLAY_LINE_2 = 'play-line-2';
const PLUS = 'plus';
const PLUS_MINUS = 'plus-minus';
const PLUS_SQUARE = 'plus-square';
Expand Down
2 changes: 1 addition & 1 deletion classes/Student.php
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ public function get_courses_tab( $active_tab, $post_type_args, $enrolled_course_
),
array(
'label' => __( 'Active', 'tutor' ),
'icon' => Icon::PLAY_LINE,
'icon' => Icon::PLAY_LINE_2,
'url' => esc_url( add_query_arg( $post_type_args, tutor_utils()->get_tutor_dashboard_page_permalink( 'courses/active-courses' ) ) ),
'active' => 'courses/active-courses' === $active_tab ? true : false,
'count' => $active_course_count,
Expand Down
28 changes: 22 additions & 6 deletions classes/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -2103,22 +2103,38 @@ public function get_total_students( $search_term = '', $course_id = '', $date =
*
* @return array
*/
public function get_completed_courses_ids_by_user( $user_id = 0 ) {
public function get_completed_courses_ids_by_user( $user_id = 0, $with_bundle_enrolled_courses = true ) {
global $wpdb;

$user_id = $this->get_user_id( $user_id );

$with_bundle_enrolled_courses_clause = '';
if ( ! $with_bundle_enrolled_courses ) {
$with_bundle_enrolled_courses_clause = $wpdb->prepare(
"AND NOT EXISTS (
SELECT 1
FROM {$wpdb->postmeta} pm
WHERE pm.post_id = e.ID
AND pm.meta_key = %s
)",
'_tutor_bundle_id'
);
}

$course_ids = (array) $wpdb->get_col(
$wpdb->prepare(
"SELECT comment_post_ID AS course_id
FROM {$wpdb->comments}
WHERE comment_agent = %s
FROM {$wpdb->comments}
WHERE comment_agent = %s
AND comment_type = %s
AND user_id = %d
AND comment_post_ID IN (
select post_parent AS course_id from {$wpdb->posts} where post_type=%s AND post_author = %d
)
",
SELECT e.post_parent
FROM {$wpdb->posts} e
WHERE e.post_type = %s
AND e.post_author = %d
{$with_bundle_enrolled_courses_clause}
)",
'TutorLMSPlugin',
'course_completed',
$user_id,
Expand Down
7 changes: 5 additions & 2 deletions models/CourseModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ function ( $item ) {
*/
public static function get_completed_courses_by_user( $user_id = 0, $offset = 0, $posts_per_page = -1, $args = array() ) {
$user_id = tutor_utils()->get_user_id( $user_id );
$course_ids = tutor_utils()->get_completed_courses_ids_by_user( $user_id );
$course_ids = tutor_utils()->get_completed_courses_ids_by_user( $user_id, false );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is used in several places, we need to ensure all the called places context before passing 2nd param false.


if ( count( $course_ids ) ) {
$course_post_type = tutor()->course_post_type;
Expand All @@ -1301,6 +1301,7 @@ public static function get_completed_courses_by_user( $user_id = 0, $offset = 0,
'post__in' => $course_ids,
'posts_per_page' => $posts_per_page,
'offset' => $offset,
'orderby' => 'post__in',
);

$args = apply_filters( 'tutor_get_completed_courses_by_user', $args, $user_id, $course_post_type );
Expand All @@ -1326,7 +1327,7 @@ public static function get_completed_courses_by_user( $user_id = 0, $offset = 0,
*/
public static function get_active_courses_by_user( $user_id = 0, $offset = 0, $posts_per_page = -1, $args = array() ) {
$user_id = tutor_utils()->get_user_id( $user_id );
$course_ids = tutor_utils()->get_completed_courses_ids_by_user( $user_id );
$course_ids = tutor_utils()->get_completed_courses_ids_by_user( $user_id, false );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

$enrolled_course_ids = tutor_utils()->get_enrolled_courses_ids_by_user( $user_id, false );
$active_courses = array_diff( $enrolled_course_ids, $course_ids );

Expand All @@ -1338,6 +1339,7 @@ public static function get_active_courses_by_user( $user_id = 0, $offset = 0, $p
'post__in' => $active_courses,
'posts_per_page' => $posts_per_page,
'offset' => $offset,
'orderby' => 'post__in',
);

$args = apply_filters( 'tutor_get_active_courses_by_user', $args, $user_id, $course_post_type );
Expand Down Expand Up @@ -1377,6 +1379,7 @@ public static function get_enrolled_courses_by_user( $user_id = 0, $post_status
'post__in' => $course_ids,
'offset' => $offset,
'posts_per_page' => $posts_per_page,
'orderby' => 'post__in',
);

$args = apply_filters( 'tutor_get_enrolled_courses_by_user', $args, $user_id, $course_post_type );
Expand Down
55 changes: 33 additions & 22 deletions templates/dashboard/courses.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,32 @@
$active_tab = 'courses';
}

$enrolled_courses = CourseModel::get_enrolled_courses_by_user( get_current_user_id(), array( 'private', 'publish' ), $offset, $courses_per_page );
$active_courses = CourseModel::get_active_courses_by_user( null, $offset, $courses_per_page, array( 'post_status' => array( 'private', 'publish' ) ) );
$completed_courses = CourseModel::get_completed_courses_by_user( null, $offset, $courses_per_page, array( 'post_status' => array( 'private', 'publish' ) ) );

$enrolled_course_count = is_a( $enrolled_courses, 'WP_Query' ) ? $enrolled_courses->found_posts : 0;
$active_course_count = is_a( $active_courses, 'WP_Query' ) ? $active_courses->found_posts : 0;
$completed_course_count = is_a( $completed_courses, 'WP_Query' ) ? $completed_courses->found_posts : 0;

// Get Paginated course list.
$courses_list_array = array(
'courses' => $enrolled_courses,
'courses/active-courses' => $active_courses,
'courses/completed-courses' => $completed_courses,
'courses/wishlist' => array(),
'courses/my-quiz-attempts' => __( 'Quiz Attempts', 'tutor' ),
);
// Only fetch the paginated list for the active tab.
switch ( $active_tab ) {
case 'courses':
$courses_list = CourseModel::get_enrolled_courses_by_user( get_current_user_id(), array( CourseModel::STATUS_PRIVATE, CourseModel::STATUS_PUBLISH ), $offset, $courses_per_page );
break;
case 'courses/active-courses':
$courses_list = CourseModel::get_active_courses_by_user( null, $offset, $courses_per_page, array( 'post_status' => array( CourseModel::STATUS_PRIVATE, CourseModel::STATUS_PUBLISH ) ) );
break;
case 'courses/completed-courses':
$courses_list = CourseModel::get_completed_courses_by_user( null, $offset, $courses_per_page, array( 'post_status' => array( CourseModel::STATUS_PRIVATE, CourseModel::STATUS_PUBLISH ) ) );
break;
default:
$courses_list = null;
break;
}

$courses_tab = ( new Student() )->get_courses_tab( $active_tab, $post_type_args, $enrolled_course_count, $active_course_count, $completed_course_count );
// Separate count queries with no offset so tab counts are always accurate regardless of current page.
$enrolled_courses_for_count = CourseModel::get_enrolled_courses_by_user( get_current_user_id(), array( CourseModel::STATUS_PRIVATE, CourseModel::STATUS_PUBLISH ), 0, 1 );
$active_courses_for_count = CourseModel::get_active_courses_by_user( null, 0, 1, array( 'post_status' => array( CourseModel::STATUS_PRIVATE, CourseModel::STATUS_PUBLISH ) ) );
$completed_courses_for_count = CourseModel::get_completed_courses_by_user( null, 0, 1, array( 'post_status' => array( CourseModel::STATUS_PRIVATE, CourseModel::STATUS_PUBLISH ) ) );

// Prepare course list based on page tab.
$courses_list = $courses_list_array[ $active_tab ];
$enrolled_course_count = is_a( $enrolled_courses_for_count, 'WP_Query' ) ? $enrolled_courses_for_count->found_posts : 0;
$active_course_count = is_a( $active_courses_for_count, 'WP_Query' ) ? $active_courses_for_count->found_posts : 0;
$completed_course_count = is_a( $completed_courses_for_count, 'WP_Query' ) ? $completed_courses_for_count->found_posts : 0;

$courses_tab = ( new Student() )->get_courses_tab( $active_tab, $post_type_args, $enrolled_course_count, $active_course_count, $completed_course_count );

?>

Expand All @@ -92,16 +97,22 @@
break;
}
elseif ( 'courses' === $active_tab || 'courses/active-courses' === $active_tab || 'courses/completed-courses' === $active_tab ) :
// Prepare course list based on page tab.
$courses_list = $courses_list_array[ $active_tab ];
?>
<div class="tutor-dashboard-courses-list tutor-flex tutor-flex-column tutor-gap-4 tutor-p-6 tutor-sm-p-none tutor-sm-mt-4">
<?php
if ( $courses_list && $courses_list->have_posts() ) :
while ( $courses_list->have_posts() ) :
$courses_list->the_post();
tutor_load_template( 'dashboard.courses.course-card' );
$course_id = get_the_ID();

$default_template = tutor_get_template( 'dashboard.courses.course-card' );
$course_card_template = apply_filters( 'tutor_dashboard_course_card_template', $default_template, $course_id );

if ( file_exists( $course_card_template ) ) {
require $course_card_template;
}
endwhile;
wp_reset_postdata();
else :
EmptyState::make()
->title( __( 'No Courses Found', 'tutor' ) )
Expand Down
26 changes: 26 additions & 0 deletions templates/dashboard/courses/course-card-header.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/**
* Course Card Header Template
*
* @package Tutor\Templates
* @subpackage Dashboard\Enrolled_Courses
* @author Themeum
*
* @since 4.0.0
*/

defined( 'ABSPATH' ) || exit;

$category = isset( $category ) ? $category : '';
?>

<div class="tutor-progress-card-header">
<?php if ( ! empty( $category ) ) : ?>
<div class="tutor-progress-card-category">
<?php echo esc_html( $category ); ?>
</div>
<?php endif; ?>
<h3 class="tutor-progress-card-title tutor-line-clamp-2">
<?php the_title(); ?>
</h3>
</div>
61 changes: 61 additions & 0 deletions templates/dashboard/courses/course-card-progress.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* Course Card Progress Template
*
* @package Tutor\Templates
* @subpackage Dashboard\Enrolled_Courses
* @author Themeum
*
* @since 4.0.0
*/

defined( 'ABSPATH' ) || exit;

use Tutor\Components\Progress;

if ( $course_progress['completed_count'] <= 0 && $course_progress['total_count'] <= 0 ) {
return;
}

$progress_message_label = isset( $progress_message_label ) ? $progress_message_label : _n( 'lesson', 'lessons', (int) $course_progress['total_count'], 'tutor' );
?>
<div class="tutor-progress-card-progress">
<?php if ( $course_progress['total_count'] > 0 ) : ?>
<div class="tutor-progress-card-details">
<?php
printf(
esc_html(
// translators: %1$s is the completed count, %2$s is the total count, %3$s is the label (lesson/lessons or course/courses).
_n(
'%1$s of %2$s %3$s',
'%1$s of %2$s %3$s',
(int) $course_progress['total_count'],
'tutor'
)
),
esc_html( $course_progress['completed_count'] ),
esc_html( $course_progress['total_count'] ),
esc_html( $progress_message_label )
);
?>
<span class="tutor-progress-card-separator">•</span>
<?php
printf(
// translators: %1$s is the completed percent.
esc_html__( '%1$s%% Complete', 'tutor' ),
esc_html( $course_progress['completed_percent'] )
);
?>
</div>
<?php endif; ?>
<?php if ( $course_progress['completed_percent'] >= 0 ) : ?>
<div class="tutor-progress-card-bar">
<?php
Progress::make()
->value( $course_progress['completed_percent'] )
->type( 'bar' )
->render();
?>
</div>
<?php endif; ?>
</div>
23 changes: 23 additions & 0 deletions templates/dashboard/courses/course-card-thumbnail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/**
* Course Card Thumbnail Template
*
* @package Tutor\Templates
* @subpackage Dashboard\Enrolled_Courses
* @author Themeum
*
* @since 4.0.0
*/

defined( 'ABSPATH' ) || exit;

$thumbnail_img = isset( $thumbnail_img ) ? $thumbnail_img : get_tutor_course_thumbnail_src();
$post_id = isset( $post_id ) ? $post_id : get_the_ID();
?>

<div class="tutor-progress-card-thumbnail">
<?php do_action( 'tutor_courses_card_before_thumbnail', $post_id ); ?>
<?php if ( ! empty( $thumbnail_img ) ) : ?>
<img src="<?php echo esc_url( $thumbnail_img ); ?>" alt="<?php the_title_attribute( array( 'post' => $post_id ) ); ?>" loading="lazy" />
<?php endif; ?>
</div>
Loading
Loading