Commit 959f1752 authored by catch's avatar catch

Issue #2922417 by alexpott, Calystod, DanielVeza, Pasqualle, Berdir, hchonov,...

Issue #2922417 by alexpott, Calystod, DanielVeza, Pasqualle, Berdir, hchonov, effulgentsia, pfrenssen, tstoeckler: Profile provided configuration entities can have unmeetable dependencies
parent bd5908ad
......@@ -123,10 +123,14 @@ public function installDefaultConfig($type, $name) {
$collection_info = $this->configManager->getConfigCollectionInfo();
foreach ($collection_info->getCollectionNames() as $collection) {
$config_to_create = $this->getConfigToCreate($storage, $collection, $prefix, $profile_storages);
// If we're installing a profile ensure configuration that is overriding
// is excluded.
if ($name == $this->drupalGetProfile()) {
$existing_configuration = $this->getActiveStorages($collection)->listAll();
// If we're installing a profile ensure simple configuration that
// already exists is excluded as it will have already been written.
// This means that if the configuration is changed by something else
// during the install it will not be overwritten again.
$existing_configuration = array_filter($this->getActiveStorages($collection)->listAll(), function ($config_name) {
return !$this->configManager->getEntityTypeIdByName($config_name);
});
$config_to_create = array_diff_key($config_to_create, array_flip($existing_configuration));
}
if (!empty($config_to_create)) {
......@@ -266,12 +270,35 @@ protected function getConfigToCreate(StorageInterface $storage, $collection, $pr
}
$data = $storage->readMultiple($storage->listAll($prefix));
// Check to see if the corresponding override storage has any overrides.
// Check to see if configuration provided by the install profile has any
// overrides.
foreach ($profile_storages as $profile_storage) {
if ($profile_storage->getCollectionName() != $collection) {
$profile_storage = $profile_storage->createCollection($collection);
}
$data = $profile_storage->readMultiple(array_keys($data)) + $data;
$profile_overrides = $profile_storage->readMultiple(array_keys($data));
if (InstallerKernel::installationAttempted()) {
// During installation overrides of simple configuration are applied
// immediately. Configuration entities that are overridden will be
// updated when the profile is installed. This allows install profiles
// to provide configuration entity overrides that have dependencies that
// cannot be met when the module provided configuration entity is
// created.
foreach ($profile_overrides as $name => $override_data) {
// The only way to determine if they are configuration entities is the
// presence of a dependencies key.
if (!isset($override_data['dependencies'])) {
$data[$name] = $override_data;
}
}
}
else {
// Allow install profiles to provide overridden configuration for new
// extensions that are being enabled after Drupal has already been
// installed. This allows profiles to ship new extensions in version
// updates without requiring additional code to apply the overrides.
$data = $profile_overrides + $data;
}
}
return $data;
}
......
......@@ -3,11 +3,13 @@
namespace Drupal\Tests\config\Functional;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Config\InstallStorage;
use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Config\FileStorage;
use Drupal\system\Entity\Action;
use Drupal\tour\Entity\Tour;
use Drupal\user\Entity\Role;
/**
* Tests installation and removal of configuration objects in install, disable
......@@ -61,6 +63,16 @@ public function testInstallProfileConfigOverwrite() {
$config = $this->config($config_name);
$this->assertIdentical($config->get(), $expected_profile_data);
$config = $this->config('system.site');
// Verify the system.site config has a valid UUID.
$site_uuid = $config->get('uuid');
$this->assertTrue(Uuid::isValid($site_uuid) && strlen($site_uuid) > 0, "Site UUID '$site_uuid' is valid");
// Verify the profile overrides have been used.
$this->assertEquals(91, $config->get('weight_select_max'));
// Ensure the site configure form is used.
$this->assertEquals('Drupal', $config->get('name'));
$this->assertEquals('simpletest@example.com', $config->get('mail'));
// Ensure that the configuration entity has the expected dependencies and
// overrides.
$action = Action::load('user_block_user_action');
......@@ -117,6 +129,10 @@ public function testInstallProfileConfigOverwrite() {
$this->rebuildContainer();
$config_test_storage = \Drupal::entityTypeManager()->getStorage('config_test');
$this->assertNull($config_test_storage->load('completely_new'));
// Ensure the authenticated role has the access tour permission.
$role = Role::load(Role::AUTHENTICATED_ID);
$this->assertTrue($role->hasPermission('access tour'), 'The Authenticated role has the "access tour" permission.');
}
}
......@@ -69,11 +69,10 @@ protected function copyTestingOverrides() {
}
}
// Add a dependency that can not be met because User is installed before
// Action.
// Add a dependency that can not be met.
$config_file = $dest . DIRECTORY_SEPARATOR . InstallStorage::CONFIG_INSTALL_DIRECTORY . DIRECTORY_SEPARATOR . 'system.action.user_block_user_action.yml';
$action = Yaml::decode(file_get_contents($config_file));
$action['dependencies']['module'][] = 'action';
$action['dependencies']['module'][] = 'does_not_exist';
file_put_contents($config_file, Yaml::encode($action));
}
......@@ -82,7 +81,7 @@ protected function copyTestingOverrides() {
*/
public function testInstalled() {
if ($this->expectedException) {
$this->assertContains('Configuration objects provided by <em class="placeholder">user</em> have unmet dependencies: <em class="placeholder">system.action.user_block_user_action (action)</em>', $this->expectedException->getMessage());
$this->assertContains('Configuration objects provided by <em class="placeholder">testing_config_overrides</em> have unmet dependencies: <em class="placeholder">system.action.user_block_user_action (does_not_exist)</em>', $this->expectedException->getMessage());
$this->assertContains('Drupal\Core\Config\UnmetDependenciesException', $this->expectedException->getMessage());
}
else {
......
uuid: ''
name: 'Test - this is overridden by the installer site configure form'
mail: ''
slogan: ''
page:
403: ''
404: ''
front: /user/login
admin_compact_mode: false
weight_select_max: 91
langcode: en
default_langcode: en
langcode: en
status: true
dependencies:
module:
- tour
id: authenticated
label: 'Authenticated user'
weight: 1
is_admin: false
permissions:
- 'access tour'
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