Problem/Motivation

$ drush pmu simplenews
simplenews is a required extension and can't be uninstalled. Reason: Fields type(s) in use.
There were no extensions that could be uninstalled.

This is at least bad DX.

Proposed resolution

Remaining tasks

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Berdir’s picture

It is, but I don't really know what to do about it.

You have to manually delete those fields first, then run cron, then you should be able to remove it. Assuming you do not have any subscribers left. Core is very strict on this right now.

Only option that would help a bit would be to move the fields to a simplenews_fields submodule, so you can uninstall simplenews, that would remove the fields, then remove the simplenews_fields modue.

Berdir’s picture

Priority: Normal » Critical

This seems like a problem we need to resolve before a stable version.

miro_dietiker’s picture

The origin of this problem is a core limitation. Core should fix this.

Until this happens, we can add a workaround:
- Add a destruction helper (a form that destroys fields and data)
- Link to it in configuration
- Mention it in module description so the text shows up in the module list: 'For uninstall go to configuration and hit "Prepare uninstall'".

mbovan’s picture

Status: Active » Needs review
FileSize
7.03 KB
43.58 KB

Implemented suggestions above and added tests.

The screenshot:
Prepare Simplenews uninstall page

mbovan’s picture

Probably we don't need to inherit from ConfigFormBase.

Berdir’s picture

Status: Needs review » Needs work

Thanks, good start.

  1. +++ b/simplenews.info.yml
    @@ -1,5 +1,5 @@
    -description: 'Send newsletters to subscribed email addresses.'
    +description: 'Send newsletters to subscribed email addresses. For uninstall go to configuration and hit <a href="/admin/config/services/simplenews/settings/uninstall"><em>Prepare uninstall</em></a>.'
    

    We can't hardcode a link like this, it won't work if you install in a Submodule. I'd just add a description like Configuration > Web services > Simplenews > Settings.

  2. +++ b/src/Form/PrepareUninstallForm.php
    @@ -0,0 +1,110 @@
    +    // Remove newsletter issues.
    +    $this->removeEntites('node', ['type' => 'simplenews_issue']);
    

    We don't need to delete nodes, just our field.

  3. +++ b/src/Form/PrepareUninstallForm.php
    @@ -0,0 +1,110 @@
    +    // Remove newsletters.
    +    $this->removeEntites('simplenews_newsletter');
    

    This is config, this should be deleted automatically.

  4. +++ b/src/Form/PrepareUninstallForm.php
    @@ -0,0 +1,110 @@
    +    $simplenews_fields = array_map(function ($field) {
    +      // Remove the field entity.
    +      $field->delete();
    +    }, array_merge($simplnews_issue_field, $simplenews_subscriber_field));
    

    That's a pretty complicated way to do it :)

    $field_config_storage->delete($simplenews_fields) should the same.

    both variables should use fieldS not field.

  5. +++ b/src/Form/PrepareUninstallForm.php
    @@ -0,0 +1,110 @@
    +    // Purge all deleted fields from the database.
    +    field_purge_batch(count($simplenews_fields));
    +
    

    the count is the amount of rows to delete, not fields. As discussed, you need to do this in a loop until that loadByProperties() at the beginning of that function, which you need to duplicate returns no results. A do while loop should work well for this.

  6. +++ b/src/Form/PrepareUninstallForm.php
    @@ -0,0 +1,110 @@
    +  protected function removeEntites($entity_type_id, array $properties = []) {
    +    $storage = $this->entityManager->getStorage($entity_type_id);
    +    $entities = $storage->loadByProperties($properties);
    +    $storage->delete($entities);
    

    I'm not sure if we should convert this into a batch already here, it probably would make sense because otherwise we'll likely not do it and then it will explode for people with a few hundred subscribers.

    Use mass-subscribe, generate 10k unique emails (php for loop, example-$i@example.org). Then try to hit that button.

  7. +++ b/src/Tests/SimplenewsUninstallTest.php
    @@ -0,0 +1,62 @@
    +    // Subscribe a user.
    +    $this->setUpSubscribers(1);
    

    Or locally, try generating 1k or 10 of them in here ;)

mbovan’s picture

Status: Needs work » Needs review
FileSize
7.17 KB
5.98 KB

Made the changes above...

Not sure if we should handle the case when user after "Prepare uninstall" wants to access (e.g.) Newsletter issues...

  • Berdir committed cc79c94 on 8.x-1.x authored by mbovan
    Issue #2418659 by mbovan: Fixed Can not uninstall: "Fields type(s) in...
Berdir’s picture

Status: Needs review » Fixed

Nice, tested manually, works quite well.

Opened #2594223: Mass subscribe is way slower than it was in 7.x.

Status: Fixed » Closed (fixed)

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