From bc1e52846f1d49f1759878dfbe6907c6052132e5 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Thu, 10 Sep 2026 15:45:55 -0600 Subject: [PATCH 1/7] Check cache return value in metadata_exists(), get_metadata_raw(), and update_meta_cache() https://core.trac.wordpress.org/ticket/66091 --- src/wp-includes/meta.php | 26 ++++++++- tests/phpunit/tests/meta.php | 109 +++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php index 577785c2163a0..96542f993fece 100644 --- a/src/wp-includes/meta.php +++ b/src/wp-includes/meta.php @@ -611,6 +611,7 @@ function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) * Retrieves raw metadata value for the specified object. * * @since 5.5.0 + * @since 7.2.0 A cached value that is not an array is now treated as a cache miss. * * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term', * 'user', or any other object type with an associated meta table. @@ -672,7 +673,8 @@ function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = fal $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); - if ( ! $meta_cache ) { + // A cached value that is not an array is unusable, treat it as a cache miss. + if ( ! $meta_cache || ! is_array( $meta_cache ) ) { $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); $meta_cache = $meta_cache[ $object_id ] ?? null; } @@ -753,6 +755,7 @@ function get_metadata_default( $meta_type, $object_id, $meta_key, $single = fals * Determines if a meta field with the given key exists for the given object ID. * * @since 3.3.0 + * @since 7.2.0 A cached value that is not an array is now treated as a cache miss. * * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term', * 'user', or any other object type with an associated meta table. @@ -778,9 +781,10 @@ function metadata_exists( $meta_type, $object_id, $meta_key ) { $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); - if ( ! $meta_cache ) { + // A cached value that is not an array is unusable, treat it as a cache miss. + if ( ! $meta_cache || ! is_array( $meta_cache ) ) { $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); - $meta_cache = $meta_cache[ $object_id ]; + $meta_cache = $meta_cache[ $object_id ] ?? null; } if ( isset( $meta_cache[ $meta_key ] ) ) { @@ -1126,6 +1130,7 @@ function delete_metadata_by_mid( $meta_type, $meta_id ) { * Updates the metadata cache for the specified objects. * * @since 2.9.0 + * @since 7.2.0 A cached value that is not an array is now treated as a cache miss. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -1182,12 +1187,17 @@ function update_meta_cache( $meta_type, $object_ids ) { $cache_group = $meta_type . '_meta'; $non_cached_ids = array(); + $invalid_ids = array(); $cache = array(); $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); foreach ( $cache_values as $id => $cached_object ) { if ( false === $cached_object ) { $non_cached_ids[] = $id; + } elseif ( ! is_array( $cached_object ) ) { + // A cached value that is not an array is unusable, treat it as a cache miss. + $non_cached_ids[] = $id; + $invalid_ids[] = $id; } else { $cache[ $id ] = $cached_object; } @@ -1229,6 +1239,16 @@ function update_meta_cache( $meta_type, $object_ids ) { } $data[ $id ] = $cache[ $id ]; } + + /* + * Remove unusable cached values so that the regenerated values can be added. + * A delete followed by an add is used instead of wp_cache_set_multiple() + * so that wp_suspend_cache_addition() is still respected. + */ + if ( ! empty( $invalid_ids ) ) { + wp_cache_delete_multiple( $invalid_ids, $cache_group ); + } + wp_cache_add_multiple( $data, $cache_group ); return $cache; diff --git a/tests/phpunit/tests/meta.php b/tests/phpunit/tests/meta.php index 6431a158610a5..c0d6d05df7528 100644 --- a/tests/phpunit/tests/meta.php +++ b/tests/phpunit/tests/meta.php @@ -131,6 +131,115 @@ public function test_metadata_exists_with_filter() { remove_filter( 'get_user_metadata', '__return_zero' ); } + /** + * Non-array values that can not be used as a meta cache entry. + * + * @return array + */ + public function data_non_array_cache_values(): array { + return array( + 'object' => array( new stdClass() ), + 'string' => array( 'meta_value' ), + 'integer' => array( 1 ), + 'float' => array( 1.5 ), + 'true' => array( true ), + ); + } + + /** + * @ticket 66091 + * + * @dataProvider data_non_array_cache_values + * + * @param mixed $cached_value Value to place in the meta cache. + */ + public function test_metadata_exists_treats_non_array_cache_value_as_miss( $cached_value ): void { + wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + + $this->assertTrue( metadata_exists( 'user', self::$author->ID, 'meta_key' ) ); + $this->assertFalse( metadata_exists( 'user', self::$author->ID, 'foobarbaz' ) ); + $this->assertIsArray( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should have been replaced.' ); + } + + /** + * @ticket 66091 + * + * @dataProvider data_non_array_cache_values + * + * @param mixed $cached_value Value to place in the meta cache. + */ + public function test_get_metadata_treats_non_array_cache_value_as_miss( $cached_value ): void { + wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + + $this->assertSame( 'meta_value', get_metadata( 'user', self::$author->ID, 'meta_key', true ) ); + $this->assertSame( array( 'meta_value' ), get_metadata( 'user', self::$author->ID, 'meta_key' ) ); + $this->assertIsArray( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should have been replaced.' ); + } + + /** + * @ticket 66091 + * + * @dataProvider data_non_array_cache_values + * + * @param mixed $cached_value Value to place in the meta cache. + */ + public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as_miss( $cached_value ): void { + wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + + $meta = get_metadata( 'user', self::$author->ID ); + + $this->assertIsArray( $meta ); + $this->assertSame( array( 'meta_value' ), $meta['meta_key'] ); + } + + /** + * @ticket 66091 + * + * @dataProvider data_non_array_cache_values + * + * @param mixed $cached_value Value to place in the meta cache. + */ + public function test_update_meta_cache_replaces_non_array_cache_value( $cached_value ): void { + wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + + $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); + + $this->assertIsArray( $meta_cache[ self::$author->ID ] ); + $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'] ); + + $cached = wp_cache_get( self::$author->ID, 'user_meta' ); + $this->assertIsArray( $cached, 'The unusable cache value should have been replaced.' ); + $this->assertSame( array( 'meta_value' ), $cached['meta_key'] ); + } + + /** + * @ticket 66091 + */ + public function test_update_meta_cache_replaces_non_array_cache_value_for_object_without_meta(): void { + $term_id = self::factory()->term->create(); + + wp_cache_set( $term_id, new stdClass(), 'term_meta' ); + + $meta_cache = update_meta_cache( 'term', array( $term_id ) ); + + $this->assertSame( array(), $meta_cache[ $term_id ] ); + $this->assertSame( array(), wp_cache_get( $term_id, 'term_meta' ) ); + } + + /** + * @ticket 66091 + */ + public function test_update_meta_cache_removes_non_array_cache_value_while_cache_addition_is_suspended(): void { + wp_cache_set( self::$author->ID, new stdClass(), 'user_meta' ); + + wp_suspend_cache_addition( true ); + $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); + wp_suspend_cache_addition( false ); + + $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'] ); + $this->assertFalse( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should be removed but not replaced while cache addition is suspended.' ); + } + /** * @ticket 18158 */ From 215ae901d1f7270c51f6cd874fe5057643912686 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Mon, 21 Sep 2026 08:48:42 -0600 Subject: [PATCH 2/7] Move the $invalid_ids check to happen earlier --- src/wp-includes/meta.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php index 410a7840abee2..318f7c366feb0 100644 --- a/src/wp-includes/meta.php +++ b/src/wp-includes/meta.php @@ -1242,6 +1242,15 @@ function update_meta_cache( $meta_type, $object_ids ) { } } + /* + * Remove unusable cached values so that the regenerated values can be added. + * A delete followed by an add is used instead of wp_cache_set_multiple() + * so that wp_suspend_cache_addition() is still respected. + */ + if ( ! empty( $invalid_ids ) ) { + wp_cache_delete_multiple( $invalid_ids, $cache_group ); + } + if ( empty( $non_cached_ids ) ) { return $cache; } @@ -1279,15 +1288,6 @@ function update_meta_cache( $meta_type, $object_ids ) { $data[ $id ] = $cache[ $id ]; } - /* - * Remove unusable cached values so that the regenerated values can be added. - * A delete followed by an add is used instead of wp_cache_set_multiple() - * so that wp_suspend_cache_addition() is still respected. - */ - if ( ! empty( $invalid_ids ) ) { - wp_cache_delete_multiple( $invalid_ids, $cache_group ); - } - wp_cache_add_multiple( $data, $cache_group ); return $cache; From 57b87e277fa56398fa028a448f45d326c8beee9a Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Tue, 22 Sep 2026 07:20:40 -0600 Subject: [PATCH 3/7] Update tests/phpunit/tests/meta.php Co-authored-by: Jon Surrell --- tests/phpunit/tests/meta.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/meta.php b/tests/phpunit/tests/meta.php index c0d6d05df7528..16dda00eaa478 100644 --- a/tests/phpunit/tests/meta.php +++ b/tests/phpunit/tests/meta.php @@ -136,7 +136,7 @@ public function test_metadata_exists_with_filter() { * * @return array */ - public function data_non_array_cache_values(): array { + public static function data_non_array_cache_values(): array { return array( 'object' => array( new stdClass() ), 'string' => array( 'meta_value' ), From e86acd5054e1ccdd30b5bbfb9a0ae2bc651d7f0d Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Thu, 24 Sep 2026 10:31:57 -0600 Subject: [PATCH 4/7] Rename $invalid_ids to $invalid_cache_ids --- src/wp-includes/meta.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php index 318f7c366feb0..6adcf389d5884 100644 --- a/src/wp-includes/meta.php +++ b/src/wp-includes/meta.php @@ -1224,19 +1224,19 @@ function update_meta_cache( $meta_type, $object_ids ) { return (bool) $check; } - $cache_group = $meta_type . '_meta'; - $non_cached_ids = array(); - $invalid_ids = array(); - $cache = array(); - $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); + $cache_group = $meta_type . '_meta'; + $non_cached_ids = array(); + $invalid_cache_ids = array(); + $cache = array(); + $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); foreach ( $cache_values as $id => $cached_object ) { if ( false === $cached_object ) { $non_cached_ids[] = $id; } elseif ( ! is_array( $cached_object ) ) { // A cached value that is not an array is unusable, treat it as a cache miss. - $non_cached_ids[] = $id; - $invalid_ids[] = $id; + $non_cached_ids[] = $id; + $invalid_cache_ids[] = $id; } else { $cache[ $id ] = $cached_object; } @@ -1247,8 +1247,8 @@ function update_meta_cache( $meta_type, $object_ids ) { * A delete followed by an add is used instead of wp_cache_set_multiple() * so that wp_suspend_cache_addition() is still respected. */ - if ( ! empty( $invalid_ids ) ) { - wp_cache_delete_multiple( $invalid_ids, $cache_group ); + if ( ! empty( $invalid_cache_ids ) ) { + wp_cache_delete_multiple( $invalid_cache_ids, $cache_group ); } if ( empty( $non_cached_ids ) ) { From a3cf1c6cf1961b3fff78618d9fe29d856da40db8 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Thu, 24 Sep 2026 10:54:59 -0600 Subject: [PATCH 5/7] Add a unique message to each test assertion --- tests/phpunit/tests/meta.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/phpunit/tests/meta.php b/tests/phpunit/tests/meta.php index 16dda00eaa478..71a0c0f2e3de3 100644 --- a/tests/phpunit/tests/meta.php +++ b/tests/phpunit/tests/meta.php @@ -154,10 +154,10 @@ public static function data_non_array_cache_values(): array { * @param mixed $cached_value Value to place in the meta cache. */ public function test_metadata_exists_treats_non_array_cache_value_as_miss( $cached_value ): void { - wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); - $this->assertTrue( metadata_exists( 'user', self::$author->ID, 'meta_key' ) ); - $this->assertFalse( metadata_exists( 'user', self::$author->ID, 'foobarbaz' ) ); + $this->assertTrue( metadata_exists( 'user', self::$author->ID, 'meta_key' ), 'An existing meta key should be reported as existing.' ); + $this->assertFalse( metadata_exists( 'user', self::$author->ID, 'foobarbaz' ), 'A missing meta key should be reported as not existing.' ); $this->assertIsArray( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should have been replaced.' ); } @@ -169,10 +169,10 @@ public function test_metadata_exists_treats_non_array_cache_value_as_miss( $cach * @param mixed $cached_value Value to place in the meta cache. */ public function test_get_metadata_treats_non_array_cache_value_as_miss( $cached_value ): void { - wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); - $this->assertSame( 'meta_value', get_metadata( 'user', self::$author->ID, 'meta_key', true ) ); - $this->assertSame( array( 'meta_value' ), get_metadata( 'user', self::$author->ID, 'meta_key' ) ); + $this->assertSame( 'meta_value', get_metadata( 'user', self::$author->ID, 'meta_key', true ), 'The single meta value should be returned.' ); + $this->assertSame( array( 'meta_value' ), get_metadata( 'user', self::$author->ID, 'meta_key' ), 'The array of meta values should be returned.' ); $this->assertIsArray( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should have been replaced.' ); } @@ -184,12 +184,12 @@ public function test_get_metadata_treats_non_array_cache_value_as_miss( $cached_ * @param mixed $cached_value Value to place in the meta cache. */ public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as_miss( $cached_value ): void { - wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $meta = get_metadata( 'user', self::$author->ID ); - $this->assertIsArray( $meta ); - $this->assertSame( array( 'meta_value' ), $meta['meta_key'] ); + $this->assertIsArray( $meta, 'All meta for the object should be returned as an array.' ); + $this->assertSame( array( 'meta_value' ), $meta['meta_key'], 'The existing meta key should be included in the returned meta.' ); } /** @@ -200,16 +200,16 @@ public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as * @param mixed $cached_value Value to place in the meta cache. */ public function test_update_meta_cache_replaces_non_array_cache_value( $cached_value ): void { - wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ); + $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); - $this->assertIsArray( $meta_cache[ self::$author->ID ] ); - $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'] ); + $this->assertIsArray( $meta_cache[ self::$author->ID ], 'The returned meta cache for the object should be an array.' ); + $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'], 'The returned meta cache should include the existing meta key.' ); $cached = wp_cache_get( self::$author->ID, 'user_meta' ); $this->assertIsArray( $cached, 'The unusable cache value should have been replaced.' ); - $this->assertSame( array( 'meta_value' ), $cached['meta_key'] ); + $this->assertSame( array( 'meta_value' ), $cached['meta_key'], 'The replaced cache value should include the existing meta key.' ); } /** @@ -218,25 +218,25 @@ public function test_update_meta_cache_replaces_non_array_cache_value( $cached_v public function test_update_meta_cache_replaces_non_array_cache_value_for_object_without_meta(): void { $term_id = self::factory()->term->create(); - wp_cache_set( $term_id, new stdClass(), 'term_meta' ); + $this->assertTrue( wp_cache_set( $term_id, new stdClass(), 'term_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $meta_cache = update_meta_cache( 'term', array( $term_id ) ); - $this->assertSame( array(), $meta_cache[ $term_id ] ); - $this->assertSame( array(), wp_cache_get( $term_id, 'term_meta' ) ); + $this->assertSame( array(), $meta_cache[ $term_id ], 'The returned meta cache for an object without meta should be an empty array.' ); + $this->assertSame( array(), wp_cache_get( $term_id, 'term_meta' ), 'The unusable cache value should have been replaced with an empty array.' ); } /** * @ticket 66091 */ public function test_update_meta_cache_removes_non_array_cache_value_while_cache_addition_is_suspended(): void { - wp_cache_set( self::$author->ID, new stdClass(), 'user_meta' ); + $this->assertTrue( wp_cache_set( self::$author->ID, new stdClass(), 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); wp_suspend_cache_addition( true ); $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); wp_suspend_cache_addition( false ); - $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'] ); + $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'], 'The meta should still be returned while cache addition is suspended.' ); $this->assertFalse( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should be removed but not replaced while cache addition is suspended.' ); } From 11eeaab2e75b29ba077c7489bdb20d5328cf2206 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Thu, 24 Sep 2026 11:17:47 -0600 Subject: [PATCH 6/7] Rename $cached_value to $invalid_cached_value in tests --- tests/phpunit/tests/meta.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/phpunit/tests/meta.php b/tests/phpunit/tests/meta.php index 71a0c0f2e3de3..ec75b957aadf5 100644 --- a/tests/phpunit/tests/meta.php +++ b/tests/phpunit/tests/meta.php @@ -151,10 +151,10 @@ public static function data_non_array_cache_values(): array { * * @dataProvider data_non_array_cache_values * - * @param mixed $cached_value Value to place in the meta cache. + * @param mixed $invalid_cached_value Unusable value to place in the meta cache. */ - public function test_metadata_exists_treats_non_array_cache_value_as_miss( $cached_value ): void { - $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); + public function test_metadata_exists_treats_non_array_cache_value_as_miss( $invalid_cached_value ): void { + $this->assertTrue( wp_cache_set( self::$author->ID, $invalid_cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $this->assertTrue( metadata_exists( 'user', self::$author->ID, 'meta_key' ), 'An existing meta key should be reported as existing.' ); $this->assertFalse( metadata_exists( 'user', self::$author->ID, 'foobarbaz' ), 'A missing meta key should be reported as not existing.' ); @@ -166,10 +166,10 @@ public function test_metadata_exists_treats_non_array_cache_value_as_miss( $cach * * @dataProvider data_non_array_cache_values * - * @param mixed $cached_value Value to place in the meta cache. + * @param mixed $invalid_cached_value Unusable value to place in the meta cache. */ - public function test_get_metadata_treats_non_array_cache_value_as_miss( $cached_value ): void { - $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); + public function test_get_metadata_treats_non_array_cache_value_as_miss( $invalid_cached_value ): void { + $this->assertTrue( wp_cache_set( self::$author->ID, $invalid_cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $this->assertSame( 'meta_value', get_metadata( 'user', self::$author->ID, 'meta_key', true ), 'The single meta value should be returned.' ); $this->assertSame( array( 'meta_value' ), get_metadata( 'user', self::$author->ID, 'meta_key' ), 'The array of meta values should be returned.' ); @@ -181,10 +181,10 @@ public function test_get_metadata_treats_non_array_cache_value_as_miss( $cached_ * * @dataProvider data_non_array_cache_values * - * @param mixed $cached_value Value to place in the meta cache. + * @param mixed $invalid_cached_value Unusable value to place in the meta cache. */ - public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as_miss( $cached_value ): void { - $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); + public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as_miss( $invalid_cached_value ): void { + $this->assertTrue( wp_cache_set( self::$author->ID, $invalid_cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $meta = get_metadata( 'user', self::$author->ID ); @@ -197,10 +197,10 @@ public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as * * @dataProvider data_non_array_cache_values * - * @param mixed $cached_value Value to place in the meta cache. + * @param mixed $invalid_cached_value Unusable value to place in the meta cache. */ - public function test_update_meta_cache_replaces_non_array_cache_value( $cached_value ): void { - $this->assertTrue( wp_cache_set( self::$author->ID, $cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); + public function test_update_meta_cache_replaces_non_array_cache_value( $invalid_cached_value ): void { + $this->assertTrue( wp_cache_set( self::$author->ID, $invalid_cached_value, 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); From 292025531cf5c6039750010907b4996da0e166ad Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 24 Sep 2026 18:11:18 -0700 Subject: [PATCH 7/7] Add assertions which guard against PHPStan errors --- tests/phpunit/tests/meta.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/phpunit/tests/meta.php b/tests/phpunit/tests/meta.php index ec75b957aadf5..3f52916d7d5de 100644 --- a/tests/phpunit/tests/meta.php +++ b/tests/phpunit/tests/meta.php @@ -204,6 +204,8 @@ public function test_update_meta_cache_replaces_non_array_cache_value( $invalid_ $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); + $this->assertIsArray( $meta_cache ); + $this->assertArrayHasKey( self::$author->ID, $meta_cache ); $this->assertIsArray( $meta_cache[ self::$author->ID ], 'The returned meta cache for the object should be an array.' ); $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'], 'The returned meta cache should include the existing meta key.' ); @@ -221,6 +223,8 @@ public function test_update_meta_cache_replaces_non_array_cache_value_for_object $this->assertTrue( wp_cache_set( $term_id, new stdClass(), 'term_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); $meta_cache = update_meta_cache( 'term', array( $term_id ) ); + $this->assertIsArray( $meta_cache ); + $this->assertArrayHasKey( $term_id, $meta_cache ); $this->assertSame( array(), $meta_cache[ $term_id ], 'The returned meta cache for an object without meta should be an empty array.' ); $this->assertSame( array(), wp_cache_get( $term_id, 'term_meta' ), 'The unusable cache value should have been replaced with an empty array.' ); @@ -235,6 +239,8 @@ public function test_update_meta_cache_removes_non_array_cache_value_while_cache wp_suspend_cache_addition( true ); $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); wp_suspend_cache_addition( false ); + $this->assertIsArray( $meta_cache ); + $this->assertIsArray( $meta_cache[ self::$author->ID ] ); $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'], 'The meta should still be returned while cache addition is suspended.' ); $this->assertFalse( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should be removed but not replaced while cache addition is suspended.' );