diff --git a/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php b/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php index c739dd9f136e766379a66a4df9d4999ffd69418e..9ff1f032b297ff7c794ceaf76035492454763461 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/InfoAlterTest.php @@ -29,6 +29,9 @@ public static function getInfo() { * return freshly altered info. */ function testSystemInfoAlter() { + \Drupal::state()->set('module_test.hook_system_info_alter', TRUE); + $info = system_rebuild_module_data(); + $this->assertFalse(isset($info['node']->info['required']), 'Before the module_test is installed the node module is not required.'); // Enable seven and the test module. theme_enable(array('seven')); \Drupal::moduleHandler()->install(array('module_test'), FALSE); @@ -44,5 +47,9 @@ function testSystemInfoAlter() { $this->assertTrue(isset($info['regions']['test_region']), 'Altered theme info was returned by system_list().'); $list_themes = list_themes(); $this->assertTrue(isset($list_themes['seven']->info['regions']['test_region']), 'Altered theme info was returned by list_themes().'); + system_list_reset(); + $info = system_rebuild_module_data(); + $this->assertTrue($info['node']->info['required'], 'After the module_test is installed the node module is required.'); + \Drupal::state()->set('module_test.hook_system_info_alter', FALSE); } } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index cb0cb54966e1bf4a960e2881b35a8bd79a4b0bf5..295c2f88a479d344493a80c8bae6d16d25b96d44 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2434,6 +2434,13 @@ function _system_rebuild_module_data() { drupal_alter('system_info', $modules[$key]->info, $modules[$key], $type); } + // It is possible that a module was marked as required by + // hook_system_info_alter() and modules that it depends on are not required. + foreach ($modules as $module) { + _system_rebuild_module_data_ensure_required($module, $modules); + } + + if (isset($modules[$profile])) { // The installation profile is required, if it's a valid module. $modules[$profile]->info['required'] = TRUE; @@ -2447,6 +2454,27 @@ function _system_rebuild_module_data() { return $modules; } +/** + * Ensures that dependencies of required modules are also required. + * + * @param \stdClass $module + * The module info. + * @param array $modules + * The array of all module info. + */ +function _system_rebuild_module_data_ensure_required($module, &$modules) { + if (!empty($module->info['required'])) { + foreach ($module->info['dependencies'] as $dependant) { + if (!isset($modules[$dependant]->info['required'])) { + $modules[$dependant]->info['required'] = TRUE; + $modules[$dependant]->info['explanation'] = t('Dependency of required module @module', array('@module' => $module->name)); + // Ensure any dependencies it has are required. + _system_rebuild_module_data_ensure_required($modules[$dependant], $modules); + } + } + } +} + /** * Rebuild, save, and return data about all currently available modules. * diff --git a/core/modules/system/tests/modules/module_test/module_test.info.yml b/core/modules/system/tests/modules/module_test/module_test.info.yml index 4c0ecf8777699afbe64f24b621f0a8bfdd578bcf..390706d7854041f3a750406b1eee461832e84a55 100644 --- a/core/modules/system/tests/modules/module_test/module_test.info.yml +++ b/core/modules/system/tests/modules/module_test/module_test.info.yml @@ -5,3 +5,8 @@ package: Testing version: VERSION core: 8.x hidden: true +# Depends on the Node module to test making a module required using +# hook_system_info_alter() and ensuring that its dependencies also become +# required. +dependencies: + - node diff --git a/core/modules/system/tests/modules/module_test/module_test.module b/core/modules/system/tests/modules/module_test/module_test.module index 94278b77ec45dba883100f416872bccbb3e5d3a3..6bb9a789f554bbe034f12e7f34765d2f71c8cef5 100644 --- a/core/modules/system/tests/modules/module_test/module_test.module +++ b/core/modules/system/tests/modules/module_test/module_test.module @@ -52,6 +52,10 @@ function module_test_system_info_alter(&$info, $file, $type) { if ($file->name == 'seven' && $type == 'theme') { $info['regions']['test_region'] = t('Test region'); } + if ($file->name == 'module_test' && \Drupal::state()->get('module_test.hook_system_info_alter')) { + $info['required'] = TRUE; + $info['explanation'] = 'Testing hook_system_info_alter()'; + } } /**