Issue #2980712 by bircher, alexpott, yogeshmpawar, mpotter, borisson_: Define config directory in settings

merge-requests/1119/head
catch 2019-06-24 14:04:44 +01:00
parent d90d0ebbda
commit 1a2babd20d
40 changed files with 461 additions and 197 deletions

View File

@ -62,7 +62,10 @@ global $config;
/**
* The location of file system directories used for site configuration data.
*
* @see drupal_install_config_directories()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Site\Settings::get('config_sync_directory') instead.
*
* @see https://www.drupal.org/node/3018145
*/
global $config_directories;

View File

@ -13,6 +13,7 @@ use Drupal\Core\Config\BootstrapConfigStorageFactory;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Test\TestDatabase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Utility\Error;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
@ -158,7 +159,10 @@ const CONFIG_ACTIVE_DIRECTORY = 'active';
/**
* $config_directories key for sync directory.
*
* @see config_get_config_directory()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Site\Settings::get('config_sync_directory') instead.
*
* @see https://www.drupal.org/node/3018145
*/
const CONFIG_SYNC_DIRECTORY = 'sync';
@ -196,10 +200,19 @@ define('DRUPAL_ROOT', dirname(dirname(__DIR__)));
* The configuration directory path.
*
* @throws \Exception
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Site\Settings::get('config_sync_directory') instead.
*
* @see https://www.drupal.org/node/3018145
*/
function config_get_config_directory($type) {
global $config_directories;
@trigger_error('config_get_config_directory() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Site\Settings::get(\'config_sync_directory\') instead. See https://www.drupal.org/node/3018145', E_USER_DEPRECATED);
$config_sync_directory = Settings::get('config_sync_directory', FALSE);
if ($config_sync_directory) {
$config_directories[CONFIG_SYNC_DIRECTORY] = $config_sync_directory;
}
// @todo Remove fallback in Drupal 9. https://www.drupal.org/node/2574943
if ($type == CONFIG_SYNC_DIRECTORY && !isset($config_directories[CONFIG_SYNC_DIRECTORY]) && isset($config_directories[CONFIG_STAGING_DIRECTORY])) {
$type = CONFIG_STAGING_DIRECTORY;

View File

@ -336,15 +336,7 @@ function file_ensure_htaccess() {
}
file_save_htaccess('temporary://', TRUE);
// If a staging directory exists then it should contain a .htaccess file.
// @todo https://www.drupal.org/node/2696103 catch a more specific exception
// and simplify this code.
try {
$staging = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
}
catch (\Exception $e) {
$staging = FALSE;
}
$staging = Settings::get('config_sync_directory', FALSE);
if ($staging) {
// Note that we log an error here if we can't write the .htaccess file. This
// can occur if the staging directory is read-only. If it is then it is the

View File

@ -380,7 +380,7 @@ function install_begin_request($class_loader, &$install_state) {
// Determine whether base system services are ready to operate.
try {
$sync_directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$sync_directory = Settings::get('config_sync_directory', FALSE);
$install_state['config_verified'] = file_exists($sync_directory);
}
catch (Exception $e) {
@ -1532,13 +1532,13 @@ function _install_get_version_info($version) {
* profile information will be added here.
*/
function install_load_profile(&$install_state) {
global $config_directories;
$profile = $install_state['parameters']['profile'];
$install_state['profiles'][$profile]->load();
$install_state['profile_info'] = install_profile_info($profile, isset($install_state['parameters']['langcode']) ? $install_state['parameters']['langcode'] : 'en');
if (!empty($install_state['parameters']['existing_config']) && !empty($config_directories[CONFIG_SYNC_DIRECTORY])) {
$install_state['config_install_path'] = $config_directories[CONFIG_SYNC_DIRECTORY];
$sync_directory = Settings::get('config_sync_directory');
if (!empty($install_state['parameters']['existing_config']) && !empty($sync_directory)) {
$install_state['config_install_path'] = $sync_directory;
}
// If the profile has a config/sync directory copy the information to the
// install_state global.

View File

@ -204,16 +204,14 @@ function drupal_get_database_types() {
* are dumped up to a stdClass object. The object can have value, required
* and comment properties.
* @code
* $settings['config_directories'] = array(
* CONFIG_SYNC_DIRECTORY => (object) array(
* $settings['settings']['config_sync_directory'] = (object) array(
* 'value' => 'config_hash/sync',
* 'required' => TRUE,
* ),
* );
* @endcode
* gets dumped as:
* @code
* $config_directories['sync'] = 'config_hash/sync'
* $settings['config_sync_directory'] = 'config_hash/sync'
* @endcode
*/
function drupal_rewrite_settings($settings = [], $settings_file = NULL) {
@ -479,10 +477,13 @@ function _drupal_rewrite_settings_dump_one(\stdClass $variable, $prefix = '', $s
/**
* Creates the config directory and ensures it is operational.
*
* @see install_settings_form_submit()
* @see update_prepare_d8_bootstrap()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. There is no
* replacement.
*
* @see https://www.drupal.org/node/3018145
*/
function drupal_install_config_directories() {
@trigger_error('drupal_install_config_directories() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. There is no replacement. See https://www.drupal.org/node/3018145.', E_USER_DEPRECATED);
global $config_directories, $install_state;
// If settings.php does not contain a config sync directory name we need to

View File

@ -2,6 +2,8 @@
namespace Drupal\Core\Config;
use Drupal\Core\Site\Settings;
/**
* Provides a factory for creating config file storage objects.
*/
@ -23,9 +25,19 @@ class FileStorageFactory {
* Returns a FileStorage object working with the sync config directory.
*
* @return \Drupal\Core\Config\FileStorage FileStorage
*
* @throws \Exception
* In case the sync directory does not exist or is not defined in
* $settings['config_sync_directory'].
*/
public static function getSync() {
return new FileStorage(config_get_config_directory(CONFIG_SYNC_DIRECTORY));
$directory = Settings::get('config_sync_directory', FALSE);
if ($directory === FALSE) {
// @todo: throw a more specific exception.
// @see https://www.drupal.org/node/2696103
throw new \Exception('The config sync directory is not defined in $settings["config_sync_directory"]');
}
return new FileStorage($directory);
}
}

View File

@ -5,6 +5,7 @@ namespace Drupal\Core\Installer\Form;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings;
/**
* Provides the profile selection form.
@ -31,7 +32,6 @@ class SelectProfileForm extends FormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $install_state = NULL) {
global $config_directories;
$form['#title'] = $this->t('Select an installation profile');
$profiles = [];
@ -88,8 +88,9 @@ class SelectProfileForm extends FormBase {
}
}
if (!empty($config_directories[CONFIG_SYNC_DIRECTORY])) {
$sync = new FileStorage($config_directories[CONFIG_SYNC_DIRECTORY]);
$config_sync_directory = Settings::get('config_sync_directory');
if (!empty($config_sync_directory)) {
$sync = new FileStorage($config_sync_directory);
$extensions = $sync->read('core.extension');
$site = $sync->read('system.site');
if (isset($site['name']) && isset($extensions['profile']) && in_array($extensions['profile'], array_keys($names), TRUE)) {
@ -106,7 +107,7 @@ class SelectProfileForm extends FormBase {
],
'info' => [
'#type' => 'item',
'#markup' => $this->t('The configuration from the directory %sync_directory will be used.', ['%sync_directory' => $config_directories[CONFIG_SYNC_DIRECTORY]]),
'#markup' => $this->t('The configuration from the directory %sync_directory will be used.', ['%sync_directory' => $config_sync_directory]),
'#wrapper_attributes' => [
'class' => ['messages', 'messages--status'],
],
@ -134,10 +135,10 @@ class SelectProfileForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
global $install_state, $config_directories;
global $install_state;
$profile = $form_state->getValue('profile');
if ($profile === static::CONFIG_INSTALL_PROFILE_KEY) {
$sync = new FileStorage($config_directories[CONFIG_SYNC_DIRECTORY]);
$sync = new FileStorage(Settings::get('config_sync_directory'));
$profile = $sync->read('core.extension')['profile'];
$install_state['parameters']['existing_config'] = TRUE;
}

View File

@ -4,9 +4,11 @@ namespace Drupal\Core\Installer\Form;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Database\Database;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Site\Settings;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@ -225,12 +227,26 @@ class SiteSettingsForm extends FormBase {
'value' => Crypt::randomBytesBase64(55),
'required' => TRUE,
];
// If settings.php does not contain a config sync directory name we need to
// configure one.
if (empty(Settings::get('config_sync_directory'))) {
if (empty($install_state['config_install_path'])) {
// Add a randomized config directory name to settings.php
$config_sync_directory = $this->createRandomConfigDirectory();
}
else {
// Install profiles can contain a config sync directory. If they do,
// 'config_install_path' is a path to the directory.
$config_sync_directory = $install_state['config_install_path'];
}
$settings['settings']['config_sync_directory'] = (object) [
'value' => $config_sync_directory,
'required' => TRUE,
];
}
drupal_rewrite_settings($settings);
// Add the config directories to settings.php.
drupal_install_config_directories();
// Indicate that the settings file has been verified, and check the database
// for the last completed task, now that we have a valid connection. This
// last step is important since we want to trigger an error if the new
@ -241,4 +257,26 @@ class SiteSettingsForm extends FormBase {
$install_state['completed_task'] = install_verify_completed_task();
}
/**
* Create a random config sync directory.
*
* @return string
* The path to the generated config sync directory.
*/
protected function createRandomConfigDirectory() {
$config_sync_directory = \Drupal::service('site.path') . '/files/config_' . Crypt::randomBytesBase64(55) . '/sync';
// This should never fail, it is created here inside the public files
// directory, which has already been verified to be writable itself.
if (\Drupal::service('file_system')->prepareDirectory($config_sync_directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
// Put a README.txt into the sync config directory. This is required so
// that they can later be added to git. Since this directory is
// auto-created, we have to write out the README rather than just adding
// it to the drupal core repo.
$text = 'This directory contains configuration to be imported into your Drupal site. To make this configuration active, visit admin/config/development/configuration/sync.' . ' For information about deploying configuration between servers, see https://www.drupal.org/documentation/administer/config';
file_put_contents($config_sync_directory . '/README.txt', $text);
}
return $config_sync_directory;
}
}

View File

@ -128,6 +128,16 @@ final class Settings {
// Initialize Database.
Database::setMultipleConnectionInfo($databases);
// For BC ensure the $config_directories global is set both in the global
// and settings.
if (!isset($settings['config_sync_directory']) && !empty($config_directories['sync'])) {
@trigger_error('$config_directories[\'sync\'] has moved to $settings[\'config_sync_directory\']. See https://www.drupal.org/node/3018145.', E_USER_DEPRECATED);
$settings['config_sync_directory'] = $config_directories['sync'];
}
elseif (isset($settings['config_sync_directory'])) {
$config_directories['sync'] = $settings['config_sync_directory'];
}
// Initialize Settings.
new Settings($settings);
}

View File

@ -43,6 +43,11 @@ trait FunctionalTestSetupTrait {
/**
* The config directories used in this test.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Site\Settings::get('config_sync_directory') instead.
*
* @see https://www.drupal.org/node/3018145
*/
protected $configDirectories = [];
@ -293,9 +298,7 @@ trait FunctionalTestSetupTrait {
*/
protected function initSettings() {
Settings::initialize(DRUPAL_ROOT, $this->siteDirectory, $this->classLoader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
}
$this->configDirectories['sync'] = Settings::get('config_sync_directory');
// After writing settings.php, the installer removes write permissions
// from the site directory. To allow drupal_generate_test_ua() to write

View File

@ -7,6 +7,7 @@ use Drupal\Core\Config\StorageInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@ -30,6 +31,13 @@ class ConfigImportForm extends FormBase {
*/
protected $fileSystem;
/**
* The settings object.
*
* @var \Drupal\Core\Site\Settings
*/
protected $settings;
/**
* Constructs a new ConfigImportForm.
*
@ -37,14 +45,21 @@ class ConfigImportForm extends FormBase {
* The configuration storage.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
* @param \Drupal\Core\Site\Settings $settings
* The settings object.
*/
public function __construct(StorageInterface $config_storage, FileSystemInterface $file_system = NULL) {
public function __construct(StorageInterface $config_storage, FileSystemInterface $file_system = NULL, Settings $settings = NULL) {
$this->configStorage = $config_storage;
if (!isset($file_system)) {
@trigger_error('The $file_system parameter was added in Drupal 8.8.0 and will be required in 9.0.0. See https://www.drupal.org/node/3021434.', E_USER_DEPRECATED);
$file_system = \Drupal::service('file_system');
}
$this->fileSystem = $file_system;
if (!isset($settings)) {
@trigger_error('The $settings parameter was added in Drupal 8.8.0 and will be required in 9.0.0. See https://www.drupal.org/node/2980712.', E_USER_DEPRECATED);
$settings = \Drupal::service('settings');
}
$this->settings = $settings;
}
/**
@ -53,7 +68,8 @@ class ConfigImportForm extends FormBase {
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.storage.sync'),
$container->get('file_system')
$container->get('file_system'),
$container->get('settings')
);
}
@ -68,7 +84,7 @@ class ConfigImportForm extends FormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$directory = $this->settings->get('config_sync_directory');
$directory_is_writable = is_writable($directory);
if (!$directory_is_writable) {
$this->messenger()->addError($this->t('The directory %directory is not writable.', ['%directory' => $directory]));
@ -115,7 +131,7 @@ class ConfigImportForm extends FormBase {
foreach ($archiver->listContent() as $file) {
$files[] = $file['filename'];
}
$archiver->extractList($files, config_get_config_directory(CONFIG_SYNC_DIRECTORY));
$archiver->extractList($files, $this->settings->get('config_sync_directory'));
$this->messenger()->addStatus($this->t('Your configuration files were successfully uploaded and are ready for import.'));
$form_state->setRedirect('config.sync');
}

View File

@ -2,6 +2,7 @@
namespace Drupal\Tests\config\Functional;
use Drupal\Core\Site\Settings;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\TestFileCreationTrait;
@ -50,7 +51,7 @@ class ConfigImportUploadTest extends BrowserTestBase {
$this->assertText(t('Could not extract the contents of the tar file'));
// Make the sync directory read-only.
$directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$directory = Settings::get('config_sync_directory');
\Drupal::service('file_system')->chmod($directory, 0555);
$this->drupalGet('admin/config/development/configuration/full/import');
$this->assertRaw(t('The directory %directory is not writable.', ['%directory' => $directory]));

View File

@ -5,6 +5,7 @@ namespace Drupal\Tests\config\Functional;
use Drupal\Core\Config\PreExistingConfigException;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\Site\Settings;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
@ -201,7 +202,7 @@ class ConfigInstallWebTest extends BrowserTestBase {
$this->drupalLogin($this->adminUser);
$this->drupalPostForm('admin/modules', ['modules[config][enable]' => TRUE], t('Install'));
$directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$directory = Settings::get('config_sync_directory');
try {
\Drupal::service('file_system')->deleteRecursive($directory);
}

View File

@ -2,8 +2,8 @@
namespace Drupal\Tests\field\Kernel;
use Drupal\Core\Site\Settings;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
@ -93,7 +93,7 @@ class FieldImportCreateTest extends FieldKernelTestBase {
// Add the new files to the sync directory.
$src_dir = __DIR__ . '/../../modules/field_test_config/sync';
$target_dir = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$target_dir = Settings::get('config_sync_directory');
/** @var \Drupal\Core\File\FileSystemInterface $file_system */
$file_system = \Drupal::service('file_system');
$this->assertTrue($file_system->copy("$src_dir/$field_storage_config_name.yml", "$target_dir/$field_storage_config_name.yml"));

View File

@ -2,6 +2,7 @@
namespace Drupal\Tests\node\Kernel\Config;
use Drupal\Core\Site\Settings;
use Drupal\field\Entity\FieldConfig;
use Drupal\node\Entity\NodeType;
use Drupal\KernelTests\KernelTestBase;
@ -60,7 +61,7 @@ class NodeImportCreateTest extends KernelTestBase {
$this->copyConfig($active, $sync);
// Manually add new node type.
$src_dir = __DIR__ . '/../../../modules/node_test_config/sync';
$target_dir = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$target_dir = Settings::get('config_sync_directory');
$this->assertTrue(\Drupal::service('file_system')->copy("$src_dir/$node_type_config_name.yml", "$target_dir/$node_type_config_name.yml"));
// Import the content of the sync directory.

View File

@ -148,9 +148,7 @@ abstract class InstallerTestBase extends WebTestBase {
$request = Request::createFromGlobals();
$class_loader = require $this->container->get('app.root') . '/autoload.php';
Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
}
$this->configDirectories['sync'] = Settings::get('config_sync_directory');
// After writing settings.php, the installer removes write permissions
// from the site directory. To allow drupal_generate_test_ua() to write

View File

@ -138,23 +138,26 @@ abstract class KernelTestBase extends TestBase {
/**
* Create and set new configuration directories.
*
* @see config_get_config_directory()
* @see \Drupal\Core\Site\Settings::getConfigDirectory()
*
* @throws \RuntimeException
* Thrown when CONFIG_SYNC_DIRECTORY cannot be created or made writable.
* Thrown when the configuration sync directory cannot be created or made
* writable.
*
* @return string
* The config sync directory path.
*/
protected function prepareConfigDirectories() {
$this->configDirectories = [];
include_once DRUPAL_ROOT . '/core/includes/install.inc';
// Assign the relative path to the global variable.
$path = $this->siteDirectory . '/config_' . CONFIG_SYNC_DIRECTORY;
$GLOBALS['config_directories'][CONFIG_SYNC_DIRECTORY] = $path;
// Ensure the directory can be created and is writeable.
if (!\Drupal::service('file_system')->prepareDirectory($path, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
throw new \RuntimeException("Failed to create '" . CONFIG_SYNC_DIRECTORY . "' config directory $path");
}
// Provide the already resolved path for tests.
$this->configDirectories[CONFIG_SYNC_DIRECTORY] = $path;
return $path;
}
/**
@ -236,14 +239,14 @@ EOD;
// @see \Drupal\Core\Extension\ExtensionDiscovery::scan()
$settings['test_parent_site'] = $this->originalSite;
// Create and set new configuration directories.
$settings['config_sync_directory'] = $this->prepareConfigDirectories();
// Restore and merge settings.
// DrupalKernel::boot() initializes new Settings, and the containerBuild()
// method sets additional settings.
new Settings($settings + Settings::getAll());
// Create and set new configuration directories.
$this->prepareConfigDirectories();
// Set the request scope.
$this->container = $this->kernel->getContainer();
$this->container->get('request_stack')->push($request);

View File

@ -1103,7 +1103,6 @@ abstract class TestBase {
// Backup statics and globals.
$this->originalContainer = \Drupal::getContainer();
$this->originalLanguage = $language_interface;
$this->originalConfigDirectories = $GLOBALS['config_directories'];
// Save further contextual information.
// Use the original files directory to avoid nesting it within an existing
@ -1275,9 +1274,6 @@ abstract class TestBase {
$GLOBALS['conf'] = $this->originalConf;
new Settings($this->originalSettings);
// Restore original statics and globals.
$GLOBALS['config_directories'] = $this->originalConfigDirectories;
// Re-initialize original stream wrappers of the parent site.
// This must happen after static variables have been reset and the original
// container and $config_directories are restored, as simpletest_log_read()

View File

@ -187,9 +187,6 @@ abstract class UpdatePathTestBase extends WebTestBase {
$container = $this->initKernel($request);
$this->initConfig($container);
// Add the config directories to settings.php.
drupal_install_config_directories();
// Restore the original Simpletest batch.
$this->restoreBatch();

View File

@ -630,8 +630,41 @@ function system_requirements($phase) {
// Check the config directory if it is defined in settings.php. If it isn't
// defined, the installer will create a valid config directory later, but
// during runtime we must always display an error.
if (!empty($GLOBALS['config_directories'])) {
foreach (array_keys(array_filter($GLOBALS['config_directories'])) as $type) {
$config_sync_directory = Settings::get('config_sync_directory');
if (!empty($config_sync_directory)) {
// If we're installing Drupal try and create the config sync directory.
if (!is_dir($config_sync_directory) && $phase == 'install') {
\Drupal::service('file_system')->prepareDirectory($config_sync_directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
}
if (!is_dir($config_sync_directory)) {
if ($phase == 'install') {
$description = t('An automated attempt to create the directory %directory failed, possibly due to a permissions problem. To proceed with the installation, either create the directory and modify its permissions manually or ensure that the installer has the permissions to create it automatically. For more information, see INSTALL.txt or the <a href=":handbook_url">online handbook</a>.', ['%directory' => $config_sync_directory, ':handbook_url' => 'https://www.drupal.org/server-permissions']);
}
else {
$description = t('The directory %directory does not exist.', ['%directory' => $config_sync_directory]);
}
$requirements['config sync directory'] = [
'title' => t('Configuration sync directory'),
'description' => $description,
'severity' => REQUIREMENT_ERROR,
];
}
}
if ($phase != 'install' && empty($config_sync_directory)) {
$requirements['config sync directory'] = [
'title' => t('Configuration sync directory'),
'value' => t('Not present'),
'description' => t("Your %file file must define the %setting setting as a string containing the directory in which configuration files can be found.", ['%file' => $site_path . '/settings.php', '%setting' => "\$settings['config_sync_directory']"]),
'severity' => REQUIREMENT_ERROR,
];
}
// Handle other configuration directories. This will be removed in Drupal 9.
// See https://www.drupal.org/node/3018145.
$bc_config_directories = isset($GLOBALS['config_directories']) ? $GLOBALS['config_directories'] : [];
unset($bc_config_directories['sync']);
foreach (array_keys(array_filter($bc_config_directories)) as $type) {
@trigger_error("Automatic creation of '$type' configuration directory will be removed from drupal:9.0.0. See https://www.drupal.org/node/3018145.", E_USER_DEPRECATED);
$directory = config_get_config_directory($type);
// If we're installing Drupal try and create the config sync directory.
if (!is_dir($directory) && $phase == 'install') {
@ -651,15 +684,6 @@ function system_requirements($phase) {
];
}
}
}
if ($phase != 'install' && (empty($GLOBALS['config_directories']) || empty($GLOBALS['config_directories'][CONFIG_SYNC_DIRECTORY]))) {
$requirements['config directories'] = [
'title' => t('Configuration directories'),
'value' => t('Not present'),
'description' => t('Your %file file must define the $config_directories variable as an array containing the names of directories in which configuration files can be found. It must contain a %sync_key key.', ['%file' => $site_path . '/settings.php', '%sync_key' => CONFIG_SYNC_DIRECTORY]),
'severity' => REQUIREMENT_ERROR,
];
}
$requirements['file system'] = [
'title' => t('File system'),

View File

@ -24,13 +24,10 @@ class StatusTest extends BrowserTestBase {
protected function setUp() {
parent::setUp();
// Unset the sync directory in settings.php to trigger $config_directories
// error.
$settings['config_directories'] = [
CONFIG_SYNC_DIRECTORY => (object) [
// Unset the sync directory in settings.php to trigger the error.
$settings['settings']['config_sync_directory'] = (object) [
'value' => '',
'required' => TRUE,
],
];
$this->writeSettings($settings);
@ -62,7 +59,7 @@ class StatusTest extends BrowserTestBase {
$this->assertNoText(t('Out of date'));
// The global $config_directories is not properly formed.
$this->assertRaw(t('Your %file file must define the $config_directories variable as an array containing the names of directories in which configuration files can be found. It must contain a %sync_key key.', ['%file' => $this->siteDirectory . '/settings.php', '%sync_key' => CONFIG_SYNC_DIRECTORY]));
$this->assertRaw(t("Your %file file must define the %setting setting", ['%file' => $this->siteDirectory . '/settings.php', '%setting' => "\$settings['config_sync_directory']"]));
// Set the schema version of update_test_postupdate to a lower version, so
// update_test_postupdate_update_8001() needs to be executed.

View File

@ -64,13 +64,11 @@ class DistributionProfileExistingSettingsTest extends InstallerTestBase {
// not be available at this point in the install process.
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
// Pre-configure config directories.
$this->settings['config_directories'] = [
CONFIG_SYNC_DIRECTORY => (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $site_path . '/files/config_staging',
'required' => TRUE,
],
];
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
mkdir($this->settings['settings']['config_sync_directory']->value, 0777, TRUE);
}
/**

View File

@ -24,7 +24,7 @@ class InstallerConfigDirectorySetNoDirectoryErrorTest extends InstallerTestBase
protected function prepareEnvironment() {
parent::prepareEnvironment();
$this->configDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64();
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $this->configDirectory . '/sync',
'required' => TRUE,
];

View File

@ -5,7 +5,7 @@ namespace Drupal\FunctionalTests\Installer;
use Drupal\Component\Utility\Crypt;
/**
* Tests the installer when a config_directory set up but does not exist.
* Tests the installer when a custom config directory set up but does not exist.
*
* @group Installer
*/
@ -24,15 +24,10 @@ class InstallerConfigDirectorySetNoDirectoryTest extends InstallerTestBase {
protected function prepareEnvironment() {
parent::prepareEnvironment();
$this->syncDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64() . '/sync';
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $this->syncDirectory,
'required' => TRUE,
];
// Other directories will be created too.
$this->settings['config_directories']['custom'] = (object) [
'value' => $this->publicFilesDirectory . '/config_custom',
'required' => TRUE,
];
}
/**
@ -42,7 +37,6 @@ class InstallerConfigDirectorySetNoDirectoryTest extends InstallerTestBase {
$this->assertUrl('user/1');
$this->assertResponse(200);
$this->assertTrue(file_exists($this->syncDirectory) && is_dir($this->syncDirectory), "The directory {$this->syncDirectory} exists.");
$this->assertTrue(file_exists($this->publicFilesDirectory . '/config_custom') && is_dir($this->publicFilesDirectory . '/config_custom'), "The directory {$this->publicFilesDirectory}/custom_config exists.");
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Drupal\FunctionalTests\Installer;
use Drupal\Core\Site\Settings;
/**
* Tests the installer when a custom config_directory set up but does not exist.
*
* @group Installer
* @group legacy
*/
class InstallerCustomConfigDirectoryCreateTest extends InstallerTestBase {
/**
* {@inheritdoc}
*/
protected function prepareEnvironment() {
parent::prepareEnvironment();
// Other directories will be created too.
// This is legacy functionality.
$this->settings['config_directories']['custom'] = (object) [
'value' => $this->publicFilesDirectory . '/config_custom',
'required' => TRUE,
];
}
/**
* Verifies that installation succeeded.
*
* @expectedDeprecation Automatic creation of 'custom' configuration directory will be removed from drupal:9.0.0. See https://www.drupal.org/node/3018145.
*/
public function testInstaller() {
$this->assertUrl('user/1');
$this->assertResponse(200);
$this->assertTrue(file_exists($this->publicFilesDirectory . '/config_custom') && is_dir($this->publicFilesDirectory . '/config_custom'), "The directory {$this->publicFilesDirectory}/custom_config exists.");
// Ensure the sync directory also exists.
$sync_directory = Settings::get('config_sync_directory');
$this->assertTrue(file_exists($sync_directory) && is_dir($sync_directory), "The directory {$sync_directory} exists.");
}
}

View File

@ -23,7 +23,7 @@ class InstallerExistingConfigDirectoryTest extends InstallerTestBase {
parent::prepareEnvironment();
mkdir($this->root . DIRECTORY_SEPARATOR . $this->siteDirectory . '/config_read_only', 0444);
$this->expectedFilePerms = fileperms($this->siteDirectory . '/config_read_only');
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $this->siteDirectory . '/config_read_only',
'required' => TRUE,
];

View File

@ -44,7 +44,7 @@ abstract class InstallerExistingConfigTestBase extends InstallerTestBase {
$path = $this->siteDirectory . '/profiles/' . $this->profile;
if ($this->existingSyncDirectory) {
$config_sync_directory = $this->siteDirectory . '/config/sync';
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $config_sync_directory,
'required' => TRUE,
];

View File

@ -48,13 +48,11 @@ class InstallerExistingSettingsMismatchProfileTest extends InstallerTestBase {
];
// Pre-configure config directories.
$this->settings['config_directories'] = [
CONFIG_SYNC_DIRECTORY => (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync',
'required' => TRUE,
],
];
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
mkdir($this->settings['settings']['config_sync_directory']->value, 0777, TRUE);
}
/**

View File

@ -40,13 +40,11 @@ class InstallerExistingSettingsNoProfileTest extends InstallerTestBase {
];
// Pre-configure config directories.
$this->settings['config_directories'] = [
CONFIG_SYNC_DIRECTORY => (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync',
'required' => TRUE,
],
];
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
mkdir($this->settings['settings']['config_sync_directory']->value, 0777, TRUE);
}
/**

View File

@ -49,13 +49,11 @@ class InstallerExistingSettingsReadOnlyMismatchProfileTest extends InstallerTest
// Pre-configure config directories.
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
$this->settings['config_directories'] = [
CONFIG_SYNC_DIRECTORY => (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $site_path . '/files/config_staging',
'required' => TRUE,
],
];
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
mkdir($this->settings['settings']['config_sync_directory']->value, 0777, TRUE);
}
/**

View File

@ -42,13 +42,11 @@ class InstallerExistingSettingsTest extends InstallerTestBase {
// not be available at this point in the install process.
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
// Pre-configure config directories.
$this->settings['config_directories'] = [
CONFIG_SYNC_DIRECTORY => (object) [
$this->settings['settings']['config_sync_directory'] = (object) [
'value' => $site_path . '/files/config_sync',
'required' => TRUE,
],
];
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
mkdir($this->settings['settings']['config_sync_directory']->value, 0777, TRUE);
}
/**

View File

@ -171,9 +171,7 @@ abstract class InstallerTestBase extends BrowserTestBase {
$request = Request::createFromGlobals();
$class_loader = require $this->container->get('app.root') . '/autoload.php';
Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
foreach ($GLOBALS['config_directories'] as $type => $path) {
$this->configDirectories[$type] = $path;
}
$this->configDirectories['sync'] = Settings::get('config_sync_directory');
// After writing settings.php, the installer removes write permissions
// from the site directory. To allow drupal_generate_test_ua() to write

View File

@ -3,11 +3,13 @@
namespace Drupal\FunctionalTests\Update;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Site\Settings;
use Drupal\Core\Test\TestRunnerKernel;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\SchemaCheckTestTrait;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Url;
use Drupal\Tests\RequirementsPageTrait;
@ -185,7 +187,8 @@ abstract class UpdatePathTestBase extends BrowserTestBase {
$this->installDrupal();
// Add the config directories to settings.php.
drupal_install_config_directories();
$sync_directory = Settings::get('config_sync_directory');
\Drupal::service('file_system')->prepareDirectory($sync_directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
// Set the container. parent::rebuildAll() would normally do this, but this
// not safe to do here, because the database has not been updated yet.
@ -274,6 +277,12 @@ abstract class UpdatePathTestBase extends BrowserTestBase {
'required' => TRUE,
];
// Set up sync directory.
$settings['settings']['config_sync_directory'] = (object) [
'value' => $this->publicFilesDirectory . '/config_sync',
'required' => TRUE,
];
$this->writeSettings($settings);
}

View File

@ -3,6 +3,7 @@
namespace Drupal\KernelTests\Core\Config;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Site\Settings;
use Drupal\KernelTests\KernelTestBase;
/**
@ -205,7 +206,7 @@ class ConfigFileContentTest extends KernelTestBase {
];
// Encode and write, and reload and decode the configuration data.
$filestorage = new FileStorage(config_get_config_directory(CONFIG_SYNC_DIRECTORY));
$filestorage = new FileStorage(Settings::get('config_sync_directory'));
$filestorage->write($name, $config_data);
$config_parsed = $filestorage->read($name);

View File

@ -749,15 +749,18 @@ class ConfigImporterTest extends KernelTestBase {
/**
* Tests config_get_config_directory().
*
* @group legacy
* @expectedDeprecation config_get_config_directory() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Site\Settings::get('config_sync_directory') instead. See https://www.drupal.org/node/3018145
*/
public function testConfigGetConfigDirectory() {
global $config_directories;
$directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
$this->assertEqual($config_directories[CONFIG_SYNC_DIRECTORY], $directory);
// Ensure the global and the setting matches.
$this->assertSame(config_get_config_directory(CONFIG_SYNC_DIRECTORY), $config_directories[CONFIG_SYNC_DIRECTORY]);
$message = 'Calling config_get_config_directory() with CONFIG_ACTIVE_DIRECTORY results in an exception.';
$message = 'Calling config_get_config_directory() with an invalid key results in an exception.';
try {
config_get_config_directory(CONFIG_ACTIVE_DIRECTORY);
config_get_config_directory('does_not_exist');
$this->fail($message);
}
catch (\Exception $e) {

View File

@ -0,0 +1,46 @@
<?php
namespace Drupal\KernelTests\Core\Config;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\FileStorageFactory;
use Drupal\Core\Site\Settings;
use Drupal\KernelTests\KernelTestBase;
/**
* @coversDefaultClass \Drupal\Core\Config\FileStorageFactory
* @group config
*/
class FileStorageFactoryTest extends KernelTestBase {
/**
* @covers ::getSync
*/
public function testGetSync() {
// Write some random data to the sync storage.
$name = $this->randomMachineName();
$data = (array) $this->getRandomGenerator()->object();
$storage = new FileStorage(Settings::get('config_sync_directory'));
$storage->write($name, $data);
// Get the sync storage and read from it.
$sync = FileStorageFactory::getSync();
$this->assertEquals($data, $sync->read($name));
// Unset the sync directory setting.
$settings = Settings::getInstance() ? Settings::getAll() : [];
unset($settings['config_sync_directory']);
new Settings($settings);
// On an empty settings there is an exception thrown.
try {
FileStorageFactory::getSync();
$this->fail("The exception was not thrown.");
}
catch (\Exception $exception) {
$this->assertEquals('The config sync directory is not defined in $settings["config_sync_directory"]', $exception->getMessage());
}
}
}

View File

@ -70,13 +70,10 @@ abstract class FileTestBase extends KernelTestBase {
mkdir($this->siteDirectory, 0775);
mkdir($this->siteDirectory . '/files', 0775);
mkdir($this->siteDirectory . '/files/config/' . CONFIG_SYNC_DIRECTORY, 0775, TRUE);
mkdir($this->siteDirectory . '/files/config/sync', 0775, TRUE);
$this->setSetting('file_public_path', $public_file_directory);
$GLOBALS['config_directories'] = [
CONFIG_SYNC_DIRECTORY => $this->siteDirectory . '/files/config/sync',
];
$this->setSetting('config_sync_directory', $this->siteDirectory . '/files/config/sync');
}
/**

View File

@ -292,15 +292,12 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
$this->siteDirectory = vfsStream::url('root/' . $test_site_path);
mkdir($this->siteDirectory . '/files', 0775);
mkdir($this->siteDirectory . '/files/config/' . CONFIG_SYNC_DIRECTORY, 0775, TRUE);
mkdir($this->siteDirectory . '/files/config/sync', 0775, TRUE);
$settings = Settings::getInstance() ? Settings::getAll() : [];
$settings['file_public_path'] = $this->siteDirectory . '/files';
$settings['config_sync_directory'] = $this->siteDirectory . '/files/config/sync';
new Settings($settings);
$GLOBALS['config_directories'] = [
CONFIG_SYNC_DIRECTORY => $this->siteDirectory . '/files/config/sync',
];
}
/**
@ -1051,9 +1048,9 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
}
if ($name === 'configDirectories') {
trigger_error(sprintf("KernelTestBase::\$%s no longer exists. Use config_get_config_directory() directly instead.", $name), E_USER_DEPRECATED);
trigger_error(sprintf("KernelTestBase::\$%s no longer exists. Use Settings::get('config_sync_directory') directly instead.", $name), E_USER_DEPRECATED);
return [
CONFIG_SYNC_DIRECTORY => config_get_config_directory(CONFIG_SYNC_DIRECTORY),
CONFIG_SYNC_DIRECTORY => Settings::get('config_sync_directory'),
];
}

View File

@ -3,7 +3,9 @@
namespace Drupal\Tests\Core\Site;
use Drupal\Core\Site\Settings;
use Drupal\Tests\Traits\ExpectDeprecationTrait;
use Drupal\Tests\UnitTestCase;
use org\bovigo\vfs\vfsStream;
/**
* @coversDefaultClass \Drupal\Core\Site\Settings
@ -11,6 +13,8 @@ use Drupal\Tests\UnitTestCase;
*/
class SettingsTest extends UnitTestCase {
use ExpectDeprecationTrait;
/**
* Simple settings array to test against.
*
@ -117,10 +121,16 @@ class SettingsTest extends UnitTestCase {
* @covers ::getApcuPrefix
*/
public function testGetApcuPrefix() {
$settings = new Settings(['hash_salt' => 123, 'apcu_ensure_unique_prefix' => TRUE]);
$settings = new Settings([
'hash_salt' => 123,
'apcu_ensure_unique_prefix' => TRUE,
]);
$this->assertNotEquals($settings::getApcuPrefix('cache_test', '/test/a'), $settings::getApcuPrefix('cache_test', '/test/b'));
$settings = new Settings(['hash_salt' => 123, 'apcu_ensure_unique_prefix' => FALSE]);
$settings = new Settings([
'hash_salt' => 123,
'apcu_ensure_unique_prefix' => FALSE,
]);
$this->assertNotEquals($settings::getApcuPrefix('cache_test', '/test/a'), $settings::getApcuPrefix('cache_test', '/test/b'));
}
@ -141,4 +151,105 @@ class SettingsTest extends UnitTestCase {
$settings->getInstance();
}
/**
* @runInSeparateProcess
* @group legacy
* @covers ::__construct
* @dataProvider configDirectoriesBcLayerProvider
*/
public function testConfigDirectoriesBcLayer($settings_file_content, $directory, $expect_deprecation) {
global $config_directories;
$class_loader = NULL;
$vfs_root = vfsStream::setup('root');
$sites_directory = vfsStream::newDirectory('sites')->at($vfs_root);
vfsStream::newFile('settings.php')
->at($sites_directory)
->setContent($settings_file_content);
if ($expect_deprecation) {
$this->expectDeprecation('$config_directories[\'sync\'] has moved to $settings[\'config_sync_directory\']. See https://www.drupal.org/node/3018145.');
}
Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);
$this->assertSame($directory, Settings::get('config_sync_directory'));
$this->assertSame($directory, $config_directories['sync']);
}
/**
* Data provider for self::testConfigDirectoriesBcLayer().
*/
public function configDirectoriesBcLayerProvider() {
$no_config_directories = <<<'EOD'
<?php
$settings['config_sync_directory'] = 'foo';
EOD;
$only_config_directories = <<<'EOD'
<?php
$config_directories['sync'] = 'bar';
EOD;
$both = <<<'EOD'
<?php
$settings['config_sync_directory'] = 'foo';
$config_directories['sync'] = 'bar';
EOD;
return [
'Only $settings[\'config_sync_directory\']' => [
$no_config_directories,
'foo',
FALSE,
],
'Only $config_directories' => [$only_config_directories, 'bar', TRUE],
'Both' => [$both, 'foo', FALSE],
];
}
/**
* @runInSeparateProcess
* @group legacy
*/
public function testConfigDirectoriesBcLayerEmpty() {
global $config_directories;
$class_loader = NULL;
$vfs_root = vfsStream::setup('root');
$sites_directory = vfsStream::newDirectory('sites')->at($vfs_root);
vfsStream::newFile('settings.php')->at($sites_directory)->setContent(<<<'EOD'
<?php
$settings = [];
EOD
);
Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);
$this->assertNull(Settings::get('config_sync_directory'));
$this->assertNull($config_directories);
}
/**
* @runInSeparateProcess
* @group legacy
*/
public function testConfigDirectoriesBcLayerMultiple() {
global $config_directories;
$class_loader = NULL;
$vfs_root = vfsStream::setup('root');
$sites_directory = vfsStream::newDirectory('sites')->at($vfs_root);
vfsStream::newFile('settings.php')->at($sites_directory)->setContent(<<<'EOD'
<?php
$settings['config_sync_directory'] = 'foo';
$config_directories['sync'] = 'bar';
$config_directories['custom'] = 'custom';
EOD
);
Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);
$this->assertSame('foo', Settings::get('config_sync_directory'));
$this->assertSame('foo', $config_directories['sync']);
$this->assertSame('custom', $config_directories['custom']);
}
}

View File

@ -229,29 +229,15 @@ $databases = [];
/**
* Location of the site configuration files.
*
* The $config_directories array specifies the location of file system
* directories used for configuration data. On install, the "sync" directory is
* created. This is used for configuration imports. The "active" directory is
* not created by default since the default storage for active configuration is
* the database rather than the file system. (This can be changed. See "Active
* configuration settings" below).
* The $settings['config_sync_directory'] specifies the location of file system
* directory used for syncing configuration data. On install, the directory is
* created. This is used for configuration imports.
*
* The default location for the "sync" directory is inside a randomly-named
* directory in the public files path. The setting below allows you to override
* the "sync" location.
*
* If you use files for the "active" configuration, you can tell the
* Configuration system where this directory is located by adding an entry with
* array key CONFIG_ACTIVE_DIRECTORY.
*
* Example:
* @code
* $config_directories = [
* CONFIG_SYNC_DIRECTORY => '/directory/outside/webroot',
* ];
* @endcode
* The default location for this directory is inside a randomly-named
* directory in the public files path. The setting below allows you to set
* its location.
*/
$config_directories = [];
# $settings['config_sync_directory'] = '/directory/outside/webroot';
/**
* Settings:
@ -596,25 +582,6 @@ if ($settings['hash_salt']) {
# ini_set('pcre.backtrack_limit', 200000);
# ini_set('pcre.recursion_limit', 200000);
/**
* Active configuration settings.
*
* By default, the active configuration is stored in the database in the
* {config} table. To use a different storage mechanism for the active
* configuration, do the following prior to installing:
* - Create an "active" directory and declare its path in $config_directories
* as explained under the 'Location of the site configuration files' section
* above in this file. To enhance security, you can declare a path that is
* outside your document root.
* - Override the 'bootstrap_config_storage' setting here. It must be set to a
* callable that returns an object that implements
* \Drupal\Core\Config\StorageInterface.
* - Override the service definition 'config.storage.active'. Put this
* override in a services.yml file in the same directory as settings.php
* (definitions in this file will override service definition defaults).
*/
# $settings['bootstrap_config_storage'] = ['Drupal\Core\Config\BootstrapConfigStorageFactory', 'getFileStorage'];
/**
* Configuration overrides.
*