diff -r be944660c56a -r 3d72ae0968f4 wp/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php --- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php Wed Sep 21 18:19:35 2022 +0200 +++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php Tue Sep 27 16:37:53 2022 +0200 @@ -198,6 +198,15 @@ ); } + // Check if capabilities is specified in GET request and if user can list users. + if ( ! empty( $request['capabilities'] ) && ! current_user_can( 'list_users' ) ) { + return new WP_Error( + 'rest_user_cannot_view', + __( 'Sorry, you are not allowed to filter users by capability.' ), + array( 'status' => rest_authorization_required_code() ) + ); + } + if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_forbidden_context', @@ -254,13 +263,14 @@ * present in $registered will be set. */ $parameter_mappings = array( - 'exclude' => 'exclude', - 'include' => 'include', - 'order' => 'order', - 'per_page' => 'number', - 'search' => 'search', - 'roles' => 'role__in', - 'slug' => 'nicename__in', + 'exclude' => 'exclude', + 'include' => 'include', + 'order' => 'order', + 'per_page' => 'number', + 'search' => 'search', + 'roles' => 'role__in', + 'capabilities' => 'capability__in', + 'slug' => 'nicename__in', ); $prepared_args = array(); @@ -301,6 +311,12 @@ $prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' ); } + if ( ! empty( $request['has_published_posts'] ) ) { + $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) + ? get_post_types( array( 'show_in_rest' => true ), 'names' ) + : (array) $request['has_published_posts']; + } + if ( ! empty( $prepared_args['search'] ) ) { $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; } @@ -722,7 +738,7 @@ if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) { return new WP_Error( 'rest_user_invalid_argument', - __( "Username isn't editable." ), + __( 'Username is not editable.' ), array( 'status' => 400 ) ); } @@ -963,13 +979,15 @@ * Prepares a single user output for response. * * @since 4.7.0 + * @since 5.9.0 Renamed `$user` to `$item` to match parent class for PHP 8 named parameter support. * - * @param WP_User $user User object. + * @param WP_User $item User object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ - public function prepare_item_for_response( $user, $request ) { - + public function prepare_item_for_response( $item, $request ) { + // Restores the more descriptive, specific name for use within this method. + $user = $item; $data = array(); $fields = $this->get_fields_for_response( $request ); @@ -1173,6 +1191,8 @@ * * @since 4.7.0 * + * @global WP_Roles $wp_roles WordPress role management object. + * * @param int $user_id User ID. * @param array $roles New user roles. * @return true|WP_Error True if the current user is allowed to make the role change, @@ -1550,6 +1570,14 @@ ), ); + $query_params['capabilities'] = array( + 'description' => __( 'Limit result set to users matching at least one specific capability provided. Accepts csv list or single capability.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + ); + $query_params['who'] = array( 'description' => __( 'Limit result set to users who are considered authors.' ), 'type' => 'string', @@ -1558,6 +1586,15 @@ ), ); + $query_params['has_published_posts'] = array( + 'description' => __( 'Limit result set to users who have published posts.' ), + 'type' => array( 'boolean', 'array' ), + 'items' => array( + 'type' => 'string', + 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), + ), + ); + /** * Filters REST API collection parameters for the users controller. *