Commit 16726375 authored by catch's avatar catch

Issue #2975328 by alexpott, Gábor Hojtsy, borisson_: Install profile in...

Issue #2975328 by alexpott, Gábor Hojtsy, borisson_: Install profile in settings.php and mismatch check makes re-installs of Drupal hard
parent 646584b3
......@@ -14,7 +14,6 @@
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;
......@@ -797,12 +796,6 @@ function drupal_get_profile() {
else {
$profile = BootstrapConfigStorageFactory::getDatabaseStorage()->read('core.extension')['profile'];
}
// A BC layer just in in case this only exists in Settings. Introduced in
// Drupal 8.3.x and will be removed before Drupal 9.0.0.
if (empty($profile)) {
$profile = Settings::get('install_profile');
}
}
return $profile;
......
......@@ -17,7 +17,6 @@
use Drupal\Core\Form\FormState;
use Drupal\Core\Installer\Exception\AlreadyInstalledException;
use Drupal\Core\Installer\Exception\InstallerException;
use Drupal\Core\Installer\Exception\InstallProfileMismatchException;
use Drupal\Core\Installer\Exception\NoProfilesException;
use Drupal\Core\Installer\InstallerKernel;
use Drupal\Core\Language\Language;
......@@ -2284,16 +2283,16 @@ function install_display_requirements($install_state, $requirements) {
*
* @see _install_select_profile()
*
* @throws \Drupal\Core\Installer\Exception\InstallProfileMismatchException
*
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. The
* install profile is written to core.extension.
*/
function install_write_profile($install_state) {
// Only need to write to settings.php if it is possible. The primary storage
// for the install profile is the core.extension configuration.
// Only write the install profile to settings.php if already exists. The value
// from settings.php is never used but drupal_rewrite_settings() does not
// support removing a setting. If the value in configuration and settings.php
// don't match there will be a warning on the status report.
$settings_path = \Drupal::service('site.path') . '/settings.php';
if (is_writable($settings_path)) {
if (is_writable($settings_path) && array_key_exists('install_profile', Settings::getAll())) {
// Remember the profile which was used.
$settings['settings']['install_profile'] = (object) [
'value' => $install_state['parameters']['profile'],
......@@ -2301,9 +2300,6 @@ function install_write_profile($install_state) {
];
drupal_rewrite_settings($settings);
}
elseif (($settings_profile = Settings::get('install_profile')) && $settings_profile !== $install_state['parameters']['profile']) {
throw new InstallProfileMismatchException($install_state['parameters']['profile'], $settings_profile, $settings_path, \Drupal::translation());
}
}
/**
......
......@@ -1604,13 +1604,14 @@ protected function addServiceFiles(array $service_yamls) {
*/
protected function getInstallProfile() {
$config = $this->getConfigStorage()->read('core.extension');
if (!empty($config['profile'])) {
if (isset($config['profile'])) {
$install_profile = $config['profile'];
}
// @todo https://www.drupal.org/node/2831065 remove the BC layer.
else {
// If system_update_8300() has not yet run fallback to using settings.
$install_profile = Settings::get('install_profile');
$settings = Settings::getAll();
$install_profile = isset($settings['install_profile']) ? $settings['install_profile'] : NULL;
}
// Normalize an empty string to a NULL value.
......
......@@ -4,6 +4,8 @@
use Drupal\Core\StringTranslation\TranslationInterface;
@trigger_error(__NAMESPACE__ . '/InstallProfileMismatchException is deprecated in Drupal 8.6.0 and will be removed before Drupal 9. See https://www.drupal.org/node/2538996', E_USER_DEPRECATED);
/**
* Exception thrown if settings.php cannot be written and the chosen profile does not match.
*/
......
......@@ -225,11 +225,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
'value' => Crypt::randomBytesBase64(55),
'required' => TRUE,
];
// Remember the profile which was used.
$settings['settings']['install_profile'] = (object) [
'value' => $install_state['parameters']['profile'],
'required' => TRUE,
];
drupal_rewrite_settings($settings);
......
......@@ -84,6 +84,9 @@ public function __sleep() {
* The value of the setting, the provided default if not set.
*/
public static function get($name, $default = NULL) {
if ($name === 'install_profile' && isset(self::$instance->storage[$name])) {
@trigger_error('To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996', E_USER_DEPRECATED);
}
return isset(self::$instance->storage[$name]) ? self::$instance->storage[$name] : $default;
}
......
......@@ -1015,6 +1015,21 @@ function system_requirements($phase) {
];
}
}
if ($phase === 'runtime') {
$settings = Settings::getAll();
if (array_key_exists('install_profile', $settings)) {
// The following message is only informational because not all site owners
// have access to edit their settings.php as it may be controlled by their
// hosting provider.
$requirements['install_profile_in_settings'] = [
'title' => t('Install profile in settings'),
'value' => t("Drupal 8 no longer uses the \$settings['install_profile'] value in settings.php and it can be removed."),
'severity' => REQUIREMENT_INFO,
];
}
}
return $requirements;
}
......
......@@ -9,6 +9,7 @@
* Tests system_update_8300().
*
* @group Update
* @group legacy
*/
class InstallProfileSystemInstall8300Test extends UpdatePathTestBase {
......@@ -23,6 +24,8 @@ protected function setDatabaseDumpFiles() {
/**
* Ensures that the system_update_8300() runs as expected.
*
* @expectedDeprecation To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996
*/
public function testUpdate() {
// Ensure the BC layers work and settings.php and configuration is in the
......
......@@ -179,7 +179,7 @@ public function testDependencyResolution() {
public function testUninstallProfileDependencyBC() {
$profile = 'testing_install_profile_dependencies_bc';
$dependency = 'dblog';
$this->setSetting('install_profile', $profile);
$this->setInstallProfile($profile);
// Prime the drupal_get_filename() static cache with the location of the
// testing profile as it is not the currently active profile and we don't
// yet have any cached way to retrieve its location.
......@@ -213,7 +213,7 @@ public function testUninstallProfileDependency() {
$profile = 'testing_install_profile_dependencies';
$dependency = 'dblog';
$non_dependency = 'ban';
$this->setSetting('install_profile', $profile);
$this->setInstallProfile($profile);
// Prime the drupal_get_filename() static cache with the location of the
// testing_install_profile_dependencies profile as it is not the currently
// active profile and we don't yet have any cached way to retrieve its
......@@ -252,7 +252,7 @@ public function testProfileAllDependencies() {
$profile = 'testing_install_profile_all_dependencies';
$dependencies = ['dblog', 'ban'];
$this->setSetting('install_profile', $profile);
$this->setInstallProfile($profile);
// Prime the drupal_get_filename() static cache with the location of the
// testing_install_profile_dependencies profile as it is not the currently
// active profile and we don't yet have any cached way to retrieve its
......
......@@ -2,7 +2,6 @@
namespace Drupal\Tests\demo_umami_content\Functional;
use Drupal\Core\Site\Settings;
use Drupal\Tests\BrowserTestBase;
/**
......@@ -18,7 +17,7 @@ class DefaultContentFilesAccessTest extends BrowserTestBase {
public function testAccessDeniedToFiles() {
// The demo_umami profile should not be used because we want to ensure that
// if you install another profile these files are not available.
$this->assertNotSame('demo_umami', Settings::get('install_profile'));
$this->assertNotSame('demo_umami', \Drupal::installProfile());
$files_to_test = [
'images/chocolate-brownie-umami.jpg',
......
......@@ -119,7 +119,7 @@ public function testInstalled() {
// Confirm that Drupal recognizes this distribution as the current profile.
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
$this->assertNull(Settings::get('install_profile'), 'The install profile has not been written to settings.php.');
$this->assertArrayNotHasKey('install_profile', Settings::getAll(), 'The install profile has not been written to settings.php.');
$this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.');
$this->rebuildContainer();
......
......@@ -3,7 +3,6 @@
namespace Drupal\FunctionalTests\Installer;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Site\Settings;
/**
* Tests distribution profile support.
......@@ -74,7 +73,6 @@ public function testInstalled() {
// Confirm that Drupal recognizes this distribution as the current profile.
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
$this->assertEqual(Settings::get('install_profile'), 'mydistro', 'The install profile has been written to settings.php.');
$this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.');
}
......
......@@ -8,9 +8,10 @@
use Symfony\Component\HttpFoundation\Request;
/**
* Tests the installer with an existing settings file but no install profile.
* Tests install with existing settings.php and a mismatching install profile.
*
* @group Installer
* @group legacy
*/
class InstallerExistingSettingsMismatchProfileTest extends InstallerTestBase {
......@@ -88,6 +89,8 @@ protected function setUpSettings() {
/**
* Verifies that installation succeeded.
*
* @expectedDeprecation To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996
*/
public function testInstaller() {
$this->assertUrl('user/1');
......
......@@ -4,14 +4,16 @@
use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database;
use Drupal\Core\Site\Settings;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests installer breaks with a profile mismatch and a read-only settings.php.
*
* @group Installer
* @group legacy
*/
class InstallerExistingSettingsMismatchProfileBrokenTest extends InstallerTestBase {
class InstallerExistingSettingsReadOnlyMismatchProfileTest extends InstallerTestBase {
/**
* {@inheritdoc}
......@@ -91,16 +93,18 @@ protected function setUpSettings() {
// already.
}
protected function setUpSite() {
// This step should not appear, since settings.php could not be written.
}
/**
* Verifies that installation did not succeed.
* Verifies that installation succeeded.
*
* @expectedDeprecation To access the install profile in Drupal 8 use \Drupal::installProfile() or inject the install_profile container parameter into your service. See https://www.drupal.org/node/2538996
*/
public function testBrokenInstaller() {
$this->assertTitle('Install profile mismatch | Drupal');
$this->assertText("The selected profile testing does not match the install_profile setting, which is minimal. Cannot write updated setting to {$this->siteDirectory}/settings.php.");
public function testInstalled() {
$this->initBrowserOutputFile();
$this->htmlOutput(NULL);
$this->assertEquals('testing', \Drupal::installProfile());
$this->assertEquals('minimal', Settings::get('install_profile'));
$this->drupalGet('admin/reports/status');
$this->assertSession()->pageTextContains("Drupal 8 no longer uses the \$settings['install_profile'] value in settings.php and it can be removed.");
}
}
......@@ -2,7 +2,6 @@
namespace Drupal\FunctionalTests\Installer;
use Drupal\Core\Site\Settings;
use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
......@@ -29,13 +28,6 @@ protected function prepareEnvironment() {
'required' => TRUE,
];
// During interactive install we'll change this to a different profile and
// this test will ensure that the new value is written to settings.php.
$this->settings['settings']['install_profile'] = (object) [
'value' => 'minimal',
'required' => TRUE,
];
// Pre-configure database credentials.
$connection_info = Database::getConnectionInfo();
unset($connection_info['default']['pdo']);
......@@ -73,8 +65,7 @@ protected function setUpSettings() {
public function testInstaller() {
$this->assertUrl('user/1');
$this->assertResponse(200);
$this->assertEqual('testing', \Drupal::installProfile(), 'Profile was changed from minimal to testing during interactive install.');
$this->assertEqual('testing', Settings::get('install_profile'), 'Profile was correctly changed to testing in Settings.php');
$this->assertEqual('testing', \Drupal::installProfile());
}
}
......@@ -3,7 +3,6 @@
namespace Drupal\FunctionalTests\Installer;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Site\Settings;
/**
* Tests multiple distribution profile support.
......@@ -78,7 +77,6 @@ public function testInstalled() {
// Confirm that Drupal recognizes this distribution as the current profile.
$this->assertEqual(\Drupal::installProfile(), 'distribution_one');
$this->assertEqual(Settings::get('install_profile'), 'distribution_one', 'The install profile has been written to settings.php.');
$this->assertEqual($this->config('core.extension')->get('profile'), 'distribution_one', 'The install profile has been written to core.extension configuration.');
$this->rebuildContainer();
......
......@@ -2,7 +2,6 @@
namespace Drupal\KernelTests\Core\Extension;
use Drupal\Core\Site\Settings;
use Drupal\KernelTests\KernelTestBase;
/**
......@@ -15,12 +14,9 @@ class ModuleExtensionListTest extends KernelTestBase {
* @covers ::getList
*/
public function testGetlist() {
$settings = Settings::getAll();
$settings['install_profile'] = 'testing';
new Settings($settings);
\Drupal::configFactory()->getEditable('core.extension')
->set('module.testing', 1000)
->set('profile', 'testing')
->save();
// The installation profile is provided by a container parameter.
......
......@@ -934,11 +934,32 @@ protected function render(array &$elements) {
* \Drupal\Core\Site\Settings::get() to perform custom merges.
*/
protected function setSetting($name, $value) {
if ($name === 'install_profile') {
@trigger_error('Use \Drupal\KernelTests\KernelTestBase::setInstallProfile() to set the install profile in kernel tests. See https://www.drupal.org/node/2538996', E_USER_DEPRECATED);
$this->setInstallProfile($value);
}
$settings = Settings::getInstance() ? Settings::getAll() : [];
$settings[$name] = $value;
new Settings($settings);
}
/**
* Sets the install profile and rebuilds the container to update it.
*
* @param string $profile
* The install profile to set.
*/
protected function setInstallProfile($profile) {
$this->container->get('config.factory')
->getEditable('core.extension')
->set('profile', $profile)
->save();
// The installation profile is provided by a container parameter. Saving
// the configuration doesn't automatically trigger invalidation
$this->container->get('kernel')->rebuildContainer();
}
/**
* Stops test execution.
*/
......
......@@ -263,23 +263,6 @@
* @see \Drupal\Core\Site\Settings::get()
*/
/**
* The active installation profile.
*
* Changing this after installation is not recommended as it changes which
* directories are scanned during extension discovery. If this is set prior to
* installation this value will be rewritten according to the profile selected
* by the user.
*
* @see install_select_profile()
*
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. The
* install profile is written to the core.extension configuration. If a
* service requires the install profile use the 'install_profile' container
* parameter. Functional code can use \Drupal::installProfile().
*/
# $settings['install_profile'] = '';
/**
* Salt for one-time login links, cancel links, form tokens, etc.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment