Make WordPress Core


Ignore:
Timestamp:
03/02/2014 10:24:50 PM (12 years ago)
Author:
nacin
Message:

Introduce get_site_by_path() and further rewrite the site detection process for multisite.

This is the first big step to supporting arbitrary domains and paths. In this new approach, sites are detected first where possible, then the network is inferred. Allows filtering for arbitrary path segments, smooths out some weirdness, and removes various restrictions. A sunrise plugin could do much of its work by adding filters, if those are even needed.

see #27003.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ms-settings.php

    r27178 r27359  
    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 );
     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 );
     36        }
     37
     38        $path = stripslashes( $_SERVER['REQUEST_URI'] );
     39        if ( is_admin() ) {
     40                $path = preg_replace( '#(.*)/wp-admin/.*#', '$1/', $path );
     41        }
     42        list( $path ) = explode( '?', $path );
     43
     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                }
     55
     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                        $current_blog = get_site_by_path( $domain, $path, 1 + count( explode( '/', trim( $current_site->path, '/' ) ) ) );
    3362                } else {
    34                         wp_load_translations_early();
    35                         wp_die( __( 'Multisite only works without the port number in the URL.' ) );
     63                        // Otherwise, use the first path segment (as usual).
     64                        $current_blog = get_site_by_path( $domain, $path, 1 );
     65                }
     66
     67        } elseif ( ! is_subdomain_install() ) {
     68                /*
     69                 * A "subdomain" install can be re-interpreted to mean "can support any domain".
     70                 * If we're not dealing with one of these installs, then the important part is determing
     71                 * the network first, because we need the network's path to identify any sites.
     72                 */
     73                if ( ! $current_site = wp_cache_get( 'current_network', 'site-options' ) ) {
     74                        // Are there even two networks installed?
     75                        $one_network = $wpdb->get_row( "SELECT * FROM $wpdb->site LIMIT 2" ); // [sic]
     76                        if ( 1 === $wpdb->num_rows ) {
     77                                $current_site = wp_get_network( $one_network );
     78                                wp_cache_set( 'current_network', 'site-options' );
     79                        } elseif ( 0 === $wpdb->num_rows ) {
     80                                ms_not_installed();
     81                        }
     82                }
     83                if ( empty( $current_site ) ) {
     84                        $current_site = get_network_by_path( $domain, $path, 1 );
     85                }
     86
     87                if ( empty( $current_site ) ) {
     88                        ms_not_installed();
     89                } elseif ( $path === $current_site->path ) {
     90                        $current_blog = get_site_by_path( $domain, $path );
     91                } else {
     92                        // Search the network path + one more path segment (on top of the network path).
     93                        $current_blog = get_site_by_path( $domain, $path, substr_count( $current_site->path, '/' ) );
     94                }
     95        } else {
     96                // Find the site by the domain and at most the first path segment.
     97                $current_blog = get_site_by_path( $domain, $path, 1 );
     98                if ( $current_blog ) {
     99                        $current_site = wp_get_network( $current_blog->site_id ? $current_blog->site_id : 1 );
     100                } else {
     101                        // If you don't have a site with the same domain/path as a network, you're pretty screwed, but:
     102                        $current_site = get_network_by_path( $domain, $path, 1 );
    36103                }
    37104        }
    38105
    39         $domain = rtrim( $domain, '.' );
     106        // The network declared by the site trumps any constants.
     107        if ( $current_blog && $current_blog->site_id != $current_site->id ) {
     108                $current_site = wp_get_network( $current_blog->site_id );
     109        }
    40110
    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 );
     111        // If we don't have a network by now, we have a problem.
     112        if ( empty( $current_site ) ) {
     113                ms_not_installed();
     114        }
    44115
    45         $current_site = wpmu_current_site();
     116        // @todo What if the domain of the network doesn't match the current site?
    46117        $current_site->cookie_domain = $current_site->domain;
    47118        if ( 'www.' === substr( $current_site->cookie_domain, 0, 4 ) ) {
     
    49120        }
    50121
    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 ) );
    53 
    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' );
     122        // Figure out the current network's main site.
     123        if ( ! isset( $current_site->blog_id ) ) {
     124                if ( $current_blog && $current_blog->domain === $current_site->domain && $current_blog->path === $current_site->path ) {
     125                        $current_site->blog_id = $current_blog->blog_id;
     126                } else {
     127                        // @todo we should be able to cache the blog ID of a network's main site easily.
     128                        $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s",
     129                                $current_site->domain, $current_site->path ) );
    60130                }
    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, '.' ) );
    67         } 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' );
    81                 }
    82                 unset($reserved_blognames);
    83131        }
    84132
    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;
     133        // If we haven't figured out our site, give up.
     134        if ( empty( $current_blog ) ) {
     135                if ( defined( 'WP_INSTALLING' ) ) {
     136                        $current_blog->blog_id = $blog_id = 1;
     137
     138                } elseif ( is_subdomain_install() ) {
     139                        // @todo This is only for an open registration subdomain network.
     140                        if ( defined( 'NOBLOGREDIRECT' ) ) {
     141                                if ( '%siteurl%' === NOBLOGREDIRECT ) {
     142                                        $destination = "http://" . $current_site->domain . $current_site->path;
     143                                } else {
     144                                        $destination = NOBLOGREDIRECT;
     145                                }
     146                        } else {
     147                                $destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
     148                        }
     149                        header( 'Location: ' . $destination );
     150                        exit;
     151
    90152                } else {
    91                         $destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
    92                 }
    93                 header( 'Location: ' . $destination );
    94                 die();
    95         }
    96 
    97         if ( ! defined( 'WP_INSTALLING' ) ) {
    98                 if ( $current_site && ! $current_blog ) {
    99                         if ( $current_site->domain != $_SERVER[ 'HTTP_HOST' ] ) {
     153                        if ( 0 !== strcasecmp( $current_site->domain, $domain ) ) {
    100154                                header( 'Location: http://' . $current_site->domain . $current_site->path );
    101155                                exit;
    102156                        }
    103                         $current_blog = get_blog_details( array( 'domain' => $current_site->domain, 'path' => $current_site->path ), false );
     157                        ms_not_installed();
    104158                }
    105                 if ( ! $current_blog || ! $current_site )
    106                         ms_not_installed();
    107159        }
    108160
     
    110162        $public  = $current_blog->public;
    111163
    112         if ( empty( $current_blog->site_id ) )
     164        if ( empty( $current_blog->site_id ) ) {
     165                // This dates to [MU134] and shouldn't be relevant anymore,
     166                // but it could be possible for arguments passed to insert_blog() etc.
    113167                $current_blog->site_id = 1;
     168        }
     169
    114170        $site_id = $current_blog->site_id;
     171        wp_load_core_site_options( $site_id );
     172}
    115173
    116         $current_site = get_current_site_name( $current_site );
    117 
    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 }
    128174$wpdb->set_prefix( $table_prefix, false ); // $table_prefix can be set in sunrise.php
    129175$wpdb->set_blog_id( $current_blog->blog_id, $current_blog->site_id );
     
    135181wp_start_object_cache();
    136182
     183if ( ! isset( $current_site->site_name ) ) {
     184        $current_site->site_name = get_site_option( 'site_name' );
     185        if ( ! $current_site->site_name ) {
     186                $current_site->site_name = ucfirst( $current_site->domain );
     187        }
     188}
     189
    137190// Define upload directory constants
    138191ms_upload_constants();
Note: See TracChangeset for help on using the changeset viewer.