diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 9ddfb0f46b85495c98a6a6f681b450ad91bd25e9..a2eb065c7aaf3802aec92f29aa75953bdc30f98a 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -391,12 +391,14 @@ public static function findSitePath(Request $request, $require_settings = TRUE, return $test_db->getTestSitePath(); } - // Determine whether multi-site functionality is enabled. + // Determine whether multi-site functionality is enabled. If not, return + // the default directory. if (!file_exists($app_root . '/sites/sites.php')) { return 'sites/default'; } - // Otherwise, use find the site path using the request. + // Pre-populate host and script variables, then include sites.php which may + // populate $sites with a site-directory mapping. $script_name = $request->server->get('SCRIPT_NAME'); if (!$script_name) { $script_name = $request->server->get('SCRIPT_FILENAME'); @@ -406,16 +408,27 @@ public static function findSitePath(Request $request, $require_settings = TRUE, $sites = []; include $app_root . '/sites/sites.php'; - $uri = explode('/', $script_name); - $server = explode('.', implode('.', array_reverse(explode(':', rtrim($http_host, '.'))))); - for ($i = count($uri) - 1; $i > 0; $i--) { - for ($j = count($server); $j > 0; $j--) { - $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i)); - if (isset($sites[$dir]) && file_exists($app_root . '/sites/' . $sites[$dir])) { - $dir = $sites[$dir]; + // Construct an identifier from pieces of the (port plus) host plus script + // path (excluding the filename). Loop over all possibilities starting from + // most specific, then dropping pieces from the start of the port/hostname + // while keeping the full path, then gradually dropping pieces from the end + // of the path... until we find a directory corresponding to the identifier. + $path_parts = explode('/', $script_name); + $host_parts = explode('.', implode('.', array_reverse(explode(':', rtrim($http_host, '.'))))); + for ($i = count($path_parts) - 1; $i > 0; $i--) { + for ($j = count($host_parts); $j > 0; $j--) { + // Assume the path has a leading slash, so the imploded path parts are + // either a path identifier with leading dot, or an empty string. + $site_id = implode('.', array_slice($host_parts, -$j)) . implode('.', array_slice($path_parts, 0, $i)); + + // If the identifier is a key in $sites, check for a directory matching + // the corresponding value. Otherwise, check for a directory matching + // the identifier. + if (isset($sites[$site_id]) && file_exists($app_root . '/sites/' . $sites[$site_id])) { + $site_id = $sites[$site_id]; } - if (file_exists($app_root . '/sites/' . $dir . '/settings.php') || (!$require_settings && file_exists($app_root . '/sites/' . $dir))) { - return "sites/$dir"; + if (file_exists($app_root . '/sites/' . $site_id . '/settings.php') || (!$require_settings && file_exists($app_root . '/sites/' . $site_id))) { + return "sites/$site_id"; } } }