From 3a6046bcc971ce7c2c8584f03cd0d0e96a36e87f Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Mon, 9 Oct 2023 23:33:30 +0600 Subject: [PATCH 01/12] method added to check a course is auto completable --- models/CourseModel.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/models/CourseModel.php b/models/CourseModel.php index 89051e43a..b3fbe2ef5 100644 --- a/models/CourseModel.php +++ b/models/CourseModel.php @@ -652,4 +652,33 @@ public static function can_complete_course( $course_id, $user_id ) { return false; } + + /** + * Check a course can be auto complete by an enrolled student. + * + * @since 2.4.0 + * + * @param int $course_id course id. + * @param int $user_id user id. + * + * @return boolean + */ + public static function can_autocomplete_course( $course_id, $user_id ) { + $auto_course_complete_option = (bool) tutor_utils()->get_option( 'auto_course_complete_on_all_lesson_completion' ); + if ( ! $auto_course_complete_option ) { + return false; + } + + $is_course_completed = tutor_utils()->is_completed_course( $course_id, $user_id ); + if ( $is_course_completed ) { + return false; + } + + $course_stats = tutor_utils()->get_course_completed_percent( $course_id, $user_id, true ); + if ( $course_stats['completed_count'] === $course_stats['total_count'] ) { + return self::can_complete_course( $course_id, $user_id ); + } else { + return false; + } + } } From 5459ecff58dee4e07fad293e57bd9887d6176e50 Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Mon, 9 Oct 2023 23:38:22 +0600 Subject: [PATCH 02/12] refactor and used resuable method from coursemodel --- templates/single/common/header.php | 41 +++++++++++++----------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/templates/single/common/header.php b/templates/single/common/header.php index 2af40d872..5ec6150fb 100644 --- a/templates/single/common/header.php +++ b/templates/single/common/header.php @@ -9,42 +9,37 @@ * @since 1.0.0 */ +use TUTOR\Course; use Tutor\Models\CourseModel; +$user_id = get_current_user_id(); $course_id = isset( $course_id ) ? (int) $course_id : 0; $is_enrolled = tutor_utils()->is_enrolled( $course_id ); $course_stats = tutor_utils()->get_course_completed_percent( $course_id, 0, true ); $show_mark_complete = isset( $mark_as_complete ) ? $mark_as_complete : false; + +$is_course_completed = tutor_utils()->is_completed_course( $course_id, $user_id ); + /** * Auto course complete on all lesson, quiz, assignment complete * * @since 2.0.7 + * @since 2.4.0 update and refactor. */ -$user_id = get_current_user_id(); -$auto_course_complete_option = tutor_utils()->get_option( 'auto_course_complete_on_all_lesson_completion' ); -$is_course_completed = tutor_utils()->is_completed_course( $course_id, $user_id ); -$completion_mode = tutor_utils()->get_option( 'course_completion_process' ); -if ( true === $auto_course_complete_option && false === $is_course_completed ) { - if ( $course_stats['completed_count'] === $course_stats['total_count'] ) { - $can_complete_course = CourseModel::can_complete_course( $course_id, $user_id ); +if ( CourseModel::can_autocomplete_course( $course_id, $user_id ) ) { + \Tutor\Models\CourseModel::mark_course_as_completed( $course_id, $user_id ); - if ( $can_complete_course ) { - \Tutor\Models\CourseModel::mark_course_as_completed( $course_id, $user_id ); - - /** - * After auto complete the course. - * Set review popup data and redirect to course details page. - * Review popup will be shown on course details page. - * - * @since 2.4.0 - */ - $course_link = get_the_permalink( $course_id ); - \TUTOR\Course::set_review_popup_data( get_current_user_id(), $course_id, $course_link ); - tutils()->redirect_to( $course_link ); - exit; - } - } + /** + * After auto complete the course. + * Set review popup data and redirect to course details page. + * Review popup will be shown on course details page. + * + * @since 2.4.0 + */ + Course::set_review_popup_data( $user_id, $course_id ); + tutils()->redirect_to( $course_link ); + exit; } ?> From c04a9c1512c3de8b3dcd973388e9e4987f4936cb Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Mon, 9 Oct 2023 23:40:52 +0600 Subject: [PATCH 03/12] review popup meta for user --- classes/User.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/classes/User.php b/classes/User.php index 2771bfc44..3108148fa 100644 --- a/classes/User.php +++ b/classes/User.php @@ -25,6 +25,8 @@ class User { const INSTRUCTOR = 'tutor_instructor'; const ADMIN = 'administrator'; + const REVIEW_POPUP_META = 'tutor_review_course_popup'; + /** * Registration notice * From 6cf0f841130df5a58744864f7d867038a84a4fd0 Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Mon, 9 Oct 2023 23:42:05 +0600 Subject: [PATCH 04/12] review popup data set logic and data source updated --- classes/Course.php | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/classes/Course.php b/classes/Course.php index 0a5dec986..cf5c20d99 100644 --- a/classes/Course.php +++ b/classes/Course.php @@ -845,48 +845,36 @@ public function mark_course_complete() { * Set data for review popup. * * @since 2.2.5 + * @since 2.4.0 removed $permalink param. store user meta instead of option data. * - * @param int $user_id user id. - * @param int $course_id course id. - * @param string $permalink course permalink. + * @param int $user_id user id. + * @param int $course_id course id. * * @return void */ - public static function set_review_popup_data( $user_id, $course_id, $permalink ) { + public static function set_review_popup_data( $user_id, $course_id ) { if ( get_tutor_option( 'enable_course_review' ) ) { $rating = tutor_utils()->get_course_rating_by_user( $course_id, $user_id ); if ( ! $rating || ( empty( $rating->rating ) && empty( $rating->review ) ) ) { - update_option( - 'tutor_course_complete_popup_' . $user_id, - array( - 'course_id' => $course_id, - 'course_url' => $permalink, - 'expires' => time() + 10, - ) - ); + add_user_meta( $user_id, User::REVIEW_POPUP_META, $course_id ); } } } /** - * Popup review form + * Popup review form on course details * * @since 1.0.0 * @return void */ public function popup_review_form() { if ( is_user_logged_in() ) { - $key = 'tutor_course_complete_popup_' . get_current_user_id(); - $popup = get_option( $key ); - - if ( is_array( $popup ) ) { - - if ( $popup['expires'] > time() ) { - $course_id = $popup['course_id']; - include tutor()->path . 'views/modal/review.php'; - } + $user_id = get_current_user_id(); + $course_id = (int) get_user_meta( $user_id, User::REVIEW_POPUP_META, true ); - delete_option( $key ); + if ( is_single() && get_the_ID() === $course_id ) { + include tutor()->path . 'views/modal/review.php'; + delete_user_meta( $user_id, User::REVIEW_POPUP_META, $course_id ); } } } From 7d2dbbc401025698f58b3e8b56d9db2cc559509c Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Mon, 9 Oct 2023 23:51:01 +0600 Subject: [PATCH 05/12] wpcs fix for user class --- classes/User.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/User.php b/classes/User.php index 3108148fa..759ff9829 100644 --- a/classes/User.php +++ b/classes/User.php @@ -130,7 +130,7 @@ public static function is_admin() { * @since 2.2.0 * * @param bool $is_approved instructor is approved or not. - * + * * @return boolean */ public static function is_instructor( $is_approved = true ) { @@ -271,7 +271,7 @@ public function update_user_photo() { * @return void */ public function profile_update( $user_id ) { - if ( tutor_utils()->array_get( 'tutor_action', $_POST ) !== 'tutor_profile_update_by_wp' ) { + if ( 'tutor_profile_update_by_wp' !== Input::post( 'tutor_action' ) ) { return; } From e257bc1b937cf0a1a6d09d8e02fb616b7684419d Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Mon, 9 Oct 2023 23:54:59 +0600 Subject: [PATCH 06/12] auto complete on course details page --- classes/Frontend.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/classes/Frontend.php b/classes/Frontend.php index 5707562ab..128348514 100644 --- a/classes/Frontend.php +++ b/classes/Frontend.php @@ -10,6 +10,8 @@ namespace TUTOR; +use Tutor\Models\CourseModel; + if ( ! defined( 'ABSPATH' ) ) { exit; } @@ -34,6 +36,27 @@ public function __construct() { // Handle flash toast message for redirect_to util helper. add_action( 'wp_head', array( new Utils(), 'handle_flash_message' ), 999 ); + + add_action( 'tutor_course/single/before/wrap', array( $this, 'do_auto_course_complete' ) ); + } + + /** + * Do auto course complete on course details page. + * + * @return void + */ + public function do_auto_course_complete() { + if ( ! is_user_logged_in() ) { + return; + } + + $course_id = get_the_ID(); + $user_id = get_current_user_id(); + + if ( CourseModel::can_autocomplete_course( $course_id, $user_id ) ) { + CourseModel::mark_course_as_completed( $course_id, $user_id ); + Course::set_review_popup_data( $user_id, $course_id ); + } } /** From 5bd2e3040aa87cf7a8e1c3045d8484fbe3ab88eb Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Wed, 11 Oct 2023 11:12:22 +0600 Subject: [PATCH 07/12] review progress link helper added to course model --- models/CourseModel.php | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/models/CourseModel.php b/models/CourseModel.php index b3fbe2ef5..6b5d6759e 100644 --- a/models/CourseModel.php +++ b/models/CourseModel.php @@ -681,4 +681,49 @@ public static function can_autocomplete_course( $course_id, $user_id ) { return false; } } + + /** + * Get review progress link when course progress 100% and + * User has pending or fail quiz or assignment + * + * @since 2.4.0 + * + * @param int $course_id course id. + * @param int $user_id user id. + * + * @return string course content permalink. + */ + public static function get_review_progress_link( $course_id, $user_id ) { + $course_progress = tutor_utils()->get_course_completed_percent( $course_id, $user_id, true ); + $completed_percent = (int) $course_progress['completed_percent']; + $course_contents = tutor_utils()->get_course_contents_by_id( $course_id ); + $permalink = ''; + + if ( tutor_utils()->count( $course_contents ) && 100 === $completed_percent ) { + foreach ( $course_contents as $content ) { + if ( 'tutor_quiz' === $content->post_type ) { + $result = QuizModel::get_quiz_result( $content->ID, $user_id ); + if ( 'pass' !== $result ) { + $permalink = get_the_permalink( $content->ID ); + break; + } + } + + if ( tutor()->has_pro && 'tutor_assignments' === $content->post_type ) { + $result = \TUTOR_ASSIGNMENTS\Assignments::get_assignment_result( $content->ID, $user_id ); + if ( 'pass' !== $result ) { + $permalink = get_the_permalink( $content->ID ); + break; + } + } + } + } + + // Fallback link. + if ( empty( $permalink ) ) { + $permalink = tutils()->get_course_first_lesson( $course_id ); + } + + return $permalink; + } } From 19826966def41a1081a77b3b6f8e49e835ec8d10 Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Wed, 11 Oct 2023 11:15:07 +0600 Subject: [PATCH 08/12] review progress link logic implemented to course loop --- templates/loop/course-continue.php | 33 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/templates/loop/course-continue.php b/templates/loop/course-continue.php index 16b3f8c81..52349a2b7 100644 --- a/templates/loop/course-continue.php +++ b/templates/loop/course-continue.php @@ -35,23 +35,24 @@ if ( $lesson_url && ! $is_completed_course ) { ob_start(); + $link_text = __( 'Continue Learning', 'tutor' ); + if ( 0 === (int) $completed_percent ) { + $link_text = __( 'Start Learning', 'tutor' ); + } elseif ( $completed_percent > 0 && $completed_percent < 100 ) { + $link_text = __( 'Continue Learning', 'tutor' ); + } elseif ( 100 === (int) $completed_percent && false === $can_complete_course ) { + $lesson_url = CourseModel::get_review_progress_link( $course_id, $user_id ); + $link_text = __( 'Review Progress', 'tutor' ); + } else { + $link_text = __( 'Continue Learning', 'tutor' ); + } ?> - - 0 && $completed_percent < 100 ) { - esc_html_e( 'Continue Learning', 'tutor' ); - } elseif ( 100 === (int) $completed_percent && false === $can_complete_course ) { - esc_html_e( 'Review Progress', 'tutor' ); - } else { - esc_html_e( 'Continue Learning', 'tutor' ); - } - } - ?> - - " + class="" + data-course_id=""> + + + Date: Wed, 11 Oct 2023 11:15:45 +0600 Subject: [PATCH 09/12] review progress link to course entry box --- templates/single/course/course-entry-box.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/single/course/course-entry-box.php b/templates/single/course/course-entry-box.php index 815353470..da06df42e 100644 --- a/templates/single/course/course-entry-box.php +++ b/templates/single/course/course-entry-box.php @@ -157,7 +157,8 @@ class="tutor-btn tutor-btn-block tutor-btn-outline-primary start-continue-retake * @since 2.4.0 */ if ( 100 === (int) $completed_percent && false === CourseModel::can_complete_course( $course_id, $user_id ) ) { - $link_text = __( 'Review Progress', 'tutor' ); + $lesson_url = CourseModel::get_review_progress_link( $course_id, $user_id ); + $link_text = __( 'Review Progress', 'tutor' ); } } From 9143dcf9dcb8caec39f08f4144ad0b33a70b9075 Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Wed, 11 Oct 2023 11:59:42 +0600 Subject: [PATCH 10/12] wpcs comment fix --- classes/Utils.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/classes/Utils.php b/classes/Utils.php index 5e5a673c4..d05898a71 100644 --- a/classes/Utils.php +++ b/classes/Utils.php @@ -1390,7 +1390,7 @@ public function is_course_enrolled_by_lesson( $lesson_id = 0, $user_id = 0 ) { * @since 1.0.0 * @since 1.4.8 Legacy Supports Added. * - * @param int $lesson_id + * @param int $lesson_id lesson id. * * @return bool|mixed */ @@ -1413,7 +1413,8 @@ public function get_course_id_by_lesson( $lesson_id = 0 ) { * * @since 1.0.0 * - * @param int $course_id course ID. + * @param int $course_id course ID. + * @param mixed $post_type post type. * * @return bool|false|string */ @@ -1489,7 +1490,7 @@ public function get_video( $post_id = 0 ) { * @param int $post_id post ID. * @param array $video_data video data. * - * @return bool + * @return void */ public function update_video( $post_id = 0, $video_data = array() ) { $post_id = $this->get_post_id( $post_id ); @@ -1590,11 +1591,11 @@ public function get_attachment_data( $attachment_id ) { } /** - * return seconds to formatted playtime + * Return seconds to formatted playtime. * * @since 1.0.0 * - * @param $seconds seconds. + * @param int $seconds seconds. * * @return string */ @@ -1612,7 +1613,7 @@ public function playtime_string( $seconds ) { * * @since 1.0.0 * - * @param $seconds seconds. + * @param int $seconds seconds. * * @return array */ @@ -1648,7 +1649,7 @@ public function playtime_array( $seconds ) { * * @since 1.0.0 * - * @param $seconds seconds. + * @param int $seconds seconds. * * @return string */ @@ -7137,7 +7138,7 @@ public function tutor_pages() { * * @since 1.4.9 * - * @param int $course_id course id. + * @param int $content_id content id. * * @return array|null|object */ @@ -7442,7 +7443,8 @@ public function get_single_comment_user_post_id( $post_id, $user_id ) { * * @since 1.7.5 * - * @param int $course_id course id. + * @param int $course_or_product_id course or product id. + * @param bool $is_product_id is product id or not. * * @return bool */ From eff5cd577ec00f0f8abf9cfc64551ef57bbed1e8 Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Wed, 11 Oct 2023 12:19:08 +0600 Subject: [PATCH 11/12] on evaluate quiz auto complete course --- classes/Quiz.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/classes/Quiz.php b/classes/Quiz.php index 040b9be5d..40591b9f6 100644 --- a/classes/Quiz.php +++ b/classes/Quiz.php @@ -116,6 +116,8 @@ public function __construct() { * @since 2.1.0 */ add_action( 'wp_ajax_tutor_attempt_delete', array( $this, 'attempt_delete' ) ); + + add_action( 'tutor_quiz/answer/review/after', array( $this, 'do_auto_course_complete' ), 10, 3 ); } /** @@ -799,6 +801,24 @@ public function review_quiz_answer() { wp_send_json_success( array( 'html' => ob_get_clean() ) ); } + /** + * Do auto course complete after review a quiz attempt. + * + * @since 2.4.0 + * + * @param int $attempt_answer_id attempt answer id. + * @param int $course_id course id. + * @param int $user_id student id. + * + * @return void + */ + public function do_auto_course_complete( $attempt_answer_id, $course_id, $user_id ) { + if ( CourseModel::can_autocomplete_course( $course_id, $user_id ) ) { + CourseModel::mark_course_as_completed( $course_id, $user_id ); + Course::set_review_popup_data( $user_id, $course_id ); + } + } + /** * Save single quiz into database and send html response * From f02454daa1736804806a8fc28fa2fbbe2d8f93b8 Mon Sep 17 00:00:00 2001 From: "Md.Harun-Ur-Rashid" Date: Wed, 11 Oct 2023 12:41:25 +0600 Subject: [PATCH 12/12] class path imported --- templates/single/common/header.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/single/common/header.php b/templates/single/common/header.php index 5ec6150fb..e3101c6ae 100644 --- a/templates/single/common/header.php +++ b/templates/single/common/header.php @@ -28,7 +28,7 @@ * @since 2.4.0 update and refactor. */ if ( CourseModel::can_autocomplete_course( $course_id, $user_id ) ) { - \Tutor\Models\CourseModel::mark_course_as_completed( $course_id, $user_id ); + CourseModel::mark_course_as_completed( $course_id, $user_id ); /** * After auto complete the course.