From 7819ac5d16c932c020371f43126b338e6abd64d0 Mon Sep 17 00:00:00 2001 From: Jeremy Felt Date: Sun, 14 Jun 2015 21:44:45 +0000 Subject: [PATCH] Introduce get_main_network_id() Expand on the logic previously available as part of `is_main_network()` and provide a way to obtain the ID of the main network. Most useful in multi-network configurations. Props @johnjamesjacoby for the initial patch. Fixes #30294. git-svn-id: https://develop.svn.wordpress.org/trunk@32775 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 57 +++++++++++++++------ tests/phpunit/tests/multisite/network.php | 61 ++++++++++++++++++++++- 2 files changed, 101 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index b09ed844af..99cf913d9a 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3873,38 +3873,63 @@ function is_main_site( $site_id = null ) { * * @since 3.7.0 * - * @global wpdb $wpdb - * * @param int $network_id Optional. Network ID to test. Defaults to current network. * @return bool True if $network_id is the main network, or if not running Multisite. */ function is_main_network( $network_id = null ) { - global $wpdb; - - if ( ! is_multisite() ) + if ( ! is_multisite() ) { return true; + } $current_network_id = (int) get_current_site()->id; - if ( ! $network_id ) + if ( null === $network_id ) { $network_id = $current_network_id; + } + $network_id = (int) $network_id; - if ( defined( 'PRIMARY_NETWORK_ID' ) ) - return $network_id === (int) PRIMARY_NETWORK_ID; + return ( $network_id === get_main_network_id() ); +} - if ( 1 === $current_network_id ) - return $network_id === $current_network_id; +/** + * Get the main network ID. + * + * @since 4.3.0 + * + * @global wpdb $wpdb + * + * @return int The ID of the main network. + */ +function get_main_network_id() { + global $wpdb; - $primary_network_id = (int) wp_cache_get( 'primary_network_id', 'site-options' ); + if ( ! is_multisite() ) { + return 1; + } - if ( $primary_network_id ) - return $network_id === $primary_network_id; + if ( defined( 'PRIMARY_NETWORK_ID' ) ) { + $main_network_id = PRIMARY_NETWORK_ID; + } elseif ( 1 === (int) get_current_site()->id ) { + // If the current network has an ID of 1, assume it is the main network. + $main_network_id = 1; + } else { + $main_network_id = wp_cache_get( 'primary_network_id', 'site-options' ); - $primary_network_id = (int) $wpdb->get_var( "SELECT id FROM $wpdb->site ORDER BY id LIMIT 1" ); - wp_cache_add( 'primary_network_id', $primary_network_id, 'site-options' ); + if ( false === $main_network_id ) { + $main_network_id = (int) $wpdb->get_var( "SELECT id FROM {$wpdb->site} ORDER BY id LIMIT 1" ); + wp_cache_add( 'primary_network_id', $main_network_id, 'site-options' ); + } + } - return $network_id === $primary_network_id; + /** + * Filter the main network ID. + * + * @since 4.3.0 + * + * @param int $main_network_id The ID of the main network. + */ + return (int) apply_filters( 'get_main_network_id', $main_network_id ); } /** diff --git a/tests/phpunit/tests/multisite/network.php b/tests/phpunit/tests/multisite/network.php index 7d34edcc1c..70a4a0dbeb 100644 --- a/tests/phpunit/tests/multisite/network.php +++ b/tests/phpunit/tests/multisite/network.php @@ -21,11 +21,70 @@ class Tests_Multisite_Network extends WP_UnitTestCase { } function tearDown() { - global $wpdb; + global $wpdb, $current_site; $wpdb->suppress_errors( $this->suppress ); + $current_site->id = 1; parent::tearDown(); } + /** + * By default, only one network exists and has a network ID of 1. + */ + function test_get_main_network_id_default() { + $this->assertEquals( 1, get_main_network_id() ); + } + + /** + * If a second network is created, network ID 1 should still be returned + * as the main network ID. + */ + function test_get_main_network_id_two_networks() { + $this->factory->network->create(); + + $this->assertEquals( 1, get_main_network_id() ); + } + + /** + * When the `$current_site` global is populated with another network, the + * main network should still return as 1. + */ + function test_get_main_network_id_after_network_switch() { + global $current_site; + + $id = $this->factory->network->create(); + + $current_site->id = (int) $id; + + $this->assertEquals( 1, get_main_network_id() ); + } + + /** + * When the first network is removed, the next should return as the main + * network ID. + * + * @todo In the future, we'll have a smarter way of deleting a network. For now, + * fake the process with UPDATE queries. + */ + function test_get_main_network_id_after_network_delete() { + global $wpdb, $current_site; + $id = $this->factory->network->create(); + + $current_site->id = (int) $id; + $wpdb->query( "UPDATE {$wpdb->site} SET id=100 WHERE id=1" ); + $this->assertEquals( $id, get_main_network_id() ); + $wpdb->query( "UPDATE {$wpdb->site} SET id=1 WHERE id=100" ); + } + + function test_get_main_network_id_filtered() { + add_filter( 'get_main_network_id', array( $this, '_get_main_network_id' ) ); + $this->assertEquals( 3, get_main_network_id() ); + remove_filter( 'get_main_network_id', array( $this, '_get_main_network_id' ) ); + } + + function _get_main_network_id() { + return 3; + } + /** * @ticket 22917 */