wp/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
   114 		register_rest_route(
   114 		register_rest_route(
   115 			$this->namespace,
   115 			$this->namespace,
   116 			'/' . $this->rest_base . '/me',
   116 			'/' . $this->rest_base . '/me',
   117 			array(
   117 			array(
   118 				array(
   118 				array(
   119 					'methods'  => WP_REST_Server::READABLE,
   119 					'methods'             => WP_REST_Server::READABLE,
   120 					'callback' => array( $this, 'get_current_item' ),
   120 					'permission_callback' => '__return_true',
   121 					'args'     => array(
   121 					'callback'            => array( $this, 'get_current_item' ),
       
   122 					'args'                => array(
   122 						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
   123 						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
   123 					),
   124 					),
   124 				),
   125 				),
   125 				array(
   126 				array(
   126 					'methods'             => WP_REST_Server::EDITABLE,
   127 					'methods'             => WP_REST_Server::EDITABLE,
   159 	 * @since 4.7.0
   160 	 * @since 4.7.0
   160 	 *
   161 	 *
   161 	 * @param int|bool        $value   The value passed to the reassign parameter.
   162 	 * @param int|bool        $value   The value passed to the reassign parameter.
   162 	 * @param WP_REST_Request $request Full details about the request.
   163 	 * @param WP_REST_Request $request Full details about the request.
   163 	 * @param string          $param   The parameter that is being sanitized.
   164 	 * @param string          $param   The parameter that is being sanitized.
   164 	 *
       
   165 	 * @return int|bool|WP_Error
   165 	 * @return int|bool|WP_Error
   166 	 */
   166 	 */
   167 	public function check_reassign( $value, $request, $param ) {
   167 	public function check_reassign( $value, $request, $param ) {
   168 		if ( is_numeric( $value ) ) {
   168 		if ( is_numeric( $value ) ) {
   169 			return $value;
   169 			return $value;
   171 
   171 
   172 		if ( empty( $value ) || false === $value || 'false' === $value ) {
   172 		if ( empty( $value ) || false === $value || 'false' === $value ) {
   173 			return false;
   173 			return false;
   174 		}
   174 		}
   175 
   175 
   176 		return new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) );
   176 		return new WP_Error(
       
   177 			'rest_invalid_param',
       
   178 			__( 'Invalid user parameter(s).' ),
       
   179 			array( 'status' => 400 )
       
   180 		);
   177 	}
   181 	}
   178 
   182 
   179 	/**
   183 	/**
   180 	 * Permissions check for getting all users.
   184 	 * Permissions check for getting all users.
   181 	 *
   185 	 *
   185 	 * @return true|WP_Error True if the request has read access, otherwise WP_Error object.
   189 	 * @return true|WP_Error True if the request has read access, otherwise WP_Error object.
   186 	 */
   190 	 */
   187 	public function get_items_permissions_check( $request ) {
   191 	public function get_items_permissions_check( $request ) {
   188 		// Check if roles is specified in GET request and if user can list users.
   192 		// Check if roles is specified in GET request and if user can list users.
   189 		if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) {
   193 		if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) {
   190 			return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to filter users by role.' ), array( 'status' => rest_authorization_required_code() ) );
   194 			return new WP_Error(
       
   195 				'rest_user_cannot_view',
       
   196 				__( 'Sorry, you are not allowed to filter users by role.' ),
       
   197 				array( 'status' => rest_authorization_required_code() )
       
   198 			);
   191 		}
   199 		}
   192 
   200 
   193 		if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
   201 		if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
   194 			return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );
   202 			return new WP_Error(
       
   203 				'rest_forbidden_context',
       
   204 				__( 'Sorry, you are not allowed to list users.' ),
       
   205 				array( 'status' => rest_authorization_required_code() )
       
   206 			);
   195 		}
   207 		}
   196 
   208 
   197 		if ( in_array( $request['orderby'], array( 'email', 'registered_date' ), true ) && ! current_user_can( 'list_users' ) ) {
   209 		if ( in_array( $request['orderby'], array( 'email', 'registered_date' ), true ) && ! current_user_can( 'list_users' ) ) {
   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() ) );
   210 			return new WP_Error(
       
   211 				'rest_forbidden_orderby',
       
   212 				__( 'Sorry, you are not allowed to order users by this parameter.' ),
       
   213 				array( 'status' => rest_authorization_required_code() )
       
   214 			);
   199 		}
   215 		}
   200 
   216 
   201 		if ( 'authors' === $request['who'] ) {
   217 		if ( 'authors' === $request['who'] ) {
   202 			$can_view = false;
   218 			$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
   203 			$types    = get_post_types( array( 'show_in_rest' => true ), 'objects' );
   219 
   204 			foreach ( $types as $type ) {
   220 			foreach ( $types as $type ) {
   205 				if ( post_type_supports( $type->name, 'author' )
   221 				if ( post_type_supports( $type->name, 'author' )
   206 					&& current_user_can( $type->cap->edit_posts ) ) {
   222 					&& current_user_can( $type->cap->edit_posts ) ) {
   207 					$can_view = true;
   223 					return true;
   208 				}
   224 				}
   209 			}
   225 			}
   210 			if ( ! $can_view ) {
   226 
   211 				return new WP_Error( 'rest_forbidden_who', __( 'Sorry, you are not allowed to query users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) );
   227 			return new WP_Error(
   212 			}
   228 				'rest_forbidden_who',
       
   229 				__( 'Sorry, you are not allowed to query users by this parameter.' ),
       
   230 				array( 'status' => rest_authorization_required_code() )
       
   231 			);
   213 		}
   232 		}
   214 
   233 
   215 		return true;
   234 		return true;
   216 	}
   235 	}
   217 
   236 
   357 	 *
   376 	 *
   358 	 * @param int $id Supplied ID.
   377 	 * @param int $id Supplied ID.
   359 	 * @return WP_User|WP_Error True if ID is valid, WP_Error otherwise.
   378 	 * @return WP_User|WP_Error True if ID is valid, WP_Error otherwise.
   360 	 */
   379 	 */
   361 	protected function get_user( $id ) {
   380 	protected function get_user( $id ) {
   362 		$error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
   381 		$error = new WP_Error(
       
   382 			'rest_user_invalid_id',
       
   383 			__( 'Invalid user ID.' ),
       
   384 			array( 'status' => 404 )
       
   385 		);
       
   386 
   363 		if ( (int) $id <= 0 ) {
   387 		if ( (int) $id <= 0 ) {
   364 			return $error;
   388 			return $error;
   365 		}
   389 		}
   366 
   390 
   367 		$user = get_userdata( (int) $id );
   391 		$user = get_userdata( (int) $id );
   395 		if ( get_current_user_id() === $user->ID ) {
   419 		if ( get_current_user_id() === $user->ID ) {
   396 			return true;
   420 			return true;
   397 		}
   421 		}
   398 
   422 
   399 		if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
   423 		if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
   400 			return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );
   424 			return new WP_Error(
       
   425 				'rest_user_cannot_view',
       
   426 				__( 'Sorry, you are not allowed to list users.' ),
       
   427 				array( 'status' => rest_authorization_required_code() )
       
   428 			);
   401 		} elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) {
   429 		} elseif ( ! count_user_posts( $user->ID, $types ) && ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) ) {
   402 			return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) );
   430 			return new WP_Error(
       
   431 				'rest_user_cannot_view',
       
   432 				__( 'Sorry, you are not allowed to list users.' ),
       
   433 				array( 'status' => rest_authorization_required_code() )
       
   434 			);
   403 		}
   435 		}
   404 
   436 
   405 		return true;
   437 		return true;
   406 	}
   438 	}
   407 
   439 
   435 	 */
   467 	 */
   436 	public function get_current_item( $request ) {
   468 	public function get_current_item( $request ) {
   437 		$current_user_id = get_current_user_id();
   469 		$current_user_id = get_current_user_id();
   438 
   470 
   439 		if ( empty( $current_user_id ) ) {
   471 		if ( empty( $current_user_id ) ) {
   440 			return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) );
   472 			return new WP_Error(
       
   473 				'rest_not_logged_in',
       
   474 				__( 'You are not currently logged in.' ),
       
   475 				array( 'status' => 401 )
       
   476 			);
   441 		}
   477 		}
   442 
   478 
   443 		$user     = wp_get_current_user();
   479 		$user     = wp_get_current_user();
   444 		$response = $this->prepare_item_for_response( $user, $request );
   480 		$response = $this->prepare_item_for_response( $user, $request );
   445 		$response = rest_ensure_response( $response );
   481 		$response = rest_ensure_response( $response );
   456 	 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
   492 	 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
   457 	 */
   493 	 */
   458 	public function create_item_permissions_check( $request ) {
   494 	public function create_item_permissions_check( $request ) {
   459 
   495 
   460 		if ( ! current_user_can( 'create_users' ) ) {
   496 		if ( ! current_user_can( 'create_users' ) ) {
   461 			return new WP_Error( 'rest_cannot_create_user', __( 'Sorry, you are not allowed to create new users.' ), array( 'status' => rest_authorization_required_code() ) );
   497 			return new WP_Error(
       
   498 				'rest_cannot_create_user',
       
   499 				__( 'Sorry, you are not allowed to create new users.' ),
       
   500 				array( 'status' => rest_authorization_required_code() )
       
   501 			);
   462 		}
   502 		}
   463 
   503 
   464 		return true;
   504 		return true;
   465 	}
   505 	}
   466 
   506 
   472 	 * @param WP_REST_Request $request Full details about the request.
   512 	 * @param WP_REST_Request $request Full details about the request.
   473 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   513 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   474 	 */
   514 	 */
   475 	public function create_item( $request ) {
   515 	public function create_item( $request ) {
   476 		if ( ! empty( $request['id'] ) ) {
   516 		if ( ! empty( $request['id'] ) ) {
   477 			return new WP_Error( 'rest_user_exists', __( 'Cannot create existing user.' ), array( 'status' => 400 ) );
   517 			return new WP_Error(
       
   518 				'rest_user_exists',
       
   519 				__( 'Cannot create existing user.' ),
       
   520 				array( 'status' => 400 )
       
   521 			);
   478 		}
   522 		}
   479 
   523 
   480 		$schema = $this->get_item_schema();
   524 		$schema = $this->get_item_schema();
   481 
   525 
   482 		if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) {
   526 		if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) {
   491 
   535 
   492 		if ( is_multisite() ) {
   536 		if ( is_multisite() ) {
   493 			$ret = wpmu_validate_user_signup( $user->user_login, $user->user_email );
   537 			$ret = wpmu_validate_user_signup( $user->user_login, $user->user_email );
   494 
   538 
   495 			if ( is_wp_error( $ret['errors'] ) && $ret['errors']->has_errors() ) {
   539 			if ( is_wp_error( $ret['errors'] ) && $ret['errors']->has_errors() ) {
   496 				$error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) );
   540 				$error = new WP_Error(
       
   541 					'rest_invalid_param',
       
   542 					__( 'Invalid user parameter(s).' ),
       
   543 					array( 'status' => 400 )
       
   544 				);
       
   545 
   497 				foreach ( $ret['errors']->errors as $code => $messages ) {
   546 				foreach ( $ret['errors']->errors as $code => $messages ) {
   498 					foreach ( $messages as $message ) {
   547 					foreach ( $messages as $message ) {
   499 						$error->add( $code, $message );
   548 						$error->add( $code, $message );
   500 					}
   549 					}
   501 					if ( $error_data = $error->get_error_data( $code ) ) {
   550 
       
   551 					$error_data = $error->get_error_data( $code );
       
   552 
       
   553 					if ( $error_data ) {
   502 						$error->add_data( $error_data, $code );
   554 						$error->add_data( $error_data, $code );
   503 					}
   555 					}
   504 				}
   556 				}
   505 				return $error;
   557 				return $error;
   506 			}
   558 			}
   508 
   560 
   509 		if ( is_multisite() ) {
   561 		if ( is_multisite() ) {
   510 			$user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email );
   562 			$user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email );
   511 
   563 
   512 			if ( ! $user_id ) {
   564 			if ( ! $user_id ) {
   513 				return new WP_Error( 'rest_user_create', __( 'Error creating new user.' ), array( 'status' => 500 ) );
   565 				return new WP_Error(
       
   566 					'rest_user_create',
       
   567 					__( 'Error creating new user.' ),
       
   568 					array( 'status' => 500 )
       
   569 				);
   514 			}
   570 			}
   515 
   571 
   516 			$user->ID = $user_id;
   572 			$user->ID = $user_id;
   517 			$user_id  = wp_update_user( wp_slash( (array) $user ) );
   573 			$user_id  = wp_update_user( wp_slash( (array) $user ) );
   518 
   574 
   600 			return $user;
   656 			return $user;
   601 		}
   657 		}
   602 
   658 
   603 		if ( ! empty( $request['roles'] ) ) {
   659 		if ( ! empty( $request['roles'] ) ) {
   604 			if ( ! current_user_can( 'promote_user', $user->ID ) ) {
   660 			if ( ! current_user_can( 'promote_user', $user->ID ) ) {
   605 				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() ) );
   661 				return new WP_Error(
       
   662 					'rest_cannot_edit_roles',
       
   663 					__( 'Sorry, you are not allowed to edit roles of this user.' ),
       
   664 					array( 'status' => rest_authorization_required_code() )
       
   665 				);
   606 			}
   666 			}
   607 
   667 
   608 			$request_params = array_keys( $request->get_params() );
   668 			$request_params = array_keys( $request->get_params() );
   609 			sort( $request_params );
   669 			sort( $request_params );
   610 			// If only 'id' and 'roles' are specified (we are only trying to
   670 			// If only 'id' and 'roles' are specified (we are only trying to
   611 			// edit roles), then only the 'promote_user' cap is required.
   671 			// edit roles), then only the 'promote_user' cap is required.
   612 			if ( $request_params === array( 'id', 'roles' ) ) {
   672 			if ( array( 'id', 'roles' ) === $request_params ) {
   613 				return true;
   673 				return true;
   614 			}
   674 			}
   615 		}
   675 		}
   616 
   676 
   617 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
   677 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
   618 			return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) );
   678 			return new WP_Error(
       
   679 				'rest_cannot_edit',
       
   680 				__( 'Sorry, you are not allowed to edit this user.' ),
       
   681 				array( 'status' => rest_authorization_required_code() )
       
   682 			);
   619 		}
   683 		}
   620 
   684 
   621 		return true;
   685 		return true;
   622 	}
   686 	}
   623 
   687 
   636 		}
   700 		}
   637 
   701 
   638 		$id = $user->ID;
   702 		$id = $user->ID;
   639 
   703 
   640 		if ( ! $user ) {
   704 		if ( ! $user ) {
   641 			return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) );
   705 			return new WP_Error(
       
   706 				'rest_user_invalid_id',
       
   707 				__( 'Invalid user ID.' ),
       
   708 				array( 'status' => 404 )
       
   709 			);
   642 		}
   710 		}
   643 
   711 
   644 		$owner_id = email_exists( $request['email'] );
   712 		$owner_id = email_exists( $request['email'] );
   645 
   713 
   646 		if ( $owner_id && $owner_id !== $id ) {
   714 		if ( $owner_id && $owner_id !== $id ) {
   647 			return new WP_Error( 'rest_user_invalid_email', __( 'Invalid email address.' ), array( 'status' => 400 ) );
   715 			return new WP_Error(
       
   716 				'rest_user_invalid_email',
       
   717 				__( 'Invalid email address.' ),
       
   718 				array( 'status' => 400 )
       
   719 			);
   648 		}
   720 		}
   649 
   721 
   650 		if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) {
   722 		if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) {
   651 			return new WP_Error( 'rest_user_invalid_argument', __( "Username isn't editable." ), array( 'status' => 400 ) );
   723 			return new WP_Error(
       
   724 				'rest_user_invalid_argument',
       
   725 				__( "Username isn't editable." ),
       
   726 				array( 'status' => 400 )
       
   727 			);
   652 		}
   728 		}
   653 
   729 
   654 		if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) {
   730 		if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) {
   655 			return new WP_Error( 'rest_user_invalid_slug', __( 'Invalid slug.' ), array( 'status' => 400 ) );
   731 			return new WP_Error(
       
   732 				'rest_user_invalid_slug',
       
   733 				__( 'Invalid slug.' ),
       
   734 				array( 'status' => 400 )
       
   735 			);
   656 		}
   736 		}
   657 
   737 
   658 		if ( ! empty( $request['roles'] ) ) {
   738 		if ( ! empty( $request['roles'] ) ) {
   659 			$check_permission = $this->check_role_update( $id, $request['roles'] );
   739 			$check_permission = $this->check_role_update( $id, $request['roles'] );
   660 
   740 
   731 	 * @since 4.7.0
   811 	 * @since 4.7.0
   732 	 *
   812 	 *
   733 	 * @param WP_REST_Request $request Full details about the request.
   813 	 * @param WP_REST_Request $request Full details about the request.
   734 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   814 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   735 	 */
   815 	 */
   736 	function update_current_item( $request ) {
   816 	public function update_current_item( $request ) {
   737 		$request['id'] = get_current_user_id();
   817 		$request['id'] = get_current_user_id();
   738 
   818 
   739 		return $this->update_item( $request );
   819 		return $this->update_item( $request );
   740 	}
   820 	}
   741 
   821 
   752 		if ( is_wp_error( $user ) ) {
   832 		if ( is_wp_error( $user ) ) {
   753 			return $user;
   833 			return $user;
   754 		}
   834 		}
   755 
   835 
   756 		if ( ! current_user_can( 'delete_user', $user->ID ) ) {
   836 		if ( ! current_user_can( 'delete_user', $user->ID ) ) {
   757 			return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) );
   837 			return new WP_Error(
       
   838 				'rest_user_cannot_delete',
       
   839 				__( 'Sorry, you are not allowed to delete this user.' ),
       
   840 				array( 'status' => rest_authorization_required_code() )
       
   841 			);
   758 		}
   842 		}
   759 
   843 
   760 		return true;
   844 		return true;
   761 	}
   845 	}
   762 
   846 
   769 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   853 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   770 	 */
   854 	 */
   771 	public function delete_item( $request ) {
   855 	public function delete_item( $request ) {
   772 		// We don't support delete requests in multisite.
   856 		// We don't support delete requests in multisite.
   773 		if ( is_multisite() ) {
   857 		if ( is_multisite() ) {
   774 			return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 501 ) );
   858 			return new WP_Error(
   775 		}
   859 				'rest_cannot_delete',
       
   860 				__( 'The user cannot be deleted.' ),
       
   861 				array( 'status' => 501 )
       
   862 			);
       
   863 		}
       
   864 
   776 		$user = $this->get_user( $request['id'] );
   865 		$user = $this->get_user( $request['id'] );
       
   866 
   777 		if ( is_wp_error( $user ) ) {
   867 		if ( is_wp_error( $user ) ) {
   778 			return $user;
   868 			return $user;
   779 		}
   869 		}
   780 
   870 
   781 		$id       = $user->ID;
   871 		$id       = $user->ID;
   782 		$reassign = false === $request['reassign'] ? null : absint( $request['reassign'] );
   872 		$reassign = false === $request['reassign'] ? null : absint( $request['reassign'] );
   783 		$force    = isset( $request['force'] ) ? (bool) $request['force'] : false;
   873 		$force    = isset( $request['force'] ) ? (bool) $request['force'] : false;
   784 
   874 
   785 		// We don't support trashing for users.
   875 		// We don't support trashing for users.
   786 		if ( ! $force ) {
   876 		if ( ! $force ) {
   787 			/* translators: %s: force=true */
   877 			return new WP_Error(
   788 			return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Users do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) );
   878 				'rest_trash_not_supported',
       
   879 				/* translators: %s: force=true */
       
   880 				sprintf( __( "Users do not support trashing. Set '%s' to delete." ), 'force=true' ),
       
   881 				array( 'status' => 501 )
       
   882 			);
   789 		}
   883 		}
   790 
   884 
   791 		if ( ! empty( $reassign ) ) {
   885 		if ( ! empty( $reassign ) ) {
   792 			if ( $reassign === $id || ! get_userdata( $reassign ) ) {
   886 			if ( $reassign === $id || ! get_userdata( $reassign ) ) {
   793 				return new WP_Error( 'rest_user_invalid_reassign', __( 'Invalid user ID for reassignment.' ), array( 'status' => 400 ) );
   887 				return new WP_Error(
       
   888 					'rest_user_invalid_reassign',
       
   889 					__( 'Invalid user ID for reassignment.' ),
       
   890 					array( 'status' => 400 )
       
   891 				);
   794 			}
   892 			}
   795 		}
   893 		}
   796 
   894 
   797 		$request->set_param( 'context', 'edit' );
   895 		$request->set_param( 'context', 'edit' );
   798 
   896 
   799 		$previous = $this->prepare_item_for_response( $user, $request );
   897 		$previous = $this->prepare_item_for_response( $user, $request );
   800 
   898 
   801 		/** Include admin user functions to get access to wp_delete_user() */
   899 		// Include user admin functions to get access to wp_delete_user().
   802 		require_once ABSPATH . 'wp-admin/includes/user.php';
   900 		require_once ABSPATH . 'wp-admin/includes/user.php';
   803 
   901 
   804 		$result = wp_delete_user( $id, $reassign );
   902 		$result = wp_delete_user( $id, $reassign );
   805 
   903 
   806 		if ( ! $result ) {
   904 		if ( ! $result ) {
   807 			return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 500 ) );
   905 			return new WP_Error(
       
   906 				'rest_cannot_delete',
       
   907 				__( 'The user cannot be deleted.' ),
       
   908 				array( 'status' => 500 )
       
   909 			);
   808 		}
   910 		}
   809 
   911 
   810 		$response = new WP_REST_Response();
   912 		$response = new WP_REST_Response();
   811 		$response->set_data(
   913 		$response->set_data(
   812 			array(
   914 			array(
   849 	 * @since 4.7.0
   951 	 * @since 4.7.0
   850 	 *
   952 	 *
   851 	 * @param WP_REST_Request $request Full details about the request.
   953 	 * @param WP_REST_Request $request Full details about the request.
   852 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   954 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
   853 	 */
   955 	 */
   854 	function delete_current_item( $request ) {
   956 	public function delete_current_item( $request ) {
   855 		$request['id'] = get_current_user_id();
   957 		$request['id'] = get_current_user_id();
   856 
   958 
   857 		return $this->delete_item( $request );
   959 		return $this->delete_item( $request );
   858 	}
   960 	}
   859 
   961 
   923 			// Defensively call array_values() to ensure an array is returned.
  1025 			// Defensively call array_values() to ensure an array is returned.
   924 			$data['roles'] = array_values( $user->roles );
  1026 			$data['roles'] = array_values( $user->roles );
   925 		}
  1027 		}
   926 
  1028 
   927 		if ( in_array( 'registered_date', $fields, true ) ) {
  1029 		if ( in_array( 'registered_date', $fields, true ) ) {
   928 			$data['registered_date'] = date( 'c', strtotime( $user->user_registered ) );
  1030 			$data['registered_date'] = gmdate( 'c', strtotime( $user->user_registered ) );
   929 		}
  1031 		}
   930 
  1032 
   931 		if ( in_array( 'capabilities', $fields, true ) ) {
  1033 		if ( in_array( 'capabilities', $fields, true ) ) {
   932 			$data['capabilities'] = (object) $user->allcaps;
  1034 			$data['capabilities'] = (object) $user->allcaps;
   933 		}
  1035 		}
   935 		if ( in_array( 'extra_capabilities', $fields, true ) ) {
  1037 		if ( in_array( 'extra_capabilities', $fields, true ) ) {
   936 			$data['extra_capabilities'] = (object) $user->caps;
  1038 			$data['extra_capabilities'] = (object) $user->caps;
   937 		}
  1039 		}
   938 
  1040 
   939 		if ( in_array( 'avatar_urls', $fields, true ) ) {
  1041 		if ( in_array( 'avatar_urls', $fields, true ) ) {
   940 			$data['avatar_urls'] = rest_get_avatar_urls( $user->user_email );
  1042 			$data['avatar_urls'] = rest_get_avatar_urls( $user );
   941 		}
  1043 		}
   942 
  1044 
   943 		if ( in_array( 'meta', $fields, true ) ) {
  1045 		if ( in_array( 'meta', $fields, true ) ) {
   944 			$data['meta'] = $this->meta->get_value( $user->ID, $request );
  1046 			$data['meta'] = $this->meta->get_value( $user->ID, $request );
   945 		}
  1047 		}
   958 		 * Filters user data returned from the REST API.
  1060 		 * Filters user data returned from the REST API.
   959 		 *
  1061 		 *
   960 		 * @since 4.7.0
  1062 		 * @since 4.7.0
   961 		 *
  1063 		 *
   962 		 * @param WP_REST_Response $response The response object.
  1064 		 * @param WP_REST_Response $response The response object.
   963 		 * @param object           $user     User object used to create response.
  1065 		 * @param WP_User          $user     User object used to create response.
   964 		 * @param WP_REST_Request  $request  Request object.
  1066 		 * @param WP_REST_Request  $request  Request object.
   965 		 */
  1067 		 */
   966 		return apply_filters( 'rest_prepare_user', $response, $user, $request );
  1068 		return apply_filters( 'rest_prepare_user', $response, $user, $request );
   967 	}
  1069 	}
   968 
  1070 
   991 	 * Prepares a single user for creation or update.
  1093 	 * Prepares a single user for creation or update.
   992 	 *
  1094 	 *
   993 	 * @since 4.7.0
  1095 	 * @since 4.7.0
   994 	 *
  1096 	 *
   995 	 * @param WP_REST_Request $request Request object.
  1097 	 * @param WP_REST_Request $request Request object.
   996 	 * @return object $prepared_user User object.
  1098 	 * @return object User object.
   997 	 */
  1099 	 */
   998 	protected function prepare_item_for_database( $request ) {
  1100 	protected function prepare_item_for_database( $request ) {
   999 		$prepared_user = new stdClass;
  1101 		$prepared_user = new stdClass;
  1000 
  1102 
  1001 		$schema = $this->get_item_schema();
  1103 		$schema = $this->get_item_schema();
  1002 
  1104 
  1003 		// required arguments.
  1105 		// Required arguments.
  1004 		if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) {
  1106 		if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) {
  1005 			$prepared_user->user_email = $request['email'];
  1107 			$prepared_user->user_email = $request['email'];
  1006 		}
  1108 		}
  1007 
  1109 
  1008 		if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) {
  1110 		if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) {
  1011 
  1113 
  1012 		if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) {
  1114 		if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) {
  1013 			$prepared_user->user_pass = $request['password'];
  1115 			$prepared_user->user_pass = $request['password'];
  1014 		}
  1116 		}
  1015 
  1117 
  1016 		// optional arguments.
  1118 		// Optional arguments.
  1017 		if ( isset( $request['id'] ) ) {
  1119 		if ( isset( $request['id'] ) ) {
  1018 			$prepared_user->ID = absint( $request['id'] );
  1120 			$prepared_user->ID = absint( $request['id'] );
  1019 		}
  1121 		}
  1020 
  1122 
  1021 		if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) {
  1123 		if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) {
  1048 
  1150 
  1049 		if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) {
  1151 		if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) {
  1050 			$prepared_user->locale = $request['locale'];
  1152 			$prepared_user->locale = $request['locale'];
  1051 		}
  1153 		}
  1052 
  1154 
  1053 		// setting roles will be handled outside of this function.
  1155 		// Setting roles will be handled outside of this function.
  1054 		if ( isset( $request['roles'] ) ) {
  1156 		if ( isset( $request['roles'] ) ) {
  1055 			$prepared_user->role = false;
  1157 			$prepared_user->role = false;
  1056 		}
  1158 		}
  1057 
  1159 
  1058 		/**
  1160 		/**
  1080 		global $wp_roles;
  1182 		global $wp_roles;
  1081 
  1183 
  1082 		foreach ( $roles as $role ) {
  1184 		foreach ( $roles as $role ) {
  1083 
  1185 
  1084 			if ( ! isset( $wp_roles->role_objects[ $role ] ) ) {
  1186 			if ( ! isset( $wp_roles->role_objects[ $role ] ) ) {
  1085 				/* translators: %s: role key */
  1187 				return new WP_Error(
  1086 				return new WP_Error( 'rest_user_invalid_role', sprintf( __( 'The role %s does not exist.' ), $role ), array( 'status' => 400 ) );
  1188 					'rest_user_invalid_role',
       
  1189 					/* translators: %s: Role key. */
       
  1190 					sprintf( __( 'The role %s does not exist.' ), $role ),
       
  1191 					array( 'status' => 400 )
       
  1192 				);
  1087 			}
  1193 			}
  1088 
  1194 
  1089 			$potential_role = $wp_roles->role_objects[ $role ];
  1195 			$potential_role = $wp_roles->role_objects[ $role ];
  1090 
  1196 
  1091 			/*
  1197 			/*
  1095 			if ( ! ( is_multisite()
  1201 			if ( ! ( is_multisite()
  1096 				&& current_user_can( 'manage_sites' ) )
  1202 				&& current_user_can( 'manage_sites' ) )
  1097 				&& get_current_user_id() === $user_id
  1203 				&& get_current_user_id() === $user_id
  1098 				&& ! $potential_role->has_cap( 'edit_users' )
  1204 				&& ! $potential_role->has_cap( 'edit_users' )
  1099 			) {
  1205 			) {
  1100 				return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => rest_authorization_required_code() ) );
  1206 				return new WP_Error(
  1101 			}
  1207 					'rest_user_invalid_role',
  1102 
  1208 					__( 'Sorry, you are not allowed to give users that role.' ),
  1103 			/** Include admin functions to get access to get_editable_roles() */
  1209 					array( 'status' => rest_authorization_required_code() )
  1104 			require_once ABSPATH . 'wp-admin/includes/admin.php';
  1210 				);
       
  1211 			}
       
  1212 
       
  1213 			// Include user admin functions to get access to get_editable_roles().
       
  1214 			require_once ABSPATH . 'wp-admin/includes/user.php';
  1105 
  1215 
  1106 			// The new role must be editable by the logged-in user.
  1216 			// The new role must be editable by the logged-in user.
  1107 			$editable_roles = get_editable_roles();
  1217 			$editable_roles = get_editable_roles();
  1108 
  1218 
  1109 			if ( empty( $editable_roles[ $role ] ) ) {
  1219 			if ( empty( $editable_roles[ $role ] ) ) {
  1110 				return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => 403 ) );
  1220 				return new WP_Error(
       
  1221 					'rest_user_invalid_role',
       
  1222 					__( 'Sorry, you are not allowed to give users that role.' ),
       
  1223 					array( 'status' => 403 )
       
  1224 				);
  1111 			}
  1225 			}
  1112 		}
  1226 		}
  1113 
  1227 
  1114 		return true;
  1228 		return true;
  1115 	}
  1229 	}
  1119 	 *
  1233 	 *
  1120 	 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
  1234 	 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
  1121 	 *
  1235 	 *
  1122 	 * @since 4.7.0
  1236 	 * @since 4.7.0
  1123 	 *
  1237 	 *
  1124 	 * @param  mixed            $value   The username submitted in the request.
  1238 	 * @param string          $value   The username submitted in the request.
  1125 	 * @param  WP_REST_Request  $request Full details about the request.
  1239 	 * @param WP_REST_Request $request Full details about the request.
  1126 	 * @param  string           $param   The parameter name.
  1240 	 * @param string          $param   The parameter name.
  1127 	 * @return WP_Error|string The sanitized username, if valid, otherwise an error.
  1241 	 * @return string|WP_Error The sanitized username, if valid, otherwise an error.
  1128 	 */
  1242 	 */
  1129 	public function check_username( $value, $request, $param ) {
  1243 	public function check_username( $value, $request, $param ) {
  1130 		$username = (string) $value;
  1244 		$username = (string) $value;
  1131 
  1245 
  1132 		if ( ! validate_username( $username ) ) {
  1246 		if ( ! validate_username( $username ) ) {
  1133 			return new WP_Error( 'rest_user_invalid_username', __( 'Username contains invalid characters.' ), array( 'status' => 400 ) );
  1247 			return new WP_Error(
       
  1248 				'rest_user_invalid_username',
       
  1249 				__( 'This username is invalid because it uses illegal characters. Please enter a valid username.' ),
       
  1250 				array( 'status' => 400 )
       
  1251 			);
  1134 		}
  1252 		}
  1135 
  1253 
  1136 		/** This filter is documented in wp-includes/user.php */
  1254 		/** This filter is documented in wp-includes/user.php */
  1137 		$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
  1255 		$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
  1138 
  1256 
  1139 		if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ) ) ) {
  1257 		if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) {
  1140 			return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) );
  1258 			return new WP_Error(
       
  1259 				'rest_user_invalid_username',
       
  1260 				__( 'Sorry, that username is not allowed.' ),
       
  1261 				array( 'status' => 400 )
       
  1262 			);
  1141 		}
  1263 		}
  1142 
  1264 
  1143 		return $username;
  1265 		return $username;
  1144 	}
  1266 	}
  1145 
  1267 
  1148 	 *
  1270 	 *
  1149 	 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
  1271 	 * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
  1150 	 *
  1272 	 *
  1151 	 * @since 4.7.0
  1273 	 * @since 4.7.0
  1152 	 *
  1274 	 *
  1153 	 * @param  mixed            $value   The password submitted in the request.
  1275 	 * @param string          $value   The password submitted in the request.
  1154 	 * @param  WP_REST_Request  $request Full details about the request.
  1276 	 * @param WP_REST_Request $request Full details about the request.
  1155 	 * @param  string           $param   The parameter name.
  1277 	 * @param string          $param   The parameter name.
  1156 	 * @return WP_Error|string The sanitized password, if valid, otherwise an error.
  1278 	 * @return string|WP_Error The sanitized password, if valid, otherwise an error.
  1157 	 */
  1279 	 */
  1158 	public function check_user_password( $value, $request, $param ) {
  1280 	public function check_user_password( $value, $request, $param ) {
  1159 		$password = (string) $value;
  1281 		$password = (string) $value;
  1160 
  1282 
  1161 		if ( empty( $password ) ) {
  1283 		if ( empty( $password ) ) {
  1162 			return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) );
  1284 			return new WP_Error(
       
  1285 				'rest_user_invalid_password',
       
  1286 				__( 'Passwords cannot be empty.' ),
       
  1287 				array( 'status' => 400 )
       
  1288 			);
  1163 		}
  1289 		}
  1164 
  1290 
  1165 		if ( false !== strpos( $password, '\\' ) ) {
  1291 		if ( false !== strpos( $password, '\\' ) ) {
  1166 			return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) );
  1292 			return new WP_Error(
       
  1293 				'rest_user_invalid_password',
       
  1294 				__( 'Passwords cannot contain the "\\" character.' ),
       
  1295 				array( 'status' => 400 )
       
  1296 			);
  1167 		}
  1297 		}
  1168 
  1298 
  1169 		return $password;
  1299 		return $password;
  1170 	}
  1300 	}
  1171 
  1301 
  1175 	 * @since 4.7.0
  1305 	 * @since 4.7.0
  1176 	 *
  1306 	 *
  1177 	 * @return array Item schema data.
  1307 	 * @return array Item schema data.
  1178 	 */
  1308 	 */
  1179 	public function get_item_schema() {
  1309 	public function get_item_schema() {
       
  1310 		if ( $this->schema ) {
       
  1311 			return $this->add_additional_fields_schema( $this->schema );
       
  1312 		}
       
  1313 
  1180 		$schema = array(
  1314 		$schema = array(
  1181 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
  1315 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
  1182 			'title'      => 'user',
  1316 			'title'      => 'user',
  1183 			'type'       => 'object',
  1317 			'type'       => 'object',
  1184 			'properties' => array(
  1318 			'properties' => array(
  1312 
  1446 
  1313 			$avatar_sizes = rest_get_avatar_sizes();
  1447 			$avatar_sizes = rest_get_avatar_sizes();
  1314 
  1448 
  1315 			foreach ( $avatar_sizes as $size ) {
  1449 			foreach ( $avatar_sizes as $size ) {
  1316 				$avatar_properties[ $size ] = array(
  1450 				$avatar_properties[ $size ] = array(
  1317 					/* translators: %d: avatar image size in pixels */
  1451 					/* translators: %d: Avatar image size in pixels. */
  1318 					'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ),
  1452 					'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ),
  1319 					'type'        => 'string',
  1453 					'type'        => 'string',
  1320 					'format'      => 'uri',
  1454 					'format'      => 'uri',
  1321 					'context'     => array( 'embed', 'view', 'edit' ),
  1455 					'context'     => array( 'embed', 'view', 'edit' ),
  1322 				);
  1456 				);
  1331 			);
  1465 			);
  1332 		}
  1466 		}
  1333 
  1467 
  1334 		$schema['properties']['meta'] = $this->meta->get_field_schema();
  1468 		$schema['properties']['meta'] = $this->meta->get_field_schema();
  1335 
  1469 
  1336 		return $this->add_additional_fields_schema( $schema );
  1470 		$this->schema = $schema;
       
  1471 
       
  1472 		return $this->add_additional_fields_schema( $this->schema );
  1337 	}
  1473 	}
  1338 
  1474 
  1339 	/**
  1475 	/**
  1340 	 * Retrieves the query params for collections.
  1476 	 * Retrieves the query params for collections.
  1341 	 *
  1477 	 *