Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/DrupalKernel.php \Drupal\Core\DrupalKernel::findSitePath()
  2. 9 core/lib/Drupal/Core/DrupalKernel.php \Drupal\Core\DrupalKernel::findSitePath()

Returns the appropriate site directory for a request.

Once the kernel has been created DrupalKernelInterface::getSitePath() is preferred since it gets the statically cached result of this method.

Site directories contain all site specific code. This includes settings.php for bootstrap level configuration, file configuration stores, public file storage and site specific modules and themes.

A file named sites.php must be present in the sites directory for multisite. If it doesn't exist, then 'sites/default' will be used.

Finds a matching site directory file by stripping the website's hostname from left to right and pathname from right to left. By default, the directory must contain a 'settings.php' file for it to match. If the parameter $require_settings is set to FALSE, then a directory without a 'settings.php' file will match as well. The first configuration file found will be used and the remaining ones will be ignored. If no configuration file is found, returns a default value 'sites/default'. See default.settings.php for examples on how the URL is converted to a directory.

The sites.php file in the sites directory can define aliases in an associative array named $sites. The array is written in the format '<port>.<domain>.<path>' => 'directory'. As an example, to create a directory alias for https://www.drupal.org:8080/my-site/test whose configuration file is in sites/example.com, the array should be defined as:

$sites = array(
  '8080.www.drupal.org.my-site.test' => 'example.com',
);

Parameters

\Symfony\Component\HttpFoundation\Request $request: The current request.

bool $require_settings: Only directories with an existing settings.php file will be recognized. Defaults to TRUE. During initial installation, this is set to FALSE so that Drupal can detect a matching directory, then create a new settings.php file in it.

string $app_root: (optional) The path to the application root as a string. If not supplied, the application root will be computed.

Return value

string The path of the matching directory.

Throws

\Symfony\Component\HttpKernel\Exception\BadRequestHttpException In case the host name in the request is invalid.

See also

\Drupal\Core\DrupalKernelInterface::getSitePath()

\Drupal\Core\DrupalKernelInterface::setSitePath()

default.settings.php

example.sites.php

15 calls to DrupalKernel::findSitePath()
db-tools.php in core/scripts/db-tools.php
A command line application to import a database generation script.
DistributionProfileExistingSettingsTest::prepareEnvironment in core/tests/Drupal/FunctionalTests/Installer/DistributionProfileExistingSettingsTest.php
DrupalKernel::initializeSettings in core/lib/Drupal/Core/DrupalKernel.php
Locate site path and initialize settings singleton.
DrupalKernelTest::testFindSitePath in core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php
Tests site path finding.
drupal_rebuild in core/includes/utility.inc
Rebuilds all caches even when Drupal itself does not work.

... See full list

File

core/lib/Drupal/Core/DrupalKernel.php, line 399

Class

DrupalKernel
The DrupalKernel class is the core of Drupal itself.

Namespace

Drupal\Core

Code

public static function findSitePath(Request $request, $require_settings = TRUE, $app_root = NULL) {
  if (static::validateHostname($request) === FALSE) {
    throw new BadRequestHttpException();
  }
  if ($app_root === NULL) {
    $app_root = static::guessApplicationRoot();
  }

  // Check for a test override.
  if ($test_prefix = drupal_valid_test_ua()) {
    $test_db = new TestDatabase($test_prefix);
    return $test_db
      ->getTestSitePath();
  }

  // Determine whether multi-site functionality is enabled. If not, return
  // the default directory.
  if (!file_exists($app_root . '/sites/sites.php')) {
    return 'sites/default';
  }

  // 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');
  }
  $http_host = $request
    ->getHttpHost();
  $sites = [];
  include $app_root . '/sites/sites.php';

  // 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/' . $site_id . '/settings.php') || !$require_settings && file_exists($app_root . '/sites/' . $site_id)) {
        return "sites/{$site_id}";
      }
    }
  }
  return 'sites/default';
}