diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php index 0719511e8e2..82c014c230e 100644 --- a/core/modules/system/src/Form/ModulesUninstallForm.php +++ b/core/modules/system/src/Form/ModulesUninstallForm.php @@ -2,13 +2,16 @@ namespace Drupal\system\Form; +use Drupal\Core\Extension\ExtensionLifecycle; use Drupal\Core\Extension\ModuleExtensionList; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleInstallerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface; +use Drupal\Core\Link; use Drupal\Core\Update\UpdateHookRegistry; +use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -154,6 +157,21 @@ class ModulesUninstallForm extends FormBase { $form['modules'][$module->getName()]['name']['#markup'] = $name; $form['modules'][$module->getName()]['description']['#markup'] = $this->t($module->info['description']); + $lifecycle = $module->info[ExtensionLifecycle::LIFECYCLE_IDENTIFIER]; + if ($lifecycle !== ExtensionLifecycle::STABLE && !empty($module->info[ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER])) { + $form['modules'][$module->getName()]['name']['#markup'] .= ' ' . Link::fromTextAndUrl('(' . $this->t('@lifecycle', ['@lifecycle' => ucfirst($lifecycle)]) . ')', + Url::fromUri($module->info[ExtensionLifecycle::LIFECYCLE_LINK_IDENTIFIER], [ + 'attributes' => + [ + 'class' => 'module-link--non-stable', + 'aria-label' => $this->t('View information on the @lifecycle status of the module @module', [ + '@lifecycle' => ucfirst($lifecycle), + '@module' => $module->info['name'], + ]), + ], + ]) + )->toString(); + } $form['uninstall'][$module->getName()] = [ '#type' => 'checkbox', '#title' => $this->t('Uninstall @module module', ['@module' => $name]), diff --git 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 index fdc7c44e7f7..c3ad6ea2a32 100644 --- 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 @@ -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 version: 8.y.x-unstable diff --git a/core/modules/system/tests/modules/system_status_obsolete_test/system_status_obsolete_test.info.yml b/core/modules/system/tests/modules/system_status_obsolete_test/system_status_obsolete_test.info.yml index 3b648efd2f2..62601cc3940 100644 --- a/core/modules/system/tests/modules/system_status_obsolete_test/system_status_obsolete_test.info.yml +++ 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.' package: Testing version: VERSION lifecycle: obsolete -lifecycle_link: 'https://i.giphy.com/media/100JPq1ylYXEti/giphy.webp' +lifecycle_link: 'https://example.com/obsolete' diff --git a/core/modules/system/tests/src/Functional/Module/UninstallTest.php b/core/modules/system/tests/src/Functional/Module/UninstallTest.php index 0fbb0fc2020..a5ecb9c2420 100644 --- a/core/modules/system/tests/src/Functional/Module/UninstallTest.php +++ b/core/modules/system/tests/src/Functional/Module/UninstallTest.php @@ -59,9 +59,29 @@ class UninstallTest extends BrowserTestBase { ]); $node->save(); + // Change the config directly to "install" non-stable modules. + $this->config('core.extension') + ->set('module.system_status_obsolete_test', 0) + ->set('module.deprecated_module', 0) + ->set('module.experimental_module_test', 0) + ->save(); + $this->rebuildAll(); + $this->drupalGet('admin/modules/uninstall'); $this->assertSession()->titleEquals('Uninstall | Drupal'); + // Check that the experimental module link was rendered correctly. + $this->assertSession()->elementExists('xpath', "//a[contains(@aria-label, 'View information on the Experimental status of the module Experimental Test')]"); + $this->assertSession()->elementExists('xpath', "//a[contains(@href, 'https://example.com/experimental')]"); + + // Check that the deprecated module link was rendered correctly. + $this->assertSession()->elementExists('xpath', "//a[contains(@aria-label, 'View information on the Deprecated status of the module Deprecated module')]"); + $this->assertSession()->elementExists('xpath', "//a[contains(@href, 'http://example.com/deprecated')]"); + + // Check that the obsolete module link was rendered correctly. + $this->assertSession()->elementExists('xpath', "//a[contains(@aria-label, 'View information on the Obsolete status of the module System obsolete status test')]"); + $this->assertSession()->elementExists('xpath', "//a[contains(@href, 'https://example.com/obsolete')]"); + foreach (\Drupal::service('extension.list.module')->getAllInstalledInfo() as $module => $info) { $field_name = "uninstall[$module]"; if (!empty($info['required'])) {