From 30ff995eb0aa2660ef4b08b9e3c5f7b0126c702b Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Tue, 27 Apr 2021 18:34:52 +0000 Subject: [PATCH] REST API: Check the results of `get_metadata()` in `WP_REST_Meta_Fields` methods. This avoids PHP warnings in case the function returns boolean `false` instead of an array. Props david.binda. Fixes #53099. git-svn-id: https://develop.svn.wordpress.org/trunk@50793 602fd350-edb4-49c9-b593-d223f7449a82 --- .../fields/class-wp-rest-meta-fields.php | 14 ++++-- .../tests/rest-api/rest-term-meta-fields.php | 48 +++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php b/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php index 817f5c106a..f186648545 100644 --- a/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php +++ b/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php @@ -94,8 +94,10 @@ abstract class WP_REST_Meta_Fields { } 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 ); + } } } @@ -281,6 +283,10 @@ abstract class WP_REST_Meta_Fields { $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; @@ -377,7 +383,9 @@ abstract class WP_REST_Meta_Fields { $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; } diff --git a/tests/phpunit/tests/rest-api/rest-term-meta-fields.php b/tests/phpunit/tests/rest-api/rest-term-meta-fields.php index 6c8f3a0135..8ed2a0a26f 100644 --- a/tests/phpunit/tests/rest-api/rest-term-meta-fields.php +++ b/tests/phpunit/tests/rest-api/rest-term-meta-fields.php @@ -1285,6 +1285,54 @@ class WP_Test_REST_Term_Meta_Fields extends WP_Test_REST_TestCase { $this->assertSame( 'Goodbye', $meta[ $meta_key ] ); } + /** + * @ticket 53099 + */ + public function test_get_term_metadata_returning_false_does_not_cause_php_warnings() { + add_filter( 'get_term_metadata', '__return_false', 11 ); + + // No PHP warning during GET request. + add_term_meta( self::$category_id, 'test_single', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/categories/%d', self::$category_id ) ); + $response = rest_get_server()->dispatch( $request ); + + // No PHP warning during POST request. + $this->grant_write_permission(); + $data = array( + 'meta' => array( + 'test_multi' => array( 'val1' ), + ), + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/categories/%d', self::$category_id ) ); + $request->set_body_params( $data ); + $response = rest_get_server()->dispatch( $request ); + + // No PHP warning during validation. + register_meta( + 'term', + 'my_meta_key', + array( + 'show_in_rest' => true, + 'single' => true, + 'type' => 'integer', + ) + ); + $this->grant_write_permission(); + $data = array( + 'meta' => array( + 'my_meta_key' => '1', // Set to a string. + ), + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/categories/%d', self::$category_id ) ); + $request->set_body_params( $data ); + $response = rest_get_server()->dispatch( $request ); + + remove_filter( 'get_term_metadata', '__return_false', 11 ); + + $data = $response->get_data(); + $this->assertSame( 0, $data['meta']['my_meta_key'] ); + } + /** * Internal function used to disable an insert query which * will trigger a wpdb error for testing purposes.