← All changes
|
inc/jwt/rest-api/version1/class-lp-rest-users-v1-controller.php
+106
-58
4.1.7.3
→
4.4.9
View file →
| @@ -1,5 +1,8 @@ | ||
| 1 | 1 | <?php |
| 2 | + | |
| 3 | +use LearnPress\Models\UserModel; | |
| 4 | + | |
| 2 | 5 | /** |
| 3 | 6 | * REST API for the user. |
| 4 | 7 | * |
| 5 | 8 | * @package LearnPress/JWT/RESTAPI |
| @@ -127,16 +130,8 @@ | ||
| 127 | 130 | ); |
| 128 | 131 | } |
| 129 | 132 | |
| 130 | 133 | public function get_items_permissions_check( $request ) { |
| 131 | - if ( ! empty( $request['roles'] ) && ! ( in_array( 'lp_teacher', $request['roles'] ) || in_array( 'subscriber', $request['roles'] ) ) && ! current_user_can( 'list_users' ) ) { | |
| 132 | - return new WP_Error( | |
| 133 | - 'rest_user_cannot_view', | |
| 134 | - __( 'Sorry, you are not allowed to filter users by role.' ), | |
| 135 | - array( 'status' => rest_authorization_required_code() ) | |
| 136 | - ); | |
| 137 | - } | |
| 138 | - | |
| 139 | 134 | return true; |
| 140 | 135 | } |
| 141 | 136 | |
| 142 | 137 | public function get_item_permissions_check( $request ) { |
| @@ -145,26 +140,26 @@ | ||
| 145 | 140 | if ( is_wp_error( $user ) ) { |
| 146 | 141 | return $user; |
| 147 | 142 | } |
| 148 | 143 | |
| 144 | + if ( ! is_user_logged_in() ) { | |
| 145 | + return new WP_Error( | |
| 146 | + 'rest_forbidden', | |
| 147 | + __( 'Authentication required to access user information.' ), | |
| 148 | + array( 'status' => rest_authorization_required_code() ) | |
| 149 | + ); | |
| 150 | + } | |
| 151 | + | |
| 149 | 152 | $types = get_post_types( array( 'show_in_rest' => true ), 'names' ); |
| 150 | 153 | |
| 151 | 154 | if ( get_current_user_id() === $user->ID ) { |
| 152 | 155 | return true; |
| 153 | - } | |
| 154 | - | |
| 155 | - if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { | |
| 156 | + } elseif ( ! current_user_can( UserModel::ROLE_ADMINISTRATOR ) ) { | |
| 156 | 157 | return new WP_Error( |
| 157 | 158 | 'rest_user_cannot_view', |
| 158 | 159 | __( 'Sorry, you are not allowed to list users.' ), |
| 159 | 160 | array( 'status' => rest_authorization_required_code() ) |
| 160 | 161 | ); |
| 161 | - } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) { | |
| 162 | - return new WP_Error( | |
| 163 | - 'rest_user_cannot_view', | |
| 164 | - __( 'Sorry, you are not allowed to list users.' ), | |
| 165 | - array( 'status' => rest_authorization_required_code() ) | |
| 166 | - ); | |
| 167 | 162 | } |
| 168 | 163 | |
| 169 | 164 | return true; |
| 170 | 165 | } |
| @@ -657,16 +652,15 @@ | ||
| 657 | 652 | |
| 658 | 653 | return $output; |
| 659 | 654 | } |
| 660 | 655 | |
| 661 | - public function get_course_tab_contents( $request ) { | |
| 656 | + public function get_course_tab_contents( $user, $request ) { | |
| 662 | 657 | $output = array( |
| 663 | 658 | 'enrolled' => array(), |
| 664 | 659 | 'created' => array(), |
| 665 | 660 | ); |
| 666 | 661 | |
| 667 | - $profile = learn_press_get_profile( $request['id'] ); | |
| 668 | - $user = learn_press_get_user( $request['id'] ); | |
| 662 | + $profile = learn_press_get_profile( $user->get_id() ); | |
| 669 | 663 | $filters_enrolled = array( |
| 670 | 664 | 'all' => 'all', |
| 671 | 665 | 'finished' => 'finished', |
| 672 | 666 | 'passed' => 'passed', |
| @@ -684,14 +678,15 @@ | ||
| 684 | 678 | 'paged' => $request['paged'] ?? 1, |
| 685 | 679 | ) |
| 686 | 680 | ); |
| 687 | 681 | |
| 688 | - if ( empty( $query_enrolled['items'] ) ) { | |
| 682 | + if ( empty( $query_enrolled->get_items() ) ) { | |
| 689 | 683 | continue; |
| 690 | 684 | } |
| 691 | 685 | |
| 686 | + $items = $query_enrolled->get_items(); | |
| 692 | 687 | $enrolled_ids = array(); |
| 693 | - foreach ( $query_enrolled['items'] as $enrolled_item ) { | |
| 688 | + foreach ( $items as $enrolled_item ) { | |
| 694 | 689 | $course_data = $user->get_course_data( $enrolled_item ); |
| 695 | 690 | |
| 696 | 691 | if ( $course_data ) { |
| 697 | 692 | $post = get_post( $enrolled_item ); |
| @@ -700,11 +695,11 @@ | ||
| 700 | 695 | 'id' => $enrolled_item ?? '', |
| 701 | 696 | 'title' => $post->post_title, |
| 702 | 697 | 'graduation' => ! empty( $course_data->get_graduation() ) ? $course_data->get_graduation() : '', |
| 703 | 698 | 'status' => ! empty( $course_data->get_status() ) ? $course_data->get_status() : '', |
| 704 | - 'start_time' => lp_jwt_prepare_date_response( $course_data->get_start_time() ? $course_data->get_start_time()->toSql( false ) : '' ), | |
| 705 | - 'end_time' => lp_jwt_prepare_date_response( $course_data->get_end_time() ? $course_data->get_end_time()->toSql( false ) : '' ), | |
| 706 | - 'expiration' => lp_jwt_prepare_date_response( $course_data->get_expiration_time() ? $course_data->get_expiration_time()->toSql( false ) : '' ), | |
| 699 | + 'start_time' => lp_jwt_prepare_date_response( $course_data->get_start_time() ? $course_data->get_start_time()->toSql() : '' ), | |
| 700 | + 'end_time' => lp_jwt_prepare_date_response( $course_data->get_end_time() ? $course_data->get_end_time()->toSql() : '' ), | |
| 701 | + 'expiration' => lp_jwt_prepare_date_response( $course_data->get_expiration_time() ? $course_data->get_expiration_time()->toSql() : '' ), | |
| 707 | 702 | 'results' => $course_data->calculate_course_results(), |
| 708 | 703 | ); |
| 709 | 704 | } |
| 710 | 705 | } |
| @@ -730,10 +725,10 @@ | ||
| 730 | 725 | ) |
| 731 | 726 | ); |
| 732 | 727 | |
| 733 | 728 | $created_ids = array(); |
| 734 | - if ( ! empty( $query_created['items'] ) ) { | |
| 735 | - foreach ( $query_created['items'] as $created_item ) { | |
| 729 | + if ( ! empty( $query_created->get_items() ) ) { | |
| 730 | + foreach ( $query_created->get_items() as $created_item ) { | |
| 736 | 731 | $created_ids[] = $created_item; |
| 737 | 732 | } |
| 738 | 733 | } |
| 739 | 734 | |
| @@ -751,9 +746,9 @@ | ||
| 751 | 746 | * @return void |
| 752 | 747 | * |
| 753 | 748 | * @author Nhamdv <[email protected]> |
| 754 | 749 | */ |
| 755 | - public function get_quiz_tab_contents( $request ) { | |
| 750 | + public function get_quiz_tab_contents( $user, $request ) { | |
| 756 | 751 | $output = array(); |
| 757 | 752 | |
| 758 | 753 | $user_profile = learn_press_get_user( $request['id'] ); |
| 759 | 754 | $filters = array( |
| @@ -773,10 +768,10 @@ | ||
| 773 | 768 | $filter->graduation = $quiz_filter !== 'complete' ? $quiz_filter : ''; |
| 774 | 769 | $query = $user_profile->get_user_quizzes( $filter ); |
| 775 | 770 | |
| 776 | 771 | $ids = array(); |
| 777 | - if ( ! empty( $query['items'] ) ) { | |
| 778 | - foreach ( $query['items'] as $item ) { | |
| 772 | + if ( ! empty( $query->get_items() ) ) { | |
| 773 | + foreach ( $query->get_items() as $item ) { | |
| 779 | 774 | $ids[] = array( |
| 780 | 775 | 'id' => $item->get_id(), |
| 781 | 776 | 'result' => $item->get_percent_result() ?? '', |
| 782 | 777 | 'graduation' => $item->get_graduation() ?? '', |
| @@ -802,9 +797,9 @@ | ||
| 802 | 797 | * @return array |
| 803 | 798 | * |
| 804 | 799 | * @author Nhamdv <[email protected]> |
| 805 | 800 | */ |
| 806 | - public function get_order_content_tab( $request ) { | |
| 801 | + public function get_order_content_tab( $user, $request ) { | |
| 807 | 802 | $output = array(); |
| 808 | 803 | |
| 809 | 804 | $profile = learn_press_get_profile( $request['id'] ); |
| 810 | 805 | |
| @@ -809,11 +804,10 @@ | ||
| 809 | 804 | $profile = learn_press_get_profile( $request['id'] ); |
| 810 | 805 | |
| 811 | 806 | if ( method_exists( $profile, 'query_orders' ) ) { |
| 812 | 807 | $query_orders = $profile->query_orders( array( 'fields' => 'ids' ) ); |
| 813 | - | |
| 814 | - if ( ! empty( $query_orders['items'] ) ) { | |
| 815 | - foreach ( $query_orders['items'] as $order_id ) { | |
| 808 | + if ( ! empty( $query_orders->get_items() ) ) { | |
| 809 | + foreach ( $query_orders->get_items() as $order_id ) { | |
| 816 | 810 | $order = learn_press_get_order( $order_id ); |
| 817 | 811 | |
| 818 | 812 | $output[ $order_id ] = array( |
| 819 | 813 | 'order_key' => $order->get_order_number() ?? '', |
| @@ -858,8 +852,12 @@ | ||
| 858 | 852 | * @param WP_REST_Request $request Full details about the request. |
| 859 | 853 | * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
| 860 | 854 | */ |
| 861 | 855 | public function get_items( $request ) { |
| 856 | + // Fixed security, with request ?context=edit | |
| 857 | + if ( isset( $_REQUEST['context'] ) ) { | |
| 858 | + die(); | |
| 859 | + } | |
| 862 | 860 | |
| 863 | 861 | // Retrieve the list of registered collection query parameters. |
| 864 | 862 | $registered = $this->get_collection_params(); |
| 865 | 863 | |
| @@ -878,8 +876,20 @@ | ||
| 878 | 876 | 'roles' => 'role__in', |
| 879 | 877 | 'slug' => 'nicename__in', |
| 880 | 878 | ); |
| 881 | 879 | |
| 880 | + $roles = $request->get_param( 'roles' ); | |
| 881 | + if ( ! empty( $roles ) && $roles == [ UserModel::ROLE_ADMINISTRATOR ] ) { | |
| 882 | + return new WP_Error( | |
| 883 | + 'rest_forbidden', | |
| 884 | + __( 'You are not allowed.' ), | |
| 885 | + array( 'status' => rest_authorization_required_code() ) | |
| 886 | + ); | |
| 887 | + } | |
| 888 | + | |
| 889 | + // Always only get instructors and administrators. | |
| 890 | + $request['roles'] = [ UserModel::ROLE_INSTRUCTOR, UserModel::ROLE_ADMINISTRATOR ]; | |
| 891 | + | |
| 882 | 892 | $prepared_args = array(); |
| 883 | 893 | |
| 884 | 894 | /* |
| 885 | 895 | * For each known parameter which is both registered and present in the request, |
| @@ -929,15 +939,38 @@ | ||
| 929 | 939 | * @param WP_REST_Request $request The REST API request. |
| 930 | 940 | */ |
| 931 | 941 | $prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request ); |
| 932 | 942 | |
| 933 | - $query = new WP_User_Query( $prepared_args ); | |
| 943 | + $users = array(); | |
| 944 | + $lp_cache = new LP_Cache(); | |
| 945 | + $key_cache_list_instructors = 'lp_get_instructors'; | |
| 934 | 946 | |
| 935 | - $users = array(); | |
| 947 | + // Check cache with cache get instructors. | |
| 948 | + if ( isset( $prepared_args['role__in'] ) ) { | |
| 949 | + $users = $lp_cache->get_cache( $key_cache_list_instructors ); | |
| 950 | + $total_users = $lp_cache->get_cache( $key_cache_list_instructors . '/total' ); | |
| 951 | + } | |
| 936 | 952 | |
| 937 | - foreach ( $query->results as $user ) { | |
| 938 | - $data = $this->prepare_item_for_response( $user, $request ); | |
| 939 | - $users[] = $this->prepare_response_for_collection( $data ); | |
| 953 | + if ( $users === false ) { | |
| 954 | + // Query max 10 instructors only. | |
| 955 | + $prepared_args['number'] = 10; | |
| 956 | + | |
| 957 | + $query = new WP_User_Query( $prepared_args ); | |
| 958 | + $users_result = $query->get_results(); | |
| 959 | + $total_users = $query->get_total(); | |
| 960 | + | |
| 961 | + foreach ( $users_result as $user ) { | |
| 962 | + $data = $this->prepare_item_for_response( $user, $request ); | |
| 963 | + | |
| 964 | + $user = $this->prepare_response_for_collection( $data ); | |
| 965 | + unset( $user['custom_register'] ); | |
| 966 | + unset( $user['is_super_admin'] ); | |
| 967 | + $users[] = $user; | |
| 968 | + } | |
| 969 | + | |
| 970 | + // Set cache with cache get instructors. | |
| 971 | + $lp_cache->set_cache( $key_cache_list_instructors, $users ); | |
| 972 | + $lp_cache->set_cache( $key_cache_list_instructors . '/total', $total_users ); | |
| 940 | 973 | } |
| 941 | 974 | |
| 942 | 975 | $response = rest_ensure_response( $users ); |
| 943 | 976 | |
| @@ -946,10 +979,8 @@ | ||
| 946 | 979 | $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); |
| 947 | 980 | |
| 948 | 981 | $prepared_args['fields'] = 'ID'; |
| 949 | 982 | |
| 950 | - $total_users = $query->get_total(); | |
| 951 | - | |
| 952 | 983 | if ( $total_users < 1 ) { |
| 953 | 984 | // Out-of-bounds, run the query again without LIMIT for total count. |
| 954 | 985 | unset( $prepared_args['number'], $prepared_args['offset'] ); |
| 955 | 986 | $count_query = new WP_User_Query( $prepared_args ); |
| @@ -1017,9 +1048,11 @@ | ||
| 1017 | 1048 | case 'id': |
| 1018 | 1049 | $data['id'] = $user->ID; |
| 1019 | 1050 | break; |
| 1020 | 1051 | case 'username': |
| 1021 | - $data['username'] = $user->user_login; | |
| 1052 | + if ( current_user_can( 'list_users' ) || current_user_can( 'edit_user', $user->ID ) ) { | |
| 1053 | + $data['username'] = $user->user_login; | |
| 1054 | + } | |
| 1022 | 1055 | break; |
| 1023 | 1056 | case 'name': |
| 1024 | 1057 | $data['name'] = $user->display_name; |
| 1025 | 1058 | break; |
| @@ -1029,9 +1062,11 @@ | ||
| 1029 | 1062 | case 'last_name': |
| 1030 | 1063 | $data['last_name'] = $user->last_name; |
| 1031 | 1064 | break; |
| 1032 | 1065 | case 'email': |
| 1033 | - $data['email'] = $user->user_email; | |
| 1066 | + if ( current_user_can( 'list_users' ) || current_user_can( 'edit_user', $user->ID ) ) { | |
| 1067 | + $data['email'] = $user->user_email; | |
| 1068 | + } | |
| 1034 | 1069 | break; |
| 1035 | 1070 | case 'url': |
| 1036 | 1071 | $data['url'] = $user->user_url; |
| 1037 | 1072 | break; |
| @@ -1094,14 +1129,16 @@ | ||
| 1094 | 1129 | public function get_social_data( $user_id ) { |
| 1095 | 1130 | return learn_press_get_user_extra_profile_info( $user_id ); |
| 1096 | 1131 | } |
| 1097 | 1132 | |
| 1098 | - public function get_profile_avatar( $user_id ) { | |
| 1133 | + /** | |
| 1134 | + * @since 4.1.4 | |
| 1135 | + * @version 1.0.1 | |
| 1136 | + */ | |
| 1137 | + public function get_profile_avatar( $user_id ): string { | |
| 1099 | 1138 | $user = learn_press_get_user( $user_id ); |
| 1100 | 1139 | |
| 1101 | - $avatar = $user->get_upload_profile_src(); | |
| 1102 | - | |
| 1103 | - return ! empty( $avatar ) ? $avatar : ''; | |
| 1140 | + return $user->get_profile_avatar_url(); | |
| 1104 | 1141 | } |
| 1105 | 1142 | |
| 1106 | 1143 | /** |
| 1107 | 1144 | * @editor tungnx |
| @@ -1129,9 +1166,17 @@ | ||
| 1129 | 1166 | |
| 1130 | 1167 | return $output; |
| 1131 | 1168 | }*/ |
| 1132 | 1169 | |
| 1133 | - public function get_lp_data_tabs( $user, $request ) { | |
| 1170 | + /** | |
| 1171 | + * Get data tabs. | |
| 1172 | + * | |
| 1173 | + * @param $user | |
| 1174 | + * @param $request | |
| 1175 | + * | |
| 1176 | + * @return array | |
| 1177 | + */ | |
| 1178 | + public function get_lp_data_tabs( $user, $request ): array { | |
| 1134 | 1179 | $output = array(); |
| 1135 | 1180 | |
| 1136 | 1181 | if ( get_current_user_id() === $user->ID || current_user_can( 'list_users' ) ) { |
| 1137 | 1182 | if ( function_exists( 'learn_press_get_user_profile_tabs' ) ) { |
| @@ -1138,24 +1183,27 @@ | ||
| 1138 | 1183 | $tabs = learn_press_get_user_profile_tabs(); |
| 1139 | 1184 | |
| 1140 | 1185 | $content = array( |
| 1141 | 1186 | 'overview' => $this->get_overview_tab_contents( $user ), |
| 1142 | - 'courses' => $this->get_course_tab_contents( $request ), | |
| 1143 | - 'quizzes' => $this->get_quiz_tab_contents( $request ), | |
| 1144 | - 'orders' => $this->get_order_content_tab( $request ), | |
| 1187 | + 'courses' => $this->get_course_tab_contents( $user, $request ), | |
| 1188 | + 'quizzes' => $this->get_quiz_tab_contents( $user, $request ), | |
| 1189 | + 'orders' => $this->get_order_content_tab( $user, $request ), | |
| 1145 | 1190 | ); |
| 1146 | 1191 | |
| 1192 | + /** | |
| 1193 | + * @var LP_Profile_Tab $tab | |
| 1194 | + */ | |
| 1147 | 1195 | foreach ( $tabs->get() as $key => $tab ) { |
| 1148 | 1196 | $output[ $key ] = array( |
| 1149 | - 'title' => $tab['title'] ?? '', | |
| 1150 | - 'slug' => $tab['slug'] ?? '', | |
| 1151 | - 'priority' => $tab['priority'] ?? '', | |
| 1152 | - 'icon' => $tab['icon'] ?? '', | |
| 1197 | + 'title' => $tab->get( 'title' ) ?? '', | |
| 1198 | + 'slug' => $tab->get( 'slug' ) ?? '', | |
| 1199 | + 'priority' => $tab->get( 'priority' ) ?? '', | |
| 1200 | + 'icon' => $tab->get( 'icon' ) ?? '', | |
| 1153 | 1201 | 'content' => $content[ $key ] ?? '', |
| 1154 | 1202 | ); |
| 1155 | 1203 | |
| 1156 | - if ( ! empty( $tab['sections'] ) ) { | |
| 1157 | - foreach ( $tab['sections'] as $section_key => $section ) { | |
| 1204 | + if ( ! empty( $tab->get( 'sections' ) ) ) { | |
| 1205 | + foreach ( $tab->get( 'sections' ) as $section_key => $section ) { | |
| 1158 | 1206 | $output[ $key ]['section'][ $section_key ] = array( |
| 1159 | 1207 | 'title' => $section['title'] ?? '', |
| 1160 | 1208 | 'slug' => $section['slug'] ?? '', |
| 1161 | 1209 | 'priority' => $section['priority'] ?? '', |
| @@ -1178,9 +1226,9 @@ | ||
| 1178 | 1226 | public function custom_register( $user ) { |
| 1179 | 1227 | $output = array(); |
| 1180 | 1228 | |
| 1181 | 1229 | if ( function_exists( 'lp_get_user_custom_register_fields' ) ) { |
| 1182 | - $custom_fields = LP_Settings::instance()->get( 'register_profile_fields' ); | |
| 1230 | + $custom_fields = LP_Profile::get_register_fields_custom(); | |
| 1183 | 1231 | $custom_profile = lp_get_user_custom_register_fields( $user->ID ); |
| 1184 | 1232 | |
| 1185 | 1233 | if ( $custom_fields ) { |
| 1186 | 1234 | foreach ( $custom_fields as $field ) { |