diff --git a/core/INSTALL.txt b/core/INSTALL.txt index e9430d4..3f47a41 100644 --- a/core/INSTALL.txt +++ b/core/INSTALL.txt @@ -151,12 +151,12 @@ INSTALLATION which is normally in the directory sites/default (to avoid problems when upgrading, Drupal is not packaged with this file). If auto-creation fails, you will need to create this file yourself, using the file - sites/default/default.settings.php as a template. + core/default.settings.php as a template. For example, on a Unix/Linux command line, you can make a copy of the default.settings.php file with the command: - cp sites/default/default.settings.php sites/default/settings.php + cp core/default.settings.php sites/default/settings.php Next, grant write privileges to the file to everyone (including the web server) with the command: diff --git a/core/UPGRADE.txt b/core/UPGRADE.txt index f035b6c..57021fb 100644 --- a/core/UPGRADE.txt +++ b/core/UPGRADE.txt @@ -163,10 +163,6 @@ following the instructions in the INTRODUCTION section at the top of this file: no longer need their data, then you can uninstall them under the Uninstall tab after disabling them. -8. On the command line or in your FTP client, remove the file - - sites/default/default.settings.php - 9. Remove all old core files and directories, except for the 'sites' directory and any custom files you added elsewhere. diff --git a/sites/default/default.settings.php b/core/default.settings.php similarity index 91% rename from sites/default/default.settings.php rename to core/default.settings.php index 5642dc5..7bf3ec7 100644 --- a/sites/default/default.settings.php +++ b/core/default.settings.php @@ -2,7 +2,7 @@ /** * @file - * Drupal site-specific configuration file. + * Drupal configuration file. * * IMPORTANT NOTE: * This file may have been set to read-only by the Drupal installation program. @@ -10,10 +10,9 @@ * your modifications. Failure to remove write permissions to this file is a * security risk. * - * In order to use the selection rules below the multisite aliasing file named - * sites/sites.php must be present. Its optional settings will be loaded, and - * the aliases in the array $sites will override the default directory rules - * below. See sites/example.sites.php for more information about aliases. + * The configuration file to be loaded is based upon the rules below. However + * if the multisite aliasing is enabled, the aliases in the $sites array will + * override the default directory rules below. * * The configuration directory will be discovered by stripping the website's * hostname from left to right and pathname from right to left. The first @@ -46,10 +45,61 @@ * hostname with that number. For example, * http://www.drupal.org:8080/mysite/test/ could be loaded from * sites/8080.www.drupal.org.mysite.test/. + */ + +/** + * Multi-site functionality and aliases. + * + * Uncomment the $sites variable below to enable Drupal's multi-site + * functionality, which allows to serve multiple different sites from the same + * code-base. + * + * An empty $sites variable just enables the sites directory discovery process. + * You can additionally define aliases that map hostnames, ports, and path names + * to specific site directories. These aliases are applied prior to scanning for + * directories and exempt from the discovery rules. + * + * Aliases are useful on development servers, where the domain name may not be + * the same as the domain of the live server. Since Drupal stores file paths in + * the database (files, system table, etc.) this will ensure the paths are + * correct when the site is deployed to a live server. + * + * Aliases are defined in an associative array named $sites. The array is + * written in the format: '..' => 'directory'. As an + * example, to map http://www.drupal.org:8080/mysite/test to the configuration + * directory sites/example.com, the array should be defined as: + * @code + * $sites = array( + * '8080.www.drupal.org.mysite.test' => 'example.com', + * ); + * @endcode + * The URL, http://www.drupal.org:8080/mysite/test/, could be a symbolic link or + * an Apache Alias directive that points to the Drupal root containing + * index.php. An alias could also be created for a subdomain. See the + * @link http://drupal.org/documentation/install online Drupal installation guide @endlink + * for more information on setting up domains, subdomains, and subdirectories. + * + * The following examples look for a site configuration in sites/example.com: + * @code + * URL: http://dev.drupal.org + * $sites['dev.drupal.org'] = 'example.com'; + * + * URL: http://localhost/example + * $sites['localhost.example'] = 'example.com'; + * + * URL: http://localhost:8080/example + * $sites['8080.localhost.example'] = 'example.com'; + * + * URL: http://www.drupal.org:8080/mysite/test/ + * $sites['8080.www.drupal.org.mysite.test'] = 'example.com'; + * @endcode * - * @see example.sites.php - * @see conf_path() + * @see default.settings.php + * @see \Drupal\Core\Site\Site::getPath() + * @see http://drupal.org/documentation/install/multi-site */ +# $sites = array(); +# $sites['localhost.example'] = 'example.com'; /** * Database settings: diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index fd24e01..e82f6c7 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -10,6 +10,7 @@ use Drupal\Core\DrupalKernel; use Drupal\Core\Database\Database; use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\Core\Site\Site; use Drupal\Core\Utility\Title; use Drupal\Core\Utility\Error; use Symfony\Component\ClassLoader\ApcClassLoader; @@ -218,116 +219,6 @@ define('DRUPAL_ROOT', dirname(dirname(__DIR__))); /** - * Returns the appropriate configuration directory. - * - * Returns the configuration path based on the site's hostname, port, and - * pathname. Uses find_conf_path() to find the current configuration directory. - * See default.settings.php for examples on how the URL is converted to a - * directory. - * - * @param bool $require_settings - * Only configuration 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. - * @param bool $reset - * Force a full search for matching directories even if one had been - * found previously. Defaults to FALSE. - * - * @return - * The path of the matching directory. - * - * @see default.settings.php - */ -function conf_path($require_settings = TRUE, $reset = FALSE) { - static $conf_path; - - if (isset($conf_path) && !$reset) { - return $conf_path; - } - - // Check for a simpletest override. - if ($test_prefix = drupal_valid_test_ua()) { - $conf_path = 'sites/simpletest/' . substr($test_prefix, 10); - return $conf_path; - } - - // Otherwise, use the normal $conf_path. - $script_name = $_SERVER['SCRIPT_NAME']; - if (!$script_name) { - $script_name = $_SERVER['SCRIPT_FILENAME']; - } - $http_host = $_SERVER['HTTP_HOST']; - $conf_path = find_conf_path($http_host, $script_name, $require_settings); - return $conf_path; -} - -/** - * Finds the appropriate configuration directory for a given host and path. - * - * Finds a matching configuration 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 '$confdir/default'. See - * default.settings.php for examples on how the URL is converted to a directory. - * - * If a file named sites.php is present in the $confdir, it will be loaded - * prior to scanning for directories. That file can define aliases in an - * associative array named $sites. The array is written in the format - * '..' => 'directory'. As an example, to create a - * directory alias for http://www.drupal.org:8080/mysite/test whose configuration - * file is in sites/example.com, the array should be defined as: - * @code - * $sites = array( - * '8080.www.drupal.org.mysite.test' => 'example.com', - * ); - * @endcode - * - * @param $http_host - * The hostname and optional port number, e.g. "www.example.com" or - * "www.example.com:8080". - * @param $script_name - * The part of the URL following the hostname, including the leading slash. - * @param $require_settings - * Defaults to TRUE. If TRUE, then only match directories with a - * 'settings.php' file. Otherwise match any directory. - * - * @return - * The path of the matching configuration directory. - * - * @see default.settings.php - * @see example.sites.php - * @see conf_path() - */ -function find_conf_path($http_host, $script_name, $require_settings = TRUE) { - // Determine whether multi-site functionality is enabled. - if (!file_exists(DRUPAL_ROOT . '/sites/sites.php')) { - return 'sites/default'; - } - - $sites = array(); - include DRUPAL_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(DRUPAL_ROOT . '/sites/' . $sites[$dir])) { - $dir = $sites[$dir]; - } - if (file_exists(DRUPAL_ROOT . '/sites/' . $dir . '/settings.php') || (!$require_settings && file_exists(DRUPAL_ROOT . '/sites/' . $dir))) { - return "sites/$dir"; - } - } - } - return 'sites/default'; -} - -/** * Returns the path of a configuration directory. * * @param string $type @@ -378,7 +269,7 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) { * excluding any GET request but including the script name * (e.g., http://www.example.com/mysite/index.php). * - * @see conf_path() + * @see \Drupal\Core\Site\Site::getPath() * @see request_uri() * @see \Symfony\Component\HttpFoundation\Request::getClientIP() */ @@ -411,7 +302,7 @@ function drupal_override_server_variables($variables = array()) { // Replace elements of the $_SERVER array, as appropriate. $request->server->replace($variables + $server_vars + $defaults); - // @todo remove once conf_path() no longer uses $_SERVER. + // @todo remove once Site::determinePath() no longer uses $_SERVER. $_SERVER = $request->server->all(); } @@ -450,7 +341,7 @@ function drupal_environment_initialize() { error_reporting(E_STRICT | E_ALL | error_reporting()); // Override PHP settings required for Drupal to work properly. - // sites/default/default.settings.php contains more runtime settings. + // settings.php contains more runtime settings. // The .htaccess file contains settings that cannot be changed at runtime. // Deny execution with enabled "magic quotes" (both GPC and runtime). @@ -495,9 +386,20 @@ function drupal_settings_initialize() { $settings = array(); $config = array(); - // Make conf_path() available as local variable in settings.php. - $conf_path = conf_path(); - if (is_readable(DRUPAL_ROOT . '/' . $conf_path . '/settings.php')) { + // Read the global /settings.php file. + // Exclude it for test requests to prevent settings of the test runner from + // leaking into the test environment. + if (!drupal_valid_test_ua() && is_readable(DRUPAL_ROOT . '/settings.php')) { + require DRUPAL_ROOT . '/settings.php'; + } + + // Discover the site directory. + Site::init(DRUPAL_ROOT, isset($sites) ? $sites : NULL, isset($conf_path) ? $conf_path : NULL); + + // Make $conf_path available as local variable in settings.php. + // Concatenation is safe here, since $conf_path is known to be not empty. + $conf_path = Site::getPath(); + if ($conf_path !== '' && is_readable(DRUPAL_ROOT . '/' . $conf_path . '/settings.php')) { require DRUPAL_ROOT . '/' . $conf_path . '/settings.php'; } // Initialize Settings. diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 68fc46e..18bed0f 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -12,6 +12,7 @@ use Drupal\Core\Database\Install\TaskException; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; +use Drupal\Core\Site\Site; use Drupal\Core\StringTranslation\Translator\FileTranslation; use Drupal\Core\DependencyInjection\ContainerBuilder; @@ -270,12 +271,6 @@ function install_begin_request(&$install_state) { drupal_override_server_variables($install_state['server']); } - // Initialize conf_path(). - // This primes the site path to be used during installation. By not requiring - // settings.php, a bare site folder can be prepared in the /sites directory, - // which will be used for installing Drupal. - conf_path(FALSE); - // If the hash salt leaks, it becomes possible to forge a valid testing user // agent, install a new copy of Drupal, and take over the original site. // The user agent header is used to pass a database prefix in the request when @@ -286,6 +281,12 @@ function install_begin_request(&$install_state) { exit; } + // Initialize the Site directory. + // This primes the site path to be used during installation, to allow a bare + // site folder to be prepared in the /sites directory, which will be used for + // installing Drupal. + Site::initInstaller(DRUPAL_ROOT); + drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION); // Ensure that procedural dependencies are loaded as early as possible, @@ -1079,8 +1080,7 @@ function install_verify_database_settings() { global $databases; if (!empty($databases)) { $database = $databases['default']['default']; - $settings_file = './' . conf_path(FALSE) . '/settings.php'; - $errors = install_database_errors($database, $settings_file); + $errors = install_database_errors($database); if (empty($errors)) { return TRUE; } @@ -1101,8 +1101,6 @@ function install_verify_database_settings() { function install_settings_form($form, &$form_state, &$install_state) { global $databases; - $conf_path = './' . conf_path(FALSE); - $settings_file = $conf_path . '/settings.php'; drupal_set_title(t('Database configuration')); @@ -1172,7 +1170,6 @@ function install_settings_form($form, &$form_state, &$install_state) { ); $form['errors'] = array(); - $form['settings_file'] = array('#type' => 'value', '#value' => $settings_file); return $form; } @@ -1193,7 +1190,7 @@ function install_settings_form_validate($form, &$form_state) { $database['driver'] = $driver; $form_state['storage']['database'] = $database; - $errors = install_database_errors($database, $form_state['values']['settings_file']); + $errors = install_database_errors($database); foreach ($errors as $name => $message) { form_set_error($name, $form_state, $message); } @@ -1202,7 +1199,7 @@ function install_settings_form_validate($form, &$form_state) { /** * Checks a database connection and returns any errors. */ -function install_database_errors($database, $settings_file) { +function install_database_errors($database) { global $databases; $errors = array(); @@ -1210,7 +1207,11 @@ function install_database_errors($database, $settings_file) { $database_types = drupal_get_database_types(); $driver = $database['driver']; if (!isset($database_types[$driver])) { - $errors['driver'] = t("In your %settings_file file you have configured @drupal to use a %driver server, however your PHP installation currently does not support this database type.", array('%settings_file' => $settings_file, '@drupal' => drupal_install_profile_distribution_name(), '%driver' => $driver)); + $errors['driver'] = t("In your %settings_file file you have configured @drupal to use a %driver server, however your PHP installation currently does not support this database type.", array( + '%settings_file' => Site::getPath('settings.php'), + '@drupal' => drupal_install_profile_distribution_name(), + '%driver' => $driver, + )); } else { // Run driver specific validation @@ -1489,7 +1490,7 @@ function install_translations_directory() { $directory = $GLOBALS['conf']['locale.settings']['translation.path']; } else { - $directory = conf_path() . '/files/translations'; + $directory = Site::getPath('files/translations'); } return $directory; } @@ -2066,8 +2067,8 @@ function install_configure_form($form, &$form_state, &$install_state) { drupal_set_title(t('Configure site')); // Warn about settings.php permissions risk - $settings_dir = conf_path(); - $settings_file = $settings_dir . '/settings.php'; + $settings_dir = Site::getPath(); + $settings_file = Site::getPath('settings.php'); // Check that $_POST is empty so we only show this message when the form is // first displayed, not on the next page after it is submitted. (We do not // want to repeat it multiple times because it is a general warning that is @@ -2076,7 +2077,7 @@ function install_configure_form($form, &$form_state, &$install_state) { // distract from the message that the Drupal installation has completed // successfully.) $post_params = \Drupal::request()->request->all(); - if (empty($post_params) && (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) { + if (empty($post_params) && (!drupal_verify_install_file(Site::getAbsolutePath('settings.php'), FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file(Site::getAbsolutePath(), FILE_NOT_WRITABLE, 'dir'))) { drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the online handbook.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning'); } @@ -2222,8 +2223,8 @@ function install_check_translations($install_state) { $readable = FALSE; $writable = FALSE; // @todo: Make this configurable. - $files_directory = conf_path() . '/files'; - $translations_directory = conf_path() . '/files/translations'; + $files_directory = Site::getPath('files'); + $translations_directory = Site::getPath('files/translations'); $translations_directory_exists = FALSE; $translation_available = FALSE; $online = FALSE; @@ -2376,15 +2377,13 @@ function install_check_requirements($install_state) { if (!$install_state['settings_verified']) { $readable = FALSE; $writable = FALSE; - $conf_path = './' . conf_path(FALSE); - $settings_file = $conf_path . '/settings.php'; - $default_settings_file = './sites/default/default.settings.php'; - $file = $conf_path; + $settings_file = Site::getAbsolutePath('settings.php'); + $default_settings_file = './core/default.settings.php'; + $file = Site::getPath('settings.php'); $exists = FALSE; // Verify that the directory exists. - if (drupal_verify_install_file($conf_path, FILE_EXIST, 'dir')) { + if (drupal_verify_install_file(Site::getAbsolutePath(), FILE_EXIST, 'dir')) { // Check if a settings.php file already exists. - $file = $settings_file; if (drupal_verify_install_file($settings_file, FILE_EXIST)) { // If it does, make sure it is writable. $readable = drupal_verify_install_file($settings_file, FILE_READABLE); @@ -2393,20 +2392,11 @@ function install_check_requirements($install_state) { } } - // If default.settings.php does not exist, or is not readable, throw an - // error. - if (!drupal_verify_install_file($default_settings_file, FILE_EXIST|FILE_READABLE)) { - $requirements['default settings file exists'] = array( - 'title' => t('Default settings file'), - 'value' => t('The default settings file does not exist.'), - 'severity' => REQUIREMENT_ERROR, - 'description' => t('The @drupal installer requires that the %default-file file not be modified in any way from the original download.', array('@drupal' => drupal_install_profile_distribution_name(), '%default-file' => $default_settings_file)), - ); - } // Otherwise, if settings.php does not exist yet, we can try to copy // default.settings.php to create it. - elseif (!$exists) { - $copied = drupal_verify_install_file($conf_path, FILE_EXIST|FILE_WRITABLE, 'dir') && @copy($default_settings_file, $settings_file); + if (!$exists) { + $copied = drupal_verify_install_file(Site::getAbsolutePath(), FILE_EXIST|FILE_WRITABLE, 'dir'); + $copied = $copied && @copy($default_settings_file, $settings_file); if ($copied) { // If the new settings file has the same owner as default.settings.php, // this means default.settings.php is owned by the webserver user. diff --git a/core/includes/install.inc b/core/includes/install.inc index 895f068..85189b2 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; +use Drupal\Core\Site\Site; /** * Requirement severity -- Informational message only. @@ -195,7 +196,7 @@ function drupal_get_database_types() { */ function drupal_rewrite_settings($settings = array(), $settings_file = NULL) { if (!isset($settings_file)) { - $settings_file = conf_path(FALSE) . '/settings.php'; + $settings_file = Site::getPath('settings.php'); } // Build list of setting names and insert the values into the global namespace. $variable_names = array(); @@ -445,11 +446,11 @@ function drupal_install_config_directories() { $config_directories_hash = Crypt::randomStringHashed(55); $settings['config_directories'] = array( CONFIG_ACTIVE_DIRECTORY => (object) array( - 'value' => conf_path() . '/files/config_' . $config_directories_hash . '/active', + 'value' => Site::getPath('files/config_' . $config_directories_hash . '/active'), 'required' => TRUE, ), CONFIG_STAGING_DIRECTORY => (object) array( - 'value' => conf_path() . '/files/config_' . $config_directories_hash . '/staging', + 'value' => Site::getPath('files/config_' . $config_directories_hash . '/staging'), 'required' => TRUE, ), ); diff --git a/core/includes/update.inc b/core/includes/update.inc index c3bc07a..038c6d5 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -14,6 +14,7 @@ use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\ConfigException; use Drupal\Core\DrupalKernel; +use Drupal\Core\Site\Site; use Drupal\Core\Utility\Error; use Drupal\Component\Uuid\Uuid; use Drupal\Component\Utility\NestedArray; @@ -81,7 +82,7 @@ function update_settings_file_requirements() { $requirements = array(); // Check whether settings.php needs to be rewritten. - $settings_file = conf_path() . '/settings.php'; + $settings_file = Site::getPath('settings.php'); $writable = drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_WRITABLE); $requirements['settings file']['title'] = 'Settings file'; if ($writable) { diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php index 97eab54..995f0e6 100644 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php @@ -11,6 +11,7 @@ use Drupal\Core\Database\Driver\sqlite\Connection; use Drupal\Core\Database\DatabaseNotFoundException; use Drupal\Core\Database\Install\Tasks as InstallTasks; +use Drupal\Core\Site\Site; /** * Specifies installation tasks for SQLite databases. @@ -49,7 +50,7 @@ public function getFormOptions(array $database) { // Make the text more accurate for SQLite. $form['database']['#title'] = t('Database file'); $form['database']['#description'] = t('The absolute path to the file where @drupal data will be stored. This must be writable by the web server and should exist outside of the web root.', array('@drupal' => drupal_install_profile_distribution_name())); - $default_database = conf_path(FALSE) . '/files/.ht.sqlite'; + $default_database = Site::getPath('files/.ht.sqlite'); $form['database']['#default_value'] = empty($database['database']) ? $default_database : $database['database']; return $form; } diff --git a/core/lib/Drupal/Core/Site/Site.php b/core/lib/Drupal/Core/Site/Site.php new file mode 100644 index 0000000..572400e --- /dev/null +++ b/core/lib/Drupal/Core/Site/Site.php @@ -0,0 +1,341 @@ +isInstaller()) { + throw new \BadMethodCallException('Site path is initialized already.'); + } + else { + // Disable the $isInstaller flag to prevent init() from being invoked + // more than once. + self::$instance->isInstaller = FALSE; + } + } + else { + new self($root_directory); + } + self::$instance->initializePath($sites, $custom_path); + } + + /** + * Initializes the Site singleton for the early installer environment. + * + * The installer uses this function to prime the site directory path very + * early in the installer environmnt. This allows the application to be + * installed into a new and empty site directory, which does not contain a + * settings.php yet. + * + * @param string $root_directory + * The root directory to use for absolute paths; i.e., DRUPAL_ROOT. + * + * @see install_begin_request() + */ + public static function initInstaller($root_directory) { + if (isset(self::$instance)) { + throw new \BadMethodCallException('Site path is initialized already.'); + } + // Set a global state flag to denote that we are operating in the special + // installer environment. + new self($root_directory, TRUE); + self::$instance->initializePath(); + } + + /** + * Constructs the Site singleton. + */ + private function __construct($root_directory, $is_installer = FALSE) { + if (isset(self::$instance)) { + throw new \BadMethodCallException('Site path is initialized already.'); + } + $this->root = $root_directory; + $this->isInstaller = $is_installer; + self::$instance = $this; + } + + /** + * Re-initializes (resets) the Site singleton for a test run. + * + * @see \Drupal\simpletest\TestBase::prepareEnvironment() + */ + public static function setUpTest() { + if (!isset(self::$instance)) { + throw new \RuntimeException('No original Site to backup. Missing invocation of Site::init()?'); + } + if (!drupal_valid_test_ua()) { + throw new \BadMethodCallException('Site is not executing a test.'); + } + self::$original = clone self::$instance; + self::$instance = NULL; + } + + /** + * Reverts the Site singleton to the original after a test run. + * + * @see \Drupal\simpletest\TestBase::restoreEnvironment() + */ + public static function tearDownTest() { + if (!isset(self::$original)) { + throw new \RuntimeException('No original Site to revert to. Missing invocation of Site::setUpTest()?'); + } + // Do not allow to restore original Site singleton in a test environment, + // unless we are testing the test environment setup and teardown itself. + // @see \Drupal\simpletest\Tests\BrokenSetUpTest + if (drupal_valid_test_ua() && !DRUPAL_TEST_IN_CHILD_SITE) { + throw new \BadMethodCallException('Unable to revert Site: A test is still being executed.'); + } + self::$instance = clone self::$original; + self::$original = NULL; + } + + /** + * Returns whether the Site singleton was instantiated for the installer. + * + * @todo Leverage this to eliminate drupal_installation_attempted()? + */ + private function isInstaller() { + return $this->isInstaller; + } + + /** + * Initializes the site path. + * + * @param array $sites + * (optional) A multi-site mapping, as defined in settings.php. + * @param string $custom_path + * (optional) An explicit site path to set; skipping site negotiation. + */ + private function initializePath(array $sites = NULL, $custom_path = NULL) { + // Force-override the site directory in tests. + if ($test_prefix = drupal_valid_test_ua()) { + $custom_path = 'sites/simpletest/' . substr($test_prefix, 10); + } + + // An explicitly defined $conf_path in /settings.php takes precedence. + if (isset($custom_path)) { + $this->path = $custom_path; + } + // If the multi-site functionality was enabled in /settings.php, discover + // the path for the current site. + // $sites just needs to be defined; an explicit mapping is not required. + elseif (isset($sites)) { + $this->path = $this->determinePath($sites, !$this->isInstaller()); + } + // If the multi-site functionality is not enabled, the Drupal root + // directory is the site directory. + else { + $this->path = ''; + } + } + + /** + * Finds the appropriate configuration directory for a given host and path. + * + * Finds a matching configuration 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. + * + * The settings.php file can define aliases in an associative array named + * $sites. For example, to create a directory alias for + * http://www.drupal.org:8080/mysite/test whose configuration file is in + * sites/example.com, the array should be defined as: + * @code + * $sites = array( + * '8080.www.drupal.org.mysite.test' => 'example.com', + * ); + * @endcode + * + * @see default.settings.php + * + * @param array $sites + * A multi-site mapping, as defined in settings.php. + * @param bool $require_settings + * Only configuration 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. + * + * @return string + * The path of the matching configuration directory. May be an empty string, + * in case the site configuration directory is the root directory. + * + * @todo Inject a Request object in instead of relying on globals? + */ + private function determinePath(array $sites, $require_settings) { + // The hostname and optional port number, e.g. "www.example.com" or + // "www.example.com:8080". + $http_host = $_SERVER['HTTP_HOST']; + // The part of the URL following the hostname, including the leading slash. + $script_name = $_SERVER['SCRIPT_NAME'] ?: $_SERVER['SCRIPT_FILENAME']; + + $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)); + // Check for an alias in $sites. + if (isset($sites[$dir])) { + $dir = $sites[$dir]; + // A defined site alias from /settings.php should be valid. + // @todo Even skip the settings.php check? + if (!$require_settings) { + return "sites/$dir"; + } + } + if ($require_settings) { + if (file_exists($this->root . '/sites/' . $dir . '/settings.php')) { + return "sites/$dir"; + } + } + elseif (file_exists($this->root . '/sites/' . $dir)) { + return "sites/$dir"; + } + } + } + return ''; + } + + /** + * Prefixes a given filepath with the site directory, if any. + * + * Ensures that a given filepath does not result in an absolute filesystem + * path in case of a string concatenation like the following: + * @code + * // If $site_path is empty (Drupal's root directory), then the resulting + * // filesystem path would become absolute; e.g.: "/some/file" + * unlink($site_path . '/' . $some_file); + * @endcode + * + * @param string $filepath + * The filepath to prefix. + * + * @return string + * The prefixed filepath. + */ + private function resolvePath($filepath) { + if ($filepath !== '' && $filepath[0] === '/') { + $filepath = substr($filepath, 1); + } + if ($this->path !== '') { + if ($filepath !== '') { + $filepath = $this->path . '/' . $filepath; + } + else { + $filepath = $this->path; + } + } + return $filepath; + } + + /** + * Returns a given path as relative path to the site directory. + * + * Use this function instead of appending strings to the site path manually, + * because the site directory may be the root directory and thus the resulting + * path would be an absolute filesystem path. + * + * @param string $filepath + * (optional) A relative filepath to append to the site path. + * + * @return string + * The given $filepath, potentially prefixed with the site path. + * + * @see \Drupal\Core\Site\Site::getAbsolutePath() + */ + public static function getPath($filepath = '') { + return self::$instance->resolvePath($filepath); + } + + /** + * Returns a given path as absolute path in the site directory. + * + * @param string $filepath + * (optional) A relative filepath to append to the site path. + * + * @return string + * The given $filepath, potentially prefixed with the site path, as an + * absolute filesystem path. + * + * @see \Drupal\Core\Site\Site::getPath() + */ + public static function getAbsolutePath($filepath = '') { + $filepath = self::$instance->resolvePath($filepath); + if ($filepath !== '') { + return self::$instance->root . '/' . $filepath; + } + else { + return self::$instance->root; + } + } + +} diff --git a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php index 760a1f8..a2239ff 100644 --- a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php +++ b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php @@ -7,6 +7,8 @@ namespace Drupal\Core\StreamWrapper; +use Drupal\Core\Site\Site; + /** * Defines a Drupal public (public://) stream wrapper class. * @@ -37,7 +39,7 @@ public function getExternalUrl() { * The base path for public:// typically sites/default/files. */ public static function basePath() { - $base_path = settings()->get('file_public_path', conf_path() . '/files'); + $base_path = settings()->get('file_public_path', Site::getPath('files')); return $base_path; } diff --git a/core/lib/Drupal/Core/SystemListing.php b/core/lib/Drupal/Core/SystemListing.php index 0a82cd2..e9aee89 100644 --- a/core/lib/Drupal/Core/SystemListing.php +++ b/core/lib/Drupal/Core/SystemListing.php @@ -8,6 +8,7 @@ namespace Drupal\Core; use Drupal\Component\Utility\Settings; +use Drupal\Core\Site\Site; /** * Returns information about system object files (modules, themes, etc.). @@ -87,7 +88,6 @@ function scan($mask, $directory, $key = 'name') { if (!in_array($key, array('uri', 'filename', 'name'))) { $key = 'uri'; } - $config = conf_path(); // Search for the directory in core. $searchdir = array('core/' . $directory); @@ -112,9 +112,13 @@ function scan($mask, $directory, $key = 'name') { if ($parent_site = Settings::getSingleton()->get('test_parent_site')) { $searchdir[] = $parent_site; } - if (file_exists("$config/$directory")) { - $searchdir[] = "$config/$directory"; + + if (Site::getPath() !== '') { + if (file_exists(Site::getPath($directory))) { + $searchdir[] = Site::getPath($directory); + } } + // @todo Find a way to skip ./config directories (but not modules/config). $nomask = '/^(CVS|lib|templates|css|js)$/'; $files = array(); diff --git a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php index d230bc5..8617566 100644 --- a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php +++ b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php @@ -7,6 +7,7 @@ namespace Drupal\file_test; +use Drupal\Core\Site\Site; use Drupal\Core\StreamWrapper\LocalReadOnlyStream; /** @@ -16,7 +17,7 @@ */ class DummyReadOnlyStreamWrapper extends LocalReadOnlyStream { function getDirectoryPath() { - return conf_path() . '/files'; + return Site::getPath('files'); } /** diff --git a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php index cbea40f..dd919c8 100644 --- a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php +++ b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php @@ -7,6 +7,7 @@ namespace Drupal\file_test; +use Drupal\Core\Site\Site; use Drupal\Core\StreamWrapper\LocalStream; /** @@ -16,7 +17,7 @@ */ class DummyStreamWrapper extends LocalStream { function getDirectoryPath() { - return conf_path() . '/files'; + return Site::getPath('files'); } /** diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index c62c842..665873f 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -6,6 +6,7 @@ */ use Drupal\Core\Language\Language; +use Drupal\Core\Site\Site; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSelected; /** @@ -14,7 +15,7 @@ function locale_install() { // Create the interface translations directory and ensure it's writable. if (!$directory = \Drupal::config('locale.settings')->get('translation.path')) { - $directory = conf_path() . '/files/translations'; + $directory = Site::getPath('files/translations'); \Drupal::config('locale.settings')->set('translation.path', $directory)->save(); } file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index cf162fd..56b83c2 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -18,6 +18,7 @@ use Drupal\Core\Config\StorageInterface; use Drupal\Core\DrupalKernel; use Drupal\Core\Language\Language; +use Drupal\Core\Site\Site; use Drupal\Core\StreamWrapper\PublicStream; use Drupal\Core\Utility\Error; use Symfony\Component\HttpFoundation\Request; @@ -982,7 +983,7 @@ private function prepareEnvironment() { } // Backup current in-memory configuration. - $this->originalSite = conf_path(); + $this->originalSite = Site::getPath(); $this->originalSettings = settings()->getAll(); $this->originalConfig = $GLOBALS['config']; @@ -998,7 +999,7 @@ private function prepareEnvironment() { // Save further contextual information. // Use the original files directory to avoid nesting it within an existing // simpletest directory if a test is executed within a test. - $this->originalFileDirectory = settings()->get('file_public_path', conf_path() . '/files'); + $this->originalFileDirectory = settings()->get('file_public_path', Site::getPath('files')); $this->originalProfile = drupal_get_profile(); $this->originalUser = isset($user) ? clone $user : NULL; @@ -1091,8 +1092,11 @@ private function prepareEnvironment() { // After preparing the environment and changing the database prefix, we are // in a valid test environment. + if (!is_dir(DRUPAL_ROOT . '/' . $this->siteDirectory)) { + throw new \RuntimeException("Test site directory '$this->siteDirectory' does not exist."); + } drupal_valid_test_ua($this->databasePrefix); - conf_path(FALSE, TRUE); + Site::setUpTest(); drupal_set_time_limit($this->timeLimit); } @@ -1223,7 +1227,7 @@ private function restoreEnvironment() { else { drupal_valid_test_ua(FALSE); } - conf_path(TRUE, TRUE); + Site::tearDownTest(); // Restore original shutdown callbacks. $callbacks = &drupal_register_shutdown_function(); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php index 643f652..6aa1ad8 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php @@ -9,6 +9,7 @@ use Drupal\Core\Database\Database; use Drupal\Core\Database\ConnectionNotDefinedException; +use Drupal\Core\Site\Site; /** * Base test case class for unit tests. @@ -36,6 +37,9 @@ function __construct($test_id = NULL) { * setUp() method. */ protected function setUp() { + // Initialize the test Site singleton, so that Site::getPath() works. + Site::init(DRUPAL_ROOT); + file_prepare_directory($this->public_files_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); $this->settingsSet('file_public_path', $this->public_files_directory); } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index af66791..17b6fa6 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\NestedArray; +use Drupal\Component\Utility\Settings; use Drupal\Component\Utility\String; use Drupal\Core\DrupalKernel; use Drupal\Core\Database\Database; @@ -774,7 +775,7 @@ protected function setUp() { // Copy and prepare an actual settings.php, so as to resemble a regular // installation. // Not using File API; a potential error must trigger a PHP warning. - copy(DRUPAL_ROOT . '/sites/default/default.settings.php', DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php'); + copy(DRUPAL_ROOT . '/core/default.settings.php', DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php'); // All file system paths are created by System module during installation. // @see system_requirements() @@ -793,7 +794,7 @@ protected function setUp() { ); // Add the parent profile's search path to the child site's search paths. // @see drupal_system_listing() - $settings['conf']['simpletest.settings']['parent_profile'] = (object) array( + $settings['config']['simpletest.settings']['parent_profile'] = (object) array( 'value' => $this->originalProfile, 'required' => TRUE, ); @@ -802,13 +803,16 @@ protected function setUp() { // Since Drupal is bootstrapped already, install_begin_request() will not // bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to // reload the newly written custom settings.php manually. - drupal_settings_initialize(); + require DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php'; + new Settings($settings); + $GLOBALS['config'] = $config; // Execute the non-interactive installer. require_once DRUPAL_ROOT . '/core/includes/install.core.inc'; install_drupal($parameters); // Import new settings.php written by the installer. + // @todo Fix non-interactive installer; this should happen automatically. drupal_settings_initialize(); foreach ($GLOBALS['config_directories'] as $type => $path) { $this->configDirectories[$type] = $path; diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php index 26b1b76..91908fc 100644 --- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php @@ -8,6 +8,7 @@ namespace Drupal\system\Tests\DrupalKernel; use Drupal\Core\DrupalKernel; +use Drupal\Core\Site\Site; use Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage; use Drupal\Component\PhpStorage\FileReadOnlyStorage; use Drupal\simpletest\DrupalUnitTestBase; @@ -26,6 +27,9 @@ public static function getInfo() { } function setUp() { + // Initialize the test Site singleton, so that Site::getPath() works. + Site::init(DRUPAL_ROOT); + // DrupalKernel relies on global $config_directories and requires those // directories to exist. Therefore, create the directories, but do not // invoke DrupalUnitTestBase::setUp(), since that would set up further diff --git a/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php b/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php index 8c5634e..de5a165 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php @@ -7,6 +7,8 @@ namespace Drupal\system\Tests\File; +use Drupal\Core\Site\Site; + /** * Directory related tests. */ @@ -23,7 +25,7 @@ public static function getInfo() { * Test local directory handling functions. */ function testFileCheckLocalDirectoryHandling() { - $directory = conf_path() . '/files'; + $directory = Site::getPath('files'); // Check a new recursively created local directory for correct file system // permissions. diff --git a/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php b/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php index e02cd07..e62cf1a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/File/ReadOnlyStreamWrapperTest.php @@ -7,6 +7,8 @@ namespace Drupal\system\Tests\File; +use Drupal\Core\Site\Site; + /** * Tests that files can not be written using ReadOnlyStreamWrapper functions. */ @@ -40,7 +42,7 @@ public static function getInfo() { function testWriteFunctions() { // Generate a test file $filename = $this->randomName(); - $filepath = conf_path() . '/files/' . $filename; + $filepath = Site::getPath('files/' . $filename); file_put_contents($filepath, $filename); // Generate a read-only stream wrapper instance @@ -83,7 +85,7 @@ function testWriteFunctions() { // Test the mkdir() function by attempting to create a directory. $dirname = $this->randomName(); - $dir = conf_path() . '/files/' . $dirname; + $dir = Site::getPath('files/' . $dirname); $readonlydir = $this->scheme . '://' . $dirname; $this->assertFalse(@drupal_mkdir($readonlydir, 0775, 0), 'Unable to create directory with read-only stream wrapper.'); // Create a temporary directory for testing purposes diff --git a/core/modules/system/lib/Drupal/system/Tests/System/SettingsRewriteTest.php b/core/modules/system/lib/Drupal/system/Tests/System/SettingsRewriteTest.php index 74c080d..6096a41 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/SettingsRewriteTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/SettingsRewriteTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\System; +use Drupal\Core\Site\Site; use Drupal\simpletest\UnitTestBase; /** @@ -104,7 +105,7 @@ function testDrupalRewriteSettings() { ), ); foreach ($tests as $test) { - $filename = settings()->get('file_public_path', conf_path() . '/files') . '/mock_settings.php'; + $filename = settings()->get('file_public_path', Site::getPath('files')) . '/mock_settings.php'; file_put_contents(DRUPAL_ROOT . '/' . $filename, "assertEqual(file_get_contents(DRUPAL_ROOT . '/' . $filename), " $conf_path)); + if (!drupal_verify_install_file(Site::getAbsolutePath(), FILE_NOT_WRITABLE, 'dir')) { + $conf_errors[] = t("The directory %file is not protected from modifications and poses a security risk. You must change the directory's permissions to be non-writable.", array( + '%file' => Site::getPath(), + )); } foreach (array('settings.php', 'settings.local.php') as $conf_file) { - $full_path = $conf_path . '/' . $conf_file; - if (file_exists($full_path) && !drupal_verify_install_file($full_path, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE)) { - $conf_errors[] = t("The file %file is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.", array('%file' => $full_path)); + if (file_exists($full_path) && !drupal_verify_install_file(Site::getAbsolutePath($conf_file), FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE)) { + $conf_errors[] = t("The file %file is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.", array( + '%file' => Site::getPath($conf_file), + )); } } if (!empty($conf_errors)) { @@ -327,7 +330,7 @@ function system_requirements($phase) { else { // If we are installing Drupal, the settings.php file might not exist yet // in the intended site directory, so don't require it. - $directories[] = conf_path(FALSE) . '/files'; + $directories[] = Site::getPath('files'); } if (!empty($GLOBALS['config']['system.file']['path']['private'])) { $directories[] = $GLOBALS['config']['system.file']['path']['private']; @@ -353,7 +356,7 @@ function system_requirements($phase) { $requirements['config directories'] = array( 'title' => t('Configuration directories'), 'value' => t('Not present'), - 'description' => t('Your %file file must define the $config_directories variable as an array containing the name of a directories in which configuration files can be written.', array('%file' => conf_path() . '/settings.php')), + 'description' => t('Your %file file must define the $config_directories variable as an array containing the name of a directories in which configuration files can be written.', array('%file' => Site::getPath('settings.php'))), 'severity' => REQUIREMENT_ERROR, ); } diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc index 19c0dc1..7fa9194 100644 --- a/core/modules/update/update.manager.inc +++ b/core/modules/update/update.manager.inc @@ -38,6 +38,7 @@ use Drupal\Core\Updater\Updater; use Drupal\Core\FileTransfer\Local; +use Drupal\Core\Site\Site; use Symfony\Component\HttpFoundation\RedirectResponse; /** @@ -470,7 +471,7 @@ function update_manager_update_ready_form_submit($form, &$form_state) { // trying to install the code, there's no need to prompt for FTP/SSH // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local and // invoke update_authorize_run_update() directly. - if (fileowner($project_real_location) == fileowner(conf_path())) { + if (fileowner($project_real_location) == fileowner(Site::getAbsolutePath())) { module_load_include('inc', 'update', 'update.authorize'); $filetransfer = new Local(DRUPAL_ROOT); update_authorize_run_update($filetransfer, $updates); @@ -748,7 +749,7 @@ function update_manager_install_form_submit($form, &$form_state) { // trying to install the code, there's no need to prompt for FTP/SSH // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local and // invoke update_authorize_run_install() directly. - if (fileowner($project_real_location) == fileowner(conf_path())) { + if (fileowner($project_real_location) == fileowner(Site::getAbsolutePath())) { module_load_include('inc', 'update', 'update.authorize'); $filetransfer = new Local(DRUPAL_ROOT); call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments)); @@ -947,7 +948,7 @@ function update_manager_local_transfers_allowed() { // the configuration directory to determine if local transfers will be // allowed. $temporary_file = drupal_tempnam('temporary://', 'update_'); - $local_transfers_allowed = fileowner($temporary_file) === fileowner(conf_path()); + $local_transfers_allowed = fileowner($temporary_file) === fileowner(Site::getAbsolutePath()); // Clean up. If this fails, we can ignore it (since this is just a temporary // file anyway). diff --git a/sites/example.sites.php b/sites/example.sites.php deleted file mode 100644 index 2a813dd..0000000 --- a/sites/example.sites.php +++ /dev/null @@ -1,55 +0,0 @@ -..' => 'directory'. As an - * example, to map http://www.drupal.org:8080/mysite/test to the configuration - * directory sites/example.com, the array should be defined as: - * @code - * $sites = array( - * '8080.www.drupal.org.mysite.test' => 'example.com', - * ); - * @endcode - * The URL, http://www.drupal.org:8080/mysite/test/, could be a symbolic link or - * an Apache Alias directive that points to the Drupal root containing - * index.php. An alias could also be created for a subdomain. See the - * @link http://drupal.org/documentation/install online Drupal installation guide @endlink - * for more information on setting up domains, subdomains, and subdirectories. - * - * The following examples look for a site configuration in sites/example.com: - * @code - * URL: http://dev.drupal.org - * $sites['dev.drupal.org'] = 'example.com'; - * - * URL: http://localhost/example - * $sites['localhost.example'] = 'example.com'; - * - * URL: http://localhost:8080/example - * $sites['8080.localhost.example'] = 'example.com'; - * - * URL: http://www.drupal.org:8080/mysite/test/ - * $sites['8080.www.drupal.org.mysite.test'] = 'example.com'; - * @endcode - * - * @see default.settings.php - * @see conf_path() - * @see http://drupal.org/documentation/install/multi-site - */