Changeset 63958
- Timestamp:
- 09/28/2026 01:56:38 AM (17 hours ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
src/wp-includes/meta.php (modified) (7 diffs)
-
tests/phpunit/tests/meta.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/meta.php
r63758 r63958 633 633 * 634 634 * @since 5.5.0 635 * @since 7.2.0 A cached value that is not an array is now treated as a cache miss. 635 636 * 636 637 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term', … … 709 710 $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); 710 711 711 if ( ! $meta_cache ) { 712 // A cached value that is not an array is unusable, treat it as a cache miss. 713 if ( ! $meta_cache || ! is_array( $meta_cache ) ) { 712 714 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); 713 715 $meta_cache = $meta_cache[ $object_id ] ?? null; … … 793 795 * 794 796 * @since 3.3.0 797 * @since 7.2.0 A cached value that is not an array is now treated as a cache miss. 795 798 * 796 799 * @param string $meta_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term', … … 818 821 $meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' ); 819 822 820 if ( ! $meta_cache ) { 823 // A cached value that is not an array is unusable, treat it as a cache miss. 824 if ( ! $meta_cache || ! is_array( $meta_cache ) ) { 821 825 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); 822 $meta_cache = $meta_cache[ $object_id ] ;826 $meta_cache = $meta_cache[ $object_id ] ?? null; 823 827 } 824 828 … … 1166 1170 * 1167 1171 * @since 2.9.0 1172 * @since 7.2.0 A cached value that is not an array is now treated as a cache miss. 1168 1173 * 1169 1174 * @global wpdb $wpdb WordPress database abstraction object. … … 1220 1225 } 1221 1226 1222 $cache_group = $meta_type . '_meta'; 1223 $non_cached_ids = array(); 1224 $cache = array(); 1225 $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); 1227 $cache_group = $meta_type . '_meta'; 1228 $non_cached_ids = array(); 1229 $invalid_cache_ids = array(); 1230 $cache = array(); 1231 $cache_values = wp_cache_get_multiple( $object_ids, $cache_group ); 1226 1232 1227 1233 foreach ( $cache_values as $id => $cached_object ) { 1228 1234 if ( false === $cached_object ) { 1229 1235 $non_cached_ids[] = $id; 1236 } elseif ( ! is_array( $cached_object ) ) { 1237 // A cached value that is not an array is unusable, treat it as a cache miss. 1238 $non_cached_ids[] = $id; 1239 $invalid_cache_ids[] = $id; 1230 1240 } else { 1231 1241 $cache[ $id ] = $cached_object; 1232 1242 } 1243 } 1244 1245 /* 1246 * Remove unusable cached values so that the regenerated values can be added. 1247 * A delete followed by an add is used instead of wp_cache_set_multiple() 1248 * so that wp_suspend_cache_addition() is still respected. 1249 */ 1250 if ( ! empty( $invalid_cache_ids ) ) { 1251 wp_cache_delete_multiple( $invalid_cache_ids, $cache_group ); 1233 1252 } 1234 1253 … … 1269 1288 $data[ $id ] = $cache[ $id ]; 1270 1289 } 1290 1271 1291 wp_cache_add_multiple( $data, $cache_group ); 1272 1292 -
trunk/tests/phpunit/tests/meta.php
r60253 r63958 130 130 $this->assertFalse( metadata_exists( 'user', 1234567890, 'meta_key' ) ); 131 131 remove_filter( 'get_user_metadata', '__return_zero' ); 132 } 133 134 /** 135 * Non-array values that can not be used as a meta cache entry. 136 * 137 * @return array<string, array{mixed}> 138 */ 139 public static function data_non_array_cache_values(): array { 140 return array( 141 'object' => array( new stdClass() ), 142 'string' => array( 'meta_value' ), 143 'integer' => array( 1 ), 144 'float' => array( 1.5 ), 145 'true' => array( true ), 146 ); 147 } 148 149 /** 150 * @ticket 66091 151 * 152 * @dataProvider data_non_array_cache_values 153 * 154 * @param mixed $invalid_cached_value Unusable value to place in the meta cache. 155 */ 156 public function test_metadata_exists_treats_non_array_cache_value_as_miss( $invalid_cached_value ): void { 157 $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.' ); 158 159 $this->assertTrue( metadata_exists( 'user', self::$author->ID, 'meta_key' ), 'An existing meta key should be reported as existing.' ); 160 $this->assertFalse( metadata_exists( 'user', self::$author->ID, 'foobarbaz' ), 'A missing meta key should be reported as not existing.' ); 161 $this->assertIsArray( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should have been replaced.' ); 162 } 163 164 /** 165 * @ticket 66091 166 * 167 * @dataProvider data_non_array_cache_values 168 * 169 * @param mixed $invalid_cached_value Unusable value to place in the meta cache. 170 */ 171 public function test_get_metadata_treats_non_array_cache_value_as_miss( $invalid_cached_value ): void { 172 $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.' ); 173 174 $this->assertSame( 'meta_value', get_metadata( 'user', self::$author->ID, 'meta_key', true ), 'The single meta value should be returned.' ); 175 $this->assertSame( array( 'meta_value' ), get_metadata( 'user', self::$author->ID, 'meta_key' ), 'The array of meta values should be returned.' ); 176 $this->assertIsArray( wp_cache_get( self::$author->ID, 'user_meta' ), 'The unusable cache value should have been replaced.' ); 177 } 178 179 /** 180 * @ticket 66091 181 * 182 * @dataProvider data_non_array_cache_values 183 * 184 * @param mixed $invalid_cached_value Unusable value to place in the meta cache. 185 */ 186 public function test_get_metadata_with_empty_key_treats_non_array_cache_value_as_miss( $invalid_cached_value ): void { 187 $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.' ); 188 189 $meta = get_metadata( 'user', self::$author->ID ); 190 191 $this->assertIsArray( $meta, 'All meta for the object should be returned as an array.' ); 192 $this->assertSame( array( 'meta_value' ), $meta['meta_key'], 'The existing meta key should be included in the returned meta.' ); 193 } 194 195 /** 196 * @ticket 66091 197 * 198 * @dataProvider data_non_array_cache_values 199 * 200 * @param mixed $invalid_cached_value Unusable value to place in the meta cache. 201 */ 202 public function test_update_meta_cache_replaces_non_array_cache_value( $invalid_cached_value ): void { 203 $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.' ); 204 205 $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); 206 207 $this->assertIsArray( $meta_cache ); 208 $this->assertArrayHasKey( self::$author->ID, $meta_cache ); 209 $this->assertIsArray( $meta_cache[ self::$author->ID ], 'The returned meta cache for the object should be an array.' ); 210 $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'], 'The returned meta cache should include the existing meta key.' ); 211 212 $cached = wp_cache_get( self::$author->ID, 'user_meta' ); 213 $this->assertIsArray( $cached, 'The unusable cache value should have been replaced.' ); 214 $this->assertSame( array( 'meta_value' ), $cached['meta_key'], 'The replaced cache value should include the existing meta key.' ); 215 } 216 217 /** 218 * @ticket 66091 219 */ 220 public function test_update_meta_cache_replaces_non_array_cache_value_for_object_without_meta(): void { 221 $term_id = self::factory()->term->create(); 222 223 $this->assertTrue( wp_cache_set( $term_id, new stdClass(), 'term_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); 224 225 $meta_cache = update_meta_cache( 'term', array( $term_id ) ); 226 $this->assertIsArray( $meta_cache ); 227 $this->assertArrayHasKey( $term_id, $meta_cache ); 228 229 $this->assertSame( array(), $meta_cache[ $term_id ], 'The returned meta cache for an object without meta should be an empty array.' ); 230 $this->assertSame( array(), wp_cache_get( $term_id, 'term_meta' ), 'The unusable cache value should have been replaced with an empty array.' ); 231 } 232 233 /** 234 * @ticket 66091 235 */ 236 public function test_update_meta_cache_removes_non_array_cache_value_while_cache_addition_is_suspended(): void { 237 $this->assertTrue( wp_cache_set( self::$author->ID, new stdClass(), 'user_meta' ), 'The unusable value should be placed in the cache, check test setup.' ); 238 239 wp_suspend_cache_addition( true ); 240 $meta_cache = update_meta_cache( 'user', array( self::$author->ID ) ); 241 wp_suspend_cache_addition( false ); 242 $this->assertIsArray( $meta_cache ); 243 $this->assertIsArray( $meta_cache[ self::$author->ID ] ); 244 245 $this->assertSame( array( 'meta_value' ), $meta_cache[ self::$author->ID ]['meta_key'], 'The meta should still be returned while cache addition is suspended.' ); 246 $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.' ); 132 247 } 133 248
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)