PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/course/abstract-course.php +183 -82 4.2.04.4.8 View file →
@@ -6,8 +6,12 @@
6 6 * @package LearnPress/Classes
7 7 * @version 4.0.0
8 8 */
9 9
10 +use LearnPress\Models\CourseModel;
11 +use LearnPress\TemplateHooks\Course\SingleCourseTemplate;
12 +use LearnPress\TemplateHooks\Instructor\SingleInstructorTemplate;
13 +
10 14 defined( 'ABSPATH' ) || exit();
11 15
12 16 if ( ! function_exists( 'LP_Abstract_Course' ) ) {
13 17
@@ -161,8 +165,14 @@
161 165 if ( metadata_exists( 'post', $this->get_id(), '_lp_regular_price' ) ) {
162 166 $regular_price = get_post_meta( $id, '_lp_regular_price', true );
163 167 }
164 168
169 + $block_course_finished = get_post_meta(
170 + $id,
171 + '_lp_block_finished',
172 + true
173 + );
174 +
165 175 $this->_set_data(
166 176 array(
167 177 'status' => $post_object->post_status,
168 178 'no_required_enroll' => get_post_meta( $id, '_lp_no_required_enroll', true ),
@@ -185,15 +195,12 @@
185 195 $id,
186 196 '_lp_block_expire_duration',
187 197 true
188 198 ),
189 - 'block_course_finished' => get_post_meta(
190 - $id,
191 - '_lp_block_finished',
192 - true
193 - ),
199 + 'block_course_finished' => $block_course_finished ? $block_course_finished : 'yes',
194 200 'allow_repurchase' => get_post_meta( $id, '_lp_allow_course_repurchase', true ),
195 201 'allow_repurchase_course_option' => get_post_meta( $id, '_lp_course_repurchase_option', true ),
202 + 'excerpt' => $post_object->post_excerpt,
196 203 )
197 204 );
198 205 }
199 206
@@ -297,13 +304,9 @@
297 304 $url = get_the_post_thumbnail_url( $parent_id, $size );
298 305 }
299 306
300 307 if ( ! $url ) {
301 - if ( 'course_thumbnail' == $size ) {
302 - $url = LearnPress::instance()->image( 'no-image.png' );
303 - } else {
304 - $url = LearnPress::instance()->image( 'placeholder-500x300' );
305 - }
308 + $url = LearnPress::instance()->image( 'no-image.png' );
306 309 }
307 310
308 311 return apply_filters( 'learn-press/course-thumbnail-url', $url, $this->get_id(), $size );
309 312 }
@@ -353,16 +356,12 @@
353 356 *
354 357 * @author hungkv
355 358 * @since 4.0.5
356 359 * @return bool
357 - * @version 1.0.0
360 + * @version 1.0.1
358 361 */
359 362 public function is_no_required_enroll(): bool {
360 - $return = false;
361 - if ( $this->get_data( 'no_required_enroll', 'no' ) == 'yes' && ! is_user_logged_in() ) {
362 - $return = true;
363 - }
364 - return apply_filters( 'learn-press/course/require-enrollment', $return, $this->get_id() );
363 + return $this->get_data( 'no_required_enroll', 'no' ) === 'yes' && ! is_user_logged_in();
365 364 }
366 365
367 366 /**
368 367 * @deprecated 4.1.6.9
@@ -451,9 +450,9 @@
451 450 * Get total students fake.
452 451 *
453 452 * @return int
454 453 */
455 - public function get_fake_students() : int {
454 + public function get_fake_students(): int {
456 455 return absint( $this->get_data( 'fake_students', 0 ) );
457 456 }
458 457
459 458 /**
@@ -506,33 +505,43 @@
506 505 return apply_filters( 'learn-press/course/instructor-name', $name, $this->get_id() );
507 506 }
508 507
509 508 /**
509 + * Get instructor html of course.
510 + *
510 511 * @param int|bool $with_avatar
511 512 * @param string $link_class
512 513 *
513 514 * @return string
514 515 */
515 - public function get_instructor_html( $with_avatar = false, $link_class = '' ) {
516 - $instructor = $this->get_instructor_name();
516 + public function get_instructor_html( $with_avatar = false, $link_class = '' ): string {
517 + $html = '';
517 518
518 - $html = sprintf(
519 - '<a href="%s"%s>%s<span>%s</span></a>',
520 - learn_press_user_profile_link( get_post_field( 'post_author', $this->get_id() ) ),
521 - $link_class ? sprintf( 'class="%s"', $link_class ) : '',
522 - $with_avatar ? get_avatar(
523 - $this->get_instructor( 'id' ),
524 - $with_avatar === true ? 48 : $with_avatar
525 - ) : '',
526 - $instructor
527 - );
519 + try {
520 + $instructor = $this->get_author();
521 + if ( ! $instructor ) {
522 + return '';
523 + }
528 524
529 - return apply_filters(
530 - 'learn_press_course_instructor_html',
531 - $html,
532 - get_post_field( 'post_author', $this->get_id() ),
533 - $this->get_id()
534 - );
525 + $singleInstructorTemplate = SingleInstructorTemplate::instance();
526 +
527 + $html = apply_filters(
528 + 'learn-press/course/instructor-html',
529 + sprintf(
530 + '<a href="%s"%s>%s %s</a>',
531 + $instructor->get_url_instructor(),
532 + $link_class ? sprintf( 'class="%s"', $link_class ) : '',
533 + $with_avatar ? $instructor->get_profile_picture() : '',
534 + $singleInstructorTemplate->html_display_name( $instructor )
535 + ),
536 + $instructor,
537 + $singleInstructorTemplate
538 + );
539 + } catch ( Throwable $e ) {
540 + error_log( $e->getMessage() );
541 + }
542 +
543 + return $html;
535 544 }
536 545
537 546 /**
538 547 * Check if a course is Free
@@ -552,9 +561,9 @@
552 561 public function get_sale_price() {
553 562 $sale_price_value = $this->get_data( 'sale_price', '' );
554 563
555 564 if ( '' !== $sale_price_value ) {
556 - return floatval( $sale_price_value );
565 + return apply_filters( 'learn-press/course/sale-price', floatval( $sale_price_value ), $this->get_id() );
557 566 }
558 567
559 568 return $sale_price_value;
560 569 }
@@ -576,11 +585,14 @@
576 585 }
577 586
578 587 // Check in days sale
579 588 if ( $has_sale_price && '' !== $start_date && '' !== $end_date ) {
580 - $now = strtotime( get_date_from_gmt( gmdate( 'Y-m-d H:i:s', time() ), 'Y-m-d H:i:s' ) );
581 - $end = strtotime( $end_date );
582 - $start = strtotime( $start_date );
589 + $nowObj = new LP_Datetime();
590 + // Compare via timezone WP
591 + $nowStr = $nowObj->toSql( true );
592 + $now = strtotime( $nowStr );
593 + $end = strtotime( $end_date );
594 + $start = strtotime( $start_date );
583 595
584 596 $has_sale_price = $now >= $start && $now <= $end;
585 597 }
586 598
@@ -608,9 +620,9 @@
608 620 */
609 621 public function get_regular_price_html() {
610 622 $price = learn_press_format_price( $this->get_regular_price(), true );
611 623
612 - return apply_filters( 'learn-press/course/regular-price', $price, $this->get_id() );
624 + return apply_filters( 'learn-press/course/regular-price-html', $price, $this->get_id() );
613 625 }
614 626
615 627 /**
616 628 * Get the price of course.
@@ -623,18 +635,20 @@
623 635
624 636 if ( false === $price ) {
625 637 if ( $this->has_sale_price() ) {
626 638 $price = $this->get_sale_price();
627 - // Add key _lp_course_is_sale for query
628 - update_post_meta( $this->get_id(), '_lp_course_is_sale', 1 );
639 + // Add key _lp_course_is_sale for query - Todo: Check performance, need write function get all courses, and set on Admin, on background
640 + //update_post_meta( $this->get_id(), '_lp_course_is_sale', 1 );
629 641 } else {
630 642 // Delete key _lp_course_is_sale
631 - delete_post_meta( $this->get_id(), '_lp_course_is_sale' );
643 + //delete_post_meta( $this->get_id(), '_lp_course_is_sale' );
632 644 $price = $this->get_regular_price();
633 645 }
634 646
635 - // For case set sale by days range
636 - update_post_meta( $this->get_id(), '_lp_price', $price );
647 + // Save price only on page Single Course
648 + /*if ( LP_PAGE_SINGLE_COURSE === LP_Page_Controller::page_current() ) {
649 + update_post_meta( $this->get_id(), '_lp_price', $price );
650 + }*/
637 651
638 652 LP_Course_Cache::cache_load_first( 'set', $key_cache, $price );
639 653 }
640 654
@@ -645,12 +659,12 @@
645 659 * Get html course price
646 660 *
647 661 * @author tungnx
648 662 * @since 4.1.5
649 - * @version 1.0.0
650 - * @return mixed|void
663 + * @version 1.0.2
664 + * @return string
651 665 */
652 - public function get_course_price_html() {
666 + public function get_course_price_html(): string {
653 667 $price_html = '';
654 668
655 669 if ( $this->is_free() ) {
656 670 if ( is_float( $this->get_sale_price() ) ) {
@@ -658,18 +672,28 @@
658 672 }
659 673
660 674 $price_html .= sprintf( '<span class="free">%s</span>', esc_html__( 'Free', 'learnpress' ) );
661 675 $price_html = apply_filters( 'learn_press_course_price_html_free', $price_html, $this );
676 + } elseif ( $this->get_data( 'no_required_enroll', 'no' ) === 'yes' ) {
677 + $price_html .= '';
662 678 } else {
663 679 if ( $this->has_sale_price() ) {
664 680 $price_html .= sprintf( '<span class="origin-price">%s</span>', $this->get_regular_price_html() );
665 681 }
666 682
667 - $price_html .= sprintf( '<span class="price">%s</span>', learn_press_format_price( $this->get_price(), true ) );
668 - $price_html = apply_filters( 'learn_press_course_price_html', $price_html, $this->has_sale_price(), $this->get_id() );
683 + $price_html .= sprintf( '<span class="price">%s</span>', learn_press_format_price( $this->get_price(), true ) );
684 + $course = CourseModel::find( $this->get_id(), true );
685 + $singleCourseTemplate = SingleCourseTemplate::instance();
686 + $price_html = sprintf(
687 + '%1$s %2$s %3$s',
688 + $singleCourseTemplate->html_price_prefix( $course ),
689 + $price_html,
690 + $singleCourseTemplate->html_price_suffix( $course )
691 + );
692 + $price_html = apply_filters( 'learn_press_course_price_html', $price_html, $this->has_sale_price(), $this->get_id() );
669 693 }
670 694
671 - return $price_html;
695 + return sprintf( '<span class="course-item-price">%s</span>', $price_html );
672 696 }
673 697
674 698 /**
675 699 * Get the price of course with html
@@ -803,11 +827,14 @@
803 827 return apply_filters( 'learn-press/is-purchasable', $is_purchasable, $this->get_id() );
804 828 }
805 829
806 830 /**
807 - * Check if students have enrolled or purchased course is reached.
831 + * Check if students have purchased course is reached.
832 + * For case check course can purchase.
808 833 *
809 834 * @return mixed
835 + * @since 3.0.0
836 + * @version 1.0.1
810 837 */
811 838 public function is_in_stock() {
812 839 $in_stock = true;
813 840 $max_allowed = $this->get_max_students();
@@ -819,8 +846,27 @@
819 846 return apply_filters( 'learn-press/is-in-stock', $in_stock, $this->get_id() );
820 847 }
821 848
822 849 /**
850 + * Check max student can enroll.
851 + * For case check course can enroll.
852 + *
853 + * @return mixed
854 + * @since 4.2.5.7
855 + * @version 1.0.0
856 + */
857 + public function is_in_stock_enroll() {
858 + $in_stock = true;
859 + $max_allowed = $this->get_max_students();
860 +
861 + if ( $max_allowed ) {
862 + $in_stock = $max_allowed > $this->get_total_user_enrolled_or_purchased();
863 + }
864 +
865 + return apply_filters( 'learn-press/is-in-stock', $in_stock, $this->get_id() );
866 + }
867 +
868 + /**
823 869 * Get max students can enroll to course.
824 870 *
825 871 * @return int
826 872 *
@@ -840,24 +886,16 @@
840 886 * and add the fake value if both are set.
841 887 *
842 888 * @return int
843 889 * @editor tungnx
890 + * @version 1.0.1
891 + * @since 3.0.0
844 892 * @Todo: view and rewrite this function
845 893 */
846 894 public function count_students(): int {
847 - $key_cache = "{$this->get_id()}/total-students";
848 - $total = LP_Course_Cache::instance()->get_cache( $key_cache );
895 + $total = $this->get_total_user_enrolled_or_purchased();
896 + $total += $this->get_fake_students();
849 897
850 - if ( $total ) {
851 - return $total;
852 - }
853 -
854 - $lp_course_db = LP_Course_DB::getInstance();
855 - $total = $lp_course_db->get_total_user_enrolled( $this->get_id() );
856 - $total += $this->get_fake_students();
857 -
858 - LP_Course_Cache::instance()->set_cache( $key_cache, $total, 6 * HOUR_IN_SECONDS );
859 -
860 898 return $total;
861 899 }
862 900
863 901 /**
@@ -862,32 +900,83 @@
862 900
863 901 /**
864 902 * Get total user enrolled
865 903 *
904 + * @since 4.1.4
905 + * @version 1.0.1
866 906 * @return int
867 907 */
868 908 public function get_total_user_enrolled(): int {
869 - $lp_course_db = LP_Course_DB::getInstance();
870 - return $lp_course_db->get_total_user_enrolled( $this->get_id() );
909 + $total = 0;
910 + $lp_course_cache = new LP_Course_Cache( true );
911 +
912 + try {
913 + $total = $lp_course_cache->get_total_students_enrolled( $this->get_id() );
914 + if ( false !== $total ) {
915 + return $total;
916 + }
917 +
918 + $lp_course_db = LP_Course_DB::getInstance();
919 + $total = $lp_course_db->get_total_user_enrolled( $this->get_id() );
920 + $lp_course_cache->set_total_students_enrolled( $this->get_id(), $total );
921 + } catch ( Throwable $e ) {
922 + error_log( $e->getMessage() );
923 + }
924 +
925 + return $total;
871 926 }
872 927
873 928 /**
874 - * Get total user enrolled or finished
929 + * Get total user enrolled include fake
930 + * @since 4.2.2
931 + * @return int
932 + */
933 + /*public function get_total_user_enrolled_include_fake() {
934 + $total_user_enrolled = 0;
935 + $key_cache = "{$this->get_id()}/total-students-include-fake";
936 +
937 + try {
938 + $total_user_enrolled = LP_Course_Cache::cache_load_first( 'get', $key_cache );
939 +
940 + if ( false === $total_user_enrolled ) {
941 + $lp_course_db = LP_Course_DB::getInstance();
942 + $total_user_enrolled = $lp_course_db->get_total_user_enrolled( $this->get_id() );
943 + $total_user_enrolled += $this->get_fake_students();
944 +
945 + LP_Course_Cache::cache_load_first( 'set', $key_cache, $total_user_enrolled );
946 + }
947 + } catch ( Throwable $e ) {
948 + error_log( $e->getMessage() );
949 + }
950 +
951 + return $total_user_enrolled;
952 + }*/
953 +
954 + /**
955 + * Get total user enrolled, purchased or finished
875 956 *
957 + * @since 4.1.4
958 + * @version 1.0.1
876 959 * @return int
877 960 */
878 961 public function get_total_user_enrolled_or_purchased(): int {
879 - $key_cache = "{$this->get_id()}/total-students-attended";
880 - $total_user_enrolled = LP_Course_Cache::cache_load_first( 'get', $key_cache );
962 + $total = 0;
963 + $lp_course_cache = new LP_Course_Cache( true );
881 964
882 - if ( false === $total_user_enrolled ) {
883 - $lp_course_db = LP_Course_DB::getInstance();
884 - $total_user_enrolled = $lp_course_db->get_total_user_enrolled_or_purchased( $this->get_id() );
965 + try {
966 + $total = $lp_course_cache->get_total_students_enrolled_or_purchased( $this->get_id() );
967 + if ( false !== $total ) {
968 + return $total;
969 + }
885 970
886 - LP_Course_Cache::cache_load_first( 'set', $key_cache, $total_user_enrolled );
971 + $lp_course_db = LP_Course_DB::getInstance();
972 + $total = $lp_course_db->get_total_user_enrolled_or_purchased( $this->get_id() );
973 + $lp_course_cache->set_total_students_enrolled_or_purchased( $this->get_id(), $total );
974 + } catch ( Throwable $e ) {
975 + error_log( $e->getMessage() );
887 976 }
888 977
889 - return $total_user_enrolled;
978 + return $total;
890 979 }
891 980
892 981 /**
893 982 * @param string|array $statuses
@@ -967,9 +1056,9 @@
967 1056 * @param string $context
968 1057 *
969 1058 * @return array|mixed|string
970 1059 */
971 - public function get_passing_condition( $format = false, $context = '' ) {
1060 + public function get_passing_condition( $format = false ) {
972 1061 $value = absint( $this->get_data( 'passing_condition' ) );
973 1062
974 1063 if ( $format ) {
975 1064 $value = "{$value}%";
@@ -974,9 +1063,9 @@
974 1063 if ( $format ) {
975 1064 $value = "{$value}%";
976 1065 }
977 1066
978 - return 'edit' === $context ? $value : apply_filters(
1067 + return apply_filters(
979 1068 'learn-press/course-passing-condition',
980 1069 $value,
981 1070 $format,
982 1071 $this->get_id()
@@ -1009,11 +1098,10 @@
1009 1098 $this->get_id()
1010 1099 );
1011 1100
1012 1101 $slug_prefix = trailingslashit( $slug_prefixes[ $item_type ] ?? '' );
1102 + $item_link = trailingslashit( $course_permalink . $slug_prefix . $item_slug );
1013 1103
1014 - $item_link = $course_permalink . $slug_prefix . $item_slug;
1015 -
1016 1104 return apply_filters( 'learn-press/course/item-link', $item_link, $item_id, $this );
1017 1105 }
1018 1106
1019 1107 /**
@@ -1074,9 +1162,9 @@
1074 1162 */
1075 1163 public function get_next_item( $args = null ) {
1076 1164 $item_nav = $this->get_item_nav();
1077 1165
1078 - return apply_filters( 'learn-press/course/next-item', $item_nav[2], $this->get_id(), $args );
1166 + return apply_filters( 'learn-press/course/next-item', $item_nav ? $item_nav[2] : 0, $this->get_id(), $args );
1079 1167 }
1080 1168
1081 1169 /**
1082 1170 * Get item standing before the item is viewing.
@@ -1086,8 +1174,11 @@
1086 1174 * @return int
1087 1175 */
1088 1176 public function get_prev_item( $args = null ) {
1089 1177 $item_nav = $this->get_item_nav();
1178 + if ( ! is_array( $item_nav ) || empty( $item_nav ) ) {
1179 + return 0;
1180 + }
1090 1181
1091 1182 return apply_filters( 'learn-press/course/prev-item', $item_nav[0], $this->get_id(), $args );
1092 1183 }
1093 1184
@@ -1121,9 +1212,9 @@
1121 1212 $user = learn_press_get_current_user();
1122 1213 $pos_tmp = $pos;
1123 1214
1124 1215 while ( $pos_tmp < $max ) {
1125 - $pos_tmp ++;
1216 + ++$pos_tmp;
1126 1217
1127 1218 if ( ! $viewable ) {
1128 1219 $next_id = $item_ids[ $pos_tmp ];
1129 1220
@@ -1133,9 +1224,9 @@
1133 1224
1134 1225 $pos_tmp = $pos;
1135 1226
1136 1227 while ( $pos_tmp > 0 ) {
1137 - $pos_tmp --;
1228 + --$pos_tmp;
1138 1229
1139 1230 if ( ! $viewable ) {
1140 1231 $prev_id = $item_ids[ $pos_tmp ];
1141 1232
@@ -1184,9 +1275,8 @@
1184 1275 return false;
1185 1276 }
1186 1277
1187 1278 public function get_prev_item_html( $args = null ) {
1188 -
1189 1279 }
1190 1280
1191 1281 public function get_preview_items() {
1192 1282 return LP_Object_Cache::get( 'course-' . $this->get_id(), 'learn-press/course-preview-items' );
@@ -1368,6 +1458,17 @@
1368 1458 $this->get_id(),
1369 1459 $this
1370 1460 );
1371 1461 }
1462 +
1463 + /**
1464 + * [get_downloadable_material get all material files of this course and lesson of this course]
1465 + * @return [array] [array of material files or empty array]
1466 + * @deprecated 4.2.6.4
1467 + */
1468 + /*public function get_downloadable_material(): array {
1469 + $material = LP_Material_Files_DB::getInstance();
1470 + $materials = $material->get_material_by_item_id( $this->get_id(), 1 );
1471 + return apply_filters( 'learn-press/course-materials', $materials, $this->get_id() );
1472 + }*/
1372 1473 }
1373 1474 }