← All changes
|
inc/jwt/rest-api/version1/class-lp-rest-courses-v1-controller.php
+78
-13
4.4.4
→
4.4.9
View file →
| @@ -2,8 +2,9 @@ | ||
| 2 | 2 | |
| 3 | 3 | use LearnPress\Models\CourseModel; |
| 4 | 4 | use LearnPress\Models\CoursePostModel; |
| 5 | 5 | use LearnPress\Models\Courses; |
| 6 | +use LearnPress\Models\PostModel; | |
| 6 | 7 | use LearnPress\Models\UserItems\UserCourseModel; |
| 7 | 8 | use LearnPress\Models\UserModel; |
| 8 | 9 | |
| 9 | 10 | class LP_Jwt_Courses_V1_Controller extends LP_REST_Jwt_Posts_Controller { |
| @@ -444,9 +445,9 @@ | ||
| 444 | 445 | * @param WP_REST_Request $request |
| 445 | 446 | * |
| 446 | 447 | * @return WP_REST_Response|LP_REST_Response |
| 447 | 448 | * @since 4.2.6.9 |
| 448 | - * @version 1.0.1 | |
| 449 | + * @version 1.0.2 | |
| 449 | 450 | */ |
| 450 | 451 | public function get_courses( WP_REST_Request $request ) { |
| 451 | 452 | $res = new LP_REST_Response(); |
| 452 | 453 | $courses = []; |
| @@ -457,8 +458,15 @@ | ||
| 457 | 458 | $params = $request->get_params(); |
| 458 | 459 | $params = $this->convert_params_query_courses( $params ); |
| 459 | 460 | |
| 460 | 461 | Courses::handle_params_for_query_courses( $filter, $params ); |
| 462 | + $filter->post_status = [ PostModel::STATUS_PUBLISH ]; | |
| 463 | + | |
| 464 | + // Filter by slug (post_name). | |
| 465 | + if ( ! empty( $params['slug'] ) ) { | |
| 466 | + $filter->post_name = is_array( $params['slug'] ) ? reset( $params['slug'] ) : $params['slug']; | |
| 467 | + } | |
| 468 | + | |
| 461 | 469 | $key_cache = 'api/' . md5( json_encode( $params ) ); |
| 462 | 470 | $key_cache_total = $key_cache . '_total'; |
| 463 | 471 | $key_cache_total_pages = $key_cache . '_total_pages'; |
| 464 | 472 | $lp_courses_cache = new LP_Courses_Cache( true ); |
| @@ -492,9 +500,9 @@ | ||
| 492 | 500 | } else { |
| 493 | 501 | // Check cache with case not learned |
| 494 | 502 | $courses_cache = $lp_courses_cache->get_cache( $key_cache ); |
| 495 | 503 | if ( $courses_cache !== false ) { |
| 496 | - $courses = json_decode( $courses_cache, true ); | |
| 504 | + $courses = $courses_cache; | |
| 497 | 505 | $total = (int) $lp_courses_cache->get_cache( $key_cache_total ); |
| 498 | 506 | $total_pages = (int) $lp_courses_cache->get_cache( $key_cache_total_pages ); |
| 499 | 507 | |
| 500 | 508 | $response = rest_ensure_response( $courses ); |
| @@ -541,12 +549,16 @@ | ||
| 541 | 549 | if ( empty( $course ) ) { |
| 542 | 550 | continue; |
| 543 | 551 | } |
| 544 | 552 | |
| 545 | - $courseObjPrepare = new stdClass(); | |
| 546 | - $courseObjPrepare->id = (int) $courseObj->ID ?? 0; | |
| 547 | - $courseObjPrepare->name = html_entity_decode( $course->get_title() ); | |
| 548 | - $courseObjPrepare->image = $course->get_image_url(); | |
| 553 | + $courseObjPrepare = new stdClass(); | |
| 554 | + $courseObjPrepare->id = (int) $courseObj->ID ?? 0; | |
| 555 | + $courseObjPrepare->name = html_entity_decode( $course->get_title() ); | |
| 556 | + $courseObjPrepare->slug = $courseObj->post_name ?? get_post_field( 'post_name', $courseObj->ID ); | |
| 557 | + $courseObjPrepare->permalink = get_permalink( $courseObj->ID ); | |
| 558 | + $courseObjPrepare->excerpt = $courseObj->post_excerpt ?? ''; | |
| 559 | + $courseObjPrepare->count_students = method_exists( $course, 'count_students' ) ? (int) $course->count_students() : 0; | |
| 560 | + $courseObjPrepare->image = $course->get_image_url(); | |
| 549 | 561 | $author = $course->get_author_model(); |
| 550 | 562 | $courseObjPrepare->instructor = ! empty( $author ) ? $this->get_author_info( $author ) : []; |
| 551 | 563 | $duration = $course->get_meta_value_by_key( CoursePostModel::META_KEY_DURATION, '' ); |
| 552 | 564 | $duration_arr = explode( ' ', $duration ); |
| @@ -576,11 +588,11 @@ | ||
| 576 | 588 | $courseObjPrepare->sale_price_rendered = html_entity_decode( |
| 577 | 589 | learn_press_format_price( $course->get_sale_price(), true ) |
| 578 | 590 | ); |
| 579 | 591 | // When release Addon Course Review v4.1.3 a long time, we will remove this code. |
| 580 | - $courseObjPrepare->rating = $this->get_course_rating( $courseObj->ID ); | |
| 581 | - $courseObjPrepare->meta_data = new stdClass(); | |
| 582 | - $courseObjPrepare->meta_data->_lp_passing_condition = $course->get_meta_value_by_key( CoursePostModel::META_KEY_PASSING_CONDITION ); | |
| 592 | + $courseObjPrepare->rating = $this->get_course_rating( $courseObj->ID ); | |
| 593 | + // All settings of the course metabox, same as the single course response. | |
| 594 | + $courseObjPrepare->meta_data = (object) $this->get_course_meta( $courseObj->ID ); | |
| 583 | 595 | |
| 584 | 596 | // Add more fields |
| 585 | 597 | if ( ! empty( $params['learned'] ) ) { |
| 586 | 598 | $courseObjPrepare->course_data = new stdClass(); |
| @@ -729,8 +741,13 @@ | ||
| 729 | 741 | public function prepare_object_for_response( $object, $request ) { |
| 730 | 742 | $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; |
| 731 | 743 | $data = $this->get_course_data( $object, $context, $request ); |
| 732 | 744 | |
| 745 | + // Ensure sections are always included for single-item response, regardless of schema/context filtering. | |
| 746 | + if ( empty( $request['optimize'] ) && ! isset( $data['sections'] ) ) { | |
| 747 | + $data['sections'] = $this->get_all_items( $object ); | |
| 748 | + } | |
| 749 | + | |
| 733 | 750 | $response = rest_ensure_response( $data ); |
| 734 | 751 | |
| 735 | 752 | return apply_filters( "lp_jwt_rest_prepare_{$this->post_type}_object", $response, $object, $request ); |
| 736 | 753 | } |
| @@ -993,13 +1010,44 @@ | ||
| 993 | 1010 | $output['id'] = $author->get_id(); |
| 994 | 1011 | $output['name'] = $author->get_display_name(); |
| 995 | 1012 | $output['description'] = $author->get_description(); |
| 996 | 1013 | $output['social'] = $extra_info; |
| 1014 | + $output['statistic'] = $this->get_instructor_statistic( $author ); | |
| 997 | 1015 | |
| 998 | 1016 | return $output; |
| 999 | 1017 | } |
| 1000 | 1018 | |
| 1001 | 1019 | /** |
| 1020 | + * Count the courses and the students of an instructor. | |
| 1021 | + * | |
| 1022 | + * Only used for the single course response, it costs several queries and | |
| 1023 | + * "LP_Cache::cache_load_first" only keeps the result within the current request. | |
| 1024 | + * | |
| 1025 | + * @param UserModel $author | |
| 1026 | + * | |
| 1027 | + * @return array | |
| 1028 | + */ | |
| 1029 | + protected function get_instructor_statistic( UserModel $author ): array { | |
| 1030 | + $statistic = $author->get_instructor_statistic(); | |
| 1031 | + | |
| 1032 | + // Keep the extra keys added by add-ons, only cast the ones of the core. | |
| 1033 | + $numeric_keys = array( | |
| 1034 | + 'total_course', | |
| 1035 | + 'published_course', | |
| 1036 | + 'pending_course', | |
| 1037 | + 'total_student', | |
| 1038 | + 'student_completed', | |
| 1039 | + 'student_in_progress', | |
| 1040 | + ); | |
| 1041 | + | |
| 1042 | + foreach ( $numeric_keys as $numeric_key ) { | |
| 1043 | + $statistic[ $numeric_key ] = absint( $statistic[ $numeric_key ] ?? 0 ); | |
| 1044 | + } | |
| 1045 | + | |
| 1046 | + return $statistic; | |
| 1047 | + } | |
| 1048 | + | |
| 1049 | + /** | |
| 1002 | 1050 | * Get instructor info |
| 1003 | 1051 | * |
| 1004 | 1052 | * @param UserModel $author |
| 1005 | 1053 | * |
| @@ -1137,8 +1185,9 @@ | ||
| 1137 | 1185 | |
| 1138 | 1186 | $data_item[] = array( |
| 1139 | 1187 | 'id' => $item->get_id(), |
| 1140 | 1188 | 'type' => $item->get_item_type(), |
| 1189 | + 'slug' => $post->post_name, | |
| 1141 | 1190 | 'title' => $post->post_title, |
| 1142 | 1191 | 'preview' => $item->is_preview(), |
| 1143 | 1192 | 'duration' => $item->get_duration()->to_timer( $format, true ), |
| 1144 | 1193 | 'graduation' => $user_item ? $user_item->get_graduation() : '', |
| @@ -1156,12 +1205,17 @@ | ||
| 1156 | 1205 | |
| 1157 | 1206 | return $output; |
| 1158 | 1207 | } |
| 1159 | 1208 | |
| 1209 | + /** | |
| 1210 | + * Get all settings of the course metabox. | |
| 1211 | + * | |
| 1212 | + * @param int $id Course ID. | |
| 1213 | + * | |
| 1214 | + * @return array | |
| 1215 | + */ | |
| 1160 | 1216 | public function get_course_meta( $id ) { |
| 1161 | - $user_id = get_current_user_id(); | |
| 1162 | - | |
| 1163 | - if ( ! $user_id ) { | |
| 1217 | + if ( empty( absint( $id ) ) ) { | |
| 1164 | 1218 | return array(); |
| 1165 | 1219 | } |
| 1166 | 1220 | |
| 1167 | 1221 | if ( ! class_exists( 'LP_Meta_Box' ) ) { |
| @@ -1171,9 +1225,9 @@ | ||
| 1171 | 1225 | if ( ! class_exists( 'LP_Meta_Box_Course' ) ) { |
| 1172 | 1226 | include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/course/settings.php'; |
| 1173 | 1227 | } |
| 1174 | 1228 | |
| 1175 | - $metabox = new LP_Meta_Box_Course(); | |
| 1229 | + $metabox = LP_Meta_Box_Course::instance(); | |
| 1176 | 1230 | |
| 1177 | 1231 | $output = array(); |
| 1178 | 1232 | |
| 1179 | 1233 | foreach ( $metabox->metabox( $id ) as $key => $tab ) { |
| @@ -1526,8 +1580,14 @@ | ||
| 1526 | 1580 | 'type' => 'array', |
| 1527 | 1581 | 'context' => array( 'view' ), |
| 1528 | 1582 | 'readonly' => true, |
| 1529 | 1583 | ), |
| 1584 | + 'statistic' => array( | |
| 1585 | + 'description' => __( 'Total courses and students of the instructor.', 'learnpress' ), | |
| 1586 | + 'type' => 'object', | |
| 1587 | + 'context' => array( 'view' ), | |
| 1588 | + 'readonly' => true, | |
| 1589 | + ), | |
| 1530 | 1590 | ), |
| 1531 | 1591 | ), |
| 1532 | 1592 | ), |
| 1533 | 1593 | 'sections' => array( |
| @@ -1568,8 +1628,13 @@ | ||
| 1568 | 1628 | 'context' => array( 'view', 'edit' ), |
| 1569 | 1629 | ), |
| 1570 | 1630 | 'type' => array( |
| 1571 | 1631 | 'description' => __( 'Item Type.', 'learnpress' ), |
| 1632 | + 'type' => 'string', | |
| 1633 | + 'context' => array( 'view', 'edit' ), | |
| 1634 | + ), | |
| 1635 | + 'slug' => array( | |
| 1636 | + 'description' => __( 'Item slug.', 'learnpress' ), | |
| 1572 | 1637 | 'type' => 'string', |
| 1573 | 1638 | 'context' => array( 'view', 'edit' ), |
| 1574 | 1639 | ), |
| 1575 | 1640 | 'title' => array( |