diff --git a/core/includes/module.inc b/core/includes/module.inc index c1d99f238ffecbfd50a941d9833cb4e841f46dfd..ef09b57c29de32fb78470b4df8482e7b0881d151 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -6,6 +6,7 @@ */ use Drupal\Component\Graph\Graph; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Loads all enabled modules. @@ -501,6 +502,12 @@ function module_enable($module_list, $enable_dependencies = TRUE) { system_list_reset(); module_implements_reset(); _system_update_bootstrap_status(); + // Update the kernel to include it. + // @todo The if statement is here because install_begin_request() creates + // a container without a kernel. It probably shouldn't. + if ($kernel = drupal_container()->get('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { + $kernel->updateModules(module_list()); + } // Refresh the schema to include it. drupal_get_schema(NULL, TRUE); // Update the theme registry to include it. @@ -632,6 +639,8 @@ function module_disable($module_list, $disable_dependents = TRUE) { // so we can still call module hooks to get information. module_invoke_all('modules_disabled', $invoke_modules); _system_update_bootstrap_status(); + // Update the kernel to exclude the disabled modules. + drupal_container()->get('kernel')->updateModules(module_list()); // Update the theme registry to remove the newly-disabled module. drupal_theme_rebuild(); } diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index e2991e1c065efa3ca83ed4abbea07b853ceac4cf..892571fc130faec19dd39cfa9232581d1de820ad 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -26,7 +26,7 @@ * own bundle, i.e. a subclass of Symfony\Component\HttpKernel\Bundle, to * register services to the container. */ -class DrupalKernel extends Kernel { +class DrupalKernel extends Kernel implements DrupalKernelInterface { /** * Holds the list of enabled modules. @@ -110,6 +110,20 @@ public function registerBundles() { return $bundles; } + /** + * Implements Drupal\Core\DrupalKernelInterface::updateModules(). + */ + public function updateModules($module_list) { + $this->moduleList = $module_list; + // If we haven't yet booted, we don't need to do anything: the new module + // list will take effect when boot() is called. If we have already booted, + // then reboot in order to refresh the bundle list and container. + if ($this->booted) { + drupal_container(NULL, TRUE); + $this->booted = FALSE; + $this->boot(); + } + } /** * Initializes the service container. @@ -222,4 +236,5 @@ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass) */ public function registerContainerConfiguration(LoaderInterface $loader) { } + } diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..828f3ba116dd97a915c65b743f7e5ff5d22376ad --- /dev/null +++ b/core/lib/Drupal/Core/DrupalKernelInterface.php @@ -0,0 +1,30 @@ +<?php + +/** + * @file + * Definition of Drupal\Core\DrupalKernelInterface. + */ + +namespace Drupal\Core; + +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * The interface for DrupalKernel, the core of Drupal. + * + * This interface extends Symfony's KernelInterface and adds methods for + * responding to modules being enabled or disabled during its lifetime. + */ +interface DrupalKernelInterface extends KernelInterface { + + /** + * Updates the kernel's list of modules to the new list. + * + * The kernel needs to update its bundle list and container to match the new + * list. + * + * @param array $module_list + * The new list of modules. + */ + public function updateModules($module_list); +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php b/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php index 3fa0d1d94a3a23637c0b843b420c3e8c4eb68229..35faa3c4280ca922cec88444a26ff1e8870467e6 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php @@ -41,4 +41,18 @@ function testBundleRegistration() { $this->drupalGet(''); $this->assertText(t('The bundle_test event subscriber fired!'), 'The bundle_test event subscriber fired'); } + + /** + * Tests that the DIC keeps up with module enable/disable in the same request. + */ + function testBundleRegistrationDynamic() { + // Disable the module and ensure the bundle's service is not registered. + module_disable(array('bundle_test')); + $this->assertFalse(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service does not exist in the DIC.'); + + // Enable the module and ensure the bundle's service is registered. + module_enable(array('bundle_test')); + $this->assertTrue(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service exists in the DIC.'); + } + }