+ $paths = array();
+
+ while ( count( $path_segments ) ) {
+ $paths[] = '/' . implode( '/', $path_segments ) . '/';
+ array_pop( $path_segments );
+ }
+
+ $paths[] = '/';
+
+ /**
+ * Determine a site by its domain and path.
+ *
+ * This allows one to short-circuit the default logic, perhaps by
+ * replacing it with a routine that is more optimal for your setup.
+ *
+ * Return null to avoid the short-circuit. Return false if no site
+ * can be found at the requested domain and path. Otherwise, return
+ * a site object.
+ *
+ * @since 3.9.0
+ *
+ * @param null|bool|object $site Site value to return by path.
+ * @param string $domain The requested domain.
+ * @param string $path The requested path, in full.
+ * @param int|null $segments The suggested number of paths to consult.
+ * Default null, meaning the entire path was to be consulted.
+ * @param array $paths The paths to search for, based on $path and $segments.
+ */
+ $pre = apply_filters( 'pre_get_site_by_path', null, $domain, $path, $segments, $paths );
+ if ( null !== $pre ) {
+ return $pre;
+ }
+
+ /*
+ * @todo
+ * get_blog_details(), caching, etc. Consider alternative optimization routes,
+ * perhaps as an opt-in for plugins, rather than using the pre_* filter.
+ * For example: The segments filter can expand or ignore paths.
+ * If persistent caching is enabled, we could query the DB for a path <> '/'
+ * 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 );
+ }
+
+ $args = array(
+ 'domain__in' => $domains,
+ 'path__in' => $paths,
+ 'number' => 1,
+ );
+
+ if ( count( $domains ) > 1 ) {
+ $args['orderby']['domain_length'] = 'DESC';
+ }
+
+ if ( count( $paths ) > 1 ) {
+ $args['orderby']['path_length'] = 'DESC';
+ }
+
+ $result = get_sites( $args );
+ $site = array_shift( $result );
+
+ if ( $site ) {
+ // @todo get_blog_details()
+ return $site;
+ }
+
+ return false;
+}
+
+/**
+ * Identifies the network and site of a requested domain and path and populates the
+ * corresponding network and site global objects as part of the multisite bootstrap process.
+ *
+ * Prior to 4.6.0, this was a procedural block in `ms-settings.php`. It was wrapped into
+ * a function to facilitate unit tests. It should not be used outside of core.
+ *
+ * Usually, it's easier to query the site first, which then declares its network.
+ * In limited situations, we either can or must find the network first.
+ *
+ * If a network and site are found, a `true` response will be returned so that the
+ * request can continue.
+ *
+ * If neither a network or site is found, `false` or a URL string will be returned
+ * so that either an error can be shown or a redirect can occur.
+ *
+ * @since 4.6.0
+ * @access private
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ * @global WP_Network $current_site The current network.
+ * @global WP_Site $current_blog The current site.
+ *
+ * @param string $domain The requested domain.
+ * @param string $path The requested path.
+ * @param bool $subdomain Optional. Whether a subdomain (true) or subdirectory (false) configuration.
+ * Default false.
+ * @return bool|string True if bootstrap successfully populated `$current_blog` and `$current_site`.
+ * False if bootstrap could not be properly completed.
+ * Redirect URL if parts exist, but the request as a whole can not be fulfilled.
+ */
+function ms_load_current_site_and_network( $domain, $path, $subdomain = false ) {
+ global $wpdb, $current_site, $current_blog;
+
+ // If the network is defined in wp-config.php, we can simply use that.