PluginProbe
Tutor LMS – eLearning and online course solution / 2.4.0
Tutor LMS – eLearning and online course solution v2.4.0
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 All 191 releases
← All changes | models/CourseModel.php +156 -10 2.3.02.4.0 View file →
@@ -32,8 +32,14 @@
32 32 const STATUS_PRIVATE = 'private';
33 33 const STATUS_FUTURE = 'future';
34 34
35 35 /**
36 + * Course completion modes
37 + */
38 + const MODE_FLEXIBLE = 'flexible';
39 + const MODE_STRICT = 'strict';
40 +
41 + /**
36 42 * Course mapped with the product using this meta key
37 43 *
38 44 * @var string
39 45 */
@@ -126,9 +132,9 @@
126 132 * Get course count by instructor
127 133 *
128 134 * @since 1.0.0
129 135 *
130 - * @param $instructor_id
136 + * @param int $instructor_id instructor ID.
131 137 *
132 138 * @return null|string
133 139 */
134 140 public static function get_course_count_by_instructor( $instructor_id ) {
@@ -161,9 +167,9 @@
161 167 * Get course by quiz
162 168 *
163 169 * @since 1.0.0
164 170 *
165 - * @param $quiz_id quiz id.
171 + * @param int $quiz_id quiz id.
166 172 *
167 173 * @return array|bool|null|object|void
168 174 */
169 175 public static function get_course_by_quiz( $quiz_id ) {
@@ -172,9 +178,9 @@
172 178
173 179 if ( $post ) {
174 180 $course = get_post( $post->post_parent );
175 181 if ( $course ) {
176 - if ( $course->post_type !== tutor()->course_post_type ) {
182 + if ( tutor()->course_post_type !== $course->post_type ) {
177 183 $course = get_post( $course->post_parent );
178 184 }
179 185 return $course;
180 186 }
@@ -187,13 +193,13 @@
187 193 * Get courses by a instructor
188 194 *
189 195 * @since 1.0.0
190 196 *
191 - * @param integer $instructor_id
192 - * @param array|string $post_status
193 - * @param integer $offset
194 - * @param integer $limit
195 - * @param boolean $count_only
197 + * @param integer $instructor_id instructor id.
198 + * @param array|string $post_status post status.
199 + * @param integer $offset offset.
200 + * @param integer $limit limit.
201 + * @param boolean $count_only count or not.
196 202 *
197 203 * @return array|null|object
198 204 */
199 205 public static function get_courses_by_instructor( $instructor_id = 0, $post_status = array( 'publish' ), int $offset = 0, int $limit = PHP_INT_MAX, $count_only = false ) {
@@ -202,9 +208,9 @@
202 208 $limit = sanitize_text_field( $limit );
203 209 $instructor_id = tutils()->get_user_id( $instructor_id );
204 210 $course_post_type = tutor()->course_post_type;
205 211
206 - if ( empty( $post_status ) || $post_status == 'any' ) {
212 + if ( empty( $post_status ) || 'any' == $post_status ) {
207 213 $where_post_status = '';
208 214 } else {
209 215 ! is_array( $post_status ) ? $post_status = array( $post_status ) : 0;
210 216 $statuses = "'" . implode( "','", $post_status ) . "'";
@@ -213,8 +219,9 @@
213 219
214 220 $select_col = $count_only ? " COUNT(DISTINCT $wpdb->posts.ID) " : " $wpdb->posts.* ";
215 221 $limit_offset = $count_only ? '' : " LIMIT $offset, $limit ";
216 222
223 + //phpcs:disable
217 224 $query = $wpdb->prepare(
218 225 "SELECT $select_col
219 226 FROM $wpdb->posts
220 227 LEFT JOIN {$wpdb->usermeta}
@@ -230,9 +237,11 @@
230 237 $course_post_type,
231 238 $instructor_id,
232 239 $instructor_id
233 240 );
241 + //phpcs:enable
234 242
243 + //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
235 244 return $count_only ? $wpdb->get_var( $query ) : $wpdb->get_results( $query, OBJECT );
236 245 }
237 246
238 247 /**
@@ -301,9 +310,9 @@
301 310 * Marking course completed at Comment.
302 311 */
303 312 global $wpdb;
304 313
305 - $date = date( 'Y-m-d H:i:s', tutor_time() );
314 + $date = date( 'Y-m-d H:i:s', tutor_time() ); //phpcs:ignore
306 315
307 316 // Making sure that, hash is unique.
308 317 do {
309 318 $hash = substr( md5( wp_generate_password( 32 ) . $date . $course_id . $user_id ), 0, 16 );
@@ -578,6 +587,143 @@
578 587 return $query->posts;
579 588 }
580 589
581 590 return array();
591 + }
592 +
593 + /**
594 + * Check the course is completeable or not
595 + *
596 + * @since 2.4.0
597 + *
598 + * @param int $course_id course id.
599 + * @param int $user_id user id.
600 + *
601 + * @return boolean
602 + */
603 + public static function can_complete_course( $course_id, $user_id ) {
604 +
605 + $mode = tutor_utils()->get_option( 'course_completion_process' );
606 + if ( self::MODE_FLEXIBLE === $mode ) {
607 + return true;
608 + }
609 +
610 + if ( self::MODE_STRICT === $mode ) {
611 + $completed_lesson = tutor_utils()->get_completed_lesson_count_by_course( $course_id, $user_id );
612 + $lesson_count = tutor_utils()->get_lesson_count_by_course( $course_id, $user_id );
613 +
614 + if ( $completed_lesson < $lesson_count ) {
615 + return false;
616 + }
617 +
618 + $quizzes = array();
619 + $assignments = array();
620 +
621 + $course_contents = tutor_utils()->get_course_contents_by_id( $course_id );
622 + if ( tutor_utils()->count( $course_contents ) ) {
623 + foreach ( $course_contents as $content ) {
624 + if ( 'tutor_quiz' === $content->post_type ) {
625 + $quizzes[] = $content;
626 + }
627 + if ( 'tutor_assignments' === $content->post_type ) {
628 + $assignments[] = $content;
629 + }
630 + }
631 + }
632 +
633 + foreach ( $quizzes as $row ) {
634 + $result = QuizModel::get_quiz_result( $row->ID );
635 + if ( 'pass' !== $result ) {
636 + return false;
637 + }
638 + }
639 +
640 + if ( tutor()->has_pro ) {
641 + foreach ( $assignments as $row ) {
642 + $result = \TUTOR_ASSIGNMENTS\Assignments::get_assignment_result( $row->ID, $user_id );
643 + if ( 'pass' !== $result ) {
644 + return false;
645 + }
646 + }
647 + }
648 +
649 + return true;
650 + }
651 +
652 + return false;
653 +
654 + }
655 +
656 + /**
657 + * Check a course can be auto complete by an enrolled student.
658 + *
659 + * @since 2.4.0
660 + *
661 + * @param int $course_id course id.
662 + * @param int $user_id user id.
663 + *
664 + * @return boolean
665 + */
666 + public static function can_autocomplete_course( $course_id, $user_id ) {
667 + $auto_course_complete_option = (bool) tutor_utils()->get_option( 'auto_course_complete_on_all_lesson_completion' );
668 + if ( ! $auto_course_complete_option ) {
669 + return false;
670 + }
671 +
672 + $is_course_completed = tutor_utils()->is_completed_course( $course_id, $user_id );
673 + if ( $is_course_completed ) {
674 + return false;
675 + }
676 +
677 + $course_stats = tutor_utils()->get_course_completed_percent( $course_id, $user_id, true );
678 + if ( $course_stats['total_count'] && $course_stats['completed_count'] === $course_stats['total_count'] ) {
679 + return self::can_complete_course( $course_id, $user_id );
680 + } else {
681 + return false;
682 + }
683 + }
684 +
685 + /**
686 + * Get review progress link when course progress 100% and
687 + * User has pending or fail quiz or assignment
688 + *
689 + * @since 2.4.0
690 + *
691 + * @param int $course_id course id.
692 + * @param int $user_id user id.
693 + *
694 + * @return string course content permalink.
695 + */
696 + public static function get_review_progress_link( $course_id, $user_id ) {
697 + $course_progress = tutor_utils()->get_course_completed_percent( $course_id, $user_id, true );
698 + $completed_percent = (int) $course_progress['completed_percent'];
699 + $course_contents = tutor_utils()->get_course_contents_by_id( $course_id );
700 + $permalink = '';
701 +
702 + if ( tutor_utils()->count( $course_contents ) && 100 === $completed_percent ) {
703 + foreach ( $course_contents as $content ) {
704 + if ( 'tutor_quiz' === $content->post_type ) {
705 + $result = QuizModel::get_quiz_result( $content->ID, $user_id );
706 + if ( 'pass' !== $result ) {
707 + $permalink = get_the_permalink( $content->ID );
708 + break;
709 + }
710 + }
711 +
712 + if ( tutor()->has_pro && 'tutor_assignments' === $content->post_type ) {
713 + $result = \TUTOR_ASSIGNMENTS\Assignments::get_assignment_result( $content->ID, $user_id );
714 + if ( 'pass' !== $result ) {
715 + $permalink = get_the_permalink( $content->ID );
716 + break;
717 + }
718 + }
719 + }
720 + }
721 +
722 + // Fallback link.
723 + if ( empty( $permalink ) ) {
724 + $permalink = tutils()->get_course_first_lesson( $course_id );
725 + }
726 +
727 + return $permalink;
582 728 }
583 729 }