Problem/Motivation

#3258782: Do not display obsolete modules at admin/modules is removing obsolete modules from the admin/modules page. We'll still see obsolete modules at the admin/modules/uninstall page, which is good, since we should leave site owners a way to manually remove these from their site if needed.

However, obsolete modules have no special warnings or indications on this page. For example, here's a fake scenario where I installed the contrib quickedit module, but marked it obsolete for testing this:

/admin/modules/uninstall form where Quickedit is marked obsolete and you can't tell
(p.s. you can ignore the baseurl in the address bar, my local really is 9.4.x even though the path says "9_1". 😉)

The same is true for any of the non-stable module status values. They all get special treatment on the "Extend" form. But none of that goodness is shared on the "Uninstall" form.

Steps to reproduce

  1. Create a 9.4.x core test site.
  2. Install a contrib module.
  3. Enable it.
  4. Edit the .info.yml file to add lifecycle: obsolete and lifecycle_link: http://example.com/obsolete
  5. Visit the /admin/modules/uninstall form.
  6. Try to quickly spot the obsolete thing you're supposed to uninstall right away to silence the warning on your status report.

Proposed resolution

Add the fancy warnings on /admin/modules/uninstall so any non-stable module looks like they do on the Extend page. E.g. how an obsolete module used to appear:

before image with obsolete module listed

Perhaps it's also worth moving all such modules to the top of the form? TBD. At least group the obsolete ones at the top?
Nah, too much scope creep.

Remaining tasks

  1. Decide exactly how this should look and work.
  2. Implement it.
  3. Add test coverage.
  4. Reviews / refinements.
  5. RTBC.
  6. Followup to sharing the code block between both core/modules/system/src/Form/ModulesListForm.php and ModulesUninstallForm.php, See #6 and #7. #3270245: Fix translatability and share code for highlighting non-stable extensions between module install, uninstall and theme appearance forms
  7. Commit

User interface changes

Testing of patch in #10 on 9.4.x

Before

After

API changes

None.

Data model changes

Nope.

Release notes snippet

Probably not.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dww created an issue. See original summary.

dww’s picture

dww’s picture

dww’s picture

Issue summary: View changes

Updating the summary based on what I posted at #3258782-40: Do not display obsolete modules at admin/modules

dww’s picture

Title: Highlight obsolete modules on the admin/modules/uninstall form » Highlight non-stable modules on the admin/modules/uninstall form
Issue summary: View changes

Expanding scope to cover all non-stable lifecycle values. The code we want to share handles it all, so the title and summary should reflect that.

benjifisher’s picture

We discussed this issue briefly at #3266551: Drupal Usability Meeting 2022-03-04. That issue will have a link to the recording, and it already has a rough transcript.

We did not come up with any firm recommendations, but we do have two (incompatible) suggestions:

  1. Maintain some consistency between the install (List) and Uninstall pages. Currently, both have three columns (bulk operations, name, description). One groups by package, and the other does not.
  2. Add a column to the Uninstall page for the lifecycle, and enable click sorting. Maybe also add a column for package: sorting on that column would be similar to the grouping on the install page. By default, order by lifecycle and name. Can we allow sorting on the enabled/disabled status of the bulk operations column?

For the record, the participants at the usability meeting were

benjifisher, rkoller, AaronMcHale, andregp, Antoniya, ckrina, guilherme-rabelo, guilherme-rabelo, kimberlly_amaral, victoria-marina, shaal, tmaiochi, worldlinemine

quietone’s picture

The intention of this patch is to highlight the modules on the uninstall page the same as on the install page.

The issue summary suggests grouping all the obsolete modules as well or putting obsolete at the top of the page. That feels like too big a change and a divergence from the install form. That is, would we then want to group deprecated modules on the install form? I much prefer keeping this simple.

As for sharing the code block between both core/modules/system/src/Form/ModulesListForm.php and ModulesUninstallForm.php, this patch does not do that. I started to make a trait but then thought that should be another issue to look at creating something that will work for modules and themes, not just modules.

The last submitted patch, 7: 3266397-7-fail.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 7: 3266397-7.patch, failed testing. View results

murilohp’s picture

Thanks for the patch @quietone! I was reviewing it here and thanks to @alexpott, there's a way to trick the installation of a deprecated and an obsolete module without creating a new module and of course, avoiding the exceptions during the installation, check: #14.

I've updated the patch with the "trick" and removed the new test modules, let's see if the test pass now.

murilohp’s picture

Status: Needs work » Needs review
FileSize
3.74 KB

Forgot the interdiff

dww’s picture

