diff --git a/src/wp-includes/ms-load.php b/src/wp-includes/ms-load.php index ee99398dfd..66047bcc0d 100644 --- a/src/wp-includes/ms-load.php +++ b/src/wp-includes/ms-load.php @@ -348,13 +348,30 @@ function get_site_by_path( $domain, $path, $segments = null ) { * then cache whether we can just always ignore paths. */ + // Either www or non-www is supported, not both. If a www domain is requested, + // query for both to provide the proper redirect. + $domains = array( $domain ); + if ( 'www.' === substr( $domain, 0, 4 ) ) { + $domains[] = substr( $domain, 4 ); + $search_domains = "'" . implode( "', '", $wpdb->_escape( $domains ) ) . "'"; + } + if ( count( $paths ) > 1 ) { - $paths = "'" . implode( "', '", $wpdb->_escape( $paths ) ) . "'"; - $sql = $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $domain ); - $sql .= " AND path IN ($paths) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1"; + $search_paths = "'" . implode( "', '", $wpdb->_escape( $paths ) ) . "'"; + } + + if ( count( $domains ) > 1 && count( $paths ) > 1 ) { + $site = $wpdb->get_row( "SELECT * FROM $wpdb->blogs WHERE domain IN ($search_domains) AND path IN ($search_paths) ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC LIMIT 1" ); + } elseif ( count( $domains ) > 1 ) { + $sql = $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE path = %s", $paths[0] ); + $sql .= " AND domain IN ($search_domains) ORDER BY CHAR_LENGTH(domain) DESC LIMIT 1"; + $site = $wpdb->get_row( $sql ); + } elseif ( count( $paths ) > 1 ) { + $sql = $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $domains[0] ); + $sql .= " AND path IN ($search_paths) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1"; $site = $wpdb->get_row( $sql ); } else { - $site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s and path = %s", $domain, $paths[0] ) ); + $site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $domains[0], $paths[0] ) ); } if ( $site ) { diff --git a/tests/phpunit/tests/ms.php b/tests/phpunit/tests/ms.php index ed5d90ff15..bb617ae14c 100644 --- a/tests/phpunit/tests/ms.php +++ b/tests/phpunit/tests/ms.php @@ -1225,6 +1225,7 @@ class Tests_MS extends WP_UnitTestCase { /** * @ticket 27003 + * @ticket 27927 */ function test_get_site_by_path() { $ids = array( @@ -1233,6 +1234,9 @@ class Tests_MS extends WP_UnitTestCase { 'wordpress.org/foo/bar/' => array( 'domain' => 'wordpress.org', 'path' => '/foo/bar/' ), 'make.wordpress.org/' => array( 'domain' => 'make.wordpress.org', 'path' => '/' ), 'make.wordpress.org/foo/' => array( 'domain' => 'make.wordpress.org', 'path' => '/foo/' ), + 'www.w.org/' => array( 'domain' => 'www.w.org', 'path' => '/' ), + 'www.w.org/foo/' => array( 'domain' => 'www.w.org', 'path' => '/foo/' ), + 'www.w.org/foo/bar/' => array( 'domain' => 'www.w.org', 'path' => '/foo/bar/' ), ); foreach ( $ids as &$id ) { @@ -1243,23 +1247,66 @@ class Tests_MS extends WP_UnitTestCase { $this->assertEquals( $ids['wordpress.org/'], get_site_by_path( 'wordpress.org', '/notapath/' )->blog_id ); + $this->assertEquals( $ids['wordpress.org/'], + get_site_by_path( 'www.wordpress.org', '/notapath/' )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/bar/'], get_site_by_path( 'wordpress.org', '/foo/bar/baz/' )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/bar/'], + get_site_by_path( 'www.wordpress.org', '/foo/bar/baz/' )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/bar/'], get_site_by_path( 'wordpress.org', '/foo/bar/baz/', 3 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/bar/'], + get_site_by_path( 'www.wordpress.org', '/foo/bar/baz/', 3 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/bar/'], get_site_by_path( 'wordpress.org', '/foo/bar/baz/', 2 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/bar/'], + get_site_by_path( 'www.wordpress.org', '/foo/bar/baz/', 2 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/'], get_site_by_path( 'wordpress.org', '/foo/bar/baz/', 1 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/foo/'], + get_site_by_path( 'www.wordpress.org', '/foo/bar/baz/', 1 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/'], get_site_by_path( 'wordpress.org', '/', 0 )->blog_id ); + $this->assertEquals( $ids['wordpress.org/'], + get_site_by_path( 'www.wordpress.org', '/', 0 )->blog_id ); + $this->assertEquals( $ids['make.wordpress.org/foo/'], get_site_by_path( 'make.wordpress.org', '/foo/bar/baz/qux/', 4 )->blog_id ); + + $this->assertEquals( $ids['make.wordpress.org/foo/'], + get_site_by_path( 'www.make.wordpress.org', '/foo/bar/baz/qux/', 4 )->blog_id ); + + $this->assertEquals( $ids['www.w.org/'], + get_site_by_path( 'www.w.org', '/', 0 )->blog_id ); + + $this->assertEquals( $ids['www.w.org/'], + get_site_by_path( 'www.w.org', '/notapath/' )->blog_id ); + + $this->assertEquals( $ids['www.w.org/foo/bar/'], + get_site_by_path( 'www.w.org', '/foo/bar/baz/' )->blog_id ); + + $this->assertEquals( $ids['www.w.org/foo/'], + get_site_by_path( 'www.w.org', '/foo/bar/baz/', 1 )->blog_id ); + + // A site installed with www will not be found by the root domain. + $this->assertFalse( get_site_by_path( 'w.org', '/' ) ); + $this->assertFalse( get_site_by_path( 'w.org', '/notapath/' ) ); + $this->assertFalse( get_site_by_path( 'w.org', '/foo/bar/baz/' ) ); + $this->assertFalse( get_site_by_path( 'w.org', '/foo/bar/baz/', 1 ) ); + + // A site will not be found by its root domain when an invalid subdomain is requested. + $this->assertFalse( get_site_by_path( 'invalid.wordpress.org', '/' ) ); + $this->assertFalse( get_site_by_path( 'invalid.wordpress.org', '/foo/bar/' ) ); } /**