PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.4.2
Jetpack – WP Security, Backup, Speed, & Growth v14.4.2
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 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 year ago class.wpcom-json-api-add-widget-endpoint.php 2 years ago class.wpcom-json-api-autosave-post-v1-1-endpoint.php 5 years ago class.wpcom-json-api-bulk-delete-post-endpoint.php 4 years ago class.wpcom-json-api-bulk-restore-post-endpoint.php 2 years ago class.wpcom-json-api-bulk-update-comments-endpoint.php 3 years ago class.wpcom-json-api-comment-endpoint.php 1 year ago class.wpcom-json-api-delete-media-endpoint.php 4 years ago class.wpcom-json-api-delete-media-v1-1-endpoint.php 4 years ago class.wpcom-json-api-edit-media-v1-2-endpoint.php 2 years ago class.wpcom-json-api-get-autosave-v1-1-endpoint.php 5 years ago class.wpcom-json-api-get-comment-counts-endpoint.php 1 year ago class.wpcom-json-api-get-comment-endpoint.php 4 years ago class.wpcom-json-api-get-comment-history-endpoint.php 1 year ago class.wpcom-json-api-get-comments-tree-endpoint.php 4 years ago class.wpcom-json-api-get-comments-tree-v1-1-endpoint.php 4 years ago class.wpcom-json-api-get-comments-tree-v1-2-endpoint.php 4 years ago class.wpcom-json-api-get-customcss.php 2 years ago class.wpcom-json-api-get-media-endpoint.php 4 years ago class.wpcom-json-api-get-media-v1-1-endpoint.php 4 years ago class.wpcom-json-api-get-media-v1-2-endpoint.php 2 years ago class.wpcom-json-api-get-post-counts-v1-1-endpoint.php 2 years ago class.wpcom-json-api-get-post-endpoint.php 2 years ago class.wpcom-json-api-get-post-v1-1-endpoint.php 2 years ago class.wpcom-json-api-get-site-endpoint.php 1 year ago class.wpcom-json-api-get-site-v1-2-endpoint.php 2 years ago class.wpcom-json-api-get-taxonomies-endpoint.php 2 years ago class.wpcom-json-api-get-taxonomy-endpoint.php 4 years ago class.wpcom-json-api-get-term-endpoint.php 4 years ago class.wpcom-json-api-list-comments-endpoint.php 1 year ago class.wpcom-json-api-list-dropdown-pages-endpoint.php 3 years ago class.wpcom-json-api-list-embeds-endpoint.php 4 years ago class.wpcom-json-api-list-media-endpoint.php 2 years ago class.wpcom-json-api-list-media-v1-1-endpoint.php 2 years ago class.wpcom-json-api-list-media-v1-2-endpoint.php 2 years ago class.wpcom-json-api-list-post-type-taxonomies-endpoint.php 4 years ago class.wpcom-json-api-list-post-types-endpoint.php 3 years ago class.wpcom-json-api-list-posts-endpoint.php 1 year ago class.wpcom-json-api-list-posts-v1-1-endpoint.php 1 year ago class.wpcom-json-api-list-posts-v1-2-endpoint.php 1 year ago class.wpcom-json-api-list-roles-endpoint.php 1 year ago class.wpcom-json-api-list-shortcodes-endpoint.php 4 years ago class.wpcom-json-api-list-terms-endpoint.php 2 years ago class.wpcom-json-api-list-users-endpoint.php 1 year ago class.wpcom-json-api-menus-v1-1-endpoint.php 1 year ago class.wpcom-json-api-post-endpoint.php 2 years ago class.wpcom-json-api-post-v1-1-endpoint.php 2 years ago class.wpcom-json-api-render-embed-endpoint.php 2 years ago class.wpcom-json-api-render-embed-reversal-endpoint.php 2 years ago class.wpcom-json-api-render-endpoint.php 3 years ago class.wpcom-json-api-render-shortcode-endpoint.php 3 years ago class.wpcom-json-api-sharing-buttons-endpoint.php 2 years ago class.wpcom-json-api-site-settings-endpoint.php 1 year ago class.wpcom-json-api-site-settings-v1-2-endpoint.php 2 years ago class.wpcom-json-api-site-settings-v1-3-endpoint.php 2 years ago class.wpcom-json-api-site-settings-v1-4-endpoint.php 1 year ago class.wpcom-json-api-site-user-endpoint.php 1 year ago class.wpcom-json-api-taxonomy-endpoint.php 4 years ago class.wpcom-json-api-update-comment-endpoint.php 2 years ago class.wpcom-json-api-update-customcss.php 2 years ago class.wpcom-json-api-update-media-endpoint.php 4 years ago class.wpcom-json-api-update-media-v1-1-endpoint.php 2 years ago class.wpcom-json-api-update-post-endpoint.php 1 year ago class.wpcom-json-api-update-post-v1-1-endpoint.php 1 year ago class.wpcom-json-api-update-post-v1-2-endpoint.php 1 year ago class.wpcom-json-api-update-site-homepage-endpoint.php 4 years ago class.wpcom-json-api-update-site-logo-endpoint.php 2 years ago class.wpcom-json-api-update-taxonomy-endpoint.php 4 years ago class.wpcom-json-api-update-term-endpoint.php 4 years ago class.wpcom-json-api-update-user-endpoint.php 3 years ago class.wpcom-json-api-upload-media-endpoint.php 3 years ago class.wpcom-json-api-upload-media-v1-1-endpoint.php 1 year ago
class.wpcom-json-api-list-users-endpoint.php
267 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 /**
4 * List users endpoint.
5 */
6 new WPCOM_JSON_API_List_Users_Endpoint(
7 array(
8 'description' => 'List the users of a site.',
9 'group' => 'users',
10 'stat' => 'users:list',
11
12 'method' => 'GET',
13 'path' => '/sites/%s/users',
14 'path_labels' => array(
15 '$site' => '(int|string) Site ID or domain',
16 ),
17
18 'query_parameters' => array(
19 'number' => '(int=20) Limit the total number of authors returned.',
20 'offset' => '(int=0) The first n authors to be skipped in the returned array.',
21 'order' => array(
22 'DESC' => 'Return authors in descending order.',
23 'ASC' => 'Return authors in ascending order.',
24 ),
25 'order_by' => array(
26 'ID' => 'Order by ID (default).',
27 'login' => 'Order by username.',
28 'nicename' => 'Order by nicename.',
29 'email' => 'Order by author email address.',
30 'url' => 'Order by author URL.',
31 'registered' => 'Order by registered date.',
32 'display_name' => 'Order by display name.',
33 'post_count' => 'Order by number of posts published.',
34 ),
35 'authors_only' => '(bool) Set to true to fetch authors only',
36 '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.',
37 '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.",
38 'search' => '(string) Find matching users.',
39 '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.",
40 'role' => '(string) Specify a specific user role to fetch.',
41 '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.',
42 ),
43
44 'response_format' => array(
45 'found' => '(int) The total number of authors found that match the request (ignoring limits and offsets).',
46 'authors' => '(array:author) Array of author objects.',
47 ),
48
49 'example_response' => '{
50 "found": 1,
51 "users": [
52 {
53 "ID": 78972699,
54 "login": "apiexamples",
55 "email": "justin+apiexamples@a8c.com",
56 "name": "apiexamples",
57 "first_name": "",
58 "last_name": "",
59 "nice_name": "apiexamples",
60 "URL": "http://apiexamples.wordpress.com",
61 "avatar_URL": "https://1.gravatar.com/avatar/a2afb7b6c0e23e5d363d8612fb1bd5ad?s=96&d=identicon&r=G",
62 "profile_URL": "https://gravatar.com/apiexamples",
63 "site_ID": 82974409,
64 "roles": [
65 "administrator"
66 ],
67 "is_super_admin": false
68 }
69 ]
70 }',
71
72 'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/82974409/users',
73 'example_request_data' => array(
74 'headers' => array(
75 'authorization' => 'Bearer YOUR_API_TOKEN',
76 ),
77 ),
78 )
79 );
80
81 /**
82 * List users endpoint class.
83 *
84 * /sites/%s/users/ -> $blog_id
85 */
86 class WPCOM_JSON_API_List_Users_Endpoint extends WPCOM_JSON_API_Endpoint {
87
88 /**
89 * The response format.
90 *
91 * @var array
92 */
93 public $response_format = array(
94 'found' => '(int) The total number of authors found that match the request (ignoring limits and offsets).',
95 'users' => '(array:author) Array of user objects',
96 );
97
98 /**
99 * Columns in which to search for a user match.
100 *
101 * @var array
102 */
103 public $search_columns;
104
105 /**
106 * API callback.
107 *
108 * @param string $path - the path.
109 * @param string $blog_id - the blog ID.
110 */
111 public function callback( $path = '', $blog_id = 0 ) {
112 $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
113 if ( is_wp_error( $blog_id ) ) {
114 return $blog_id;
115 }
116
117 $args = $this->query_args();
118
119 $authors_only = ( ! empty( $args['authors_only'] ) );
120
121 if ( $args['number'] < 1 ) {
122 $args['number'] = 20;
123 } elseif ( 1000 < $args['number'] ) {
124 return new WP_Error( 'invalid_number', 'The NUMBER parameter must be less than or equal to 1000.', 400 );
125 }
126
127 if ( $authors_only ) {
128 if ( empty( $args['type'] ) ) {
129 $args['type'] = 'post';
130 }
131
132 if ( ! $this->is_post_type_allowed( $args['type'] ) ) {
133 return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
134 }
135
136 $post_type_object = get_post_type_object( $args['type'] );
137 if ( ! $post_type_object || ! current_user_can( $post_type_object->cap->edit_others_posts ) ) {
138 return new WP_Error( 'unauthorized', 'User cannot view authors for specified post type', 403 );
139 }
140 } elseif ( ! current_user_can( 'list_users' ) ) {
141 return new WP_Error( 'unauthorized', 'User cannot view users for specified site', 403 );
142 }
143
144 $query = array(
145 'number' => $args['number'],
146 'offset' => $args['offset'],
147 'order' => $args['order'],
148 'orderby' => $args['order_by'],
149 'fields' => 'ID',
150 );
151
152 if ( $authors_only ) {
153 $query['capability'] = array( 'edit_posts' );
154 }
155
156 if ( ! empty( $args['search'] ) ) {
157 $query['search'] = $args['search'];
158 }
159
160 if ( ! empty( $args['search_columns'] ) ) {
161 // this `user_search_columns` filter is necessary because WP_User_Query does not allow `display_name` as a search column.
162 $this->search_columns = array_intersect( $args['search_columns'], array( 'ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name' ) );
163 add_filter( 'user_search_columns', array( $this, 'api_user_override_search_columns' ), 10, 3 );
164 }
165
166 if ( ! empty( $args['role'] ) ) {
167 $query['role'] = $args['role'];
168 }
169
170 if ( ! empty( $args['capability'] ) ) {
171 $query['capability'] = $args['capability'];
172 }
173
174 $user_query = new WP_User_Query( $query );
175
176 remove_filter( 'user_search_columns', array( $this, 'api_user_override_search_columns' ) );
177
178 $is_wpcom = defined( 'IS_WPCOM' ) && IS_WPCOM;
179 $include_viewers = (bool) isset( $args['include_viewers'] ) && $args['include_viewers'] && $is_wpcom;
180
181 $page = ( (int) ( $args['offset'] / $args['number'] ) ) + 1;
182 $viewers = $include_viewers ? get_private_blog_users(
183 $blog_id,
184 array(
185 'page' => $page,
186 'per_page' => $args['number'],
187 )
188 ) : array();
189 $viewers = array_map( array( $this, 'get_author' ), $viewers );
190
191 // When include_viewers is true, search by username or email.
192 if ( $include_viewers && ! empty( $args['search'] ) ) {
193 $viewers = array_filter(
194 $viewers,
195 function ( $viewer ) use ( $args ) {
196 // Convert to WP_User so expected fields are available.
197 $wp_viewer = new WP_User( $viewer->ID );
198 // remove special database search characters from search term
199 $search_term = str_replace( '*', '', $args['search'] );
200 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 ) );
201 }
202 );
203 }
204
205 $return = array();
206 foreach ( array_keys( $this->response_format ) as $key ) {
207 switch ( $key ) {
208 case 'found':
209 $user_count = (int) $user_query->get_total();
210
211 $viewer_count = 0;
212 if ( $include_viewers ) {
213 if ( empty( $args['search'] ) ) {
214 $viewer_count = (int) get_count_private_blog_users( $blog_id );
215 } else {
216 $viewer_count = count( $viewers );
217 }
218 }
219
220 $return[ $key ] = $user_count + $viewer_count;
221 break;
222 case 'users':
223 $users = array();
224 $is_multisite = is_multisite();
225 foreach ( $user_query->get_results() as $u ) {
226 $the_user = $this->get_author( $u, true );
227 if ( $the_user && ! is_wp_error( $the_user ) ) {
228 $userdata = get_userdata( $u );
229 $the_user->roles = ! is_wp_error( $userdata ) ? array_values( $userdata->roles ) : array();
230 if ( $is_multisite ) {
231 $the_user->is_super_admin = user_can( $the_user->ID, 'manage_network' );
232 }
233 $users[] = $the_user;
234 }
235 }
236
237 $combined_users = array_merge( $users, $viewers );
238
239 // When viewers are included, we ignore the order & orderby parameters.
240 if ( $include_viewers ) {
241 usort(
242 $combined_users,
243 function ( $a, $b ) {
244 return strcmp( strtolower( $a->name ), strtolower( $b->name ) );
245 }
246 );
247 }
248
249 $return[ $key ] = $combined_users;
250 break;
251 }
252 }
253
254 return $return;
255 }
256
257 /**
258 * Override search columns.
259 *
260 * @param array $search_columns - the search column we're overriding.
261 * @param array $search - the search query.
262 */
263 public function api_user_override_search_columns( $search_columns, $search ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
264 return $this->search_columns;
265 }
266 }
267