Issue #1993202 by fubhy, h3rj4n, Pancho: Convert system_modules_uninstall() to a Controller.
parent
788cb06d60
commit
04ef7cf88d
|
@ -8,27 +8,94 @@
|
|||
namespace Drupal\system\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\StringTranslation\TranslationManager;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Controller\ControllerInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
|
||||
/**
|
||||
* Builds a confirmation form to uninstall selected modules.
|
||||
*
|
||||
* Used internally from system_modules_uninstall().
|
||||
*/
|
||||
class ModulesUninstallConfirmForm extends ConfirmFormBase {
|
||||
class ModulesUninstallConfirmForm extends ConfirmFormBase implements ControllerInterface {
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The expirable key value store.
|
||||
*
|
||||
* @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
|
||||
*/
|
||||
protected $keyValueExpirable;
|
||||
|
||||
/**
|
||||
* The translation manager service.
|
||||
*
|
||||
* @var \Drupal\Core\StringTranslation\TranslationManager
|
||||
*/
|
||||
protected $translationManager;
|
||||
|
||||
/**
|
||||
* The request object.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* An array of modules to uninstall.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $modules = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('module_handler'),
|
||||
$container->get('keyvalue.expirable')->get('modules_uninstall'),
|
||||
$container->get('string_translation')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ModulesUninstallConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable
|
||||
* The key value expirable factory.
|
||||
* @param \Drupal\Core\StringTranslation\TranslationManager
|
||||
* The translation manager.
|
||||
*/
|
||||
public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable, TranslationManager $translation_manager) {
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->keyValueExpirable = $key_value_expirable;
|
||||
$this->translationManager = $translation_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return t('Confirm uninstall');
|
||||
return $this->translationManager->translate('Confirm uninstall');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return t('Uninstall');
|
||||
return $this->translationManager->translate('Uninstall');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +109,7 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return t('Would you like to continue with uninstalling the above?');
|
||||
return $this->translationManager->translate('Would you like to continue with uninstalling the above?');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,23 +121,28 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $modules
|
||||
* The array of modules.
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, $modules = array(), Request $request = NULL) {
|
||||
$uninstall = array();
|
||||
// Construct the hidden form elements and list items.
|
||||
foreach ($modules as $module => $value) {
|
||||
$info = drupal_parse_info_file(drupal_get_path('module', $module) . '/' . $module . '.info.yml');
|
||||
$uninstall[] = $info['name'];
|
||||
$form['uninstall'][$module] = array('#type' => 'hidden', '#value' => 1);
|
||||
public function buildForm(array $form, array &$form_state, Request $request = NULL) {
|
||||
// Store the request for use in the submit handler.
|
||||
$this->request = $request;
|
||||
|
||||
// Retrieve the list of modules from the key value store.
|
||||
$account = $request->attributes->get('account')->id();
|
||||
$this->modules = $this->keyValueExpirable->get($account);
|
||||
|
||||
// Prevent this page from showing when the module list is empty.
|
||||
if (empty($this->modules)) {
|
||||
return new RedirectResponse('/admin/modules/uninstall');
|
||||
}
|
||||
|
||||
$form['#confirmed'] = TRUE;
|
||||
$form['uninstall']['#tree'] = TRUE;
|
||||
$form['text'] = array('#markup' => '<p>' . t('The following modules will be completely uninstalled from your site, and <em>all data from these modules will be lost</em>!') . '</p>');
|
||||
$form['modules'] = array('#theme' => 'item_list', '#items' => $uninstall);
|
||||
$data = system_rebuild_module_data();
|
||||
$form['text']['#markup'] = '<p>' . $this->translationManager->translate('The following modules will be completely uninstalled from your site, and <em>all data from these modules will be lost</em>!') . '</p>';
|
||||
$form['modules'] = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => array_map(function ($module) use ($data) {
|
||||
return $data[$module]->info['name'];
|
||||
}, $this->modules),
|
||||
);
|
||||
|
||||
return parent::buildForm($form, $form_state, $request);
|
||||
}
|
||||
|
@ -79,6 +151,15 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
// Clear the key value store entry.
|
||||
$account = $this->request->attributes->get('account')->id();
|
||||
$this->keyValueExpirable->delete($account);
|
||||
|
||||
// Uninstall the modules.
|
||||
$this->moduleHandler->uninstall($this->modules);
|
||||
|
||||
drupal_set_message($this->translationManager->translate('The selected modules have been uninstalled.'));
|
||||
$form_state['redirect'] = 'admin/modules/uninstall';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Form\ModulesUninstallForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Form;
|
||||
|
||||
use Drupal\Core\Form\FormInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Controller\ControllerInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Provides a form for uninstalling modules.
|
||||
*/
|
||||
class ModulesUninstallForm implements FormInterface, ControllerInterface {
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The expirable key value store.
|
||||
*
|
||||
* @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
|
||||
*/
|
||||
protected $keyValueExpirable;
|
||||
|
||||
/**
|
||||
* The translation manager service.
|
||||
*
|
||||
* @var \Drupal\Core\StringTranslation\TranslationManager
|
||||
*/
|
||||
protected $translationManager;
|
||||
|
||||
/**
|
||||
* The request object.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('module_handler'),
|
||||
$container->get('keyvalue.expirable')->get('modules_uninstall'),
|
||||
$container->get('string_translation')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ModulesUninstallForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable
|
||||
* The key value expirable factory.
|
||||
* @param \Drupal\Core\StringTranslation\TranslationManager $translation_manager
|
||||
* The translation manager.
|
||||
*/
|
||||
public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable, TranslationManager $translation_manager) {
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->keyValueExpirable = $key_value_expirable;
|
||||
$this->translationManager = $translation_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormID() {
|
||||
return 'system_modules_uninstall';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, Request $request = NULL) {
|
||||
// Store the request for use in the submit handler.
|
||||
$this->request = $request;
|
||||
|
||||
// Make sure the install API is available.
|
||||
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
|
||||
// Get a list of disabled, installed modules.
|
||||
$modules = system_rebuild_module_data();
|
||||
$disabled = array_filter($modules, function ($module) {
|
||||
return empty($module->status) && drupal_get_installed_schema_version($module->name) > SCHEMA_UNINSTALLED;
|
||||
});
|
||||
|
||||
$form['modules'] = array();
|
||||
|
||||
// Only build the rest of the form if there are any modules available to
|
||||
// uninstall;
|
||||
if (empty($disabled)) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
$profile = drupal_get_profile();
|
||||
|
||||
// Sort all modules by their name.
|
||||
$this->moduleHandler->loadInclude('system', 'inc', 'system.admin');
|
||||
uasort($disabled, 'system_sort_modules_by_info_name');
|
||||
|
||||
$form['uninstall'] = array('#tree' => TRUE);
|
||||
foreach ($disabled as $module) {
|
||||
$name = $module->info['name'] ?: $module->name;
|
||||
$form['modules'][$module->name]['#module_name'] = $name;
|
||||
$form['modules'][$module->name]['name']['#markup'] = $name;
|
||||
$form['modules'][$module->name]['description']['#markup'] = $this->translationManager->translate($module->info['description']);
|
||||
|
||||
$form['uninstall'][$module->name] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->translationManager->translate('Uninstall @module module', array('@module' => $name)),
|
||||
'#title_display' => 'invisible',
|
||||
);
|
||||
|
||||
// All modules which depend on this one must be uninstalled first, before
|
||||
// we can allow this module to be uninstalled. (The installation profile
|
||||
// is excluded from this list.)
|
||||
foreach (array_keys($module->required_by) as $dependent) {
|
||||
if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
|
||||
$name = isset($modules[$dependent]->info['name']) ? $modules[$dependent]->info['name'] : $dependent;
|
||||
$form['modules'][$module->name]['#dependents'][] = $name;
|
||||
$form['uninstall'][$module->name]['#disabled'] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->translationManager->translate('Uninstall'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
// Form submitted, but no modules selected.
|
||||
if (!array_filter($form_state['values']['uninstall'])) {
|
||||
drupal_set_message($this->translationManager->translate('No modules selected.'), 'error');
|
||||
$form_state['redirect'] = 'admin/modules/uninstall';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
// Save all the values in an expirable key value store.
|
||||
$modules = $form_state['values']['uninstall'];
|
||||
$uninstall = array_keys(array_filter($modules));
|
||||
$account = $this->request->attributes->get('account')->id();
|
||||
$this->keyValueExpirable->setWithExpire($account, $uninstall, 60);
|
||||
|
||||
// Redirect to the confirm form.
|
||||
$form_state['redirect'] = 'admin/modules/uninstall/confirm';
|
||||
}
|
||||
}
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
use Drupal\system\DateFormatInterface;
|
||||
use Drupal\system\Form\ModulesInstallConfirmForm;
|
||||
use Drupal\system\Form\ModulesUninstallConfirmForm;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Drupal\Core\Datetime\DrupalDateTime;
|
||||
|
||||
/**
|
||||
* Menu callback; Provide the administration overview page.
|
||||
|
@ -763,113 +763,6 @@ function system_modules_submit($form, &$form_state) {
|
|||
$form_state['redirect'] = 'admin/modules';
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Form constructor for the uninstalling disabled modules form.
|
||||
*
|
||||
* @see system_menu()
|
||||
* @see system_modules_uninstall_validate()
|
||||
* @see system_modules_uninstall_submit()
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function system_modules_uninstall($form, $form_state = NULL) {
|
||||
// Make sure the install API is available.
|
||||
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
|
||||
// Display the confirm form if any modules have been submitted.
|
||||
if (!empty($form_state['storage']['uninstall']) && $modules = array_filter($form_state['storage']['uninstall'])) {
|
||||
// Contents of confirm form is injected here because already in form
|
||||
// building function.
|
||||
$confirm_form = new ModulesUninstallConfirmForm();
|
||||
return $confirm_form->buildForm($form, $form_state, $modules, Drupal::request());
|
||||
}
|
||||
|
||||
// Get a list of disabled, installed modules.
|
||||
$all_modules = system_rebuild_module_data();
|
||||
$disabled_modules = array();
|
||||
foreach ($all_modules as $name => $module) {
|
||||
if (empty($module->status) && drupal_get_installed_schema_version($name) > SCHEMA_UNINSTALLED) {
|
||||
$disabled_modules[$name] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
// Only build the rest of the form if there are any modules available to
|
||||
// uninstall.
|
||||
if (!empty($disabled_modules)) {
|
||||
$profile = drupal_get_profile();
|
||||
uasort($disabled_modules, 'system_sort_modules_by_info_name');
|
||||
$form['uninstall'] = array('#tree' => TRUE);
|
||||
foreach ($disabled_modules as $module) {
|
||||
$module_name = $module->info['name'] ? $module->info['name'] : $module->name;
|
||||
$form['modules'][$module->name]['#module_name'] = $module_name;
|
||||
$form['modules'][$module->name]['name']['#markup'] = $module_name;
|
||||
$form['modules'][$module->name]['description']['#markup'] = t($module->info['description']);
|
||||
$form['uninstall'][$module->name] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Uninstall @module module', array('@module' => $module_name)),
|
||||
'#title_display' => 'invisible',
|
||||
);
|
||||
// All modules which depend on this one must be uninstalled first, before
|
||||
// we can allow this module to be uninstalled. (The installation profile
|
||||
// is excluded from this list.)
|
||||
foreach (array_keys($module->required_by) as $dependent) {
|
||||
if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
|
||||
$dependent_name = isset($all_modules[$dependent]->info['name']) ? $all_modules[$dependent]->info['name'] : $dependent;
|
||||
$form['modules'][$module->name]['#required_by'][] = $dependent_name;
|
||||
$form['uninstall'][$module->name]['#disabled'] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Uninstall'),
|
||||
);
|
||||
$form['#action'] = url('admin/modules/uninstall/confirm');
|
||||
}
|
||||
else {
|
||||
$form['modules'] = array();
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the submitted uninstall form.
|
||||
*/
|
||||
function system_modules_uninstall_validate($form, &$form_state) {
|
||||
// Form submitted, but no modules selected.
|
||||
if (!count(array_filter($form_state['values']['uninstall']))) {
|
||||
drupal_set_message(t('No modules selected.'), 'error');
|
||||
return new RedirectResponse(url('admin/modules/uninstall', array('absolute' => TRUE)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the submitted uninstall form.
|
||||
*/
|
||||
function system_modules_uninstall_submit($form, &$form_state) {
|
||||
// Make sure the install API is available.
|
||||
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
|
||||
if (!empty($form['#confirmed'])) {
|
||||
// Call the uninstall routine for each selected module.
|
||||
$modules = array_keys($form_state['values']['uninstall']);
|
||||
module_uninstall($modules);
|
||||
drupal_set_message(t('The selected modules have been uninstalled.'));
|
||||
|
||||
$form_state['redirect'] = 'admin/modules/uninstall';
|
||||
}
|
||||
else {
|
||||
$form_state['storage'] = $form_state['values'];
|
||||
$form_state['rebuild'] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default page callback for batches.
|
||||
*/
|
||||
|
@ -1240,11 +1133,11 @@ function theme_system_modules_uninstall($variables) {
|
|||
// Display table.
|
||||
$rows = array();
|
||||
foreach (element_children($form['modules']) as $module) {
|
||||
if (!empty($form['modules'][$module]['#required_by'])) {
|
||||
$disabled_message = format_plural(count($form['modules'][$module]['#required_by']),
|
||||
if (!empty($form['modules'][$module]['#dependents'])) {
|
||||
$disabled_message = format_plural(count($form['modules'][$module]['#dependents']),
|
||||
'To uninstall @module, the following module must be uninstalled first: @required_modules',
|
||||
'To uninstall @module, the following modules must be uninstalled first: @required_modules',
|
||||
array('@module' => $form['modules'][$module]['#module_name'], '@required_modules' => implode(', ', $form['modules'][$module]['#required_by'])));
|
||||
array('@module' => $form['modules'][$module]['#module_name'], '@required_modules' => implode(', ', $form['modules'][$module]['#dependents'])));
|
||||
$disabled_message = '<div class="admin-requirements">' . $disabled_message . '</div>';
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -736,17 +736,14 @@ function system_menu() {
|
|||
);
|
||||
$items['admin/modules/uninstall'] = array(
|
||||
'title' => 'Uninstall',
|
||||
'page arguments' => array('system_modules_uninstall'),
|
||||
'access arguments' => array('administer modules'),
|
||||
'route_name' => 'system_modules_uninstall',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'file' => 'system.admin.inc',
|
||||
'weight' => 20,
|
||||
);
|
||||
$items['admin/modules/uninstall/confirm'] = array(
|
||||
'title' => 'Uninstall',
|
||||
'access arguments' => array('administer modules'),
|
||||
'route_name' => 'system_modules_uninstall_confirm',
|
||||
'type' => MENU_VISIBLE_IN_BREADCRUMB,
|
||||
'file' => 'system.admin.inc',
|
||||
);
|
||||
|
||||
// Configuration.
|
||||
|
|
|
@ -165,6 +165,20 @@ system_theme_settings_global:
|
|||
requirements:
|
||||
_permission: 'administer themes'
|
||||
|
||||
system_modules_uninstall:
|
||||
pattern: 'admin/modules/uninstall'
|
||||
defaults:
|
||||
_form: 'Drupal\system\Form\ModulesUninstallForm'
|
||||
requirements:
|
||||
_permission: 'administer modules'
|
||||
|
||||
system_modules_uninstall_confirm:
|
||||
pattern: 'admin/modules/uninstall/confirm'
|
||||
defaults:
|
||||
_form: 'Drupal\system\Form\ModulesUninstallConfirmForm'
|
||||
requirements:
|
||||
_permission: 'administer modules'
|
||||
|
||||
system_timezone:
|
||||
pattern: '/system/timezone'
|
||||
defaults:
|
||||
|
|
Loading…
Reference in New Issue