diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index c74ee06..090fa69 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -16,7 +16,10 @@ use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; -use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\TerminableInterface; /** * The DrupalKernel class is the core of Drupal itself. @@ -31,7 +34,37 @@ * Drupal\Core\DependencyInjection\ServiceProvider, to register services to the * container, or modify existing services. */ -class DrupalKernel extends Kernel implements DrupalKernelInterface { +class DrupalKernel implements DrupalKernelInterface, TerminableInterface { + + const CONTAINER_BASE_CLASS = 'Container'; + + /** + * Holds the container instance. + * + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + protected $container; + + /** + * The environment, e.g. 'testing', 'install'. + * + * @var string + */ + protected $environment; + + /** + * Whether we are in debug mode. + * + * @var bool + */ + protected $debug; + + /** + * Whether the kernel has been booted. + * + * @var bool + */ + protected $booted; /** * Holds the list of enabled modules. @@ -138,7 +171,9 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface { * from disk. Defaults to TRUE. */ public function __construct($environment, $debug, ClassLoader $class_loader, $allow_dumping = TRUE) { - parent::__construct($environment, $debug); + $this->environment = $environment; + $this->debug = (Boolean) $debug; + $this->booted = false; $this->classLoader = $class_loader; $this->allowDumping = $allow_dumping; } @@ -159,17 +194,7 @@ public function unserialize($data) { } /** - * Overrides Kernel::init(). - */ - public function init() { - // Intentionally empty. The sole purpose is to not execute Kernel::init(), - // since that overrides/breaks Drupal's current error handling. - // @todo Investigate whether it is possible to migrate Drupal's error - // handling to the one of Kernel without losing functionality. - } - - /** - * Overrides Kernel::boot(). + * {@inheritdoc} */ public function boot() { if ($this->booted) { @@ -177,22 +202,35 @@ public function boot() { } $this->initializeContainer(); $this->booted = TRUE; - if ($this->containerNeedsDumping && !$this->dumpDrupalContainer($this->container, $this->getContainerBaseClass())) { + if ($this->containerNeedsDumping && !$this->dumpDrupalContainer($this->container, static::CONTAINER_BASE_CLASS)) { watchdog('DrupalKernel', 'Container cannot be written to disk'); } } - public function registerBundles() { - // We do not support symfony bundles + /** + * {@inheritdoc} + */ + public function shutdown() + { + if (false === $this->booted) { + return; + } + $this->booted = false; + $this->container = null; } /** - * Returns an array of available serviceProviders. - * - * @return array - * The available serviceProviders. + * {@inheritdoc} + */ + public function getContainer() + { + return $this->container; + } + + /** + * {@inheritdoc} */ - public function registerServiceProviders() { + public function discoverServiceProviders() { $this->configStorage = BootstrapConfigStorageFactory::get(); $serviceProviders = array( 'CoreServiceProvider' => new CoreServiceProvider(), @@ -240,6 +278,40 @@ public function registerServiceProviders() { return $serviceProviders; } + + /** + * {@inheritdoc} + */ + public function getServiceProviders() { + return $this->serviceProviders; + } + + /** + * {@inheritdoc} + */ + public function terminate(Request $request, Response $response) + { + if (false === $this->booted) { + return; + } + + if ($this->getHttpKernel() instanceof TerminableInterface) { + $this->getHttpKernel()->terminate($request, $response); + } + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + if (false === $this->booted) { + $this->boot(); + } + + return $this->getHttpKernel()->handle($request, $type, $catch); + } + /** * Returns module data on the filesystem. * @@ -309,6 +381,20 @@ protected function getClassName() { return implode('_', $parts); } + + /** + * Returns the kernel parameters. + * + * @return array An array of kernel parameters + */ + protected function getKernelParameters() + { + return array( + 'kernel.environment' => $this->environment, + 'kernel.debug' => $this->debug, + ); + } + /** * Initializes the service container. */ @@ -488,7 +574,7 @@ protected function buildContainer() { protected function initializeServiceProviders() { $this->serviceProviders = array(); - foreach ($this->registerServiceProviders() as $name => $provider) { + foreach ($this->discoverServiceProviders() as $name => $provider) { if (isset($this->serviceProviders[$name])) { throw new \LogicException(sprintf('Trying to register two service providers with the same name "%s"', $name)); } @@ -497,16 +583,6 @@ protected function initializeServiceProviders() { } /** - * Getter for the serviceProviders property. - * - * @return ServiceProvider[] - * An associative array of ServiceProvider objects, keyed by name. - */ - public function getServiceProviders() { - return $this->serviceProviders; - } - - /** * Gets a new ContainerBuilder instance used to build the service container. * * @return ContainerBuilder @@ -540,6 +616,17 @@ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass) return $this->storage()->save($class . '.php', $content); } + + /** + * Gets a http kernel from the container + * + * @return HttpKernel + */ + protected function getHttpKernel() + { + return $this->container->get('http_kernel'); + } + /** * Overrides and eliminates this method from the parent class. Do not use. * diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php index 60d0403..96b2f92 100644 --- a/core/lib/Drupal/Core/DrupalKernelInterface.php +++ b/core/lib/Drupal/Core/DrupalKernelInterface.php @@ -7,7 +7,7 @@ namespace Drupal\Core; -use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\HttpKernel\HttpKernelInterface; /** * The interface for DrupalKernel, the core of Drupal. @@ -15,7 +15,40 @@ * This interface extends Symfony's KernelInterface and adds methods for * responding to modules being enabled or disabled during its lifetime. */ -interface DrupalKernelInterface extends KernelInterface { +interface DrupalKernelInterface extends HttpKernelInterface, \Serializable { + + /** + * Boots the current kernel. + */ + public function boot(); + + /** + * Shuts down the kernel. + */ + public function shutdown(); + + /** + * Discovers available serviceProviders. + * + * @return array + * The available serviceProviders. + */ + public function discoverServiceProviders(); + + /** + * Returns all registered service providers. + * + * @return array + * An associative array of ServiceProvider objects, keyed by name. + */ + public function getServiceProviders(); + + /** + * Gets the current container. + * + * @return ContainerInterface A ContainerInterface instance + */ + public function getContainer(); /** * Updates the kernel's list of modules to the new list. diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index 656e918..c510192 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -81,7 +81,7 @@ class ModuleHandler implements ModuleHandlerInterface { * %container.modules% parameter being set up by DrupalKernel. * * @see \Drupal\Core\DrupalKernel - * @see \Drupal\Core\CoreBundle + * @see \Drupal\Core\CoreServiceProvider */ public function __construct(array $module_list = array()) { $this->moduleList = $module_list; diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 898fdf8..3c86bd1 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -6,7 +6,7 @@ * * This provides a Twig extension that registers various Drupal specific extensions to Twig. * - * @see \Drupal\Core\CoreBundle + * @see \Drupal\Core\CoreServiceProvider */ namespace Drupal\Core\Template; @@ -14,7 +14,7 @@ /** * A class for providing Twig extensions (specific Twig_NodeVisitors, filters and functions). * - * @see \Drupal\Core\CoreBundle + * @see \Drupal\Core\CoreServiceProvider */ class TwigExtension extends \Twig_Extension { public function getFunctions() { diff --git a/core/modules/system/language.api.php b/core/modules/system/language.api.php index fb165a4..7f4b0c2 100644 --- a/core/modules/system/language.api.php +++ b/core/modules/system/language.api.php @@ -201,7 +201,7 @@ function hook_language_fallback_candidates_alter(array &$fallback_candidates) { * hook_transliteration_overrides_alter() to provide further language-specific * overrides (including providing transliteration for Unicode characters that * are longer than 4 bytes). Modules can also completely override the - * transliteration classes in \Drupal\Core\CoreBundle. + * transliteration classes in \Drupal\Core\CoreServiceProvider. */ /** diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php index 87c7019..a73c6db 100644 --- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php @@ -86,11 +86,11 @@ function testCompileDIC() { // is functioning correctly, i.e. we get a brand new ContainerBuilder // which has the required new services, after changing the list of enabled // modules. - $this->assertFalse($container->has('bundle_test_class')); + $this->assertFalse($container->has('service_provider_test_class')); // Add another module so that we can test that the new module's bundle is // registered to the new container. - $module_enabled['bundle_test'] = 'bundle_test'; + $module_enabled['service_provider_test'] = 'service_provider_test'; $kernel = new DrupalKernel('testing', FALSE, $classloader); $kernel->updateModules($module_enabled); $kernel->boot(); @@ -104,14 +104,14 @@ function testCompileDIC() { $is_container_builder = $refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder'); $this->assertTrue($is_container_builder); // Assert that the new module's bundle was registered to the new container. - $this->assertTrue($container->has('bundle_test_class')); + $this->assertTrue($container->has('service_provider_test_class')); // Test that our synthetic services are there. $classloader = $container->get('class_loader'); $refClass = new ReflectionClass($classloader); $this->assertTrue($refClass->hasMethod('loadClass'), 'Container has a classloader'); // Check that the location of the new module is registered. $modules = $container->getParameter('container.modules'); - $this->assertEqual($modules['bundle_test'], drupal_get_filename('module', 'bundle_test')); + $this->assertEqual($modules['service_provider_test'], drupal_get_filename('module', 'service_provider_test')); } /** diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php index 9bfde63..a48e883 100644 --- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php @@ -29,16 +29,16 @@ public static function getInfo() { */ public function testDestructionUsed() { // Enable the test module to add it to the container. - $this->enableModules(array('bundle_test')); + $this->enableModules(array('service_provider_test')); // The service has not been destructed yet. - $this->assertNull(\Drupal::state()->get('bundle_test.destructed')); + $this->assertNull(\Drupal::state()->get('service_provider_test.destructed')); // Call the class and then terminate the kernel - $this->container->get('bundle_test_class'); + $this->container->get('service_provider_test_class'); $response = new Response(); $this->container->get('kernel')->terminate($this->container->get('request'), $response); - $this->assertTrue(\Drupal::state()->get('bundle_test.destructed')); + $this->assertTrue(\Drupal::state()->get('service_provider_test.destructed')); } /** @@ -46,15 +46,15 @@ public function testDestructionUsed() { */ public function testDestructionUnused() { // Enable the test module to add it to the container. - $this->enableModules(array('bundle_test')); + $this->enableModules(array('service_provider_test')); // The service has not been destructed yet. - $this->assertNull(\Drupal::state()->get('bundle_test.destructed')); + $this->assertNull(\Drupal::state()->get('service_provider_test.destructed')); // Terminate the kernel. The test class has not been called, so it should not // be destructed. $response = new Response(); $this->container->get('kernel')->terminate($this->container->get('request'), $response); - $this->assertNull(\Drupal::state()->get('bundle_test.destructed')); + $this->assertNull(\Drupal::state()->get('service_provider_test.destructed')); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php b/core/modules/system/lib/Drupal/system/Tests/ServiceProvider/ServiceProviderTest.php similarity index 59% rename from core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php rename to core/modules/system/lib/Drupal/system/Tests/ServiceProvider/ServiceProviderTest.php index 35faa3c..12791a2 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/ServiceProvider/ServiceProviderTest.php @@ -19,7 +19,7 @@ class BundleTest extends WebTestBase { * * @var array */ - public static $modules = array('bundle_test'); + public static $modules = array('service_provider_test'); public static function getInfo() { return array( @@ -33,13 +33,13 @@ public static function getInfo() { * Tests that services provided by module bundles get registered to the DIC. */ function testBundleRegistration() { - $this->assertTrue(drupal_container()->getDefinition('file.usage')->getClass() == 'Drupal\\bundle_test\\TestFileUsage', 'Class has been changed'); - $this->assertTrue(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service has been registered to the DIC'); + $this->assertTrue(drupal_container()->getDefinition('file.usage')->getClass() == 'Drupal\\service_provider_test\\TestFileUsage', 'Class has been changed'); + $this->assertTrue(drupal_container()->has('service_provider_test_class'), 'The service_provider_test_class service has been registered to the DIC'); // The event subscriber method in the test class calls drupal_set_message with // a message saying it has fired. This will fire on every page request so it // should show up on the front page. $this->drupalGet(''); - $this->assertText(t('The bundle_test event subscriber fired!'), 'The bundle_test event subscriber fired'); + $this->assertText(t('The service_provider_test event subscriber fired!'), 'The service_provider_test event subscriber fired'); } /** @@ -47,12 +47,12 @@ function testBundleRegistration() { */ 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.'); + module_disable(array('service_provider_test')); + $this->assertFalse(drupal_container()->has('service_provider_test_class'), 'The service_provider_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.'); + module_enable(array('service_provider_test')); + $this->assertTrue(drupal_container()->has('service_provider_test_class'), 'The service_provider_test_class service exists in the DIC.'); } } diff --git a/core/modules/system/tests/modules/bundle_test/bundle_test.info.yml b/core/modules/system/tests/modules/bundle_test/bundle_test.info.yml deleted file mode 100644 index 49335fb..0000000 --- a/core/modules/system/tests/modules/bundle_test/bundle_test.info.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: 'Bundle test' -type: module -description: 'Support module for bundle testing.' -package: Testing -version: VERSION -core: 8.x -hidden: true diff --git a/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml b/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml deleted file mode 100644 index 88b3caf..0000000 --- a/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - bundle_test_class: - class: Drupal\bundle_test\TestClass - tags: - - { name: event_subscriber } - - { name: needs_destruction } - arguments: ['@state'] - file.usage: - class: Drupal\bundle_test\TestFileUsage diff --git a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php b/core/modules/system/tests/modules/service_provider_test/lib/Drupal/service_provider_test/TestClass.php similarity index 83% rename from core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php rename to core/modules/system/tests/modules/service_provider_test/lib/Drupal/service_provider_test/TestClass.php index ad711cb..1c8ea06 100644 --- a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php +++ b/core/modules/system/tests/modules/service_provider_test/lib/Drupal/service_provider_test/TestClass.php @@ -2,10 +2,10 @@ /** * @file - * Definition of Drupal\bundle_test\TestClass. + * Definition of Drupal\service_provider_test\TestClass. */ -namespace Drupal\bundle_test; +namespace Drupal\service_provider_test; use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Core\DestructableInterface; @@ -36,7 +36,7 @@ public function __construct(KeyValueStoreInterface $state) { * A simple kernel listener method. */ public function onKernelRequestTest(GetResponseEvent $event) { - drupal_set_message(t('The bundle_test event subscriber fired!')); + drupal_set_message(t('The service_provider_test event subscriber fired!')); } /** @@ -54,6 +54,6 @@ static function getSubscribedEvents() { * Implements \Drupal\Core\DestructableInterface::destruct(). */ public function destruct() { - $this->state->set('bundle_test.destructed', TRUE); + $this->state->set('service_provider_test.destructed', TRUE); } } diff --git a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestFileUsage.php b/core/modules/system/tests/modules/service_provider_test/lib/Drupal/service_provider_test/TestFileUsage.php similarity index 84% rename from core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestFileUsage.php rename to core/modules/system/tests/modules/service_provider_test/lib/Drupal/service_provider_test/TestFileUsage.php index 0ee5f2d..df6cb44 100644 --- a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestFileUsage.php +++ b/core/modules/system/tests/modules/service_provider_test/lib/Drupal/service_provider_test/TestFileUsage.php @@ -2,10 +2,10 @@ /** * @file - * Definition of Drupal\bundle_test\TestFileUsage. + * Definition of Drupal\service_provider_test\TestFileUsage. */ -namespace Drupal\bundle_test; +namespace Drupal\service_provider_test; use Drupal\file\Plugin\Core\Entity\File; diff --git a/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml b/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml new file mode 100644 index 0000000..620c897 --- /dev/null +++ b/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml @@ -0,0 +1,7 @@ +name: 'Service Provider test' +type: module +description: 'Support module for service provider testing.' +package: Testing +version: VERSION +core: 8.x +hidden: true diff --git a/core/modules/system/tests/modules/bundle_test/bundle_test.module b/core/modules/system/tests/modules/service_provider_test/service_provider_test.module similarity index 100% rename from core/modules/system/tests/modules/bundle_test/bundle_test.module rename to core/modules/system/tests/modules/service_provider_test/service_provider_test.module diff --git a/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml b/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml new file mode 100644 index 0000000..4c75baf --- /dev/null +++ b/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml @@ -0,0 +1,9 @@ +services: + service_provider_test_class: + class: Drupal\service_provider_test\TestClass + tags: + - { name: event_subscriber } + - { name: needs_destruction } + arguments: ['@state'] + file.usage: + class: Drupal\service_provider_test\TestFileUsage