WordPress.org

Make WordPress Core

Ticket #37217: 37217.4.diff

File 37217.4.diff, 8.1 KB (added by jeremyfelt, 3 years ago)
  • src/wp-includes/class-wp-network.php

     
    267267         * @return WP_Network|bool Network object if successful. False when no network is found.
    268268         */
    269269        public static function get_by_path( $domain = '', $path = '', $segments = null ) {
    270                 global $wpdb;
    271 
    272270                $domains = array( $domain );
    273271                $pieces  = explode( '.', $domain );
    274272
     
    295293                if ( wp_using_ext_object_cache() ) {
    296294                        $using_paths = wp_cache_get( 'networks_have_paths', 'site-options' );
    297295                        if ( false === $using_paths ) {
    298                                 $using_paths = (int) $wpdb->get_var( "SELECT id FROM {$wpdb->site} WHERE path <> '/' LIMIT 1" );
     296                                $using_paths = get_networks( array(
     297                                        'number'       => 1,
     298                                        'count'        => true,
     299                                        'path__not_in' => '/',
     300                                ) );
    299301                                wp_cache_add( 'networks_have_paths', $using_paths, 'site-options'  );
    300302                        }
    301303                }
     
    353355                        return $pre;
    354356                }
    355357
    356                 // @todo Consider additional optimization routes, perhaps as an opt-in for plugins.
    357                 // We already have paths covered. What about how far domains should be drilled down (including www)?
    358 
    359                 $search_domains = "'" . implode( "', '", $wpdb->_escape( $domains ) ) . "'";
    360 
    361358                if ( ! $using_paths ) {
    362                         $network = $wpdb->get_row( "
    363                                 SELECT * FROM {$wpdb->site}
    364                                 WHERE domain IN ({$search_domains})
    365                                 ORDER BY CHAR_LENGTH(domain)
    366                                 DESC LIMIT 1
    367                         " );
     359                        $networks = get_networks( array(
     360                                'number'     => 1,
     361                                'orderby'    => array(
     362                                        'domain_length' => 'DESC',
     363                                ),
     364                                'domain__in' => $domains,
     365                        ) );
    368366
    369                         if ( ! empty( $network ) && ! is_wp_error( $network ) ) {
    370                                 return new WP_Network( $network );
     367                        if ( ! empty( $networks ) ) {
     368                                return array_shift( $networks );
    371369                        }
    372370
    373371                        return false;
    374 
    375                 } else {
    376                         $search_paths = "'" . implode( "', '", $wpdb->_escape( $paths ) ) . "'";
    377                         $networks = $wpdb->get_results( "
    378                                 SELECT * FROM {$wpdb->site}
    379                                 WHERE domain IN ({$search_domains})
    380                                 AND path IN ({$search_paths})
    381                                 ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC
    382                         " );
    383372                }
    384373
     374                $networks = get_networks( array(
     375                        'orderby'    => array(
     376                                'domain_length' => 'DESC',
     377                                'path_length'   => 'DESC',
     378                        ),
     379                        'domain__in' => $domains,
     380                        'path__in'   => $paths,
     381                ) );
     382
    385383                /*
    386384                 * Domains are sorted by length of domain, then by length of path.
    387385                 * The domain must match for the path to be considered. Otherwise,
     
    402400                }
    403401
    404402                if ( true === $found ) {
    405                         return new WP_Network( $network );
     403                        return $network;
    406404                }
    407405
    408406                return false;
  • tests/phpunit/tests/multisite/bootstrap.php

     
    1717                        'wordpress.org/'         => array( 'domain' => 'wordpress.org', 'path' => '/' ),
    1818                        'make.wordpress.org/'    => array( 'domain' => 'make.wordpress.org', 'path' => '/' ),
    1919                        'wordpress.org/one/'     => array( 'domain' => 'wordpress.org', 'path' => '/one/' ),
     20                        'wordpress.org/one/b/'   => array( 'domain' => 'wordpress.org', 'path' => '/one/b/' ),
    2021                        'wordpress.net/'         => array( 'domain' => 'wordpress.net', 'path' => '/' ),
    2122                        'www.wordpress.net/'     => array( 'domain' => 'www.wordpress.net', 'path' => '/' ),
    2223                        'www.wordpress.net/two/' => array( 'domain' => 'www.wordpress.net', 'path' => '/two/' ),
     
    8081                        array( 'wordpress.net/',         'wordpress.net',       '/notapath/', 'A missing path on a top level domain should find the correct network.' ),
    8182                        array( 'www.wordpress.net/',     'www.wordpress.net',   '/notapath/', 'A missing path should find the correct network.' ),
    8283                        array( 'wordpress.org/one/',     'www.wordpress.org',   '/one/',      'Should find the path despite the www.' ),
     84                        array( 'wordpress.org/one/',     'wordpress.org',       '/one/page/', 'A request with two path segments should find the correct network.' ),
     85                        array( 'wordpress.org/one/b/',   'wordpress.org',       '/one/b/',    'A request with two valid path segments should find the correct network.' ),
    8386                        array( 'wordpress.org/',         'site1.wordpress.org', '/one/',      'Should not find path because domains do not match.' ),
    8487                        array( 'wordpress.net/three/',   'wordpress.net',       '/three/',    'A network can have a path.' ),
    8588                        array( 'www.wordpress.net/two/', 'www.wordpress.net',   '/two/',      'A www network with a path can coexist with a non-www network.' ),
    8689                        array( 'wordpress.net/',         'site1.wordpress.net', '/notapath/', 'An invalid subdomain should find the top level network domain.' ),
    8790                        array( 'wordpress.net/',         'site1.wordpress.net', '/three/',    'An invalid subdomain and path should find the top level network domain.' ),
     91                        array( 'wordpress.net/',         'x.y.wordpress.net',   '/',          'An invalid two level subdomain should find the top level network domain.' ),
    8892                );
    8993        }
    9094
    9195        /**
     96         * @ticket 37217
     97         * @dataProvider data_get_network_by_path_not_using_paths
     98         *
     99         * @param string $expected_key The array key associated with expected data for the test.
     100         * @param string $domain       The requested domain.
     101         * @param string $path         The requested path.
     102         * @param string $message      The message to pass for failed tests.
     103         */
     104        public function test_get_network_by_path_not_using_paths( $expected_key, $domain, $path, $message ) {
     105                if ( ! wp_using_ext_object_cache() ) {
     106                        $this->markTestSkipped( 'Only testable with an external object cache.' );
     107                }
     108
     109                // Temporarily store original object cache and using paths values.
     110                $using_paths_orig = wp_cache_get( 'networks_have_paths', 'site-options' );
     111
     112                wp_cache_set( 'networks_have_paths', 0, 'site-options'  );
     113
     114                $network = get_network_by_path( $domain, $path );
     115
     116                // Restore original object cache and using paths values.
     117                wp_cache_set( 'networks_have_paths', $using_paths_orig, 'site-options' );
     118
     119                $this->assertEquals( self::$network_ids[ $expected_key ], $network->id, $message );
     120        }
     121
     122        public function data_get_network_by_path_not_using_paths() {
     123                return array(
     124                        array( 'wordpress.org/',         'wordpress.org',       '/',          'A standard domain and path request should work.' ),
     125                        array( 'wordpress.net/',         'wordpress.net',       '/notapath/', 'A network matching a top level domain should be found regardless of path.' ),
     126                        array( 'www.wordpress.net/',     'www.wordpress.net',   '/notapath/', 'A network matching a domain should be found regardless of path.' ),
     127                        array( 'wordpress.org/',         'www.wordpress.org',   '/one/',      'Should find the network despite the www and regardless of path.' ),
     128                        array( 'wordpress.org/',         'site1.wordpress.org', '/one/',      'Should find the network with the corresponding top level domain regardless of path.' ),
     129                        array( 'www.wordpress.net/',     'www.wordpress.net',   '/two/',      'A www network can coexist with a non-www network.' ),
     130                        array( 'make.wordpress.org/',    'make.wordpress.org',  '/notapath/', 'A subdomain network should be found regardless of path.' ),
     131                        array( 'wordpress.net/',         'x.y.wordpress.net',   '/',          'An invalid two level subdomain should find the top level network domain.' ),
     132                );
     133        }
     134
     135        /**
     136         * Even if a matching network is available, it should not match if the the filtered
     137         * value for network path segments is fewer than the number of paths passed.
     138         */
     139        public function test_get_network_by_path_with_forced_single_path_segment_returns_single_path_network() {
     140                add_filter( 'network_by_path_segments_count', array( $this, 'filter_network_path_segments' ) );
     141                $network = get_network_by_path( 'wordpress.org', '/one/b/' );
     142                remove_filter( 'network_by_path_segments_count', array( $this, 'filter_network_path_segments' ) );
     143
     144                $this->assertEquals( self::$network_ids[ 'wordpress.org/one/' ], $network->id );
     145        }
     146
     147        public function filter_network_path_segments() {
     148                return 1;
     149        }
     150
     151        /**
    92152         * @ticket 27003
    93153         * @ticket 27927
    94154         * @dataProvider data_get_site_by_path