Commit 3cc312e2 authored by alexpott's avatar alexpott

Issue #2228215 by znerol, Berdir: Remove module check in DrupalKernel.

parent 486e276f
......@@ -116,6 +116,13 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
*/
protected $allowDumping;
/**
* Whether the container can be loaded.
*
* @var bool
*/
protected $allowLoading;
/**
* Whether the container needs to be dumped once booting is complete.
*
......@@ -171,12 +178,16 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
* @param bool $allow_dumping
* (optional) FALSE to stop the container from being written to or read
* from disk. Defaults to TRUE.
* @param bool $allow_loading
* (optional) FALSE to prevent the kernel attempting to read the dependency
* injection container from disk. Defaults to $allow_dumping.
*/
public function __construct($environment, ClassLoader $class_loader, $allow_dumping = TRUE) {
public function __construct($environment, ClassLoader $class_loader, $allow_dumping = TRUE, $allow_loading = NULL) {
$this->environment = $environment;
$this->booted = FALSE;
$this->classLoader = $class_loader;
$this->allowDumping = $allow_dumping;
$this->allowLoading = isset($allow_loading) ? $allow_loading : $allow_dumping;
}
/**
......@@ -344,6 +355,12 @@ public function updateModules(array $module_list, array $module_filenames = arra
foreach ($module_filenames as $name => $extension) {
$this->moduleData[$name] = $extension;
}
// This method is called whenever the list of modules changed. Therefore
// disable loading of a dumped container from the disk, because it is
// guaranteed to be out of date and needs to be rebuilt anyway.
$this->allowLoading = FALSE;
// 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 serviceProvider list and container.
......@@ -397,7 +414,7 @@ protected function initializeContainer() {
$class = $this->getClassName();
$cache_file = $class . '.php';
if ($this->allowDumping) {
if ($this->allowLoading) {
// First, try to load.
if (!class_exists($class, FALSE)) {
$this->storage()->load($cache_file);
......@@ -417,33 +434,12 @@ protected function initializeContainer() {
$this->moduleList = $this->newModuleList;
unset($this->newModuleList);
}
// Second, check if some other request -- for example on another web
// frontend or during the installer -- changed the list of enabled modules.
if (isset($this->container)) {
// All namespaces must be registered before we attempt to use any service
// from the container.
$container_modules = $this->container->getParameter('container.modules');
$namespaces_before = $this->classLoader->getPrefixesPsr4();
$this->registerNamespacesPsr4($this->container->getParameter('container.namespaces'));
// If 'container.modules' is wrong, the container must be rebuilt.
if (!isset($this->moduleList)) {
$this->moduleList = $this->container->get('config.factory')->get('core.extension')->get('module') ?: array();
}
if (array_keys($this->moduleList) !== array_keys($container_modules)) {
$persist = $this->getServicesToPersist();
unset($this->container);
// Revert the class loader to its prior state. However,
// registerNamespaces() performs a merge rather than replace, so to
// effectively remove erroneous registrations, we must replace them with
// empty arrays.
$namespaces_after = $this->classLoader->getPrefixesPsr4();
$namespaces_before += array_fill_keys(array_diff(array_keys($namespaces_after), array_keys($namespaces_before)), array());
$this->registerNamespacesPsr4($namespaces_before);
}
}
if (!isset($this->container)) {
else {
$this->container = $this->buildContainer();
$this->persistServices($persist);
......
......@@ -1094,7 +1094,7 @@ protected function rebuildContainer($environment = 'prod') {
$request_stack = \Drupal::service('request_stack');
}
$this->kernel = new DrupalKernel($environment, drupal_classloader(), FALSE);
$this->kernel = new DrupalKernel($environment, drupal_classloader(), TRUE, FALSE);
$this->kernel->boot();
// DrupalKernel replaces the container in \Drupal::getContainer() with a
// different object, so we need to replace the instance on this test class.
......
......@@ -56,7 +56,6 @@ function testCompileDIC() {
// Instantiate it a second time and we should get the compiled Container
// class.
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
$refClass = new \ReflectionClass($container);
......@@ -64,6 +63,10 @@ function testCompileDIC() {
$refClass->getParentClass()->getName() == 'Drupal\Core\DependencyInjection\Container' &&
!$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_compiled_container);
// Verify that the list of modules is the same for the initial and the
// compiled container.
$module_list = array_keys($container->get('module_handler')->getModuleList());
$this->assertEqual(array_values($module_enabled), $module_list);
// Now use the read-only storage implementation, simulating a "production"
// environment.
......@@ -71,7 +74,6 @@ function testCompileDIC() {
$php_storage['service_container']['class'] = 'Drupal\Component\PhpStorage\FileReadOnlyStorage';
$this->settingsSet('php_storage', $php_storage);
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
$refClass = new \ReflectionClass($container);
......@@ -79,6 +81,10 @@ function testCompileDIC() {
$refClass->getParentClass()->getName() == 'Drupal\Core\DependencyInjection\Container' &&
!$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_compiled_container);
// Verify that the list of modules is the same for the initial and the
// compiled container.
$module_list = array_keys($container->get('module_handler')->getModuleList());
$this->assertEqual(array_values($module_enabled), $module_list);
// Test that our synthetic services are there.
$classloader = $container->get('class_loader');
$refClass = new \ReflectionClass($classloader);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment