Skip to content

Commit e23004c

Browse files
committed
Multisite: Introduce get_main_site_id().
This function can be used to easily get the main site ID of a given network via the optional `$network_id` parameter, which defaults to the current network. The existing `is_main_site()` now uses the new function internally and now accepts an optional `$network_id` parameter as well. The main purpose of the new function at this point is to ensure that the `WP_Network::$blog_id` property is always set. Magic getters in the class have been adjusted to auto-fill the property when it is accessed and empty. Furthermore the function encapsulates logic that was previously part of `ms_load_current_site_and_network()` and has been replaced with a call to the function now. Props spacedmonkey, jeremyfelt, johnjamesjacoby, flixos90. Fixes #29684. git-svn-id: https://develop.svn.wordpress.org/trunk@41380 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 95a2632 commit e23004c

6 files changed

Lines changed: 249 additions & 15 deletions

File tree

src/wp-includes/class-wp-network.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ public function __get( $key ) {
148148
case 'id':
149149
return (int) $this->id;
150150
case 'blog_id':
151-
return $this->blog_id;
151+
return $this->get_main_site_id();
152152
case 'site_id':
153-
return (int) $this->blog_id;
153+
return (int) $this->get_main_site_id();
154154
}
155155

156156
return null;
@@ -201,6 +201,25 @@ public function __set( $key, $value ) {
201201
}
202202
}
203203

204+
/**
205+
* Returns the main site ID for the network.
206+
*
207+
* Internal method used by the magic getter for the 'blog_id' and 'site_id'
208+
* properties.
209+
*
210+
* @since 4.9.0
211+
* @see get_main_site_id()
212+
*
213+
* @return string Main site ID as numeric string, for compatibility reasons.
214+
*/
215+
private function get_main_site_id() {
216+
if ( empty( $this->blog_id ) ) {
217+
$this->blog_id = (string) get_main_site_id( $this->id );
218+
}
219+
220+
return $this->blog_id;
221+
}
222+
204223
/**
205224
* Set the site name assigned to the network if one has not been populated.
206225
*

src/wp-includes/functions.php

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4390,19 +4390,92 @@ function wp_suspend_cache_invalidation( $suspend = true ) {
43904390
* Determine whether a site is the main site of the current network.
43914391
*
43924392
* @since 3.0.0
4393+
* @since 4.9.0 The $network_id parameter has been added.
43934394
*
4394-
* @param int $site_id Optional. Site ID to test. Defaults to current site.
4395+
* @param int $site_id Optional. Site ID to test. Defaults to current site.
4396+
* @param int $network_id Optional. Network ID of the network to check for.
4397+
* Defaults to current network.
43954398
* @return bool True if $site_id is the main site of the network, or if not
43964399
* running Multisite.
43974400
*/
4398-
function is_main_site( $site_id = null ) {
4399-
if ( ! is_multisite() )
4401+
function is_main_site( $site_id = null, $network_id = null ) {
4402+
if ( ! is_multisite() ) {
44004403
return true;
4404+
}
44014405

4402-
if ( ! $site_id )
4406+
if ( ! $site_id ) {
44034407
$site_id = get_current_blog_id();
4408+
}
4409+
4410+
$site_id = (int) $site_id;
4411+
4412+
return $site_id === get_main_site_id( $network_id );
4413+
}
4414+
4415+
/**
4416+
* Gets the main site ID.
4417+
*
4418+
* @since 4.9.0
4419+
*
4420+
* @param int $network_id Optional. The ID of the network for which to get the main site.
4421+
* Defaults to the current network.
4422+
* @return int The ID of the main site.
4423+
*/
4424+
function get_main_site_id( $network_id = null ) {
4425+
if ( ! is_multisite() ) {
4426+
return 1;
4427+
}
4428+
4429+
$network = get_network( $network_id );
4430+
if ( ! $network ) {
4431+
return 0;
4432+
}
4433+
4434+
/**
4435+
* Filters the main site ID.
4436+
*
4437+
* Returning anything other than null will effectively short-circuit the function, returning
4438+
* the result parsed as an integer immediately.
4439+
*
4440+
* @since 4.9.0
4441+
*
4442+
* @param int|null $main_site_id If anything other than null is returned, it is interpreted as the main site ID.
4443+
* @param int $network_id The ID of the network for which the main site was detected.
4444+
*/
4445+
$main_site_id = apply_filters( 'pre_get_main_site_id', null, $network->id );
4446+
if ( null !== $main_site_id ) {
4447+
return (int) $main_site_id;
4448+
}
4449+
4450+
if ( ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) && $network->domain === DOMAIN_CURRENT_SITE && $network->path === PATH_CURRENT_SITE )
4451+
|| ( defined( 'SITE_ID_CURRENT_SITE' ) && $network->id == SITE_ID_CURRENT_SITE ) ) {
4452+
if ( defined( 'BLOG_ID_CURRENT_SITE' ) ) {
4453+
return BLOG_ID_CURRENT_SITE;
4454+
} elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) { // deprecated.
4455+
return BLOGID_CURRENT_SITE;
4456+
}
4457+
}
4458+
4459+
$site = get_site();
4460+
if ( $site->domain === $network->domain && $site->path === $network->path ) {
4461+
$main_site_id = (int) $site->id;
4462+
} else {
4463+
$main_site_id = wp_cache_get( 'network:' . $network->id . ':main_site', 'site-options' );
4464+
if ( false === $main_site_id ) {
4465+
$_sites = get_sites( array(
4466+
'fields' => 'ids',
4467+
'number' => 1,
4468+
'domain' => $network->domain,
4469+
'path' => $network->path,
4470+
'network_id' => $network->id,
4471+
) );
4472+
$main_site_id = ! empty( $_sites ) ? array_shift( $_sites ) : 0;
4473+
4474+
wp_cache_add( 'network:' . $network->id . ':main_site', $main_site_id, 'site-options' );
4475+
}
4476+
}
44044477

4405-
return (int) $site_id === (int) get_network()->site_id;
4478+
return (int) $main_site_id;
44064479
}
44074480

44084481
/**

src/wp-includes/ms-load.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ function get_network_by_path( $domain, $path, $segments = null ) {
135135

136136
/**
137137
* Retrieves the closest matching site object by its domain and path.
138-
*
138+
*
139139
* This will not necessarily return an exact match for a domain and path. Instead, it
140140
* breaks the domain and path into pieces that are then used to match the closest
141141
* possibility from a query.
@@ -424,13 +424,7 @@ function ms_load_current_site_and_network( $domain, $path, $subdomain = false )
424424

425425
// Figure out the current network's main site.
426426
if ( empty( $current_site->blog_id ) ) {
427-
if ( $current_blog->domain === $current_site->domain && $current_blog->path === $current_site->path ) {
428-
$current_site->blog_id = $current_blog->blog_id;
429-
} elseif ( ! $current_site->blog_id = wp_cache_get( 'network:' . $current_site->id . ':main_site', 'site-options' ) ) {
430-
$current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s",
431-
$current_site->domain, $current_site->path ) );
432-
wp_cache_add( 'network:' . $current_site->id . ':main_site', $current_site->blog_id, 'site-options' );
433-
}
427+
$current_site->blog_id = get_main_site_id( $current_site->id );
434428
}
435429

436430
return true;
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
if ( is_multisite() ) :
4+
5+
/**
6+
* Tests for the get_main_site_id() function.
7+
*
8+
* @group ms-site
9+
* @group multisite
10+
*/
11+
class Tests_Multisite_Get_Main_Site_ID extends WP_UnitTestCase {
12+
protected static $network_ids;
13+
protected static $site_ids;
14+
15+
public static function wpSetUpBeforeClass( $factory ) {
16+
self::$network_ids = array(
17+
'wordpress.org/' => array( 'domain' => 'wordpress.org', 'path' => '/' ),
18+
'wp.org/' => array( 'domain' => 'wp.org', 'path' => '/' ), // A network with no sites.
19+
);
20+
21+
foreach ( self::$network_ids as &$id ) {
22+
$id = $factory->network->create( $id );
23+
}
24+
unset( $id );
25+
26+
self::$site_ids = array(
27+
'www.w.org/' => array( 'domain' => 'www.w.org', 'path' => '/' ),
28+
'wordpress.org/' => array( 'domain' => 'wordpress.org', 'path' => '/', 'site_id' => self::$network_ids['wordpress.org/'] ),
29+
'wordpress.org/foo/' => array( 'domain' => 'wordpress.org', 'path' => '/foo/', 'site_id' => self::$network_ids['wordpress.org/'] ),
30+
);
31+
32+
foreach ( self::$site_ids as &$id ) {
33+
$id = $factory->blog->create( $id );
34+
}
35+
unset( $id );
36+
}
37+
38+
public static function wpTearDownAfterClass() {
39+
foreach( self::$site_ids as $id ) {
40+
wpmu_delete_blog( $id, true );
41+
}
42+
43+
global $wpdb;
44+
45+
foreach( self::$network_ids as $id ) {
46+
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE site_id = %d", $id ) );
47+
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->site} WHERE id= %d", $id ) );
48+
}
49+
50+
wp_update_network_site_counts();
51+
}
52+
53+
/**
54+
* @ticket 29684
55+
*/
56+
public function test_get_main_site_id_on_main_site_returns_self() {
57+
$this->assertSame( get_current_blog_id(), get_main_site_id() );
58+
}
59+
60+
/**
61+
* @ticket 29684
62+
*/
63+
public function test_get_main_site_id_returns_main_site_in_switched_context() {
64+
$main_site_id = get_current_blog_id();
65+
$other_site_id = self::$site_ids['www.w.org/'];
66+
67+
switch_to_blog( $other_site_id );
68+
$result = get_main_site_id();
69+
restore_current_blog();
70+
71+
$this->assertSame( $main_site_id, $result );
72+
}
73+
74+
/**
75+
* @ticket 29684
76+
*/
77+
public function test_get_main_site_id_with_different_network_returns_correct_id() {
78+
$this->assertSame( self::$site_ids['wordpress.org/'], get_main_site_id( self::$network_ids['wordpress.org/'] ) );
79+
}
80+
81+
/**
82+
* @ticket 29684
83+
*/
84+
public function test_get_main_site_id_on_network_without_site_returns_0() {
85+
$this->assertSame( 0, get_main_site_id( self::$network_ids['wp.org/'] ) );
86+
}
87+
88+
/**
89+
* @ticket 29684
90+
*/
91+
public function test_get_main_site_id_on_invalid_network_returns_0() {
92+
$this->assertSame( 0, get_main_site_id( 333 ) );
93+
}
94+
95+
/**
96+
* @ticket 29684
97+
*/
98+
public function test_get_main_site_id_filtered() {
99+
add_filter( 'pre_get_main_site_id', array( $this, 'filter_get_main_site_id' ) );
100+
$result = get_main_site_id();
101+
102+
$this->assertSame( 333, $result );
103+
}
104+
105+
public function filter_get_main_site_id() {
106+
return 333;
107+
}
108+
}
109+
110+
endif;

