PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.9-a.7
Jetpack – WP Security, Backup, Speed, & Growth v15.9-a.7
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / json-endpoints / class.wpcom-json-api-list-users-endpoint.php
jetpack / json-endpoints Last commit date
jetpack 1 week ago class.wpcom-json-api-add-widget-endpoint.php 6 months ago class.wpcom-json-api-autosave-post-v1-1-endpoint.php 6 months ago class.wpcom-json-api-bulk-delete-post-endpoint.php 6 months ago class.wpcom-json-api-bulk-restore-post-endpoint.php 6 months ago class.wpcom-json-api-bulk-update-comments-endpoint.php 1 week ago class.wpcom-json-api-comment-endpoint.php 6 months ago class.wpcom-json-api-delete-media-endpoint.php 6 months ago class.wpcom-json-api-delete-media-v1-1-endpoint.php 6 months ago class.wpcom-json-api-edit-media-v1-2-endpoint.php 1 week ago class.wpcom-json-api-get-autosave-v1-1-endpoint.php 6 months ago class.wpcom-json-api-get-comment-counts-endpoint.php 6 months ago class.wpcom-json-api-get-comment-endpoint.php 6 months ago class.wpcom-json-api-get-comment-history-endpoint.php 6 months ago class.wpcom-json-api-get-comments-tree-endpoint.php 6 months ago class.wpcom-json-api-get-comments-tree-v1-1-endpoint.php 6 months ago class.wpcom-json-api-get-comments-tree-v1-2-endpoint.php 6 months ago class.wpcom-json-api-get-customcss.php 6 months ago class.wpcom-json-api-get-media-endpoint.php 6 months ago class.wpcom-json-api-get-media-v1-1-endpoint.php 6 months ago class.wpcom-json-api-get-media-v1-2-endpoint.php 6 months ago class.wpcom-json-api-get-post-counts-v1-1-endpoint.php 6 months ago class.wpcom-json-api-get-post-endpoint.php 6 months ago class.wpcom-json-api-get-post-v1-1-endpoint.php 6 months ago class.wpcom-json-api-get-site-endpoint.php 4 weeks ago class.wpcom-json-api-get-site-v1-2-endpoint.php 3 months ago class.wpcom-json-api-get-taxonomies-endpoint.php 1 month ago class.wpcom-json-api-get-taxonomy-endpoint.php 6 months ago class.wpcom-json-api-get-term-endpoint.php 6 months ago class.wpcom-json-api-list-comments-endpoint.php 1 week ago class.wpcom-json-api-list-dropdown-pages-endpoint.php 6 months ago class.wpcom-json-api-list-embeds-endpoint.php 6 months ago class.wpcom-json-api-list-media-endpoint.php 6 months ago class.wpcom-json-api-list-media-v1-1-endpoint.php 1 week ago class.wpcom-json-api-list-media-v1-2-endpoint.php 6 months ago class.wpcom-json-api-list-post-type-taxonomies-endpoint.php 6 months ago class.wpcom-json-api-list-post-types-endpoint.php 6 months ago class.wpcom-json-api-list-posts-endpoint.php 1 week ago class.wpcom-json-api-list-posts-v1-1-endpoint.php 1 week ago class.wpcom-json-api-list-posts-v1-2-endpoint.php 1 week ago class.wpcom-json-api-list-roles-endpoint.php 6 months ago class.wpcom-json-api-list-shortcodes-endpoint.php 6 months ago class.wpcom-json-api-list-terms-endpoint.php 6 months ago class.wpcom-json-api-list-users-endpoint.php 6 months ago class.wpcom-json-api-menus-v1-1-endpoint.php 1 week ago class.wpcom-json-api-post-endpoint.php 6 months ago class.wpcom-json-api-post-v1-1-endpoint.php 1 month ago class.wpcom-json-api-render-embed-endpoint.php 6 months ago class.wpcom-json-api-render-embed-reversal-endpoint.php 6 months ago class.wpcom-json-api-render-endpoint.php 2 weeks ago class.wpcom-json-api-render-shortcode-endpoint.php 6 months ago class.wpcom-json-api-sharing-buttons-endpoint.php 1 week ago class.wpcom-json-api-site-settings-endpoint.php 2 months ago class.wpcom-json-api-site-settings-v1-2-endpoint.php 6 months ago class.wpcom-json-api-site-settings-v1-3-endpoint.php 6 months ago class.wpcom-json-api-site-settings-v1-4-endpoint.php 2 months ago class.wpcom-json-api-site-user-endpoint.php 6 months ago class.wpcom-json-api-taxonomy-endpoint.php 6 months ago class.wpcom-json-api-update-comment-endpoint.php 4 months ago class.wpcom-json-api-update-customcss.php 6 months ago class.wpcom-json-api-update-media-endpoint.php 6 months ago class.wpcom-json-api-update-media-v1-1-endpoint.php 1 week ago class.wpcom-json-api-update-post-endpoint.php 1 week ago class.wpcom-json-api-update-post-v1-1-endpoint.php 1 week ago class.wpcom-json-api-update-post-v1-2-endpoint.php 1 week ago class.wpcom-json-api-update-site-homepage-endpoint.php 6 months ago class.wpcom-json-api-update-site-logo-endpoint.php 6 months ago class.wpcom-json-api-update-taxonomy-endpoint.php 5 months ago class.wpcom-json-api-update-term-endpoint.php 6 months ago class.wpcom-json-api-update-user-endpoint.php 6 months ago class.wpcom-json-api-upload-media-endpoint.php 6 months ago class.wpcom-json-api-upload-media-v1-1-endpoint.php 6 months ago
class.wpcom-json-api-list-users-endpoint.php
275 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit( 0 );
5 }
6
7 /**
8 * List users endpoint.
9 */
10 new WPCOM_JSON_API_List_Users_Endpoint(
11 array(
12 'description' => 'List the users of a site.',
13 'group' => 'users',
14 'stat' => 'users:list',
15
16 'method' => 'GET',
17 'path' => '/sites/%s/users',
18 'path_labels' => array(
19 '$site' => '(int|string) Site ID or domain',
20 ),
21 'rest_route' => '/users',
22 'rest_min_jp_version' => '14.5-a.2',
23
24 'query_parameters' => array(
25 'number' => '(int=20) Limit the total number of authors returned.',
26 'offset' => '(int=0) The first n authors to be skipped in the returned array.',
27 'order' => array(
28 'DESC' => 'Return authors in descending order.',
29 'ASC' => 'Return authors in ascending order.',
30 ),
31 'order_by' => array(
32 'ID' => 'Order by ID (default).',
33 'login' => 'Order by username.',
34 'nicename' => 'Order by nicename.',
35 'email' => 'Order by author email address.',
36 'url' => 'Order by author URL.',
37 'registered' => 'Order by registered date.',
38 'display_name' => 'Order by display name.',
39 'post_count' => 'Order by number of posts published.',
40 ),
41 'authors_only' => '(bool) Set to true to fetch authors only',
42 'include_viewers' => '(bool) Set to true to include viewers for Simple sites. When you pass in this parameter, order, order_by and search_columns are ignored. Currently, `search` is limited to the first page of results.',
43 'type' => "(string) Specify the post type to query authors for. Only works when combined with the `authors_only` flag. Defaults to 'post'. Post types besides post and page need to be whitelisted using the <code>rest_api_allowed_post_types</code> filter.",
44 'search' => '(string) Find matching users.',
45 'search_columns' => "(array) Specify which columns to check for matching users. Can be any of 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename', and 'display_name'. Only works when combined with `search` parameter.",
46 'role' => '(string) Specify a specific user role to fetch.',
47 'capability' => '(string) Specify a specific capability to fetch. You can specify multiple by comma-separating them, in which case the user needs to match all capabilities provided.',
48 ),
49
50 'response_format' => array(
51 'found' => '(int) The total number of authors found that match the request (ignoring limits and offsets).',
52 'authors' => '(array:author) Array of author objects.',
53 ),
54
55 'example_response' => '{
56 "found": 1,
57 "users": [
58 {
59 "ID": 78972699,
60 "login": "apiexamples",
61 "email": "justin+apiexamples@a8c.com",
62 "name": "apiexamples",
63 "first_name": "",
64 "last_name": "",
65 "nice_name": "apiexamples",
66 "URL": "http://apiexamples.wordpress.com",
67 "avatar_URL": "https://1.gravatar.com/avatar/a2afb7b6c0e23e5d363d8612fb1bd5ad?s=96&d=identicon&r=G",
68 "profile_URL": "https://gravatar.com/apiexamples",
69 "site_ID": 82974409,
70 "roles": [
71 "administrator"
72 ],
73 "is_super_admin": false
74 }
75 ]
76 }',
77
78 'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/82974409/users',
79 'example_request_data' => array(
80 'headers' => array(
81 'authorization' => 'Bearer YOUR_API_TOKEN',
82 ),
83 ),
84 )
85 );
86
87 /**
88 * List users endpoint class.
89 *
90 * /sites/%s/users/ -> $blog_id
91 *
92 * @phan-constructor-used-for-side-effects
93 */
94 class WPCOM_JSON_API_List_Users_Endpoint extends WPCOM_JSON_API_Endpoint {
95
96 /**
97 * The response format.
98 *
99 * @var array
100 */
101 public $response_format = array(
102 'found' => '(int) The total number of authors found that match the request (ignoring limits and offsets).',
103 'users' => '(array:author) Array of user objects',
104 );
105
106 /**
107 * Columns in which to search for a user match.
108 *
109 * @var array
110 */
111 public $search_columns;
112
113 /**
114 * API callback.
115 *
116 * @param string $path - the path.
117 * @param string $blog_id - the blog ID.
118 */
119 public function callback( $path = '', $blog_id = 0 ) {
120 $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
121 if ( is_wp_error( $blog_id ) ) {
122 return $blog_id;
123 }
124
125 $args = $this->query_args();
126
127 $authors_only = ( ! empty( $args['authors_only'] ) );
128
129 if ( $args['number'] < 1 ) {
130 $args['number'] = 20;
131 } elseif ( 1000 < $args['number'] ) {
132 return new WP_Error( 'invalid_number', 'The NUMBER parameter must be less than or equal to 1000.', 400 );
133 }
134
135 if ( $authors_only ) {
136 if ( empty( $args['type'] ) ) {
137 $args['type'] = 'post';
138 }
139
140 if ( ! $this->is_post_type_allowed( $args['type'] ) ) {
141 return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
142 }
143
144 $post_type_object = get_post_type_object( $args['type'] );
145 if ( ! $post_type_object || ! current_user_can( $post_type_object->cap->edit_others_posts ) ) {
146 return new WP_Error( 'unauthorized', 'User cannot view authors for specified post type', 403 );
147 }
148 } elseif ( ! current_user_can( 'list_users' ) ) {
149 return new WP_Error( 'unauthorized', 'User cannot view users for specified site', 403 );
150 }
151
152 $query = array(
153 'number' => $args['number'],
154 'offset' => $args['offset'],
155 'order' => $args['order'],
156 'orderby' => $args['order_by'],
157 'fields' => 'ID',
158 );
159
160 if ( $authors_only ) {
161 $query['capability'] = array( 'edit_posts' );
162 }
163
164 if ( ! empty( $args['search'] ) ) {
165 $query['search'] = $args['search'];
166 }
167
168 if ( ! empty( $args['search_columns'] ) ) {
169 // this `user_search_columns` filter is necessary because WP_User_Query does not allow `display_name` as a search column.
170 $this->search_columns = array_intersect( $args['search_columns'], array( 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name' ) );
171 add_filter( 'user_search_columns', array( $this, 'api_user_override_search_columns' ), 10, 3 );
172 }
173
174 if ( ! empty( $args['role'] ) ) {
175 $query['role'] = $args['role'];
176 }
177
178 if ( ! empty( $args['capability'] ) ) {
179 $query['capability'] = $args['capability'];
180 }
181
182 $user_query = new WP_User_Query( $query );
183
184 remove_filter( 'user_search_columns', array( $this, 'api_user_override_search_columns' ) );
185
186 $is_wpcom = defined( 'IS_WPCOM' ) && IS_WPCOM;
187 $include_viewers = isset( $args['include_viewers'] ) && $args['include_viewers'] && $is_wpcom;
188
189 $page = ( (int) ( $args['offset'] / $args['number'] ) ) + 1;
190 $viewers = $include_viewers ? get_private_blog_users(
191 $blog_id,
192 array(
193 'page' => $page,
194 'per_page' => $args['number'],
195 )
196 ) : array();
197 $viewers = array_map( array( $this, 'get_author' ), $viewers );
198
199 // When include_viewers is true, search by username or email.
200 if ( $include_viewers && ! empty( $args['search'] ) ) {
201 $viewers = array_filter(
202 $viewers,
203 function ( $viewer ) use ( $args ) {
204 // Convert to WP_User so expected fields are available.
205 $wp_viewer = new WP_User( $viewer->ID );
206 // remove special database search characters from search term
207 $search_term = str_replace( '*', '', $args['search'] );
208 return ( str_contains( $wp_viewer->user_login, $search_term ) || str_contains( $wp_viewer->user_email, $search_term ) || str_contains( $wp_viewer->display_name, $search_term ) );
209 }
210 );
211 }
212
213 $return = array();
214 foreach ( array_keys( $this->response_format ) as $key ) {
215 switch ( $key ) {
216 case 'found':
217 $user_count = (int) $user_query->get_total();
218
219 $viewer_count = 0;
220 if ( $include_viewers ) {
221 if ( empty( $args['search'] ) ) {
222 $viewer_count = (int) get_count_private_blog_users( $blog_id );
223 } else {
224 $viewer_count = count( $viewers );
225 }
226 }
227
228 $return[ $key ] = $user_count + $viewer_count;
229 break;
230 case 'users':
231 $users = array();
232 $is_multisite = is_multisite();
233 foreach ( $user_query->get_results() as $u ) {
234 $the_user = $this->get_author( $u, true );
235 if ( $the_user && ! is_wp_error( $the_user ) ) {
236 $userdata = get_userdata( $u );
237 $the_user->roles = ! is_wp_error( $userdata ) ? array_values( $userdata->roles ) : array();
238 if ( $is_multisite ) {
239 $the_user->is_super_admin = user_can( $the_user->ID, 'manage_network' );
240 }
241 $users[] = $the_user;
242 }
243 }
244
245 $combined_users = array_merge( $users, $viewers );
246
247 // When viewers are included, we ignore the order & orderby parameters.
248 if ( $include_viewers ) {
249 usort(
250 $combined_users,
251 function ( $a, $b ) {
252 return strcmp( strtolower( $a->name ), strtolower( $b->name ) );
253 }
254 );
255 }
256
257 $return[ $key ] = $combined_users;
258 break;
259 }
260 }
261
262 return $return;
263 }
264
265 /**
266 * Override search columns.
267 *
268 * @param array $search_columns - the search column we're overriding.
269 * @param array $search - the search query.
270 */
271 public function api_user_override_search_columns( $search_columns, $search ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
272 return $this->search_columns;
273 }
274 }
275