diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index 52875bb..ef49b65 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -417,7 +417,7 @@ public function getConfigCollectionInfo() { * TRUE if the entity has changed as a result of calling the * onDependencyRemoval() method, FALSE if not. */ - protected function callOnDependencyResolver($operation, ConfigEntityInterface $entity, array $dependent_entities, $type, array $names) { + protected function callOnDependencyResolver($operation, ConfigEntityInterface $entity, array $dependent_entities, $type, array $names) { $entity_dependencies = $entity->getDependencies(); if (empty($entity_dependencies)) { // No dependent entities nothing to do. diff --git a/core/lib/Drupal/Core/Config/ConfigManagerDependencyFinderInterface.php b/core/lib/Drupal/Core/Config/ConfigManagerDependencyFinderInterface.php index f6f49f2..e4f857e 100644 --- a/core/lib/Drupal/Core/Config/ConfigManagerDependencyFinderInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigManagerDependencyFinderInterface.php @@ -29,7 +29,9 @@ * should be a list of module names or theme names. In the case of 'config' * or 'content' it should be a list of configuration dependency names. For * entity dependencies, the caller can, alternatively, pass the full entity - * object instead of its dependency name. + * object instead of its dependency name. This is particularly useful when + * the dependency gets updated and needs to send the whole entity so that + * the dependant is able to access the fresh data from the entity. * @param bool $dry_run * If set to FALSE the entities returned in the list of updates will be * modified. In order to make the changes the caller needs to save them. If diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index cf1e83d..b7a31fe 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -593,7 +593,7 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie break; } // Fix or remove any dependencies. - $config_entities = static::getConfigManager()->getConfigEntitiesToChangeOnDependencyRemoval('config', [$entity->getConfigDependencyName()], FALSE); + $config_entities = static::getConfigManager()->getConfigEntitiesToChange(ConfigManagerInterface::REMOVE, 'config', [$entity], FALSE); /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $dependent_entity */ foreach ($config_entities['update'] as $dependent_entity) { $dependent_entity->save(); diff --git a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml index 9af8c7b..abb30a9 100644 --- a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml +++ b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml @@ -162,6 +162,12 @@ config_test.dependent_config_test.*: label: type: label label: 'Label' + description: + type: string + label: 'Description' targetConfigId: type: string label: 'Target configuration ID' + targetConfig2Id: + type: string + label: 'Second target configuration ID' diff --git a/core/modules/config/tests/config_test/src/Entity/DependentConfigTest.php b/core/modules/config/tests/config_test/src/Entity/DependentConfigTest.php index c5ba944..06189dd 100644 --- a/core/modules/config/tests/config_test/src/Entity/DependentConfigTest.php +++ b/core/modules/config/tests/config_test/src/Entity/DependentConfigTest.php @@ -18,8 +18,7 @@ * config_prefix = "dependent_config_test", * entity_keys = { * "id" = "id", - * "label" = "label", - * "status" = "status" + * "label" = "label" * }, * ) */ @@ -40,25 +39,45 @@ class DependentConfigTest extends ConfigEntityBase { public $label; /** - * Target configuration. + * The description. * - * @var \Drupal\config_test\ConfigTestInterface + * @var string + */ + public $description; + + /** + * Target configuration entity of type 'config_test'. + * + * @var string */ public $targetConfigId; /** + * Target configuration entity of type 'dependent_config_test'. + * + * @var string + */ + public $targetConfig2Id; + + /** * {@inheritdoc} */ public function calculateDependencies() { parent::calculateDependencies(); - + // Add a dependency to config_test config entity, if an ID is set. if (!empty($this->targetConfigId)) { $storage = $this->entityTypeManager()->getStorage('config_test'); if ($target = $storage->load($this->targetConfigId)) { $this->addDependency($target->getConfigDependencyKey(), $target->getConfigDependencyName()); } } - + // Add a dependency to dependent_config_test config entity, if an ID is set. + if (!empty($this->targetConfig2Id)) { + $storage = $this->entityTypeManager()->getStorage('dependent_config_test'); + if ($target = $storage->load($this->targetConfig2Id)) { + $this->addDependency($target->getConfigDependencyKey(), $target->getConfigDependencyName()); + } + } return $this; } @@ -77,6 +96,15 @@ public function onDependencyUpdating(array $dependencies) { } } } + if (!empty($this->targetConfig2Id)) { + $storage = $this->entityTypeManager()->getStorage('dependent_config_test'); + if ($target = $storage->load($this->targetConfig2Id)) { + if (!empty($dependency = $dependencies[$target->getConfigDependencyKey()][$target->getConfigDependencyName()])) { + $this->set('description', "Description for: {$dependency->label()}"); + $changed = TRUE; + } + } + } return $changed; } diff --git a/core/modules/config/tests/src/Kernel/ConfigDependencyTest.php b/core/modules/config/tests/src/Kernel/ConfigDependencyTest.php deleted file mode 100644 index b9ebf9a..0000000 --- a/core/modules/config/tests/src/Kernel/ConfigDependencyTest.php +++ /dev/null @@ -1,60 +0,0 @@ -container->get('entity_type.manager')->getStorage('config_test'); - - /** @var \Drupal\config_test\Entity\DependentConfigTest $dependency */ - $dependency = $storage->create(['id' => 'dependency', 'label' => 'Dependency']); - $dependency->save(); - - // Create a new 'dependent_config_test' config entity that has $dependency - // entity as dependency. - $config = DependentConfigTest::create([ - 'id' => 'config', - // The $config entity label reflects the dependency entity label. - 'label' => "Config of '{$dependency->label()}'", - 'targetConfigId' => 'dependency', - ]); - $config->save(); - - // Modify the dependency by setting a new label. - $dependency->set('label', 'Overridden')->save(); - - // Check that $config has automatically changed its label. - $this->assertSame("Config of 'Overridden'", DependentConfigTest::load('config')->label()); - - // Delete the dependency. - $dependency->delete(); - - // Check that $config has been deleted too. - $this->assertNull(DependentConfigTest::load('config')); - } - -} diff --git a/core/modules/config/tests/src/Kernel/ConfigEntityResolveDependencyTest.php b/core/modules/config/tests/src/Kernel/ConfigEntityResolveDependencyTest.php new file mode 100644 index 0000000..0a9dd0e --- /dev/null +++ b/core/modules/config/tests/src/Kernel/ConfigEntityResolveDependencyTest.php @@ -0,0 +1,77 @@ +container->get('entity_type.manager')->getStorage('config_test'); + + // This is the last entity in the dependency chain. + /** @var \Drupal\config_test\Entity\DependentConfigTest $last_dependency */ + $last_dependency = $storage->create(['id' => 'last_dependency', 'label' => 'Last dependency']); + $last_dependency->save(); + + // Create a new 'dependent_config_test' config entity that has + // $last_dependency entity as dependency. + $middle_dependency = DependentConfigTest::create([ + 'id' => 'middle_dependency', + // The $middle_dependency label reflects the last dependency entity label. + 'label' => "Config of '{$last_dependency->label()}'", + 'targetConfigId' => 'last_dependency', + ]); + $middle_dependency->save(); + + // Create a new 'dependent_config_test' that depends on $middle_dependency. + $config = DependentConfigTest::create([ + 'id' => 'config', + // The $config label reflects the middle dependency entity label. + 'description' => "Description for: {$middle_dependency->label()}", + 'targetConfig2Id' => 'middle_dependency', + ]); + $config->save(); + + // Check that initial values are correct set. + $this->assertSame('Last dependency', $last_dependency->label()); + $this->assertSame("Config of 'Last dependency'", $middle_dependency->label()); + $this->assertSame("Description for: Config of 'Last dependency'", $config->get('description')); + + // Modify the last dependency by setting a new label. + $last_dependency->set('label', 'Overridden')->save(); + + // Check that dependant entities were automatically updated. + $this->assertSame('Overridden', $last_dependency->label()); + $this->assertSame("Config of 'Overridden'", DependentConfigTest::load('middle_dependency')->label()); + $this->assertSame("Description for: Config of 'Overridden'", DependentConfigTest::load('config')->get('description')); + + // Delete the last dependency in chain. + $last_dependency->delete(); + + // Check that dependant entities were removed too. + $this->assertNull(DependentConfigTest::load('middle_dependency')); + $this->assertNull(DependentConfigTest::load('config')); + } + +}