wp/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php
changeset 18 be944660c56a
parent 16 a86126ab1dd4
child 21 48c4eec2b7e6
--- a/wp/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php	Tue Dec 15 15:52:01 2020 +0100
+++ b/wp/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php	Wed Sep 21 18:19:35 2022 +0200
@@ -48,10 +48,13 @@
 	 * Registers the meta field.
 	 *
 	 * @since 4.7.0
+	 * @deprecated 5.6.0
 	 *
 	 * @see register_rest_field()
 	 */
 	public function register_field() {
+		_deprecated_function( __METHOD__, '5.6.0' );
+
 		register_rest_field(
 			$this->get_rest_field_type(),
 			'meta',
@@ -91,8 +94,10 @@
 			} else {
 				$value = array();
 
-				foreach ( $all_values as $row ) {
-					$value[] = $this->prepare_value_for_response( $row, $request, $args );
+				if ( is_array( $all_values ) ) {
+					foreach ( $all_values as $row ) {
+						$value[] = $this->prepare_value_for_response( $row, $request, $args );
+					}
 				}
 			}
 
@@ -142,11 +147,15 @@
 				continue;
 			}
 
+			$value = $meta[ $name ];
+
 			/*
 			 * A null value means reset the field, which is essentially deleting it
 			 * from the database and then relying on the default value.
+			 *
+			 * Non-single meta can also be removed by passing an empty array.
 			 */
-			if ( is_null( $meta[ $name ] ) ) {
+			if ( is_null( $value ) || ( array() === $value && ! $args['single'] ) ) {
 				$args = $this->get_registered_fields()[ $meta_key ];
 
 				if ( $args['single'] ) {
@@ -169,8 +178,6 @@
 				continue;
 			}
 
-			$value = $meta[ $name ];
-
 			if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) {
 				return new WP_Error(
 					'rest_invalid_stored_value',
@@ -210,7 +217,7 @@
 	 * @param int    $object_id Object ID the field belongs to.
 	 * @param string $meta_key  Key for the field.
 	 * @param string $name      Name for the field that is exposed in the REST API.
-	 * @return bool|WP_Error True if meta field is deleted, WP_Error otherwise.
+	 * @return true|WP_Error True if meta field is deleted, WP_Error otherwise.
 	 */
 	protected function delete_meta_value( $object_id, $meta_key, $name ) {
 		$meta_type = $this->get_meta_type();
@@ -227,6 +234,10 @@
 			);
 		}
 
+		if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
+			return true;
+		}
+
 		if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) {
 			return new WP_Error(
 				'rest_meta_database_error',
@@ -252,7 +263,7 @@
 	 * @param string $meta_key  Key for the custom field.
 	 * @param string $name      Name for the field that is exposed in the REST API.
 	 * @param array  $values    List of values to update to.
-	 * @return bool|WP_Error True if meta fields are updated, WP_Error otherwise.
+	 * @return true|WP_Error True if meta fields are updated, WP_Error otherwise.
 	 */
 	protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) {
 		$meta_type = $this->get_meta_type();
@@ -272,6 +283,10 @@
 		$current_values = get_metadata( $meta_type, $object_id, $meta_key, false );
 		$subtype        = get_object_subtype( $meta_type, $object_id );
 
+		if ( ! is_array( $current_values ) ) {
+			$current_values = array();
+		}
+
 		$to_remove = $current_values;
 		$to_add    = $values;
 
@@ -347,7 +362,7 @@
 	 * @param string $meta_key  Key for the custom field.
 	 * @param string $name      Name for the field that is exposed in the REST API.
 	 * @param mixed  $value     Updated value.
-	 * @return bool|WP_Error True if the meta field was updated, WP_Error otherwise.
+	 * @return true|WP_Error True if the meta field was updated, WP_Error otherwise.
 	 */
 	protected function update_meta_value( $object_id, $meta_key, $name, $value ) {
 		$meta_type = $this->get_meta_type();
@@ -368,11 +383,13 @@
 		$old_value = get_metadata( $meta_type, $object_id, $meta_key );
 		$subtype   = get_object_subtype( $meta_type, $object_id );
 
-		if ( 1 === count( $old_value ) && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) ) {
+		if ( is_array( $old_value ) && 1 === count( $old_value )
+			&& $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value )
+		) {
 			return true;
 		}
 
-		if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash_strings_only( $value ) ) ) {
+		if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) {
 			return new WP_Error(
 				'rest_meta_database_error',
 				/* translators: %s: Custom field key. */
@@ -463,7 +480,7 @@
 				$rest_args['schema']['default'] = static::get_empty_value_for_type( $type );
 			}
 
-			$rest_args['schema'] = $this->default_additional_properties_to_false( $rest_args['schema'] );
+			$rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] );
 
 			if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) {
 				continue;
@@ -568,27 +585,15 @@
 	 * default.
 	 *
 	 * @since 5.3.0
+	 * @deprecated 5.6.0 Use rest_default_additional_properties_to_false() instead.
 	 *
 	 * @param array $schema The schema array.
 	 * @return array
 	 */
 	protected function default_additional_properties_to_false( $schema ) {
-		switch ( $schema['type'] ) {
-			case 'object':
-				foreach ( $schema['properties'] as $key => $child_schema ) {
-					$schema['properties'][ $key ] = $this->default_additional_properties_to_false( $child_schema );
-				}
+		_deprecated_function( __METHOD__, '5.6.0', 'rest_default_additional_properties_to_false()' );
 
-				if ( ! isset( $schema['additionalProperties'] ) ) {
-					$schema['additionalProperties'] = false;
-				}
-				break;
-			case 'array':
-				$schema['items'] = $this->default_additional_properties_to_false( $schema['items'] );
-				break;
-		}
-
-		return $schema;
+		return rest_default_additional_properties_to_false( $schema );
 	}
 
 	/**