Issue #1990544 by fubhy, Pancho, h3rj4n, dawehner: Convert system_modules() to a Controller.
parent
862b4d6347
commit
8d693aded0
|
@ -114,6 +114,19 @@ class Connection extends DatabaseConnection {
|
|||
return $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize() {
|
||||
// Cleanup the connection, much like __destruct() does it as well.
|
||||
if ($this->needsCleanup) {
|
||||
$this->nextIdDelete();
|
||||
}
|
||||
$this->needsCleanup = FALSE;
|
||||
|
||||
return parent::serialize();
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
if ($this->needsCleanup) {
|
||||
$this->nextIdDelete();
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Form\ModulesInstallConfirmForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Builds a confirmation form for required modules.
|
||||
*
|
||||
* Used internally in system_modules().
|
||||
*/
|
||||
class ModulesInstallConfirmForm extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return t('Some required modules must be enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return t('Continue');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelPath() {
|
||||
return 'admin/modules';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return t('Would you like to continue with the above?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormID() {
|
||||
return 'system_modules_confirm_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param array $modules
|
||||
* The array of modules.
|
||||
* @param array $storage
|
||||
* Temporary storage of module dependency information.
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, $modules = array(), $storage = array(), Request $request = NULL) {
|
||||
$items = array();
|
||||
|
||||
$form['validation_modules'] = array('#type' => 'value', '#value' => $modules);
|
||||
$form['status']['#tree'] = TRUE;
|
||||
|
||||
foreach ($storage['more_required'] as $info) {
|
||||
$t_argument = array(
|
||||
'@module' => $info['name'],
|
||||
'@required' => implode(', ', $info['requires']),
|
||||
);
|
||||
$items[] = format_plural(count($info['requires']), 'You must enable the @required module to install @module.', 'You must enable the @required modules to install @module.', $t_argument);
|
||||
}
|
||||
|
||||
foreach ($storage['missing_modules'] as $name => $info) {
|
||||
$t_argument = array(
|
||||
'@module' => $name,
|
||||
'@depends' => implode(', ', $info['depends']),
|
||||
);
|
||||
$items[] = format_plural(count($info['depends']), 'The @module module is missing, so the following module will be disabled: @depends.', 'The @module module is missing, so the following modules will be disabled: @depends.', $t_argument);
|
||||
}
|
||||
|
||||
$form['modules'] = array('#theme' => 'item_list', '#items' => $items);
|
||||
|
||||
return parent::buildForm($form, $form_state, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Form\ModulesListConfirmForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Form;
|
||||
|
||||
use Drupal\Core\Controller\ControllerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Builds a confirmation form for enabling modules with dependencies.
|
||||
*/
|
||||
class ModulesListConfirmForm 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 associative list of modules to enable or disable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $modules = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('module_handler'),
|
||||
$container->get('keyvalue.expirable')->get('module_list'),
|
||||
$container->get('string_translation')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ModulesListConfirmForm 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 $this->translationManager->translate('Some required modules must be enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelPath() {
|
||||
return 'admin/modules';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->translationManager->translate('Continue');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return $this->translationManager->translate('Would you like to continue with the above?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormID() {
|
||||
return 'system_modules_confirm_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, Request $request = NULL) {
|
||||
$account = $request->attributes->get('account')->id();
|
||||
$this->modules = $this->keyValueExpirable->get($account);
|
||||
|
||||
// Redirect to the modules list page if the key value store is empty.
|
||||
if (!$this->modules) {
|
||||
return new RedirectResponse(url($this->getCancelPath(), array('absolute' => TRUE)));
|
||||
}
|
||||
|
||||
// Store the request for use in the submit handler.
|
||||
$this->request = $request;
|
||||
|
||||
$items = array();
|
||||
// Display a list of required modules that have to be installed as well but
|
||||
// were not manually selected.
|
||||
foreach ($this->modules['dependencies'] as $module => $dependencies) {
|
||||
$items[] = format_plural(count($dependencies), 'You must enable the @required module to install @module.', 'You must enable the @required modules to install @module.', array(
|
||||
'@module' => $this->modules['enable'][$module],
|
||||
'@required' => implode(', ', $dependencies),
|
||||
));
|
||||
}
|
||||
|
||||
foreach ($this->modules['missing'] as $name => $dependents) {
|
||||
$items[] = format_plural(count($dependents), 'The @module module is missing, so the following module will be disabled: @depends.', 'The @module module is missing, so the following modules will be disabled: @depends.', array(
|
||||
'@module' => $name,
|
||||
'@depends' => implode(', ', $dependents),
|
||||
));
|
||||
}
|
||||
|
||||
$form['message'] = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
);
|
||||
|
||||
return parent::buildForm($form, $form_state, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
// Remove the key value store entry.
|
||||
$account = $this->request->attributes->get('account')->id();
|
||||
$this->keyValueExpirable->delete($account);
|
||||
|
||||
// Gets list of modules prior to install process.
|
||||
$before = $this->moduleHandler->getModuleList();
|
||||
|
||||
// Installs, enables, and disables modules.
|
||||
if (!empty($this->modules['enable'])) {
|
||||
$this->moduleHandler->enable(array_keys($this->modules['enable']));
|
||||
}
|
||||
if (!empty($this->modules['disable'])) {
|
||||
$this->moduleHandler->disable(array_keys($this->modules['disable']));
|
||||
}
|
||||
|
||||
// Gets module list after install process, flushes caches and displays a
|
||||
// message if there are changes.
|
||||
if ($before != $this->moduleHandler->getModuleList()) {
|
||||
drupal_flush_all_caches();
|
||||
drupal_set_message($this->translationManager->translate('The configuration options have been saved.'));
|
||||
}
|
||||
|
||||
$form_state['redirect'] = $this->getCancelPath();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,458 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Form\ModulesListForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Form;
|
||||
|
||||
use Drupal\Core\Controller\ControllerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationManager;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Provides module enable/disable interface.
|
||||
*
|
||||
* The list of modules gets populated by module.info.yml files, which contain
|
||||
* each module's name, description, and information about which modules it
|
||||
* requires. See drupal_parse_info_file() for info on module.info.yml
|
||||
* descriptors.
|
||||
*/
|
||||
class ModulesListForm 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('module_list'),
|
||||
$container->get('string_translation')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ModulesListForm 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 getFormID() {
|
||||
return 'system_modules';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, Request $request = NULL) {
|
||||
require_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
$distribution = check_plain(drupal_install_profile_distribution_name());
|
||||
|
||||
// Include system.admin.inc so we can use the sort callbacks.
|
||||
$this->moduleHandler->loadInclude('system', 'inc', 'system.admin');
|
||||
|
||||
// Store the request for use in the submit handler.
|
||||
$this->request = $request;
|
||||
|
||||
$form['filters'] = array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array(
|
||||
'class' => array('table-filter', 'js-show'),
|
||||
),
|
||||
);
|
||||
|
||||
$form['filters']['text'] = array(
|
||||
'#type' => 'search',
|
||||
'#title' => $this->translationManager->translate('Search'),
|
||||
'#size' => 30,
|
||||
'#placeholder' => $this->translationManager->translate('Enter module name'),
|
||||
'#attributes' => array(
|
||||
'class' => array('table-filter-text'),
|
||||
'data-table' => '#system-modules',
|
||||
'autocomplete' => 'off',
|
||||
'title' => $this->translationManager->translate('Enter a part of the module name or description to filter by.'),
|
||||
),
|
||||
);
|
||||
|
||||
// Sort all modules by their names.
|
||||
$modules = system_rebuild_module_data();
|
||||
uasort($modules, 'system_sort_modules_by_info_name');
|
||||
|
||||
// Iterate over each of the modules.
|
||||
$form['modules']['#tree'] = TRUE;
|
||||
foreach ($modules as $filename => $module) {
|
||||
if (empty($module->info['hidden'])) {
|
||||
$package = $module->info['package'];
|
||||
$form['modules'][$package][$filename] = $this->buildRow($modules, $module, $distribution);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a wrapper around every package.
|
||||
foreach (element_children($form['modules']) as $package) {
|
||||
$form['modules'][$package] += array(
|
||||
'#type' => 'details',
|
||||
'#title' => $this->translationManager->translate($package),
|
||||
'#theme' => 'system_modules_details',
|
||||
'#header' => array(
|
||||
array('data' => '<span class="element-invisible">' . $this->translationManager->translate('Enabled') . '</span>', 'class' => array('checkbox')),
|
||||
array('data' => $this->translationManager->translate('Name'), 'class' => array('name')),
|
||||
array('data' => $this->translationManager->translate('Description'), 'class' => array('description', RESPONSIVE_PRIORITY_LOW)),
|
||||
),
|
||||
// Ensure that the "Core" package comes first.
|
||||
'#weight' => $package == 'Core' ? -10 : NULL,
|
||||
);
|
||||
}
|
||||
|
||||
// Lastly, sort all packages by title.
|
||||
uasort($form['modules'], 'element_sort_by_title');
|
||||
|
||||
$form['#attached']['library'][] = array('system', 'drupal.system.modules');
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->translationManager->translate('Save configuration'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a table row for the system modules page.
|
||||
*
|
||||
* @param array $modules
|
||||
* The list existing modules.
|
||||
* @param object $module
|
||||
* The module for which to build the form row.
|
||||
* @param $distribution
|
||||
*
|
||||
* @return array
|
||||
* The form row for the given module.
|
||||
*/
|
||||
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->translationManager->translate($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->translationManager->translate('Help'),
|
||||
'#href' => "admin/help/$module->name",
|
||||
'#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->translationManager->translate('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->translationManager->translate('Permissions'),
|
||||
'#href' => 'admin/people/permissions',
|
||||
'#options' => array('fragment' => 'module-' . $module->name, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->translationManager->translate('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 (($configure = menu_get_item($module->info['configure'])) && $configure['access']) {
|
||||
$row['links']['configure'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => $this->translationManager->translate('Configure'),
|
||||
'#href' => $configure['href'],
|
||||
'#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $configure['description'])),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Present a checkbox for installing and indicating the status of a module.
|
||||
$row['enable'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->translationManager->translate('Enable'),
|
||||
'#default_value' => (bool) $module->status,
|
||||
);
|
||||
|
||||
// Disable the checkbox for required modules.
|
||||
if (!empty($module->info['required'])) {
|
||||
// Used when displaying modules that are required by the installation profile
|
||||
$row['enable']['#disabled'] = TRUE;
|
||||
$row['#required_by'][] = $distribution . (!empty($module->info['explanation']) ? ' ('. $module->info['explanation'] .')' : '');
|
||||
}
|
||||
|
||||
// Check the compatibilities.
|
||||
$compatible = TRUE;
|
||||
$status = '';
|
||||
|
||||
// Check the core compatibility.
|
||||
if ($module->info['core'] != DRUPAL_CORE_COMPATIBILITY) {
|
||||
$compatible = FALSE;
|
||||
$status .= $this->translationManager->translate('This version is not compatible with Drupal !core_version and should be replaced.', array(
|
||||
'!core_version' => DRUPAL_CORE_COMPATIBILITY,
|
||||
));
|
||||
}
|
||||
|
||||
// Ensure this module is compatible with the currently installed version of PHP.
|
||||
if (version_compare(phpversion(), $module->info['php']) < 0) {
|
||||
$compatible = FALSE;
|
||||
$required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : '');
|
||||
$status .= $this->translationManager->translate('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array(
|
||||
'@php_required' => $required,
|
||||
'!php_version' => phpversion(),
|
||||
));
|
||||
}
|
||||
|
||||
// If this module is not compatible, disable the checkbox.
|
||||
if (!$compatible) {
|
||||
$row['enable']['#disabled'] = TRUE;
|
||||
$row['description'] = array(
|
||||
'#theme' => 'system_modules_incompatible',
|
||||
'#message' => $status,
|
||||
);
|
||||
}
|
||||
|
||||
// If this module requires other modules, add them to the array.
|
||||
foreach ($module->requires as $dependency => $version) {
|
||||
if (!isset($modules[$dependency])) {
|
||||
$row['#requires'][$dependency] = $this->translationManager->translate('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency)));
|
||||
$row['enable']['#disabled'] = TRUE;
|
||||
}
|
||||
// Only display visible modules.
|
||||
elseif (empty($modules[$dependency]->hidden)) {
|
||||
$name = $modules[$dependency]->info['name'];
|
||||
// Disable the module's checkbox if it is incompatible with the
|
||||
// dependency's version.
|
||||
if ($incompatible_version = drupal_check_incompatibility($version, str_replace(DRUPAL_CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
|
||||
$row['#requires'][$dependency] = $this->translationManager->translate('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
|
||||
'@module' => $name . $incompatible_version,
|
||||
'@version' => $modules[$dependency]->info['version'],
|
||||
));
|
||||
$row['enable']['#disabled'] = TRUE;
|
||||
}
|
||||
// Disable the checkbox if the dependency is incompatible with this
|
||||
// version of Drupal core.
|
||||
elseif ($modules[$dependency]->info['core'] != DRUPAL_CORE_COMPATIBILITY) {
|
||||
$row['#requires'][$dependency] = $this->translationManager->translate('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
|
||||
'@module' => $name,
|
||||
));
|
||||
$row['enable']['#disabled'] = TRUE;
|
||||
}
|
||||
elseif ($modules[$dependency]->status) {
|
||||
$row['#requires'][$dependency] = $this->translationManager->translate('@module', array('@module' => $name));
|
||||
}
|
||||
else {
|
||||
$row['#requires'][$dependency] = $this->translationManager->translate('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this module is required by other modules, list those, and then make it
|
||||
// impossible to disable this one.
|
||||
foreach ($module->required_by as $dependent => $version) {
|
||||
if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) {
|
||||
if ($modules[$dependent]->status == 1 && $module->status == 1) {
|
||||
$row['#required_by'][$dependent] = $this->translationManager->translate('@module', array('@module' => $modules[$dependent]->info['name']));
|
||||
$row['enable']['#disabled'] = TRUE;
|
||||
}
|
||||
else {
|
||||
$row['#required_by'][$dependent] = $this->translationManager->translate('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $modules[$dependent]->info['name']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for building a list of modules to enable or disable.
|
||||
*
|
||||
* @param array $form_state
|
||||
* The form state array.
|
||||
*
|
||||
* @return array
|
||||
* An array of modules to disable/enable and their dependencies.
|
||||
*/
|
||||
protected function buildModuleList(array $form_state) {
|
||||
$packages = $form_state['values']['modules'];
|
||||
|
||||
// Build a list of modules to enable or disable.
|
||||
$modules = array(
|
||||
'enable' => array(),
|
||||
'disable' => array(),
|
||||
'dependencies' => array(),
|
||||
'missing' => array(),
|
||||
);
|
||||
|
||||
// Build a list of missing dependencies.
|
||||
// @todo This should really not be handled here.
|
||||
$data = system_rebuild_module_data();
|
||||
foreach ($data as $name => $module) {
|
||||
// Modules with missing dependencies have to be disabled.
|
||||
if ($this->moduleHandler->moduleExists($name)) {
|
||||
foreach (array_keys($module->requires) as $dependency) {
|
||||
if (!isset($data[$dependency])) {
|
||||
$modules['missing'][$dependency][$name] = $module->info['name'];
|
||||
$modules['disable'][$name] = $module->info['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (!empty($module->required)) {
|
||||
$modules['enable'][$name] = $module->info['name'];
|
||||
}
|
||||
}
|
||||
|
||||
// First, build a list of all modules that were selected.
|
||||
foreach ($packages as $items) {
|
||||
foreach ($items as $name => $checkbox) {
|
||||
// Do not override modules that are forced to be enabled/disabled.
|
||||
if (isset($modules['enable'][$name]) || isset($modules['disable'][$name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$enabled = $this->moduleHandler->moduleExists($name);
|
||||
if (!$checkbox['enable'] && $enabled) {
|
||||
$modules['disable'][$name] = $data[$name]->info['name'];
|
||||
}
|
||||
elseif ($checkbox['enable'] && !$enabled) {
|
||||
$modules['enable'][$name] = $data[$name]->info['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add all dependencies to a list.
|
||||
while (list($module) = each($modules['enable'])) {
|
||||
foreach (array_keys($data[$module]->requires) as $dependency) {
|
||||
if (!isset($modules['enable'][$dependency]) && !$this->moduleHandler->moduleExists($dependency)) {
|
||||
$modules['dependencies'][$module][$dependency] = $data[$dependency]->info['name'];
|
||||
$modules['enable'][$dependency] = $data[$dependency]->info['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the install API is available.
|
||||
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
|
||||
// Invoke hook_requirements('install'). If failures are detected, make
|
||||
// sure the dependent modules aren't installed either.
|
||||
foreach (array_keys($modules['enable']) as $module) {
|
||||
if (drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED && !drupal_check_module($module)) {
|
||||
unset($modules['enable'][$module]);
|
||||
foreach (array_keys($data[$module]->required_by) as $dependent) {
|
||||
unset($modules['enable'][$dependent]);
|
||||
unset($modules['dependencies'][$dependent]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
// Retrieve a list of modules to enable/disable and their dependencies.
|
||||
$modules = $this->buildModuleList($form_state);
|
||||
|
||||
// Check if we have to enable any dependencies. If there is one or more
|
||||
// dependencies that are not enabled yet, redirect to the confirmation form.
|
||||
if (!empty($modules['dependencies']) || !empty($modules['missing'])) {
|
||||
// Write the list of changed module states into a key value store.
|
||||
$account = $this->request->attributes->get('account')->id();
|
||||
$this->keyValueExpirable->setWithExpire($account, $modules, 60);
|
||||
|
||||
// Redirect to the confirmation form.
|
||||
$form_state['redirect'] = 'admin/modules/list/confirm';
|
||||
|
||||
// We can exit here because at least one modules has dependencies
|
||||
// which we have to prompt the user for in a confirmation form.
|
||||
return;
|
||||
}
|
||||
|
||||
// Gets list of modules prior to install process.
|
||||
$before = $this->moduleHandler->getModuleList();
|
||||
|
||||
// There seem to be no dependencies that would need approval.
|
||||
if (!empty($modules['enable'])) {
|
||||
$this->moduleHandler->enable(array_keys($modules['enable']));
|
||||
}
|
||||
if (!empty($modules['disable'])) {
|
||||
$this->moduleHandler->disable(array_keys($modules['disable']));
|
||||
}
|
||||
|
||||
// Gets module list after install process, flushes caches and displays a
|
||||
// message if there are changes.
|
||||
if ($before != $this->moduleHandler->getModuleList()) {
|
||||
drupal_flush_all_caches();
|
||||
drupal_set_message(t('The configuration options have been saved.'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -61,7 +61,7 @@ class DependencyTest extends ModuleTestBase {
|
|||
// Verify that the module is forced to be disabled when submitting
|
||||
// the module page.
|
||||
$this->drupalPost('admin/modules', array(), t('Save configuration'));
|
||||
$this->assertText(t('The @module module is missing, so the following module will be disabled: @depends.', array('@module' => '_missing_dependency', '@depends' => 'system_dependencies_test')), 'The module missing dependencies will be disabled.');
|
||||
$this->assertText(t('The @module module is missing, so the following module will be disabled: @depends.', array('@module' => '_missing_dependency', '@depends' => 'System dependency test')), 'The module missing dependencies will be disabled.');
|
||||
|
||||
// Confirm.
|
||||
$this->drupalPost(NULL, NULL, t('Continue'));
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
*/
|
||||
|
||||
use Drupal\system\DateFormatInterface;
|
||||
use Drupal\system\Form\ModulesInstallConfirmForm;
|
||||
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.
|
||||
|
@ -331,203 +329,6 @@ function _system_is_incompatible(&$incompatible, $files, $file) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor for the module enable/disable interface.
|
||||
*
|
||||
* The list of modules gets populated by module.info.yml files, which contain
|
||||
* each module's name, description, and information about which modules it
|
||||
* requires.
|
||||
* See drupal_parse_info_file() for information on module.info.yml descriptors.
|
||||
*
|
||||
* Dependency checking is performed to ensure that a module:
|
||||
* - can not be enabled if there are disabled modules it requires.
|
||||
* - can not be disabled if there are enabled modules which depend on it.
|
||||
*
|
||||
* @see system_menu()
|
||||
* @see theme_system_modules()
|
||||
* @see system_modules_submit()
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function system_modules($form, $form_state = array()) {
|
||||
// Get current list of modules.
|
||||
$files = system_rebuild_module_data();
|
||||
|
||||
// Remove hidden modules from display list.
|
||||
$visible_files = $files;
|
||||
foreach ($visible_files as $filename => $file) {
|
||||
if (!empty($file->info['hidden'])) {
|
||||
unset($visible_files[$filename]);
|
||||
}
|
||||
}
|
||||
|
||||
uasort($visible_files, 'system_sort_modules_by_info_name');
|
||||
|
||||
// If the modules form was submitted, then system_modules_submit() runs first
|
||||
// and if there are unfilled required modules, then $form_state['storage'] is
|
||||
// filled, triggering a rebuild. In this case we need to display a
|
||||
// confirmation form.
|
||||
if (!empty($form_state['storage'])) {
|
||||
// Contents of confirm form is injected here because already in form
|
||||
// building function.
|
||||
$confirm_form = new ModulesInstallConfirmForm();
|
||||
return $confirm_form->buildForm($form, $form_state, $visible_files, $form_state['storage'], Drupal::request());
|
||||
}
|
||||
|
||||
// JS-only table filters.
|
||||
$form['filters'] = array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array(
|
||||
'class' => array('table-filter', 'js-show'),
|
||||
),
|
||||
);
|
||||
$form['filters']['text'] = array(
|
||||
'#type' => 'search',
|
||||
'#title' => t('Search'),
|
||||
'#size' => 30,
|
||||
'#placeholder' => t('Enter module name…'),
|
||||
'#attributes' => array(
|
||||
'class' => array('table-filter-text'),
|
||||
'data-table' => '#system-modules',
|
||||
'autocomplete' => 'off',
|
||||
'title' => t('Enter a part of the module name or description to filter by.'),
|
||||
),
|
||||
);
|
||||
|
||||
$modules = array();
|
||||
$form['modules'] = array('#tree' => TRUE);
|
||||
|
||||
// Used when checking if module implements a help page.
|
||||
$help_arg = module_exists('help') ? drupal_help_arg() : FALSE;
|
||||
|
||||
// Used when displaying modules that are required by the installation profile.
|
||||
require_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
$distribution_name = check_plain(drupal_install_profile_distribution_name());
|
||||
|
||||
// Iterate through each of the modules.
|
||||
foreach ($visible_files as $filename => $module) {
|
||||
$extra = array();
|
||||
$extra['enabled'] = (bool) $module->status;
|
||||
if (!empty($module->info['required'] )) {
|
||||
$extra['disabled'] = TRUE;
|
||||
$extra['required_by'][] = $distribution_name . (!empty($module->info['explanation']) ? ' ('. $module->info['explanation'] .')' : '');
|
||||
}
|
||||
|
||||
// If this module requires other modules, add them to the array.
|
||||
foreach ($module->requires as $requires => $v) {
|
||||
if (!isset($files[$requires])) {
|
||||
$extra['requires'][$requires] = t('@module (<span class="admin-missing">missing</span>)', array('@module' => drupal_ucfirst($requires)));
|
||||
$extra['disabled'] = TRUE;
|
||||
}
|
||||
// Only display visible modules.
|
||||
elseif (isset($visible_files[$requires])) {
|
||||
$requires_name = $files[$requires]->info['name'];
|
||||
// Disable this module if it is incompatible with the dependency's version.
|
||||
if ($incompatible_version = drupal_check_incompatibility($v, str_replace(DRUPAL_CORE_COMPATIBILITY . '-', '', $files[$requires]->info['version']))) {
|
||||
$extra['requires'][$requires] = t('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
|
||||
'@module' => $requires_name . $incompatible_version,
|
||||
'@version' => $files[$requires]->info['version'],
|
||||
));
|
||||
$extra['disabled'] = TRUE;
|
||||
}
|
||||
// Disable this module if the dependency is incompatible with this
|
||||
// version of Drupal core.
|
||||
elseif ($files[$requires]->info['core'] != DRUPAL_CORE_COMPATIBILITY) {
|
||||
$extra['requires'][$requires] = t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
|
||||
'@module' => $requires_name,
|
||||
));
|
||||
$extra['disabled'] = TRUE;
|
||||
}
|
||||
elseif ($files[$requires]->status) {
|
||||
$extra['requires'][$requires] = t('@module', array('@module' => $requires_name));
|
||||
}
|
||||
else {
|
||||
$extra['requires'][$requires] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $requires_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generate link for module's help page, if there is one.
|
||||
if ($help_arg && $module->status && in_array($filename, module_implements('help'))) {
|
||||
if (module_invoke($filename, 'help', "admin/help#$filename", $help_arg)) {
|
||||
$extra['links']['help'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Help'),
|
||||
'#href' => "admin/help/$filename",
|
||||
'#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => t('Help'))),
|
||||
);
|
||||
}
|
||||
}
|
||||
// Generate link for module's permission, if the user has access to it.
|
||||
if ($module->status && user_access('administer permissions') && in_array($filename, module_implements('permission'))) {
|
||||
$extra['links']['permissions'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Permissions'),
|
||||
'#href' => 'admin/people/permissions',
|
||||
'#options' => array('fragment' => 'module-' . $filename, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => t('Configure permissions'))),
|
||||
);
|
||||
}
|
||||
// Generate link for module's configuration page, if the module provides
|
||||
// one.
|
||||
if ($module->status && isset($module->info['configure'])) {
|
||||
$configure_link = menu_get_item($module->info['configure']);
|
||||
if ($configure_link['access']) {
|
||||
$extra['links']['configure'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Configure'),
|
||||
'#href' => $configure_link['href'],
|
||||
'#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $configure_link['description'])),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If this module is required by other modules, list those, and then make it
|
||||
// impossible to disable this one.
|
||||
foreach ($module->required_by as $required_by => $v) {
|
||||
// Hidden modules are unset already.
|
||||
if (isset($visible_files[$required_by])) {
|
||||
if ($files[$required_by]->status == 1 && $module->status == 1) {
|
||||
$extra['required_by'][] = t('@module', array('@module' => $files[$required_by]->info['name']));
|
||||
$extra['disabled'] = TRUE;
|
||||
}
|
||||
else {
|
||||
$extra['required_by'][] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $files[$required_by]->info['name']));
|
||||
}
|
||||
}
|
||||
}
|
||||
$form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $extra);
|
||||
}
|
||||
|
||||
// Add basic information to the details.
|
||||
foreach (element_children($form['modules']) as $package) {
|
||||
$form['modules'][$package] += array(
|
||||
'#type' => 'details',
|
||||
'#title' => t($package),
|
||||
'#theme' => 'system_modules_details',
|
||||
'#header' => array(
|
||||
array('data' => t('<span class="visually-hidden">Enabled</span>'), 'class' => array('checkbox')),
|
||||
array('data' => t('Name'), 'class' => array('name')),
|
||||
array('data' => t('Description'), 'class' => array('description', RESPONSIVE_PRIORITY_LOW)),
|
||||
),
|
||||
'#attributes' => array('class' => array('package-listing')),
|
||||
// Ensure that the "Core" package comes first.
|
||||
'#weight' => $package == 'Core' ? -10 : NULL,
|
||||
);
|
||||
}
|
||||
|
||||
// Lastly, sort all packages by title.
|
||||
uasort($form['modules'], 'element_sort_by_title');
|
||||
|
||||
$form['#attached']['library'][] = array('system', 'drupal.system.modules');
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save configuration'),
|
||||
);
|
||||
$form['#action'] = url('admin/modules/list/confirm');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array sorting callback; sorts modules or themes by their name.
|
||||
*/
|
||||
|
@ -548,221 +349,6 @@ function system_sort_themes($a, $b) {
|
|||
return strcasecmp($a->info['name'], $b->info['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a table row for the system modules page.
|
||||
*/
|
||||
function _system_modules_build_row($info, $extra) {
|
||||
// Add in the defaults.
|
||||
$extra += array(
|
||||
'requires' => array(),
|
||||
'required_by' => array(),
|
||||
'disabled' => FALSE,
|
||||
'enabled' => FALSE,
|
||||
'links' => array(),
|
||||
);
|
||||
$form = array(
|
||||
'#tree' => TRUE,
|
||||
);
|
||||
// Set the basic properties.
|
||||
$form['name'] = array(
|
||||
'#markup' => $info['name'],
|
||||
);
|
||||
$form['description'] = array(
|
||||
'#markup' => t($info['description']),
|
||||
);
|
||||
$form['version'] = array(
|
||||
'#markup' => $info['version'],
|
||||
);
|
||||
$form['#requires'] = $extra['requires'];
|
||||
$form['#required_by'] = $extra['required_by'];
|
||||
|
||||
// Check the compatibilities.
|
||||
$compatible = TRUE;
|
||||
$status_short = '';
|
||||
$status_long = '';
|
||||
|
||||
// Check the core compatibility.
|
||||
if (!isset($info['core']) || $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
|
||||
$compatible = FALSE;
|
||||
$status_short .= t('Incompatible with this version of Drupal core.');
|
||||
$status_long .= t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => DRUPAL_CORE_COMPATIBILITY));
|
||||
}
|
||||
|
||||
// Ensure this module is compatible with the currently installed version of PHP.
|
||||
if (version_compare(phpversion(), $info['php']) < 0) {
|
||||
$compatible = FALSE;
|
||||
$status_short .= t('Incompatible with this version of PHP');
|
||||
$php_required = $info['php'];
|
||||
if (substr_count($info['php'], '.') < 2) {
|
||||
$php_required .= '.*';
|
||||
}
|
||||
$status_long .= t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $php_required, '!php_version' => phpversion()));
|
||||
}
|
||||
|
||||
// If this module is compatible, present a checkbox indicating
|
||||
// this module may be installed. Otherwise, show a big red X.
|
||||
if ($compatible) {
|
||||
$form['enable'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable'),
|
||||
'#default_value' => $extra['enabled'],
|
||||
'#attributes' => array('role' => 'disabled'),
|
||||
);
|
||||
if ($extra['disabled']) {
|
||||
$form['enable']['#disabled'] = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form['enable'] = array(
|
||||
'#markup' => theme('image', array('uri' => 'core/misc/watchdog-error.png', 'alt' => $status_short, 'title' => $status_short)),
|
||||
);
|
||||
$form['description']['#markup'] .= theme('system_modules_incompatible', array('message' => $status_long));
|
||||
}
|
||||
|
||||
// Build operation links.
|
||||
foreach (array('help', 'permissions', 'configure') as $key) {
|
||||
$form['links'][$key] = (isset($extra['links'][$key]) ? $extra['links'][$key] : array());
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback; handles modules form submission.
|
||||
*/
|
||||
function system_modules_submit($form, &$form_state) {
|
||||
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||
|
||||
// Builds list of modules.
|
||||
$modules = array();
|
||||
// If we're not coming from the confirmation form, build the list of modules.
|
||||
if (empty($form_state['storage'])) {
|
||||
// If we're not coming from the confirmation form, build the module list.
|
||||
foreach ($form_state['values']['modules'] as $group_name => $group) {
|
||||
foreach ($group as $module => $enabled) {
|
||||
$modules[$module] = array('group' => $group_name, 'enabled' => $enabled['enable']);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If we are coming from the confirmation form, fetch
|
||||
// the modules out of $form_state.
|
||||
$modules = $form_state['storage']['modules'];
|
||||
}
|
||||
|
||||
// Collect data for all modules to be able to determine dependencies.
|
||||
$files = system_rebuild_module_data();
|
||||
|
||||
// Sorts modules by weight.
|
||||
$sort = array();
|
||||
foreach (array_keys($modules) as $module) {
|
||||
$sort[$module] = $files[$module]->sort;
|
||||
}
|
||||
array_multisort($sort, $modules);
|
||||
|
||||
// Makes sure all required modules are set to be enabled.
|
||||
$more_required = array();
|
||||
$missing_modules = array();
|
||||
foreach ($modules as $name => $module) {
|
||||
if ($module['enabled']) {
|
||||
// Checks that all dependencies are set to be enabled. Stores the ones
|
||||
// that are not in $dependencies variable so that the user can be alerted
|
||||
// in the confirmation form that more modules need to be enabled.
|
||||
$dependencies = array();
|
||||
foreach (array_keys($files[$name]->requires) as $required) {
|
||||
if (empty($modules[$required]['enabled'])) {
|
||||
if (isset($files[$required])) {
|
||||
$dependencies[] = $files[$required]->info['name'];
|
||||
$modules[$required]['enabled'] = TRUE;
|
||||
}
|
||||
else {
|
||||
$missing_modules[$required]['depends'][] = $name;
|
||||
$modules[$name]['enabled'] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stores additional modules that need to be enabled in $more_required.
|
||||
if (!empty($dependencies)) {
|
||||
$more_required[$name] = array(
|
||||
'name' => $files[$name]->info['name'],
|
||||
'requires' => $dependencies,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Redirects to confirmation form if more modules need to be enabled.
|
||||
if ((!empty($more_required) || !empty($missing_modules)) && !isset($form_state['values']['confirm'])) {
|
||||
$form_state['storage'] = array(
|
||||
'more_required' => $more_required,
|
||||
'modules' => $modules,
|
||||
'missing_modules' => $missing_modules,
|
||||
);
|
||||
$form_state['rebuild'] = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Invokes hook_requirements('install'). If failures are detected, makes sure
|
||||
// the dependent modules aren't installed either.
|
||||
foreach ($modules as $name => $module) {
|
||||
// Only invoke hook_requirements() on modules that are going to be installed.
|
||||
if ($module['enabled'] && drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) {
|
||||
if (!drupal_check_module($name)) {
|
||||
$modules[$name]['enabled'] = FALSE;
|
||||
foreach (array_keys($files[$name]->required_by) as $required_by) {
|
||||
$modules[$required_by]['enabled'] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes array of actions.
|
||||
$actions = array(
|
||||
'enable' => array(),
|
||||
'disable' => array(),
|
||||
'install' => array(),
|
||||
);
|
||||
|
||||
// Builds arrays of modules that need to be enabled, disabled, and installed.
|
||||
foreach ($modules as $name => $module) {
|
||||
if ($module['enabled']) {
|
||||
if (drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) {
|
||||
$actions['install'][] = $name;
|
||||
$actions['enable'][] = $name;
|
||||
}
|
||||
elseif (!module_exists($name)) {
|
||||
$actions['enable'][] = $name;
|
||||
}
|
||||
}
|
||||
elseif (module_exists($name)) {
|
||||
$actions['disable'][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
// Gets list of modules prior to install process, unsets $form_state['storage']
|
||||
// so we don't get redirected back to the confirmation form.
|
||||
$pre_install_list = Drupal::moduleHandler()->getModuleList();
|
||||
unset($form_state['storage']);
|
||||
|
||||
// Reverse the 'enable' list, to order dependencies before dependents.
|
||||
krsort($actions['enable']);
|
||||
|
||||
// Installs, enables, and disables modules.
|
||||
module_enable($actions['enable'], FALSE);
|
||||
module_disable($actions['disable'], FALSE);
|
||||
|
||||
// Gets module list after install process, flushes caches and displays a
|
||||
// message if there are changes.
|
||||
$post_install_list = Drupal::moduleHandler()->getModuleList();
|
||||
if ($pre_install_list != $post_install_list) {
|
||||
drupal_flush_all_caches();
|
||||
drupal_set_message(t('The configuration options have been saved.'));
|
||||
}
|
||||
|
||||
$form_state['redirect'] = 'admin/modules';
|
||||
}
|
||||
|
||||
/**
|
||||
* Default page callback for batches.
|
||||
*/
|
||||
|
|
|
@ -719,10 +719,7 @@ function system_menu() {
|
|||
$items['admin/modules'] = array(
|
||||
'title' => 'Extend',
|
||||
'description' => 'Add and enable modules to extend site functionality.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('system_modules'),
|
||||
'access arguments' => array('administer modules'),
|
||||
'file' => 'system.admin.inc',
|
||||
'route_name' => 'system_modules_list',
|
||||
'weight' => -2,
|
||||
);
|
||||
$items['admin/modules/list'] = array(
|
||||
|
@ -731,7 +728,7 @@ function system_menu() {
|
|||
);
|
||||
$items['admin/modules/list/confirm'] = array(
|
||||
'title' => 'List',
|
||||
'access arguments' => array('administer modules'),
|
||||
'route_name' => 'system_modules_list_confirm',
|
||||
'type' => MENU_VISIBLE_IN_BREADCRUMB,
|
||||
);
|
||||
$items['admin/modules/uninstall'] = array(
|
||||
|
|
|
@ -116,6 +116,20 @@ date_format_localize_reset:
|
|||
requirements:
|
||||
_permission: 'administer site configuration'
|
||||
|
||||
system_modules_list:
|
||||
pattern: 'admin/modules'
|
||||
defaults:
|
||||
_form: 'Drupal\system\Form\ModulesListForm'
|
||||
requirements:
|
||||
_permission: 'administer modules'
|
||||
|
||||
system_modules_list_confirm:
|
||||
pattern: 'admin/modules/list/confirm'
|
||||
defaults:
|
||||
_form: 'Drupal\system\Form\ModulesListConfirmForm'
|
||||
requirements:
|
||||
_permission: 'administer modules'
|
||||
|
||||
system_theme_disable:
|
||||
pattern: '/admin/appearance/disable'
|
||||
defaults:
|
||||
|
|
Loading…
Reference in New Issue