diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 60b086a..8fad9b1 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2744,73 +2744,29 @@ function get_t() { * @see language() */ function drupal_language_initialize() { - if (language_multilingual()) { - $types = language_types_get_all(); - foreach ($types as $type) { - language($type); - } - // Allow modules to react on language system initialization in multilingual - // environments. - bootstrap_invoke_all('language_init'); - // @todo D8: Remove after http://drupal.org/node/1859110. - drupal_container()->get('config.factory')->reset(); - } + drupal_container()->get('language_manager')->init(); } /** * Returns the language object for a given language type. * - * The 'language_manager' service is only available within the scope of a kernel - * request. When it's not available, we return a default language object, - * regardless of the type passed in. - * * @see Drupal\Core\Language\LanguageManager * * @param string $type * The type of language object needed, e.g. LANGUAGE_TYPE_INTERFACE. - * @param bool $reset - * TRUE to reset the statically cached language object for the type, or for - * all types if $type is NULL. - */ -function language($type, $reset = FALSE) { - // We don't use drupal_static() here because resetting is not a simple case of - // drupal_static_reset(). - static $languages = array(); - - // Reset the language manager's cache and our own. - if ($reset) { - if (drupal_container()->isScopeActive('request')) { - drupal_container()->get('language_manager')->reset($type); - } - if (!isset($type)) { - $languages = array(); - } - elseif (isset($languages[$type])) { - unset($languages[$type]); - } - } - - // If no type is passed (most likely when resetting all types), return. - if (!isset($type)) { - return; - } - - // When the language_manager service exists (is both defined and the 'request' - // scope is active in the container), use it to get the language. Otherwise - // return the default language. - if (drupal_container()->isScopeActive('request')) { - $language_manager = drupal_container()->get('language_manager', Container::NULL_ON_INVALID_REFERENCE); - } - - if (isset($language_manager)) { - return $language_manager->getLanguage($type); + */ +function language($type) { + $container = drupal_container(); + if (!$container) { + return language_default(); } - else { - if (!isset($languages[$type])) { - $languages[$type] = language_default(); - } - return $languages[$type]; + if (!$container->has('language_manager')) { + // This happens in rare situations when the container has not been built by + // a kernel and has no services e.g. when t() is called during unit tests for + // assertions. + $container->register('language_manager', 'Drupal\Core\Language\LanguageManager'); } + return $container->get('language_manager')->getLanguage($type); } /** @@ -3016,6 +2972,21 @@ function language_default() { } /** + * Store or retrieve the path derived during language negotiation. + * + * @todo Replace this with a path processor in language module. See + * http://drupal.org/node/1888424. + */ +function _language_resolved_path($new_path = NULL) { + $path = &drupal_static(__FUNCTION__, NULL); + if ($new_path === NULL) { + return $path; + } + $path = $new_path; + return $path; +} + +/** * Returns the requested URL path of the page being viewed. * * Examples: diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 01bde01..b06a8cc 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -339,6 +339,9 @@ function install_begin_request(&$install_state) { ->addArgument(new Reference('config.storage')) ->addArgument(new Reference('event_dispatcher')); + // Register the 'language_manager' service. + $container->register('language_manager', 'Drupal\Core\Language\LanguageManager'); + // The install process cannot use the database lock backend since the database // is not fully up, so we use a null backend implementation during the // installation process. This will also speed up the installation process. diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 624c716..aecb0cc 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -94,7 +94,8 @@ public function build(ContainerBuilder $container) { $container->register('path.alias_manager', 'Drupal\Core\Path\AliasManager') ->addArgument(new Reference('database')) - ->addArgument(new Reference('keyvalue')); + ->addArgument(new Reference('state')) + ->addArgument(new Reference('language_manager')); $container->register('http_client_simpletest_subscriber', 'Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber'); $container->register('http_default_client', 'Guzzle\Http\Client') @@ -138,9 +139,10 @@ public function build(ContainerBuilder $container) { ->addArgument(new Reference('event_dispatcher')) ->addArgument(new Reference('service_container')) ->addArgument(new Reference('controller_resolver')); - $container->register('language_manager', 'Drupal\Core\Language\LanguageManager') - ->addArgument(new Reference('request')) - ->setScope('request'); + + // Register the 'language_manager' service. + $container->register('language_manager', 'Drupal\Core\Language\LanguageManager'); + $container->register('database.slave', 'Drupal\Core\Database\Connection') ->setFactoryClass('Drupal\Core\Database\Database') ->setFactoryMethod('getConnection') @@ -234,6 +236,9 @@ public function build(ContainerBuilder $container) { ->addTag('event_subscriber'); $container->register('config_global_override_subscriber', 'Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber') ->addTag('event_subscriber'); + $container->register('language_request_subscriber', 'Drupal\Core\EventSubscriber\LanguageRequestSubscriber') + ->addArgument(new Reference('language_manager')) + ->addTag('event_subscriber'); $container->register('exception_controller', 'Drupal\Core\ExceptionController') ->addArgument(new Reference('content_negotiation')) diff --git a/core/lib/Drupal/Core/EventSubscriber/LanguageRequestSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/LanguageRequestSubscriber.php new file mode 100644 index 0000000..3e00a91 --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/LanguageRequestSubscriber.php @@ -0,0 +1,50 @@ +languageManager = $language_manager; + } + + /** + * Sets the request on the language manager. + * + * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event + * The Event to process. + */ + public function onKernelRequestLanguage(GetResponseEvent $event) { + if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) { + $this->languageManager->setRequest($event->getRequest()); + } + } + + /** + * Registers the methods in this class that should be listeners. + * + * @return array + * An array of event listener definitions. + */ + static function getSubscribedEvents() { + $events[KernelEvents::REQUEST][] = array('onKernelRequestLanguage', 300); + + return $events; + } +} diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php index be0e779..698057b 100644 --- a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php @@ -77,22 +77,15 @@ public function onKernelRequestFrontPageResolve(GetResponseEvent $event) { /** * Decode language information embedded in the request path. * - * @todo Refactor this entire method to inline the relevant portions of - * drupal_language_initialize(). See the inline comment for more details. - * * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The Event to process. */ public function onKernelRequestLanguageResolve(GetResponseEvent $event) { - // drupal_language_initialize() combines: - // - Determination of language from $request information (e.g., path). - // - Determination of language from other information (e.g., site default). - // - Population of determined language into drupal_container(). - // - Removal of language code from _current_path(). - // @todo Decouple the above, but for now, invoke it and update the path - // prior to front page and alias resolution. When above is decoupled, also - // add 'langcode' (determined from $request only) to $request->attributes. - drupal_language_initialize(); + $request = $event->getRequest(); + $path = _language_resolved_path(); + if ($path !== NULL) { + $this->setPath($request, $path); + } } /** diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index ff0177d..5ee33d9 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -2,52 +2,145 @@ /** * @file - * Definition of Drupal\Core\Language\LanguageManager. + * Contains Drupal\Core\Language\LanguageManager. */ namespace Drupal\Core\Language; +use Drupal\Core\Config\ConfigFactory; use Symfony\Component\HttpFoundation\Request; /** * Class responsible for initializing each language type. - * - * This service is dependent on the 'request' service and can therefore pass the - * Request object to the code that deals with each particular language type. - * This means the Request can be used directly for things like URL-based - * language negotiation. */ class LanguageManager { - private $request; - private $languages; + /** + * A request object. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; - public function __construct(Request $request = NULL) { + /** + * An array of language objects keyed by language type. + * + * @var array + */ + protected $languages; + + /** + * Whether or not the language manager has been initialized. + * + * @var boolean + */ + protected $initialized = FALSE; + + /** + * Whether already in the process of language initialization. + * + * @todo This is only needed due to the circular dependency between language + * and config. See http://drupal.org/node/1862202 for the plan to fix this. + */ + protected $initializing = FALSE; + + /** + * Initializes each language type to a language object. + */ + public function init() { + if ($this->initialized) { + return; + } + if ($this->getLanguageCount() > 1) { + foreach ($this->getLanguageTypes() as $type) { + $this->getLanguage($type); + } + } + $this->initialized = TRUE; + } + + /** + * Sets the $request property and resets all language types. + */ + public function setRequest(Request $request) { $this->request = $request; + $this->reset(); + $this->init(); } + /** + * Returns a language object for the given type. + */ public function getLanguage($type) { if (isset($this->languages[$type])) { return $this->languages[$type]; } // @todo Objectify the language system so that we don't have to do this. - if (language_multilingual()) { - include_once DRUPAL_ROOT . '/core/includes/language.inc'; - $this->languages[$type] = language_types_initialize($type, $this->request); + if ($this->getLanguageCount() > 1 && $this->request) { + if (!$this->initializing) { + $this->initializing = TRUE; + include_once DRUPAL_ROOT . '/core/includes/language.inc'; + $this->languages[$type] = language_types_initialize($type, $this->request); + $this->initializing = FALSE; + } + else { + // Config has called getLanguage() during initialization of a language + // type. Simply return the default language without setting it on the + // $this->languages property. See the TODO in the docblock for the + // $initializing property. + return new Language($this->getLanguageDefault() + array('default' => TRUE)); + } } else { - $this->languages[$type] = language_default(); + $this->languages[$type] = new Language($this->getLanguageDefault() + array('default' => TRUE)); } return $this->languages[$type]; } + /** + * Resets the given language type or all types if none specified. + */ public function reset($type = NULL) { if (!isset($type)) { $this->languages = array(); + $this->initialized = FALSE; } elseif (isset($this->languages[$type])) { unset($this->languages[$type]); } } + + /** + * @todo Inject state once these variables have been converted to use the + * state system, then remove these methods and replace calls to them with + * $this->state->get('language_count') etc. + */ + + /** + * Returns the number of currently enabled langauges. + */ + protected function getLanguageCount() { + return variable_get('language_count', 1); + } + + /** + * Returns the array of language types. + */ + protected function getLanguageTypes() { + return array_keys(variable_get('language_types', language_types_get_default())); + } + + /** + * Returns an array of information representing the current default language. + */ + protected function getLanguageDefault() { + return variable_get('language_default', array( + 'langcode' => 'en', + 'name' => 'English', + 'direction' => 0, + 'weight' => 0, + 'locked' => 0, + )); + } } diff --git a/core/lib/Drupal/Core/Path/AliasManager.php b/core/lib/Drupal/Core/Path/AliasManager.php index 47bf77b..45bdca2 100644 --- a/core/lib/Drupal/Core/Path/AliasManager.php +++ b/core/lib/Drupal/Core/Path/AliasManager.php @@ -8,7 +8,8 @@ namespace Drupal\Core\Path; use Drupal\Core\Database\Connection; -use Drupal\Core\KeyValueStore\KeyValueFactory; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; +use Drupal\Core\Language\LanguageManager; class AliasManager implements AliasManagerInterface { @@ -27,11 +28,11 @@ class AliasManager implements AliasManagerInterface { protected $state; /** - * The default langcode to use when none is specified for path lookups. + * Language manager for retrieving the default langcode when none is specified. * - * @var string + * @var \Drupal\Core\Language\LanguageManager */ - protected $langcode; + protected $languageManager; /** * Holds the map of path lookups per language. @@ -78,11 +79,12 @@ class AliasManager implements AliasManagerInterface { */ protected $preloadedPathLookups = array(); - public function __construct(Connection $connection, KeyValueFactory $keyvalue) { + public function __construct(Connection $connection, KeyValueStoreInterface $state, LanguageManager $language_manager) { $this->connection = $connection; - $this->state = $keyvalue->get('state'); - $this->langcode = language(LANGUAGE_TYPE_URL)->langcode; + $this->state = $state; + $this->languageManager = $language_manager; $this->whitelist = $this->state->get('system.path_alias_whitelist', NULL); + if (!isset($this->whitelist)) { $this->whitelist = $this->pathAliasWhitelistRebuild(); } @@ -96,7 +98,7 @@ public function getSystemPath($path, $path_language = NULL) { // language. If we used a language different from the one conveyed by the // requested URL, we might end up being unable to check if there is a path // alias matching the URL path. - $path_language = $path_language ?: $this->langcode; + $path_language = $path_language ?: $this->languageManager->getLanguage(LANGUAGE_TYPE_URL)->langcode; $original_path = $path; // Lookup the path alias first. if (!empty($path) && $source = $this->lookupPathSource($path, $path_language)) { @@ -114,7 +116,7 @@ public function getPathAlias($path, $path_language = NULL) { // language. If we used a language different from the one conveyed by the // requested URL, we might end up being unable to check if there is a path // alias matching the URL path. - $path_language = $path_language ?: $this->langcode; + $path_language = $path_language ?: $this->languageManager->getLanguage(LANGUAGE_TYPE_URL)->langcode; $result = $path; if (!empty($path) && $alias = $this->lookupPathAlias($path, $path_language)) { $result = $alias; diff --git a/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php b/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php index 350a166..20f835d 100644 --- a/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php +++ b/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php @@ -33,10 +33,6 @@ function testLocaleConfigOverride() { $name = 'config_test.system'; // Verify the default configuration values exist. $config = config($name); - $this->assertIdentical($config->get('foo'), 'bar'); - // Spoof multilingual. - $GLOBALS['conf']['language_count'] = 2; - drupal_language_initialize(); $this->assertIdentical($config->get('foo'), 'en bar'); } } diff --git a/core/modules/language/language.module b/core/modules/language/language.module index 3486ff4..d0b91bf 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -507,7 +507,6 @@ function language_save($language) { if (!empty($language->default)) { // Set the new version of this language as default in a variable. - $default_language = language_default(); variable_set('language_default', (array) $language); } diff --git a/core/modules/language/language.negotiation.inc b/core/modules/language/language.negotiation.inc index 8bf45a6..c654d84 100644 --- a/core/modules/language/language.negotiation.inc +++ b/core/modules/language/language.negotiation.inc @@ -209,11 +209,12 @@ function language_from_user($languages) { * @return * A valid language code on success, FALSE otherwise. */ -function language_from_user_admin($languages) { +function language_from_user_admin($languages, $request = NULL) { // User preference (only for authenticated users). global $user; - if ($user->uid && !empty($user->preferred_admin_langcode) && isset($languages[$user->preferred_admin_langcode]) && path_is_admin(current_path())) { + $request_path = $request ? urldecode(trim($request->getPathInfo(), '/')) : _current_path(); + if ($user->uid && !empty($user->preferred_admin_langcode) && isset($languages[$user->preferred_admin_langcode]) && path_is_admin($request_path)) { return $user->preferred_admin_langcode; } @@ -273,15 +274,11 @@ function language_from_url($languages, $request) { switch (config('language.negotiation')->get('url.source')) { case LANGUAGE_NEGOTIATION_URL_PREFIX: - $current_path = $request->attributes->get('system_path'); - if (!isset($current_path)) { - $current_path = trim($request->getPathInfo(), '/'); - } + $request_path = urldecode(trim($request->getPathInfo(), '/')); - list($language, $path) = language_url_split_prefix($current_path, $languages); - // Store the correct system path, i.e. minus the path prefix, in the - // request. - $request->attributes->set('system_path', $path); + list($language, $path) = language_url_split_prefix($request_path, $languages); + // Store the correct system path, i.e. minus the path prefix. + _language_resolved_path($path); if ($language !== FALSE) { $language_url = $language->langcode; diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php index f72c51a..92a419b 100644 --- a/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php +++ b/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php @@ -35,7 +35,7 @@ function setUp() { parent::setUp(); // Ensure we are building a new Language object for each test. - language(NULL, TRUE); + $this->container->get('language_manager')->reset(); } diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php index e86ad6c..9200d89 100644 --- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php +++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php @@ -369,6 +369,7 @@ protected function runTest($test) { if (!empty($test['language_test_domain'])) { state()->set('language_test.domain', $test['language_test_domain']); } + $this->container->get('language_manager')->reset(); $this->drupalGet($test['path'], array(), $test['http_header']); $this->assertText($test['expect'], $test['message']); $this->assertText(t('Language negotiation method: @name', array('@name' => $test['expected_method_id']))); diff --git a/core/modules/locale/lib/Drupal/locale/LocaleBundle.php b/core/modules/locale/lib/Drupal/locale/LocaleBundle.php new file mode 100644 index 0000000..c474b20 --- /dev/null +++ b/core/modules/locale/lib/Drupal/locale/LocaleBundle.php @@ -0,0 +1,26 @@ +register('locale_config_subscriber', 'Drupal\locale\LocaleConfigSubscriber') + ->addTag('event_subscriber'); + } + +} diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php index e22e65d..465a4b9 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php @@ -56,8 +56,8 @@ function testUninstallProcess() { 'default' => $this->langcode == 'fr', )); language_save($language); - // Reset statically cached language objects. - language(NULL, TRUE); + // Reset the language manager. + $this->container->get('language_manager')->reset(); // Check the UI language. drupal_language_initialize(); $this->assertEqual(language(LANGUAGE_TYPE_INTERFACE)->langcode, $this->langcode, t('Current language: %lang', array('%lang' => language(LANGUAGE_TYPE_INTERFACE)->langcode))); @@ -101,13 +101,11 @@ function testUninstallProcess() { // Uninstall Locale. module_disable($locale_module); module_uninstall($locale_module); + $this->rebuildContainer(); // Visit the front page. $this->drupalGet(''); - // Reset statically cached language objects. - language(NULL, TRUE); // Check the init language logic. - drupal_language_initialize(); $this->assertEqual(language(LANGUAGE_TYPE_INTERFACE)->langcode, 'en', t('Language after uninstall: %lang', array('%lang' => language(LANGUAGE_TYPE_INTERFACE)->langcode))); // Check JavaScript files deletion. diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 5ba05d2..579819e 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -1303,11 +1303,3 @@ function _locale_rebuild_js($langcode = NULL) { return TRUE; } } - -/** - * Implements hook_language_init(). - */ -function locale_language_init() { - // Add locale helper to configuration subscribers. - drupal_container()->get('event_dispatcher')->addSubscriber(new LocaleConfigSubscriber()); -} diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index b337e4c..21388a8 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -1024,13 +1024,6 @@ protected function tearDown() { // this second reset is guranteed to reset everything to nothing. drupal_static_reset(); - // Reset static in language(). - // Restoring drupal_container() makes language() return the proper languages - // already, but it contains an additional static that needs to be reset. The - // reset can happen before the container is restored, as it is unnecessary - // to reset the language_manager service. - language(NULL, TRUE); - // Restore original in-memory configuration. $conf = $this->originalConf; new Settings($this->originalSettings); diff --git a/core/modules/system/language.api.php b/core/modules/system/language.api.php index eb8bc3c..ed81b92 100644 --- a/core/modules/system/language.api.php +++ b/core/modules/system/language.api.php @@ -11,33 +11,6 @@ */ /** - * Allows modules to act after language initialization has been performed. - * - * This is primarily needed to provide translation for configuration variables - * in the proper bootstrap phase. Variables are user-defined strings and - * therefore should not be translated via t(), since the source string can - * change without notice and any previous translation would be lost. Moreover, - * since variables can be used in the bootstrap phase, we need a bootstrap hook - * to provide a translation early enough to avoid misalignments between code - * using the original values and code using the translated values. However - * modules implementing hook_boot() should be aware that language initialization - * did not happen yet and thus they cannot rely on translated variables. - */ -function hook_language_init() { - global $conf; - - switch (language(LANGUAGE_TYPE_INTERFACE)->langcode) { - case 'it': - $conf['system.site']['name'] = 'Il mio sito Drupal'; - break; - - case 'fr': - $conf['system.site']['name'] = 'Mon site Drupal'; - break; - } -} - -/** * Perform alterations on language switcher links. * * A language switcher link may need to point to a different path or use a diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php index 21a129a..275e1c4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php @@ -43,7 +43,7 @@ function testCRUD() { $this->fixtures->createTables($connection); //Create AliasManager and Path object. - $aliasManager = new AliasManager($connection, $this->container->get('keyvalue')); + $aliasManager = new AliasManager($connection, $this->container->get('state'), $this->container->get('language_manager')); $path = new Path($connection, $aliasManager); $aliases = $this->fixtures->sampleUrlAliases(); @@ -96,7 +96,7 @@ function testLookupPath() { $this->fixtures->createTables($connection); //Create AliasManager and Path object. - $aliasManager = new AliasManager($connection, $this->container->get('keyvalue')); + $aliasManager = new AliasManager($connection, $this->container->get('state'), $this->container->get('language_manager')); $pathObject = new Path($connection, $aliasManager); // Test the situation where the source is the same for multiple aliases. diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php index c4dda65..ff45adc 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php @@ -288,6 +288,7 @@ protected function performUpgrade($register_errors = TRUE) { * @see WebTestBase::drupalGet() */ protected function getUpdatePhp() { + $this->rebuildContainer(); $path = $GLOBALS['base_url'] . '/core/update.php'; $out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $path, CURLOPT_NOBODY => FALSE)); // Ensure that any changes to variables in the other thread are picked up.