tests/phpunit/tests/multisite/network.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,15 @@ public function test_wpmu_create_blog_updates_correct_network_site_count() {
583583

584584
$this->assertEquals( $original_count + 1, $result );
585585
}
586+
587+
/**
588+
* @ticket 29684
589+
*/
590+
public function test_network_blog_id_set() {
591+
$network = get_network( self::$different_network_id );
592+
593+
$this->assertSame( (string) self::$different_site_ids[0], $network->blog_id );
594+
}
586595
}
587596

588597
endif;

tests/phpunit/tests/multisite/site.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
class Tests_Multisite_Site extends WP_UnitTestCase {
1212
protected $suppress = false;
1313
protected static $network_ids;
14+
protected static $site_ids;
1415

1516
function setUp() {
1617
global $wpdb;
@@ -33,11 +34,25 @@ public static function wpSetUpBeforeClass( $factory ) {
3334
$id = $factory->network->create( $id );
3435
}
3536
unset( $id );
37+
38+
self::$site_ids = array(
39+
'make.wordpress.org/' => array( 'domain' => 'make.wordpress.org', 'path' => '/', 'site_id' => self::$network_ids['make.wordpress.org/'] ),
40+
'make.wordpress.org/foo/' => array( 'domain' => 'make.wordpress.org', 'path' => '/foo/', 'site_id' => self::$network_ids['make.wordpress.org/'] ),
41+
);
42+
43+
foreach ( self::$site_ids as &$id ) {
44+
$id = $factory->blog->create( $id );
45+
}
46+
unset( $id );
3647
}
3748

3849
public static function wpTearDownAfterClass() {
3950
global $wpdb;
4051

52+
foreach( self::$site_ids as $id ) {
53+
wpmu_delete_blog( $id, true );
54+
}
55+
4156
foreach( self::$network_ids as $id ) {
4257
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE site_id = %d", $id ) );
4358
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->site} WHERE id= %d", $id ) );
@@ -1028,6 +1043,20 @@ function test_different_network_language() {
10281043
function filter_allow_unavailable_languages( $value, $option, $original_value ) {
10291044
return $original_value;
10301045
}
1046+
1047+
/**
1048+
* @ticket 29684
1049+
*/
1050+
public function test_is_main_site_different_network() {
1051+
$this->assertTrue( is_main_site( self::$site_ids['make.wordpress.org/'], self::$network_ids['make.wordpress.org/'] ) );
1052+
}
1053+
1054+
/**
1055+
* @ticket 29684
1056+
*/
1057+
public function test_is_main_site_different_network_random_site() {
1058+
$this->assertFalse( is_main_site( self::$site_ids['make.wordpress.org/foo/'], self::$network_ids['make.wordpress.org/'] ) );
1059+
}
10311060
}
10321061

10331062
endif;

0 commit comments

Comments
 (0)