diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 6fae299..13f7107 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -733,7 +733,7 @@ function drupal_bootstrap($phase = NULL) { $boot_level = $phase; } - return \Drupal::getContainer() ? DRUPAL_BOOTSTRAP_CODE : DRUPAL_BOOTSTRAP_CONFIGURATION; + return \Drupal::hasContainer() ? DRUPAL_BOOTSTRAP_CODE : DRUPAL_BOOTSTRAP_CONFIGURATION; } /** diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php index 7b52d13..1bc06ea 100644 --- a/core/lib/Drupal.php +++ b/core/lib/Drupal.php @@ -5,6 +5,7 @@ * Contains Drupal. */ +use Drupal\Core\DependencyInjection\ContainerNotInitializedException; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Url; @@ -103,27 +104,53 @@ class Drupal { * Sets a new global container. * * @param \Symfony\Component\DependencyInjection\ContainerInterface $container - * A new container instance to replace the current. NULL may be passed by - * testing frameworks to ensure that the global state of a previous - * environment does not leak into a test. + * A new container instance to replace the current. */ - public static function setContainer(ContainerInterface $container = NULL) { + public static function setContainer(ContainerInterface $container) { static::$container = $container; } /** + * Unsets the global container. + */ + public static function unsetContainer() { + static::$container = NULL; + } + + /** * Returns the currently active global container. * - * @deprecated This method is only useful for the testing environment. It - * should not be used otherwise. + * @deprecated This method currently returns NULL when the container is not + * initialized. This behavior is deprecated, before 8.0.0 it will instead + * throw an exception. An additional parameter was added to simulate the + * future behavior. + * + * @throws \Drupal\Core\DependencyInjection\ContainerNotInitializedException + * + * @param bool $exception_on_invalid + * (optional) If TRUE and the container is not initialized, an exception + * will be thrown. Defaults to FALSE. * * @return \Symfony\Component\DependencyInjection\ContainerInterface|null */ - public static function getContainer() { + public static function getContainer($exception_on_invalid = FALSE) { + if (static::$container === NULL && $exception_on_invalid) { + throw new ContainerNotInitializedException('\Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.'); + } return static::$container; } /** + * Returns TRUE if the container has been initialized, FALSE otherwise. + * + * @return bool + */ + public static function hasContainer() { + return static::$container !== NULL; + } + + + /** * Retrieves a service from the container. * * Use this method if the desired service is not one of those with a dedicated @@ -136,7 +163,7 @@ public static function getContainer() { * The specified service. */ public static function service($id) { - return static::$container->get($id); + return static::getContainer(TRUE)->get($id); } /** @@ -149,7 +176,8 @@ public static function service($id) { * TRUE if the specified service exists, FALSE otherwise. */ public static function hasService($id) { - return static::$container && static::$container->has($id); + // Check hasContainer() first in order to always return a Boolean. + return static::hasContainer() && static::getContainer()->has($id); } /** @@ -158,7 +186,7 @@ public static function hasService($id) { * @return string */ public static function root() { - return static::$container->get('app.root'); + return static::getContainer(TRUE)->get('app.root'); } /** @@ -168,7 +196,8 @@ public static function root() { * TRUE if there is a currently active request object, FALSE otherwise. */ public static function hasRequest() { - return static::$container && static::$container->has('request_stack') && static::$container->get('request_stack')->getCurrentRequest() !== NULL; + // Check hasContainer() first in order to always return a Boolean. + return static::hasContainer() && static::getContainer()->has('request_stack') && static::getContainer()->get('request_stack')->getCurrentRequest() !== NULL; } /** @@ -194,7 +223,7 @@ public static function hasRequest() { * The currently active request object. */ public static function request() { - return static::$container->get('request_stack')->getCurrentRequest(); + return static::getContainer(TRUE)->get('request_stack')->getCurrentRequest(); } /** @@ -204,7 +233,7 @@ public static function request() { * The request stack */ public static function requestStack() { - return static::$container->get('request_stack'); + return static::getContainer(TRUE)->get('request_stack'); } /** @@ -214,7 +243,7 @@ public static function requestStack() { * The currently active route match object. */ public static function routeMatch() { - return static::$container->get('current_route_match'); + return static::getContainer(TRUE)->get('current_route_match'); } /** @@ -223,7 +252,7 @@ public static function routeMatch() { * @return \Drupal\Core\Session\AccountProxyInterface */ public static function currentUser() { - return static::$container->get('current_user'); + return static::getContainer(TRUE)->get('current_user'); } /** @@ -233,7 +262,7 @@ public static function currentUser() { * The entity manager service. */ public static function entityManager() { - return static::$container->get('entity.manager'); + return static::getContainer(TRUE)->get('entity.manager'); } /** @@ -243,7 +272,7 @@ public static function entityManager() { * The current active database's master connection. */ public static function database() { - return static::$container->get('database'); + return static::getContainer(TRUE)->get('database'); } /** @@ -259,7 +288,7 @@ public static function database() { * @ingroup cache */ public static function cache($bin = 'default') { - return static::$container->get('cache.' . $bin); + return static::getContainer(TRUE)->get('cache.' . $bin); } /** @@ -272,7 +301,7 @@ public static function cache($bin = 'default') { * An expirable key value store collection. */ public static function keyValueExpirable($collection) { - return static::$container->get('keyvalue.expirable')->get($collection); + return static::getContainer(TRUE)->get('keyvalue.expirable')->get($collection); } /** @@ -283,7 +312,7 @@ public static function keyValueExpirable($collection) { * @ingroup lock */ public static function lock() { - return static::$container->get('lock'); + return static::getContainer(TRUE)->get('lock'); } /** @@ -302,7 +331,7 @@ public static function lock() { * An immutable configuration object. */ public static function config($name) { - return static::$container->get('config.factory')->get($name); + return static::getContainer(TRUE)->get('config.factory')->get($name); } /** @@ -316,7 +345,7 @@ public static function config($name) { * The configuration factory service. */ public static function configFactory() { - return static::$container->get('config.factory'); + return static::getContainer(TRUE)->get('config.factory'); } /** @@ -342,7 +371,7 @@ public static function configFactory() { * The queue object for a given name. */ public static function queue($name, $reliable = FALSE) { - return static::$container->get('queue')->get($name, $reliable); + return static::getContainer(TRUE)->get('queue')->get($name, $reliable); } /** @@ -354,7 +383,7 @@ public static function queue($name, $reliable = FALSE) { * @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface */ public static function keyValue($collection) { - return static::$container->get('keyvalue')->get($collection); + return static::getContainer(TRUE)->get('keyvalue')->get($collection); } /** @@ -369,7 +398,7 @@ public static function keyValue($collection) { * @return \Drupal\Core\State\StateInterface */ public static function state() { - return static::$container->get('state'); + return static::getContainer(TRUE)->get('state'); } /** @@ -379,7 +408,7 @@ public static function state() { * A guzzle http client instance. */ public static function httpClient() { - return static::$container->get('http_client'); + return static::getContainer(TRUE)->get('http_client'); } /** @@ -396,7 +425,7 @@ public static function httpClient() { * The query object that can query the given entity type. */ public static function entityQuery($entity_type, $conjunction = 'AND') { - return static::$container->get('entity.query')->get($entity_type, $conjunction); + return static::getContainer(TRUE)->get('entity.query')->get($entity_type, $conjunction); } /** @@ -413,7 +442,7 @@ public static function entityQuery($entity_type, $conjunction = 'AND') { * The query object that can query the given entity type. */ public static function entityQueryAggregate($entity_type, $conjunction = 'AND') { - return static::$container->get('entity.query')->getAggregate($entity_type, $conjunction); + return static::getContainer(TRUE)->get('entity.query')->getAggregate($entity_type, $conjunction); } /** @@ -422,7 +451,7 @@ public static function entityQueryAggregate($entity_type, $conjunction = 'AND') * @return \Drupal\Core\Flood\FloodInterface */ public static function flood() { - return static::$container->get('flood'); + return static::getContainer(TRUE)->get('flood'); } /** @@ -431,7 +460,7 @@ public static function flood() { * @return \Drupal\Core\Extension\ModuleHandlerInterface */ public static function moduleHandler() { - return static::$container->get('module_handler'); + return static::getContainer(TRUE)->get('module_handler'); } /** @@ -445,7 +474,7 @@ public static function moduleHandler() { * @see \Drupal\Core\TypedData\TypedDataManager::create() */ public static function typedDataManager() { - return static::$container->get('typed_data_manager'); + return static::getContainer(TRUE)->get('typed_data_manager'); } /** @@ -455,7 +484,7 @@ public static function typedDataManager() { * The token service. */ public static function token() { - return static::$container->get('token'); + return static::getContainer(TRUE)->get('token'); } /** @@ -465,7 +494,7 @@ public static function token() { * The url generator service. */ public static function urlGenerator() { - return static::$container->get('url_generator'); + return static::getContainer(TRUE)->get('url_generator'); } /** @@ -494,7 +523,7 @@ public static function urlGenerator() { * @see \Drupal\Core\Url::fromUri() */ public static function url($route_name, $route_parameters = array(), $options = array()) { - return static::$container->get('url_generator')->generateFromRoute($route_name, $route_parameters, $options); + return static::getContainer(TRUE)->get('url_generator')->generateFromRoute($route_name, $route_parameters, $options); } /** @@ -503,7 +532,7 @@ public static function url($route_name, $route_parameters = array(), $options = * @return \Drupal\Core\Utility\LinkGeneratorInterface */ public static function linkGenerator() { - return static::$container->get('link_generator'); + return static::getContainer(TRUE)->get('link_generator'); } /** @@ -525,7 +554,7 @@ public static function linkGenerator() { * @see \Drupal\Core\Url */ public static function l($text, Url $url) { - return static::$container->get('link_generator')->generate($text, $url); + return static::getContainer(TRUE)->get('link_generator')->generate($text, $url); } /** @@ -535,7 +564,7 @@ public static function l($text, Url $url) { * The string translation manager. */ public static function translation() { - return static::$container->get('string_translation'); + return static::getContainer(TRUE)->get('string_translation'); } /** @@ -545,7 +574,7 @@ public static function translation() { * The language manager. */ public static function languageManager() { - return static::$container->get('language_manager'); + return static::getContainer(TRUE)->get('language_manager'); } /** @@ -562,7 +591,7 @@ public static function languageManager() { * @see \Drupal\Core\Session\SessionManager::start() */ public static function csrfToken() { - return static::$container->get('csrf_token'); + return static::getContainer(TRUE)->get('csrf_token'); } /** @@ -572,7 +601,7 @@ public static function csrfToken() { * The transliteration manager. */ public static function transliteration() { - return static::$container->get('transliteration'); + return static::getContainer(TRUE)->get('transliteration'); } /** @@ -582,7 +611,7 @@ public static function transliteration() { * The form builder. */ public static function formBuilder() { - return static::$container->get('form_builder'); + return static::getContainer(TRUE)->get('form_builder'); } /** @@ -591,7 +620,7 @@ public static function formBuilder() { * @return \Drupal\Core\Theme\ThemeManagerInterface */ public static function theme() { - return static::$container->get('theme.manager'); + return static::getContainer(TRUE)->get('theme.manager'); } /** @@ -601,7 +630,7 @@ public static function theme() { * Returns TRUE is syncing flag set. */ public static function isConfigSyncing() { - return static::$container->get('config.installer')->isSyncing(); + return static::getContainer(TRUE)->get('config.installer')->isSyncing(); } /** @@ -615,7 +644,7 @@ public static function isConfigSyncing() { * The logger for this channel. */ public static function logger($channel) { - return static::$container->get('logger.factory')->get($channel); + return static::getContainer(TRUE)->get('logger.factory')->get($channel); } /** @@ -625,7 +654,7 @@ public static function logger($channel) { * The menu tree. */ public static function menuTree() { - return static::$container->get('menu.link_tree'); + return static::getContainer(TRUE)->get('menu.link_tree'); } /** @@ -634,7 +663,7 @@ public static function menuTree() { * @return \Drupal\Core\Path\PathValidatorInterface */ public static function pathValidator() { - return static::$container->get('path.validator'); + return static::getContainer(TRUE)->get('path.validator'); } /** @@ -644,7 +673,7 @@ public static function pathValidator() { * The access manager service. */ public static function accessManager() { - return static::$container->get('access_manager'); + return static::getContainer(TRUE)->get('access_manager'); } } diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerNotInitializedException.php b/core/lib/Drupal/Core/DependencyInjection/ContainerNotInitializedException.php new file mode 100644 index 0000000..1ef7ebd --- /dev/null +++ b/core/lib/Drupal/Core/DependencyInjection/ContainerNotInitializedException.php @@ -0,0 +1,18 @@ +container = NULL; - \Drupal::setContainer(NULL); + \Drupal::unsetContainer(); // Unset globals. unset($GLOBALS['config_directories']); diff --git a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php index a7bcca7..43dee4f 100644 --- a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php +++ b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php @@ -19,7 +19,7 @@ class GetFilenameUnitTest extends KernelTestBase { protected function setUp() { parent::setUp(); $this->container = NULL; - \Drupal::setContainer(NULL); + \Drupal::unsetContainer(); } /** diff --git a/core/tests/Drupal/Tests/Core/DrupalContainerNotInitializedTest.php b/core/tests/Drupal/Tests/Core/DrupalContainerNotInitializedTest.php new file mode 100644 index 0000000..9bdf238 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/DrupalContainerNotInitializedTest.php @@ -0,0 +1,112 @@ +root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))); }