diff --git a/src/wp-admin/includes/schema.php b/src/wp-admin/includes/schema.php index 92fd6d6619b7..1d1cbcbc2fa6 100644 --- a/src/wp-admin/includes/schema.php +++ b/src/wp-admin/includes/schema.php @@ -1159,6 +1159,12 @@ function populate_network_meta( $network_id, array $meta = array() ) { } } + if ( function_exists( 'clean_network_cache' ) ) { + clean_network_cache( $network_id ); + } else { + wp_cache_delete( $network_id, 'networks' ); + } + wp_cache_delete( 'networks_have_paths', 'site-options' ); if ( ! is_multisite() ) { diff --git a/src/wp-includes/class-wp-network.php b/src/wp-includes/class-wp-network.php index 4926c0d8b548..849dfc127134 100644 --- a/src/wp-includes/class-wp-network.php +++ b/src/wp-includes/class-wp-network.php @@ -101,16 +101,20 @@ public static function get_instance( $network_id ) { $_network = wp_cache_get( $network_id, 'networks' ); - if ( ! $_network ) { + if ( false === $_network ) { $_network = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->site} WHERE id = %d LIMIT 1", $network_id ) ); if ( empty( $_network ) || is_wp_error( $_network ) ) { - return false; + $_network = -1; } wp_cache_add( $network_id, $_network, 'networks' ); } + if ( is_numeric( $_network ) ) { + return false; + } + return new WP_Network( $_network ); } @@ -231,8 +235,8 @@ private function get_main_site_id() { return (int) $this->blog_id; } - if ( ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) && $this->domain === DOMAIN_CURRENT_SITE && $this->path === PATH_CURRENT_SITE ) - || ( defined( 'SITE_ID_CURRENT_SITE' ) && $this->id == SITE_ID_CURRENT_SITE ) ) { + if ( ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) && DOMAIN_CURRENT_SITE === $this->domain && PATH_CURRENT_SITE === $this->path ) + || ( defined( 'SITE_ID_CURRENT_SITE' ) && SITE_ID_CURRENT_SITE == $this->id ) ) { if ( defined( 'BLOG_ID_CURRENT_SITE' ) ) { $this->blog_id = (string) BLOG_ID_CURRENT_SITE; @@ -457,7 +461,7 @@ public static function get_by_path( $domain = '', $path = '', $segments = null ) break; } } - if ( $network->path === '/' ) { + if ( '/' === $network->path ) { $found = true; break; } diff --git a/src/wp-includes/class-wp-site.php b/src/wp-includes/class-wp-site.php index b0459be2d4e1..e1839fed9e4c 100644 --- a/src/wp-includes/class-wp-site.php +++ b/src/wp-includes/class-wp-site.php @@ -162,16 +162,20 @@ public static function get_instance( $site_id ) { $_site = wp_cache_get( $site_id, 'sites' ); - if ( ! $_site ) { + if ( false === $_site ) { $_site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->blogs} WHERE blog_id = %d LIMIT 1", $site_id ) ); if ( empty( $_site ) || is_wp_error( $_site ) ) { - return false; + $_site = -1; } wp_cache_add( $site_id, $_site, 'sites' ); } + if ( is_numeric( $_site ) ) { + return false; + } + return new WP_Site( $_site ); } diff --git a/src/wp-includes/ms-site.php b/src/wp-includes/ms-site.php index 952697351063..039eb488d992 100644 --- a/src/wp-includes/ms-site.php +++ b/src/wp-includes/ms-site.php @@ -69,14 +69,14 @@ function wp_insert_site( array $data ) { return new WP_Error( 'db_insert_error', __( 'Could not insert site into the database.' ), $wpdb->last_error ); } + clean_blog_cache( $wpdb->insert_id ); + $new_site = get_site( $wpdb->insert_id ); if ( ! $new_site ) { return new WP_Error( 'get_site_error', __( 'Could not retrieve site data.' ) ); } - clean_blog_cache( $new_site ); - /** * Fires once a site has been inserted into the database. * diff --git a/tests/phpunit/tests/multisite/network.php b/tests/phpunit/tests/multisite/network.php index 18e8510e5b86..0a5d57cb9903 100644 --- a/tests/phpunit/tests/multisite/network.php +++ b/tests/phpunit/tests/multisite/network.php @@ -613,6 +613,49 @@ public function test_network_blog_id_set() { $this->assertSame( (string) self::$different_site_ids[0], $network->blog_id ); } + + /** + * @ticket 42251 + */ + public function test_get_network_not_found_cache() { + global $wpdb; + + $new_network_id = $this->_get_next_network_id(); + $this->assertNull( get_network( $new_network_id ) ); + + $num_queries = $wpdb->num_queries; + $this->assertNull( get_network( $new_network_id ) ); + $this->assertSame( $num_queries, $wpdb->num_queries ); + } + + /** + * @ticket 42251 + */ + public function test_get_network_not_found_cache_clear() { + $new_network_id = $this->_get_next_network_id(); + $this->assertNull( get_network( $new_network_id ) ); + + $new_network = $this->factory()->network->create_and_get(); + + // Double-check we got the ID of the new network correct. + $this->assertEquals( $new_network_id, $new_network->id ); + + // Verify that if we fetch the network now, it's no longer false. + $fetched_network = get_network( $new_network_id ); + $this->assertInstanceOf( 'WP_Network', $fetched_network ); + $this->assertEquals( $new_network_id, $fetched_network->id ); + } + + /** + * Gets the ID of the site with the highest ID + * @return int + */ + protected function _get_next_network_id() { + global $wpdb; + //create an extra network, just to make sure we know the ID of the following one + static::factory()->network->create(); + return (int) $wpdb->get_var( 'SELECT id FROM ' . $wpdb->site . ' ORDER BY id DESC LIMIT 1' ) + 1; + } } endif; diff --git a/tests/phpunit/tests/multisite/site.php b/tests/phpunit/tests/multisite/site.php index 2beb4ca090a2..f0aa28a06d1c 100644 --- a/tests/phpunit/tests/multisite/site.php +++ b/tests/phpunit/tests/multisite/site.php @@ -2383,6 +2383,51 @@ public function test_wpmu_new_blog_action_backward_compatible( $meta, $expected_ $this->wp_initialize_site_meta = array(); } + /** + * @ticket 42251 + */ + public function test_get_site_not_found_cache() { + global $wpdb; + + $new_site_id = $this->_get_next_site_id(); + $this->assertNull( get_site( $new_site_id ) ); + + $num_queries = $wpdb->num_queries; + $this->assertNull( get_site( $new_site_id ) ); + $this->assertSame( $num_queries, $wpdb->num_queries ); + } + + /** + * @ticket 42251 + */ + public function test_get_site_not_found_cache_clear() { + $new_site_id = $this->_get_next_site_id(); + $this->assertNull( get_site( $new_site_id ) ); + + $new_site = $this->factory()->blog->create_and_get(); + + // Double-check we got the ID of the new site correct. + $this->assertEquals( $new_site_id, $new_site->blog_id ); + + // Verify that if we fetch the site now, it's no longer false. + $fetched_site = get_site( $new_site_id ); + $this->assertInstanceOf( 'WP_Site', $fetched_site ); + $this->assertEquals( $new_site_id, $fetched_site->blog_id ); + + } + + /** + * Gets the ID of the next site that will get inserted + * @return int + */ + protected function _get_next_site_id() { + global $wpdb; + //create an entry + static::factory()->blog->create(); + //get the ID after it + return (int) $wpdb->get_var( 'SELECT blog_id FROM ' . $wpdb->blogs . ' ORDER BY blog_ID DESC LIMIT 1' ) + 1; + } + /** * Capture the $meta value passed to the wpmu_new_blog action and compare it. */