[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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 * @var WP_REST_User_Meta_Fields 24 */ 25 protected $meta; 26 27 /** 28 * Whether the controller supports batching. 29 * 30 * @since 6.6.0 31 * @var array 32 */ 33 protected $allow_batch = array( 'v1' => true ); 34 35 /** 36 * Constructor. 37 * 38 * @since 4.7.0 39 */ 40 public function __construct() { 41 $this->namespace = 'wp/v2'; 42 $this->rest_base = 'users'; 43 44 $this->meta = new WP_REST_User_Meta_Fields(); 45 } 46 47 /** 48 * Registers the routes for users. 49 * 50 * @since 4.7.0 51 * 52 * @see register_rest_route() 53 */ 54 public function register_routes() { 55 56 register_rest_route( 57 $this->namespace, 58 '/' . $this->rest_base, 59 array( 60 array( 61 'methods' => WP_REST_Server::READABLE, 62 'callback' => array( $this, 'get_items' ), 63 'permission_callback' => array( $this, 'get_items_permissions_check' ), 64 'args' => $this->get_collection_params(), 65 ), 66 array( 67 'methods' => WP_REST_Server::CREATABLE, 68 'callback' => array( $this, 'create_item' ), 69 'permission_callback' => array( $this, 'create_item_permissions_check' ), 70 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), 71 ), 72 'allow_batch' => $this->allow_batch, 73 'schema' => array( $this, 'get_public_item_schema' ), 74 ) 75 ); 76 77 register_rest_route( 78 $this->namespace, 79 '/' . $this->rest_base . '/(?P<id>[\d]+)', 80 array( 81 'args' => array( 82 'id' => array( 83 'description' => __( 'Unique identifier for the user.' ), 84 'type' => 'integer', 85 ), 86 ), 87 array( 88 'methods' => WP_REST_Server::READABLE, 89 'callback' => array( $this, 'get_item' ), 90 'permission_callback' => array( $this, 'get_item_permissions_check' ), 91 'args' => array( 92 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 93 ), 94 ), 95 array( 96 'methods' => WP_REST_Server::EDITABLE, 97 'callback' => array( $this, 'update_item' ), 98 'permission_callback' => array( $this, 'update_item_permissions_check' ), 99 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 100 ), 101 array( 102 'methods' => WP_REST_Server::DELETABLE, 103 'callback' => array( $this, 'delete_item' ), 104 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 105 'args' => array( 106 'force' => array( 107 'type' => 'boolean', 108 'default' => false, 109 'description' => __( 'Required to be true, as users do not support trashing.' ), 110 ), 111 'reassign' => array( 112 'type' => 'integer', 113 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ), 114 'required' => true, 115 'sanitize_callback' => array( $this, 'check_reassign' ), 116 ), 117 ), 118 ), 119 'allow_batch' => $this->allow_batch, 120 'schema' => array( $this, 'get_public_item_schema' ), 121 ) 122 ); 123 124 register_rest_route( 125 $this->namespace, 126 '/' . $this->rest_base . '/me', 127 array( 128 array( 129 'methods' => WP_REST_Server::READABLE, 130 'permission_callback' => '__return_true', 131 'callback' => array( $this, 'get_current_item' ), 132 'args' => array( 133 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 134 ), 135 ), 136 array( 137 'methods' => WP_REST_Server::EDITABLE, 138 'callback' => array( $this, 'update_current_item' ), 139 'permission_callback' => array( $this, 'update_current_item_permissions_check' ), 140 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 141 ), 142 array( 143 'methods' => WP_REST_Server::DELETABLE, 144 'callback' => array( $this, 'delete_current_item' ), 145 'permission_callback' => array( $this, 'delete_current_item_permissions_check' ), 146 'args' => array( 147 'force' => array( 148 'type' => 'boolean', 149 'default' => false, 150 'description' => __( 'Required to be true, as users do not support trashing.' ), 151 ), 152 'reassign' => array( 153 'type' => 'integer', 154 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ), 155 'required' => true, 156 'sanitize_callback' => array( $this, 'check_reassign' ), 157 ), 158 ), 159 ), 160 'schema' => array( $this, 'get_public_item_schema' ), 161 ) 162 ); 163 } 164 165 /** 166 * Checks for a valid value for the reassign parameter when deleting users. 167 * 168 * The value can be an integer, 'false', false, or ''. 169 * 170 * @since 4.7.0 171 * 172 * @param int|bool $value The value passed to the reassign parameter. 173 * @param WP_REST_Request $request Full details about the request. 174 * @param string $param The parameter that is being sanitized. 175 * @return int|bool|WP_Error 176 */ 177 public function check_reassign( $value, $request, $param ) { 178 if ( is_numeric( $value ) ) { 179 return $value; 180 } 181 182 if ( empty( $value ) || false === $value || 'false' === $value ) { 183 return false; 184 } 185 186 return new WP_Error( 187 'rest_invalid_param', 188 __( 'Invalid user parameter(s).' ), 189 array( 'status' => 400 ) 190 ); 191 } 192 193 /** 194 * Permissions check for getting all users. 195 * 196 * @since 4.7.0 197 * 198 * @param WP_REST_Request $request Full details about the request. 199 * @return true|WP_Error True if the request has read access, otherwise WP_Error object. 200 */ 201 public function get_items_permissions_check( $request ) { 202 // Check if roles is specified in GET request and if user can list users. 203 if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) { 204 return new WP_Error( 205 'rest_user_cannot_view', 206 __( 'Sorry, you are not allowed to filter users by role.' ), 207 array( 'status' => rest_authorization_required_code() ) 208 ); 209 } 210 211 // Check if capabilities is specified in GET request and if user can list users. 212 if ( ! empty( $request['capabilities'] ) && ! current_user_can( 'list_users' ) ) { 213 return new WP_Error( 214 'rest_user_cannot_view', 215 __( 'Sorry, you are not allowed to filter users by capability.' ), 216 array( 'status' => rest_authorization_required_code() ) 217 ); 218 } 219 220 if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 221 return new WP_Error( 222 'rest_forbidden_context', 223 __( 'Sorry, you are not allowed to list users.' ), 224 array( 'status' => rest_authorization_required_code() ) 225 ); 226 } 227 228 if ( in_array( $request['orderby'], array( 'email', 'registered_date' ), true ) && ! current_user_can( 'list_users' ) ) { 229 return new WP_Error( 230 'rest_forbidden_orderby', 231 __( 'Sorry, you are not allowed to order users by this parameter.' ), 232 array( 'status' => rest_authorization_required_code() ) 233 ); 234 } 235 236 if ( 'authors' === $request['who'] ) { 237 $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); 238 239 foreach ( $types as $type ) { 240 if ( post_type_supports( $type->name, 'author' ) 241 && current_user_can( $type->cap->edit_posts ) ) { 242 return true; 243 } 244 } 245 246 return new WP_Error( 247 'rest_forbidden_who', 248 __( 'Sorry, you are not allowed to query users by this parameter.' ), 249 array( 'status' => rest_authorization_required_code() ) 250 ); 251 } 252 253 return true; 254 } 255 256 /** 257 * Retrieves all users. 258 * 259 * @since 4.7.0 260 * 261 * @param WP_REST_Request $request Full details about the request. 262 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 263 */ 264 public function get_items( $request ) { 265 266 // Retrieve the list of registered collection query parameters. 267 $registered = $this->get_collection_params(); 268 269 /* 270 * This array defines mappings between public API query parameters whose 271 * values are accepted as-passed, and their internal WP_Query parameter 272 * name equivalents (some are the same). Only values which are also 273 * present in $registered will be set. 274 */ 275 $parameter_mappings = array( 276 'exclude' => 'exclude', 277 'include' => 'include', 278 'order' => 'order', 279 'per_page' => 'number', 280 'search' => 'search', 281 'roles' => 'role__in', 282 'capabilities' => 'capability__in', 283 'slug' => 'nicename__in', 284 ); 285 286 $prepared_args = array(); 287 288 /* 289 * For each known parameter which is both registered and present in the request, 290 * set the parameter's value on the query $prepared_args. 291 */ 292 foreach ( $parameter_mappings as $api_param => $wp_param ) { 293 if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { 294 $prepared_args[ $wp_param ] = $request[ $api_param ]; 295 } 296 } 297 298 if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) { 299 $prepared_args['offset'] = $request['offset']; 300 } else { 301 $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; 302 } 303 304 if ( isset( $registered['orderby'] ) ) { 305 $orderby_possibles = array( 306 'id' => 'ID', 307 'include' => 'include', 308 'name' => 'display_name', 309 'registered_date' => 'registered', 310 'slug' => 'user_nicename', 311 'include_slugs' => 'nicename__in', 312 'email' => 'user_email', 313 'url' => 'user_url', 314 ); 315 $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; 316 } 317 318 if ( isset( $registered['who'] ) && ! empty( $request['who'] ) && 'authors' === $request['who'] ) { 319 $prepared_args['who'] = 'authors'; 320 } elseif ( ! current_user_can( 'list_users' ) ) { 321 $prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' ); 322 } 323 324 if ( ! empty( $request['has_published_posts'] ) ) { 325 $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) 326 ? get_post_types( array( 'show_in_rest' => true ), 'names' ) 327 : (array) $request['has_published_posts']; 328 } 329 330 if ( ! empty( $prepared_args['search'] ) ) { 331 if ( ! current_user_can( 'list_users' ) ) { 332 $prepared_args['search_columns'] = array( 'ID', 'user_login', 'user_nicename', 'display_name' ); 333 } 334 $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; 335 } 336 /** 337 * Filters WP_User_Query arguments when querying users via the REST API. 338 * 339 * @link https://developer.wordpress.org/reference/classes/wp_user_query/ 340 * 341 * @since 4.7.0 342 * 343 * @param array $prepared_args Array of arguments for WP_User_Query. 344 * @param WP_REST_Request $request The REST API request. 345 */ 346 $prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request ); 347 348 $query = new WP_User_Query( $prepared_args ); 349 350 $users = array(); 351 352 foreach ( $query->get_results() as $user ) { 353 $data = $this->prepare_item_for_response( $user, $request ); 354 $users[] = $this->prepare_response_for_collection( $data ); 355 } 356 357 $response = rest_ensure_response( $users ); 358 359 // Store pagination values for headers then unset for count query. 360 $per_page = (int) $prepared_args['number']; 361 $page = (int) ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); 362 363 $prepared_args['fields'] = 'ID'; 364 365 $total_users = $query->get_total(); 366 367 if ( $total_users < 1 ) { 368 // Out-of-bounds, run the query again without LIMIT for total count. 369 unset( $prepared_args['number'], $prepared_args['offset'] ); 370 $count_query = new WP_User_Query( $prepared_args ); 371 $total_users = $count_query->get_total(); 372 } 373 374 $response->header( 'X-WP-Total', (int) $total_users ); 375 376 $max_pages = (int) ceil( $total_users / $per_page ); 377 378 $response->header( 'X-WP-TotalPages', $max_pages ); 379 380 $base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); 381 if ( $page > 1 ) { 382 $prev_page = $page - 1; 383 384 if ( $prev_page > $max_pages ) { 385 $prev_page = $max_pages; 386 } 387 388 $prev_link = add_query_arg( 'page', $prev_page, $base ); 389 $response->link_header( 'prev', $prev_link ); 390 } 391 if ( $max_pages > $page ) { 392 $next_page = $page + 1; 393 $next_link = add_query_arg( 'page', $next_page, $base ); 394 395 $response->link_header( 'next', $next_link ); 396 } 397 398 return $response; 399 } 400 401 /** 402 * Get the user, if the ID is valid. 403 * 404 * @since 4.7.2 405 * 406 * @param int $id Supplied ID. 407 * @return WP_User|WP_Error True if ID is valid, WP_Error otherwise. 408 */ 409 protected function get_user( $id ) { 410 $error = new WP_Error( 411 'rest_user_invalid_id', 412 __( 'Invalid user ID.' ), 413 array( 'status' => 404 ) 414 ); 415 416 if ( (int) $id <= 0 ) { 417 return $error; 418 } 419 420 $user = get_userdata( (int) $id ); 421 if ( empty( $user ) || ! $user->exists() ) { 422 return $error; 423 } 424 425 if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) { 426 return $error; 427 } 428 429 return $user; 430 } 431 432 /** 433 * Checks if a given request has access to read a user. 434 * 435 * @since 4.7.0 436 * 437 * @param WP_REST_Request $request Full details about the request. 438 * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. 439 */ 440 public function get_item_permissions_check( $request ) { 441 $user = $this->get_user( $request['id'] ); 442 if ( is_wp_error( $user ) ) { 443 return $user; 444 } 445 446 $types = get_post_types( array( 'show_in_rest' => true ), 'names' ); 447 448 if ( get_current_user_id() === $user->ID ) { 449 return true; 450 } 451 452 if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { 453 return new WP_Error( 454 'rest_user_cannot_view', 455 __( 'Sorry, you are not allowed to list users.' ), 456 array( 'status' => rest_authorization_required_code() ) 457 ); 458 } elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) { 459 return new WP_Error( 460 'rest_user_cannot_view', 461 __( 'Sorry, you are not allowed to list users.' ), 462 array( 'status' => rest_authorization_required_code() ) 463 ); 464 } 465 466 return true; 467 } 468 469 /** 470 * Retrieves a single user. 471 * 472 * @since 4.7.0 473 * 474 * @param WP_REST_Request $request Full details about the request. 475 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 476 */ 477 public function get_item( $request ) { 478 $user = $this->get_user( $request['id'] ); 479 if ( is_wp_error( $user ) ) { 480 return $user; 481 } 482 483 $user = $this->prepare_item_for_response( $user, $request ); 484 $response = rest_ensure_response( $user ); 485 486 return $response; 487 } 488 489 /** 490 * Retrieves the current user. 491 * 492 * @since 4.7.0 493 * 494 * @param WP_REST_Request $request Full details about the request. 495 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 496 */ 497 public function get_current_item( $request ) { 498 $current_user_id = get_current_user_id(); 499 500 if ( empty( $current_user_id ) ) { 501 return new WP_Error( 502 'rest_not_logged_in', 503 __( 'You are not currently logged in.' ), 504 array( 'status' => 401 ) 505 ); 506 } 507 508 $user = wp_get_current_user(); 509 $response = $this->prepare_item_for_response( $user, $request ); 510 $response = rest_ensure_response( $response ); 511 512 return $response; 513 } 514 515 /** 516 * Checks if a given request has access create users. 517 * 518 * @since 4.7.0 519 * 520 * @param WP_REST_Request $request Full details about the request. 521 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. 522 */ 523 public function create_item_permissions_check( $request ) { 524 525 if ( ! current_user_can( 'create_users' ) ) { 526 return new WP_Error( 527 'rest_cannot_create_user', 528 __( 'Sorry, you are not allowed to create new users.' ), 529 array( 'status' => rest_authorization_required_code() ) 530 ); 531 } 532 533 return true; 534 } 535 536 /** 537 * Creates a single user. 538 * 539 * @since 4.7.0 540 * 541 * @param WP_REST_Request $request Full details about the request. 542 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 543 */ 544 public function create_item( $request ) { 545 if ( ! empty( $request['id'] ) ) { 546 return new WP_Error( 547 'rest_user_exists', 548 __( 'Cannot create existing user.' ), 549 array( 'status' => 400 ) 550 ); 551 } 552 553 $schema = $this->get_item_schema(); 554 555 if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { 556 $check_permission = $this->check_role_update( $request['id'], $request['roles'] ); 557 558 if ( is_wp_error( $check_permission ) ) { 559 return $check_permission; 560 } 561 } 562 563 $user = $this->prepare_item_for_database( $request ); 564 565 if ( is_multisite() ) { 566 $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); 567 568 if ( is_wp_error( $ret['errors'] ) && $ret['errors']->has_errors() ) { 569 $error = new WP_Error( 570 'rest_invalid_param', 571 __( 'Invalid user parameter(s).' ), 572 array( 'status' => 400 ) 573 ); 574 575 foreach ( $ret['errors']->errors as $code => $messages ) { 576 foreach ( $messages as $message ) { 577 $error->add( $code, $message ); 578 } 579 580 $error_data = $error->get_error_data( $code ); 581 582 if ( $error_data ) { 583 $error->add_data( $error_data, $code ); 584 } 585 } 586 return $error; 587 } 588 } 589 590 if ( is_multisite() ) { 591 $user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email ); 592 593 if ( ! $user_id ) { 594 return new WP_Error( 595 'rest_user_create', 596 __( 'Error creating new user.' ), 597 array( 'status' => 500 ) 598 ); 599 } 600 601 $user->ID = $user_id; 602 $user_id = wp_update_user( wp_slash( (array) $user ) ); 603 604 if ( is_wp_error( $user_id ) ) { 605 return $user_id; 606 } 607 608 $result = add_user_to_blog( get_site()->id, $user_id, '' ); 609 if ( is_wp_error( $result ) ) { 610 return $result; 611 } 612 } else { 613 $user_id = wp_insert_user( wp_slash( (array) $user ) ); 614 615 if ( is_wp_error( $user_id ) ) { 616 return $user_id; 617 } 618 } 619 620 $user = get_user_by( 'id', $user_id ); 621 622 /** 623 * Fires immediately after a user is created or updated via the REST API. 624 * 625 * @since 4.7.0 626 * 627 * @param WP_User $user Inserted or updated user object. 628 * @param WP_REST_Request $request Request object. 629 * @param bool $creating True when creating a user, false when updating. 630 */ 631 do_action( 'rest_insert_user', $user, $request, true ); 632 633 if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { 634 array_map( array( $user, 'add_role' ), $request['roles'] ); 635 } 636 637 if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { 638 $meta_update = $this->meta->update_value( $request['meta'], $user_id ); 639 640 if ( is_wp_error( $meta_update ) ) { 641 return $meta_update; 642 } 643 } 644 645 $user = get_user_by( 'id', $user_id ); 646 $fields_update = $this->update_additional_fields_for_object( $user, $request ); 647 648 if ( is_wp_error( $fields_update ) ) { 649 return $fields_update; 650 } 651 652 $request->set_param( 'context', 'edit' ); 653 654 /** 655 * Fires after a user is completely created or updated via the REST API. 656 * 657 * @since 5.0.0 658 * 659 * @param WP_User $user Inserted or updated user object. 660 * @param WP_REST_Request $request Request object. 661 * @param bool $creating True when creating a user, false when updating. 662 */ 663 do_action( 'rest_after_insert_user', $user, $request, true ); 664 665 $response = $this->prepare_item_for_response( $user, $request ); 666 $response = rest_ensure_response( $response ); 667 668 $response->set_status( 201 ); 669 $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user_id ) ) ); 670 671 return $response; 672 } 673 674 /** 675 * Checks if a given request has access to update a user. 676 * 677 * @since 4.7.0 678 * 679 * @param WP_REST_Request $request Full details about the request. 680 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. 681 */ 682 public function update_item_permissions_check( $request ) { 683 $user = $this->get_user( $request['id'] ); 684 if ( is_wp_error( $user ) ) { 685 return $user; 686 } 687 688 if ( ! empty( $request['roles'] ) ) { 689 if ( ! current_user_can( 'promote_user', $user->ID ) ) { 690 return new WP_Error( 691 'rest_cannot_edit_roles', 692 __( 'Sorry, you are not allowed to edit roles of this user.' ), 693 array( 'status' => rest_authorization_required_code() ) 694 ); 695 } 696 697 $request_params = array_keys( $request->get_params() ); 698 sort( $request_params ); 699 /* 700 * If only 'id' and 'roles' are specified (we are only trying to 701 * edit roles), then only the 'promote_user' cap is required. 702 */ 703 if ( array( 'id', 'roles' ) === $request_params ) { 704 return true; 705 } 706 } 707 708 if ( ! current_user_can( 'edit_user', $user->ID ) ) { 709 return new WP_Error( 710 'rest_cannot_edit', 711 __( 'Sorry, you are not allowed to edit this user.' ), 712 array( 'status' => rest_authorization_required_code() ) 713 ); 714 } 715 716 return true; 717 } 718 719 /** 720 * Updates a single user. 721 * 722 * @since 4.7.0 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 public function update_item( $request ) { 728 $user = $this->get_user( $request['id'] ); 729 if ( is_wp_error( $user ) ) { 730 return $user; 731 } 732 733 $id = $user->ID; 734 735 $owner_id = false; 736 if ( is_string( $request['email'] ) ) { 737 $owner_id = email_exists( $request['email'] ); 738 } 739 740 if ( $owner_id && $owner_id !== $id ) { 741 return new WP_Error( 742 'rest_user_invalid_email', 743 __( 'Invalid email address.' ), 744 array( 'status' => 400 ) 745 ); 746 } 747 748 if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) { 749 return new WP_Error( 750 'rest_user_invalid_argument', 751 __( 'Username is not editable.' ), 752 array( 'status' => 400 ) 753 ); 754 } 755 756 if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) { 757 return new WP_Error( 758 'rest_user_invalid_slug', 759 __( 'Invalid slug.' ), 760 array( 'status' => 400 ) 761 ); 762 } 763 764 if ( ! empty( $request['roles'] ) ) { 765 $check_permission = $this->check_role_update( $id, $request['roles'] ); 766 767 if ( is_wp_error( $check_permission ) ) { 768 return $check_permission; 769 } 770 } 771 772 $user = $this->prepare_item_for_database( $request ); 773 774 // Ensure we're operating on the same user we already checked. 775 $user->ID = $id; 776 777 $user_id = wp_update_user( wp_slash( (array) $user ) ); 778 779 if ( is_wp_error( $user_id ) ) { 780 return $user_id; 781 } 782 783 $user = get_user_by( 'id', $user_id ); 784 785 /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ 786 do_action( 'rest_insert_user', $user, $request, false ); 787 788 if ( ! empty( $request['roles'] ) ) { 789 array_map( array( $user, 'add_role' ), $request['roles'] ); 790 } 791 792 $schema = $this->get_item_schema(); 793 794 if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { 795 $meta_update = $this->meta->update_value( $request['meta'], $id ); 796 797 if ( is_wp_error( $meta_update ) ) { 798 return $meta_update; 799 } 800 } 801 802 $user = get_user_by( 'id', $user_id ); 803 $fields_update = $this->update_additional_fields_for_object( $user, $request ); 804 805 if ( is_wp_error( $fields_update ) ) { 806 return $fields_update; 807 } 808 809 $request->set_param( 'context', 'edit' ); 810 811 /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ 812 do_action( 'rest_after_insert_user', $user, $request, false ); 813 814 $response = $this->prepare_item_for_response( $user, $request ); 815 $response = rest_ensure_response( $response ); 816 817 return $response; 818 } 819 820 /** 821 * Checks if a given request has access to update the current user. 822 * 823 * @since 4.7.0 824 * 825 * @param WP_REST_Request $request Full details about the request. 826 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. 827 */ 828 public function update_current_item_permissions_check( $request ) { 829 $request['id'] = get_current_user_id(); 830 831 return $this->update_item_permissions_check( $request ); 832 } 833 834 /** 835 * Updates the current user. 836 * 837 * @since 4.7.0 838 * 839 * @param WP_REST_Request $request Full details about the request. 840 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 841 */ 842 public function update_current_item( $request ) { 843 $request['id'] = get_current_user_id(); 844 845 return $this->update_item( $request ); 846 } 847 848 /** 849 * Checks if a given request has access delete a user. 850 * 851 * @since 4.7.0 852 * 853 * @param WP_REST_Request $request Full details about the request. 854 * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. 855 */ 856 public function delete_item_permissions_check( $request ) { 857 $user = $this->get_user( $request['id'] ); 858 if ( is_wp_error( $user ) ) { 859 return $user; 860 } 861 862 if ( ! current_user_can( 'delete_user', $user->ID ) ) { 863 return new WP_Error( 864 'rest_user_cannot_delete', 865 __( 'Sorry, you are not allowed to delete this user.' ), 866 array( 'status' => rest_authorization_required_code() ) 867 ); 868 } 869 870 return true; 871 } 872 873 /** 874 * Deletes a single user. 875 * 876 * @since 4.7.0 877 * 878 * @param WP_REST_Request $request Full details about the request. 879 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 880 */ 881 public function delete_item( $request ) { 882 // We don't support delete requests in multisite. 883 if ( is_multisite() ) { 884 return new WP_Error( 885 'rest_cannot_delete', 886 __( 'The user cannot be deleted.' ), 887 array( 'status' => 501 ) 888 ); 889 } 890 891 $user = $this->get_user( $request['id'] ); 892 893 if ( is_wp_error( $user ) ) { 894 return $user; 895 } 896 897 $id = $user->ID; 898 $reassign = false === $request['reassign'] ? null : absint( $request['reassign'] ); 899 $force = isset( $request['force'] ) ? (bool) $request['force'] : false; 900 901 // We don't support trashing for users. 902 if ( ! $force ) { 903 return new WP_Error( 904 'rest_trash_not_supported', 905 /* translators: %s: force=true */ 906 sprintf( __( "Users do not support trashing. Set '%s' to delete." ), 'force=true' ), 907 array( 'status' => 501 ) 908 ); 909 } 910 911 if ( ! empty( $reassign ) ) { 912 if ( $reassign === $id || ! get_userdata( $reassign ) ) { 913 return new WP_Error( 914 'rest_user_invalid_reassign', 915 __( 'Invalid user ID for reassignment.' ), 916 array( 'status' => 400 ) 917 ); 918 } 919 } 920 921 $request->set_param( 'context', 'edit' ); 922 923 $previous = $this->prepare_item_for_response( $user, $request ); 924 925 // Include user admin functions to get access to wp_delete_user(). 926 require_once ABSPATH . 'wp-admin/includes/user.php'; 927 928 $result = wp_delete_user( $id, $reassign ); 929 930 if ( ! $result ) { 931 return new WP_Error( 932 'rest_cannot_delete', 933 __( 'The user cannot be deleted.' ), 934 array( 'status' => 500 ) 935 ); 936 } 937 938 $response = new WP_REST_Response(); 939 $response->set_data( 940 array( 941 'deleted' => true, 942 'previous' => $previous->get_data(), 943 ) 944 ); 945 946 /** 947 * Fires immediately after a user is deleted via the REST API. 948 * 949 * @since 4.7.0 950 * 951 * @param WP_User $user The user data. 952 * @param WP_REST_Response $response The response returned from the API. 953 * @param WP_REST_Request $request The request sent to the API. 954 */ 955 do_action( 'rest_delete_user', $user, $response, $request ); 956 957 return $response; 958 } 959 960 /** 961 * Checks if a given request has access to delete the current user. 962 * 963 * @since 4.7.0 964 * 965 * @param WP_REST_Request $request Full details about the request. 966 * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. 967 */ 968 public function delete_current_item_permissions_check( $request ) { 969 $request['id'] = get_current_user_id(); 970 971 return $this->delete_item_permissions_check( $request ); 972 } 973 974 /** 975 * Deletes the current user. 976 * 977 * @since 4.7.0 978 * 979 * @param WP_REST_Request $request Full details about the request. 980 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 981 */ 982 public function delete_current_item( $request ) { 983 $request['id'] = get_current_user_id(); 984 985 return $this->delete_item( $request ); 986 } 987 988 /** 989 * Prepares a single user output for response. 990 * 991 * @since 4.7.0 992 * @since 5.9.0 Renamed `$user` to `$item` to match parent class for PHP 8 named parameter support. 993 * 994 * @param WP_User $item User object. 995 * @param WP_REST_Request $request Request object. 996 * @return WP_REST_Response Response object. 997 */ 998 public function prepare_item_for_response( $item, $request ) { 999 // Restores the more descriptive, specific name for use within this method. 1000 $user = $item; 1001 1002 $fields = $this->get_fields_for_response( $request ); 1003 $data = array(); 1004 1005 if ( in_array( 'id', $fields, true ) ) { 1006 $data['id'] = $user->ID; 1007 } 1008 1009 if ( in_array( 'username', $fields, true ) ) { 1010 $data['username'] = $user->user_login; 1011 } 1012 1013 if ( in_array( 'name', $fields, true ) ) { 1014 $data['name'] = $user->display_name; 1015 } 1016 1017 if ( in_array( 'first_name', $fields, true ) ) { 1018 $data['first_name'] = $user->first_name; 1019 } 1020 1021 if ( in_array( 'last_name', $fields, true ) ) { 1022 $data['last_name'] = $user->last_name; 1023 } 1024 1025 if ( in_array( 'email', $fields, true ) ) { 1026 $data['email'] = $user->user_email; 1027 } 1028 1029 if ( in_array( 'url', $fields, true ) ) { 1030 $data['url'] = $user->user_url; 1031 } 1032 1033 if ( in_array( 'description', $fields, true ) ) { 1034 $data['description'] = $user->description; 1035 } 1036 1037 if ( in_array( 'link', $fields, true ) ) { 1038 $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename ); 1039 } 1040 1041 if ( in_array( 'locale', $fields, true ) ) { 1042 $data['locale'] = get_user_locale( $user ); 1043 } 1044 1045 if ( in_array( 'nickname', $fields, true ) ) { 1046 $data['nickname'] = $user->nickname; 1047 } 1048 1049 if ( in_array( 'slug', $fields, true ) ) { 1050 $data['slug'] = $user->user_nicename; 1051 } 1052 1053 if ( in_array( 'roles', $fields, true ) ) { 1054 // Defensively call array_values() to ensure an array is returned. 1055 $data['roles'] = array_values( $user->roles ); 1056 } 1057 1058 if ( in_array( 'registered_date', $fields, true ) ) { 1059 $data['registered_date'] = gmdate( 'c', strtotime( $user->user_registered ) ); 1060 } 1061 1062 if ( in_array( 'capabilities', $fields, true ) ) { 1063 $data['capabilities'] = (object) $user->allcaps; 1064 } 1065 1066 if ( in_array( 'extra_capabilities', $fields, true ) ) { 1067 $data['extra_capabilities'] = (object) $user->caps; 1068 } 1069 1070 if ( in_array( 'avatar_urls', $fields, true ) ) { 1071 $data['avatar_urls'] = rest_get_avatar_urls( $user ); 1072 } 1073 1074 if ( in_array( 'meta', $fields, true ) ) { 1075 $data['meta'] = $this->meta->get_value( $user->ID, $request ); 1076 } 1077 1078 $context = ! empty( $request['context'] ) ? $request['context'] : 'embed'; 1079 1080 $data = $this->add_additional_fields_to_object( $data, $request ); 1081 $data = $this->filter_response_by_context( $data, $context ); 1082 1083 // Wrap the data in a response object. 1084 $response = rest_ensure_response( $data ); 1085 1086 if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { 1087 $response->add_links( $this->prepare_links( $user ) ); 1088 } 1089 1090 /** 1091 * Filters user data returned from the REST API. 1092 * 1093 * @since 4.7.0 1094 * 1095 * @param WP_REST_Response $response The response object. 1096 * @param WP_User $user User object used to create response. 1097 * @param WP_REST_Request $request Request object. 1098 */ 1099 return apply_filters( 'rest_prepare_user', $response, $user, $request ); 1100 } 1101 1102 /** 1103 * Prepares links for the user request. 1104 * 1105 * @since 4.7.0 1106 * 1107 * @param WP_User $user User object. 1108 * @return array Links for the given user. 1109 */ 1110 protected function prepare_links( $user ) { 1111 $links = array( 1112 'self' => array( 1113 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ), 1114 ), 1115 'collection' => array( 1116 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), 1117 ), 1118 ); 1119 1120 return $links; 1121 } 1122 1123 /** 1124 * Prepares a single user for creation or update. 1125 * 1126 * @since 4.7.0 1127 * 1128 * @param WP_REST_Request $request Request object. 1129 * @return object User object. 1130 */ 1131 protected function prepare_item_for_database( $request ) { 1132 $prepared_user = new stdClass(); 1133 1134 $schema = $this->get_item_schema(); 1135 1136 // Required arguments. 1137 if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) { 1138 $prepared_user->user_email = $request['email']; 1139 } 1140 1141 if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) { 1142 $prepared_user->user_login = $request['username']; 1143 } 1144 1145 if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) { 1146 $prepared_user->user_pass = $request['password']; 1147 } 1148 1149 // Optional arguments. 1150 if ( isset( $request['id'] ) ) { 1151 $prepared_user->ID = absint( $request['id'] ); 1152 } 1153 1154 if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { 1155 $prepared_user->display_name = $request['name']; 1156 } 1157 1158 if ( isset( $request['first_name'] ) && ! empty( $schema['properties']['first_name'] ) ) { 1159 $prepared_user->first_name = $request['first_name']; 1160 } 1161 1162 if ( isset( $request['last_name'] ) && ! empty( $schema['properties']['last_name'] ) ) { 1163 $prepared_user->last_name = $request['last_name']; 1164 } 1165 1166 if ( isset( $request['nickname'] ) && ! empty( $schema['properties']['nickname'] ) ) { 1167 $prepared_user->nickname = $request['nickname']; 1168 } 1169 1170 if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) { 1171 $prepared_user->user_nicename = $request['slug']; 1172 } 1173 1174 if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) { 1175 $prepared_user->description = $request['description']; 1176 } 1177 1178 if ( isset( $request['url'] ) && ! empty( $schema['properties']['url'] ) ) { 1179 $prepared_user->user_url = $request['url']; 1180 } 1181 1182 if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) { 1183 $prepared_user->locale = $request['locale']; 1184 } 1185 1186 // Setting roles will be handled outside of this function. 1187 if ( isset( $request['roles'] ) ) { 1188 $prepared_user->role = false; 1189 } 1190 1191 /** 1192 * Filters user data before insertion via the REST API. 1193 * 1194 * @since 4.7.0 1195 * 1196 * @param object $prepared_user User object. 1197 * @param WP_REST_Request $request Request object. 1198 */ 1199 return apply_filters( 'rest_pre_insert_user', $prepared_user, $request ); 1200 } 1201 1202 /** 1203 * Determines if the current user is allowed to make the desired roles change. 1204 * 1205 * @since 4.7.0 1206 * 1207 * @global WP_Roles $wp_roles WordPress role management object. 1208 * 1209 * @param int $user_id User ID. 1210 * @param array $roles New user roles. 1211 * @return true|WP_Error True if the current user is allowed to make the role change, 1212 * otherwise a WP_Error object. 1213 */ 1214 protected function check_role_update( $user_id, $roles ) { 1215 global $wp_roles; 1216 1217 foreach ( $roles as $role ) { 1218 1219 if ( ! isset( $wp_roles->role_objects[ $role ] ) ) { 1220 return new WP_Error( 1221 'rest_user_invalid_role', 1222 /* translators: %s: Role key. */ 1223 sprintf( __( 'The role %s does not exist.' ), $role ), 1224 array( 'status' => 400 ) 1225 ); 1226 } 1227 1228 $potential_role = $wp_roles->role_objects[ $role ]; 1229 1230 /* 1231 * Don't let anyone with 'edit_users' (admins) edit their own role to something without it. 1232 * Multisite super admins can freely edit their blog roles -- they possess all caps. 1233 */ 1234 if ( ! ( is_multisite() 1235 && current_user_can( 'manage_sites' ) ) 1236 && get_current_user_id() === $user_id 1237 && ! $potential_role->has_cap( 'edit_users' ) 1238 ) { 1239 return new WP_Error( 1240 'rest_user_invalid_role', 1241 __( 'Sorry, you are not allowed to give users that role.' ), 1242 array( 'status' => rest_authorization_required_code() ) 1243 ); 1244 } 1245 1246 // Include user admin functions to get access to get_editable_roles(). 1247 require_once ABSPATH . 'wp-admin/includes/user.php'; 1248 1249 // The new role must be editable by the logged-in user. 1250 $editable_roles = get_editable_roles(); 1251 1252 if ( empty( $editable_roles[ $role ] ) ) { 1253 return new WP_Error( 1254 'rest_user_invalid_role', 1255 __( 'Sorry, you are not allowed to give users that role.' ), 1256 array( 'status' => 403 ) 1257 ); 1258 } 1259 } 1260 1261 return true; 1262 } 1263 1264 /** 1265 * Check a username for the REST API. 1266 * 1267 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php. 1268 * 1269 * @since 4.7.0 1270 * 1271 * @param string $value The username submitted in the request. 1272 * @param WP_REST_Request $request Full details about the request. 1273 * @param string $param The parameter name. 1274 * @return string|WP_Error The sanitized username, if valid, otherwise an error. 1275 */ 1276 public function check_username( $value, $request, $param ) { 1277 $username = (string) $value; 1278 1279 if ( ! validate_username( $username ) ) { 1280 return new WP_Error( 1281 'rest_user_invalid_username', 1282 __( 'This username is invalid because it uses illegal characters. Please enter a valid username.' ), 1283 array( 'status' => 400 ) 1284 ); 1285 } 1286 1287 /** This filter is documented in wp-includes/user.php */ 1288 $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); 1289 1290 if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) { 1291 return new WP_Error( 1292 'rest_user_invalid_username', 1293 __( 'Sorry, that username is not allowed.' ), 1294 array( 'status' => 400 ) 1295 ); 1296 } 1297 1298 return $username; 1299 } 1300 1301 /** 1302 * Check a user password for the REST API. 1303 * 1304 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php. 1305 * 1306 * @since 4.7.0 1307 * 1308 * @param string $value The password submitted in the request. 1309 * @param WP_REST_Request $request Full details about the request. 1310 * @param string $param The parameter name. 1311 * @return string|WP_Error The sanitized password, if valid, otherwise an error. 1312 */ 1313 public function check_user_password( $value, $request, $param ) { 1314 $password = (string) $value; 1315 1316 if ( empty( $password ) ) { 1317 return new WP_Error( 1318 'rest_user_invalid_password', 1319 __( 'Passwords cannot be empty.' ), 1320 array( 'status' => 400 ) 1321 ); 1322 } 1323 1324 if ( str_contains( $password, '\\' ) ) { 1325 return new WP_Error( 1326 'rest_user_invalid_password', 1327 sprintf( 1328 /* translators: %s: The '\' character. */ 1329 __( 'Passwords cannot contain the "%s" character.' ), 1330 '\\' 1331 ), 1332 array( 'status' => 400 ) 1333 ); 1334 } 1335 1336 return $password; 1337 } 1338 1339 /** 1340 * Retrieves the user's schema, conforming to JSON Schema. 1341 * 1342 * @since 4.7.0 1343 * 1344 * @return array Item schema data. 1345 */ 1346 public function get_item_schema() { 1347 if ( $this->schema ) { 1348 return $this->add_additional_fields_schema( $this->schema ); 1349 } 1350 1351 $schema = array( 1352 '$schema' => 'http://json-schema.org/draft-04/schema#', 1353 'title' => 'user', 1354 'type' => 'object', 1355 'properties' => array( 1356 'id' => array( 1357 'description' => __( 'Unique identifier for the user.' ), 1358 'type' => 'integer', 1359 'context' => array( 'embed', 'view', 'edit' ), 1360 'readonly' => true, 1361 ), 1362 'username' => array( 1363 'description' => __( 'Login name for the user.' ), 1364 'type' => 'string', 1365 'context' => array( 'edit' ), 1366 'required' => true, 1367 'arg_options' => array( 1368 'sanitize_callback' => array( $this, 'check_username' ), 1369 ), 1370 ), 1371 'name' => array( 1372 'description' => __( 'Display name for the user.' ), 1373 'type' => 'string', 1374 'context' => array( 'embed', 'view', 'edit' ), 1375 'arg_options' => array( 1376 'sanitize_callback' => 'sanitize_text_field', 1377 ), 1378 ), 1379 'first_name' => array( 1380 'description' => __( 'First name for the user.' ), 1381 'type' => 'string', 1382 'context' => array( 'edit' ), 1383 'arg_options' => array( 1384 'sanitize_callback' => 'sanitize_text_field', 1385 ), 1386 ), 1387 'last_name' => array( 1388 'description' => __( 'Last name for the user.' ), 1389 'type' => 'string', 1390 'context' => array( 'edit' ), 1391 'arg_options' => array( 1392 'sanitize_callback' => 'sanitize_text_field', 1393 ), 1394 ), 1395 'email' => array( 1396 'description' => __( 'The email address for the user.' ), 1397 'type' => 'string', 1398 'format' => 'email', 1399 'context' => array( 'edit' ), 1400 'required' => true, 1401 ), 1402 'url' => array( 1403 'description' => __( 'URL of the user.' ), 1404 'type' => 'string', 1405 'format' => 'uri', 1406 'context' => array( 'embed', 'view', 'edit' ), 1407 ), 1408 'description' => array( 1409 'description' => __( 'Description of the user.' ), 1410 'type' => 'string', 1411 'context' => array( 'embed', 'view', 'edit' ), 1412 ), 1413 'link' => array( 1414 'description' => __( 'Author URL of the user.' ), 1415 'type' => 'string', 1416 'format' => 'uri', 1417 'context' => array( 'embed', 'view', 'edit' ), 1418 'readonly' => true, 1419 ), 1420 'locale' => array( 1421 'description' => __( 'Locale for the user.' ), 1422 'type' => 'string', 1423 'enum' => array_merge( array( '', 'en_US' ), get_available_languages() ), 1424 'context' => array( 'edit' ), 1425 ), 1426 'nickname' => array( 1427 'description' => __( 'The nickname for the user.' ), 1428 'type' => 'string', 1429 'context' => array( 'edit' ), 1430 'arg_options' => array( 1431 'sanitize_callback' => 'sanitize_text_field', 1432 ), 1433 ), 1434 'slug' => array( 1435 'description' => __( 'An alphanumeric identifier for the user.' ), 1436 'type' => 'string', 1437 'context' => array( 'embed', 'view', 'edit' ), 1438 'arg_options' => array( 1439 'sanitize_callback' => array( $this, 'sanitize_slug' ), 1440 ), 1441 ), 1442 'registered_date' => array( 1443 'description' => __( 'Registration date for the user.' ), 1444 'type' => 'string', 1445 'format' => 'date-time', 1446 'context' => array( 'edit' ), 1447 'readonly' => true, 1448 ), 1449 'roles' => array( 1450 'description' => __( 'Roles assigned to the user.' ), 1451 'type' => 'array', 1452 'items' => array( 1453 'type' => 'string', 1454 ), 1455 'context' => array( 'edit' ), 1456 ), 1457 'password' => array( 1458 'description' => __( 'Password for the user (never included).' ), 1459 'type' => 'string', 1460 'context' => array(), // Password is never displayed. 1461 'required' => true, 1462 'arg_options' => array( 1463 'sanitize_callback' => array( $this, 'check_user_password' ), 1464 ), 1465 ), 1466 'capabilities' => array( 1467 'description' => __( 'All capabilities assigned to the user.' ), 1468 'type' => 'object', 1469 'context' => array( 'edit' ), 1470 'readonly' => true, 1471 ), 1472 'extra_capabilities' => array( 1473 'description' => __( 'Any extra capabilities assigned to the user.' ), 1474 'type' => 'object', 1475 'context' => array( 'edit' ), 1476 'readonly' => true, 1477 ), 1478 ), 1479 ); 1480 1481 if ( get_option( 'show_avatars' ) ) { 1482 $avatar_properties = array(); 1483 1484 $avatar_sizes = rest_get_avatar_sizes(); 1485 1486 foreach ( $avatar_sizes as $size ) { 1487 $avatar_properties[ $size ] = array( 1488 /* translators: %d: Avatar image size in pixels. */ 1489 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ), 1490 'type' => 'string', 1491 'format' => 'uri', 1492 'context' => array( 'embed', 'view', 'edit' ), 1493 ); 1494 } 1495 1496 $schema['properties']['avatar_urls'] = array( 1497 'description' => __( 'Avatar URLs for the user.' ), 1498 'type' => 'object', 1499 'context' => array( 'embed', 'view', 'edit' ), 1500 'readonly' => true, 1501 'properties' => $avatar_properties, 1502 ); 1503 } 1504 1505 $schema['properties']['meta'] = $this->meta->get_field_schema(); 1506 1507 $this->schema = $schema; 1508 1509 return $this->add_additional_fields_schema( $this->schema ); 1510 } 1511 1512 /** 1513 * Retrieves the query params for collections. 1514 * 1515 * @since 4.7.0 1516 * 1517 * @return array Collection parameters. 1518 */ 1519 public function get_collection_params() { 1520 $query_params = parent::get_collection_params(); 1521 1522 $query_params['context']['default'] = 'view'; 1523 1524 $query_params['exclude'] = array( 1525 'description' => __( 'Ensure result set excludes specific IDs.' ), 1526 'type' => 'array', 1527 'items' => array( 1528 'type' => 'integer', 1529 ), 1530 'default' => array(), 1531 ); 1532 1533 $query_params['include'] = array( 1534 'description' => __( 'Limit result set to specific IDs.' ), 1535 'type' => 'array', 1536 'items' => array( 1537 'type' => 'integer', 1538 ), 1539 'default' => array(), 1540 ); 1541 1542 $query_params['offset'] = array( 1543 'description' => __( 'Offset the result set by a specific number of items.' ), 1544 'type' => 'integer', 1545 ); 1546 1547 $query_params['order'] = array( 1548 'default' => 'asc', 1549 'description' => __( 'Order sort attribute ascending or descending.' ), 1550 'enum' => array( 'asc', 'desc' ), 1551 'type' => 'string', 1552 ); 1553 1554 $query_params['orderby'] = array( 1555 'default' => 'name', 1556 'description' => __( 'Sort collection by user attribute.' ), 1557 'enum' => array( 1558 'id', 1559 'include', 1560 'name', 1561 'registered_date', 1562 'slug', 1563 'include_slugs', 1564 'email', 1565 'url', 1566 ), 1567 'type' => 'string', 1568 ); 1569 1570 $query_params['slug'] = array( 1571 'description' => __( 'Limit result set to users with one or more specific slugs.' ), 1572 'type' => 'array', 1573 'items' => array( 1574 'type' => 'string', 1575 ), 1576 ); 1577 1578 $query_params['roles'] = array( 1579 'description' => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ), 1580 'type' => 'array', 1581 'items' => array( 1582 'type' => 'string', 1583 ), 1584 ); 1585 1586 $query_params['capabilities'] = array( 1587 'description' => __( 'Limit result set to users matching at least one specific capability provided. Accepts csv list or single capability.' ), 1588 'type' => 'array', 1589 'items' => array( 1590 'type' => 'string', 1591 ), 1592 ); 1593 1594 $query_params['who'] = array( 1595 'description' => __( 'Limit result set to users who are considered authors.' ), 1596 'type' => 'string', 1597 'enum' => array( 1598 'authors', 1599 ), 1600 ); 1601 1602 $query_params['has_published_posts'] = array( 1603 'description' => __( 'Limit result set to users who have published posts.' ), 1604 'type' => array( 'boolean', 'array' ), 1605 'items' => array( 1606 'type' => 'string', 1607 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), 1608 ), 1609 ); 1610 1611 /** 1612 * Filters REST API collection parameters for the users controller. 1613 * 1614 * This filter registers the collection parameter, but does not map the 1615 * collection parameter to an internal WP_User_Query parameter. Use the 1616 * `rest_user_query` filter to set WP_User_Query arguments. 1617 * 1618 * @since 4.7.0 1619 * 1620 * @param array $query_params JSON Schema-formatted collection parameters. 1621 */ 1622 return apply_filters( 'rest_user_collection_params', $query_params ); 1623 } 1624 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |