diff --git a/core/core.services.yml b/core/core.services.yml index ac24e17..bffac1b 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -464,7 +464,7 @@ services: class: Drupal\Core\Access\CsrfTokenGenerator arguments: ['@private_key'] calls: - - [setCurrentUser, ['@?current_user']] + - [setCurrentUser, ['@?current_user=']] access_manager: class: Drupal\Core\Access\AccessManager arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager'] @@ -498,6 +498,7 @@ services: - { name: access_check, applies_to: _entity_create_access } access_check.theme: class: Drupal\Core\Theme\ThemeAccessCheck + arguments: ['@theme_handler'] tags: - { name: access_check, applies_to: _access_theme } access_check.custom: @@ -686,7 +687,7 @@ services: class: Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry theme.registry: class: Drupal\Core\Theme\Registry - arguments: ['@cache.cache', '@lock', '@module_handler'] + arguments: ['@cache.cache', '@lock', '@module_handler', '@theme.negotiator'] tags: - { name: needs_destruction } authentication: diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 7962015..703024a 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1334,6 +1334,10 @@ function drupal_anonymous_user() { $request = \Drupal::request(); $hostname = $request->getClientIP(); } + catch (InvalidArgumentException $e) { + // We are not in a request context. + $hostname = ''; + } catch (DependencyInjectionRuntimeException $e) { // We are not in a request context. $hostname = ''; diff --git a/core/includes/common.inc b/core/includes/common.inc index d18c0c1..4b3ba50 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2253,7 +2253,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS // Don't add settings if there is no other JavaScript on the page, unless // this is an AJAX request. if (!empty($items['settings']) || $is_ajax) { - global $theme_key; + $theme_key = \Drupal::themeNegotiator()->getActiveTheme(); // Provide the page with information about the theme that's used, so that // a later AJAX request can be rendered using the same theme. // @see \Drupal\Core\Theme\AjaxBasePageNegotiator @@ -4560,9 +4560,9 @@ function drupal_render_cache_by_query($query, $function, $expire = Cache::PERMAN * $granularity was passed in, more parts are added. */ function drupal_render_cid_parts($granularity = NULL) { - global $theme, $base_root; + global $base_root; - $cid_parts[] = $theme; + $cid_parts[] = \Drupal::themeNegotiator()->getActiveTheme(); // If we have only one language enabled we do not need it as cid part. $language_manager = \Drupal::languageManager(); diff --git a/core/includes/theme.inc b/core/includes/theme.inc index cfd8427..cdb9f80 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -739,7 +739,7 @@ function drupal_find_theme_templates($cache, $extension, $path) { } } } - global $theme; + $theme = \Drupal::themeNegotiator()->getActiveTheme(); $subtheme_paths = isset($theme_paths[$theme]) ? $theme_paths[$theme] : array(); // Escape the periods in the extension. @@ -841,7 +841,7 @@ function theme_get_setting($setting_name, $theme = NULL) { // If no key is given, use the current theme if we can determine it. if (!isset($theme)) { - $theme = !empty($GLOBALS['theme_key']) ? $GLOBALS['theme_key'] : ''; + $theme = \Drupal::themeNegotiator()->getActiveTheme(); } if (empty($cache[$theme])) { @@ -2247,7 +2247,8 @@ function template_preprocess_maintenance_page(&$variables) { drupal_render($build); } - foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) { + $theme = \Drupal::themeNegotiator()->getActiveTheme(); + foreach (system_region_list($theme) as $region_key => $region_name) { if (!isset($variables[$region_key])) { $variables[$region_key] = array(); } diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index 429b932..57e6d31 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -15,12 +15,13 @@ * complete. Seven is always used for the initial install and update * operations. In other cases, Bartik is used, but this can be overridden by * setting a "maintenance_theme" key in the $settings variable in settings.php. + * + * @todo Figure out whether this logic could be put into a theme negotiator + * itself. */ function _drupal_maintenance_theme() { - global $theme, $theme_key; - // If $theme is already set, assume the others are set too, and do nothing. - if (isset($theme)) { + if (\Drupal::themeNegotiator()->hasActiveTheme()) { return; } @@ -88,6 +89,7 @@ function _drupal_maintenance_theme() { // Store the identifier for retrieving theme settings with. $theme_key = $theme; + \Drupal::themeNegotiator()->setActiveTheme($theme_key); // Find all our ancestor themes and put them in an array. $base_theme = array(); diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php index a646096..00b14dd 100644 --- a/core/lib/Drupal.php +++ b/core/lib/Drupal.php @@ -403,6 +403,15 @@ public static function moduleHandler() { } /** + * Returns the theme negotiator. + * + * @return \Drupal\Core\Theme\ThemeNegotiator + */ + public static function themeNegotiator() { + return static::$container->get('theme.negotiator'); + } + + /** * Returns the typed data manager service. * * Use the typed data manager service for creating typed data objects. diff --git a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php index ae108dc..c7c21e8 100644 --- a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php +++ b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Authentication\Provider; use Drupal\Core\Authentication\AuthenticationProviderInterface; +use Drupal\Core\Database\Database; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; @@ -33,6 +34,9 @@ public function authenticate(Request $request) { // Global $user is deprecated, but the session system is still based on it. global $user; require_once DRUPAL_ROOT . '/' . settings()->get('session_inc', 'core/includes/session.inc'); + if (!Database::getConnection()->schema()->tableExists('users')) { + return NULL; + } drupal_session_initialize(); if (drupal_session_started()) { return $user; diff --git a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php index 2389a62..9ea4ff6 100644 --- a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php +++ b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php @@ -75,6 +75,7 @@ public function alter(ContainerBuilder $container) { $definition = $container->getDefinition($id); $definition->clearTag('persist'); } + $container->set('current_user', drupal_anonymous_user()); } } diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php index e84b33b..f25f9d7 100644 --- a/core/lib/Drupal/Core/Theme/Registry.php +++ b/core/lib/Drupal/Core/Theme/Registry.php @@ -115,6 +115,13 @@ class Registry implements DestructableInterface { protected $runtimeRegistry; /** + * The theme negotiation. + * + * @var \Drupal\Core\Theme\ThemeNegotiator + */ + protected $theme_negotiator; + + /** * Constructs a \Drupal\Core\\Theme\Registry object. * * @param \Drupal\Core\Cache\CacheBackendInterface $cache @@ -123,13 +130,16 @@ class Registry implements DestructableInterface { * The lock backend. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler to use to load modules. + * @param \Drupal\Core\Theme\ThemeNegotiator $theme_negotiator + * The theme negotiator. * @param string $theme_name * (optional) The name of the theme for which to construct the registry. */ - public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, $theme_name = NULL) { + public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, ThemeNegotiator $theme_negotiator, $theme_name = NULL) { $this->cache = $cache; $this->lock = $lock; $this->moduleHandler = $module_handler; + $this->themeNegotiator = $theme_negotiator; $this->init($theme_name); } @@ -147,14 +157,14 @@ protected function init($theme_name = NULL) { if (!isset($theme_name)) { // #1: The theme registry might get instantiated before the theme was // initialized. Cope with that. - if (!isset($GLOBALS['theme_info']) || !isset($GLOBALS['theme'])) { + if (!isset($GLOBALS['theme_info']) || !$this->themeNegotiator->hasActiveTheme()) { unset($this->runtimeRegistry); unset($this->registry); drupal_theme_initialize(); } // #2: The testing framework only cares for the global $theme variable at // this point. Cope with that. - if ($GLOBALS['theme'] != $GLOBALS['theme_info']->getName()) { + if ($this->themeNegotiator->getActiveTheme() != $GLOBALS['theme_info']->getName()) { unset($this->runtimeRegistry); unset($this->registry); $this->initializeTheme(); diff --git a/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php index 75afddc..121fa6b 100644 --- a/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php +++ b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Theme; +use Drupal\Core\Extension\ThemeHandlerInterface; use Drupal\Core\Routing\Access\AccessInterface; use Drupal\Core\Session\AccountInterface; use Symfony\Component\HttpFoundation\Request; @@ -18,6 +19,23 @@ class ThemeAccessCheck implements AccessInterface { /** + * The theme handler. + * + * @var \Drupal\Core\Extension\ThemeHandlerInterface + */ + protected $themeHandler; + + /** + * Constructs a ThemeAccessCheck instance. + * + * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler + * The theme handler. + */ + public function __construct(ThemeHandlerInterface $theme_handler) { + $this->themeHandler = $theme_handler; + } + + /** * {@inheritdoc} */ public function access(Route $route, Request $request, AccountInterface $account) { @@ -34,7 +52,7 @@ public function access(Route $route, Request $request, AccountInterface $account * TRUE if the theme is enabled, FALSE otherwise. */ public function checkAccess($theme) { - $themes = list_themes(); + $themes = $this->themeHandler->listInfo(); return !empty($themes[$theme]->status); } diff --git a/core/lib/Drupal/Core/Theme/ThemeNegotiator.php b/core/lib/Drupal/Core/Theme/ThemeNegotiator.php index 21ba80c..285f471 100644 --- a/core/lib/Drupal/Core/Theme/ThemeNegotiator.php +++ b/core/lib/Drupal/Core/Theme/ThemeNegotiator.php @@ -118,6 +118,23 @@ public function getActiveTheme() { } /** + * Is there already an active theme. + */ + public function hasActiveTheme() { + return $this->request->attributes->has('_theme_active'); + } + + /** + * Sets the current active theme for the request. + * + * @param string $theme + * The theme name. + */ + public function setActiveTheme($theme) { + $this->request->attributes->set('_theme_active', $theme); + } + + /** * {@inheritdoc} */ public function applies(Request $request) { diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 1bca18b..4af3f42 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -112,10 +112,9 @@ function block_menu_link_defaults() { * Renders blocks into their regions. */ function block_page_build(&$page) { - global $theme; - // The theme system might not yet be initialized. We need $theme. drupal_theme_initialize(); + $theme = \Drupal::themeNegotiator()->getActiveTheme(); // Fetch a list of regions for the current theme. $all_regions = system_region_list($theme); @@ -326,7 +325,7 @@ function block_list($region) { $blocks = &drupal_static(__FUNCTION__); if (!isset($blocks)) { - global $theme; + $theme = \Drupal::themeNegotiator()->getActiveTheme(); $blocks = array(); foreach (entity_load_multiple_by_properties('block', array('theme' => $theme)) as $block_id => $block) { // Onlye include valid blocks in the list. diff --git a/core/modules/block/lib/Drupal/block/BlockListController.php b/core/modules/block/lib/Drupal/block/BlockListController.php index 65db261..d6b271f 100644 --- a/core/modules/block/lib/Drupal/block/BlockListController.php +++ b/core/modules/block/lib/Drupal/block/BlockListController.php @@ -87,7 +87,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI public function load() { // If no theme was specified, use the current theme. if (!$this->theme) { - $this->theme = $GLOBALS['theme']; + $this->theme = \Drupal::themeNegotiator()->getActiveTheme(); } // Store the region list. @@ -117,7 +117,7 @@ public function load() { public function render($theme = NULL, Request $request = NULL) { $this->request = $request; // If no theme was specified, use the current theme. - $this->theme = $theme ?: $GLOBALS['theme_key']; + $this->theme = $theme ?: \Drupal::themeNegotiator()->getActiveTheme();; return drupal_get_form($this); } diff --git a/core/modules/color/color.module b/core/modules/color/color.module index 7809f5f..f9da95a 100644 --- a/core/modules/color/color.module +++ b/core/modules/color/color.module @@ -62,7 +62,7 @@ function color_form_system_theme_settings_alter(&$form, &$form_state) { * Replaces style sheets with color-altered style sheets. */ function color_css_alter(&$css) { - global $theme_key; + $theme_key = \Drupal::themeNegotiator()->getActiveTheme(); $themes = list_themes(); // Override stylesheets. @@ -92,7 +92,7 @@ function color_css_alter(&$css) { * Replace the logo with the colored version if available. */ function color_preprocess_page(&$variables) { - global $theme_key; + $theme_key = \Drupal::themeNegotiator()->getActiveTheme(); // Override logo. $logo = \Drupal::config('color.' . $theme_key)->get('logo'); diff --git a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php index 9459aad..137bd64 100644 --- a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php +++ b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php @@ -282,8 +282,8 @@ public function buildForm(array $form, array &$form_state, $theme = '') { // Save the name of the current theme (if any), so that we can temporarily // override the current theme and allow theme_get_setting() to work // without having to pass the theme name to it. - $default_theme = !empty($GLOBALS['theme_key']) ? $GLOBALS['theme_key'] : NULL; - $GLOBALS['theme_key'] = $theme; + $default_theme = \Drupal::themeNegotiator()->getActiveTheme(); + \Drupal::themeNegotiator()->setActiveTheme($theme); // Process the theme and all its base themes. foreach ($theme_keys as $theme) { @@ -302,10 +302,10 @@ public function buildForm(array $form, array &$form_state, $theme = '') { // Restore the original current theme. if (isset($default_theme)) { - $GLOBALS['theme_key'] = $default_theme; + \Drupal::themeNegotiator()->setActiveTheme($default_theme); } else { - unset($GLOBALS['theme_key']); + \Drupal::themeNegotiator()->setActiveTheme(NULL); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/AlterTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/AlterTest.php index e02c590..e249652 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/AlterTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/AlterTest.php @@ -35,8 +35,8 @@ public static function getInfo() { function testDrupalAlter() { // This test depends on Bartik, so make sure that it is always the current // active theme. - global $theme, $base_theme_info; - $theme = 'bartik'; + global $base_theme_info; + \Drupal::themeNegotiator()->setActiveTheme('bartik'); $base_theme_info = array(); $array = array('foo' => 'bar'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php index e8b8201..6450010 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php @@ -25,7 +25,7 @@ public static function getInfo() { * Tests setting and retrieving content for theme regions. */ function testRegions() { - global $theme_key; + $theme_key = \Drupal::themeNegotiator()->getActiveTheme(); $block_regions = array_keys(system_region_list($theme_key)); $delimiter = $this->randomName(32); diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php index 638d8e5..1f08a89 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php @@ -223,7 +223,7 @@ function testListThemes() { * Test the theme_get_setting() function. */ function testThemeGetSetting() { - $GLOBALS['theme_key'] = 'test_theme'; + \Drupal::themeNegotiator()->setActiveTheme('test_theme'); $this->assertIdentical(theme_get_setting('theme_test_setting'), 'default value', 'theme_get_setting() uses the default theme automatically.'); $this->assertNotEqual(theme_get_setting('subtheme_override', 'test_basetheme'), theme_get_setting('subtheme_override', 'test_subtheme'), 'Base theme\'s default settings values can be overridden by subtheme.'); $this->assertIdentical(theme_get_setting('basetheme_only', 'test_subtheme'), 'base theme value', 'Base theme\'s default settings values are inherited by subtheme.'); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 65a8796..bbbc177 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -1896,7 +1896,7 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl function system_page_alter(&$page) { // Find all non-empty page regions, and add a theme wrapper function that // allows them to be consistently themed. - $regions = system_region_list($GLOBALS['theme']); + $regions = system_region_list(\Drupal::themeNegotiator()->getActiveTheme()); foreach (array_keys($regions) as $region) { if (!empty($page[$region])) { $page[$region]['#theme_wrappers'][] = 'region'; diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module index b97f966..96d39c2 100644 --- a/core/modules/system/tests/modules/batch_test/batch_test.module +++ b/core/modules/system/tests/modules/batch_test/batch_test.module @@ -374,8 +374,7 @@ function _batch_test_theme_callback() { // theme is being used on the batch processing page by viewing that page // directly. Instead, we save the theme being used in a variable here, so // that it can be loaded and inspected in the thread running the test. - global $theme; - batch_test_stack($theme); + batch_test_stack(\Drupal::themeNegotiator()->getActiveTheme()); } /** diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/system/tests/modules/menu_test/menu_test.module index 08e6382..aecd648 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.module +++ b/core/modules/system/tests/modules/menu_test/menu_test.module @@ -262,9 +262,9 @@ function menu_test_custom_403_404_callback() { * @deprecated Use \Drupal\menu_test\Controller\MenuTestController::themePage() */ function menu_test_theme_page_callback($inherited = FALSE) { - global $theme_key; // Initialize the theme system so that $theme_key will be populated. drupal_theme_initialize(); + $theme_key = \Drupal::themeNegotiator()->getActiveTheme(); // Now we check what the theme negotiator service returns. $active_theme = \Drupal::service('theme.negotiator')->getActiveTheme('getActiveTheme'); $output = "Active theme: $active_theme. Actual theme: $theme_key."; diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php index 665b7a5..2d1e0d0 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php @@ -314,7 +314,7 @@ public function generateOutputKey() { 'result' => $this->view->result, 'roles' => $user->getRoles(), 'super-user' => $user->id() == 1, // special caching for super user. - 'theme' => $GLOBALS['theme'], + 'theme' => \Drupal::themeNegotiator()->getActiveTheme(), 'langcode' => \Drupal::languageManager()->getCurrentLanguage()->id, 'base_url' => $GLOBALS['base_url'], );