Sweet, just came back here now that #3266308: %extensions placeholder not extension names printed on the Status report warning about obsolete extensions is in and found lots of great progress. Thanks, y'all! Also adding #3266449: Add a link to the Status report warning about obsolete extensions so site owners can fix the problem as related. I kinda think this one should land first, since if we add a link to this page but it's really hard to figure out where the obsolete thing is to uninstall, we haven't improved the UX that much. 😅 When $day_job settles down a bit, I'll give this a close review. Since I haven't yet added any code, I should be qualified to RTBC it...

quietone’s picture

Issue summary: View changes
Status: Needs review » Needs work
FileSize
8.7 KB
3.4 KB
12.37 KB
5.37 KB

Tested with the patch in #10 to get up to date screenshots in the IS. I then successfully uninstalled all three test modules.

And for some odd reason this is not testing experimental on the uninstall form. I reckon that could be added. Setting NW for that

quietone’s picture

Status: Needs work » Needs review
FileSize
1.74 KB
5.47 KB

@murilohp, thanks for change to use config.

Added a test for experimental. None of the existing experimental modules have a lifecycle_link so there is no need to test the link. I guess it could be added but doing so may alter existing tests and I didn't want to go down that route.

Status: Needs review » Needs work

The last submitted patch, 14: 3266397-14.patch, failed testing. View results

dww’s picture

Issue tags: +Needs followup

I'm not totally thrilled about duplicating the code here instead of reusing from the main modules page, but I hear you in #7 about a follow-up to unify this with the theme code, too. Tagging for the follow-up.

