wp/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    43 	 *
    43 	 *
    44 	 * @see register_rest_route()
    44 	 * @see register_rest_route()
    45 	 */
    45 	 */
    46 	public function register_routes() {
    46 	public function register_routes() {
    47 
    47 
    48 		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
    48 		register_rest_route(
       
    49 			$this->namespace,
       
    50 			'/' . $this->rest_base,
    49 			array(
    51 			array(
    50 				'methods'             => WP_REST_Server::READABLE,
    52 				array(
    51 				'callback'            => array( $this, 'get_items' ),
    53 					'methods'             => WP_REST_Server::READABLE,
    52 				'permission_callback' => array( $this, 'get_items_permissions_check' ),
    54 					'callback'            => array( $this, 'get_items' ),
    53 				'args'                => $this->get_collection_params(),
    55 					'permission_callback' => array( $this, 'get_items_permissions_check' ),
    54 			),
    56 					'args'                => $this->get_collection_params(),
       
    57 				),
       
    58 				array(
       
    59 					'methods'             => WP_REST_Server::CREATABLE,
       
    60 					'callback'            => array( $this, 'create_item' ),
       
    61 					'permission_callback' => array( $this, 'create_item_permissions_check' ),
       
    62 					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
       
    63 				),
       
    64 				'schema' => array( $this, 'get_public_item_schema' ),
       
    65 			)
       
    66 		);
       
    67 
       
    68 		register_rest_route(
       
    69 			$this->namespace,
       
    70 			'/' . $this->rest_base . '/(?P<id>[\d]+)',
    55 			array(
    71 			array(
    56 				'methods'             => WP_REST_Server::CREATABLE,
    72 				'args'   => array(
    57 				'callback'            => array( $this, 'create_item' ),
    73 					'id' => array(
    58 				'permission_callback' => array( $this, 'create_item_permissions_check' ),
    74 						'description' => __( 'Unique identifier for the user.' ),
    59 				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
    75 						'type'        => 'integer',
    60 			),
    76 					),
    61 			'schema' => array( $this, 'get_public_item_schema' ),
    77 				),
    62 		) );
    78 				array(
    63 
    79 					'methods'             => WP_REST_Server::READABLE,
    64 		register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
    80 					'callback'            => array( $this, 'get_item' ),
    65 			'args' => array(
    81 					'permission_callback' => array( $this, 'get_item_permissions_check' ),
    66 				'id' => array(
    82 					'args'                => array(
    67 					'description' => __( 'Unique identifier for the user.' ),
    83 						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
    68 					'type'        => 'integer',
    84 					),
    69 				),
    85 				),
    70 			),
    86 				array(
       
    87 					'methods'             => WP_REST_Server::EDITABLE,
       
    88 					'callback'            => array( $this, 'update_item' ),
       
    89 					'permission_callback' => array( $this, 'update_item_permissions_check' ),
       
    90 					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
       
    91 				),
       
    92 				array(
       
    93 					'methods'             => WP_REST_Server::DELETABLE,
       
    94 					'callback'            => array( $this, 'delete_item' ),
       
    95 					'permission_callback' => array( $this, 'delete_item_permissions_check' ),
       
    96 					'args'                => array(
       
    97 						'force'    => array(
       
    98 							'type'        => 'boolean',
       
    99 							'default'     => false,
       
   100 							'description' => __( 'Required to be true, as users do not support trashing.' ),
       
   101 						),
       
   102 						'reassign' => array(
       
   103 							'type'              => 'integer',
       
   104 							'description'       => __( 'Reassign the deleted user\'s posts and links to this user ID.' ),
       
   105 							'required'          => true,
       
   106 							'sanitize_callback' => array( $this, 'check_reassign' ),
       
   107 						),
       
   108 					),
       
   109 				),
       
   110 				'schema' => array( $this, 'get_public_item_schema' ),
       
   111 			)
       
   112 		);
       
   113 
       
   114 		register_rest_route(
       
   115 			$this->namespace,
       
   116 			'/' . $this->rest_base . '/me',
    71 			array(
   117 			array(
    72 				'methods'             => WP_REST_Server::READABLE,
   118 				array(
    73 				'callback'            => array( $this, 'get_item' ),
   119 					'methods'  => WP_REST_Server::READABLE,
    74 				'permission_callback' => array( $this, 'get_item_permissions_check' ),
   120 					'callback' => array( $this, 'get_current_item' ),
    75 				'args'                => array(
   121 					'args'     => array(
    76 					'context' => $this->get_context_param( array( 'default' => 'view' ) ),
   122 						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
    77 				),
       
    78 			),
       
    79 			array(
       
    80 				'methods'             => WP_REST_Server::EDITABLE,
       
    81 				'callback'            => array( $this, 'update_item' ),
       
    82 				'permission_callback' => array( $this, 'update_item_permissions_check' ),
       
    83 				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
       
    84 			),
       
    85 			array(
       
    86 				'methods'             => WP_REST_Server::DELETABLE,
       
    87 				'callback'            => array( $this, 'delete_item' ),
       
    88 				'permission_callback' => array( $this, 'delete_item_permissions_check' ),
       
    89 				'args'                => array(
       
    90 					'force'    => array(
       
    91 						'type'        => 'boolean',
       
    92 						'default'     => false,
       
    93 						'description' => __( 'Required to be true, as users do not support trashing.' ),
       
    94 					),
   123 					),
    95 					'reassign' => array(
   124 				),
    96 						'type'        => 'integer',
   125 				array(
    97 						'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ),
   126 					'methods'             => WP_REST_Server::EDITABLE,
    98 						'required'    => true,
   127 					'callback'            => array( $this, 'update_current_item' ),
    99 						'sanitize_callback' => array( $this, 'check_reassign' ),
   128 					'permission_callback' => array( $this, 'update_current_item_permissions_check' ),
       
   129 					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
       
   130 				),
       
   131 				array(
       
   132 					'methods'             => WP_REST_Server::DELETABLE,
       
   133 					'callback'            => array( $this, 'delete_current_item' ),
       
   134 					'permission_callback' => array( $this, 'delete_current_item_permissions_check' ),
       
   135 					'args'                => array(
       
   136 						'force'    => array(
       
   137 							'type'        => 'boolean',
       
   138 							'default'     => false,
       
   139 							'description' => __( 'Required to be true, as users do not support trashing.' ),
       
   140 						),
       
   141 						'reassign' => array(
       
   142 							'type'              => 'integer',
       
   143 							'description'       => __( 'Reassign the deleted user\'s posts and links to this user ID.' ),
       
   144 							'required'          => true,
       
   145 							'sanitize_callback' => array( $this, 'check_reassign' ),
       
   146 						),
   100 					),
   147 					),
   101 				),
   148 				),
   102 			),
   149 				'schema' => array( $this, 'get_public_item_schema' ),
   103 			'schema' => array( $this, 'get_public_item_schema' ),
   150 			)
   104 		) );
   151 		);
   105 
       
   106 		register_rest_route( $this->namespace, '/' . $this->rest_base . '/me', array(
       
   107 			array(
       
   108 				'methods'             => WP_REST_Server::READABLE,
       
   109 				'callback'            => array( $this, 'get_current_item' ),
       
   110 				'args'                => array(
       
   111 					'context' => $this->get_context_param( array( 'default' => 'view' ) ),
       
   112 				),
       
   113 			),
       
   114 			array(
       
   115 				'methods'             => WP_REST_Server::EDITABLE,
       
   116 				'callback'            => array( $this, 'update_current_item' ),
       
   117 				'permission_callback' => array( $this, 'update_current_item_permissions_check' ),
       
   118 				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
       
   119 			),
       
   120 			array(
       
   121 				'methods'             => WP_REST_Server::DELETABLE,
       
   122 				'callback'            => array( $this, 'delete_current_item' ),
       
   123 				'permission_callback' => array( $this, 'delete_current_item_permissions_check' ),
       
   124 				'args'                => array(
       
   125 					'force'    => array(
       
   126 						'type'        => 'boolean',
       
   127 						'default'     => false,
       
   128 						'description' => __( 'Required to be true, as users do not support trashing.' ),
       
   129 					),
       
   130 					'reassign' => array(
       
   131 						'type'        => 'integer',
       
   132 						'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ),
       
   133 						'required'    => true,
       
   134 						'sanitize_callback' => array( $this, 'check_reassign' ),
       
   135 					),
       
   136 				),
       
   137 			),
       
   138 			'schema' => array( $this, 'get_public_item_schema' ),
       
   139 		));
       
   140 	}
   152 	}
   141 
   153 
   142 	/**
   154 	/**
   143 	 * Checks for a valid value for the reassign parameter when deleting users.
   155 	 * Checks for a valid value for the reassign parameter when deleting users.
   144 	 *
   156 	 *
   186 			return new WP_Error( 'rest_forbidden_orderby', __( 'Sorry, you are not allowed to order users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) );
   198 			return new WP_Error( 'rest_forbidden_orderby', __( 'Sorry, you are not allowed to order users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) );
   187 		}
   199 		}
   188 
   200 
   189 		if ( 'authors' === $request['who'] ) {
   201 		if ( 'authors' === $request['who'] ) {
   190 			$can_view = false;
   202 			$can_view = false;
   191 			$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
   203 			$types    = get_post_types( array( 'show_in_rest' => true ), 'objects' );
   192 			foreach ( $types as $type ) {
   204 			foreach ( $types as $type ) {
   193 				if ( post_type_supports( $type->name, 'author' )
   205 				if ( post_type_supports( $type->name, 'author' )
   194 					&& current_user_can( $type->cap->edit_posts ) ) {
   206 					&& current_user_can( $type->cap->edit_posts ) ) {
   195 					$can_view = true;
   207 					$can_view = true;
   196 				}
   208 				}
   245 		}
   257 		}
   246 
   258 
   247 		if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) {
   259 		if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) {
   248 			$prepared_args['offset'] = $request['offset'];
   260 			$prepared_args['offset'] = $request['offset'];
   249 		} else {
   261 		} else {
   250 			$prepared_args['offset']  = ( $request['page'] - 1 ) * $prepared_args['number'];
   262 			$prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
   251 		}
   263 		}
   252 
   264 
   253 		if ( isset( $registered['orderby'] ) ) {
   265 		if ( isset( $registered['orderby'] ) ) {
   254 			$orderby_possibles = array(
   266 			$orderby_possibles        = array(
   255 				'id'              => 'ID',
   267 				'id'              => 'ID',
   256 				'include'         => 'include',
   268 				'include'         => 'include',
   257 				'name'            => 'display_name',
   269 				'name'            => 'display_name',
   258 				'registered_date' => 'registered',
   270 				'registered_date' => 'registered',
   259 				'slug'            => 'user_nicename',
   271 				'slug'            => 'user_nicename',
   288 		$query = new WP_User_Query( $prepared_args );
   300 		$query = new WP_User_Query( $prepared_args );
   289 
   301 
   290 		$users = array();
   302 		$users = array();
   291 
   303 
   292 		foreach ( $query->results as $user ) {
   304 		foreach ( $query->results as $user ) {
   293 			$data = $this->prepare_item_for_response( $user, $request );
   305 			$data    = $this->prepare_item_for_response( $user, $request );
   294 			$users[] = $this->prepare_response_for_collection( $data );
   306 			$users[] = $this->prepare_response_for_collection( $data );
   295 		}
   307 		}
   296 
   308 
   297 		$response = rest_ensure_response( $users );
   309 		$response = rest_ensure_response( $users );
   298 
   310 
   315 
   327 
   316 		$max_pages = ceil( $total_users / $per_page );
   328 		$max_pages = ceil( $total_users / $per_page );
   317 
   329 
   318 		$response->header( 'X-WP-TotalPages', (int) $max_pages );
   330 		$response->header( 'X-WP-TotalPages', (int) $max_pages );
   319 
   331 
   320 		$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) );
   332 		$base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) );
   321 		if ( $page > 1 ) {
   333 		if ( $page > 1 ) {
   322 			$prev_page = $page - 1;
   334 			$prev_page = $page - 1;
   323 
   335 
   324 			if ( $prev_page > $max_pages ) {
   336 			if ( $prev_page > $max_pages ) {
   325 				$prev_page = $max_pages;
   337 				$prev_page = $max_pages;
   405 		$user = $this->get_user( $request['id'] );
   417 		$user = $this->get_user( $request['id'] );
   406 		if ( is_wp_error( $user ) ) {
   418 		if ( is_wp_error( $user ) ) {
   407 			return $user;
   419 			return $user;
   408 		}
   420 		}
   409 
   421 
   410 		$user = $this->prepare_item_for_response( $user, $request );
   422 		$user     = $this->prepare_item_for_response( $user, $request );
   411 		$response = rest_ensure_response( $user );
   423 		$response = rest_ensure_response( $user );
   412 
   424 
   413 		return $response;
   425 		return $response;
   414 	}
   426 	}
   415 
   427 
   430 
   442 
   431 		$user     = wp_get_current_user();
   443 		$user     = wp_get_current_user();
   432 		$response = $this->prepare_item_for_response( $user, $request );
   444 		$response = $this->prepare_item_for_response( $user, $request );
   433 		$response = rest_ensure_response( $response );
   445 		$response = rest_ensure_response( $response );
   434 
   446 
   435 
       
   436 		return $response;
   447 		return $response;
   437 	}
   448 	}
   438 
   449 
   439 	/**
   450 	/**
   440 	 * Checks if a given request has access create users.
   451 	 * Checks if a given request has access create users.
   479 		$user = $this->prepare_item_for_database( $request );
   490 		$user = $this->prepare_item_for_database( $request );
   480 
   491 
   481 		if ( is_multisite() ) {
   492 		if ( is_multisite() ) {
   482 			$ret = wpmu_validate_user_signup( $user->user_login, $user->user_email );
   493 			$ret = wpmu_validate_user_signup( $user->user_login, $user->user_email );
   483 
   494 
   484 			if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) {
   495 			if ( is_wp_error( $ret['errors'] ) && $ret['errors']->has_errors() ) {
   485 				$error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) );
   496 				$error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) );
   486 				foreach ( $ret['errors']->errors as $code => $messages ) {
   497 				foreach ( $ret['errors']->errors as $code => $messages ) {
   487 					foreach ( $messages as $message ) {
   498 					foreach ( $messages as $message ) {
   488 						$error->add( $code, $message );
   499 						$error->add( $code, $message );
   489 					}
   500 					}
   507 
   518 
   508 			if ( is_wp_error( $user_id ) ) {
   519 			if ( is_wp_error( $user_id ) ) {
   509 				return $user_id;
   520 				return $user_id;
   510 			}
   521 			}
   511 
   522 
   512 			$result= add_user_to_blog( get_site()->id, $user_id, '' );
   523 			$result = add_user_to_blog( get_site()->id, $user_id, '' );
   513 			if ( is_wp_error( $result ) ) {
   524 			if ( is_wp_error( $result ) ) {
   514 				return $result;
   525 				return $result;
   515 			}
   526 			}
   516 		} else {
   527 		} else {
   517 			$user_id = wp_insert_user( wp_slash( (array) $user ) );
   528 			$user_id = wp_insert_user( wp_slash( (array) $user ) );
   544 			if ( is_wp_error( $meta_update ) ) {
   555 			if ( is_wp_error( $meta_update ) ) {
   545 				return $meta_update;
   556 				return $meta_update;
   546 			}
   557 			}
   547 		}
   558 		}
   548 
   559 
   549 		$user = get_user_by( 'id', $user_id );
   560 		$user          = get_user_by( 'id', $user_id );
   550 		$fields_update = $this->update_additional_fields_for_object( $user, $request );
   561 		$fields_update = $this->update_additional_fields_for_object( $user, $request );
   551 
   562 
   552 		if ( is_wp_error( $fields_update ) ) {
   563 		if ( is_wp_error( $fields_update ) ) {
   553 			return $fields_update;
   564 			return $fields_update;
   554 		}
   565 		}
   555 
   566 
   556 		$request->set_param( 'context', 'edit' );
   567 		$request->set_param( 'context', 'edit' );
       
   568 
       
   569 		/**
       
   570 		 * Fires after a user is completely created or updated via the REST API.
       
   571 		 *
       
   572 		 * @since 5.0.0
       
   573 		 *
       
   574 		 * @param WP_User         $user     Inserted or updated user object.
       
   575 		 * @param WP_REST_Request $request  Request object.
       
   576 		 * @param bool            $creating True when creating a user, false when updating.
       
   577 		 */
       
   578 		do_action( 'rest_after_insert_user', $user, $request, true );
   557 
   579 
   558 		$response = $this->prepare_item_for_response( $user, $request );
   580 		$response = $this->prepare_item_for_response( $user, $request );
   559 		$response = rest_ensure_response( $response );
   581 		$response = rest_ensure_response( $response );
   560 
   582 
   561 		$response->set_status( 201 );
   583 		$response->set_status( 201 );
   617 
   639 
   618 		if ( ! $user ) {
   640 		if ( ! $user ) {
   619 			return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
   641 			return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
   620 		}
   642 		}
   621 
   643 
   622 		if ( email_exists( $request['email'] ) && $request['email'] !== $user->user_email ) {
   644 		$owner_id = email_exists( $request['email'] );
       
   645 
       
   646 		if ( $owner_id && $owner_id !== $id ) {
   623 			return new WP_Error( 'rest_user_invalid_email', __( 'Invalid email address.' ), array( 'status' => 400 ) );
   647 			return new WP_Error( 'rest_user_invalid_email', __( 'Invalid email address.' ), array( 'status' => 400 ) );
   624 		}
   648 		}
   625 
   649 
   626 		if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) {
   650 		if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) {
   627 			return new WP_Error( 'rest_user_invalid_argument', __( "Username isn't editable." ), array( 'status' => 400 ) );
   651 			return new WP_Error( 'rest_user_invalid_argument', __( "Username isn't editable." ), array( 'status' => 400 ) );
   667 			if ( is_wp_error( $meta_update ) ) {
   691 			if ( is_wp_error( $meta_update ) ) {
   668 				return $meta_update;
   692 				return $meta_update;
   669 			}
   693 			}
   670 		}
   694 		}
   671 
   695 
   672 		$user = get_user_by( 'id', $user_id );
   696 		$user          = get_user_by( 'id', $user_id );
   673 		$fields_update = $this->update_additional_fields_for_object( $user, $request );
   697 		$fields_update = $this->update_additional_fields_for_object( $user, $request );
   674 
   698 
   675 		if ( is_wp_error( $fields_update ) ) {
   699 		if ( is_wp_error( $fields_update ) ) {
   676 			return $fields_update;
   700 			return $fields_update;
   677 		}
   701 		}
   678 
   702 
   679 		$request->set_param( 'context', 'edit' );
   703 		$request->set_param( 'context', 'edit' );
       
   704 
       
   705 		/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */
       
   706 		do_action( 'rest_after_insert_user', $user, $request, false );
   680 
   707 
   681 		$response = $this->prepare_item_for_response( $user, $request );
   708 		$response = $this->prepare_item_for_response( $user, $request );
   682 		$response = rest_ensure_response( $response );
   709 		$response = rest_ensure_response( $response );
   683 
   710 
   684 		return $response;
   711 		return $response;
   779 		if ( ! $result ) {
   806 		if ( ! $result ) {
   780 			return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 500 ) );
   807 			return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 500 ) );
   781 		}
   808 		}
   782 
   809 
   783 		$response = new WP_REST_Response();
   810 		$response = new WP_REST_Response();
   784 		$response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data() ) );
   811 		$response->set_data(
       
   812 			array(
       
   813 				'deleted'  => true,
       
   814 				'previous' => $previous->get_data(),
       
   815 			)
       
   816 		);
   785 
   817 
   786 		/**
   818 		/**
   787 		 * Fires immediately after a user is deleted via the REST API.
   819 		 * Fires immediately after a user is deleted via the REST API.
   788 		 *
   820 		 *
   789 		 * @since 4.7.0
   821 		 * @since 4.7.0
   942 	 * @param WP_Post $user User object.
   974 	 * @param WP_Post $user User object.
   943 	 * @return array Links for the given user.
   975 	 * @return array Links for the given user.
   944 	 */
   976 	 */
   945 	protected function prepare_links( $user ) {
   977 	protected function prepare_links( $user ) {
   946 		$links = array(
   978 		$links = array(
   947 			'self' => array(
   979 			'self'       => array(
   948 				'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ),
   980 				'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ),
   949 			),
   981 			),
   950 			'collection' => array(
   982 			'collection' => array(
   951 				'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
   983 				'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
   952 			),
   984 			),
  1128 
  1160 
  1129 		if ( empty( $password ) ) {
  1161 		if ( empty( $password ) ) {
  1130 			return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) );
  1162 			return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) );
  1131 		}
  1163 		}
  1132 
  1164 
  1133 		if ( false !== strpos( $password, "\\" ) ) {
  1165 		if ( false !== strpos( $password, '\\' ) ) {
  1134 			return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) );
  1166 			return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) );
  1135 		}
  1167 		}
  1136 
  1168 
  1137 		return $password;
  1169 		return $password;
  1138 	}
  1170 	}
  1148 		$schema = array(
  1180 		$schema = array(
  1149 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
  1181 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
  1150 			'title'      => 'user',
  1182 			'title'      => 'user',
  1151 			'type'       => 'object',
  1183 			'type'       => 'object',
  1152 			'properties' => array(
  1184 			'properties' => array(
  1153 				'id'          => array(
  1185 				'id'                 => array(
  1154 					'description' => __( 'Unique identifier for the user.' ),
  1186 					'description' => __( 'Unique identifier for the user.' ),
  1155 					'type'        => 'integer',
  1187 					'type'        => 'integer',
  1156 					'context'     => array( 'embed', 'view', 'edit' ),
  1188 					'context'     => array( 'embed', 'view', 'edit' ),
  1157 					'readonly'    => true,
  1189 					'readonly'    => true,
  1158 				),
  1190 				),
  1159 				'username'    => array(
  1191 				'username'           => array(
  1160 					'description' => __( 'Login name for the user.' ),
  1192 					'description' => __( 'Login name for the user.' ),
  1161 					'type'        => 'string',
  1193 					'type'        => 'string',
  1162 					'context'     => array( 'edit' ),
  1194 					'context'     => array( 'edit' ),
  1163 					'required'    => true,
  1195 					'required'    => true,
  1164 					'arg_options' => array(
  1196 					'arg_options' => array(
  1165 						'sanitize_callback' => array( $this, 'check_username' ),
  1197 						'sanitize_callback' => array( $this, 'check_username' ),
  1166 					),
  1198 					),
  1167 				),
  1199 				),
  1168 				'name'        => array(
  1200 				'name'               => array(
  1169 					'description' => __( 'Display name for the user.' ),
  1201 					'description' => __( 'Display name for the user.' ),
  1170 					'type'        => 'string',
  1202 					'type'        => 'string',
  1171 					'context'     => array( 'embed', 'view', 'edit' ),
  1203 					'context'     => array( 'embed', 'view', 'edit' ),
  1172 					'arg_options' => array(
  1204 					'arg_options' => array(
  1173 						'sanitize_callback' => 'sanitize_text_field',
  1205 						'sanitize_callback' => 'sanitize_text_field',
  1174 					),
  1206 					),
  1175 				),
  1207 				),
  1176 				'first_name'  => array(
  1208 				'first_name'         => array(
  1177 					'description' => __( 'First name for the user.' ),
  1209 					'description' => __( 'First name for the user.' ),
  1178 					'type'        => 'string',
  1210 					'type'        => 'string',
  1179 					'context'     => array( 'edit' ),
  1211 					'context'     => array( 'edit' ),
  1180 					'arg_options' => array(
  1212 					'arg_options' => array(
  1181 						'sanitize_callback' => 'sanitize_text_field',
  1213 						'sanitize_callback' => 'sanitize_text_field',
  1182 					),
  1214 					),
  1183 				),
  1215 				),
  1184 				'last_name'   => array(
  1216 				'last_name'          => array(
  1185 					'description' => __( 'Last name for the user.' ),
  1217 					'description' => __( 'Last name for the user.' ),
  1186 					'type'        => 'string',
  1218 					'type'        => 'string',
  1187 					'context'     => array( 'edit' ),
  1219 					'context'     => array( 'edit' ),
  1188 					'arg_options' => array(
  1220 					'arg_options' => array(
  1189 						'sanitize_callback' => 'sanitize_text_field',
  1221 						'sanitize_callback' => 'sanitize_text_field',
  1190 					),
  1222 					),
  1191 				),
  1223 				),
  1192 				'email'       => array(
  1224 				'email'              => array(
  1193 					'description' => __( 'The email address for the user.' ),
  1225 					'description' => __( 'The email address for the user.' ),
  1194 					'type'        => 'string',
  1226 					'type'        => 'string',
  1195 					'format'      => 'email',
  1227 					'format'      => 'email',
  1196 					'context'     => array( 'edit' ),
  1228 					'context'     => array( 'edit' ),
  1197 					'required'    => true,
  1229 					'required'    => true,
  1198 				),
  1230 				),
  1199 				'url'         => array(
  1231 				'url'                => array(
  1200 					'description' => __( 'URL of the user.' ),
  1232 					'description' => __( 'URL of the user.' ),
  1201 					'type'        => 'string',
  1233 					'type'        => 'string',
  1202 					'format'      => 'uri',
  1234 					'format'      => 'uri',
  1203 					'context'     => array( 'embed', 'view', 'edit' ),
  1235 					'context'     => array( 'embed', 'view', 'edit' ),
  1204 				),
  1236 				),
  1205 				'description' => array(
  1237 				'description'        => array(
  1206 					'description' => __( 'Description of the user.' ),
  1238 					'description' => __( 'Description of the user.' ),
  1207 					'type'        => 'string',
  1239 					'type'        => 'string',
  1208 					'context'     => array( 'embed', 'view', 'edit' ),
  1240 					'context'     => array( 'embed', 'view', 'edit' ),
  1209 				),
  1241 				),
  1210 				'link'        => array(
  1242 				'link'               => array(
  1211 					'description' => __( 'Author URL of the user.' ),
  1243 					'description' => __( 'Author URL of the user.' ),
  1212 					'type'        => 'string',
  1244 					'type'        => 'string',
  1213 					'format'      => 'uri',
  1245 					'format'      => 'uri',
  1214 					'context'     => array( 'embed', 'view', 'edit' ),
  1246 					'context'     => array( 'embed', 'view', 'edit' ),
  1215 					'readonly'    => true,
  1247 					'readonly'    => true,
  1216 				),
  1248 				),
  1217 				'locale'    => array(
  1249 				'locale'             => array(
  1218 					'description' => __( 'Locale for the user.' ),
  1250 					'description' => __( 'Locale for the user.' ),
  1219 					'type'        => 'string',
  1251 					'type'        => 'string',
  1220 					'enum'        => array_merge( array( '', 'en_US' ), get_available_languages() ),
  1252 					'enum'        => array_merge( array( '', 'en_US' ), get_available_languages() ),
  1221 					'context'     => array( 'edit' ),
  1253 					'context'     => array( 'edit' ),
  1222 				),
  1254 				),
  1223 				'nickname'    => array(
  1255 				'nickname'           => array(
  1224 					'description' => __( 'The nickname for the user.' ),
  1256 					'description' => __( 'The nickname for the user.' ),
  1225 					'type'        => 'string',
  1257 					'type'        => 'string',
  1226 					'context'     => array( 'edit' ),
  1258 					'context'     => array( 'edit' ),
  1227 					'arg_options' => array(
  1259 					'arg_options' => array(
  1228 						'sanitize_callback' => 'sanitize_text_field',
  1260 						'sanitize_callback' => 'sanitize_text_field',
  1229 					),
  1261 					),
  1230 				),
  1262 				),
  1231 				'slug'        => array(
  1263 				'slug'               => array(
  1232 					'description' => __( 'An alphanumeric identifier for the user.' ),
  1264 					'description' => __( 'An alphanumeric identifier for the user.' ),
  1233 					'type'        => 'string',
  1265 					'type'        => 'string',
  1234 					'context'     => array( 'embed', 'view', 'edit' ),
  1266 					'context'     => array( 'embed', 'view', 'edit' ),
  1235 					'arg_options' => array(
  1267 					'arg_options' => array(
  1236 						'sanitize_callback' => array( $this, 'sanitize_slug' ),
  1268 						'sanitize_callback' => array( $this, 'sanitize_slug' ),
  1237 					),
  1269 					),
  1238 				),
  1270 				),
  1239 				'registered_date' => array(
  1271 				'registered_date'    => array(
  1240 					'description' => __( 'Registration date for the user.' ),
  1272 					'description' => __( 'Registration date for the user.' ),
  1241 					'type'        => 'string',
  1273 					'type'        => 'string',
  1242 					'format'      => 'date-time',
  1274 					'format'      => 'date-time',
  1243 					'context'     => array( 'edit' ),
  1275 					'context'     => array( 'edit' ),
  1244 					'readonly'    => true,
  1276 					'readonly'    => true,
  1245 				),
  1277 				),
  1246 				'roles'           => array(
  1278 				'roles'              => array(
  1247 					'description' => __( 'Roles assigned to the user.' ),
  1279 					'description' => __( 'Roles assigned to the user.' ),
  1248 					'type'        => 'array',
  1280 					'type'        => 'array',
  1249 					'items'       => array(
  1281 					'items'       => array(
  1250 						'type'    => 'string',
  1282 						'type' => 'string',
  1251 					),
  1283 					),
  1252 					'context'     => array( 'edit' ),
  1284 					'context'     => array( 'edit' ),
  1253 				),
  1285 				),
  1254 				'password'        => array(
  1286 				'password'           => array(
  1255 					'description' => __( 'Password for the user (never included).' ),
  1287 					'description' => __( 'Password for the user (never included).' ),
  1256 					'type'        => 'string',
  1288 					'type'        => 'string',
  1257 					'context'     => array(), // Password is never displayed.
  1289 					'context'     => array(), // Password is never displayed.
  1258 					'required'    => true,
  1290 					'required'    => true,
  1259 					'arg_options' => array(
  1291 					'arg_options' => array(
  1260 						'sanitize_callback' => array( $this, 'check_user_password' ),
  1292 						'sanitize_callback' => array( $this, 'check_user_password' ),
  1261 					),
  1293 					),
  1262 				),
  1294 				),
  1263 				'capabilities'    => array(
  1295 				'capabilities'       => array(
  1264 					'description' => __( 'All capabilities assigned to the user.' ),
  1296 					'description' => __( 'All capabilities assigned to the user.' ),
  1265 					'type'        => 'object',
  1297 					'type'        => 'object',
  1266 					'context'     => array( 'edit' ),
  1298 					'context'     => array( 'edit' ),
  1267 					'readonly'    => true,
  1299 					'readonly'    => true,
  1268 				),
  1300 				),
  1288 					'format'      => 'uri',
  1320 					'format'      => 'uri',
  1289 					'context'     => array( 'embed', 'view', 'edit' ),
  1321 					'context'     => array( 'embed', 'view', 'edit' ),
  1290 				);
  1322 				);
  1291 			}
  1323 			}
  1292 
  1324 
  1293 			$schema['properties']['avatar_urls']  = array(
  1325 			$schema['properties']['avatar_urls'] = array(
  1294 				'description' => __( 'Avatar URLs for the user.' ),
  1326 				'description' => __( 'Avatar URLs for the user.' ),
  1295 				'type'        => 'object',
  1327 				'type'        => 'object',
  1296 				'context'     => array( 'embed', 'view', 'edit' ),
  1328 				'context'     => array( 'embed', 'view', 'edit' ),
  1297 				'readonly'    => true,
  1329 				'readonly'    => true,
  1298 				'properties'  => $avatar_properties,
  1330 				'properties'  => $avatar_properties,
  1315 		$query_params = parent::get_collection_params();
  1347 		$query_params = parent::get_collection_params();
  1316 
  1348 
  1317 		$query_params['context']['default'] = 'view';
  1349 		$query_params['context']['default'] = 'view';
  1318 
  1350 
  1319 		$query_params['exclude'] = array(
  1351 		$query_params['exclude'] = array(
  1320 			'description'        => __( 'Ensure result set excludes specific IDs.' ),
  1352 			'description' => __( 'Ensure result set excludes specific IDs.' ),
  1321 			'type'               => 'array',
  1353 			'type'        => 'array',
  1322 			'items'              => array(
  1354 			'items'       => array(
  1323 				'type'           => 'integer',
  1355 				'type' => 'integer',
  1324 			),
  1356 			),
  1325 			'default'            => array(),
  1357 			'default'     => array(),
  1326 		);
  1358 		);
  1327 
  1359 
  1328 		$query_params['include'] = array(
  1360 		$query_params['include'] = array(
  1329 			'description'        => __( 'Limit result set to specific IDs.' ),
  1361 			'description' => __( 'Limit result set to specific IDs.' ),
  1330 			'type'               => 'array',
  1362 			'type'        => 'array',
  1331 			'items'              => array(
  1363 			'items'       => array(
  1332 				'type'           => 'integer',
  1364 				'type' => 'integer',
  1333 			),
  1365 			),
  1334 			'default'            => array(),
  1366 			'default'     => array(),
  1335 		);
  1367 		);
  1336 
  1368 
  1337 		$query_params['offset'] = array(
  1369 		$query_params['offset'] = array(
  1338 			'description'        => __( 'Offset the result set by a specific number of items.' ),
  1370 			'description' => __( 'Offset the result set by a specific number of items.' ),
  1339 			'type'               => 'integer',
  1371 			'type'        => 'integer',
  1340 		);
  1372 		);
  1341 
  1373 
  1342 		$query_params['order'] = array(
  1374 		$query_params['order'] = array(
  1343 			'default'            => 'asc',
  1375 			'default'     => 'asc',
  1344 			'description'        => __( 'Order sort attribute ascending or descending.' ),
  1376 			'description' => __( 'Order sort attribute ascending or descending.' ),
  1345 			'enum'               => array( 'asc', 'desc' ),
  1377 			'enum'        => array( 'asc', 'desc' ),
  1346 			'type'               => 'string',
  1378 			'type'        => 'string',
  1347 		);
  1379 		);
  1348 
  1380 
  1349 		$query_params['orderby'] = array(
  1381 		$query_params['orderby'] = array(
  1350 			'default'            => 'name',
  1382 			'default'     => 'name',
  1351 			'description'        => __( 'Sort collection by object attribute.' ),
  1383 			'description' => __( 'Sort collection by object attribute.' ),
  1352 			'enum'               => array(
  1384 			'enum'        => array(
  1353 				'id',
  1385 				'id',
  1354 				'include',
  1386 				'include',
  1355 				'name',
  1387 				'name',
  1356 				'registered_date',
  1388 				'registered_date',
  1357 				'slug',
  1389 				'slug',
  1358 				'include_slugs',
  1390 				'include_slugs',
  1359 				'email',
  1391 				'email',
  1360 				'url',
  1392 				'url',
  1361 			),
  1393 			),
  1362 			'type'               => 'string',
  1394 			'type'        => 'string',
  1363 		);
  1395 		);
  1364 
  1396 
  1365 		$query_params['slug']    = array(
  1397 		$query_params['slug'] = array(
  1366 			'description'        => __( 'Limit result set to users with one or more specific slugs.' ),
  1398 			'description' => __( 'Limit result set to users with one or more specific slugs.' ),
  1367 			'type'               => 'array',
  1399 			'type'        => 'array',
  1368 			'items'              => array(
  1400 			'items'       => array(
  1369 				'type'               => 'string',
  1401 				'type' => 'string',
  1370 			),
  1402 			),
  1371 		);
  1403 		);
  1372 
  1404 
  1373 		$query_params['roles']   = array(
  1405 		$query_params['roles'] = array(
  1374 			'description'        => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ),
  1406 			'description' => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ),
  1375 			'type'               => 'array',
  1407 			'type'        => 'array',
  1376 			'items'              => array(
  1408 			'items'       => array(
  1377 				'type'           => 'string',
  1409 				'type' => 'string',
  1378 			),
  1410 			),
  1379 		);
  1411 		);
  1380 
  1412 
  1381 		$query_params['who'] = array(
  1413 		$query_params['who'] = array(
  1382 			'description' => __( 'Limit result set to users who are considered authors.' ),
  1414 			'description' => __( 'Limit result set to users who are considered authors.' ),