Problem/Motivation

When we uninstall a module we list which configuration entities will be "affected" by the uninstallation. Configuration entities will either be deleted or fixed (through implementations of ConfigEntityInterface::onDependencyRemoval(). Previously it was not possible to work out what would happen to each configuration entity but #2361775: Third party settings dependencies cause config entity deletion has opened up the possibility of that we can. Also #2416409: Delete dependent config entities that don't implement onDependencyRemoval() when a config entity is deleted is looking to implement dependency fixing / deletion on all config entity deletes so telling the user exactly what is going to happen in more important.

Proposed resolution

Add new functionality to the ConfigManager and ConfigDependencyManager to work out what is going to happen when a specified dependency (or set of dependencies in the case of multiple modules) is going to be removed.

Remaining tasks

Write patch
Review
Commit

User interface changes

The list of affected configuration on the module uninstall confirm screen will change.

API changes

Only additions.

Files: 
CommentFileSizeAuthor
#16 2420107.16.patch31.46 KBalexpott
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,882 pass(es). View
#16 14-16-interdiff.txt1.13 KBalexpott
#14 2420107.14.patch30.92 KBalexpott
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,908 pass(es). View
#14 9-14-interdiff.txt4.5 KBalexpott
#9 2420107.9.patch30.9 KBalexpott
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,746 pass(es). View
#9 7-9-interdiff.txt7.01 KBalexpott
#7 2420107.7.patch29.48 KBalexpott
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,719 pass(es), 4 fail(s), and 0 exception(s). View
#7 5-7-interdiff.txt1.1 KBalexpott
#5 2420107.5.patch29.3 KBalexpott
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,738 pass(es), 0 fail(s), and 2 exception(s). View
#1 2420107.1.patch7.04 KBalexpott
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 85,996 pass(es). View

Comments

alexpott’s picture

Status: Active » Needs review
FileSize
7.04 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 85,996 pass(es). View

Here's a patch that implements the functionality. Now need to use it and write tests.

alexpott’s picture

Wim Leers’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

This will allow for significantly enhanced usability/DX. The code looks beautiful and promising. :)

  1. +++ b/core/lib/Drupal/Core/Config/ConfigManager.php
    @@ -311,6 +321,68 @@ public function findConfigEntityDependentsAsEntities($type, array $names) {
    +      'theme' => []
    

    Should have a trailing comma.

  2. +++ b/core/lib/Drupal/Core/Config/ConfigManager.php
    @@ -311,6 +321,68 @@ public function findConfigEntityDependentsAsEntities($type, array $names) {
    +    // Try to fix any dependencies and find out what will happen to the
    +    // dependency graph.
    

    That sounds beautiful :)

    The body of the loop is a bit hard to follow for those less familiar with details of CMI though (at least for me). A few more high-level comments at for the three if-branches would be helpful.

  3. +++ b/core/lib/Drupal/Core/Config/ConfigManager.php
    @@ -311,6 +321,68 @@ public function findConfigEntityDependentsAsEntities($type, array $names) {
    +      if (empty($dependents) || reset($dependents)->uuid() == $first_uuid) {
    +        // We've looped around everything or all dependencies are fixable.
    

    I don't think the empty check is necessary, the while condition takes care of that?

alexpott’s picture

Priority: Major » Critical

Since this is blocking a critical and I would argue it is a critical in itself. Just listing which entities is affected on the module uninstall confirm form is not that helpful for users.

alexpott’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
29.3 KB
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,738 pass(es), 0 fail(s), and 2 exception(s). View

I've rewritten the config uninstaller and module list confirm form to use the new code and in doing that brought in necessary changes to the original code in #1 which makes an interdiff irrelevant.

Test coverage of both module uninstall and config uninstall has been expanded to cover as many of the possibilities I can think of. Additional test coverage has been added to ensure that methods work with content dependencies too even though it is unlikely the core will use the methods to do this.

Status: Needs review » Needs work

The last submitted patch, 5: 2420107.5.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
1.1 KB
29.48 KB
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,719 pass(es), 4 fail(s), and 0 exception(s). View

Fix the delete. This is due to dependency ordering that was working in the config uninstaller - that's why it is good that everything - config uninstall and config entity delete will use the same code path.

Status: Needs review » Needs work

The last submitted patch, 7: 2420107.7.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
7.01 KB
30.9 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,746 pass(es). View

Yep the order is significant - fixed my tests, doh :)

The patch also fixes some documentation around checking content dependencies.

cilefen’s picture

+++ b/core/lib/Drupal/Core/Config/ConfigManager.php
@@ -311,6 +287,69 @@ public function findConfigEntityDependentsAsEntities($type, array $names) {
+  public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names, $dry_run = TRUE) {

+1 for the function name.

alexpott’s picture

@cilefen yeah I just said what is does - but would be happy to have a better suggestion because it is long winded. And I didn't want to think that much about naming when the real mind-bending stuff is how to manage a dependency graph and changing it.

cilefen’s picture

@alexpott I wasn't judging! I agree with everything you said.

Wim Leers’s picture

Status: Needs review » Needs work

#4: Just listing which entities is affected on the module uninstall confirm form is not that helpful for users.
+1

#7: […] that's why it is good that everything - config uninstall and config entity delete will use the same code path. HURRAY!

#12: I think the only way to shorten the name is to have an intermediate value object. Which is probably not justified here.


I can basically only find nitpicks:

  1. +++ b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php
    @@ -126,6 +136,30 @@ public function findConfigEntityDependents($type, array $names);
    +   * @param bool $dry_run
    +   *   If set to FALSE the entities returned in the list of updates will
    +   *   modified. In order to make the changes the caller needs to save them. If
    +   *   set to TRUE the entities returned will not be modified.
    

    s/will modified/will be modified/

  2. +++ b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php
    @@ -126,6 +136,30 @@ public function findConfigEntityDependents($type, array $names);
    +   *   processed before deletes. The order of the deletes is significant and
    +   *   must be processed in the order.
    

    "in the returned order" ?

  3. +++ b/core/lib/Drupal/Core/Config/Entity/ConfigDependencyManager.php
    @@ -286,4 +286,20 @@ public function setData(array $data) {
    +   * @param $dependencies
    ...
    +  public function updateData($name, $dependencies) {
    

    Nit: Typehint to array?

  4. +++ b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
    @@ -145,43 +145,83 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +      '#title' => $this->t('Configuration deletes'),
    

    "deletes" or "deletions"?

alexpott’s picture

Status: Needs work » Needs review
FileSize
4.5 KB
30.92 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,908 pass(es). View

Fixed everything in #13.

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

Just one tiny remaining nit that can be fixed on commit: the #14.3 typehint is added to the code, but missing in the docs.

alexpott’s picture

FileSize
1.13 KB
31.46 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 86,882 pass(es). View

Fixing #15 - thanks.

catch’s picture

Status: Reviewed & tested by the community » Fixed
+++ b/core/lib/Drupal/Core/Config/ConfigManager.php
@@ -311,6 +287,69 @@ public function findConfigEntityDependentsAsEntities($type, array $names) {
+        // Ensure that the dependency has actually been fixed. it is possible

Just fixed missing capital letter here on commit.

Fantastic patch. Committed/pushed to 8.0.x, thanks!

  • catch committed 0bc927f on 8.0.x
    Issue #2420107 by alexpott: Determine which config entities can be fixed...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.