Code review:

  1. +++ b/core/modules/system/src/Form/ModulesUninstallForm.php
    @@ -154,6 +157,21 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +      if ($lifecycle !== ExtensionLifecycle::STABLE && !empty($module->info[ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER])) {
    

    I guess we have to depend on the lifecycle_link being defined for this to work at all? I think we have an exception thrown somewhere if you define a non-stable lifecycle without a link, right?

    If not, it's too bad this requires a link. It'd still be nice to get a warning icon and something to indicate it's non-stable without needing the link. Probably out of scope. ;)

  2. +++ b/core/modules/system/src/Form/ModulesUninstallForm.php
    @@ -154,6 +157,21 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +        $form['modules'][$module->getName()]['name']['#markup'] .= ' ' . Link::fromTextAndUrl('(' . $this->t('@lifecycle', ['@lifecycle' => ucfirst($lifecycle)]) . ')',
    

    This is copied from elsewhere, but how can anyone translate these lifecycle terms like this? If all we get is a @lifecycle placeholder that's always forced into the underlying English version, why bother with t() at all?

    Seems like we really want ExtensionLifecycle::getLabel($lifecycle) or something that does:

    
    switch($lifecycle) {
      case static::STABLE:
        return t('Stable');
    
      case static::OBSOLETE:
        return t('Obsolete');
    ...
    }
    
  3. +++ b/core/modules/system/src/Form/ModulesUninstallForm.php
    @@ -154,6 +157,21 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +                    '@lifecycle' => ucfirst($lifecycle),
    

    This would be another spot to use the ExtensionLifecycle::getLabel() method proposed above.

  4. +++ b/core/modules/system/src/Form/ModulesUninstallForm.php
    --- a/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml
    +++ b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml
    
    +++ b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml
    +++ b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml
    @@ -3,4 +3,5 @@ type: module
    
    @@ -3,4 +3,5 @@ type: module
     description: 'Module in the experimental package to test experimental functionality.'
     package: Core (Experimental)
     lifecycle: experimental
    +lifecycle_link: https://example.com/experimental
    

    Here's a lifecycle_link for "experimental_module_test". I'm confused by comment #14 in the issue and the code comments in the test below...

    Update: looks like most of these use http, so we should probably be the same here.

  5. +++ b/core/modules/system/tests/modules/system_status_obsolete_test/system_status_obsolete_test.info.yml
    @@ -4,4 +4,4 @@ description: 'Support module for testing an obsolete module extension.'
    +lifecycle_link: 'http://example.com/obsolete'
    

    Nit: https? 🤓 (for consistency, and as a general best practice).

    Update: Got to the end of the patch, looks like the others are mostly http...

  6. +++ b/core/modules/system/tests/src/Functional/Module/UninstallTest.php
    @@ -59,9 +59,27 @@ public function testUninstallPage() {
    +    // Change the config directly to "install" an obsolete and a deprecated
    +    // module.
    

    Comment should now include "experimental", too.

  7. +++ b/core/modules/system/tests/src/Functional/Module/UninstallTest.php
    @@ -59,9 +59,27 @@ public function testUninstallPage() {
    +    $this->config('core.extension')->set('module.system_status_obsolete_test', 0)->save();
    +    $this->config('core.extension')->set('module.deprecated_module', 0)->save();
    +    $this->config('core.extension')->set('module.experimental_module_test', 0)->save();
    

    Probably irrelevant, but can we chain these and only call save()once? E.g., does this work?

    $this->config('core.extension')
      ->set('module.system_status_obsolete_test', 0)
      ->set('module.deprecated_module', 0)
      ->set('module.experimental_module_test', 0)
      ->save();
    

    ?

  8. +++ b/core/modules/system/tests/src/Functional/Module/UninstallTest.php
    @@ -59,9 +59,27 @@ public function testUninstallPage() {
    +    // Check the experimental module, which does not have a lifecycle_link.
    +    $this->assertSession()->elementExists('xpath', "//a[contains(@aria-label, 'View information on the Experimental status of the module Experimental Test')]");
    

    I think this comment doesn't match reality anymore. Especially since the assertion is an xpath looking for an a tag. Can't this check for https://example.com/experimental too like all the others?

Thanks!

dww’s picture

quietone’s picture

Status: Needs work » Needs review
FileSize
3.13 KB
5.49 KB

#16. Doing the simplest items for now.
1 - 3. To do
4. See comment below for #8.
5. Now https in obsolete module.
6. Done. I used 'non-stable' for all of them.
7. Yes, that seems to work. So fixed.
8. Oh that is a hoot. The presence of the lifecycle_link in the experimental module is left over from my testing. I did not intend to include that. However, here we are it didn't cause other test failures so let's leave it for now.

quietone’s picture

1. I do like that the lifecycle_link means there is a page where folks can get some more information. I lean more to enforcing that on all non-stable modules, not just deprecated and obsolete. I don't know why it is that way and I have never looked for why experimental does not need a lifecycle_link.
2, 3 Yes, copied from ModulesListForm. Perhaps this is something for another issue?

@dww, And a belated, thanks for the prompt review!

dww’s picture

Thanks for addressing all that so promptly, @quietone!

1. I like having the link, too. My only point was that it'd be nice if the obsolete warning and icon appeared, even if there was no lifecycle link. But I agree that's out of scope for now.

2-3: I rarely get the scope decisions right. 😅 I think it's currently broken on ModulesListForm. We're copying the broken here. We could either:
a. Fix it as part of #3270245: Fix translatability and share code for highlighting non-stable extensions between module install, uninstall and theme appearance forms
b. Open yet another follow-up to fix this in ModulesListForm, and then depending on when that issue lands relative to this one, we re-roll this one to Do It Right(tm) 😉 or expand the scope of the follow-up to fix it in both places.

4-8: Great, thanks!

quietone’s picture

Your idea, option 2-3a, is the way to go. That is the shared code and it makes to touch it just once.

dww’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

Re: #21: In that case, re-titled #3270245: Fix translatability and share code for highlighting non-stable extensions between module install, uninstall and theme appearance forms to expand the scope a bit and reclassified as a bug.

I manually tested. Was about to post the after screenshot but realized @quietone already did that in #13.

I don't love committing this with a known bug, but it's an existing known bug and the patch here is definitely an improvement over not having anything to indicate non-stable on this form. We've got the follow-up in place to fix the known bug in both/all places it exists.

Nothing else to complain about with the patch. The summary is up to date and accurate. Hence, RTBC.

Thanks!
-Derek

AaronMcHale’s picture

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 18: 3266397-18.patch, failed testing. View results

quietone’s picture

Status: Needs work » Reviewed & tested by the community

Random failure Drupal\Tests\quickedit\FunctionalJavascript\QuickEditFileTest::testRemove
Restoring RTBC

catch credited Antoniya.

catch credited andregp.

catch credited ckrina.

catch credited rkoller.

catch’s picture

I lean more to enforcing that on all non-stable modules, not just deprecated and obsolete. I don't know why it is that way and I have never looked for why experimental does not need a lifecycle_link.

This is because we started with experimental: true some time ago before adding lifecycle/lifecycle_link.

Adding credit for usability meeting participants.

  • catch committed 62c91e9 on 10.0.x
    Issue #3266397 by quietone, murilohp, dww, AaronMcHale, benjifisher,...

  • catch committed 9220170 on 9.4.x
    Issue #3266397 by quietone, murilohp, dww, AaronMcHale, benjifisher,...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.0.x and cherry-picked to 9.4.x.

Agreed with handling consolidation and fixing the translation issue in the follow-up.

AaronMcHale’s picture

Status: Fixed » Closed (fixed)

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