wp/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    73 			return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) );
    73 			return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) );
    74 		}
    74 		}
    75 
    75 
    76 		// Attaching media to a post requires ability to edit said post.
    76 		// Attaching media to a post requires ability to edit said post.
    77 		if ( ! empty( $request['post'] ) ) {
    77 		if ( ! empty( $request['post'] ) ) {
    78 			$parent = get_post( (int) $request['post'] );
    78 			$parent           = get_post( (int) $request['post'] );
    79 			$post_parent_type = get_post_type_object( $parent->post_type );
    79 			$post_parent_type = get_post_type_object( $parent->post_type );
    80 
    80 
    81 			if ( ! current_user_can( $post_parent_type->cap->edit_post, $request['post'] ) ) {
    81 			if ( ! current_user_can( $post_parent_type->cap->edit_post, $request['post'] ) ) {
    82 				return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to upload media to this post.' ), array( 'status' => rest_authorization_required_code() ) );
    82 				return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to upload media to this post.' ), array( 'status' => rest_authorization_required_code() ) );
    83 			}
    83 			}
    99 		if ( ! empty( $request['post'] ) && in_array( get_post_type( $request['post'] ), array( 'revision', 'attachment' ), true ) ) {
    99 		if ( ! empty( $request['post'] ) && in_array( get_post_type( $request['post'] ), array( 'revision', 'attachment' ), true ) ) {
   100 			return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) );
   100 			return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) );
   101 		}
   101 		}
   102 
   102 
   103 		// Get the file via $_FILES or raw data.
   103 		// Get the file via $_FILES or raw data.
   104 		$files = $request->get_file_params();
   104 		$files   = $request->get_file_params();
   105 		$headers = $request->get_headers();
   105 		$headers = $request->get_headers();
   106 
   106 
   107 		if ( ! empty( $files ) ) {
   107 		if ( ! empty( $files ) ) {
   108 			$file = $this->upload_from_file( $files, $headers );
   108 			$file = $this->upload_from_file( $files, $headers );
   109 		} else {
   109 		} else {
   112 
   112 
   113 		if ( is_wp_error( $file ) ) {
   113 		if ( is_wp_error( $file ) ) {
   114 			return $file;
   114 			return $file;
   115 		}
   115 		}
   116 
   116 
   117 		$name       = basename( $file['file'] );
   117 		$name       = wp_basename( $file['file'] );
   118 		$name_parts = pathinfo( $name );
   118 		$name_parts = pathinfo( $name );
   119 		$name       = trim( substr( $name, 0, -(1 + strlen( $name_parts['extension'] ) ) ) );
   119 		$name       = trim( substr( $name, 0, -( 1 + strlen( $name_parts['extension'] ) ) ) );
   120 
   120 
   121 		$url     = $file['url'];
   121 		$url  = $file['url'];
   122 		$type    = $file['type'];
   122 		$type = $file['type'];
   123 		$file    = $file['file'];
   123 		$file = $file['file'];
       
   124 
       
   125 		// Include image functions to get access to wp_read_image_metadata().
       
   126 		require_once ABSPATH . 'wp-admin/includes/image.php';
   124 
   127 
   125 		// use image exif/iptc data for title and caption defaults if possible
   128 		// use image exif/iptc data for title and caption defaults if possible
   126 		$image_meta = wp_read_image_metadata( $file );
   129 		$image_meta = wp_read_image_metadata( $file );
   127 
   130 
   128 		if ( ! empty( $image_meta ) ) {
   131 		if ( ! empty( $image_meta ) ) {
   133 			if ( empty( $request['caption'] ) && trim( $image_meta['caption'] ) ) {
   136 			if ( empty( $request['caption'] ) && trim( $image_meta['caption'] ) ) {
   134 				$request['caption'] = $image_meta['caption'];
   137 				$request['caption'] = $image_meta['caption'];
   135 			}
   138 			}
   136 		}
   139 		}
   137 
   140 
   138 		$attachment = $this->prepare_item_for_database( $request );
   141 		$attachment                 = $this->prepare_item_for_database( $request );
   139 		$attachment->post_mime_type = $type;
   142 		$attachment->post_mime_type = $type;
   140 		$attachment->guid = $url;
   143 		$attachment->guid           = $url;
   141 
   144 
   142 		if ( empty( $attachment->post_title ) ) {
   145 		if ( empty( $attachment->post_title ) ) {
   143 			$attachment->post_title = preg_replace( '/\.[^.]+$/', '', basename( $file ) );
   146 			$attachment->post_title = preg_replace( '/\.[^.]+$/', '', wp_basename( $file ) );
   144 		}
   147 		}
   145 
   148 
   146 		// $post_parent is inherited from $attachment['post_parent'].
   149 		// $post_parent is inherited from $attachment['post_parent'].
   147 		$id = wp_insert_attachment( wp_slash( (array) $attachment ), $file, 0, true );
   150 		$id = wp_insert_attachment( wp_slash( (array) $attachment ), $file, 0, true );
   148 
   151 
   167 		 * @param WP_REST_Request $request    The request sent to the API.
   170 		 * @param WP_REST_Request $request    The request sent to the API.
   168 		 * @param bool            $creating   True when creating an attachment, false when updating.
   171 		 * @param bool            $creating   True when creating an attachment, false when updating.
   169 		 */
   172 		 */
   170 		do_action( 'rest_insert_attachment', $attachment, $request, true );
   173 		do_action( 'rest_insert_attachment', $attachment, $request, true );
   171 
   174 
   172 		// Include admin functions to get access to wp_generate_attachment_metadata().
   175 		// Include admin function to get access to wp_generate_attachment_metadata().
   173 		require_once ABSPATH . 'wp-admin/includes/admin.php';
   176 		require_once ABSPATH . 'wp-admin/includes/media.php';
   174 
   177 
   175 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
   178 		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
   176 
   179 
   177 		if ( isset( $request['alt_text'] ) ) {
   180 		if ( isset( $request['alt_text'] ) ) {
   178 			update_post_meta( $id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) );
   181 			update_post_meta( $id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) );
   183 		if ( is_wp_error( $fields_update ) ) {
   186 		if ( is_wp_error( $fields_update ) ) {
   184 			return $fields_update;
   187 			return $fields_update;
   185 		}
   188 		}
   186 
   189 
   187 		$request->set_param( 'context', 'edit' );
   190 		$request->set_param( 'context', 'edit' );
       
   191 
       
   192 		/**
       
   193 		 * Fires after a single attachment is completely created or updated via the REST API.
       
   194 		 *
       
   195 		 * @since 5.0.0
       
   196 		 *
       
   197 		 * @param WP_Post         $attachment Inserted or updated attachment object.
       
   198 		 * @param WP_REST_Request $request    Request object.
       
   199 		 * @param bool            $creating   True when creating an attachment, false when updating.
       
   200 		 */
       
   201 		do_action( 'rest_after_insert_attachment', $attachment, $request, true );
       
   202 
   188 		$response = $this->prepare_item_for_response( $attachment, $request );
   203 		$response = $this->prepare_item_for_response( $attachment, $request );
   189 		$response = rest_ensure_response( $response );
   204 		$response = rest_ensure_response( $response );
   190 		$response->set_status( 201 );
   205 		$response->set_status( 201 );
   191 		$response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $id ) ) );
   206 		$response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $id ) ) );
   192 
   207 
   211 		if ( is_wp_error( $response ) ) {
   226 		if ( is_wp_error( $response ) ) {
   212 			return $response;
   227 			return $response;
   213 		}
   228 		}
   214 
   229 
   215 		$response = rest_ensure_response( $response );
   230 		$response = rest_ensure_response( $response );
   216 		$data = $response->get_data();
   231 		$data     = $response->get_data();
   217 
   232 
   218 		if ( isset( $request['alt_text'] ) ) {
   233 		if ( isset( $request['alt_text'] ) ) {
   219 			update_post_meta( $data['id'], '_wp_attachment_image_alt', $request['alt_text'] );
   234 			update_post_meta( $data['id'], '_wp_attachment_image_alt', $request['alt_text'] );
   220 		}
   235 		}
   221 
   236 
   222 		$attachment = get_post( $request['id'] );
   237 		$attachment = get_post( $request['id'] );
   223 
   238 
   224 		/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php */
       
   225 		do_action( 'rest_insert_attachment', $data, $request, false );
       
   226 
       
   227 		$fields_update = $this->update_additional_fields_for_object( $attachment, $request );
   239 		$fields_update = $this->update_additional_fields_for_object( $attachment, $request );
   228 
   240 
   229 		if ( is_wp_error( $fields_update ) ) {
   241 		if ( is_wp_error( $fields_update ) ) {
   230 			return $fields_update;
   242 			return $fields_update;
   231 		}
   243 		}
   232 
   244 
   233 		$request->set_param( 'context', 'edit' );
   245 		$request->set_param( 'context', 'edit' );
       
   246 
       
   247 		/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php */
       
   248 		do_action( 'rest_after_insert_attachment', $attachment, $request, false );
       
   249 
   234 		$response = $this->prepare_item_for_response( $attachment, $request );
   250 		$response = $this->prepare_item_for_response( $attachment, $request );
   235 		$response = rest_ensure_response( $response );
   251 		$response = rest_ensure_response( $response );
   236 
   252 
   237 		return $response;
   253 		return $response;
   238 	}
   254 	}
   370 
   386 
   371 		$links = $response->get_links();
   387 		$links = $response->get_links();
   372 
   388 
   373 		// Wrap the data in a response object.
   389 		// Wrap the data in a response object.
   374 		$response = rest_ensure_response( $data );
   390 		$response = rest_ensure_response( $data );
   375 		$response->add_links( $links );
   391 
       
   392 		foreach ( $links as $rel => $rel_links ) {
       
   393 			foreach ( $rel_links as $link ) {
       
   394 				$response->add_link( $rel, $link['href'], $link['attributes'] );
       
   395 			}
       
   396 		}
   376 
   397 
   377 		/**
   398 		/**
   378 		 * Filters an attachment returned from the REST API.
   399 		 * Filters an attachment returned from the REST API.
   379 		 *
   400 		 *
   380 		 * Allows modification of the attachment right before it is returned.
   401 		 * Allows modification of the attachment right before it is returned.
   398 	public function get_item_schema() {
   419 	public function get_item_schema() {
   399 
   420 
   400 		$schema = parent::get_item_schema();
   421 		$schema = parent::get_item_schema();
   401 
   422 
   402 		$schema['properties']['alt_text'] = array(
   423 		$schema['properties']['alt_text'] = array(
   403 			'description'     => __( 'Alternative text to display when attachment is not displayed.' ),
   424 			'description' => __( 'Alternative text to display when attachment is not displayed.' ),
   404 			'type'            => 'string',
   425 			'type'        => 'string',
   405 			'context'         => array( 'view', 'edit', 'embed' ),
   426 			'context'     => array( 'view', 'edit', 'embed' ),
   406 			'arg_options'     => array(
   427 			'arg_options' => array(
   407 				'sanitize_callback' => 'sanitize_text_field',
   428 				'sanitize_callback' => 'sanitize_text_field',
   408 			),
   429 			),
   409 		);
   430 		);
   410 
   431 
   411 		$schema['properties']['caption'] = array(
   432 		$schema['properties']['caption'] = array(
   415 			'arg_options' => array(
   436 			'arg_options' => array(
   416 				'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database()
   437 				'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database()
   417 				'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database()
   438 				'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database()
   418 			),
   439 			),
   419 			'properties'  => array(
   440 			'properties'  => array(
   420 				'raw' => array(
   441 				'raw'      => array(
   421 					'description' => __( 'Caption for the attachment, as it exists in the database.' ),
   442 					'description' => __( 'Caption for the attachment, as it exists in the database.' ),
   422 					'type'        => 'string',
   443 					'type'        => 'string',
   423 					'context'     => array( 'edit' ),
   444 					'context'     => array( 'edit' ),
   424 				),
   445 				),
   425 				'rendered' => array(
   446 				'rendered' => array(
   438 			'arg_options' => array(
   459 			'arg_options' => array(
   439 				'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database()
   460 				'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database()
   440 				'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database()
   461 				'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database()
   441 			),
   462 			),
   442 			'properties'  => array(
   463 			'properties'  => array(
   443 				'raw' => array(
   464 				'raw'      => array(
   444 					'description' => __( 'Description for the object, as it exists in the database.' ),
   465 					'description' => __( 'Description for the object, as it exists in the database.' ),
   445 					'type'        => 'string',
   466 					'type'        => 'string',
   446 					'context'     => array( 'edit' ),
   467 					'context'     => array( 'edit' ),
   447 				),
   468 				),
   448 				'rendered' => array(
   469 				'rendered' => array(
   453 				),
   474 				),
   454 			),
   475 			),
   455 		);
   476 		);
   456 
   477 
   457 		$schema['properties']['media_type'] = array(
   478 		$schema['properties']['media_type'] = array(
   458 			'description'     => __( 'Attachment type.' ),
   479 			'description' => __( 'Attachment type.' ),
   459 			'type'            => 'string',
   480 			'type'        => 'string',
   460 			'enum'            => array( 'image', 'file' ),
   481 			'enum'        => array( 'image', 'file' ),
   461 			'context'         => array( 'view', 'edit', 'embed' ),
   482 			'context'     => array( 'view', 'edit', 'embed' ),
   462 			'readonly'        => true,
   483 			'readonly'    => true,
   463 		);
   484 		);
   464 
   485 
   465 		$schema['properties']['mime_type'] = array(
   486 		$schema['properties']['mime_type'] = array(
   466 			'description'     => __( 'The attachment MIME type.' ),
   487 			'description' => __( 'The attachment MIME type.' ),
   467 			'type'            => 'string',
   488 			'type'        => 'string',
   468 			'context'         => array( 'view', 'edit', 'embed' ),
   489 			'context'     => array( 'view', 'edit', 'embed' ),
   469 			'readonly'        => true,
   490 			'readonly'    => true,
   470 		);
   491 		);
   471 
   492 
   472 		$schema['properties']['media_details'] = array(
   493 		$schema['properties']['media_details'] = array(
   473 			'description'     => __( 'Details about the media file, specific to its type.' ),
   494 			'description' => __( 'Details about the media file, specific to its type.' ),
   474 			'type'            => 'object',
   495 			'type'        => 'object',
   475 			'context'         => array( 'view', 'edit', 'embed' ),
   496 			'context'     => array( 'view', 'edit', 'embed' ),
   476 			'readonly'        => true,
   497 			'readonly'    => true,
   477 		);
   498 		);
   478 
   499 
   479 		$schema['properties']['post'] = array(
   500 		$schema['properties']['post'] = array(
   480 			'description'     => __( 'The ID for the associated post of the attachment.' ),
   501 			'description' => __( 'The ID for the associated post of the attachment.' ),
   481 			'type'            => 'integer',
   502 			'type'        => 'integer',
   482 			'context'         => array( 'view', 'edit' ),
   503 			'context'     => array( 'view', 'edit' ),
   483 		);
   504 		);
   484 
   505 
   485 		$schema['properties']['source_url'] = array(
   506 		$schema['properties']['source_url'] = array(
   486 			'description'     => __( 'URL to the original attachment file.' ),
   507 			'description' => __( 'URL to the original attachment file.' ),
   487 			'type'            => 'string',
   508 			'type'        => 'string',
   488 			'format'          => 'uri',
   509 			'format'      => 'uri',
   489 			'context'         => array( 'view', 'edit', 'embed' ),
   510 			'context'     => array( 'view', 'edit', 'embed' ),
   490 			'readonly'        => true,
   511 			'readonly'    => true,
   491 		);
   512 		);
   492 
   513 
   493 		unset( $schema['properties']['password'] );
   514 		unset( $schema['properties']['password'] );
   494 
   515 
   495 		return $schema;
   516 		return $schema;
   534 		}
   555 		}
   535 
   556 
   536 		// Get the content-type.
   557 		// Get the content-type.
   537 		$type = array_shift( $headers['content_type'] );
   558 		$type = array_shift( $headers['content_type'] );
   538 
   559 
   539 		/** Include admin functions to get access to wp_tempnam() and wp_handle_sideload() */
   560 		/** Include admin functions to get access to wp_tempnam() and wp_handle_sideload(). */
   540 		require_once ABSPATH . 'wp-admin/includes/admin.php';
   561 		require_once ABSPATH . 'wp-admin/includes/file.php';
   541 
   562 
   542 		// Save the file.
   563 		// Save the file.
   543 		$tmpfname = wp_tempnam( $filename );
   564 		$tmpfname = wp_tempnam( $filename );
   544 
   565 
   545 		$fp = fopen( $tmpfname, 'w+' );
   566 		$fp = fopen( $tmpfname, 'w+' );
   655 	 * @since 4.7.0
   676 	 * @since 4.7.0
   656 	 *
   677 	 *
   657 	 * @return array Query parameters for the attachment collection as an array.
   678 	 * @return array Query parameters for the attachment collection as an array.
   658 	 */
   679 	 */
   659 	public function get_collection_params() {
   680 	public function get_collection_params() {
   660 		$params = parent::get_collection_params();
   681 		$params                            = parent::get_collection_params();
   661 		$params['status']['default'] = 'inherit';
   682 		$params['status']['default']       = 'inherit';
   662 		$params['status']['items']['enum'] = array( 'inherit', 'private', 'trash' );
   683 		$params['status']['items']['enum'] = array( 'inherit', 'private', 'trash' );
   663 		$media_types = $this->get_media_types();
   684 		$media_types                       = $this->get_media_types();
   664 
   685 
   665 		$params['media_type'] = array(
   686 		$params['media_type'] = array(
   666 			'default'           => null,
   687 			'default'     => null,
   667 			'description'       => __( 'Limit result set to attachments of a particular media type.' ),
   688 			'description' => __( 'Limit result set to attachments of a particular media type.' ),
   668 			'type'              => 'string',
   689 			'type'        => 'string',
   669 			'enum'              => array_keys( $media_types ),
   690 			'enum'        => array_keys( $media_types ),
   670 		);
   691 		);
   671 
   692 
   672 		$params['mime_type'] = array(
   693 		$params['mime_type'] = array(
   673 			'default'     => null,
   694 			'default'     => null,
   674 			'description' => __( 'Limit result set to attachments of a particular MIME type.' ),
   695 			'description' => __( 'Limit result set to attachments of a particular MIME type.' ),
   675 			'type'        => 'string',
   696 			'type'        => 'string',
   676 		);
   697 		);
   677 
   698 
   678 		return $params;
   699 		return $params;
   679 	}
       
   680 
       
   681 	/**
       
   682 	 * Validates whether the user can query private statuses.
       
   683 	 *
       
   684 	 * @since 4.7.0
       
   685 	 *
       
   686 	 * @param mixed           $value     Status value.
       
   687 	 * @param WP_REST_Request $request   Request object.
       
   688 	 * @param string          $parameter Additional parameter to pass for validation.
       
   689 	 * @return WP_Error|bool True if the user may query, WP_Error if not.
       
   690 	 */
       
   691 	public function validate_user_can_query_private_statuses( $value, $request, $parameter ) {
       
   692 		if ( 'inherit' === $value ) {
       
   693 			return true;
       
   694 		}
       
   695 
       
   696 		return parent::validate_user_can_query_private_statuses( $value, $request, $parameter );
       
   697 	}
   700 	}
   698 
   701 
   699 	/**
   702 	/**
   700 	 * Handles an upload via multipart/form-data ($_FILES).
   703 	 * Handles an upload via multipart/form-data ($_FILES).
   701 	 *
   704 	 *
   721 			}
   724 			}
   722 		}
   725 		}
   723 
   726 
   724 		// Pass off to WP to handle the actual upload.
   727 		// Pass off to WP to handle the actual upload.
   725 		$overrides = array(
   728 		$overrides = array(
   726 			'test_form'   => false,
   729 			'test_form' => false,
   727 		);
   730 		);
   728 
   731 
   729 		// Bypasses is_uploaded_file() when running unit tests.
   732 		// Bypasses is_uploaded_file() when running unit tests.
   730 		if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) {
   733 		if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) {
   731 			$overrides['action'] = 'wp_handle_mock_upload';
   734 			$overrides['action'] = 'wp_handle_mock_upload';
   734 		$size_check = self::check_upload_size( $files['file'] );
   737 		$size_check = self::check_upload_size( $files['file'] );
   735 		if ( is_wp_error( $size_check ) ) {
   738 		if ( is_wp_error( $size_check ) ) {
   736 			return $size_check;
   739 			return $size_check;
   737 		}
   740 		}
   738 
   741 
   739 		/** Include admin functions to get access to wp_handle_upload() */
   742 		/** Include admin function to get access to wp_handle_upload(). */
   740 		require_once ABSPATH . 'wp-admin/includes/admin.php';
   743 		require_once ABSPATH . 'wp-admin/includes/file.php';
   741 
   744 
   742 		$file = wp_handle_upload( $files['file'], $overrides );
   745 		$file = wp_handle_upload( $files['file'], $overrides );
   743 
   746 
   744 		if ( isset( $file['error'] ) ) {
   747 		if ( isset( $file['error'] ) ) {
   745 			return new WP_Error( 'rest_upload_unknown_error', $file['error'], array( 'status' => 500 ) );
   748 			return new WP_Error( 'rest_upload_unknown_error', $file['error'], array( 'status' => 500 ) );
   803 		if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
   806 		if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
   804 			/* translators: %s: maximum allowed file size in kilobytes */
   807 			/* translators: %s: maximum allowed file size in kilobytes */
   805 			return new WP_Error( 'rest_upload_file_too_big', sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) ), array( 'status' => 400 ) );
   808 			return new WP_Error( 'rest_upload_file_too_big', sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) ), array( 'status' => 400 ) );
   806 		}
   809 		}
   807 
   810 
       
   811 		// Include admin function to get access to upload_is_user_over_quota().
       
   812 		require_once ABSPATH . 'wp-admin/includes/ms.php';
       
   813 
   808 		if ( upload_is_user_over_quota( false ) ) {
   814 		if ( upload_is_user_over_quota( false ) ) {
   809 			return new WP_Error( 'rest_upload_user_quota_exceeded', __( 'You have used your space quota. Please delete files before uploading.' ), array( 'status' => 400 ) );
   815 			return new WP_Error( 'rest_upload_user_quota_exceeded', __( 'You have used your space quota. Please delete files before uploading.' ), array( 'status' => 400 ) );
   810 		}
   816 		}
   811 		return true;
   817 		return true;
   812 	}
   818 	}