diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 6f7955a76b..abae69842e 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -194,7 +194,7 @@ function install_state_defaults() { // Partial configuration cached during an installation from existing config. 'config' => NULL, // The path to the configuration to install when installing from config. - 'config_install' => NULL, + 'config_install_path' => NULL, // TRUE when there are valid config directories. 'config_verified' => FALSE, // TRUE when there is a valid database connection. @@ -462,15 +462,13 @@ function install_begin_request($class_loader, &$install_state) { } // Use the language from profile configuration if available. - if (!empty($install_state['config_install']) && $install_state['config']['system.site']) { + if (!empty($install_state['config_install_path']) && $install_state['config']['system.site']) { $install_state['parameters']['langcode'] = $install_state['config']['system.site']['default_langcode']; } - else { + elseif (isset($install_state['profile_info']['distribution']['langcode'])) { // Otherwise, Use the language from the profile configuration, if available, // to override the language previously set in the parameters. - if (isset($install_state['profile_info']['distribution']['langcode'])) { - $install_state['parameters']['langcode'] = $install_state['profile_info']['distribution']['langcode']; - } + $install_state['parameters']['langcode'] = $install_state['profile_info']['distribution']['langcode']; } // Set the default language to the selected language, if any. @@ -806,7 +804,7 @@ function install_tasks($install_state) { ], ]; - if (!empty($install_state['config_install'])) { + if (!empty($install_state['config_install_path'])) { // The chosen profile indicates that rather than installing a new site, an // instance of the same site should be installed from the given // configuration. @@ -1508,8 +1506,8 @@ function install_load_profile(&$install_state) { $install_state['profile_info'] = install_profile_info($profile, isset($install_state['parameters']['langcode']) ? $install_state['parameters']['langcode'] : 'en'); // If the profile has a config/sync directory copy the information to the // install_state global. - if (!empty($install_state['profile_info']['config_install'])) { - $install_state['config_install'] = $install_state['profile_info']['config_install']; + if (!empty($install_state['profile_info']['config_install_path'])) { + $install_state['config_install_path'] = $install_state['profile_info']['config_install_path']; if (!empty($install_state['profile_info']['config'])) { $install_state['config'] = $install_state['profile_info']['config']; } @@ -2390,7 +2388,6 @@ function install_config_import_batch_finish($success, $results, $operations) { } } - /** * Replaces install_download_translation() during configuration installs. * @@ -2410,7 +2407,6 @@ function install_config_download_translations(&$install_state) { } } - /** * Fixes configuration if the install profile has made changes in hook_install(). */ diff --git a/core/includes/install.inc b/core/includes/install.inc index a5d15783f6..5f9ded0b7b 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -489,14 +489,14 @@ function drupal_install_config_directories() { // If settings.php does not contain a config sync directory name we need to // configure one. if (empty($config_directories[CONFIG_SYNC_DIRECTORY])) { - if (empty($install_state['config_install'])) { + if (empty($install_state['config_install_path'])) { // Add a randomized config directory name to settings.php $config_directories[CONFIG_SYNC_DIRECTORY] = \Drupal::service('site.path') . '/files/config_' . Crypt::randomBytesBase64(55) . '/sync'; } else { // Install profiles can contain a config sync directory. If they do, - // 'config_install' is a path to the directory. - $config_directories[CONFIG_SYNC_DIRECTORY] = $install_state['config_install']; + // 'config_install_path' is a path to the directory. + $config_directories[CONFIG_SYNC_DIRECTORY] = $install_state['config_install_path']; } $settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [ 'value' => $config_directories[CONFIG_SYNC_DIRECTORY], @@ -1090,7 +1090,7 @@ function install_profile_info($profile, $langcode = 'en') { 'version' => NULL, 'hidden' => FALSE, 'php' => DRUPAL_MINIMUM_PHP, - 'config_install' => NULL, + 'config_install_path' => NULL, ]; $profile_path = drupal_get_path('profile', $profile); $info = \Drupal::service('info_parser')->parse($profile_path . "/$profile.info.yml"); @@ -1106,7 +1106,7 @@ function install_profile_info($profile, $langcode = 'en') { // If the profile has a config/sync directory use that to install drupal. if (is_dir($profile_path . '/config/sync')) { - $info['config_install'] = $profile_path . '/config/sync'; + $info['config_install_path'] = $profile_path . '/config/sync'; $sync = new FileStorage($profile_path . '/config/sync'); $info['config']['system.site'] = $sync->read('system.site'); } diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php index 79c073b70f..d7e6c4b880 100644 --- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php +++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php @@ -148,14 +148,14 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['site_information'] = [ '#type' => 'fieldgroup', '#title' => $this->t('Site information'), - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['site_information']['site_name'] = [ '#type' => 'textfield', '#title' => $this->t('Site name'), '#required' => TRUE, '#weight' => -20, - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['site_information']['site_mail'] = [ '#type' => 'email', @@ -164,7 +164,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#description' => $this->t("Automated emails, such as registration information, will be sent from this address. Use an address ending in your site's domain to help prevent these emails from being flagged as spam."), '#required' => TRUE, '#weight' => -15, - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['admin_account'] = [ @@ -194,7 +194,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['regional_settings'] = [ '#type' => 'fieldgroup', '#title' => $this->t('Regional settings'), - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $countries = $this->countryManager->getList(); $form['regional_settings']['site_default_country'] = [ @@ -205,7 +205,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#options' => $countries, '#description' => $this->t('Select the default country for the site.'), '#weight' => 0, - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['regional_settings']['date_default_timezone'] = [ '#type' => 'select', @@ -216,20 +216,20 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#description' => $this->t('By default, dates in this site will be displayed in the chosen time zone.'), '#weight' => 5, '#attributes' => ['class' => ['timezone-detect']], - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['update_notifications'] = [ '#type' => 'fieldgroup', '#title' => $this->t('Update notifications'), '#description' => $this->t('The system will notify you when updates and important security releases are available for installed components. Anonymous information about your site is sent to Drupal.org.', [':drupal' => 'https://www.drupal.org']), - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['update_notifications']['enable_update_status_module'] = [ '#type' => 'checkbox', '#title' => $this->t('Check for updates automatically'), '#default_value' => 1, - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['update_notifications']['enable_update_status_emails'] = [ '#type' => 'checkbox', @@ -240,7 +240,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { 'input[name="enable_update_status_module"]' => ['checked' => TRUE], ], ], - '#access' => empty($install_state['config_install']), + '#access' => empty($install_state['config_install_path']), ]; $form['actions'] = ['#type' => 'actions']; @@ -269,7 +269,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { global $install_state; - if (empty($install_state['config_install'])) { + if (empty($install_state['config_install_path'])) { $this->config('system.site') ->set('name', (string) $form_state->getValue('site_name')) ->set('mail', (string) $form_state->getValue('site_mail')) @@ -285,7 +285,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Enable update.module if this option was selected. $update_status_module = $form_state->getValue('enable_update_status_module'); - if (empty($install_state['config_install']) && $update_status_module) { + if (empty($install_state['config_install_path']) && $update_status_module) { $this->moduleInstaller->install(['file', 'update'], FALSE); // Add the site maintenance account's email address to the list of diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingConfigNoConfigTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingConfigNoConfigTest.php index 2e7fdbce06..0a726ff86d 100644 --- a/core/modules/system/src/Tests/Installer/InstallerExistingConfigNoConfigTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerExistingConfigNoConfigTest.php @@ -3,7 +3,7 @@ namespace Drupal\system\Tests\Installer; /** - * Verifies that installing from existing configuration works. + * Verifies that profiles invalid config can not be installed. * * @group Installer */ @@ -26,6 +26,9 @@ protected function getConfigTarball() { return __DIR__ . '/../../../tests/fixtures/config_install/testing_config_install_no_config.tar.gz'; } + /** + * Tests that profiles with an empty config/sync directory do not work. + */ public function testConfigSync() { $this->assertTitle('Configuration validation | Drupal'); $this->assertText('The configuration synchronization failed validation.'); diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingConfigProfileHookInstall.php b/core/modules/system/src/Tests/Installer/InstallerExistingConfigProfileHookInstall.php new file mode 100644 index 0000000000..fd56c6cf3f --- /dev/null +++ b/core/modules/system/src/Tests/Installer/InstallerExistingConfigProfileHookInstall.php @@ -0,0 +1,61 @@ +siteDirectory . '/profiles/' . $this->profile; + $contents = <<profile}.install", $contents); + parent::visitInstaller(); + } + + /** + * Installer step: Configure settings. + */ + protected function setUpSettings() { + // There are errors therefore there is nothing to do here. + return; + } + + /** + * Final installer step: Configure site. + */ + protected function setUpSite() { + // There are errors therefore there is nothing to do here. + return; + } + + /** + * @inheritDoc + */ + protected function getConfigTarball() { + // We're not going to get to the config import stage so this does not + // matter. + return __DIR__ . '/../../../tests/fixtures/config_install/testing_config_install_no_config.tar.gz'; + } + + public function testConfigSync() { + $this->assertTitle('Requirements problem | Drupal'); + $this->assertText($this->profile); + $this->assertText('The selected profile has a hook_install() implementation and therefore can not be installed from configuration.'); + } + +} diff --git a/core/modules/system/system.install b/core/modules/system/system.install index ef6f124f51..2e69787549 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -993,6 +993,19 @@ function system_requirements($phase) { ]; } + // During installs from configuration don't support install profiles that + // implement hook_install. + if ($phase == 'install' && !empty($install_state['config_install_path'])) { + $install_hook = $install_state['parameters']['profile'] . '_install'; + if (function_exists($install_hook)) { + $requirements['config_install'] = [ + 'title' => t('Configuration install'), + 'value' => $install_state['parameters']['profile'], + 'description' => t('The selected profile has a hook_install() implementation and therefore can not be installed from configuration.'), + 'severity' => REQUIREMENT_ERROR, + ]; + } + } return $requirements; }