1 system.admin.inc | system_modules($form, $form_state = array()) |
Menu callback; provides module enable/disable interface.
The list of modules gets populated by module.info files, which contain each module's name, description, and information about which modules it requires. See backdrop_parse_info_file() for information on module.info 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.
Parameters
$form_state: An associative array containing the current state of the form.
Return value
The form array.:
See also
theme_system_modules()
Related topics
File
- core/
modules/ system/ system.admin.inc, line 546 - Admin page callbacks for the System module.
Code
function system_modules($form, $form_state = array()) {
backdrop_set_title('Modules');
// JS-only table filters.
$form['filter'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array('table-filter', 'js-show'),
),
'#attached' => array(
'library' => array(array('system', 'backdrop.modules')),
),
);
$form['filter']['search'] = array(
'#type' => 'textfield',
'#title' => t('Filter'),
'#size' => 30,
'#placeholder' => t('Search...'),
'#attributes' => array(
'class' => array('table-filter-text'),
'autocomplete' => 'off',
'title' => t('Enter a part of the module name or description to filter.'),
),
'#default_value' => (isset($_GET['search'])) ? $_GET['search'] : '',
);
$form['filter']['reset'] = array(
'#theme' => 'link',
'#text' => t('Reset'),
'#path' => 'admin/modules',
'#options' => array(
'attributes' => array(
'class' => array('button', 'button-secondary', 'search-reset'),
),
),
);
// Get current list of modules.
$files = system_rebuild_module_data();
$visible_files = $files;
foreach ($visible_files as $filename => $file) {
// Remove hidden modules from the modules list.
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'])) {
return system_modules_confirm_form($visible_files, $form_state['storage']);
}
$modules = array();
$form['modules'] = array('#tree' => TRUE);
// Used when displaying modules that are required by the installation profile.
require_once BACKDROP_ROOT . '/core/includes/install.inc';
$distribution_name = check_plain(backdrop_install_profile_distribution_name());
// Iterate through each of the modules.
foreach ($visible_files as $filename => $module) {
$extra = array();
$extra['enabled'] = (bool) $module->status;
$extra['disabled'] = (array_key_exists('disabled', $module->info)) ? $module->info['disabled'] : FALSE;
if ($extra['disabled'] && !empty($module->info['explanation'])) {
$extra['required_by'][] = $module->info['explanation'];
}
// Check to see if this is a core module.
if (strstr($module->uri, 'core/modules')) {
$extra['core'] = TRUE;
}
// Some modules are always required by core and cannot be disabled, for
// example: entity, node, system, and user.
$extra['required_by_distribution'] = FALSE;
if (!empty($module->info['required'])) {
$extra['disabled'] = TRUE;
$extra['required_by'][] = $distribution_name . (!empty($module->info['explanation']) ? ' (' . $module->info['explanation'] . ')' : '');
$extra['required_by_distribution'] = TRUE;
}
// 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' => backdrop_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.
$version_string = FALSE;
// Make sure the version string of the dependency is available.
if (!empty($files[$requires]->info['version'])) {
$version_string = preg_replace('/^' . preg_quote(BACKDROP_CORE_COMPATIBILITY, '/') . '-/', '', $files[$requires]->info['version']);
}
if ($version_string && $incompatible_version = backdrop_check_incompatibility($v, $version_string)) {
$extra['requires'][$requires] = t('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
'@module' => $requires_name . ' ' . $incompatible_version,
'@version' => $version_string,
));
$extra['disabled'] = TRUE;
}
// Disable this module if the dependency is incompatible with this version of Backdrop core.
elseif (isset($files[$requires]->info['backdrop']) && $files[$requires]->info['backdrop'] != BACKDROP_CORE_COMPATIBILITY) {
$extra['requires'][$requires] = t('@module (<span class="admin-missing">incompatible with</span> this version of Backdrop core)', array(
'@module' => $requires_name,
));
$extra['disabled'] = TRUE;
}
elseif ($files[$requires]->status) {
$extra['requires'][$requires] = t('@module (<span class="admin-enabled">enabled</span>)', 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 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(
'title' => t('Permissions'),
'href' => 'admin/config/people/permissions',
'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => t('Configure permissions')),
'fragment' => 'module-' . $filename,
);
}
// Generate link for module's configuration page, if provided.
if ($module->status && isset($module->info['configure'])) {
$configure_link = menu_get_item($module->info['configure']);
if (is_array($configure_link) && $configure_link['access']) {
$extra['links']['configure'] = array(
'title' => t('Configure'),
'href' => $configure_link['href'],
'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 (<span class="admin-enabled">enabled</span>)', 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 fieldsets.
foreach (element_children($form['modules']) as $package) {
$form['modules'][$package] += array(
'#type' => 'fieldset',
'#title' => t($package),
'#collapsible' => TRUE,
'#theme' => 'system_modules_fieldset',
'#header' => array(
array('class' => array('checkbox')),
t('Name'),
array('data' => t('Version'), 'class' => array(RESPONSIVE_PRIORITY_MEDIUM)),
array('data' => t('Description'), 'class' => array(RESPONSIVE_PRIORITY_LOW)),
array('data' => t('Operations')),
),
);
}
ksort($form['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;
}