diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php index e523943..ef63b04 100644 --- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php @@ -330,7 +330,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) { foreach ($reasons as $reason) { $reason_message[] = implode(', ', $reason); } - throw new ModuleUninstallValidatorException(format_string('The following reasons prevents the modules from being uninstalled: @reasons', array( + throw new ModuleUninstallValidatorException(format_string('The following reasons prevent the modules from being uninstalled: @reasons', array( '@reasons' => implode('; ', $reason_message), ))); } diff --git a/core/modules/system/css/system.admin.css b/core/modules/system/css/system.admin.css index 1dd5da9..b4af1d0 100644 --- a/core/modules/system/css/system.admin.css +++ b/core/modules/system/css/system.admin.css @@ -157,7 +157,8 @@ small .admin-link:after { margin-bottom: 0; } .admin-requirements, -.admin-required { +.admin-required, +.validation-reasons { font-size: 0.9em; color: #666; } diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php index f72fa43..6755dca 100644 --- a/core/modules/system/src/Form/ModulesUninstallForm.php +++ b/core/modules/system/src/Form/ModulesUninstallForm.php @@ -7,12 +7,14 @@ namespace Drupal\system\Form; +use Drupal\Component\Utility\SafeMarkup; 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 Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\StringTranslation\TranslationInterface; /** * Provides a form for uninstalling modules. @@ -41,13 +43,21 @@ class ModulesUninstallForm extends FormBase { protected $keyValueExpirable; /** + * The string translation manager. + * + * @var \Drupal\Core\StringTranslation\TranslationInterface + */ + protected $stringTranslation; + + /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('module_handler'), $container->get('module_installer'), - $container->get('keyvalue.expirable')->get('modules_uninstall') + $container->get('keyvalue.expirable')->get('modules_uninstall'), + $container->get('string_translation') ); } @@ -60,11 +70,14 @@ public static function create(ContainerInterface $container) { * The module installer. * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable * The key value expirable factory. + * @param \Drupal\Core\StringTranslation\TranslationInterface $stringTranslation + * The string translation manager. */ - public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable) { + public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, TranslationInterface $stringTranslation) { $this->moduleHandler = $module_handler; $this->moduleInstaller = $module_installer; $this->keyValueExpirable = $key_value_expirable; + $this->stringTranslation = $stringTranslation; } /** @@ -110,7 +123,23 @@ public function buildForm(array $form, FormStateInterface $form_state) { ), ); - $form['modules'] = array(); + $profile = drupal_get_profile(); + + // Sort all modules by their name. + if (!empty($uninstallable)) { + uasort($uninstallable, 'system_sort_modules_by_info_name'); + $validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable)); + } + + $form['uninstall'] = [ + '#type' => 'table', + '#header' => [ + 'title' => $this->t('Name'), + 'description' => $this->t('Description'), + ], + '#empty' => $this->t('There are no items available to uninstall.'), + '#tableselect' => TRUE, + ]; // Only build the rest of the form if there are any modules available to // uninstall; @@ -118,41 +147,51 @@ public function buildForm(array $form, FormStateInterface $form_state) { return $form; } - $profile = drupal_get_profile(); - - // Sort all modules by their name. - uasort($uninstallable, 'system_sort_modules_by_info_name'); - $validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable)); - - $form['uninstall'] = array('#tree' => TRUE); foreach ($uninstallable as $module_key => $module) { - $name = $module->info['name'] ?: $module->getName(); - $form['modules'][$module->getName()]['#module_name'] = $name; - $form['modules'][$module->getName()]['name']['#markup'] = $name; - $form['modules'][$module->getName()]['description']['#markup'] = $this->t($module->info['description']); + // Define