/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php

  1. <?php 
  2. /** 
  3. * REST API: WP_REST_Users_Controller class 
  4. * 
  5. * @package WordPress 
  6. * @subpackage REST_API 
  7. * @since 4.7.0 
  8. */ 
  9.  
  10. /** 
  11. * Core class used to manage users via the REST API. 
  12. * 
  13. * @since 4.7.0 
  14. * 
  15. * @see WP_REST_Controller 
  16. */ 
  17. class WP_REST_Users_Controller extends WP_REST_Controller { 
  18.  
  19. /** 
  20. * Instance of a user meta fields object. 
  21. * 
  22. * @since 4.7.0 
  23. * @access protected 
  24. * @var WP_REST_User_Meta_Fields 
  25. */ 
  26. protected $meta; 
  27.  
  28. /** 
  29. * Constructor. 
  30. * 
  31. * @since 4.7.0 
  32. * @access public 
  33. */ 
  34. public function __construct() { 
  35. $this->namespace = 'wp/v2'; 
  36. $this->rest_base = 'users'; 
  37.  
  38. $this->meta = new WP_REST_User_Meta_Fields(); 
  39.  
  40. /** 
  41. * Registers the routes for the objects of the controller. 
  42. * 
  43. * @since 4.7.0 
  44. * @access public 
  45. * 
  46. * @see register_rest_route() 
  47. */ 
  48. public function register_routes() { 
  49.  
  50. register_rest_route( $this->namespace, '/' . $this->rest_base, array( 
  51. array( 
  52. 'methods' => WP_REST_Server::READABLE,  
  53. 'callback' => array( $this, 'get_items' ),  
  54. 'permission_callback' => array( $this, 'get_items_permissions_check' ),  
  55. 'args' => $this->get_collection_params(),  
  56. ),  
  57. array( 
  58. 'methods' => WP_REST_Server::CREATABLE,  
  59. 'callback' => array( $this, 'create_item' ),  
  60. 'permission_callback' => array( $this, 'create_item_permissions_check' ),  
  61. 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),  
  62. ),  
  63. 'schema' => array( $this, 'get_public_item_schema' ),  
  64. ) ); 
  65.  
  66. register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 
  67. 'args' => array( 
  68. 'id' => array( 
  69. 'description' => __( 'Unique identifier for the user.' ),  
  70. 'type' => 'integer',  
  71. ),  
  72. ),  
  73. array( 
  74. 'methods' => WP_REST_Server::READABLE,  
  75. 'callback' => array( $this, 'get_item' ),  
  76. 'permission_callback' => array( $this, 'get_item_permissions_check' ),  
  77. 'args' => array( 
  78. 'context' => $this->get_context_param( array( 'default' => 'view' ) ),  
  79. ),  
  80. ),  
  81. array( 
  82. 'methods' => WP_REST_Server::EDITABLE,  
  83. 'callback' => array( $this, 'update_item' ),  
  84. 'permission_callback' => array( $this, 'update_item_permissions_check' ),  
  85. 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),  
  86. ),  
  87. array( 
  88. 'methods' => WP_REST_Server::DELETABLE,  
  89. 'callback' => array( $this, 'delete_item' ),  
  90. 'permission_callback' => array( $this, 'delete_item_permissions_check' ),  
  91. 'args' => array( 
  92. 'force' => array( 
  93. 'type' => 'boolean',  
  94. 'default' => false,  
  95. 'description' => __( 'Required to be true, as users do not support trashing.' ),  
  96. ),  
  97. 'reassign' => array( 
  98. 'type' => 'integer',  
  99. 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ),  
  100. 'required' => true,  
  101. 'sanitize_callback' => array( $this, 'check_reassign' ),  
  102. ),  
  103. ),  
  104. ),  
  105. 'schema' => array( $this, 'get_public_item_schema' ),  
  106. ) ); 
  107.  
  108. register_rest_route( $this->namespace, '/' . $this->rest_base . '/me', array( 
  109. array( 
  110. 'methods' => WP_REST_Server::READABLE,  
  111. 'callback' => array( $this, 'get_current_item' ),  
  112. 'args' => array( 
  113. 'context' => $this->get_context_param( array( 'default' => 'view' ) ),  
  114. ),  
  115. ),  
  116. array( 
  117. 'methods' => WP_REST_Server::EDITABLE,  
  118. 'callback' => array( $this, 'update_current_item' ),  
  119. 'permission_callback' => array( $this, 'update_current_item_permissions_check' ),  
  120. 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),  
  121. ),  
  122. array( 
  123. 'methods' => WP_REST_Server::DELETABLE,  
  124. 'callback' => array( $this, 'delete_current_item' ),  
  125. 'permission_callback' => array( $this, 'delete_current_item_permissions_check' ),  
  126. 'args' => array( 
  127. 'force' => array( 
  128. 'type' => 'boolean',  
  129. 'default' => false,  
  130. 'description' => __( 'Required to be true, as users do not support trashing.' ),  
  131. ),  
  132. 'reassign' => array( 
  133. 'type' => 'integer',  
  134. 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ),  
  135. 'required' => true,  
  136. 'sanitize_callback' => array( $this, 'check_reassign' ),  
  137. ),  
  138. ),  
  139. ),  
  140. 'schema' => array( $this, 'get_public_item_schema' ),  
  141. )); 
  142.  
  143. /** 
  144. * Checks for a valid value for the reassign parameter when deleting users. 
  145. * 
  146. * The value can be an integer, 'false', false, or ''. 
  147. * 
  148. * @since 4.7.0 
  149. * 
  150. * @param int|bool $value The value passed to the reassign parameter. 
  151. * @param WP_REST_Request $request Full details about the request. 
  152. * @param string $param The parameter that is being sanitized. 
  153. * 
  154. * @return int|bool|WP_Error 
  155. */ 
  156. public function check_reassign( $value, $request, $param ) { 
  157. if ( is_numeric( $value ) ) { 
  158. return $value; 
  159.  
  160. if ( empty( $value ) || false === $value || 'false' === $value ) { 
  161. return false; 
  162.  
  163. return new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) ); 
  164.  
  165. /** 
  166. * Permissions check for getting all users. 
  167. * 
  168. * @since 4.7.0 
  169. * @access public 
  170. * 
  171. * @param WP_REST_Request $request Full details about the request. 
  172. * @return true|WP_Error True if the request has read access, otherwise WP_Error object. 
  173. */ 
  174. public function get_items_permissions_check( $request ) { 
  175. // Check if roles is specified in GET request and if user can list users. 
  176. if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) { 
  177. return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to filter users by role.' ), array( 'status' => rest_authorization_required_code() ) ); 
  178.  
  179. if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 
  180. return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); 
  181.  
  182. if ( in_array( $request['orderby'], array( 'email', 'registered_date' ), true ) && ! current_user_can( 'list_users' ) ) { 
  183. return new WP_Error( 'rest_forbidden_orderby', __( 'Sorry, you are not allowed to order users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) ); 
  184.  
  185. return true; 
  186.  
  187. /** 
  188. * Retrieves all users. 
  189. * 
  190. * @since 4.7.0 
  191. * @access public 
  192. * 
  193. * @param WP_REST_Request $request Full details about the request. 
  194. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  195. */ 
  196. public function get_items( $request ) { 
  197.  
  198. // Retrieve the list of registered collection query parameters. 
  199. $registered = $this->get_collection_params(); 
  200.  
  201. /** 
  202. * This array defines mappings between public API query parameters whose 
  203. * values are accepted as-passed, and their internal WP_Query parameter 
  204. * name equivalents (some are the same). Only values which are also 
  205. * present in $registered will be set. 
  206. */ 
  207. $parameter_mappings = array( 
  208. 'exclude' => 'exclude',  
  209. 'include' => 'include',  
  210. 'order' => 'order',  
  211. 'per_page' => 'number',  
  212. 'search' => 'search',  
  213. 'roles' => 'role__in',  
  214. 'slug' => 'nicename__in',  
  215. ); 
  216.  
  217. $prepared_args = array(); 
  218.  
  219. /** 
  220. * For each known parameter which is both registered and present in the request,  
  221. * set the parameter's value on the query $prepared_args. 
  222. */ 
  223. foreach ( $parameter_mappings as $api_param => $wp_param ) { 
  224. if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { 
  225. $prepared_args[ $wp_param ] = $request[ $api_param ]; 
  226.  
  227. if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) { 
  228. $prepared_args['offset'] = $request['offset']; 
  229. } else { 
  230. $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; 
  231.  
  232. if ( isset( $registered['orderby'] ) ) { 
  233. $orderby_possibles = array( 
  234. 'id' => 'ID',  
  235. 'include' => 'include',  
  236. 'name' => 'display_name',  
  237. 'registered_date' => 'registered',  
  238. 'slug' => 'user_nicename',  
  239. 'email' => 'user_email',  
  240. 'url' => 'user_url',  
  241. ); 
  242. $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; 
  243.  
  244. if ( ! current_user_can( 'list_users' ) ) { 
  245. $prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' ); 
  246.  
  247. if ( ! empty( $prepared_args['search'] ) ) { 
  248. $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; 
  249. /** 
  250. * Filters WP_User_Query arguments when querying users via the REST API. 
  251. * 
  252. * @link https://developer.wordpress.org/reference/classes/wp_user_query/ 
  253. * 
  254. * @since 4.7.0 
  255. * 
  256. * @param array $prepared_args Array of arguments for WP_User_Query. 
  257. * @param WP_REST_Request $request The current request. 
  258. */ 
  259. $prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request ); 
  260.  
  261. $query = new WP_User_Query( $prepared_args ); 
  262.  
  263. $users = array(); 
  264.  
  265. foreach ( $query->results as $user ) { 
  266. $data = $this->prepare_item_for_response( $user, $request ); 
  267. $users[] = $this->prepare_response_for_collection( $data ); 
  268.  
  269. $response = rest_ensure_response( $users ); 
  270.  
  271. // Store pagination values for headers then unset for count query. 
  272. $per_page = (int) $prepared_args['number']; 
  273. $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); 
  274.  
  275. $prepared_args['fields'] = 'ID'; 
  276.  
  277. $total_users = $query->get_total(); 
  278.  
  279. if ( $total_users < 1 ) { 
  280. // Out-of-bounds, run the query again without LIMIT for total count. 
  281. unset( $prepared_args['number'], $prepared_args['offset'] ); 
  282. $count_query = new WP_User_Query( $prepared_args ); 
  283. $total_users = $count_query->get_total(); 
  284.  
  285. $response->header( 'X-WP-Total', (int) $total_users ); 
  286.  
  287. $max_pages = ceil( $total_users / $per_page ); 
  288.  
  289. $response->header( 'X-WP-TotalPages', (int) $max_pages ); 
  290.  
  291. $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); 
  292. if ( $page > 1 ) { 
  293. $prev_page = $page - 1; 
  294.  
  295. if ( $prev_page > $max_pages ) { 
  296. $prev_page = $max_pages; 
  297.  
  298. $prev_link = add_query_arg( 'page', $prev_page, $base ); 
  299. $response->link_header( 'prev', $prev_link ); 
  300. if ( $max_pages > $page ) { 
  301. $next_page = $page + 1; 
  302. $next_link = add_query_arg( 'page', $next_page, $base ); 
  303.  
  304. $response->link_header( 'next', $next_link ); 
  305.  
  306. return $response; 
  307.  
  308. /** 
  309. * Get the user, if the ID is valid. 
  310. * 
  311. * @since 4.7.2 
  312. * 
  313. * @param int $id Supplied ID. 
  314. * @return WP_User|WP_Error True if ID is valid, WP_Error otherwise. 
  315. */ 
  316. protected function get_user( $id ) { 
  317. $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); 
  318. if ( (int) $id <= 0 ) { 
  319. return $error; 
  320.  
  321. $user = get_userdata( (int) $id ); 
  322. if ( empty( $user ) || ! $user->exists() ) { 
  323. return $error; 
  324.  
  325. if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) { 
  326. return $error; 
  327.  
  328. return $user; 
  329.  
  330. /** 
  331. * Checks if a given request has access to read a user. 
  332. * 
  333. * @since 4.7.0 
  334. * @access public 
  335. * 
  336. * @param WP_REST_Request $request Full details about the request. 
  337. * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. 
  338. */ 
  339. public function get_item_permissions_check( $request ) { 
  340. $user = $this->get_user( $request['id'] ); 
  341. if ( is_wp_error( $user ) ) { 
  342. return $user; 
  343.  
  344. $types = get_post_types( array( 'show_in_rest' => true ), 'names' ); 
  345.  
  346. if ( get_current_user_id() === $user->ID ) { 
  347. return true; 
  348.  
  349. if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 
  350. return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); 
  351. } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) { 
  352. return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); 
  353.  
  354. return true; 
  355.  
  356. /** 
  357. * Retrieves a single user. 
  358. * 
  359. * @since 4.7.0 
  360. * @access public 
  361. * 
  362. * @param WP_REST_Request $request Full details about the request. 
  363. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  364. */ 
  365. public function get_item( $request ) { 
  366. $user = $this->get_user( $request['id'] ); 
  367. if ( is_wp_error( $user ) ) { 
  368. return $user; 
  369.  
  370. $user = $this->prepare_item_for_response( $user, $request ); 
  371. $response = rest_ensure_response( $user ); 
  372.  
  373. return $response; 
  374.  
  375. /** 
  376. * Retrieves the current user. 
  377. * 
  378. * @since 4.7.0 
  379. * @access public 
  380. * 
  381. * @param WP_REST_Request $request Full details about the request. 
  382. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  383. */ 
  384. public function get_current_item( $request ) { 
  385. $current_user_id = get_current_user_id(); 
  386.  
  387. if ( empty( $current_user_id ) ) { 
  388. return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); 
  389.  
  390. $user = wp_get_current_user(); 
  391. $response = $this->prepare_item_for_response( $user, $request ); 
  392. $response = rest_ensure_response( $response ); 
  393.  
  394.  
  395. return $response; 
  396.  
  397. /** 
  398. * Checks if a given request has access create users. 
  399. * 
  400. * @since 4.7.0 
  401. * @access public 
  402. * 
  403. * @param WP_REST_Request $request Full details about the request. 
  404. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. 
  405. */ 
  406. public function create_item_permissions_check( $request ) { 
  407.  
  408. if ( ! current_user_can( 'create_users' ) ) { 
  409. return new WP_Error( 'rest_cannot_create_user', __( 'Sorry, you are not allowed to create new users.' ), array( 'status' => rest_authorization_required_code() ) ); 
  410.  
  411. return true; 
  412.  
  413. /** 
  414. * Creates a single user. 
  415. * 
  416. * @since 4.7.0 
  417. * @access public 
  418. * 
  419. * @param WP_REST_Request $request Full details about the request. 
  420. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  421. */ 
  422. public function create_item( $request ) { 
  423. if ( ! empty( $request['id'] ) ) { 
  424. return new WP_Error( 'rest_user_exists', __( 'Cannot create existing user.' ), array( 'status' => 400 ) ); 
  425.  
  426. $schema = $this->get_item_schema(); 
  427.  
  428. if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { 
  429. $check_permission = $this->check_role_update( $request['id'], $request['roles'] ); 
  430.  
  431. if ( is_wp_error( $check_permission ) ) { 
  432. return $check_permission; 
  433.  
  434. $user = $this->prepare_item_for_database( $request ); 
  435.  
  436. if ( is_multisite() ) { 
  437. $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); 
  438.  
  439. if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) { 
  440. $error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) ); 
  441. foreach ( $ret['errors']->errors as $code => $messages ) { 
  442. foreach ( $messages as $message ) { 
  443. $error->add( $code, $message ); 
  444. if ( $error_data = $error->get_error_data( $code ) ) { 
  445. $error->add_data( $error_data, $code ); 
  446. return $error; 
  447.  
  448. if ( is_multisite() ) { 
  449. $user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email ); 
  450.  
  451. if ( ! $user_id ) { 
  452. return new WP_Error( 'rest_user_create', __( 'Error creating new user.' ), array( 'status' => 500 ) ); 
  453.  
  454. $user->ID = $user_id; 
  455. $user_id = wp_update_user( wp_slash( (array) $user ) ); 
  456.  
  457. if ( is_wp_error( $user_id ) ) { 
  458. return $user_id; 
  459.  
  460. add_user_to_blog( get_site()->id, $user_id, '' ); 
  461. } else { 
  462. $user_id = wp_insert_user( wp_slash( (array) $user ) ); 
  463.  
  464. if ( is_wp_error( $user_id ) ) { 
  465. return $user_id; 
  466.  
  467. $user = get_user_by( 'id', $user_id ); 
  468.  
  469. /** 
  470. * Fires immediately after a user is created or updated via the REST API. 
  471. * 
  472. * @since 4.7.0 
  473. * 
  474. * @param WP_User $user Inserted or updated user object. 
  475. * @param WP_REST_Request $request Request object. 
  476. * @param bool $creating True when creating a user, false when updating. 
  477. */ 
  478. do_action( 'rest_insert_user', $user, $request, true ); 
  479.  
  480. if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { 
  481. array_map( array( $user, 'add_role' ), $request['roles'] ); 
  482.  
  483. if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { 
  484. $meta_update = $this->meta->update_value( $request['meta'], $user_id ); 
  485.  
  486. if ( is_wp_error( $meta_update ) ) { 
  487. return $meta_update; 
  488.  
  489. $user = get_user_by( 'id', $user_id ); 
  490. $fields_update = $this->update_additional_fields_for_object( $user, $request ); 
  491.  
  492. if ( is_wp_error( $fields_update ) ) { 
  493. return $fields_update; 
  494.  
  495. $request->set_param( 'context', 'edit' ); 
  496.  
  497. $response = $this->prepare_item_for_response( $user, $request ); 
  498. $response = rest_ensure_response( $response ); 
  499.  
  500. $response->set_status( 201 ); 
  501. $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user_id ) ) ); 
  502.  
  503. return $response; 
  504.  
  505. /** 
  506. * Checks if a given request has access to update a user. 
  507. * 
  508. * @since 4.7.0 
  509. * @access public 
  510. * 
  511. * @param WP_REST_Request $request Full details about the request. 
  512. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. 
  513. */ 
  514. public function update_item_permissions_check( $request ) { 
  515. $user = $this->get_user( $request['id'] ); 
  516. if ( is_wp_error( $user ) ) { 
  517. return $user; 
  518.  
  519. if ( ! current_user_can( 'edit_user', $user->ID ) ) { 
  520. return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); 
  521.  
  522. if ( ! empty( $request['roles'] ) && ! current_user_can( 'edit_users' ) ) { 
  523. return new WP_Error( 'rest_cannot_edit_roles', __( 'Sorry, you are not allowed to edit roles of this user.' ), array( 'status' => rest_authorization_required_code() ) ); 
  524.  
  525. return true; 
  526.  
  527. /** 
  528. * Updates a single user. 
  529. * 
  530. * @since 4.7.0 
  531. * @access public 
  532. * 
  533. * @param WP_REST_Request $request Full details about the request. 
  534. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  535. */ 
  536. public function update_item( $request ) { 
  537. $user = $this->get_user( $request['id'] ); 
  538. if ( is_wp_error( $user ) ) { 
  539. return $user; 
  540.  
  541. $id = $user->ID; 
  542.  
  543. if ( ! $user ) { 
  544. return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); 
  545.  
  546. if ( email_exists( $request['email'] ) && $request['email'] !== $user->user_email ) { 
  547. return new WP_Error( 'rest_user_invalid_email', __( 'Invalid email address.' ), array( 'status' => 400 ) ); 
  548.  
  549. if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) { 
  550. return new WP_Error( 'rest_user_invalid_argument', __( "Username isn't editable." ), array( 'status' => 400 ) ); 
  551.  
  552. if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) { 
  553. return new WP_Error( 'rest_user_invalid_slug', __( 'Invalid slug.' ), array( 'status' => 400 ) ); 
  554.  
  555. if ( ! empty( $request['roles'] ) ) { 
  556. $check_permission = $this->check_role_update( $id, $request['roles'] ); 
  557.  
  558. if ( is_wp_error( $check_permission ) ) { 
  559. return $check_permission; 
  560.  
  561. $user = $this->prepare_item_for_database( $request ); 
  562.  
  563. // Ensure we're operating on the same user we already checked. 
  564. $user->ID = $id; 
  565.  
  566. $user_id = wp_update_user( wp_slash( (array) $user ) ); 
  567.  
  568. if ( is_wp_error( $user_id ) ) { 
  569. return $user_id; 
  570.  
  571. $user = get_user_by( 'id', $user_id ); 
  572.  
  573. /** This action is documented in lib/endpoints/class-wp-rest-users-controller.php */ 
  574. do_action( 'rest_insert_user', $user, $request, false ); 
  575.  
  576. if ( ! empty( $request['roles'] ) ) { 
  577. array_map( array( $user, 'add_role' ), $request['roles'] ); 
  578.  
  579. $schema = $this->get_item_schema(); 
  580.  
  581. if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { 
  582. $meta_update = $this->meta->update_value( $request['meta'], $id ); 
  583.  
  584. if ( is_wp_error( $meta_update ) ) { 
  585. return $meta_update; 
  586.  
  587. $user = get_user_by( 'id', $user_id ); 
  588. $fields_update = $this->update_additional_fields_for_object( $user, $request ); 
  589.  
  590. if ( is_wp_error( $fields_update ) ) { 
  591. return $fields_update; 
  592.  
  593. $request->set_param( 'context', 'edit' ); 
  594.  
  595. $response = $this->prepare_item_for_response( $user, $request ); 
  596. $response = rest_ensure_response( $response ); 
  597.  
  598. return $response; 
  599.  
  600. /** 
  601. * Checks if a given request has access to update the current user. 
  602. * 
  603. * @since 4.7.0 
  604. * @access public 
  605. * 
  606. * @param WP_REST_Request $request Full details about the request. 
  607. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. 
  608. */ 
  609. public function update_current_item_permissions_check( $request ) { 
  610. $request['id'] = get_current_user_id(); 
  611.  
  612. return $this->update_item_permissions_check( $request ); 
  613.  
  614. /** 
  615. * Updates the current user. 
  616. * 
  617. * @since 4.7.0 
  618. * @access public 
  619. * 
  620. * @param WP_REST_Request $request Full details about the request. 
  621. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  622. */ 
  623. function update_current_item( $request ) { 
  624. $request['id'] = get_current_user_id(); 
  625.  
  626. return $this->update_item( $request ); 
  627.  
  628. /** 
  629. * Checks if a given request has access delete a user. 
  630. * 
  631. * @since 4.7.0 
  632. * @access public 
  633. * 
  634. * @param WP_REST_Request $request Full details about the request. 
  635. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. 
  636. */ 
  637. public function delete_item_permissions_check( $request ) { 
  638. $user = $this->get_user( $request['id'] ); 
  639. if ( is_wp_error( $user ) ) { 
  640. return $user; 
  641.  
  642. if ( ! current_user_can( 'delete_user', $user->ID ) ) { 
  643. return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) ); 
  644.  
  645. return true; 
  646.  
  647. /** 
  648. * Deletes a single user. 
  649. * 
  650. * @since 4.7.0 
  651. * @access public 
  652. * 
  653. * @param WP_REST_Request $request Full details about the request. 
  654. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  655. */ 
  656. public function delete_item( $request ) { 
  657. // We don't support delete requests in multisite. 
  658. if ( is_multisite() ) { 
  659. return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 501 ) ); 
  660. $user = $this->get_user( $request['id'] ); 
  661. if ( is_wp_error( $user ) ) { 
  662. return $user; 
  663.  
  664. $id = $user->ID; 
  665. $reassign = false === $request['reassign'] ? null : absint( $request['reassign'] ); 
  666. $force = isset( $request['force'] ) ? (bool) $request['force'] : false; 
  667.  
  668. // We don't support trashing for users. 
  669. if ( ! $force ) { 
  670. return new WP_Error( 'rest_trash_not_supported', __( 'Users do not support trashing. Set force=true to delete.' ), array( 'status' => 501 ) ); 
  671.  
  672. if ( ! empty( $reassign ) ) { 
  673. if ( $reassign === $id || ! get_userdata( $reassign ) ) { 
  674. return new WP_Error( 'rest_user_invalid_reassign', __( 'Invalid user ID for reassignment.' ), array( 'status' => 400 ) ); 
  675.  
  676. $request->set_param( 'context', 'edit' ); 
  677.  
  678. $previous = $this->prepare_item_for_response( $user, $request ); 
  679.  
  680. /** Include admin user functions to get access to wp_delete_user() */ 
  681. require_once ABSPATH . 'wp-admin/includes/user.php'; 
  682.  
  683. $result = wp_delete_user( $id, $reassign ); 
  684.  
  685. if ( ! $result ) { 
  686. return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 500 ) ); 
  687.  
  688. $response = new WP_REST_Response(); 
  689. $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data() ) ); 
  690.  
  691. /** 
  692. * Fires immediately after a user is deleted via the REST API. 
  693. * 
  694. * @since 4.7.0 
  695. * 
  696. * @param WP_User $user The user data. 
  697. * @param WP_REST_Response $response The response returned from the API. 
  698. * @param WP_REST_Request $request The request sent to the API. 
  699. */ 
  700. do_action( 'rest_delete_user', $user, $response, $request ); 
  701.  
  702. return $response; 
  703.  
  704. /** 
  705. * Checks if a given request has access to delete the current user. 
  706. * 
  707. * @since 4.7.0 
  708. * @access public 
  709. * 
  710. * @param WP_REST_Request $request Full details about the request. 
  711. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. 
  712. */ 
  713. public function delete_current_item_permissions_check( $request ) { 
  714. $request['id'] = get_current_user_id(); 
  715.  
  716. return $this->delete_item_permissions_check( $request ); 
  717.  
  718. /** 
  719. * Deletes the current user. 
  720. * 
  721. * @since 4.7.0 
  722. * @access public 
  723. * 
  724. * @param WP_REST_Request $request Full details about the request. 
  725. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 
  726. */ 
  727. function delete_current_item( $request ) { 
  728. $request['id'] = get_current_user_id(); 
  729.  
  730. return $this->delete_item( $request ); 
  731.  
  732. /** 
  733. * Prepares a single user output for response. 
  734. * 
  735. * @since 4.7.0 
  736. * @access public 
  737. * 
  738. * @param WP_User $user User object. 
  739. * @param WP_REST_Request $request Request object. 
  740. * @return WP_REST_Response Response object. 
  741. */ 
  742. public function prepare_item_for_response( $user, $request ) { 
  743.  
  744. $data = array(); 
  745. $schema = $this->get_item_schema(); 
  746.  
  747. if ( ! empty( $schema['properties']['id'] ) ) { 
  748. $data['id'] = $user->ID; 
  749.  
  750. if ( ! empty( $schema['properties']['username'] ) ) { 
  751. $data['username'] = $user->user_login; 
  752.  
  753. if ( ! empty( $schema['properties']['name'] ) ) { 
  754. $data['name'] = $user->display_name; 
  755.  
  756. if ( ! empty( $schema['properties']['first_name'] ) ) { 
  757. $data['first_name'] = $user->first_name; 
  758.  
  759. if ( ! empty( $schema['properties']['last_name'] ) ) { 
  760. $data['last_name'] = $user->last_name; 
  761.  
  762. if ( ! empty( $schema['properties']['email'] ) ) { 
  763. $data['email'] = $user->user_email; 
  764.  
  765. if ( ! empty( $schema['properties']['url'] ) ) { 
  766. $data['url'] = $user->user_url; 
  767.  
  768. if ( ! empty( $schema['properties']['description'] ) ) { 
  769. $data['description'] = $user->description; 
  770.  
  771. if ( ! empty( $schema['properties']['link'] ) ) { 
  772. $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename ); 
  773.  
  774. if ( ! empty( $schema['properties']['locale'] ) ) { 
  775. $data['locale'] = get_user_locale( $user ); 
  776.  
  777. if ( ! empty( $schema['properties']['nickname'] ) ) { 
  778. $data['nickname'] = $user->nickname; 
  779.  
  780. if ( ! empty( $schema['properties']['slug'] ) ) { 
  781. $data['slug'] = $user->user_nicename; 
  782.  
  783. if ( ! empty( $schema['properties']['roles'] ) ) { 
  784. // Defensively call array_values() to ensure an array is returned. 
  785. $data['roles'] = array_values( $user->roles ); 
  786.  
  787. if ( ! empty( $schema['properties']['registered_date'] ) ) { 
  788. $data['registered_date'] = date( 'c', strtotime( $user->user_registered ) ); 
  789.  
  790. if ( ! empty( $schema['properties']['capabilities'] ) ) { 
  791. $data['capabilities'] = (object) $user->allcaps; 
  792.  
  793. if ( ! empty( $schema['properties']['extra_capabilities'] ) ) { 
  794. $data['extra_capabilities'] = (object) $user->caps; 
  795.  
  796. if ( ! empty( $schema['properties']['avatar_urls'] ) ) { 
  797. $data['avatar_urls'] = rest_get_avatar_urls( $user->user_email ); 
  798.  
  799. if ( ! empty( $schema['properties']['meta'] ) ) { 
  800. $data['meta'] = $this->meta->get_value( $user->ID, $request ); 
  801.  
  802. $context = ! empty( $request['context'] ) ? $request['context'] : 'embed'; 
  803.  
  804. $data = $this->add_additional_fields_to_object( $data, $request ); 
  805. $data = $this->filter_response_by_context( $data, $context ); 
  806.  
  807. // Wrap the data in a response object. 
  808. $response = rest_ensure_response( $data ); 
  809.  
  810. $response->add_links( $this->prepare_links( $user ) ); 
  811.  
  812. /** 
  813. * Filters user data returned from the REST API. 
  814. * 
  815. * @since 4.7.0 
  816. * 
  817. * @param WP_REST_Response $response The response object. 
  818. * @param object $user User object used to create response. 
  819. * @param WP_REST_Request $request Request object. 
  820. */ 
  821. return apply_filters( 'rest_prepare_user', $response, $user, $request ); 
  822.  
  823. /** 
  824. * Prepares links for the user request. 
  825. * 
  826. * @since 4.7.0 
  827. * @access protected 
  828. * 
  829. * @param WP_Post $user User object. 
  830. * @return array Links for the given user. 
  831. */ 
  832. protected function prepare_links( $user ) { 
  833. $links = array( 
  834. 'self' => array( 
  835. 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ),  
  836. ),  
  837. 'collection' => array( 
  838. 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),  
  839. ),  
  840. ); 
  841.  
  842. return $links; 
  843.  
  844. /** 
  845. * Prepares a single user for creation or update. 
  846. * 
  847. * @since 4.7.0 
  848. * @access protected 
  849. * 
  850. * @param WP_REST_Request $request Request object. 
  851. * @return object $prepared_user User object. 
  852. */ 
  853. protected function prepare_item_for_database( $request ) { 
  854. $prepared_user = new stdClass; 
  855.  
  856. $schema = $this->get_item_schema(); 
  857.  
  858. // required arguments. 
  859. if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) { 
  860. $prepared_user->user_email = $request['email']; 
  861.  
  862. if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) { 
  863. $prepared_user->user_login = $request['username']; 
  864.  
  865. if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) { 
  866. $prepared_user->user_pass = $request['password']; 
  867.  
  868. // optional arguments. 
  869. if ( isset( $request['id'] ) ) { 
  870. $prepared_user->ID = absint( $request['id'] ); 
  871.  
  872. if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { 
  873. $prepared_user->display_name = $request['name']; 
  874.  
  875. if ( isset( $request['first_name'] ) && ! empty( $schema['properties']['first_name'] ) ) { 
  876. $prepared_user->first_name = $request['first_name']; 
  877.  
  878. if ( isset( $request['last_name'] ) && ! empty( $schema['properties']['last_name'] ) ) { 
  879. $prepared_user->last_name = $request['last_name']; 
  880.  
  881. if ( isset( $request['nickname'] ) && ! empty( $schema['properties']['nickname'] ) ) { 
  882. $prepared_user->nickname = $request['nickname']; 
  883.  
  884. if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) { 
  885. $prepared_user->user_nicename = $request['slug']; 
  886.  
  887. if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) { 
  888. $prepared_user->description = $request['description']; 
  889.  
  890. if ( isset( $request['url'] ) && ! empty( $schema['properties']['url'] ) ) { 
  891. $prepared_user->user_url = $request['url']; 
  892.  
  893. if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) { 
  894. $prepared_user->locale = $request['locale']; 
  895.  
  896. // setting roles will be handled outside of this function. 
  897. if ( isset( $request['roles'] ) ) { 
  898. $prepared_user->role = false; 
  899.  
  900. /** 
  901. * Filters user data before insertion via the REST API. 
  902. * 
  903. * @since 4.7.0 
  904. * 
  905. * @param object $prepared_user User object. 
  906. * @param WP_REST_Request $request Request object. 
  907. */ 
  908. return apply_filters( 'rest_pre_insert_user', $prepared_user, $request ); 
  909.  
  910. /** 
  911. * Determines if the current user is allowed to make the desired roles change. 
  912. * 
  913. * @since 4.7.0 
  914. * @access protected 
  915. * 
  916. * @param integer $user_id User ID. 
  917. * @param array $roles New user roles. 
  918. * @return true|WP_Error True if the current user is allowed to make the role change,  
  919. * otherwise a WP_Error object. 
  920. */ 
  921. protected function check_role_update( $user_id, $roles ) { 
  922. global $wp_roles; 
  923.  
  924. foreach ( $roles as $role ) { 
  925.  
  926. if ( ! isset( $wp_roles->role_objects[ $role ] ) ) { 
  927. /** translators: %s: role key */ 
  928. return new WP_Error( 'rest_user_invalid_role', sprintf( __( 'The role %s does not exist.' ), $role ), array( 'status' => 400 ) ); 
  929.  
  930. $potential_role = $wp_roles->role_objects[ $role ]; 
  931.  
  932. /** 
  933. * Don't let anyone with 'edit_users' (admins) edit their own role to something without it. 
  934. * Multisite super admins can freely edit their blog roles -- they possess all caps. 
  935. */ 
  936. if ( ! ( is_multisite() 
  937. && current_user_can( 'manage_sites' ) ) 
  938. && get_current_user_id() === $user_id 
  939. && ! $potential_role->has_cap( 'edit_users' ) 
  940. ) { 
  941. return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => rest_authorization_required_code() ) ); 
  942.  
  943. /** Include admin functions to get access to get_editable_roles() */ 
  944. require_once ABSPATH . 'wp-admin/includes/admin.php'; 
  945.  
  946. // The new role must be editable by the logged-in user. 
  947. $editable_roles = get_editable_roles(); 
  948.  
  949. if ( empty( $editable_roles[ $role ] ) ) { 
  950. return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => 403 ) ); 
  951.  
  952. return true; 
  953.  
  954. /** 
  955. * Check a username for the REST API. 
  956. * 
  957. * Performs a couple of checks like edit_user() in wp-admin/includes/user.php. 
  958. * 
  959. * @since 4.7.0 
  960. * 
  961. * @param mixed $value The username submitted in the request. 
  962. * @param WP_REST_Request $request Full details about the request. 
  963. * @param string $param The parameter name. 
  964. * @return WP_Error|string The sanitized username, if valid, otherwise an error. 
  965. */ 
  966. public function check_username( $value, $request, $param ) { 
  967. $username = (string) $value; 
  968.  
  969. if ( ! validate_username( $username ) ) { 
  970. return new WP_Error( 'rest_user_invalid_username', __( 'Username contains invalid characters.' ), array( 'status' => 400 ) ); 
  971.  
  972. /** This filter is documented in wp-includes/user.php */ 
  973. $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); 
  974.  
  975. if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ) ) ) { 
  976. return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) ); 
  977.  
  978. return $username; 
  979.  
  980. /** 
  981. * Check a user password for the REST API. 
  982. * 
  983. * Performs a couple of checks like edit_user() in wp-admin/includes/user.php. 
  984. * 
  985. * @since 4.7.0 
  986. * 
  987. * @param mixed $value The password submitted in the request. 
  988. * @param WP_REST_Request $request Full details about the request. 
  989. * @param string $param The parameter name. 
  990. * @return WP_Error|string The sanitized password, if valid, otherwise an error. 
  991. */ 
  992. public function check_user_password( $value, $request, $param ) { 
  993. $password = (string) $value; 
  994.  
  995. if ( empty( $password ) ) { 
  996. return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) ); 
  997.  
  998. if ( false !== strpos( $password, "\\" ) ) { 
  999. return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) ); 
  1000.  
  1001. return $password; 
  1002.  
  1003. /** 
  1004. * Retrieves the user's schema, conforming to JSON Schema. 
  1005. * 
  1006. * @since 4.7.0 
  1007. * @access public 
  1008. * 
  1009. * @return array Item schema data. 
  1010. */ 
  1011. public function get_item_schema() { 
  1012. $schema = array( 
  1013. '$schema' => 'http://json-schema.org/schema#',  
  1014. 'title' => 'user',  
  1015. 'type' => 'object',  
  1016. 'properties' => array( 
  1017. 'id' => array( 
  1018. 'description' => __( 'Unique identifier for the user.' ),  
  1019. 'type' => 'integer',  
  1020. 'context' => array( 'embed', 'view', 'edit' ),  
  1021. 'readonly' => true,  
  1022. ),  
  1023. 'username' => array( 
  1024. 'description' => __( 'Login name for the user.' ),  
  1025. 'type' => 'string',  
  1026. 'context' => array( 'edit' ),  
  1027. 'required' => true,  
  1028. 'arg_options' => array( 
  1029. 'sanitize_callback' => array( $this, 'check_username' ),  
  1030. ),  
  1031. ),  
  1032. 'name' => array( 
  1033. 'description' => __( 'Display name for the user.' ),  
  1034. 'type' => 'string',  
  1035. 'context' => array( 'embed', 'view', 'edit' ),  
  1036. 'arg_options' => array( 
  1037. 'sanitize_callback' => 'sanitize_text_field',  
  1038. ),  
  1039. ),  
  1040. 'first_name' => array( 
  1041. 'description' => __( 'First name for the user.' ),  
  1042. 'type' => 'string',  
  1043. 'context' => array( 'edit' ),  
  1044. 'arg_options' => array( 
  1045. 'sanitize_callback' => 'sanitize_text_field',  
  1046. ),  
  1047. ),  
  1048. 'last_name' => array( 
  1049. 'description' => __( 'Last name for the user.' ),  
  1050. 'type' => 'string',  
  1051. 'context' => array( 'edit' ),  
  1052. 'arg_options' => array( 
  1053. 'sanitize_callback' => 'sanitize_text_field',  
  1054. ),  
  1055. ),  
  1056. 'email' => array( 
  1057. 'description' => __( 'The email address for the user.' ),  
  1058. 'type' => 'string',  
  1059. 'format' => 'email',  
  1060. 'context' => array( 'edit' ),  
  1061. 'required' => true,  
  1062. ),  
  1063. 'url' => array( 
  1064. 'description' => __( 'URL of the user.' ),  
  1065. 'type' => 'string',  
  1066. 'format' => 'uri',  
  1067. 'context' => array( 'embed', 'view', 'edit' ),  
  1068. ),  
  1069. 'description' => array( 
  1070. 'description' => __( 'Description of the user.' ),  
  1071. 'type' => 'string',  
  1072. 'context' => array( 'embed', 'view', 'edit' ),  
  1073. ),  
  1074. 'link' => array( 
  1075. 'description' => __( 'Author URL of the user.' ),  
  1076. 'type' => 'string',  
  1077. 'format' => 'uri',  
  1078. 'context' => array( 'embed', 'view', 'edit' ),  
  1079. 'readonly' => true,  
  1080. ),  
  1081. 'locale' => array( 
  1082. 'description' => __( 'Locale for the user.' ),  
  1083. 'type' => 'string',  
  1084. 'enum' => array_merge( array( '', 'en_US' ), get_available_languages() ),  
  1085. 'context' => array( 'edit' ),  
  1086. ),  
  1087. 'nickname' => array( 
  1088. 'description' => __( 'The nickname for the user.' ),  
  1089. 'type' => 'string',  
  1090. 'context' => array( 'edit' ),  
  1091. 'arg_options' => array( 
  1092. 'sanitize_callback' => 'sanitize_text_field',  
  1093. ),  
  1094. ),  
  1095. 'slug' => array( 
  1096. 'description' => __( 'An alphanumeric identifier for the user.' ),  
  1097. 'type' => 'string',  
  1098. 'context' => array( 'embed', 'view', 'edit' ),  
  1099. 'arg_options' => array( 
  1100. 'sanitize_callback' => array( $this, 'sanitize_slug' ),  
  1101. ),  
  1102. ),  
  1103. 'registered_date' => array( 
  1104. 'description' => __( 'Registration date for the user.' ),  
  1105. 'type' => 'string',  
  1106. 'format' => 'date-time',  
  1107. 'context' => array( 'edit' ),  
  1108. 'readonly' => true,  
  1109. ),  
  1110. 'roles' => array( 
  1111. 'description' => __( 'Roles assigned to the user.' ),  
  1112. 'type' => 'array',  
  1113. 'items' => array( 
  1114. 'type' => 'string',  
  1115. ),  
  1116. 'context' => array( 'edit' ),  
  1117. ),  
  1118. 'password' => array( 
  1119. 'description' => __( 'Password for the user (never included).' ),  
  1120. 'type' => 'string',  
  1121. 'context' => array(), // Password is never displayed. 
  1122. 'required' => true,  
  1123. 'arg_options' => array( 
  1124. 'sanitize_callback' => array( $this, 'check_user_password' ),  
  1125. ),  
  1126. ),  
  1127. 'capabilities' => array( 
  1128. 'description' => __( 'All capabilities assigned to the user.' ),  
  1129. 'type' => 'object',  
  1130. 'context' => array( 'edit' ),  
  1131. 'readonly' => true,  
  1132. ),  
  1133. 'extra_capabilities' => array( 
  1134. 'description' => __( 'Any extra capabilities assigned to the user.' ),  
  1135. 'type' => 'object',  
  1136. 'context' => array( 'edit' ),  
  1137. 'readonly' => true,  
  1138. ),  
  1139. ),  
  1140. ); 
  1141.  
  1142. if ( get_option( 'show_avatars' ) ) { 
  1143. $avatar_properties = array(); 
  1144.  
  1145. $avatar_sizes = rest_get_avatar_sizes(); 
  1146.  
  1147. foreach ( $avatar_sizes as $size ) { 
  1148. $avatar_properties[ $size ] = array( 
  1149. /** translators: %d: avatar image size in pixels */ 
  1150. 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ),  
  1151. 'type' => 'string',  
  1152. 'format' => 'uri',  
  1153. 'context' => array( 'embed', 'view', 'edit' ),  
  1154. ); 
  1155.  
  1156. $schema['properties']['avatar_urls'] = array( 
  1157. 'description' => __( 'Avatar URLs for the user.' ),  
  1158. 'type' => 'object',  
  1159. 'context' => array( 'embed', 'view', 'edit' ),  
  1160. 'readonly' => true,  
  1161. 'properties' => $avatar_properties,  
  1162. ); 
  1163.  
  1164. $schema['properties']['meta'] = $this->meta->get_field_schema(); 
  1165.  
  1166. return $this->add_additional_fields_schema( $schema ); 
  1167.  
  1168. /** 
  1169. * Retrieves the query params for collections. 
  1170. * 
  1171. * @since 4.7.0 
  1172. * @access public 
  1173. * 
  1174. * @return array Collection parameters. 
  1175. */ 
  1176. public function get_collection_params() { 
  1177. $query_params = parent::get_collection_params(); 
  1178.  
  1179. $query_params['context']['default'] = 'view'; 
  1180.  
  1181. $query_params['exclude'] = array( 
  1182. 'description' => __( 'Ensure result set excludes specific IDs.' ),  
  1183. 'type' => 'array',  
  1184. 'items' => array( 
  1185. 'type' => 'integer',  
  1186. ),  
  1187. 'default' => array(),  
  1188. ); 
  1189.  
  1190. $query_params['include'] = array( 
  1191. 'description' => __( 'Limit result set to specific IDs.' ),  
  1192. 'type' => 'array',  
  1193. 'items' => array( 
  1194. 'type' => 'integer',  
  1195. ),  
  1196. 'default' => array(),  
  1197. ); 
  1198.  
  1199. $query_params['offset'] = array( 
  1200. 'description' => __( 'Offset the result set by a specific number of items.' ),  
  1201. 'type' => 'integer',  
  1202. ); 
  1203.  
  1204. $query_params['order'] = array( 
  1205. 'default' => 'asc',  
  1206. 'description' => __( 'Order sort attribute ascending or descending.' ),  
  1207. 'enum' => array( 'asc', 'desc' ),  
  1208. 'type' => 'string',  
  1209. ); 
  1210.  
  1211. $query_params['orderby'] = array( 
  1212. 'default' => 'name',  
  1213. 'description' => __( 'Sort collection by object attribute.' ),  
  1214. 'enum' => array( 
  1215. 'id',  
  1216. 'include',  
  1217. 'name',  
  1218. 'registered_date',  
  1219. 'slug',  
  1220. 'email',  
  1221. 'url',  
  1222. ),  
  1223. 'type' => 'string',  
  1224. ); 
  1225.  
  1226. $query_params['slug'] = array( 
  1227. 'description' => __( 'Limit result set to users with a specific slug.' ),  
  1228. 'type' => 'array',  
  1229. 'items' => array( 
  1230. 'type' => 'string',  
  1231. ),  
  1232. ); 
  1233.  
  1234. $query_params['roles'] = array( 
  1235. 'description' => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ),  
  1236. 'type' => 'array',  
  1237. 'items' => array( 
  1238. 'type' => 'string',  
  1239. ),  
  1240. ); 
  1241.  
  1242. /** 
  1243. * Filter collection parameters for the users controller. 
  1244. * 
  1245. * This filter registers the collection parameter, but does not map the 
  1246. * collection parameter to an internal WP_User_Query parameter. Use the 
  1247. * `rest_user_query` filter to set WP_User_Query arguments. 
  1248. * 
  1249. * @since 4.7.0 
  1250. * 
  1251. * @param array $query_params JSON Schema-formatted collection parameters. 
  1252. */ 
  1253. return apply_filters( 'rest_user_collection_params', $query_params ); 
.