WordPress.org

Make WordPress Core

Ticket #27003: 27003.12.diff

File 27003.12.diff, 14.3 KB (added by nacin, 6 years ago)
  • src/wp-includes/ms-load.php

     
    145145function get_network_by_path( $domain, $path ) {
    146146        global $wpdb;
    147147
    148         $network_id = false;
    149148
    150149        $domains = $exact_domains = array( $domain );
    151150        $pieces = explode( '.', $domain );
     
    191190        }
    192191
    193192        if ( $found ) {
    194                 $network = wp_get_network( $network );
    195 
    196                 return $network;
     193                return wp_get_network( $network );
    197194        }
    198195
    199196        return false;
     
    220217        return $network;
    221218}
    222219
    223 /**
    224  * Sets current_site object.
    225  *
    226  * @access private
    227  * @since 3.0.0
    228  * @return object $current_site object
    229  */
    230 function wpmu_current_site() {
    231         global $wpdb, $current_site, $domain, $path;
     220function get_site_by_path( $domain, $path ) {
     221        global $wpdb;
    232222
    233         if ( empty( $current_site ) )
    234                 $current_site = new stdClass;
     223        if ( is_array( $path ) ) {
     224                $paths = $path;
     225                $path = $paths[0];
     226        } else {
     227                $paths = array( '/', $path );
     228        }
    235229
    236         // 1. If constants are defined, that's our network.
    237         if ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) ) {
    238                 $current_site->id = defined( 'SITE_ID_CURRENT_SITE' ) ? SITE_ID_CURRENT_SITE : 1;
    239                 $current_site->domain = DOMAIN_CURRENT_SITE;
    240                 $current_site->path   = $path = PATH_CURRENT_SITE;
    241                 if ( defined( 'BLOG_ID_CURRENT_SITE' ) )
    242                         $current_site->blog_id = BLOG_ID_CURRENT_SITE;
    243                 elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) // deprecated.
    244                         $current_site->blog_id = BLOGID_CURRENT_SITE;
     230        // @todo get_blog_details(), caching, etc.
     231        if ( count( $paths ) > 1 ) {
     232                $paths = "'" . implode( "', '", $wpdb->_escape( $paths ) ) . "'";
     233                $site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs
     234                        WHERE domain = %s AND path IN ($paths) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1", $domain ) );
     235        } else {
     236                $site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s and path = %s", $domain, $path ) );
     237        }
    245238
    246         // 2. Pull the network from cache, if possible.
    247         } elseif ( ! $current_site = wp_cache_get( 'current_site', 'site-options' ) ) {
    248 
    249                 // 3. See if they have only one network.
    250                 $networks = $wpdb->get_col( "SELECT id FROM $wpdb->site LIMIT 2" );
    251 
    252                 if ( count( $networks ) <= 1 ) {
    253                         $current_site = wp_get_network( $networks[0]->id );
    254 
    255                         $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id
    256                                 FROM $wpdb->blogs WHERE domain = %s AND path = %s",
    257                                 $current_site->domain, $current_site->path ) );
    258 
    259                         wp_cache_set( 'current_site', 'site-options' );
    260 
    261                 // 4. Multiple networks are in play. Determine which via domain and path.
    262                 } else {
    263                         // Find the first path segment.
    264                         $path = substr( $_SERVER['REQUEST_URI'], 0, 1 + strpos( $_SERVER['REQUEST_URI'], '/', 1 ) );
    265                         $current_site = get_network_by_path( $domain, $path );
    266 
    267                         // Option 1. We did not find anything.
    268                         if ( ! $current_site ) {
    269                                 wp_load_translations_early();
    270                                 wp_die( __( 'No site defined on this host. If you are the owner of this site, please check <a href="http://codex.wordpress.org/Debugging_a_WordPress_Network">Debugging a WordPress Network</a> for help.' ) );
    271                         }
    272                 }
     239        if ( $site ) {
     240                // @todo get_blog_details()
     241                return $site;
    273242        }
    274243
    275         // Option 2. We found something. Load up site meta and return.
    276         wp_load_core_site_options();
    277         $current_site = get_current_site_name( $current_site );
    278         return $current_site;
     244        return false;
    279245}
    280246
    281247/**
  • src/wp-includes/ms-settings.php

     
    2222
    2323if ( !isset( $current_site ) || !isset( $current_blog ) ) {
    2424
    25         $domain = addslashes( $_SERVER['HTTP_HOST'] );
    26         if ( false !== strpos( $domain, ':' ) ) {
    27                 if ( substr( $domain, -3 ) == ':80' ) {
    28                         $domain = substr( $domain, 0, -3 );
    29                         $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -3 );
    30                 } elseif ( substr( $domain, -4 ) == ':443' ) {
    31                         $domain = substr( $domain, 0, -4 );
    32                         $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -4 );
    33                 } else {
    34                         wp_load_translations_early();
    35                         wp_die( __( 'Multisite only works without the port number in the URL.' ) );
    36                 }
     25        // Given the domain and path, let's try to identify the network and site.
     26        // Usually, it's easier to query the site first, which declares its network.
     27        // In limited situations, though, we either can or must find the network first.
     28
     29        $domain = strtolower( stripslashes( $_SERVER['HTTP_HOST'] ) );
     30        if ( substr( $domain, -3 ) == ':80' ) {
     31                $domain = substr( $domain, 0, -3 );
     32                $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -3 );
     33        } elseif ( substr( $domain, -4 ) == ':443' ) {
     34                $domain = substr( $domain, 0, -4 );
     35                $_SERVER['HTTP_HOST'] = substr( $_SERVER['HTTP_HOST'], 0, -4 );
    3736        }
    3837
    39         $domain = rtrim( $domain, '.' );
     38        $path = stripslashes( $_SERVER['REQUEST_URI'] );
     39        if ( is_admin() ) {
     40                $path = preg_replace( '#(.*)/wp-admin/.*#', '$1/', $path );
     41        }
     42        list( $path ) = explode( '?', $path );
    4043
    41         $path = preg_replace( '|([a-z0-9-]+.php.*)|', '', $_SERVER['REQUEST_URI'] );
    42         $path = str_replace ( '/wp-admin/', '/', $path );
    43         $path = preg_replace( '|(/[a-z0-9-]+?/).*|', '$1', $path );
     44        // If the network is defined in wp-config.php, we can simply use that.
     45        if ( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) ) {
     46                $current_site = new stdClass;
     47                $current_site->id = defined( 'SITE_ID_CURRENT_SITE' ) ? SITE_ID_CURRENT_SITE : 1;
     48                $current_site->domain = DOMAIN_CURRENT_SITE;
     49                $current_site->path = PATH_CURRENT_SITE;
     50                if ( defined( 'BLOG_ID_CURRENT_SITE' ) ) {
     51                        $current_site->blog_id = BLOG_ID_CURRENT_SITE;
     52                } elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) { // deprecated.
     53                        $current_site->blog_id = BLOGID_CURRENT_SITE;
     54                }
    4455
    45         $current_site = wpmu_current_site();
    46         $current_site->cookie_domain = $current_site->domain;
    47         if ( 'www.' === substr( $current_site->cookie_domain, 0, 4 ) ) {
    48                 $current_site->cookie_domain = substr( $current_site->cookie_domain, 4 );
    49         }
     56                if ( $current_site->domain === $domain && $current_site->path === $path ) {
     57                        $current_blog = get_site_by_path( $domain, $path );
     58                } elseif ( '/' !== $current_site->path && $current_site->domain === $domain && 0 === strpos( $path, $current_site->path ) ) {
     59                        // If the current network has a path and also matches the domain and path of the request,
     60                        // we need to look for a site using the first path segment following the network's path.
     61                        $next_segment = substr( $path, strlen( $current_site->path ) );
     62                        $next_segment = substr( $next_segment, 0, 1 + strpos( $next_segment, '/', 1 ) );
     63                        $current_blog = get_site_by_path( $domain, array( $current_site->path, $current_site->path . $next_segment ) );
     64                        unset( $next_segment );
     65                } else {
     66                        // Otherwise, use the first path segment (as usual).
     67                        $current_blog = get_site_by_path( $domain, substr( $path, 0, 1 + strpos( $path, '/', 1 ) ) );
     68                }
    5069
    51         if ( ! isset( $current_site->blog_id ) )
    52                 $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) );
     70        } elseif ( ! is_subdomain_install() ) {
     71                /*
     72                 * A "subdomain" install can be re-interpreted to mean "can support any domain".
     73                 * If we're not dealing with one of these installs, then the important part is determing
     74                 * the network first, because we need the network's path to identify any sites.
     75                 */
     76                if ( ! $current_site = wp_cache_get( 'current_network', 'site-options' ) ) {
     77                        // Are there even two networks installed?
     78                        $one_network = $wpdb->get_row( "SELECT * FROM $wpdb->site LIMIT 2" ); // [sic]
     79                        if ( $wpdb->num_rows === 1 ) {
     80                                $current_site = wp_get_network( $one_network );
     81                                wp_cache_set( 'current_network', 'site-options' );
     82                        }
     83                }
     84                if ( empty( $current_site ) ) {
     85                        $current_site = get_network_by_path( $domain, substr( $path, 0, 1 + strpos( $path, '/', 1 ) ) );
     86                }
    5387
    54         if ( is_subdomain_install() ) {
    55                 $current_blog = wp_cache_get( 'current_blog_' . $domain, 'site-options' );
    56                 if ( !$current_blog ) {
    57                         $current_blog = get_blog_details( array( 'domain' => $domain ), false );
    58                         if ( $current_blog )
    59                                 wp_cache_set( 'current_blog_' . $domain, $current_blog, 'site-options' );
     88                if ( $path === $current_site->path ) {
     89                        $current_blog = get_site_by_path( $domain, $path );
     90                } else {
     91                        // Search the network path + one more path segment (and also the network path).
     92                        $next_segment = substr( $path, strlen( $current_site->path ) );
     93                        $next_segment = substr( $next_segment, 0, 1 + strpos( $next_segment, '/', 1 ) );
     94                        $current_blog = get_site_by_path( $domain, array( $current_site->path, $current_site->path . $next_segment ) );
     95                        unset( $next_segment );
    6096                }
    61                 if ( $current_blog && $current_blog->site_id != $current_site->id ) {
    62                         $current_site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->site WHERE id = %d", $current_blog->site_id ) );
    63                         if ( ! isset( $current_site->blog_id ) )
    64                                 $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) );
    65                 } else
    66                         $blogname = substr( $domain, 0, strpos( $domain, '.' ) );
    6797        } else {
    68                 $blogname = htmlspecialchars( substr( $_SERVER[ 'REQUEST_URI' ], strlen( $path ) ) );
    69                 if ( false !== strpos( $blogname, '/' ) )
    70                         $blogname = substr( $blogname, 0, strpos( $blogname, '/' ) );
    71                 if ( false !== strpos( $blogname, '?' ) )
    72                         $blogname = substr( $blogname, 0, strpos( $blogname, '?' ) );
    73                 $reserved_blognames = array( 'page', 'comments', 'blog', 'wp-admin', 'wp-includes', 'wp-content', 'files', 'feed' );
    74                 if ( $blogname != '' && ! in_array( $blogname, $reserved_blognames ) && ! is_file( $blogname ) )
    75                         $path .= $blogname . '/';
    76                 $current_blog = wp_cache_get( 'current_blog_' . $domain . $path, 'site-options' );
    77                 if ( ! $current_blog ) {
    78                         $current_blog = get_blog_details( array( 'domain' => $domain, 'path' => $path ), false );
    79                         if ( $current_blog )
    80                                 wp_cache_set( 'current_blog_' . $domain . $path, $current_blog, 'site-options' );
     98                // Find the site by the domain and at most the first path segment.
     99                $current_blog = get_site_by_path( $domain, substr( $path, 0, 1 + strpos( $path, '/', 1 ) ) );
     100                if ( $current_blog ) {
     101                        $current_site = wp_get_network( $current_blog->site_id ? $current_blog->site_id : 1 );
     102                } else {
     103                        // If you don't have a site with the same domain/path as a network, you're pretty screwed, but what the hell:
     104                        $current_site = get_network_by_path( $domain, substr( $path, 0, 1 + strpos( $path, '/', 1 ) ) );
    81105                }
    82                 unset($reserved_blognames);
    83106        }
    84107
    85         if ( ! defined( 'WP_INSTALLING' ) && is_subdomain_install() && ! is_object( $current_blog ) ) {
    86                 if ( defined( 'NOBLOGREDIRECT' ) ) {
    87                         $destination = NOBLOGREDIRECT;
    88                         if ( '%siteurl%' == $destination )
    89                                 $destination = "http://" . $current_site->domain . $current_site->path;
     108        // If we don't have a network by now, we have a problem.
     109        if ( empty( $current_site ) ) {
     110                ms_not_installed();
     111        }
     112
     113        // @todo What if the domain of the network doesn't match the current site?
     114        $current_site->cookie_domain = $current_site->domain;
     115        if ( 'www.' === substr( $current_site->cookie_domain, 0, 4 ) ) {
     116                $current_site->cookie_domain = substr( $current_site->cookie_domain, 4 );
     117        }
     118
     119        // Figure out the current network's main site.
     120        if ( ! isset( $current_site->blog_id ) ) {
     121                if ( $current_blog && $current_blog->domain === $current_site->domain && $current_blog->path === $current_site->path ) {
     122                        $current_site->blog_id = $current_blog->blog_id;
    90123                } else {
    91                         $destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
     124                        // @todo we should be able to cache the blog ID of a network's main site easily.
     125                        $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s",
     126                                $current_site->domain, $current_site->path ) );
    92127                }
    93                 header( 'Location: ' . $destination );
    94                 die();
    95128        }
    96129
    97         if ( ! defined( 'WP_INSTALLING' ) ) {
    98                 if ( $current_site && ! $current_blog ) {
    99                         if ( $current_site->domain != $_SERVER[ 'HTTP_HOST' ] ) {
     130        // If we haven't figured out our site, the hell, man.
     131        if ( empty( $current_blog ) ) {
     132                if ( defined( 'WP_INSTALLING' ) ) {
     133                        $current_blog->blog_id = $blog_id = 1;
     134
     135                } elseif ( is_subdomain_install() ) {
     136                        // @todo This is only for an open registration subdomain network.
     137                        if ( defined( 'NOBLOGREDIRECT' ) ) {
     138                                if ( '%siteurl%' === NOBLOGREDIRECT ) {
     139                                        $destination = "http://" . $current_site->domain . $current_site->path;
     140                                } else {
     141                                        $destination = NOBLOGREDIRECT;
     142                                }
     143                        } else {
     144                                $destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
     145                        }
     146                        header( 'Location: ' . $destination );
     147                        exit;
     148
     149                } else {
     150                        if ( 0 !== strcasecmp( $current_site->domain, $domain ) ) {
    100151                                header( 'Location: http://' . $current_site->domain . $current_site->path );
    101152                                exit;
    102153                        }
    103                         $current_blog = get_blog_details( array( 'domain' => $current_site->domain, 'path' => $current_site->path ), false );
     154                        ms_not_installed();
    104155                }
    105                 if ( ! $current_blog || ! $current_site )
    106                         ms_not_installed();
    107156        }
    108157
    109158        $blog_id = $current_blog->blog_id;
    110159        $public  = $current_blog->public;
    111160
    112         if ( empty( $current_blog->site_id ) )
     161        if ( empty( $current_blog->site_id ) ) {
     162                // This dates to [MU134] and shouldn't be relevant anymore,
     163                // but it could be possible for arguments passed to insert_blog() etc.
    113164                $current_blog->site_id = 1;
     165        }
     166
    114167        $site_id = $current_blog->site_id;
    115 
     168        wp_load_core_site_options();
    116169        $current_site = get_current_site_name( $current_site );
     170}
    117171
    118         if ( ! $blog_id ) {
    119                 if ( defined( 'WP_INSTALLING' ) ) {
    120                         $current_blog->blog_id = $blog_id = 1;
    121                 } else {
    122                         wp_load_translations_early();
    123                         $msg = ! $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->site'" ) ? ' ' . __( 'Database tables are missing.' ) : '';
    124                         wp_die( __( 'No site by that name on this system.' ) . $msg );
    125                 }
    126         }
    127 }
    128172$wpdb->set_prefix( $table_prefix, false ); // $table_prefix can be set in sunrise.php
    129173$wpdb->set_blog_id( $current_blog->blog_id, $current_blog->site_id );
    130174$table_prefix = $wpdb->get_blog_prefix();