diff --git a/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php b/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php index a090c67..651b2b4 100644 --- a/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php +++ b/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php @@ -117,19 +117,24 @@ public function buildForm(array $form, array &$form_state) { // Add a wrapper around every package. foreach (element_children($form['modules']) as $package) { - $form['modules'][$package] += array( - '#type' => 'details', - '#title' => $this->t($package), - '#theme' => 'system_modules_details', + $table = array( + '#type' => 'table', '#header' => array( array('data' => '' . $this->t('Installed') . '', 'class' => array('checkbox')), array('data' => $this->t('Name'), 'class' => array('name')), array('data' => $this->t('Description'), 'class' => array('description', RESPONSIVE_PRIORITY_LOW)), ), - '#attributes' => array('class' => array('package-listing')), + ) + $form['modules'][$package]; + + $form['modules'][$package] = array( + '#type' => 'details', + '#title' => $this->t($package), // Ensure that the "Core" package comes first. '#weight' => $package == 'Core' ? -10 : NULL, + '#attributes' => array('class' => array('package-listing')), + 'table' => $table, ); + } // Lastly, sort all packages by title. @@ -159,65 +164,13 @@ public function buildForm(array $form, array &$form_state) { */ protected function buildRow(array $modules, $module, $distribution) { // Set the basic properties. - $row['#required'] = array(); - $row['#requires'] = array(); - $row['#required_by'] = array(); - - $row['name']['#markup'] = $module->info['name']; - $row['description']['#markup'] = $this->t($module->info['description']); - $row['version']['#markup'] = $module->info['version']; - - // Add links for each module. - // Used when checking if a module implements a help page. - $help = $this->moduleHandler->moduleExists('help') ? drupal_help_arg() : FALSE; - - // Generate link for module's help page, if there is one. - $row['links']['help'] = array(); - if ($help && $module->status && in_array($module->name, $this->moduleHandler->getImplementations('help'))) { - if ($this->moduleHandler->invoke($module->name, 'help', array("admin/help#$module->name", $help))) { - $row['links']['help'] = array( - '#type' => 'link', - '#title' => $this->t('Help'), - '#href' => "admin/help/$module->name", - '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))), - ); - } - } - - // Generate link for module's permission, if the user has access to it. - $row['links']['permissions'] = array(); - if ($module->status && user_access('administer permissions') && in_array($module->name, $this->moduleHandler->getImplementations('permission'))) { - $row['links']['permissions'] = array( - '#type' => 'link', - '#title' => $this->t('Permissions'), - '#href' => 'admin/people/permissions', - '#options' => array('fragment' => 'module-' . $module->name, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))), - ); - } - - // Generate link for module's configuration page, if it has one. - $row['links']['configure'] = array(); - if ($module->status && isset($module->info['configure'])) { - if ($this->accessManager->checkNamedRoute($module->info['configure'], array(), \Drupal::currentUser())) { - $item = menu_get_item(trim($this->url($module->info['configure']), '/')); - $row['links']['configure'] = array( - '#type' => 'link', - '#title' => $this->t('Configure'), - '#route_name' => $module->info['configure'], - '#options' => array( - 'attributes' => array( - 'class' => array('module-link', 'module-link-configure'), - 'title' => $item['description'], - ), - ), - ); - } - } + $row['#version'] = $module->info['version']; + $row['#requires'] = isset($row['#requires']) ? $row['#requires'] : FALSE; + $row['#required_by'] = isset($row['#required_by']) ? $row['#required_by'] : FALSE; // Present a checkbox for installing and indicating the status of a module. $row['enable'] = array( '#type' => 'checkbox', - '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status, ); @@ -309,6 +262,111 @@ protected function buildRow(array $modules, $module, $distribution) { } } + // Set id for checkbox here so module label can reference it. + $id = drupal_html_class('edit-modules-' . $module->info['package'] . '-' . $module->name . '-enable'); + + $row['name']['#markup'] = $module->info['name']; + + $row['enable'] += array( + '#wrapper_attributes' => array( + 'class' => array('checkbox'), + ), + '#id' => $id, + '#parents' => array('modules', $module->info['package'], $module->name, 'enable'), + ); + + // Add the module label and expand/collapse functionalty. + $row['name'] = array( + '#prefix' => '', + '#wrapper_attributes' => array( + 'class' => array('module'), + ), + ); + + // Add the description, along with any modules it requires. + $description = ''; + if ($module->info['version'] || $row['#requires'] || $row['#required_by']) { + $description .= '
'; + if ($module->info['version']) { + $description .= '
' . t('Version: !module-version', array('!module-version' => $module->info['version'])) . '
'; + } + if ($row['#requires']) { + $description .= '
' . t('Requires: !module-list', array('!module-list' => implode(', ', $row['#requires']))) . '
'; + } + if ($row['#required_by']) { + $description .= '
' . t('Required by: !module-list', array('!module-list' => implode(', ', $row['#required_by']))) . '
'; + } + $description .= '
'; + } + + // Add links for each module. + // Used when checking if a module implements a help page. + $help = $this->moduleHandler->moduleExists('help') ? drupal_help_arg() : FALSE; + + // Generate link for module's help page, if there is one. + $links['help'] = array(); + if ($help && $module->status && in_array($module->name, $this->moduleHandler->getImplementations('help'))) { + if ($this->moduleHandler->invoke($module->name, 'help', array("admin/help#$module->name", $help))) { + $links['help'] = array( + '#type' => 'link', + '#title' => $this->t('Help'), + '#href' => "admin/help/$module->name", + '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))), + ); + } + } + + // Generate link for module's permission, if the user has access to it. + $links['permissions'] = array(); + if ($module->status && user_access('administer permissions') && in_array($module->name, $this->moduleHandler->getImplementations('permission'))) { + $links['permissions'] = array( + '#type' => 'link', + '#title' => $this->t('Permissions'), + '#href' => 'admin/people/permissions', + '#options' => array('fragment' => 'module-' . $module->name, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))), + ); + } + + // Generate link for module's configuration page, if it has one. + $links['configure'] = array(); + if ($module->status && isset($module->info['configure'])) { + if ($this->accessManager->checkNamedRoute($module->info['configure'], array(), \Drupal::currentUser())) { + $item = menu_get_item(trim($this->url($module->info['configure']), '/')); + $links['configure'] = array( + '#type' => 'link', + '#title' => $this->t('Configure'), + '#route_name' => $module->info['configure'], + '#options' => array( + 'attributes' => array( + 'class' => array('module-link', 'module-link-configure'), + 'title' => $item['description'], + ), + ), + ); + } + } + + $linkEntry = ''; + foreach (array('help', 'permissions', 'configure') as $key) { + $linkEntry .= (isset($links[$key]) ? drupal_render($links[$key]) : ''); + } + + if ($linkEntry) { + $description .= ' '; + } + + $row['description'] = array( + '#type' => 'details', + '#title' => ' ' . t($module->info['description']) . '', + '#attributes' => array('id' => $id . '-description'), + '#description' => $description, + '#collapsed' => TRUE, + ); + return $row; } @@ -341,6 +399,7 @@ protected function buildModuleList(array $form_state) { // First, build a list of all modules that were selected. foreach ($packages as $items) { + unset($items['table']); foreach ($items as $name => $checkbox) { if ($checkbox['enable'] && !$this->moduleHandler->moduleExists($name)) { $modules['install'][$name] = $data[$name]->info['name']; diff --git a/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php b/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php index 93bf906..5bf262e 100644 --- a/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php +++ b/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php @@ -87,30 +87,59 @@ public function buildForm(array $form, array &$form_state) { // Sort all modules by their name. uasort($uninstallable, 'system_sort_modules_by_info_name'); - $form['uninstall'] = array('#tree' => TRUE); + $form['modules'] = array( + '#type' => 'table', + '#header' => array( + $this->t('Uninstall'), + $this->t('Name'), + $this->t('Description'), + ), + '#empty' => $this->t('No modules are available to uninstall.'), + ); + foreach ($uninstallable 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->t($module->info['description']); - $form['uninstall'][$module->name] = array( + $module_name = $module->info['name'] ?: $module->name; + + $form['modules'][$module->name]['uninstall']['checkbox'] = array( '#type' => 'checkbox', - '#title' => $this->t('Uninstall @module module', array('@module' => $name)), + '#parent' => '$module->name', + '#title' => $this->t('Uninstall @module module', array('@module' => $module_name)), '#title_display' => 'invisible', + '#attributes' => array('name' => "uninstall[$module->name]") ); // 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.) + + $required_by = array(); 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]['#required_by'][] = $name; - $form['uninstall'][$module->name]['#disabled'] = TRUE; + $required_by[] = $name; + $form['modules'][$module->name]['uninstall']['checkbox']['#disabled'] = TRUE; } } - } + + $form['modules'][$module->name]['name'] = array( + '#markup' => '' . $module_name . '', + ); + + $disabled_message = ''; + if (!$required_by) { + $disabled_message = \Drupal::translation()->formatPlural(count($required_by), + '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' => $module_name, + '@required_modules' => implode(', ', $required_by), + )); + $disabled_message = '
' . $disabled_message . '
'; + } + $form['modules'][$module->name]['description']['#markup'] = $this->t($module->info['description']) . $disabled_message; + + } $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( @@ -125,8 +154,21 @@ public function buildForm(array $form, array &$form_state) { * {@inheritdoc} */ public function validateForm(array &$form, array &$form_state) { + // Get the selected modules. + $modules = $form_state['input']['uninstall']; + + $selected_modules = array(); + foreach ($modules as $module_name => $input) { + //var_dump($input); + if ($input === '1') { + $selected_modules[] = $module_name; + } + } + + $form_state['values']['selected_modules'] = $selected_modules; + // Form submitted, but no modules selected. - if (!array_filter($form_state['values']['uninstall'])) { + if (!$selected_modules) { drupal_set_message($this->t('No modules selected.'), 'error'); $form_state['redirect_route']['route_name'] = 'system.modules_uninstall'; } @@ -136,13 +178,15 @@ public function validateForm(array &$form, array &$form_state) { * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { + // Get the selected modules. + $selected_modules = $form_state['values']['selected_modules']; + // Save all the values in an expirable key value store. - $modules = $form_state['values']['uninstall']; - $uninstall = array_keys(array_filter($modules)); $account = $this->currentUser()->id(); - $this->keyValueExpirable->setWithExpire($account, $uninstall, 60); + $this->keyValueExpirable->setWithExpire($account, $selected_modules, 60); // Redirect to the confirm form. $form_state['redirect_route']['route_name'] = 'system.modules_uninstall_confirm'; } + } diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index 4a6005d..1963f67 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -328,86 +328,6 @@ function template_preprocess_status_report(&$variables) { } /** - * Returns HTML for the modules form. - * - * @param $variables - * An associative array containing: - * - form: A render element representing the form. - * - * @ingroup themeable - */ -function theme_system_modules_details($variables) { - $form = $variables['form']; - - // Individual table headers. - $rows = array(); - // Iterate through all the modules, which are children of this element. - foreach (element_children($form) as $key) { - // Stick the key into $module for easier access. - $module = $form[$key]; - // Create the row for the table. - $row = array(); - // Add the checkbox into the first cell. - unset($module['enable']['#title']); - $module['#requires'] = array_filter($module['#requires']); - $module['#required_by'] = array_filter($module['#required_by']); - - $requires = !empty($module['#requires']); - $required_by = !empty($module['#required_by']); - $version = !empty($module['version']['#markup']); - - $row[] = array('class' => array('checkbox'), 'data' => drupal_render($module['enable'])); - - // Add the module label and expand/collapse functionalty. - $col2 = ''; - $row[] = array('class' => array('module'), 'data' => $col2); - - // Add the description, along with any modules it requires. - $description = ''; - if ($version || $requires || $required_by) { - $description .= '
'; - if ($version) { - $description .= '
' . t('Version: !module-version', array('!module-version' => drupal_render($module['version']))) . '
'; - } - if ($requires) { - $description .= '
' . t('Requires: !module-list', array('!module-list' => implode(', ', $module['#requires']))) . '
'; - } - if ($required_by) { - $description .= '
' . t('Required by: !module-list', array('!module-list' => implode(', ', $module['#required_by']))) . '
'; - } - $description .= '
'; - } - $links = ''; - foreach (array('help', 'permissions', 'configure') as $key) { - $links .= drupal_render($module['links'][$key]); - } - if ($links) { - $description .= ' '; - } - $details = array( - '#type' => 'details', - '#title' => ' ' . drupal_render($module['description']) . '', - '#attributes' => array('id' => $module['enable']['#id'] . '-description'), - '#description' => $description, - '#collapsed' => TRUE, - ); - $col4 = drupal_render($details); - $row[] = array('class' => array('description', 'expand'), 'data' => $col4); - - $rows[] = $row; - } - - $table = array( - '#theme' => 'table', - '#header' => $form['#header'], - '#rows' => $rows, - ); - return drupal_render($table); -} - -/** * Returns HTML for a message about incompatible modules. * * @param $variables @@ -421,61 +341,6 @@ function theme_system_modules_incompatible($variables) { } /** - * Returns HTML for a table of currently disabled modules. - * - * @param $variables - * An associative array containing: - * - form: A render element representing the form. - * - * @ingroup themeable - */ -function theme_system_modules_uninstall($variables) { - $form = $variables['form']; - - // No theming for the confirm form. - if (isset($form['confirm'])) { - return drupal_render($form); - } - - // Table headers. - $header = array(t('Uninstall'), - t('Name'), - t('Description'), - ); - - // 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']), - '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']))); - $disabled_message = '
' . $disabled_message . '
'; - } - else { - $disabled_message = ''; - } - $rows[] = array( - array('data' => drupal_render($form['uninstall'][$module]), 'align' => 'center'), - '', - array('data' => drupal_render($form['modules'][$module]['description']) . $disabled_message, 'class' => array('description')), - ); - } - - $table = array( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows, - '#empty' => t('No modules are available to uninstall.'), - ); - $output = drupal_render($table); - $output .= drupal_render_children($form); - - return $output; -} - -/** * Returns HTML for the Appearance page. * * @param $variables diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 1657f9f..e366905 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -173,10 +173,6 @@ function system_theme() { 'variables' => array('message' => NULL), 'file' => 'system.admin.inc', ), - 'system_modules_uninstall' => array( - 'render element' => 'form', - 'file' => 'system.admin.inc', - ), 'status_report' => array( 'variables' => array('requirements' => NULL), 'file' => 'system.admin.inc',