diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php index a3cbed0b99..86cc324d4e 100644 --- a/src/wp-includes/meta.php +++ b/src/wp-includes/meta.php @@ -363,8 +363,14 @@ function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $d if ( !count( $meta_ids ) ) return false; - if ( $delete_all ) - $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $meta_key ) ); + if ( $delete_all ) { + $value_clause = ''; + if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) { + $value_clause = $wpdb->prepare( " AND meta_value = %s", $meta_value ); + } + + $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s $value_clause", $meta_key ) ); + } /** * Fires immediately before deleting metadata of a specific type. diff --git a/tests/phpunit/tests/meta/deleteMetadata.php b/tests/phpunit/tests/meta/deleteMetadata.php index 1be8204ea4..ab7d67e4a3 100644 --- a/tests/phpunit/tests/meta/deleteMetadata.php +++ b/tests/phpunit/tests/meta/deleteMetadata.php @@ -97,4 +97,49 @@ class Tests_Meta_DeleteMetadata extends WP_UnitTestCase { $m = get_metadata( 'post', 12345, 'foo', false ); $this->assertEqualSets( array(), $m ); } + + /** + * @ticket 35797 + */ + public function test_delete_all_should_only_invalidate_cache_for_objects_matching_meta_value() { + $p1 = 1234; + $p2 = 5678; + + add_metadata( 'post', $p1, 'foo', 'value1' ); + add_metadata( 'post', $p2, 'foo', 'value2' ); + + // Prime caches. + update_meta_cache( 'post', array( $p1, $p2 ) ); + + $deleted = delete_metadata( 'post', 5, 'foo', 'value1', true ); + + $p1_cache = wp_cache_get( $p1, 'post_meta' ); + $this->assertFalse( $p1_cache ); + + // Should not have been touched. + $p2_cache = wp_cache_get( $p2, 'post_meta' ); + $this->assertNotEmpty( $p2_cache ); + } + + /** + * @ticket 35797 + */ + public function test_delete_all_should_invalidate_cache_for_all_objects_with_meta_key_when_meta_value_is_not_provided() { + $p1 = 1234; + $p2 = 5678; + + add_metadata( 'post', $p1, 'foo', 'value1' ); + add_metadata( 'post', $p2, 'foo', 'value2' ); + + // Prime caches. + update_meta_cache( 'post', array( $p1, $p2 ) ); + + $deleted = delete_metadata( 'post', 5, 'foo', false, true ); + + $p1_cache = wp_cache_get( $p1, 'post_meta' ); + $this->assertFalse( $p1_cache ); + + $p2_cache = wp_cache_get( $p2, 'post_meta' ); + $this->assertFalse( $p2_cache ); + } }