diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php index 73b32ec..56a7e4b 100644 --- a/core/modules/system/src/Form/ModulesListForm.php +++ b/core/modules/system/src/Form/ModulesListForm.php @@ -8,6 +8,7 @@ namespace Drupal\system\Form; use Drupal\Component\Utility\SafeMarkup; +use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; use Drupal\Core\Config\PreExistingConfigException; use Drupal\Core\Config\UnmetDependenciesException; @@ -28,6 +29,7 @@ use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; +use Drupal\Core\Render\RendererInterface; /** * Provides module installation interface. @@ -103,6 +105,13 @@ class ModulesListForm extends FormBase { protected $permissionHandler; /** + * The module installer. + * + * @var \Drupal\Core\Extension\ModuleInstallerInterface + */ + protected $renderer; + + /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { @@ -116,7 +125,8 @@ public static function create(ContainerInterface $container) { $container->get('title_resolver'), $container->get('router.route_provider'), $container->get('plugin.manager.menu.link'), - $container->get('user.permissions') + $container->get('user.permissions'), + $container->get('renderer') ); } @@ -143,8 +153,10 @@ public static function create(ContainerInterface $container) { * The menu link manager. * @param \Drupal\user\PermissionHandlerInterface $permission_handler * The permission handler. + * @param \Drupal\Core\Render\RendererInterface $renderer + * The render service. */ - public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, AccessManagerInterface $access_manager, AccountInterface $current_user, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider, MenuLinkManagerInterface $menu_link_manager, PermissionHandlerInterface $permission_handler) { + public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, AccessManagerInterface $access_manager, AccountInterface $current_user, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider, MenuLinkManagerInterface $menu_link_manager, PermissionHandlerInterface $permission_handler, RendererInterface $renderer) { $this->moduleHandler = $module_handler; $this->moduleInstaller = $module_installer; $this->keyValueExpirable = $key_value_expirable; @@ -155,6 +167,7 @@ public function __construct(ModuleHandlerInterface $module_handler, ModuleInstal $this->routeProvider = $route_provider; $this->menuLinkManager = $menu_link_manager; $this->permissionHandler = $permission_handler; + $this->renderer = $renderer; } /** @@ -209,20 +222,23 @@ public function buildForm(array $form, FormStateInterface $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), - '#open' => TRUE, - '#theme' => 'system_modules_details', - '#header' => array( + $table = array( + '#type' => 'table', + '#header' => [ array('data' => $this->t('Installed'), 'class' => array('checkbox', 'visually-hidden')), array('data' => $this->t('Name'), 'class' => array('name', 'visually-hidden')), array('data' => $this->t('Description'), 'class' => array('description', 'visually-hidden', RESPONSIVE_PRIORITY_LOW)), - ), - '#attributes' => array('class' => array('package-listing')), + ], + ) + $form['modules'][$package]; + $form['modules'][$package] = [ + '#type' => 'details', + '#title' => $this->t($package), + '#open' => TRUE, // Ensure that the "Core" package comes first. '#weight' => $package == 'Core' ? -10 : NULL, - ); + '#attributes' => ['class' => ['package-listing']], + 'table' => $table, + ]; } // If testing modules are shown, collapse the corresponding package by @@ -259,40 +275,36 @@ public function buildForm(array $form, FormStateInterface $form_state) { */ protected function buildRow(array $modules, Extension $module, $distribution) { // Set the basic properties. - $row['#required'] = array(); + $row['#version'] = $module->info['version']; $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']; - // Generate link for module's help page. Assume that if a hook_help() // implementation exists then the module provides an overview page, rather // than checking to see if the page exists, which is costly. - $row['links']['help'] = array(); + $row_links['help'] = array(); if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) { - $row['links']['help'] = array( + $row_links['help'] = [ '#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#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(); + $row_links['permissions'] = []; if ($module->status && $this->currentUser->hasPermission('administer permissions') && $this->permissionHandler->moduleProvidesPermissions($module->getName())) { - $row['links']['permissions'] = array( + $row_links['permissions'] = [ '#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), '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(); + $row_links['configure'] = []; if ($module->status && isset($module->info['configure'])) { $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array(); if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) { @@ -314,7 +326,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) { $description = $this->titleResolver->getTitle($request, $route_object); } - $row['links']['configure'] = array( + $row_links['configure'] = [ '#type' => 'link', '#title' => $this->t('Configure'), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), @@ -324,14 +336,13 @@ protected function buildRow(array $modules, Extension $module, $distribution) { 'title' => $description, ), ), - ); + ]; } } // 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, ); @@ -425,6 +436,66 @@ protected function buildRow(array $modules, Extension $module, $distribution) { } } + // Set id for checkbox here so module label can reference it. + $id = Html::getClass('edit-modules-' . $module->info['package'] . '-' . $module->getName() . '-enable'); + + $row['enable'] += [ + '#id' => $id, + '#parents' => [ + 'modules', + $module->info['package'], + $module->getName(), 'enable', + ], + ]; + + // Add the module label and expand/collapse functionality. + $row['name'] = [ + '#type' => 'inline_template', + '#template' => '', + '#context' => [ + 'machine_name' => $module->getName(), + 'label_id' => $id, + 'module_name' => $module->info['name'], + ], + '#wrapper_attributes' => ['class' => ['module']], + ]; + + // Add the description, along with any modules it requires. + $description = '
'; + $description .= '
' . $this->t('Machine name: !key', ['!key' => $module->getName()]) . '
'; + if ($module->info['version'] || $row['#requires'] || $row['#required_by']) { + if ($module->info['version']) { + $description .= '
' . $this->t('Version: !module-version', ['!module-version' => $module->info['version']]) . '
'; + } + if ($row['#requires']) { + $description .= '
' . $this->t('Requires: !module-list', ['!module-list' => implode(', ', $row['#requires'])]) . '
'; + } + if ($row['#required_by']) { + $description .= '
' . $this->t('Required by: !module-list', ['!module-list' => implode(', ', $row['#required_by'])]) . '
'; + } + } + $description .= '
'; + + $links = ''; + foreach (['help', 'permissions', 'configure'] as $key) { + $links .= (isset($row_links[$key]) ? $this->renderer->render($row_links[$key]) : ''); + } + + if ($links) { + $description .= ''; + } + + $row['description'] = [ + '#type' => 'details', + '#title' => $this->t(' ' . $module->info['description'] . ''), + '#attributes' => ['id' => $id . '-description'], + '#description' => $description, + '#collapsed' => TRUE, + '#wrapper_attributes' => ['class' => ['description', 'expand']] + ]; + return $row; } @@ -457,6 +528,7 @@ protected function buildModuleList(FormStateInterface $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/system.admin.inc b/core/modules/system/system.admin.inc index 276e393..d186e5a 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -197,87 +197,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 functionality. - $id = Html::getUniqueId('module-' . $key); - $col2 = ''; - $row[] = array('class' => array('module'), 'data' => SafeMarkup::set($col2)); - - // Add the description, along with any modules it requires. - $description = ''; - $description .= '
'; - $description .= '
' . t('Machine name: !machine-name', array('!machine-name' => '' . $key . '')) . '
'; - if ($version || $requires || $required_by) { - 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 $link_type) { - $links .= drupal_render($module['links'][$link_type]); - } - if ($links) { - $description .= ' '; - } - $details = array( - '#type' => 'details', - '#title' => SafeMarkup::set(' ' . drupal_render($module['description']) . ''), - '#attributes' => array('id' => $module['enable']['#id'] . '-description'), - '#description' => $description, - ); - $col4 = drupal_render($details); - $row[] = array('class' => array('description', 'expand'), 'data' => $col4); - - $rows[] = $module['#attributes'] + array('data' => $row); - } - - $table = array( - '#type' => 'table', - '#header' => $form['#header'], - '#rows' => $rows, - ); - return drupal_render($table); -} - -/** * Returns HTML for a table of currently disabled modules. * * @param $variables diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 732e27b..8562da6 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -187,11 +187,6 @@ function system_theme() { 'confirm_form' => array( 'render element' => 'form', ), - 'system_modules_details' => array( - 'render element' => 'form', - 'file' => 'system.admin.inc', - 'function' => 'theme_system_modules_details', - ), 'system_modules_uninstall' => array( 'render element' => 'form', 'file' => 'system.admin.inc',