diff --git a/src/wp-includes/class-wp-metadata-lazyloader.php b/src/wp-includes/class-wp-metadata-lazyloader.php index fa2067c5c2..f9c02391d2 100644 --- a/src/wp-includes/class-wp-metadata-lazyloader.php +++ b/src/wp-includes/class-wp-metadata-lazyloader.php @@ -61,6 +61,10 @@ class WP_Metadata_Lazyloader { 'filter' => 'get_comment_metadata', 'callback' => array( $this, 'lazyload_meta_callback' ), ), + 'blog' => array( + 'filter' => 'get_blog_metadata', + 'callback' => array( $this, 'lazyload_meta_callback' ), + ), ); } diff --git a/src/wp-includes/class-wp-site-query.php b/src/wp-includes/class-wp-site-query.php index c9b96280a5..6435ac02e1 100644 --- a/src/wp-includes/class-wp-site-query.php +++ b/src/wp-includes/class-wp-site-query.php @@ -388,6 +388,10 @@ class WP_Site_Query { $site_ids = array_map( 'intval', $site_ids ); + if ( $this->query_vars['update_site_meta_cache'] ) { + wp_lazyload_site_meta( $site_ids ); + } + if ( 'ids' === $this->query_vars['fields'] ) { $this->sites = $site_ids; @@ -396,7 +400,7 @@ class WP_Site_Query { // Prime site network caches. if ( $this->query_vars['update_site_cache'] ) { - _prime_site_caches( $site_ids, $this->query_vars['update_site_meta_cache'] ); + _prime_site_caches( $site_ids, false ); } // Fetch full site objects from the primed cache. diff --git a/src/wp-includes/ms-site.php b/src/wp-includes/ms-site.php index 90cf484049..486fad2414 100644 --- a/src/wp-includes/ms-site.php +++ b/src/wp-includes/ms-site.php @@ -340,6 +340,7 @@ function get_site( $site = null ) { * @since 4.6.0 * @since 5.1.0 Introduced the `$update_meta_cache` parameter. * @since 6.1.0 This function is no longer marked as "private". + * @since 6.3.0 Use wp_lazyload_site_meta() for lazy-loading of site meta. * * @see update_site_cache() * @global wpdb $wpdb WordPress database abstraction object. @@ -354,8 +355,27 @@ function _prime_site_caches( $ids, $update_meta_cache = true ) { if ( ! empty( $non_cached_ids ) ) { $fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared - update_site_cache( $fresh_sites, $update_meta_cache ); + update_site_cache( $fresh_sites, false ); } + + if ( $update_meta_cache ) { + wp_lazyload_site_meta( $ids ); + } +} + +/** + * Queue site meta for lazy-loading. + * + * @since 6.3.0 + * + * @param array $site_ids List of site IDs. + */ +function wp_lazyload_site_meta( array $site_ids ) { + if ( empty( $site_ids ) ) { + return; + } + $lazyloader = wp_metadata_lazyloader(); + $lazyloader->queue_objects( 'blog', $site_ids ); } /** diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 8f70f2a739..0669a052d0 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -1004,9 +1004,8 @@ function get_blogs_of_user( $user_id, $all = false ) { if ( ! empty( $site_ids ) ) { $args = array( - 'number' => '', - 'site__in' => $site_ids, - 'update_site_meta_cache' => false, + 'number' => '', + 'site__in' => $site_ids, ); if ( ! $all ) { $args['archived'] = 0; diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index b03d12a097..4aa84c41b7 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -281,6 +281,7 @@ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase { $lazyloader = wp_metadata_lazyloader(); $lazyloader->reset_queue( 'term' ); $lazyloader->reset_queue( 'comment' ); + $lazyloader->reset_queue( 'blog' ); } /** diff --git a/tests/phpunit/tests/multisite/siteMeta.php b/tests/phpunit/tests/multisite/siteMeta.php index 9c41afaead..ad59c75e34 100644 --- a/tests/phpunit/tests/multisite/siteMeta.php +++ b/tests/phpunit/tests/multisite/siteMeta.php @@ -248,7 +248,79 @@ if ( is_multisite() ) : $num_queries = get_num_queries(); get_site_meta( self::$site_id, 'foo', true ); - $this->assertSame( $num_queries, get_num_queries() ); + $this->assertSame( 1, get_num_queries() - $num_queries ); + } + + /** + * @ticket 58185 + */ + public function test_lazy_load_site_meta() { + if ( ! is_site_meta_supported() ) { + $this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' ); + } + + $filter = new MockAction(); + add_filter( 'update_blog_metadata_cache', array( $filter, 'filter' ), 10, 2 ); + + $q = new WP_Site_Query( + array( + 'ID' => self::$site_id, + ) + ); + + $this->assertSameSets( array( (string) self::$site_id ), wp_list_pluck( $q->sites, 'blog_id' ), 'Site query should return the first test site' ); + + $q = new WP_Site_Query( + array( + 'ID' => self::$site_id2, + ) + ); + + $this->assertSameSets( array( (string) self::$site_id2 ), wp_list_pluck( $q->sites, 'blog_id' ), 'Site query should return the second test site' ); + + get_site_meta( self::$site_id2 ); + + $args = $filter->get_args(); + $first = reset( $args ); + $site_ids = end( $first ); + $this->assertSameSets( $site_ids, array( self::$site_id, self::$site_id2 ), 'This should have two site\'s meta' ); + } + + /** + * @ticket 58185 + */ + public function test_lazy_load_site_meta_fields_id() { + if ( ! is_site_meta_supported() ) { + $this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' ); + } + + $filter = new MockAction(); + add_filter( 'update_blog_metadata_cache', array( $filter, 'filter' ), 10, 2 ); + + $q = new WP_Site_Query( + array( + 'ID' => self::$site_id, + 'fields' => 'ids', + ) + ); + + $this->assertSameSets( array( self::$site_id ), $q->sites, 'Site query should return the first test site' ); + + $q = new WP_Site_Query( + array( + 'ID' => self::$site_id2, + 'fields' => 'ids', + ) + ); + + $this->assertSameSets( array( self::$site_id2 ), $q->sites, 'Site query should return the second test site' ); + + get_site_meta( self::$site_id2 ); + + $args = $filter->get_args(); + $first = reset( $args ); + $site_ids = end( $first ); + $this->assertSameSets( $site_ids, array( self::$site_id, self::$site_id2 ), 'This should have two sites meta' ); } public function test_query_update_site_meta_cache_false() { @@ -267,7 +339,7 @@ if ( is_multisite() ) : $num_queries = get_num_queries(); get_site_meta( self::$site_id, 'foo', true ); - $this->assertSame( $num_queries + 1, get_num_queries() ); + $this->assertSame( 1, get_num_queries() - $num_queries ); } /**